Indigresso Wiki

Open Source Stuff for DASH7

User Tools

Site Tools


Mode 2 Network Module (OTlib)

DASH7 Mode 2 implements a fairly simple network layer that contains several network protocols. The OpenTag Network Module is part of OTlib, and it implements all the Mode 2 network protocols, general-purpose processing of DLL frames, and simplistic two-hop routing (as derived from Mode 2). Mode 2 allows as many as 15 hops, optionally, and developers interested in enhancing the multihop abilities of OpenTag should consider writing an OTlib extension that fits into the Network Module.

Implementation Notes

Network Module functions tend to get called from the Kernel, and they are not generally interfaced by the user application. In certain cases, it may be valuable to inspect the contents of Network Module data elements however, as done in the M2QP Transport Module and perhaps elsewhere. Additionally, the Network Module includes a built-in callback function that may be useful to the user application.

Data Elements

Some data elements stored inside the Network Module may be useful for the user application, or for other Modules to inspect. The way this diagram is constructed is such that the routing callback would be accessed by m2np.signal.route, the frame info byte by m2np.header.fr_info, etc.

  • m2np (m2np_struct: M2_network.h)
    • rt (routing_tmpl: OTAPI_tmpl.h)
      • hop_code (ot_u8) – contains flags and number of hops (0-15) for doing multihopping
      • hop_ext (ot_u8) – contains optional extra data for special multihop methods
      • dlog (id_tmpl: OTAPI_tmpl.h) – ID of other device in the dialog
        • length (ot_u8) – length of ID (2 or 8)
        • value (ot_u8*) – ID string
      • orig (id_tmpl) – ID of origin device (only used in multihop)
      • dest (id_tmpl) – ID of final destination device (only used in multihop)
    • header (header_struct: M2_network.h)
      • fr_info (ot_u8) – Frame Info byte from DASH7 DLL, used in Foreground Frames
      • addr_ctl (ot_u8) – Address Control byte from DASH7 DLL, used in Foreground Frames
    • signal (m2npsig_struct: M2_network.h)
      • route (ot_sig2) – routing callback
  • m2dp (m2dp_struct: M2_network.h)
    • dscfg (dscfg_struct: M2_network.h) – Datastream Configuration data
      • ctl (ot_u8) – Control bits for datastream
      • dmg_count (ot_u8) – number of damaged frames in the stream
    • out_rec (alp_record: alp.h) – Datastream record structure
      • flags (ot_u8) – NDEF record flags
      • payload_length (ot_u8) – NDEF record payload length
      • dir_id (ot_u8) – datastream directive ID
      • dir_cmd (ot_u8) – datastream command ID
      • bookmark (void*) – pointer for extensions

The m2np data element is where most of the important network & routing frame data exists. The m2dp data element is used only for datastreaming, which at this point is experimental and not officially supported. The m2np.dlog data and m2np.header data are referenced commonly in the kernel and the transport layer. The callbacks (currently just m2np.signal.route) is optionally used by the application layer.


As stated above, M2NP currently has one callback. It is designed for routing extensions, but it can be used for other purposes. If it is enabled in the compile-time configuration of the OpenTag build, the route callback will be called after an M2NP frame has been successfully processed. This enables the user to manipulate the m2np data, dll data, or run any manner of other processes before the kernel resumes doing work at the data link layer (DLL). In a simple example, this callback can be used just to print out good packets that have been processed successfully.


The code from M2_network.h is pasted below, although you can also check the doxygen code documentation.

#include "OT_types.h"
#include "session.h"
//#include "system.h"
#include "alp.h"

/** M2NP Routing Parameters
  * ============================================================================
  * @todo adjust to lastest spec

// Mode 2 Frame Info Field
#define M2FI_FRTYPEMASK         (0x03)
#define M2FI_FRDIALOG           (0x00)
#define M2FI_FRNACK             (0x01)
#define M2FI_STREAM             (0x02)
#define M2FI_RFU                (0x03)
#define M2FI_NM2                (0x04)
#define M2FI_CRC32              (0x08)
#define M2FI_FRCONT             (0x10)
#define M2FI_ENADDR             (0x20)
#define M2FI_DLLS               (0x40)
#define M2FI_LISTEN             (0x80)

// Official Mode 2 Network Protocol IDs
#define M2PID_M2NPv0            (0x50)
#define M2PID_M2NPv1            (0x51)
#define M2PID_M2DP              (0x60)
#define M2PID_M2ADVP            (0xF0)
#define M2PID_M2RESP            (0xF1)

// M2NP Routing Types
#define M2RT_UNICAST            (0x00 << 6)
#define M2RT_BROADCAST          (0x01 << 6) 
#define M2RT_ANYCAST            (0x02 << 6)
#define M2RT_MULTICAST          (0x03 << 6)
#define M2RT_MASK               (0x03 << 6)

// M2NP Address Control Flags
#define M2AC_VID                (0x01 << 5)
#define M2AC_NLS                (0x01 << 4)

// M2NP Command Code Options
#define M2CC_SLEEP              (0x01 << 4) 
#define M2CC_EXT                (0x01 << 5) 

// Mode 2 Hop Control Options
#define M2HC_HOPMASK            (0x0F)
#define M2HC_VID                (0x01 << 4)
#define M2HC_DEST               (0x01 << 5)
#define M2HC_ORIG               (0x01 << 6) 
#define M2HC_EXT                (0x01 << 7) 

// Application Device Flags
#define M2DF_EALARM             (0x01 << 3)
#define M2DF_SALARM             (0x01 << 4)
#define M2DF_LOWBATT            (0x01 << 5)
#define M2DF_SYSFAULT           (0x01 << 6)
#define M2DF_NACK               (0x01 << 7)

// Datastream Flags
#define M2DS_DISABLE_ACKREQ      (0x01 << 7)
#define M2DS_DISABLE_ACKRESP     (0x01 << 1)

typedef struct {
    ot_u8   fr_info;
    ot_u8   addr_ctl;
} header_struct;

typedef struct {
    ot_sig2 route;
} m2npsig_struct;

typedef struct {
    routing_tmpl    rt;
    header_struct   header;
        m2npsig_struct  signal;    
#   endif
} m2np_struct;

typedef struct {
    ot_u8   ctl;
    //ot_u8   fr_total;
    //ot_u8   fr_per_pkt;
    ot_u8   dmg_count;
    //ot_u16  data_total;
} dscfg_struct;

typedef struct {
    dscfg_struct    dscfg;
    //alp_record      in_rec;
    alp_record      out_rec;
} m2dp_struct;

    extern m2dp_struct m2dp;
extern m2np_struct m2np;

/** Low-Level Network Functions
  * ============================================================================
  * - In some OSI models, these might be in the "LLC" layer of the MAC.  They
  *   fit more nicely and cleanly in this module, though.

/** @brief  Initializes all persistent network data (objects)
  * @param  None
  * @retval None
  * @ingroup Network
  * @sa sys_init()
  * Call when initializing your runtime application (it gets called within 
  * sys_init() in system.c)
void network_init();

/** @brief  parses a background frame, namely one using M2AdvP
  * @param  session     (m2session*) Pointer to active session
  * @retval ot_int      -1 on ignore, non-negative on session modified/created
  * @ingroup Network
m2session* network_parse_bf();

/** @brief  parses and routes a foreground frame
  * @param  session     (m2session*) Pointer to active session
  * @retval ot_int      -1 on ignore, non-negative is Routing Index of the
  *                     device/host that should be forwarded the message.
  * @ingroup Network
  * The routing index return value will always be 0 if this device does not 
  * support multihop routing.  0 is the Routing Index of the localhost.  Any 
  * other positive return value is the index of the routing table which 
  * corresponds to the host that shall be forwarded the frame.
ot_int network_route_ff(m2session* session);

/** M2NP Network Functions
  * ============================================================================
  * - M2NP = Mode 2 Network Protocol.
  * - Routable, primary data-networking protocol for DASH7 Mode 2.
void m2np_header(m2session* session, ot_u8 addressing, ot_u8 nack);

void m2np_footer(m2session* session);

void m2np_put_deviceid(ot_bool use_vid);

ot_bool m2np_idcmp(ot_int length, void* id);

/** M2AdvP Network Functions
  * ============================================================================
  * - M2AdvP = Advertising Protocol, i.e. flooding for group synchronization.

/** @brief  Prepares an M2AdvP frame from a session container
  * @param  session     (m2session*) Pointer to active session
  * @retval none
  * @ingroup Network
void m2advp_open(m2session* session);

void m2advp_close();

ot_int m2advp_init_flood(m2session* session, ot_u16 schedule);

/** M2DP Network Functions
  * ============================================================================
  * - M2DP = Mode 2 Datastream Protocol
  * - Very little overhead, good for arbitrary data encapsulation
  * - Supports multi-frame packets and multi-packet streams
  * - No inherent flow control or ACK (requires a session layer to do it)
  * @note OpenTag uses a spec-legal, partial implementation of M2DP, including:
  * - Encapsulated data is restricted to supported application subprotocols
  * - Requires in-order frame delivery for datastreams that span multiple frames
  * - Usage with multiframe packets should work but is untested

/** @brief  Prepares an M2DP frame, moving the queue putcursor as needed
  * @param  frame_id    (ot_u8) Frame ID of the M2DP frame
  * @param  session     (m2session*) Pointer to active session
  * @retval none
  * @ingroup Network
void m2dp_open(ot_u8 frame_id, m2session* session);

/** @brief  Parses an M2DP frame, which is expected to carry an embedded ALP
  * @param  session     (m2session*) Pointer to active session
  * @retval ot_int      negative on parse error, 0 on parse success
  * @ingroup Network
ot_int m2dp_parse_dspkt(m2session* session);

/** @brief  Marks an M2DP frame as damaged (CRC is bad).
  * @param  session     (m2session*) Pointer to active session
  * @retval none
  * @ingroup Network
  * The datastream transport protocol (that tunnels within M2QP) is kind of like
  * SCTP.  Frames do not NEED to be transported in order (unlike TCP).  So when
  * a frame is damaged, it is marked, and it can be re-transfered later without
  * interrupting the stream.
  * @note Implementing the SCTP-style stream marking is not practical for light
  * devices because it requires a "large" RAM buffer.  So on light devices,
  * set Max-Frames-Per-Packet to 1 in order to get TCP-like behavior. 
void m2dp_mark_dsframe(m2session* session);

/** @brief  Processing function for ALP contents of the Datstream frame
  * @param  none
  * @retval none
  * @ingroup Network
  * The input frame is expected to be in the RX queue (rxq, from buffers.h).
  * The output is put onto TX queue (txq, from buffers.h).  The ALP states are
  * managed internally via the m2dp data "object."
void m2dp_dsproc();
opentag/otlib/m2network.txt · Last modified: 2012/03/11 20:34 by jpnorair