-
Notifications
You must be signed in to change notification settings - Fork 0
Controller Behavior
When we receive an ISIC ID, we always send an OPEN request and let the server make the decision. If the server is offline (we don't get a reply), TODO then what?
Notes:
With respect to deciding about whether to open the door, the controller can be viewed as an FSM in one of S states. The data we have is a list of (ISIC_id, StateBits). When in state q, when we receive the ISIC ID id, we look up the StateBits for id and answer with StateBits[q].
Motivation: whatever complex rules we come up with are processed by the server, and compiled into a simple list of states that correspond to whatever combinations are needed. The controller then just needs to know what state it should be in, which is much simpler than any rule evaluation.
As specified in Protocol, the controller can ask for the DB diff between specific versions and the response is a sorted list of (ISIC_id, StateBits). How this will be used:
We will store two lists:
- base: the full database (from version 0 to version baseVersion), stored in flash
- diffList: diff from baseVersion to newestVersion, stored in RAM
When we want to update the DB, we leave base as it is and only update diffList (request: XFER DB origDiffListVersion newestVersion
). In case we are told that length(diffList) + incoming diff length > K (for some K determined by the size of RAM and speed requirements) we abandon updating diffList and instead update base (request: XFER DB 0 newestVersion
) (and empty diffList). This allows for frequent DB updates without wearing off the flash.
Updating diffList is appending the server-sent diff to the end of the original diffList. We first receive the full diff and append it after diffList and then atomically update the length variable used in querying.
Updating base is not done in place: we write the new list somewhere else and once it's fully written, we atomically switch to using the new one (and "free" the old one).
When we want to look up ISIC id, in state q:
-
StateBits sb = 0x0;
(deny by default) - binary search for id in base (the long list with most data, which we want to be done with fast), setting
sb
to what was found if anything - traverse diffList (the shorter list which we can afford to go over in linear time), overwriting sb if something was found
- open the door iff
sb & (1<<q)
All logic is on the server. We send a PING request in (e.g.) 5-minute intervals and set our state to whatever the server told us. Before the first PING reply (after a reset) is received, or if no reply is received for PINGs in 15min, we fall back to state 0 (and the server should ensure that 0 is a good fallback state when compiling the DB).
The server will also send a list of (time specification, state) -- which state we should be in at the given time. Every minute we will check the list and change state appropriately.