A retail barcode terminal and its desktop exchange server, known to EKOS only as a bin/Release folder of compiled .NET assemblies: no source code, no documentation, no developers to ask. This deck explains how the whole system works. Every claim traces to a metadata token in a specific binary.
The handheld window is titled “Data Collection Terminal”. Store staff use it for price checks, stock-taking, receiving trucks and boxes, and returns. The desktop app, “TSD Exchange Server”, loads the product catalogue and documents onto it and pulls the scans back.
TSDClient.exe, .NET Compact Framework 2.0 on Windows CE. 117 types, 1,189 methods.TSDServer.exe, Windows Forms tray app. 59 types, 817 methods.Calib: barcode reader, Bluetooth, buzzer/vibrator.NavCode, shown as “Navision code”. The ERP is most likely Dynamics NAV (reading).Across all 12 binaries, EKOS found no call into any database provider. The typed TableAdapters call FamilTsdDB's Fill/Write, an in-house indexed file store.
The handheld declares its classes in namespace TSDServer. Both executables compile the same DataSets and the same storage engine.
RAPI.BeginCopyFileToDevice / CopyFileFromDevice in TSDServer.exe 0x06000011 / 0x06000025| # | Where | What happens | Method |
|---|---|---|---|
| 1 | desktop | Operator imports the product or document file; parsing runs on a background thread | AutoLoadProduct · LoadFile |
| 2 | desktop | windows-1251 text is parsed (fixed-width or delimited) into FamilTsdDB; bad barcodes are skipped | BeginImport |
| 3 | desktop → device | Catalogue-age check, old files deleted on the device, new ones copied over RAPI (device clock is synced on connect) | button2_Click |
| 4 | device | Settings.xml loaded (with built-in defaults), numbered menu shown, scanner started | Program.Main · BeginScan |
| 5 | device | Every scan updates the table and is journaled to disk at once, via change events | WriteDbTxt |
| 6 | device → desktop | Scanned files copied back over RAPI | downloadBtn_Click |
| 7 | desktop | Results written and archived as {name}_{yyyyMMddhhmmss}.txt; terminal wiped if configured | UploadResults · DeleteOldDB |
TSDServer.exe /c runs steps 1–2 unattended with a 900,000 ms timeout per file; every import's status is emailed (subject “Data load status”)MenuEvents 0x0600013C · key ↔ form pairing: reading“This is a foreign box!”
“Box already accepted!”
“Waybill is not for this store!”
“Accepted {0} of {1} boxes”
“Scan the new count sheet barcode”
“Count already exists!”
“Barcode {0}: wrong address!”
“Item already received: {0} of {1}”
“This item is part of a return”
“No returns found”
“Box {0} already closed”
F1 / F2 print label · F4 documents
OBROpen via OBReadLibNet; waits on "OBRScanningEvent" with a 2000 ms timeout.|-separated, UTF-8, flushed per change, so a battery loss loses nothing.ekos_impact: 29 methods (14 direct, deepest 4 hops away) write scan records through AddScannedRow.navCodeTB_KeyDown (cc 42) and DoAction (cc 38) are the most complex methods in the system.Each DocsTbl row carries LabelCode, MusicCode, VibroCode and Priority. On a scan, the action handler plays SOUND_{MusicCode}.def on the buzzer and VIBRO_{VibroCode}.def on the vibrator. It can also print LABEL_{n}.DEF to the Bluetooth printer, after filling <GOODS_ATTRIBUTE_x>, <DOCS_ATTRIBUTE_x>, <SCAN_ATTRIBUTE_x> and <SYSTEMDATE>.
NoAction Returns Reprice Remove InventoryGlobal InventoryLocal QuickHelp IncomeBox BoxIncomes SimpleIncome CloseIncome Cars CarsBoxes BoxWProducts StrangeBox BoxReturns ReturnBoxWProducts CloseBoxReturns ReturnsTTN ReturnInInventory CloseInventar AlreadyAccepted NotFound DocNotFound // labels: REPRICING, TRANSFER, // QUICK HELP, Deliveries (waybill), …
| Table | Columns | Role |
|---|---|---|
| ProductsTbl | Barcode · NavCode · Article · ProductName · Country · Structure · OldPrice · NewPrice · Message (+ MarketPrice · Message2 · AcceptDefect on the client) | catalogue |
| DocsTbl | DocId · DocType · NavCode · DocumentDate · Quantity · Priority · LabelCode · MusicCode · VibroCode · Text1–3 | plan + per-document behaviour |
| ScannedBarcodes | Barcode · DocId · DocType · PlanQuanity · FactQuantity · ScannedDate · TerminalId · Priority | the day's result |
| TypedSettings | 19 terminal settings: printer MAC and COM port, storage path, templates, permissions… | Settings.xml |
# terminal journal (8 fields) scannedbarcodes.txt1 6600000000001|6600000000001|8|0|02.01.2003|0|0|0 # desktop export (7 fields) scannedbarcodes.txt 2900655000005|02: 15.06.11|2|1|29.06.2011|1|0
Including VibarationOn/ScanSoundNotifyOn and the SQL CE products.sdf connection string. Their getters have no incoming Calls edge.
ReturnBoxForm (11 methods, a near-copy of IncomeForm) is never constructed. GetDeviceID is never called either, so TerminalID comes from the settings file.
PrintLabel reads LABEL_{n}.DEF, and none is in the folder. Three DLLs that no binary depends on (Imager, MoFlink, ControlsLib) ship anyway.
TSDClient.exe, TSDClient - Copy.exe and TSDClient.ex_ differ in type count. The folder alone cannot tell which one is deployed.
ekos_binary_explain over all 931 types; ekos_impact, ekos_neighborhood, ekos_dependents, ekos_state.DoAction's 33 branches; enum numeric values; import column widths (runtime settings).MCSSLib.dll (ARM), the .pdb and the .zip.# compile the binaries into a ledger ekos init && ekos build && ekos recover ekos resolve --force && ekos compile && ekos commit # deterministic docs, then ask through MCP ekos docs generate --layout curated ekos mcp serve --workspace . # ekos_binary_explain · ekos_impact
Full documentation (18 sections) · raw ekos_binary_explain output · EKOS-generated reports