Exportable version of WizziLab's modem driver.

Dependents:   modem_ref_helper

include/d7a_1x.h

Committer:
Jeej
Date:
2019-07-31
Revision:
46:9b83866cef2c
Parent:
41:6f83174ffed4
Child:
47:cf4519ba56d9

File content as of revision 46:9b83866cef2c:

/// ======================================================================
///
/// Copyright (C) 20XX WizziLab
/// All Rights Reserved
///
/// =======================================================================
///
/// @file           d7a_1x.h
/// @brief          D7A 1.x API (below ALP and FS) 
/// @defgroup D7A   D7A 1.x API
/// @{
/// =======================================================================

#ifndef __D7A_1X_H__
#define __D7A_1X_H__

#include "kal_codec.h"

/// @ingroup D7A_API
/// @defgroup D7A_API_STR       D7A API (all except APL)
/// @{

// =======================================================================
// d7a_buf_t
// -----------------------------------------------------------------------
/// Generic D7A buffer structure
// =======================================================================
typedef struct
{
    /// Buffer payload length
    u8  len;
    /// Payload start offset (Result length)
    u8  pof;
    /// Shadow buffer payload length (snap/restore)
    u8  shadow_len;
    /// Shadow Payload start offset (snap/restore)
    u8  shadow_pof;
    /// Data
    u8  data[1];

} d7a_buf_t;

//======================================================================
//  D7A_BUF_R_PTR
//----------------------------------------------------------------------
/// @brief Pointer to the metadata (result)
/// @param  buf         d7a_buf_t buffer
//======================================================================
#define D7A_BUF_R_PTR(buf)              (void*)(((d7a_buf_t*)(buf))->data)

//======================================================================
//  D7A_BUF_P_PTR
//----------------------------------------------------------------------
/// @brief Pointer to the payload
/// @param  buf         d7a_buf_t buffer
//======================================================================
#define D7A_BUF_P_PTR(buf)              (void*)(((d7a_buf_t*)(buf))->data + ((d7a_buf_t*)(buf))->pof)

//======================================================================
//  D7A_BUF_P_LEN
//----------------------------------------------------------------------
/// @brief Get the payload length
/// @param  buf         d7a_buf_t buffer
//======================================================================
#define D7A_BUF_P_LEN(buf)              (((d7a_buf_t*)(buf))->len)

//======================================================================
//  Special session identifiers
//======================================================================
#define D7A_RESP_ID                     (0xff)

// =======================================================================
// d7a_id_t
// -----------------------------------------------------------------------
/// Identifier types enumerator
// =======================================================================
typedef enum
{
    /// skipped Unicast identifier 
    D7A_ID_VOID = 0,
    /// Void identifier (broadcast) 
    /// with indication of number of reached devices
    D7A_ID_NBID = 0,
    /// Void identifier (broadcast)
    D7A_ID_NOID = 1,
    /// Unique Identifier
    D7A_ID_UID  = 2,
    /// Virtual identifier
    D7A_ID_VID  = 3,

} d7a_id_t;

// =======================================================================
// d7a_nls_t
// -----------------------------------------------------------------------
/// Enumerator of the NWL security modes
// =======================================================================
typedef enum
{
    /// No security enabled
    D7A_NLS_NO = 0,
    /// Encryption only, Counter Mode
    D7A_NLS_AES_CTR,
    /// No encryption, Authentication, Cipher-block chaining with 128 bit MAC
    D7A_NLS_AES_CBC_MAC_128,
    /// No encryption, Authentication, Cipher-block chaining with 64 bit MAC
    D7A_NLS_AES_CBC_MAC_64,
    /// No encryption, Authentication, Cipher-block chaining with 32 bit MAC
    D7A_NLS_AES_CBC_MAC_32,
    /// Authentication with CBC-MAC-128 and Encryption with Counter Mode
    D7A_NLS_AES_CCM_128,
    /// Authentication with CBC-MAC-128 and Encryption with Counter Mode
    D7A_NLS_AES_CCM_64,
    /// Authentication with CBC-MAC-128 and Encryption with Counter Mode
    D7A_NLS_AES_CCM_32,
    /// QTY
    D7A_NLS_QTY

} d7a_nls_t;

//======================================================================
// ID manipulation macros 
//======================================================================

/// Unique ID length
#define D7A_UID_LEN                     (8)
/// Virtual ID length
#define D7A_VID_LEN                     (2)
/// No identifier length
#define D7A_NOID_LEN                    (0)
/// Void (skipped) identifier length
#define D7A_VOID_LEN                    (0)
/// Void ID length with reached 
/// devices number indicaiton
#define D7A_NBID_LEN                    (1)

/// Address is unicast (VID or UID)
#define D7A_ID_IS_UCAST(ctrl)           ((D7A_ID_UID == (ctrl).bf.idf) || (D7A_ID_VID == (ctrl).bf.idf))

/// Address is broadcast (no identifier)
#define D7A_ID_IS_BCAST(ctrl)           ((D7A_ID_NOID == (ctrl).bf.idf) || (D7A_ID_NBID == (ctrl).bf.idf))

/// Length of the Addressee identifier
#define D7A_ID_LEN(ctrl)                (((ctrl).bf.idf == D7A_ID_VID) ?    D7A_VID_LEN : \
                                        ((ctrl).bf.idf == D7A_ID_UID) ?     D7A_UID_LEN : \
                                        ((ctrl).bf.idf == D7A_ID_NBID) ?    D7A_NBID_LEN : \
                                                                            D7A_NOID_LEN)

/// Length of the DLL identifier
#define D7A_DLL_ID_LEN(ctrl)            (((ctrl).bf.idf == D7A_ID_VID) ?    D7A_VID_LEN : \
                                        ((ctrl).bf.idf == D7A_ID_UID) ?     D7A_UID_LEN : \
                                        ((ctrl).bf.idf == D7A_ID_VOID) ?    D7A_VOID_LEN : \
                                                                            D7A_NOID_LEN)
/// length of the Addressee
#define D7A_ADDR_LEN(ctrl)              (D7A_ID_LEN(ctrl) + sizeof(d7a_addressee_t) - D7A_UID_LEN)

//======================================================================
// Compressed format conversions to use in declarations
//======================================================================

/// Decode e/m
#define D7A_CTF_D(e,m)                  ((1 << (2*(e))) * (m))

/// Encode e/m
#define D7A_CTF_E(e,v)                  ((((e) & 0x7) << 5) | (KAL_DIV_INT((v), D7A_CTF_D(e,1)) & 0x1f))

/// Encode unit to CTF
#define D7A_CTF_ENCODE(v)               (((v) < D7A_CTF_D(0,32)) ? D7A_CTF_E(0,(v)) : \
                                        ((v) < D7A_CTF_D(1,32)) ? D7A_CTF_E(1,(v)) : \
                                        ((v) < D7A_CTF_D(2,32)) ? D7A_CTF_E(2,(v)) : \
                                        ((v) < D7A_CTF_D(3,32)) ? D7A_CTF_E(3,(v)) : \
                                        ((v) < D7A_CTF_D(4,32)) ? D7A_CTF_E(4,(v)) : \
                                        ((v) < D7A_CTF_D(5,32)) ? D7A_CTF_E(5,(v)) : \
                                        ((v) < D7A_CTF_D(6,32)) ? D7A_CTF_E(6,(v)) : \
                                        ((v) < D7A_CTF_D(7,32)) ? D7A_CTF_E(7,(v)) : \
                                        0xff)

/// Decode from CTF to unit
#define D7A_CTF_DECODE(ctf)             D7A_CTF_D((ctf).bf.exp,(ctf).bf.mant)

// =======================================================================
// d7a_addressee_ctrl_t
// -----------------------------------------------------------------------
/// Bitfield structure of the Addressee control byte
// =======================================================================
typedef union
{
    // bit access fields
    struct {
        /// Network security method
        u8 nls      : 4;
        /// ID type
        u8 idf      : 2;
        /// RFU
        u8 rfu_6    : 1;
        u8 rfu_7    : 1;
    } bf;

    // byte access
    u8 byte;

} d7a_addressee_ctrl_t;

// =======================================================================
// d7a_xcl_t
// -----------------------------------------------------------------------
/// Bitfield structure of the Addressee Access Class
// =======================================================================
typedef union
{
    // bit access fields
    struct {
        /// Subclass mask
        u8 m    : 4;
        /// Specifier
        u8 s    : 4;
    } bf;

    // byte access
    u8 byte;

} d7a_xcl_t;

// =======================================================================
// d7a_addressee_t
// -----------------------------------------------------------------------
/// Structure of the D7ATP Addressee byte
// =======================================================================
TYPEDEF_STRUCT_PACKED
{
    d7a_addressee_ctrl_t ctrl;
    d7a_xcl_t xcl;
    u8 id[D7A_UID_LEN];

} d7a_addressee_t;

// =======================================================================
// d7a_ctf_t
// -----------------------------------------------------------------------
/// DLL compressed time format
// =======================================================================
typedef kal_ctf_t d7a_ctf_t;

// =======================================================================
// d7a_ch_header_t
// -----------------------------------------------------------------------
/// Bitfield structure of the channel identifier
// =======================================================================
typedef union
{
    // bit access fields
    struct {
        /// Coding scheme
        u8 cs   : 2;
        /// Channel Class
        u8 cl   : 2;
        /// Channel Band
        u8 band : 3;
        /// Extension 
        u8 ext  : 1;
    } bf;

    // byte access
    u8 byte;

} d7a_ch_header_t;

// =======================================================================
// d7a_resp_t
// -----------------------------------------------------------------------
/// Enumerator of the D7ASP Response types
// =======================================================================
typedef enum
{
    /// No response requested
    D7A_RESP_NO = 0,
    /// Get all responses in response period.
    D7A_RESP_ALL,
    /// Get at least one ACK per request during response period
    D7A_RESP_ANY,
    /// Same as D7A_RESP_ALL, but responders respond only if upper layer payload is available
    /// It is suitable for cases when the smart addressing (queries) is used.
    D7A_RESP_ALL_ON_DATA,
    /// No response requested, repeat the number of times defined in the SEL configuration file
    D7A_RESP_NO_RPT,
    /// Same as D7A_RESP_ANY, but responders respond only if upper layer payload is available
    /// It is suitable for cases when the smart addressing (queries) is used.
    D7A_RESP_ANY_ON_DATA,
    /// Get at least one acknowledgement per request during response period. 
    /// Stick to a single responder when possible
    D7A_RESP_PREFERRED,
    /// Same as D7A_RESP_PREFERRED, but responders respond only if upper layer payload is available
    /// It is suitable for cases when the smart addressing (queries) is used.
    D7A_RESP_PREFERRED_ON_DATA

} d7a_resp_t;

// =======================================================================
// d7a_qos_t
// -----------------------------------------------------------------------
/// Bitfield structure of the D7ASP Quality of Service control byte
// =======================================================================
typedef union
{
    // bit access fields
    struct {
        /// Response mode
        u8 resp         : 3;
        /// Retry mode
        u8 retry        : 3;
        /// RFU
        u8 rfu          : 2;
    } bf;

    // byte access
    u8 byte;

} d7a_qos_t;

// =======================================================================
// d7a_sp_cfg_t
// -----------------------------------------------------------------------
/// Structure of the D7ASP Configuration
// =======================================================================
TYPEDEF_STRUCT_PACKED
{
    /// D7ASP QoS
    d7a_qos_t qos;
    /// Session Start timeout
    d7a_ctf_t to;
    /// Response execution delay
    d7a_ctf_t te;
    /// Addressee
    d7a_addressee_t addressee;

} d7a_sp_cfg_t;

// =======================================================================
// d7a_sp_status_t
// -----------------------------------------------------------------------
/// Bitfield structure of the D7ASP segment status byte
// =======================================================================
typedef union
{
    // bit access fields
    struct {
        /// RFU
        u8 rfu          : 4;
        /// Identifier type of the received segment
        u8 idf          : 2; 
        /// Current seqnum was already received
        u8 retry        : 1;
        /// There are not received seqnums anterior to the current seqnum
        u8 missed       : 1;
    } bf;

    // byte access
    u8 byte;

} d7a_sp_status_t;

// =======================================================================
// d7a_nwl_security_t
// -----------------------------------------------------------------------
/// NWL Security File structure
// =======================================================================
TYPEDEF_STRUCT_PACKED
{
    /// Key counter
    u8 key_counter;
    /// Frame counter
    u32 frame_counter;

} d7a_nwl_security_t;

// =======================================================================
// d7a_sp_res_t
// -----------------------------------------------------------------------
/// D7A specific segment metadata
// =======================================================================
TYPEDEF_STRUCT_PACKED
{
    /// channel header
    d7a_ch_header_t header;    
    /// channel index
    u16 idx;
    /// RSSI in -dBm
    u8  rxlev;
    /// Link budget in dB
    u8  lb;
    /// Signal-to-noise ratio in dB
    s8  snr;
    /// D7ASP status
    d7a_sp_status_t status;
    /// D7ASP Token
    u8  token;
    /// D7ASP Sequence number
    u8  seq;
    /// Response timeout
    u32 resp_to;
    /// Addressee
    d7a_addressee_t addressee;
    /// NLS security state (optional)
    d7a_nwl_security_t nls_state;

} d7a_sp_res_t;

// =======================================================================
// d7a_res_t
// -----------------------------------------------------------------------
/// Aggregate packet reception metadata
// =======================================================================
typedef struct
{
    /// Handle
    u8  id;
    /// End reception date
    u32 date;
    /// frequency offset (frequency error)
    s16 fei;
    /// Size of the result (depends on origin Addresse ID)
    u8  len;
    /// Target RXLEV in -dBm
    u8  target_rxlev;
    /// segment metadata
    d7a_sp_res_t sp;
    
} d7a_res_t;

// =======================================================================
// d7a_error_t
// -----------------------------------------------------------------------
/// Error types enumerator for D7A
// =======================================================================
typedef enum
{
    /// No error
    D7A_ERROR_NO                        =  0,
    /// Resource busy
    D7A_ERROR_BUSY                      = -1,
    /// Bad parameter
    D7A_ERROR_BAD_PARAM                 = -2,
    /// Duty cycle limit overflow
    D7A_ERROR_DUTY_CYCLE                = -3,
    /// CCA timeout
    D7A_ERROR_CCA_TO                    = -4,
    /// Security frame counter overflow
    D7A_ERROR_NLS_KEY                   = -5,
    /// TX stream underflow
    D7A_ERROR_TX_UDF                    = -6,
    /// RX stream overflow
    D7A_ERROR_RX_OVF                    = -7,
    /// RX checksum
    D7A_ERROR_RX_CRC                    = -8,
    /// Abort
    D7A_ERROR_ABORT                     = -9,
    /// No ACK received
    D7A_ERROR_NO_ACK                    = -10,
    /// RX timeout
    D7A_ERROR_RX_TO                     = -11,
    /// Not supported band
    D7A_ERROR_NOT_SUPPORTED_BAND        = -12,
    /// Not supported channel
    D7A_ERROR_NOT_SUPPORTED_CHANNEL     = -13,
    /// Not supported modulation
    D7A_ERROR_NOT_SUPPORTED_MODULATION  = -14,
    /// No channels in list
    D7A_ERROR_VOID_CHANNEL_LIST         = -15,

} d7a_error_t;

// =======================================================================
// d7a_req_status_t
// -----------------------------------------------------------------------
/// D7A session request status
// =======================================================================
typedef union
{
    struct {
        /// Fifo identifier (handle)
        u32 id  : 8;
        /// Tag of the request
        u32 tag : 8;
        /// request flush status
        u32 ok  : 1;
        /// RFU
        u32 rfu : 7;
        /// D7A error 
        u32 err : 8;
    } bf;

    /// word access
    u32 word;

} d7a_req_status_t;

// =======================================================================
// d7a_status_t
// -----------------------------------------------------------------------
/// D7A session procedure status upon termination
// =======================================================================
typedef union
{
    struct
    {
        /// Fifo identifier (handle)
        u32 id  :  8;
        /// Flush status.
        u32 ok  :  1;
        /// RFU 
        u32 rfu : 15;
        /// D7A error 
        u32 err :  8;
    } bf;

    /// word access
    u32 word;

} d7a_status_t;

#endif // __D7A_1X_H__