Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

include/d7a.h

Committer:
Jeej
Date:
2016-10-26
Revision:
68:d2778c6abf1a
Parent:
67:9ac9d109b80a
Child:
71:f03727ff0f99

File content as of revision 68:d2778c6abf1a:

#ifndef _D7A_H_
#define _D7A_H_

#include "rtos.h"
#include "d7a_common.h"

//======================================================================
// Defines
//======================================================================

#define D7A_UID_LEN     (8)

#define D7A_XCL_ENDPOINT_NO    (0x01) // Normal rate
#define D7A_XCL_GATEWAY_NO     (0x21) // Normal Rate

#define D7A_XCL_ENDPOINT_LO    (0x11) // Low rate
#define D7A_XCL_GATEWAY_LO     (0x31) // Low Rate

#define D7A_XCL_ENDPOINT_HI    (0x41) // High rate
#define D7A_XCL_GATEWAY_HI     (0x51) // High Rate

#define D7A_CTF_VAL(mant,exp)   ((uint8_t)(mant|(exp<<5)))

#define D7A_NBID(nbid)          (nbid >= 32)? D7A_CTF_VAL(8,1) : D7A_CTF_VAL(nbid,0)

#define D7A_ROOT_KEY_SIZE       (8) // 16 bytes max


//======================================================================
// Enums
//======================================================================

//======================================================================
// d7a_fs_storage_t
//----------------------------------------------------------------------
/// File "Storage Class"
//======================================================================
typedef enum {
    /// No data is keeped. Write only!
    /// Ex: Use for commands.
    TRANSIENT = 0,
    /// Data is stocked in RAM and initialized at 0.
    /// Can not guarantee data integrity over time.
    /// Ex: Use for often updated data.
    VOLATILE,
    /// Data is stocked in RAM and initialized with the last flushed data from EEPROM.
    /// Can not guarantee data integrity over time.
    /// Ex: Use for temporary configurations.
    RESTORABLE,
    /// Data is stoked in EEPROM.
    /// Data integrity is guaranteed.
    /// Ex: Use for important configurations.
    /// /!\ Use sparingly as operations on these type of files are time and ressource consuming
    PERMANENT
} d7a_fs_storage_t;

//======================================================================
// d7a_fs_perm_t
//----------------------------------------------------------------------
/// File permissions for USER/GUEST
//======================================================================
typedef enum {
    O_O                = 0b11000000,
    R_O                = 0b11100000,
    R_R                = 0b11100100,
    W_O                = 0b11010000,
    W_W                = 0b11010010,
    RW_O               = 0b11110000,
    RW_R               = 0b11110100,
    RW_W               = 0b11110010,
    RW_RW              = 0b11110110,
    RWX_O              = 0b11111000,
    RWX_RWX            = 0b11111111,
} d7a_fs_perm_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-64 and Encryption with Counter Mode
    D7A_NLS_AES_CCM_64,
    /// Authentication with CBC-MAC-32 and Encryption with Counter Mode
    D7A_NLS_AES_CCM_32,
    /// QTY
    D7A_NLS_QTY

} d7a_nls_t;


// Mimic ALP Errors
typedef enum
{
    D7A_ERR_ITF_FULL                    =  2, // 0x02: For interfaces supporting buffering, indicates buffer reached maximum capacity (no data loss)
    D7A_ERR_PARTIAL_COMPLETION          =  1, // 0x01: Action received and partially completed at response.  To be completed after response

    D7A_ERR_NONE                        =  0, // 0x00: Action completed (OK)
    D7A_ERR_FILE_NOT_FOUND              = -1, // 0xFF: Error access file: File ID does not exist
    D7A_ERR_FILE_EXIST                  = -2, // 0xFE: Error create file: File ID already exists
    D7A_ERR_FILE_NOT_RESTORABLE         = -3, // 0xFD: Error restore file: File is not restorable
    D7A_ERR_PERMISSION_DENIED           = -4, // 0xFC: Error access file: Insufficient permissions
    D7A_ERR_LENGTH_OVERFLOW             = -5, // 0xFB: Error create file: Supplied length (in header) is beyond file limits
    D7A_ERR_ALLOC_OVERFLOW              = -6, // 0xFA: Error create file: Supplied allocation (in header) is beyond file limits
    D7A_ERR_OFFSET_OVERFLOW             = -7, // 0xF9: Error write: Supplied start offset is out of bounds of file allocation
    D7A_ERR_WRITE_OVERFLOW              = -8, // 0xF8: Error complete write: Supplied data goes beyond file allocation
    D7A_ERR_WRITE_ERROR                 = -9, // 0xF7: Error write: impossible to write in storage location
    D7A_ERR_OPERATION_UNKNOWN           = -10,// 0xF6: Error unknown Operation
    D7A_ERR_OPERAND_INCOMPLETE          = -11,// 0xF5: Error incomplete Operand
    D7A_ERR_OPERAND_WRONG_FORMAT        = -12,// 0xF4: Error wrong Operand format
    D7A_ERR_ITF_INVALID                 = -13,// 0xF3: Error invalid interface
    D7A_ERR_ITF_OVERFLOW                = -14,// 0xF2: Error interface overflown (i.e. ressources exhausted, buffer full with data discarded)
    D7A_ERR_QUERY_FAIL                  = -15,// 0xF1: (Group of) Query result was false (Informative error code).

    D7A_ERR_UNKNOWN                     = -128,// 0x80: Unknown error
    D7A_ERR_FS_TIMEOUT                  ,// 0x81: Internal FS Error
    D7A_ERR_ITF_UNKNOWN                 ,// 0x82: Unknown Interface
    
    // Modem errors
    D7A_ERR_NOT_READY                   ,// The modem is not ready to recieve commands
    D7A_ERR_COM_LINK                    ,// A serial link timeout occured
    D7A_ERR_ILLEGAL_FID                 ,// The FID specified is illegal
    D7A_ERR_ILLEGAL_FILE_DEF            ,// The FILE parameters specified are illegal
    D7A_ERR_CMD_TO                      ,// The command expired
    D7A_ERR_TX_FAILED                   ,// Transmission failed
    D7A_ERR_STATE                       ,// The device is not in the right state to execute the command
    
} d7a_errors_t;


/// Types of retry policies
/// Respond: When finished the host will be notified
/// Persist: When finished on error data is kept in the queue for next transmission
/// Depth:   Number of commands kept in the queue
/// Bulk:    Notifications sent only when the queue is full
/// Retries: Number of retries after initial transmission
/// Slot:    Time between retries (sec)
typedef enum {
    /// Respond: true
    /// Persist: false
    /// Depth:   1
    /// Bulk:    false
    /// Retries: 0
    /// Slot:    0
    ALP_RPOL_ONESHOT         = 0,
    /// Respond: true
    /// Persist: false
    /// Depth:   1
    /// Bulk:    false
    /// Retries: 3
    /// Slot:    2
    ALP_RPOL_SINGLE          = 1,
    /// Respond: true
    /// Persist: false
    /// Depth:   1
    /// Bulk:    false
    /// Retries: 3
    /// Slot:    2
    ALP_RPOL_REPORT          = 2,
    /// Respond: false
    /// Persist: true
    /// Depth:   4
    /// Bulk:    false
    /// Retries: 16
    /// Slot:    20
    ALP_RPOL_REPORT_CHECKED  = 3,
    /// Respond: true
    /// Persist: false
    /// Depth:   4
    /// Bulk:    true
    /// Retries: 0
    /// Slot:    1
    ALP_RPOL_BULK            = 4,
    /// Respond: false
    /// Persist: false
    /// Depth:   1
    /// Bulk:    false
    /// Retries: 0
    /// Slot:    1
    ALP_RPOL_BLINK           = 5,
    
    //ALP_RPOL_SPARE_2         = 6,
    //ALP_RPOL_SPARE_3         = 7,
} alp_rpol_t;

/// Action when file notifying
typedef enum {
    D7A_ACTION_NONE = 0,
    /// Notify the whole file
    D7A_NOTIFICATION_FULL = 100,
    /// Notify only part of the file
    D7A_NOTIFICATION_PART
} d7a_action_t;


// =======================================================================
// d7a_id_t
// -----------------------------------------------------------------------
// Identifier types enumerator
// =======================================================================
typedef enum
{
    // 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;

//======================================================================
// Structures
//======================================================================

//======================================================================
// d7a_com_config_t
//----------------------------------------------------------------------
/// Com port configuration structure
//======================================================================
typedef struct {
     /// Tx pin
     PinName tx;
     /// RX pin
     PinName rx;
     /// WKUP pin
     PinName rts;
     /// HST_WKUP pin
     PinName cts;
     /// Size of RX buffer
     uint16_t rx_buffer_size;
} d7a_com_config_t;

TYPEDEF_STRUCT_PACKED {
    uint8_t fid;
    uint32_t length;
    uint32_t offset;
    uint8_t buf[1];
} d7a_data_t;

// =======================================================================
// d7a_msg_t
// -----------------------------------------------------------------------
/// Response data and meta-data from a device
// =======================================================================
typedef struct
{
    /// Error code
    int8_t err;
    /// Responder's UID
    uint8_t id[D7A_UID_LEN];
    /// Transmission Link Budget
    int8_t lb;
    /// Transmission RSSI
    int8_t rxlev;
    /// Potential data
    d7a_data_t* data;
} d7a_msg_t;


typedef uint32_t (*WriteFileFunction)(  const uint8_t file_id,
                                        const uint16_t offset,
                                        const uint16_t size,
                                        const uint8_t* const content);
                                            
typedef uint32_t (*ReadFileFunction)(   const uint8_t file_id,
                                        const uint16_t offset,
                                        const uint16_t size,
                                        uint8_t* buf);

typedef void (*NotifDoneFunction)(      const uint8_t file_id,
                                        const uint8_t error);
                                        
typedef void (*UnsolicitedMsgFunction)( d7a_msg_t** msg);

//======================================================================
// d7a_fs_callbacks_t
//----------------------------------------------------------------------
/// File system callbacks
//======================================================================
typedef struct {
    /// Write in local file
    WriteFileFunction   write_file;
    /// Read from local file
    ReadFileFunction    read_file;
    /// Is called when the notification is finished (depending on the retry policy)
    NotifDoneFunction   notif_done;
    /// This function is called when an unsolicited message is catched
    UnsolicitedMsgFunction unsolicited_msg;
} d7a_callbacks_t;

//======================================================================
// fw_version_t
//----------------------------------------------------------------------
/// Firmware version Structure
/// Used within the revision structure
//======================================================================
TYPEDEF_STRUCT_PACKED
{
    /// Software identifier
    uint8_t  id;
    /// Version major
    uint8_t  major;
    /// Version minor
    uint8_t  minor;
    /// Version patch
    uint16_t patch;
    /// Version hash
    uint32_t hash;
} fw_version_t;

//======================================================================
// d7a_revision_t
//----------------------------------------------------------------------
/// Revision Structure
///
/// Usage within D7B server:
/// An XML describing the File system of a device is associated to a
/// couple manufacturer_id/device_id (==Device).
/// Different versions of the Device's XML can exist and can be mapped
/// according to fw_version id/major/minor
//======================================================================
TYPEDEF_STRUCT_PACKED
{
    /// Manufacturer ID: provided by Wizzilab
    uint32_t manufacturer_id;
    /// Device ID: Arbitrary number, at user/customer choice
    uint32_t device_id;
    /// Hardware Board ID:
    uint32_t hw_version;
    /// Firmware Version: made of
    ///  - major,minor and patch indexes : comes from versioning tool
    ///  - fw_id : "build-flavour" : comes from build setup
    ///  FW_ID | MAJOR | MINOR | PATCH | HASH |
    ///    1B  |  1B   |  1B   |   2B  |  4B  |
    fw_version_t fw_version;
    /// "file-system" signature XXX: to be worked out
    uint32_t fs_crc;
} d7a_revision_t;


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

    /// byte access
    uint8_t byte;

} d7a_addressee_ctrl_t;

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

    /// byte access
    uint8_t byte;

} d7a_xcl_t;

// =======================================================================
// d7a_addressee_t
// -----------------------------------------------------------------------
/// Structure of the D7ATP Addressee byte
// =======================================================================
TYPEDEF_STRUCT_PACKED
{
    /// Addressee control byte
    d7a_addressee_ctrl_t ctrl;
    /// Access Class
    d7a_xcl_t xcl;
    /// UID
    uint8_t id[D7A_UID_LEN];

} d7a_addressee_t;


//======================================================================
// Prototypes
//======================================================================

//======================================================================
// d7a_open
//----------------------------------------------------------------------
/// @brief                      Open D7A driver and start the modem
/// @param com_config           Com port configuration structure
/// @param reset_pin            Reset pin
/// @param callbacks            File system callbacks (You cannot use local files if this is not specified)
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_open(const d7a_com_config_t* com_config, 
                      PinName reset_pin, 
                      const d7a_callbacks_t* callbacks);

//======================================================================
// d7a_close
//----------------------------------------------------------------------
/// @brief                      Close D7A driver and stop the modem
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_close(void);

//======================================================================
// d7a_start
//----------------------------------------------------------------------
/// @brief                      Start the modem
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_start(void);

//======================================================================
// d7a_stop
//----------------------------------------------------------------------
/// @brief                      Stop the modem (goes to low power)
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_stop(void);

//======================================================================
// d7a_create
//----------------------------------------------------------------------
/// @brief                      Creates a file on the modem
/// @param file_id              ID of the file to create
/// @param prop                 Type of file
/// @param perm                 Access permissions
/// @param size                 Length of the created file
/// @param alloc                Maximum size of the file
/// @param action               Type of action to trigger
/// @param retry                Index to the retry policy to use when notifying
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_create(const uint8_t file_id,
                        d7a_fs_storage_t prop,
                        d7a_fs_perm_t perm, 
                        uint32_t size, 
                        uint32_t alloc, 
                        d7a_action_t action = D7A_ACTION_NONE, 
                        alp_rpol_t retry = ALP_RPOL_ONESHOT);

//======================================================================
// d7a_declare
//----------------------------------------------------------------------
/// @brief                      Declare a file stored on the host to the modem (need to have implemented the fs_callbacks)
/// @param file_id              ID of the file to declare
/// @param prop                 Type of file
/// @param perm                 Access permissions
/// @param size                 Length of the created file
/// @param alloc                Maximum size of the file
/// @param action               Type of action to trigger
/// @param retry                Index to the retry policy to use when notifying
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_declare(const uint8_t file_id, 
                         d7a_fs_storage_t prop, 
                         d7a_fs_perm_t perm, 
                         uint32_t size, 
                         uint32_t alloc, 
                         d7a_action_t action = D7A_ACTION_NONE, 
                         alp_rpol_t retry = ALP_RPOL_ONESHOT);

//======================================================================
// d7a_read
//----------------------------------------------------------------------
/// @brief                      Read data from a file
/// @param file_id              File ID of file to read
/// @param offset               Offset from which to start reading
/// @param size                 Size of data to read
/// @param buf                  Buffer to retrieve data
/// @param addressee            Addressee to an eventual distant device
/// @param retry                Index to the retry policy to use
/// @return d7a_errors_t        Error code
//======================================================================
d7a_msg_t** d7a_read(const uint8_t file_id, 
                      const uint32_t offset, 
                      const uint32_t size,
                      const uint8_t* root_key = NULL,
                      d7a_addressee_t* addressee = NULL, 
                      alp_rpol_t retry = ALP_RPOL_ONESHOT);

//======================================================================
// d7a_write
//----------------------------------------------------------------------
/// @brief                      Write data to a file
/// @param file_id              File ID of file to write
/// @param offset               Offset from which to start reading
/// @param size                 Size of data to read
/// @param buf                  Buffer to retrieve data
/// @param addressee            Addressee to an eventual distant device
/// @param retry                Index to the retry policy to use
/// @param resp                 Wait to see if write is OK
/// @return d7a_errors_t        Error code
//======================================================================
d7a_msg_t** d7a_write(const uint8_t file_id,
                       const uint32_t offset,
                       const uint32_t size,
                       const uint8_t* const buf,
                       const uint8_t* root_key = NULL,
                       d7a_addressee_t* addressee = NULL, 
                       alp_rpol_t retry = ALP_RPOL_ONESHOT, 
                       bool resp = true);

d7a_msg_t** d7a_flush(const uint8_t file_id,
                        const uint8_t* root_key = NULL,
                        d7a_addressee_t* addressee = NULL,
                        alp_rpol_t retry = ALP_RPOL_ONESHOT,
                        bool resp = true);

//======================================================================
// d7a_notify
//----------------------------------------------------------------------
/// @brief                      Write data to a file
/// @param file_id              File ID of file to write
/// @param offset               Offset from which to start writing
/// @param size                 Size of data to write
/// @return d7a_errors_t        Error code
//======================================================================
d7a_errors_t d7a_notify(const uint8_t file_id, 
                        const uint32_t offset = 0, 
                        const uint32_t size = 0);

//======================================================================
// d7a_free_msg
//----------------------------------------------------------------------
/// @brief                      Free the message
/// @param msg                  message to free
//======================================================================
void d7a_free_msg(d7a_msg_t** msg);

//======================================================================
// d7a_print_msg
//----------------------------------------------------------------------
/// @brief                      Prints the message
/// @param msg                  message to print
//======================================================================
void d7a_print_msg(d7a_msg_t** msg);

//======================================================================
// d7a_modem_print_infos
//----------------------------------------------------------------------
/// @brief                      Prints the modem infos
//======================================================================
void d7a_modem_print_infos(void);

//======================================================================
// d7a_modem_print_infos
//----------------------------------------------------------------------
/// @brief                      Wait for modem to finish boot
//======================================================================
d7a_errors_t d7a_wait_ready(uint32_t millisec = osWaitForever);


#endif // _D7A_H_