/*
 * oc_emaLink_at.h
 *
 * Created: 6/24/2019 11:50:06 AM
 *
 * oc_emaLink_at.c
 *
 * Created: 6/24/2019 11:49:48 AM
 * 
 *  ######################################################################################################
 *  DISCLAIMER:
 *  OptConnect Management, LLC provides this documentation in support of its products for the internal use
 *  of its current and prospective customers. The publication of this document does not create any other
 *  right or license in any party to use any content contained in or referred to in this document and any
 *  modification or redistribution of this document is not permitted. While efforts are made to ensure
 *  accuracy, typographical and other errors may exist in this document. OptConnect Management, LLC reserves
 *  the right to modify or discontinue its products and to modify this and any other product documentation
 *  at any time.
 * 
 *  All OptConnect products are sold subject to its published Terms and Conditions and subject to any
 *  separate terms agreed with its customers. No warranty of any type is extended by publication of this
 *  documentation, including, but not limited to, implied warranties of merchantability, fitness for a
 *  particular purpose and non-infringement.
 * 
 *  OptConnect is a trademark, and OptConnect ema is a trademark, of OptConnect Management, LLC. All
 *  trademarks, service marks and similar designations referenced in this document are the property of
 *  their respective owners
 *  #######################################################################################################
 * 
 *  version: 1.0
 * 
 *  History:
 *  Version     Description                                     Date
 *  1.0         Initial Release                                 5/19/2020
 */ 

#ifndef OC_EMALINK_AT_H_
#define OC_EMALINK_AT_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*############ emaLink context/AT definitions ###########*/
#define EMA_AT_CMD_MAX_SIZE             128
#define EMA_AT_CMD_RESPONSE_MAX_SIZE    512
#define EMA_BOARD_NOTIFY_MSG_SIZE       160

// the emaLink_context struct must be declared prior to using any APIs
struct emaLink_context
{
    char at_cmd[EMA_AT_CMD_MAX_SIZE];
    unsigned char at_cmd_flags;
        #define     EMA_LINK_FL_SYNC_RX     (1<<0)

    char bn_msg[EMA_BOARD_NOTIFY_MSG_SIZE];
    char response[EMA_AT_CMD_RESPONSE_MAX_SIZE];
    unsigned short response_length;
    unsigned char response_flags; 

    unsigned long  urc_status;
        #define     EMA_LINK_CNTX_EMA_AT_READY              (1<<0)
        #define     EMA_LINK_CNTX_MODULE_POWERING_ON        (1<<1)
        #define     EMA_LINK_CNTX_MODULE_READY              (1<<2)    
            #define     EMA_LINK_CNTX_MODULE_READY_GROUP           ( EMA_LINK_CNTX_MODULE_POWERING_ON | EMA_LINK_CNTX_MODULE_READY )
        #define     EMA_LINK_CNTX_MODULE_POWERING_OFF       (1<<3)
        #define     EMA_LINK_CNTX_MODULE_POWERED_OFF        (1<<4)    
            #define     EMA_LINK_CNTX_MODULE_OFF_GROUP             (EMA_LINK_CNTX_MODULE_POWERING_OFF | EMA_LINK_CNTX_MODULE_POWERED_OFF)
        #define     EMA_LINK_CNTX_MODULE_UART_READY         (1<<5)
        #define     EMA_LINK_CNTX_MODULE_UART_DOWN          (1<<6)
        #define     EMA_LINK_CNTX_MODULE_RESET_REQ          (1<<10)
        #define     EMA_LINK_CNTX_MODULE_RESETTING          (1<<11)
        #define     EMA_LINK_CNTX_MODULE_RESET              (1<<12)
        #define     EMA_LINK_CNTX_MODULE_RESET_SHORT        (1<<13)
            #define     EMA_LINK_CNTX_EMA_RESET_GROUP           (EMA_LINK_CNTX_MODULE_RESET_REQ | EMA_LINK_CNTX_MODULE_RESETTING | EMA_LINK_CNTX_MODULE_RESET) 
            #define     EMA_LINK_CNTX_EMA_RESET_SHORT_GROUP     (EMA_LINK_CNTX_MODULE_RESET_REQ | EMA_LINK_CNTX_MODULE_RESET_SHORT)
        // emaLink tasks/urcs
        #define     EMA_LINK_CNTX_EMA_MICROFOTA_STARTED     (1<<14)
        #define     EMA_LINK_CNTX_EMA_MICROFOTA_COMPLETE    (1<<15)
        #define     EMA_LINK_CNTX_EMA_MICROFOTA_FAILED      (1<<16)
        #define     EMA_LINK_CNTX_EMA_BOARD_NOTIFY          (1<<17)
        #define     EMA_LINK_CNTX_EMA_REBOOTING_60_SECONDS  (1<<18)  
        #define     EMA_LINK_CNTX_EMA_REBOOTING_NOW         (1<<19)
            #define EMA_LINK_CNTX_ADMIN_ASYNCH_GROUP            ( EMA_LINK_CNTX_MODULE_POWERING_OFF | EMA_LINK_CNTX_EMA_REBOOTING_60_SECONDS | EMA_LINK_CNTX_EMA_MICROFOTA_STARTED | \
                                                              EMA_LINK_CNTX_EMA_MICROFOTA_COMPLETE | EMA_LINK_CNTX_EMA_MICROFOTA_FAILED | EMA_LINK_CNTX_EMA_BOARD_NOTIFY )
};

// at cmd query function (user provided via emaModAT_init()). It is expected that the user's application
// creates a send/receive function that can be passed into the emaLinkAT_Init(). 
int (*ema_at_comm_handle)(struct emaLink_context *);

#define EMA_FW_SIZE             32
#define EMA_SN_SIZE             16
#define EMA_MODEL_SIZE          16

#define CARRIER_SIZE            16
#define CELL_FW_SIZE            16
#define REG_ST_SIZE             32
#define FAIL_OVER_EN_DIS_SIZE   8
#define ACC_TECH_SIZE           16 

#define EMA_SERV_ST_SIZE        16

#define EMA_FW_REV_SIZE         16
#define EMA_FW_SUB_REV_SIZE     2
#define EMA_FW_HASH_SIZE        8
#define EMA_FW_BUILD_SIZE       16    

struct ema_glimpse1
{
    unsigned long ema_uptime;
    char ema_fw[EMA_FW_SIZE+1];
    char ema_sn[EMA_SN_SIZE+1];
    char ema_model[EMA_MODEL_SIZE+1];
};
struct ema_glimpse2
{
    char pri_carr[CARRIER_SIZE+1];
    char active_carr[CARRIER_SIZE+1];
    char active_fw[CELL_FW_SIZE+1];
    char reg_st[REG_ST_SIZE+1];
    char failover_en[FAIL_OVER_EN_DIS_SIZE+1];
    unsigned long last_failover_ev;
    char acc_tech[ACC_TECH_SIZE+1];
};
struct ema_glimpse3
{
    unsigned long cell_id;
    unsigned short mcc;
    unsigned short mnc;
    unsigned short tac;
};
struct ema_glimpse4
{
    unsigned char sig_q;
    int curr_rssi;
    int curr_rsrq;
    int curr_rsrp;
    int min_rssi;
    int max_rssi;
    int avg_rssi;
    int min_rsrq;
    int max_rsrq;
    int avg_rsrq;
    int min_rsrp;
    int max_rsrp;
    int avg_rsrp;
};
struct ema_glimpse5
{
    char ema_services_state[EMA_SERV_ST_SIZE+1];
};

struct ema_glimpse
{
    struct ema_glimpse1 glimpse1;
    struct ema_glimpse2 glimpse2;
    struct ema_glimpse3 glimpse3;
    struct ema_glimpse4 glimpse4;
    struct ema_glimpse5 glimpse5;
};

struct ema_ext_fw
{
    char fw_full[EMA_FW_SIZE+1];
    char fw_rev[EMA_FW_REV_SIZE+1]; 
    char fw_sub_rev[EMA_FW_SUB_REV_SIZE+1]; 
    char fw_hash[EMA_FW_HASH_SIZE+1];
    char fw_build[EMA_FW_BUILD_SIZE+1];
    char fw_ver;
};

// accessible helpers
int emaLinkURC_GetValue( char *msg, unsigned short len );
void emaLinkURC_GetMsg( struct emaLink_context *context, char *msg );
int emaLinkAT_CheckOK( char *buff, unsigned short *len );
// emaLink APIs
void emaLinkAT_Init( struct emaLink_context *handle, int (*func_ptr)(struct emaLink_context *) );
int emaLinkAT_CheckComm( struct emaLink_context *context );
int emaLinkAT_DisableEcho( struct emaLink_context *context );
int emaLinkAT_EnableEcho( struct emaLink_context *context );
int emaLinkAT_GlimpseTest(struct emaLink_context *context, char *formatting );
int emaLinkAT_Glimpse( struct emaLink_context *context, char *buffer );
int emaLinkAT_Glimpse1( struct emaLink_context *context, struct ema_glimpse1 *glimpse );
int emaLinkAT_Glimpse2( struct emaLink_context *context, struct ema_glimpse2 *glimpse );
int emaLinkAT_Glimpse3( struct emaLink_context *context, struct ema_glimpse3 *glimpse );
int emaLinkAT_Glimpse4( struct emaLink_context *context, struct ema_glimpse4 *glimpse );
int emaLinkAT_Glimpse5( struct emaLink_context *context, struct ema_glimpse5 *glimpse );
int emaLinkAT_CheckOK( char *buff, unsigned short *len );
int emaLinkAT_GetFWVersion( struct emaLink_context *context, char *fw_string );
int emaLinkAT_ExtFWFull( struct emaLink_context *context, struct ema_ext_fw *fw );
int emaLinkAT_ExtFWRevision(struct emaLink_context *context, struct ema_ext_fw *fw );
int emaLinkAT_ExtFWSubRevision( struct emaLink_context *context, struct ema_ext_fw *fw );
int emaLinkAT_ExtFWHash( struct emaLink_context *context, struct ema_ext_fw *fw );
int emaLinkAT_ExtFWBuild( struct emaLink_context *context, struct ema_ext_fw *fw );
int emaLinkAT_ExtFWVersion( struct emaLink_context *context, struct ema_ext_fw *fw );
int emaLinkAT_GetSN( struct emaLink_context *context, char *sn_string );
int emaLinkAT_SetBID( struct emaLink_context *context, char *bid_string );
int emaLinkAT_GetBID( struct emaLink_context *context, char *bid_string );
int emaLinkAT_BIDTestCmd( struct emaLink_context *context, char *formatting );
int emaLinkAT_ListAvailCMDs( struct emaLink_context *context, char *cmd_list );
int emaLinkAT_EnableEcho( struct emaLink_context *context );

// status codes
#define EMA_LINK_AT_ST_NO_OK                    -1
#define EMA_LINK_AT_ST_BAD_RESPONSE             0
#define EMA_LINK_AT_ST_SUCCESS                  1
/*###########################################*/

/*############ ema URC definitions ###########*/
#define EMA_LINK_URC_AT_READY                   0
#define EMA_LINK_URC_POWERING_ON                1
#define EMA_LINK_URC_READY                      2
#define EMA_LINK_URC_POWERING_OFF               3
#define EMA_LINK_URC_POWERED_OFF                4
#define EMA_LINK_URC_EMA_REBOOTING_NOW          5
#define EMA_LINK_URC_EMA_REBOOTING_60_SECONDS   6
#define EMA_LINK_URC_MODULE_UART_ESTABLISHED    7
#define EMA_LINK_URC_USB_ESTABLISHED            8
#define EMA_LINK_URC_MODULE_UART_REMOVED        9
#define EMA_LINK_URC_USB_REMOVED                10
#define EMA_LINK_URC_MODULE_RESET_REQUESTED     11
#define EMA_LINK_URC_MODULE_RESETTING           12
#define EMA_LINK_URC_MODULE_RESET_SUCCESS       13
#define EMA_LINK_URC_MODULE_RESET_NOT_OBSERVED  14
#define EMA_LINK_URC_EMA_MICROFOTA_STARTING     30
#define EMA_LINK_URC_EMA_MICROFOTA_COMPLETE     31
#define EMA_LINK_URC_EMA_MICROFOTA_FAILED       32
#define EMA_LINK_URC_EMA_BOARD_NOTIFY           99

#define EMA_LINK_URC_INVALID                    255
/*###########################################*/

#endif /* OC_EMALINK_AT_H_ */
