Exportable version of WizziLab's modem driver.

Dependents:   modem_ref_helper

include/modem_ref.h

Committer:
Jeej
Date:
2019-02-20
Revision:
45:6a4c373e1178
Parent:
44:656cbcc7843b
Child:
50:9eb5eed8b014

File content as of revision 45:6a4c373e1178:

/// @copyright
/// ========================================================================={{{
/// Copyright (c) 2013-2016 WizziLab                                           /
/// All rights reserved                                                        /
/// =========================================================================}}}
/// @endcopyright

//  =======================================================================
/// @file       modem_ref.h
/// @brief      Wizzilab Modem Reference Driver Implementation
///             Source code should be disclosable and easily portable to
///             any architecture.
//  =======================================================================

#ifndef __MODEM_REF_DRV_H__
#define __MODEM_REF_DRV_H__

#include "hal_types.h"

#include "alp_spec.h"
#include "alp_helpers.h"

// Stuff depending on implementation
#ifdef _ARCH_WIZZILAB_
    // Map debug features on Wizzilab's kernel
    #include "kal.h"
    #define L_API           (1 << 1)
    #define L_URC           (1 << 2)
    #define L_SER           (1 << 3)
    #define ASSERT(c,...)   kal_dbg_assert(c, ##__VA_ARGS__)
    #define DPRINT(l,...)   do {kal_dbg_cprintf(TLEV(7,l), ##__VA_ARGS__);} while(0)
    #define MALLOC(s)       kal_malloc(s)
    #define FREE(s)         kal_free(s)
#else
    // TODO Map on host architecture
#endif

// Maximum number of concurrent 'users'
#define MAX_USER_NB     (8)

// Depending on Host needs/capacities, choose variable-size buffer allocation style
#if 1 // Auto stack alloc
    #define MAX_CMD_BUFFER_SIZE             256
    #define ALLOC_BUFFER(_t,_b,_size)       _t _b[MAX_CMD_BUFFER_SIZE];
    //#define ALLOC_BUFFER(_t,_b,_size)     _t _b[_size]; // If VLA available...
    #define DEALLOC_BUFFER(_b)
#else // Dynamic alloc
    #define ALLOC_BUFFER(_t,_b,_size)       _t* _b = MALLOC(_size);
    #define DEALLOC_BUFFER(_b)              FREE(_b);
#endif

//======================================================================
// Modem Serial Link input/output functions
//==================================================================={{{
// ALP protocol is conveyed on serial link encapsulated in WizziCom (WC)
// packets.
// WC Serial protocol:
// +--------------+--------+--------+--------+---- - - - - - - - - - - --------+
// |     SYNC     |   LEN  |   SEQ  | FLOWID |             PAYLOAD             |
// +--------------+--------+--------+--------+---- - - - - - - - - - - --------+
// |    2 bytes   | 1 byte | 1 byte | 1 byte |            LEN bytes            |
// |<------------>|<------>|<------>|<------>|<--- - - - - - - - - - - ------->|
#define WC_SYNC_BYTE_0          0x01
#define WC_SYNC_BYTE_1          0x1F
#define WC_HEADER_SIZE          5

#define WC_SYNC0_OFFSET         0
#define WC_SYNC1_OFFSET         1
#define WC_LEN_OFFSET           2
#define WC_SEQ_OFFSET           3
#define WC_FLOWID_OFFSET        4

// =======================================================================
// wm_cfg_t
// -----------------------------------------------------------------------
/// Modem Configuration
// ===================================================================={{{
TYPEDEF_STRUCT_PACKED
{
    /// Automatic openning of D7A stack
    u8  autostart_d7a;
    /// Automatic 'Join' of LoRaWAN stack
    u8  autostart_lwan;
    /// Automatic procedure start time (sec)
    u16 autostart_delay_s;
    /// Debug COM port number (N/A:KAL_COM_NULL)
    u8  dbg_com;
} wm_cfg_t;
//}}}

// Input:Serial-traffic coming from Modem must be packetized in WC chuncks
// before being sent to modem-driver through 'modem_input'.
// An example deserializer can be found in "wc_deserialized.c".
//======================================================================
// modem_input
//----------------------------------------------------------------------
/// @brief  Parse packets and handles calls to relevant callbacks.
/// @param  flowid      : WizziCom FlowID.
/// @param  payload     : pointer to payload buffer.
/// @param  size        : payload size in bytes.
//======================================================================
protected void modem_input(u8 flowid,u8* payload,u8 size);

// Output:Modem-driver sends data to Modem through calls to the 'send'
// function passed in 'modem_open'.
// 'send' must be provided by the host application.
//======================================================================
// fx_serial_send_t
//----------------------------------------------------------------------
/// @brief  Send concatenation of 2 buffers of given size over serial link.
/// @param  buffer1     : Pointer to the 1st data buffer to be sent
/// @param  size1       : Size in bytes of the 1st buffer to be sent
/// @param  buffer2     : Pointer to the 2nd data buffer to be sent
/// @param  size2       : Size in bytes of the 2nd buffer to be sent
/// @return               number of bytes sent.
/// @note                 either buffers can be of size zero.
/// @note                 buffer1 is used for WC header
/// @note                 buffer2 is used actual payload
//======================================================================
typedef int  (fx_serial_send_t)     (u8* buffer1, u8 size1,u8* buffer2, u8 size2);

//======================Low-Level-API================================}}}

//======================================================================
// High-level API that must be provided by the host application
//==================================================================={{{

//======================================================================
// fx_read_t
//----------------------------------------------------------------------
/// @brief  Called when ALP-Read is requested by the modem.
///         Function must perform required actions to fullfil the request
///         then should call 'respond_read' (or 'respond' in case of error)
/// @param  fid         : File ID
/// @param  offset      : Access Offset in bytes
/// @param  length      : Access Size in bytes
/// @param  id          : ID of the request
//======================================================================
typedef void (fx_read_t)            (u8 fid,u32 offset,u32 length, int id);

//======================================================================
// fx_write_t
//----------------------------------------------------------------------
/// @brief  Called when ALP-Write is requested by the modem.
///         Function must perform required actions to fullfil the request
///         then should call 'respond'
/// @param  fid         : File ID
/// @param  data        : Pointer to the destination data buffer
/// @param  offset      : Access Offset in bytes
/// @param  length      : Access Size in bytes
/// @param  id          : ID of the request
//======================================================================
typedef void (fx_write_t)           (u8 fid,void *data,u32 offset,u32 length, int id);

//======================================================================
// fx_read_fprop_t
//----------------------------------------------------------------------
/// @brief  Called when ALP-Read-file-properties is requested by the modem.
///         Function must perform required actions to fullfil the request
///         then should call 'respond_fprop' (or 'respond' in case of error)
/// @param  fid         : File ID
/// @param  id          : ID of the request
//======================================================================
typedef void (fx_read_fprop_t)      (u8 fid, int id);

//======================================================================
// fx_flush_t
//----------------------------------------------------------------------
/// @brief  Called when ALP-Flush is requested by the modem.
///         Function must perform required actions to fullfil the request
///         then should call 'respond'
/// @param  fid         : File ID
/// @param  id          : ID of the request
//======================================================================
typedef void (fx_flush_t)           (u8 fid, int id);

//======================================================================
// fx_delete_t
//----------------------------------------------------------------------
/// @brief  Called when ALP-Delete is requested by the modem.
///         Function must perform required actions to fullfil the request
///         then should call 'respond'
/// @param  fid         : File ID
/// @param  id          : ID of the request
//======================================================================
typedef void (fx_delete_t)          (u8 fid, int id);

//======================================================================
// fx_udata_t
//----------------------------------------------------------------------
/// @brief  Called when Unsollicited Data is received by the Modem (i.e.
///         peer notifications etc).
/// @param  data        : Pointer to the data buffer
/// @param  length      : Data Size in bytes
//======================================================================
typedef void (fx_udata_t)           (void *data, u32 length);

//======================================================================
// fx_lqual_t
//----------------------------------------------------------------------
/// @brief  Called when LQUAL URC is generated by the modem.
///         LQUAL URC is setup by the user through 'modem_enable_urc'.
///         LQUAL gives percentage of successfully sent packets on a
///         particular interface (IFID).
/// @param  ifid        : Interface File ID from which LQUAL is issued
/// @param  per         : Packet Error Rate in %
//======================================================================
typedef void (fx_lqual_t)           (u8 ifid, int per);

//======================================================================
// fx_ldown_t
//----------------------------------------------------------------------
/// @brief  Called when LDOWN URC is generated by the modem.
///         LDOWN URC is setup by the user through 'modem_enable_urc'
///         LDOWN is generated for a particular interface (IFID) after
///         a (configurable) number of consecutive transmission have failed.
/// @param  ifid        : Interface File ID from which LDOWN is issued
//======================================================================
typedef void (fx_ldown_t)           (u8 ifid);

//======================================================================
// fx_reset_t
//----------------------------------------------------------------------
/// @brief  Called when RESET URC is generated by the modem.
///         LDOWN URC is setup by the user through 'modem_enable_urc'
/// @param  ifid        : Interface File ID from which LDOWN is issued
//======================================================================
typedef void (fx_reset_t)           (void);

//======================================================================
// fx_boot_t
//----------------------------------------------------------------------
/// @brief  Called when BOOT URC is generated by the modem.
/// @param  cause       : Cause of the boot 'H':Pin/Hardware reset
///                                         'P':POR reset
///                                         'S':Software reset
///                                         'L':Low-power reset
///                                         'W':Watchdog reset
/// @param  nb_boot     : Number of boots since last POR
//======================================================================
typedef void (fx_boot_t)            (u8 cause, u16 nb_boot);

//======================================================================
// fx_busy_t
//----------------------------------------------------------------------
/// @brief  Called when BUSY URC is generated by the modem.
/// @param  busy       : 0 if not busy, else busy
//======================================================================
typedef void (fx_busy_t)            (u8 busy);

//======================================================================
// fx_itf_busy_t
//----------------------------------------------------------------------
/// @brief  Called when BUSY URC is generated by the modem.
/// @param  ifid       : interface file id
/// @param  busy       : busy time in seconds
//======================================================================
typedef void (fx_itf_busy_t)        (u8 ifid, u32 busy);

// Set of functions passed together at modem openning
typedef struct {
    // ALP File 'Action' callbacks
    fx_read_t*          read;
    fx_write_t*         write;
    fx_read_fprop_t*    read_fprop;
    fx_flush_t*         flush;
    fx_delete_t*        remove;
    // 'URC' callbacks
    fx_udata_t*         udata;
    fx_lqual_t*         lqual;
    fx_ldown_t*         ldown;
    fx_reset_t*         reset;
    fx_boot_t*          boot;
    fx_busy_t*          busy;
    fx_itf_busy_t*      itf_busy;
} modem_callbacks_t;
//======================High-Level-API===============================}}}

//======================================================================
// action_callback_t
//----------------------------------------------------------------------
/// @brief  Type of function called on response(s) generated by an
///         'action' function. Different functions of this kind can be
///         associated to different IDs through 'get_id'.
///         'Action' function are subsequently called with relevant ID.
/// @param  terminal    : '1' at the last call for this ID, '0' otherwise
/// @param  err         : ALP Error code
/// @param  id          : ID of the request
//======================================================================
typedef void (action_callback_t)  (u8 terminal, s8 err, u8 id);

//======================================================================
// modem_open
//----------------------------------------------------------------------
/// @brief  Open Wizzilab Modem Driver
/// @param  send        : User function implementing serial output.
/// @param  callbacks   : Set of functions called by the driver upon
///                       reception of commands
/// @return 0
//======================================================================
public void modem_open(fx_serial_send_t* send,modem_callbacks_t* callbacks);
public void modem_close(void);

//======================================================================
// modem_get_id
//----------------------------------------------------------------------
/// @brief  Request an ID to perform modem operations
/// @param  cb          : Function called on responses generated for
///                       this ID.
/// @return Positive ID value, -1 if no more IDs available.
//======================================================================
public int modem_get_id(action_callback_t* cb);

//======================================================================
// modem_free_id
//----------------------------------------------------------------------
/// @brief  Release an ID
/// @param  id          : ID to release.
/// @return ID value, -1 if ID was not in use.
//======================================================================
public int modem_free_id(u8 id);

//======================================================================
// "Action" functions performing requests to the modem
//==================================================================={{{

//======================================================================
// modem_read_file
//----------------------------------------------------------------------
/// @brief  Read a file on Modem
/// @param  fid         : File ID
/// @param  data        : Pointer to the destination data buffer
/// @param  offset      : Access Offset in bytes
/// @param  length      : Access Size in bytes
/// @param  id          : User ID
//======================================================================
public void modem_read_file(u8 fid, void *data, u32 offset, u32 length, u8 id);

//======================================================================
// modem_read_fprop
//----------------------------------------------------------------------
/// @brief  Read a file-properties on Modem
/// @param  fid         : File ID
/// @param  data        : Pointer to the destination data buffer
/// @param  id          : User ID
//======================================================================
public void modem_read_fprop(u8 fid, alp_file_header_t* data, u8 id);

//======================================================================
// modem_read_fprop
//----------------------------------------------------------------------
/// @brief  Read a file-properties on Modem with ROOT privileges
/// @param  fid         : File ID
/// @param  data        : Pointer to the destination data buffer
/// @param  root_key    : Pointer to the ROOT key
/// @param  id          : User ID
//======================================================================
public void modem_read_fprop_root(u8 fid, alp_file_header_t* data, u8* root_key, u8 id);

//======================================================================
// modem_write_fprop
//----------------------------------------------------------------------
/// @brief  Write a file-properties on Modem
/// @param  fid         : File ID
/// @param  data        : Pointer to the header data
/// @param  id          : User ID
//======================================================================
public void modem_write_fprop(u8 fid, alp_file_header_t* data, u8 id);

//======================================================================
// modem_write_fprop_root
//----------------------------------------------------------------------
/// @brief  Write a file-properties on Modem with ROOT privileges
/// @param  fid         : File ID
/// @param  data        : Pointer to the header data
/// @param  root_key    : Pointer to the ROOT key
/// @param  id          : User ID
//======================================================================
public void modem_write_fprop_root(u8 fid, alp_file_header_t* data, u8* root_key, u8 id);

//======================================================================
// modem_write_file
//----------------------------------------------------------------------
/// @brief  Write a file on Modem
/// @note   Writing can trigger a 'notification' depending on file properties.
/// @param  fid         : File ID
/// @param  data        : Pointer to the source data buffer
/// @param  offset      : Access Offset in bytes
/// @param  length      : Access Size in bytes
/// @param  id          : User ID
//======================================================================
public void modem_write_file(u8 fid, void *data, u32 offset, u32 length, u8 id);

//======================================================================
// modem_write_file_root
//----------------------------------------------------------------------
/// @brief  Write a file on Modem with ROOT privileges
/// @note   Writing can trigger a 'notification' depending on file properties.
/// @param  fid         : File ID
/// @param  data        : Pointer to the source data buffer
/// @param  offset      : Access Offset in bytes
/// @param  length      : Access Size in bytes
/// @param  root_key    : Pointer to the ROOT key
/// @param  id          : User ID
//======================================================================
public void modem_write_file_root(u8 fid, void *data, u32 offset, u32 length, u8* root_key, u8 id);

//======================================================================
// modem_flush_file
//----------------------------------------------------------------------
/// @brief  Flush a file on Modem
/// @param  fid         : File ID
/// @param  id          : User ID
//======================================================================
public void modem_flush_file(u8 fid, u8 id);

//======================================================================
// modem_write_file_root
//----------------------------------------------------------------------
/// @brief  Flush a file on Modem with ROOT privileges
/// @param  fid         : File ID
/// @param  root_key    : Pointer to the ROOT key
/// @param  id          : User ID
//======================================================================
public void modem_flush_file_root(u8 fid, u8* root_key, u8 id);

//======================================================================
// modem_declare_file
//----------------------------------------------------------------------
/// @brief  Declare a local file to the Modem. Once declared, the file
///         becomes virtually part of Modem's file-system and can:
///         - be remotely accessed (depending on its permissions)
///         - be "Notified" through notify_file use
/// @note   The file must exist locally.
/// @note   Modem will access the file when needed using ALP commands.
/// @param  fid         : File ID
/// @param  hdr         : ALP File Header.
/// @param  local       : File is local.
/// @param  id          : User ID
//======================================================================
public void modem_declare_file(u8 fid, alp_file_header_t* hdr, u8 local, u8 id);

//======================================================================
// modem_create_file
//----------------------------------------------------------------------
/// @brief  Creates a file on the Modem.
/// @param  fid         : File ID
/// @param  hdr         : ALP File Header.
/// @param  id          : User ID
//======================================================================
public void modem_create_file(u8 fid, alp_file_header_t* hdr, u8 id);

//======================================================================
// modem_delete_file
//----------------------------------------------------------------------
/// @brief  Deletes a file on the Modem.
/// @param  fid         : File ID
/// @param  id          : User ID
//======================================================================
public void modem_delete_file(u8 fid, u8 id);

public void modem_delete_file_root(u8 fid, u8* root_key, u8 id);

//======================================================================
// modem_notify_file
//----------------------------------------------------------------------
/// @brief  "Notify" a local file using its D7AActP properties.
/// @note   The file must exist locally and must have been 'declared'.
/// @param  fid         : File ID
/// @param  offset      : Access Offset in bytes
/// @param  length      : Access Size in bytes
/// @param  id          : User ID
//======================================================================
public void modem_notify_file(u8 fid, u32 offset, u32 length, u8 id);

//======================================================================
// modem_alp_raw
//----------------------------------------------------------------------
/// @brief  Execute specific ALP payload on Modem.
/// @param  payload     : pointer to ALP Payload to be executed on Modem
/// @param  length      : ALP Payload size
/// @param  id          : User ID
//======================================================================
public void modem_send_raw_alp(u8* payload, u32 length, u8 id);

public void modem_send_file_content(u8* itf, u8 itf_length, void *istatus, u8 fid, void *data,u32 offset,u32 length, u8 id);

public void modem_remote_read_file(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8 id);

public void modem_remote_write_file(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8 id);

public void modem_remote_write_file_root(u8* itf, u8 itf_length, void *istatus , u8 fid, void *data, u32 offset, u32 length, u8* root_key, u8 id);

public void modem_enable_urc(u8 type, u8 ifid, u8 val, u8 enable, u8 id);

public void modem_activate_itf(u8 type, u8 nb_dev, u8 ifid, u8 flags, u8 enable, u8 id);

//==========================Action===================================}}}

//======================================================================
// "Response" functions to be called-back on requests from the modem
//==================================================================={{{
public void modem_respond(s8 status, int id);
public void modem_respond_fprop(u8 fid, u8* hdr, int id);
public void modem_respond_read(u8 fid,void *data,u32 offset,u32 length, int id);
//==========================Response=================================}}}


//=======================================================================
// Modem File IDs are mapped from 64 to 127
// These files are mandatory when building an application that
// uses Wizzilab's D7A Stack, so it will be included in all "Modem"
// applications.
//=======================================================================
// Modem Config/Status
#define FID_WM_REV                        2 // Match D7A one.
#define FID_HOST_REV                     65
#define FID_WM_SCRATCH                   66
#define FID_WM_STATUS                    67
#define FID_WM_CFG                       68
#define FID_WM_HWCFG                     69
#define FID_WM_CTRL                      70
#define FID_WM_LED_CFG                   71
#define FID_WM_DEBUG                     72
#define FID_WM_POWER_STATUS              73 // For GW power supervisor reporting

// LORAWAN "ITFs"
#define FID_LWAN_ITF0                    98
#define FID_LWAN_ITF1                    99

// Action files
#define FID_ACTP_RPT_FULL               100
#define FID_ACTP_RPT_PART               101

// Reserved 
#define FID_RESERVED_102                102
#define FID_RESERVED_103                103
#define FID_RESERVED_104                104
#define FID_RESERVED_105                105
#define FID_RESERVED_106                106
#define FID_RESERVED_107                107

// Interface files
#define IFID_ONESHOT_HOST               108
#define IFID_ONESHOT_ACTP               109
#define IFID_REPORT                     110
#define IFID_ITF3                       111
#define IFID_ITF4                       112
#define IFID_BLINKER                    113

// Reserved 
#define FID_RESERVED_114                114 
#define FID_RESERVED_115                115 
#define FID_RESERVED_116                116 
#define FID_RESERVED_117                117 
#define FID_RESERVED_118                118 
#define FID_RESERVED_119                119 
#define FID_RESERVED_120                120 
#define FID_RESERVED_121                121 
#define FID_RESERVED_122                122 
#define FID_RESERVED_123                123 

// Modem Security protocols
#define FID_WM_CHALLENGE                124

// Modem CUP
#define FID_CUP_CFG_BCAST               125
#define FID_CUP_CFG                     126
#define FID_CUP_CODE                    127

// HST CUP
#define FID_APP_CUP_CFG_BCAST           252
#define FID_APP_CUP_CFG                 253
#define FID_APP_CUP_CODE                254

#endif

// vim:fdm=marker:fdc=2