Edge connector
edge-connector.exe runs as the Windows service EdgeConnector on a
computer in a site's network. Source: entrosity-edge-connector
(cmd/edge-connector, packages app, controllers, driver, spool,
simui), sharing entrosity-shared-go/agentkit (transport, job executor,
DPAPI secret store, logging, service wrapper) with the Axis agent and
connector. How to install it: Connectors.
Installation
msiexec /i edge-connector.msi /qn ENROLLMENT_TOKEN=<token> SERVER_URL=https://hub.entrosity.com/edge
| Property | Meaning |
|---|---|
ENROLLMENT_TOKEN | An Edge connector enrollment token (Connectors → Install a connector). |
SERVER_URL | Edge's address, including /edge. |
- Installs to
%ProgramFiles%\Entrosity Edge Connector\(64-bit, per machine) and registers the serviceEdgeConnector(display name Entrosity Edge Connector, LocalSystem, automatic start,run) and an Application event log source of the same name. - With both properties,
edge-connector enrollruns as SYSTEM before the service starts; a failed enrollment rolls the install back. On a computer that is already enrolled it does nothing and succeeds. Without the properties the service starts and waits for an enrollment. - After start, the service is set to restart 30 seconds after each of its
first three failures, the count reset after a day (
sc.exe failure, best effort). - Any installed version is replaced: a newer, the same or an older MSI (downgrades are allowed so that the self-update watchdog can reinstall the previous version). The data directory is kept, so the connector stays enrolled.
- Uninstalling removes the service,
connector.dat,state.json,controllers.json, atrackbase.jsonleft by older versions and the event queue (spool\, whose events belong to the removed connector); the logs are kept. - A verbose install log (
/l*v) contains the token: delete it afterwards.
Command line
edge-connector <command> [flags]
run run the connector (foreground, or as a service under the SCM)
--server URL --token T enroll first if not enrolled yet
enroll enroll this machine: --server URL --token T [--force]
(URL is the Edge address, e.g. https://hub.entrosity.com/edge)
status show enrollment state and events waiting for the server
install install the Windows service
uninstall remove the Windows service
version print the version
enrollon an enrolled computer printsalready enrolledunless--forceis given. Errors name the cause: the token is invalid (not an Edge connector token), has no uses left, or has expired or was revoked.runwithout credentials and without--server/--tokenwaits, checking every 10 seconds, untilenrollhas stored them.statusprintsenrolled: connector <id>, server <url>andevents waiting for the server: <n>.- Without a command it prints the usage, flags and environment variables.
Environment
| Variable | Default | Meaning |
|---|---|---|
EDGE_CONNECTOR_DATA_DIR | %ProgramData%\Entrosity Edge Connector (Windows), ~/.edge-connector elsewhere | Data directory. |
EDGE_LOG_LEVEL | info | debug, info, warn or error. |
EDGE_SIM_ADDR | 127.0.0.1:9199 | Address of the simulator page; must be a loopback address. off disables it. |
For the service, set variables as a service environment
(HKLM\SYSTEM\CurrentControlSet\Services\EdgeConnector, value
Environment, REG_MULTI_SZ) and restart it.
Files
%ProgramData%\Entrosity Edge Connector\
connector.dat credentials {connector_id, connector_key, server_url, ws_url},
encrypted with machine-scope DPAPI
state.json jobs in progress (reported as failed after a restart)
controllers.json each controller's target (with its PIN), driver, last applied
configuration (version, hash, snapshot), configurations that
failed part-way since ("attempts") and event cursor
update\ self-update: the downloaded MSIs, the update script and its
outcome (see Self-update)
spool\ the event queue: segments <first seq>.jsonl (4 MiB each)
and "acked" (the highest acknowledged sequence number)
logs\connector.log rotating log (the service also writes to the Application event log)
The data directory is created with owner-only permissions. Outside Windows the credentials are stored unencrypted (development only).
Drivers
| Driver | Status |
|---|---|
simulator | Complete: two simulated TrackBase002-compatible controllers (127.0.0.1:9001, 127.0.0.1:9002) and any other address on first use; 2,000 cards, 32,000 events, badge decisions with the reference semantics. See Trying Edge with the simulator. |
trackbase002 | The Track Access controller protocol over TCP: probe, discovery, configuration, events, clock, remote opening and status (see below). Serial ports (RS-485) return unsupported. Not yet verified against a live controller. |
Drivers implement one coarse interface (internal/driver): probe,
discover, apply a whole configuration, read events after a cursor, open a
door, report status. With each configuration a driver also receives the
configurations the controller may still hold: the last applied one and any
that failed part-way since (kept in controllers.json as attempts). A
resend of the same configuration (resync, Send configuration again)
asks for a full rewrite.
trackbase002
The protocol was reverse-engineered from the vendor's server software and
has not been verified against a live controller yet. Every frame is logged
at debug level with the PIN masked, so a traffic capture can confirm it.
Verify on one controller before moving a site over.
- Transport: TCP only, to the controller's
host:port. Binary request/reply frames (A…B, 37 or 264 bytes) carry the controller's 32-bit PIN and an 8-bit checksum; one command at a time per controller. The connector keeps one connection per controller, opens it with a handshake (which identifies the controller: firmware shown as e.g.0123 (type 02)) and reopens it after 1 minute idle or on an error. - PINs: set in Edge per controller
(Controller PIN) and delivered in
the target of every job for the controller (
target.pin, Edge connector protocol). The connector keeps the target with its PIN incontrollers.jsonand never reports the PIN back.trackbase.json, read by earlier versions, is ignored. Without a PIN the controller is offline with the error the controller's PIN is not set: set it in Edge (the controller's page, Controller PIN), and applying fails withconfig_rejected. With a wrong PIN the controller does not answer the handshake: unreachable (check the controller's PIN). - Discovery has no PINs: an address that answers on TCP is listed without its firmware; Test connection after adding it with its PIN shows the firmware.
- A new target (PIN, address, transport or bus address changed in
Edge) arrives as an
edge.config.applyof the unchanged configuration: the connector only updates the target, without a full rewrite. - Configuration: a card is enrolled with one time zone (of 16) and a
reader mask. Each distinct set of schedules becomes a time zone: at most
16 per controller, at most 8 time windows per day each (windows of
overlapping or adjacent schedules are merged). Card numbers are 24-bit:
Wiegand 26 is facility code and number; iButton keys must fit in 24 bits
(6 hex digits).
config_rejectednames the cause: a card with different schedules at different doors, too many time zones or windows, an iButton key over 24 bits, two credentials with the same 24-bit number. Memory full:capacity_exceeded. - Applying: controllers cannot list or clear their cards, so the connector applies the difference to what it last applied: it deletes removed cards, rewrites changed time zones, enrolls new and changed cards, then commits. A resync rewrites every time zone and card. Cards enrolled outside Edge and not in its configuration are not removed.
- Holidays cannot be stored: weekday times apply on holidays, and the status carries the warning holidays are not enforced by TrackBase controllers: weekday times apply on them. iButton readers (readers 3 and 4) accept every enrolled card at every door, as in the vendor's software; the status warns when that matters.
- Events: read from the controller's event log (a ring of 31,968
records). A newly configured controller is read from its current
position; older events are not imported. Card records become
access_granted,access_deniedorunknown_cardwith door, reader, direction and credential. The record does not say whether the controller opened, so the connector decides the type from the applied configuration (which the controller enforces), without holidays. Other records (temperatures, inputs) are logged, not reported, until their layout is known. After a restart, events are read once the configuration has been applied again (automatically when the controller is online; retried every minute). - Clock: set to the configuration's time zone whenever it is more than 2 seconds off or invalid (some controllers report day 00), checked at each connection and status read. After setting it, the connector reads it back with a status read; if the date did not take, it tries the other known layouts (weekday Sunday = 0, weekday Monday = 0, BCD) and keeps the one that reads back valid. If none does, the protocol's layout is left on the controller and tried again after 10 minutes. Another program setting the clock (the vendor's server) makes the connector set it again at each read: stop it first.
- Remote opening: operates the door's lock relay (the door's Lock
relay, else relay N for door N); the controller releases it after its
own relay time, and the unlock time set in Edge is not sent. A
door_opened_remoteevent is recorded. - Status: online or offline from a status read at most every 30
seconds. Door open and locked states are not reported yet (which inputs
are door contacts is not known). A missing PIN is the controller's error
text; the limits above (holidays, iButton readers) go with the
config_appliedevent instead.
Jobs and lanes
| Lane | Jobs | Parallelism |
|---|---|---|
config | edge.config.apply, edge.controller.remove | 1 (a bus of controllers is written serially) |
door | edge.door.open | 4 (never behind a configuration) |
discover | edge.discover, edge.controller.test | 1 |
update | update_agent (component edge-connector) | 1 |
Payloads and results: Edge connector protocol.
Timing
| What | Interval |
|---|---|
| Heartbeat | 1 minute |
| Reading each controller's events | 1 second |
| Controller status report | 1 minute, and after each change |
| Upload of the event queue | At once when events arrive, else every 5 seconds; back-off up to 1 minute on errors |
| Resend of an unacknowledged chunk over HTTP | 15 seconds |
| Reconnect | Exponential back-off with jitter, as for Axis agents (Protocol) |
The connector announces the capabilities access_control and
edge_update (it installs self-updates) in hello.
Self-update
Edge offers a newer connector version as an update_agent job
(component: edge-connector, Edge connector protocol);
how releases get there: Running Entrosity Edge.
- The job carries the release (
target) and, when Edge has it, the MSI of the running version (rollback), each with an Ed25519 signature over its component, version, SHA-256 and size. The connector checks the signatures against the public key built into it (RELEASE_PUBLIC_KEYat build time,-X …/agentkit/update.PublicKey=) before downloading anything: a build without the key answersupdate_unsigned, a bad signaturesignature_invalid. - It downloads both MSIs from the job's signed links
(
GET <Edge address>/api/connector/v1/releases/{id}/msi?exp=&sig=, valid 24 hours) into<data dir>\update\, checks their SHA-256 and size (download_failed,hash_mismatch), and registers a one-shot SYSTEM scheduled taskEdgeConnectorUpdatethat starts a minute later. The job succeeds withUpdateResult{scheduled, from_version, to_version, rollback}. - The task runs
msiexec /i <new MSI> /qn. Its watchdog then waits (up to five minutes) for theEdgeConnectorservice to be running and still running a minute later; if it is not, it installs the previous MSI again (the MSI allows downgrades) and starts the service. - The outcome is logged in the connector log at the next start
(
self-update outcome, with the status and both versions), and the new version is reported inhello.
Job errors: update_unsigned, signature_invalid, download_failed,
hash_mismatch, exec_failed (the update folder or the scheduled task
could not be created), invalid_payload.
Connectors built before self-update do not announce edge_update and are
never offered updates: upgrade them by hand once
(Connectors → Updates).