Skip to content

Controller Behavior

Kamila Součková edited this page Feb 1, 2015 · 1 revision

Deciding whether to open the door

The Online-Only Model

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:

  • needs to support only OPEN and CRITICAL request types
  • server-side does not need to compile rules

The States Model

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.

Data storage

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).

The Decision Algorithm

When we want to look up ISIC id, in state q:

  1. StateBits sb = 0x0; (deny by default)
  2. 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
  3. traverse diffList (the shorter list which we can afford to go over in linear time), overwriting sb if something was found
  4. open the door iff sb & (1<<q)

State transitions

v0.1: server-sent state

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).

Maybe one day: Time-based state transition

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.