Net2WG/Topics/LinkLayerInterfaceProposal
Contents
Interfaces for T2 Link Layer
Neighbor Table
{{{ typedef uint8_t interface_type_t; typedef uint8_t interface_id_t;
typedef struct mac_info_t {
nx_am_addr_t netAddr; interface_type_t interfaceType; interface_id_t interfaceID;
} mac_info_t;
typedef uint8_t ll_handle_t; typedef uint8_t ll_flag_t;
typedef struct duty_info_t{
uint32_t timeOn; uint32_t timeOff;
/* Alternate Version * uint32_t timeOn; * uint32_t onDuration; * uint32_t offDuration; * * This allows multiple cycles to be stored in one struct */
} duty_info_t;
typedef struct neigh_entry_t {
ll_handle_t nodeHandle; mac_info_t macInfo; duty_info_t timeInfo; ll_flag_t flags; // Listen - 1 bit, Pinned - 1 bit, Message Pending - 1 bit?
}
command error_t NeighborTable.insert(nx_uint8_t netAddr); command error_t NeighborTable.remove(ll_handle_t llHandle); command error_t NeighborTable.pin(ll_handle_t llHandle); command error_t NeighborTable.unpin(ll_handle_t llHandle); command ll_handle_t* NeighborTable.getHandle(nx_uint8_t netAddr); command duty_info_t* NeighborTable.getPeriod(ll_handle_t llHandle); command nx_am_addr_t* NeighborTable.getAddr(ll_handle_t llHandle); command interface_type_t* NeighborTable.getInterfaceType(ll_handle_t llHandle); command interface_id_t* NeighborTable.getInterfaceID(ll_handle_t llHandle); command error_t NeighborTable.setPeriod(ll_handle_t llHandle, duty_info_t* timeInfo); command error_t NeighborTable.setListen(ll_handle_t llHandle);
}}}
What actions do we need events for? Do we ask for admit permission on insert and remove, meaning presenting an admit and evict event? Or do we just assume the presence of a resource manager that controls this and consequently only use an admitted and evicted event? Could potentially have both but this seems redundant. {{{ event void NeighborTable.updated(ll_handle_t llHandle); event void NeighborTable.admitted(ll_handle_t llHandle); event void NeighborTable.evicted(ll_handle_t llHandle); // Should this present different parameters? event void NeighborTable.expiration(ll_handle_t llHandle); }}}
Link Estimation:
{{{ typedef uint8_t link_quality_t;
// Link Estimator will maintain own table, based on ll_handle_t's, with pertinent info
command link_quality_t* LinkEstimator.getForwardQuality(ll_handle_t llHandle); commnad link_quality_t* LinkEstimator.getReverseQuality(ll_handle_t llHandle);
// Do we need a getQuality call? I don't see the need as it as different network protocols can use different combinations // We could provide access to the link estimator table, but would this not create a dependency on the specific estimator?
}}}
Message Pool:
The MessagePool interface has to present all the basic interface capabilities, such as getMaxPayload, and getPayloadLength.
{{{ typedef uint32_t timing_unit_t;
typedef struct timing_req_t {
timing_unit_t latencyTimeout; // Amount of time before message is sent urgently timing_unit_t holdFor; // Indicates period for which message should not be sent timing_unit_t timeSubmitted; timing_unit_t linkDelay; timing_unit_t totalDelay;
} timing_req_t;
typedef nx_uint8_t message_id_t; typedef nx_uint8_t message_flags_t;
typedef struct ll_message_t {
message_t* mainMessage; ll_handle_t destHandle; timing_req_t timingReqs; nx_uint8_t quantity; message_flags_t flags; message_id_t msgID;
} ll_message_t;
command message_id_t* MessagePool.newMessage(); command error_t MessagePool.setDestination(message_id_t msgID, ll_handle_t destHandle); command error_t MessagePool.setLatencyTimeout(message_id_t msgID, timing_unit_t latencyTimeout); command error_t MessagePool.setHoldDuration(message_id_t msgID, timing_unit_t holdDuration); command error_t MessagePool.setQuantity(message_id_t msgID, nx_uint8_t quantity); command error_t MessagePool.setReliability(message_id_t msgID, bool reliability); command error_t MessagePool.send(message_id_t msgID); command error_t MessagePool.cancel(message_id_t msgID); //command error_t MessagePool.rawSend(nx_am_addr_t* destAddr,
interface_type_t* destInterfaceType, interface_id_t* destInterfaceID; timing_unit_t* latencyTimeout, timing_unit_t* holdDuration);
command timing_unit_t* MessagePool.getLinkDelay(message_id_t msgID); command timing_unit_t* MessagePool.getTotalDelay(message_id_t msgID);
event error_t MessagePool.sendDone(message_id_t msgID); event message_t* MessagePool.getNext(message_id_t msgID, error_t result); event message_t* MessagePool.receive(message_t* msg, void* payload, uint8_t len);
}}}
Global Behavior:
// Allows a network component to set global node behavior {{{ // Allows protocols such as flush to instruct link layer to remain quiet for specified period of time // Should potentially be specifying interface to remain quiet on. Can do this either by specifying the interface // ID or by specifying a neighbor that exists on the desired interface. command error_t GlobalBehavior.setSilentPeriod(timing_unit_t silentPeriod); }}}