From 210a55c1f7e633e795d22da4bc2bc4f6fa5b6c65 Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Mon, 29 Mar 2021 14:35:09 +0800 Subject: [PATCH 01/32] Update cellular library to MIT license --- LICENSE | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/LICENSE b/LICENSE index 1bb4f21e..9cf10627 100644 --- a/LICENSE +++ b/LICENSE @@ -1,15 +1,19 @@ -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 582cc8f478b9fe7d37615de33e87f7ac3d396c2b Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 28 Sep 2022 11:52:28 +0800 Subject: [PATCH 02/32] Remove modules in cellular interface repo. --- .gitmodules | 3 - modules/ThirdParty/Community-Supported-Ports | 1 - modules/bg96/cellular_bg96.c | 358 -- modules/bg96/cellular_bg96.h | 106 - modules/bg96/cellular_bg96_api.c | 3206 ------------------ modules/bg96/cellular_bg96_urc_handler.c | 807 ----- modules/bg96/cellular_bg96_wrapper.c | 268 -- modules/hl7802/cellular_hl7802.c | 585 ---- modules/hl7802/cellular_hl7802.h | 150 - modules/hl7802/cellular_hl7802_api.c | 2788 --------------- modules/hl7802/cellular_hl7802_urc_handler.c | 349 -- modules/hl7802/cellular_hl7802_wrapper.c | 269 -- modules/sara_r4/cellular_r4.c | 562 --- modules/sara_r4/cellular_r4.h | 164 - modules/sara_r4/cellular_r4_api.c | 2906 ---------------- modules/sara_r4/cellular_r4_urc_handler.c | 656 ---- modules/sara_r4/cellular_r4_wrapper.c | 263 -- 17 files changed, 13441 deletions(-) delete mode 160000 modules/ThirdParty/Community-Supported-Ports delete mode 100644 modules/bg96/cellular_bg96.c delete mode 100644 modules/bg96/cellular_bg96.h delete mode 100644 modules/bg96/cellular_bg96_api.c delete mode 100644 modules/bg96/cellular_bg96_urc_handler.c delete mode 100644 modules/bg96/cellular_bg96_wrapper.c delete mode 100644 modules/hl7802/cellular_hl7802.c delete mode 100644 modules/hl7802/cellular_hl7802.h delete mode 100644 modules/hl7802/cellular_hl7802_api.c delete mode 100644 modules/hl7802/cellular_hl7802_urc_handler.c delete mode 100644 modules/hl7802/cellular_hl7802_wrapper.c delete mode 100644 modules/sara_r4/cellular_r4.c delete mode 100644 modules/sara_r4/cellular_r4.h delete mode 100644 modules/sara_r4/cellular_r4_api.c delete mode 100644 modules/sara_r4/cellular_r4_urc_handler.c delete mode 100644 modules/sara_r4/cellular_r4_wrapper.c diff --git a/.gitmodules b/.gitmodules index f6ff6f36..7c299f97 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "test/unit-test/CMock"] path = test/unit-test/CMock url = https://github.com/ThrowTheSwitch/CMock -[submodule "modules/ThirdParty/Community-Supported-Ports"] - path = modules/ThirdParty/Community-Supported-Ports - url = https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports diff --git a/modules/ThirdParty/Community-Supported-Ports b/modules/ThirdParty/Community-Supported-Ports deleted file mode 160000 index 0f5e3703..00000000 --- a/modules/ThirdParty/Community-Supported-Ports +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0f5e3703aab3357b50bc6266e2dbd9f9ccd0b92c diff --git a/modules/bg96/cellular_bg96.c b/modules/bg96/cellular_bg96.c deleted file mode 100644 index 8cac8cd7..00000000 --- a/modules/bg96/cellular_bg96.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* The config header is always included first. */ - - -#include -#include "cellular_platform.h" -#include "cellular_config.h" -#include "cellular_config_defaults.h" -#include "cellular_common.h" -#include "cellular_common_portable.h" -#include "cellular_bg96.h" - -/*-----------------------------------------------------------*/ - -#define ENBABLE_MODULE_UE_RETRY_COUNT ( 3U ) -#define ENBABLE_MODULE_UE_RETRY_TIMEOUT ( 5000U ) -#define BG96_NWSCANSEQ_CMD_MAX_SIZE ( 29U ) /* The length of AT+QCFG="nwscanseq",020301,1\0. */ - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq ); - -/*-----------------------------------------------------------*/ - -static cellularModuleContext_t cellularBg96Context = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenErrorTable[] = -{ "ERROR", "BUSY", "NO CARRIER", "NO ANSWER", "NO DIALTONE", "ABORTED", "+CMS ERROR", "+CME ERROR", "SEND FAIL" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenErrorTableSize = sizeof( CellularSrcTokenErrorTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenSuccessTable[] = -{ "OK", "CONNECT", "SEND OK", ">" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenSuccessTableSize = sizeof( CellularSrcTokenSuccessTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularUrcTokenWoPrefixTable[] = -{ "NORMAL POWER DOWN", "PSM POWER DOWN", "RDY" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcTokenWoPrefixTableSize = sizeof( CellularUrcTokenWoPrefixTable ) / sizeof( char * ); - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint8_t tryCount = 0; - - if( pAtReq == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - for( ; tryCount < ENBABLE_MODULE_UE_RETRY_COUNT; tryCount++ ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, *pAtReq, ENBABLE_MODULE_UE_RETRY_TIMEOUT ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static bool appendRatList( char * pRatList, - CellularRat_t cellularRat ) -{ - bool retValue = true; - - /* Configure RAT Searching Sequence to default radio access technology. */ - switch( cellularRat ) - { - case CELLULAR_RAT_CATM1: - strcat( pRatList, "02" ); - break; - - case CELLULAR_RAT_NBIOT: - strcat( pRatList, "03" ); - break; - - case CELLULAR_RAT_GSM: - strcat( pRatList, "01" ); - break; - - default: - /* Configure RAT Searching Sequence to automatic. */ - retValue = false; - break; - } - - return retValue; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext, - void ** ppModuleContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - bool status = false; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ppModuleContext == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Initialize the module context. */ - ( void ) memset( &cellularBg96Context, 0, sizeof( cellularModuleContext_t ) ); - - /* Create the mutex for DNS. */ - status = PlatformMutex_Create( &cellularBg96Context.dnsQueryMutex, false ); - - if( status == false ) - { - cellularStatus = CELLULAR_NO_MEMORY; - } - else - { - /* Create the queue for DNS. */ - cellularBg96Context.pktDnsQueue = xQueueCreate( 1, sizeof( cellularDnsQueryResult_t ) ); - - if( cellularBg96Context.pktDnsQueue == NULL ) - { - PlatformMutex_Destroy( &cellularBg96Context.dnsQueryMutex ); - cellularStatus = CELLULAR_NO_MEMORY; - } - else - { - *ppModuleContext = ( void * ) &cellularBg96Context; - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else - { - /* Delete DNS queue. */ - vQueueDelete( cellularBg96Context.pktDnsQueue ); - - /* Delete the mutex for DNS. */ - PlatformMutex_Destroy( &cellularBg96Context.dnsQueryMutex ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - CellularAtReq_t atReqGetWithResult = - { - NULL, - CELLULAR_AT_MULTI_WO_PREFIX, - NULL, - NULL, - NULL, - 0 - }; - char ratSelectCmd[ BG96_NWSCANSEQ_CMD_MAX_SIZE ] = "AT+QCFG=\"nwscanseq\","; - bool retAppendRat = true; - - if( pContext != NULL ) - { - /* Disable echo. */ - atReqGetWithResult.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetWithResult ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Disable DTR function. */ - atReqGetNoResult.pAtCmd = "AT&D0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - #ifndef CELLULAR_CONFIG_DISABLE_FLOW_CONTROL - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Enable RTS/CTS hardware flow control. */ - atReqGetNoResult.pAtCmd = "AT+IFC=2,2"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - #endif - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Setting URC output port. */ - #if defined( CELLULAR_BG96_URC_PORT_USBAT ) || defined( BG96_URC_PORT_USBAT ) - atReqGetNoResult.pAtCmd = "AT+QURCCFG=\"urcport\",\"usbat\""; - #else - atReqGetNoResult.pAtCmd = "AT+QURCCFG=\"urcport\",\"uart1\""; - #endif - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Configure Band configuration to all bands. */ - atReqGetNoResult.pAtCmd = "AT+QCFG=\"band\",f,400a0e189f,a0e189f"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Configure RAT(s) to be Searched to Automatic. */ - atReqGetNoResult.pAtCmd = "AT+QCFG=\"nwscanmode\",0,1"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Configure Network Category to be Searched under LTE RAT to LTE Cat M1 and Cat NB1. */ - atReqGetNoResult.pAtCmd = "AT+QCFG=\"iotopmode\",2,1"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT ); - configASSERT( retAppendRat == true ); - - #ifdef CELLULAR_CONFIG_DEFAULT_RAT_2 - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT_2 ); - configASSERT( retAppendRat == true ); - #endif - - #ifdef CELLULAR_CONFIG_DEFAULT_RAT_3 - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT_3 ); - configASSERT( retAppendRat == true ); - #endif - - strcat( ratSelectCmd, ",1" ); /* Take effect immediately. */ - atReqGetNoResult.pAtCmd = ratSelectCmd; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+CFUN=1"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqGetNoResult.pAtCmd = "AT+COPS=3,2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CGREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CEREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CTZR=1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ diff --git a/modules/bg96/cellular_bg96.h b/modules/bg96/cellular_bg96.h deleted file mode 100644 index eceb01c4..00000000 --- a/modules/bg96/cellular_bg96.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#ifndef __CELLULAR_BG96_H__ -#define __CELLULAR_BG96_H__ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -/* AT Command timeout for PDN activation */ -#define PDN_ACTIVATION_PACKET_REQ_TIMEOUT_MS ( 150000UL ) - -/* AT Command timeout for PDN deactivation. */ -#define PDN_DEACTIVATION_PACKET_REQ_TIMEOUT_MS ( 40000UL ) - -/* AT Command timeout for Socket connection */ -#define SOCKET_CONNECT_PACKET_REQ_TIMEOUT_MS ( 150000UL ) - -#define PACKET_REQ_TIMEOUT_MS ( 5000UL ) - -/* AT Command timeout for Socket disconnection */ -#define SOCKET_DISCONNECT_PACKET_REQ_TIMEOUT_MS ( 12000UL ) - -#define DATA_SEND_TIMEOUT_MS ( 50000UL ) -#define DATA_READ_TIMEOUT_MS ( 50000UL ) - -/** - * @brief DNS query result. - */ -typedef enum cellularDnsQueryResult -{ - CELLULAR_DNS_QUERY_SUCCESS, - CELLULAR_DNS_QUERY_FAILED, - CELLULAR_DNS_QUERY_MAX, - CELLULAR_DNS_QUERY_UNKNOWN -} cellularDnsQueryResult_t; - -typedef struct cellularModuleContext cellularModuleContext_t; - -/** - * @brief DNS query URC callback fucntion. - */ -typedef void ( * CellularDnsResultEventCallback_t )( cellularModuleContext_t * pModuleContext, - char * pDnsResult, - char * pDnsUsrData ); - -typedef struct cellularModuleContext -{ - /* DNS related variables. */ - PlatformMutex_t dnsQueryMutex; /* DNS query mutex to protect the following data. */ - QueueHandle_t pktDnsQueue; /* DNS queue to receive the DNS query result. */ - uint8_t dnsResultNumber; /* DNS query result number. */ - uint8_t dnsIndex; /* DNS query current index. */ - char * pDnsUsrData; /* DNS user data to store the result. */ - CellularDnsResultEventCallback_t dnsEventCallback; - /* Forward declaration to declar the callback function prototype. */ - /* coverity[misra_c_2012_rule_1_1_violation]. */ -} cellularModuleContext_t; - -CellularPktStatus_t _Cellular_ParseSimstat( char * pInputStr, - CellularSimCardState_t * pSimState ); - -extern CellularAtParseTokenMap_t CellularUrcHandlerTable[]; -extern uint32_t CellularUrcHandlerTableSize; - -extern const char * CellularSrcTokenErrorTable[]; -extern uint32_t CellularSrcTokenErrorTableSize; - -extern const char * CellularSrcTokenSuccessTable[]; -extern uint32_t CellularSrcTokenSuccessTableSize; - -extern const char * CellularUrcTokenWoPrefixTable[]; -extern uint32_t CellularUrcTokenWoPrefixTableSize; - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* ifndef __CELLULAR_BG96_H__ */ diff --git a/modules/bg96/cellular_bg96_api.c b/modules/bg96/cellular_bg96_api.c deleted file mode 100644 index 798202f5..00000000 --- a/modules/bg96/cellular_bg96_api.c +++ /dev/null @@ -1,3206 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* Standard includes. */ -#include -#include -#include -#include - -#include "cellular_platform.h" -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -#include "cellular_types.h" -#include "cellular_api.h" -#include "cellular_common_api.h" -#include "cellular_common.h" -#include "cellular_at_core.h" -#include "cellular_bg96.h" - -/*-----------------------------------------------------------*/ - -#define CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ( 32U ) -#define CELLULAR_AT_CMD_QUERY_DNS_MAX_SIZE ( 280U ) - -#define SIGNAL_QUALITY_POS_SYSMODE ( 1U ) -#define SIGNAL_QUALITY_POS_GSM_LTE_RSSI ( 2U ) -#define SIGNAL_QUALITY_POS_LTE_RSRP ( 3U ) -#define SIGNAL_QUALITY_POS_LTE_SINR ( 4U ) -#define SIGNAL_QUALITY_POS_LTE_RSRQ ( 5U ) -#define SIGNAL_QUALITY_SINR_MIN_VALUE ( -20 ) -#define SIGNAL_QUALITY_SINR_DIVISIBILITY_FACTOR ( 5 ) - -#define COPS_POS_MODE ( 1U ) -#define COPS_POS_FORMAT ( 2U ) -#define COPS_POS_MCC_MNC_OPER_NAME ( 3U ) -#define COPS_POS_RAT ( 4U ) - -/* AT command timeout for Get IP Address by Domain Name. */ -#define DNS_QUERY_TIMEOUT_MS ( 60000UL ) - -/* Length of HPLMN including RAT. */ -#define CRSM_HPLMN_RAT_LENGTH ( 9U ) - -/* Windows simulator implementation. */ -#if defined( _WIN32 ) || defined( _WIN64 ) - #define strtok_r strtok_s -#endif - -#define PRINTF_BINARY_PATTERN_INT4 "%c%c%c%c" -#define PRINTF_BYTE_TO_BINARY_INT4( i ) \ - ( ( ( ( i ) & 0x08UL ) != 0UL ) ? '1' : '0' ), \ - ( ( ( ( i ) & 0x04UL ) != 0UL ) ? '1' : '0' ), \ - ( ( ( ( i ) & 0x02UL ) != 0UL ) ? '1' : '0' ), \ - ( ( ( ( i ) & 0x01UL ) != 0UL ) ? '1' : '0' ) - -#define PRINTF_BINARY_PATTERN_INT8 \ - PRINTF_BINARY_PATTERN_INT4 PRINTF_BINARY_PATTERN_INT4 -#define PRINTF_BYTE_TO_BINARY_INT8( i ) \ - PRINTF_BYTE_TO_BINARY_INT4( ( i ) >> 4 ), PRINTF_BYTE_TO_BINARY_INT4( i ) - -#define QPSMS_POS_MODE ( 0U ) -#define QPSMS_POS_RAU ( 1U ) -#define QPSMS_POS_RDY_TIMER ( 2U ) -#define QPSMS_POS_TAU ( 3U ) -#define QPSMS_POS_ACTIVE_TIME ( 4U ) - -#define CELLULAR_PDN_STATUS_POS_CONTEXT_ID ( 0U ) -#define CELLULAR_PDN_STATUS_POS_CONTEXT_STATE ( 1U ) -#define CELLULAR_PDN_STATUS_POS_CONTEXT_TYPE ( 2U ) -#define CELLULAR_PDN_STATUS_POS_IP_ADDRESS ( 3U ) - -#define RAT_PRIOIRTY_STRING_LENGTH ( 2U ) -#define RAT_PRIOIRTY_LIST_LENGTH ( 3U ) - -#define INVALID_PDN_INDEX ( 0xFFU ) - -#define DATA_PREFIX_STRING "+QIRD:" -#define DATA_PREFIX_STRING_LENGTH ( 6U ) -#define DATA_PREFIX_STRING_CHANGELINE_LENGTH ( 2U ) /* The length of the change line "\r\n". */ - -#define MAX_QIRD_STRING_PREFIX_STRING ( 14U ) /* The max data prefix string is "+QIRD: 1460\r\n" */ - -/*-----------------------------------------------------------*/ - -/** - * @brief Parameters involved in receiving data through sockets - */ -typedef struct _socketDataRecv -{ - uint32_t * pDataLen; - uint8_t * pData; - CellularSocketAddress_t * pRemoteSocketAddress; -} _socketDataRecv_t; - -/*-----------------------------------------------------------*/ - -static bool _parseSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ); -static CellularPktStatus_t _Cellular_RecvFuncGetSignalInfo( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t controlSignalStrengthIndication( CellularContext_t * pContext, - bool enable ); -static CellularPktStatus_t _Cellular_RecvFuncGetIccid( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularPktStatus_t _Cellular_RecvFuncGetImsi( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static bool _checkCrsmMemoryStatus( const char * pToken ); -static bool _checkCrsmReadStatus( const char * pToken ); -static bool _parseHplmn( char * pToken, - void * pData ); -static CellularPktStatus_t _Cellular_RecvFuncGetHplmn( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularPktStatus_t _Cellular_RecvFuncGetSimCardStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularSimCardLockState_t _getSimLockState( char * pToken ); -static CellularPktStatus_t _Cellular_RecvFuncGetSimLockStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularATError_t parsePdnStatusContextId( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ); -static CellularATError_t parsePdnStatusContextState( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ); -static CellularATError_t parsePdnStatusContextType( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ); -static CellularATError_t getPdnStatusParseToken( char * pToken, - uint8_t tokenIndex, - CellularPdnStatus_t * pPdnStatusBuffers ); -static CellularATError_t getPdnStatusParseLine( char * pRespLine, - CellularPdnStatus_t * pPdnStatusBuffers ); -static CellularPktStatus_t _Cellular_RecvFuncGetPdnStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t buildSocketConnect( CellularSocketHandle_t socketHandle, - char * pCmdBuf ); -static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pAtResp, - const _socketDataRecv_t * pDataRecv, - uint32_t outBufSize ); -static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularATError_t parseQpsmsMode( char * pToken, - CellularPsmSettings_t * pPsmSettings ); -static CellularATError_t parseQpsmsRau( char * pToken, - CellularPsmSettings_t * pPsmSettings ); -static CellularATError_t parseQpsmsRdyTimer( char * pToken, - CellularPsmSettings_t * pPsmSettings ); -static CellularATError_t parseQpsmsTau( char * pToken, - CellularPsmSettings_t * pPsmSettings ); -static CellularATError_t parseQpsmsActiveTime( char * pToken, - CellularPsmSettings_t * pPsmSettings ); -static CellularATError_t parseGetPsmToken( char * pToken, - uint8_t tokenIndex, - CellularPsmSettings_t * pPsmSettings ); -static CellularRat_t convertRatPriority( char * pRatString ); -static CellularPktStatus_t _Cellular_RecvFuncGetRatPriority( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularPktStatus_t _Cellular_RecvFuncGetPsmSettings( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t lineLength, - char ** ppDataStart, - uint32_t * pDataLength ); -static CellularError_t storeAccessModeAndAddress( CellularContext_t * pContext, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ); -static CellularError_t registerDnsEventCallback( cellularModuleContext_t * pModuleContext, - CellularDnsResultEventCallback_t dnsEventCallback, - char * pDnsUsrData ); -static void _dnsResultCallback( cellularModuleContext_t * pModuleContext, - char * pDnsResult, - char * pDnsUsrData ); -static uint32_t appendBinaryPattern( char * cmdBuf, - uint32_t cmdLen, - uint32_t value, - bool endOfString ); -static CellularPktStatus_t socketSendDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t * pBytesRead ); - -/*-----------------------------------------------------------*/ - -static bool _parseSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ) -{ - char * pToken = NULL, * pTmpQcsqPayload = pQcsqPayload; - int32_t tempValue = 0; - bool parseStatus = true; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( ( pSignalInfo == NULL ) || ( pQcsqPayload == NULL ) ) - { - LogError( ( "_parseSignalQuality: Invalid Input Parameters" ) ); - parseStatus = false; - } - - if( ( parseStatus == true ) && ( Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ) == CELLULAR_AT_SUCCESS ) ) - { - if( ( strcmp( pToken, "GSM" ) != 0 ) && - ( strcmp( pToken, "CAT-M1" ) != 0 ) && - ( strcmp( pToken, "CAT-NB1" ) != 0 ) ) - { - parseStatus = false; - } - } - else - { - LogDebug( ( "_parseSignalQuality: No Valid RAT in QCSQ Response" ) ); - parseStatus = false; - } - - if( ( parseStatus == true ) && ( Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ) == CELLULAR_AT_SUCCESS ) ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSignalInfo->rssi = ( int16_t ) tempValue; - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RSSI. Token %s", pToken ) ); - parseStatus = false; - } - } - else - { - parseStatus = false; - } - - if( ( parseStatus == true ) && ( Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ) == CELLULAR_AT_SUCCESS ) ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSignalInfo->rsrp = ( int16_t ) tempValue; - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RSRP. Token %s", pToken ) ); - parseStatus = false; - } - } - else - { - parseStatus = false; - } - - if( ( parseStatus == true ) && ( Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ) == CELLULAR_AT_SUCCESS ) ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* SINR is reported as an integer value ranging from 0 to 250 representing 1/5 of a dB. - * Value 0 correspond to -20 dBm and 250 corresponds to +30 dBm. */ - pSignalInfo->sinr = ( int16_t ) ( SIGNAL_QUALITY_SINR_MIN_VALUE + ( ( tempValue ) / ( SIGNAL_QUALITY_SINR_DIVISIBILITY_FACTOR ) ) ); - } - else - { - LogError( ( "_parseSignalQuality: Error in processing SINR. pToken %s", pToken ) ); - parseStatus = false; - } - } - else - { - parseStatus = false; - } - - if( ( parseStatus == true ) && ( Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ) == CELLULAR_AT_SUCCESS ) ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSignalInfo->rsrq = ( int16_t ) tempValue; - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RSRQ. Token %s", pToken ) ); - parseStatus = false; - } - } - else - { - parseStatus = false; - } - - return parseStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetSignalInfo( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularSignalInfo_t * pSignalInfo = ( CellularSignalInfo_t * ) pData; - bool parseStatus = true; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pSignalInfo == NULL ) || ( dataLen != sizeof( CellularSignalInfo_t ) ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetSignalInfo: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputLine ); - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - parseStatus = _parseSignalQuality( pInputLine, pSignalInfo ); - - if( parseStatus != true ) - { - pSignalInfo->rssi = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->ber = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->bars = CELLULAR_INVALID_SIGNAL_BAR_VALUE; - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t controlSignalStrengthIndication( CellularContext_t * pContext, - bool enable ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - uint8_t enable_value = 0; - CellularAtReq_t atReqControlSignalStrengthIndication = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - if( enable == true ) - { - enable_value = 1; - } - else - { - enable_value = 0; - } - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "AT+QINDCFG=\"csq\",%u", enable_value ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqControlSignalStrengthIndication ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetIccid( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pRespLine = NULL; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || ( pData == NULL ) ) - { - LogError( ( "getIccid: Response in invalid " ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pRespLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Removing QCCID Prefix in AT Response. */ - atCoreStatus = Cellular_ATRemovePrefix( &pRespLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Storing the ICCID value in the AT Response. */ - if( strlen( pRespLine ) < ( ( size_t ) CELLULAR_ICCID_MAX_SIZE + 1U ) ) - { - ( void ) strncpy( pData, pRespLine, dataLen ); - } - else - { - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetImsi( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pRespLine = NULL; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || ( pData == NULL ) ) - { - LogError( ( "getImsi: Response in invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pRespLine = pAtResp->pItm->pLine; - - /* Removing all the Spaces in the AT Response. */ - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( strlen( pRespLine ) < ( CELLULAR_IMSI_MAX_SIZE + 1U ) ) - { - ( void ) strncpy( ( char * ) pData, pRespLine, dataLen ); - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static bool _checkCrsmMemoryStatus( const char * pToken ) -{ - bool memoryStatus = true; - - if( pToken == NULL ) - { - LogError( ( "Input Parameter NULL" ) ); - memoryStatus = false; - } - - if( memoryStatus ) - { - /* checking the value sw2 in AT command response for memory problem during CRSM read. - * Refer 3GPP Spec TS 51.011 Section 9.4. */ - if( strcmp( pToken, "64" ) == 0 ) - { - LogError( ( "_checkCrsmMemoryStatus: Error in Processing HPLMN: CRSM Memory Error" ) ); - memoryStatus = false; - } - } - - return memoryStatus; -} - -/*-----------------------------------------------------------*/ - -static bool _checkCrsmReadStatus( const char * pToken ) -{ - bool readStatus = true; - - if( pToken == NULL ) - { - LogError( ( "Input Parameter NULL" ) ); - readStatus = false; - } - - if( readStatus ) - { - /* checking the parameter sw1 in AT command response for successful CRSM read. - * Refer 3GPP Spec TS 51.011 Section 9.4. */ - if( ( strcmp( pToken, "144" ) != 0 ) && - ( strcmp( pToken, "145" ) != 0 ) && - ( strcmp( pToken, "146" ) != 0 ) ) - { - LogError( ( "_checkCrsmReadStatus: Error in Processing HPLMN: CRSM Read Error" ) ); - readStatus = false; - } - } - - return readStatus; -} - -/*-----------------------------------------------------------*/ - -static bool _parseHplmn( char * pToken, - void * pData ) -{ - bool parseStatus = true; - CellularPlmnInfo_t * plmn = ( CellularPlmnInfo_t * ) pData; - - if( ( pToken == NULL ) || ( pData == NULL ) ) - { - LogError( ( "Input Parameter NULL" ) ); - parseStatus = false; - } - - if( parseStatus == true ) - { - /* Checking if the very first HPLMN entry in AT command Response is valid*/ - if( ( strlen( pToken ) < ( CRSM_HPLMN_RAT_LENGTH ) ) || ( strncmp( pToken, "FFFFFF", 6 ) == 0 ) ) - { - LogError( ( "_parseHplmn: Error in Processing HPLMN: Invalid Token %s", pToken ) ); - parseStatus = false; - } - } - - if( parseStatus == true ) - { - /* Returning only the very first HPLMN present in EFHPLMNwACT in SIM. - * EF-HPLMNwACT can contain a maximum of 10 HPLMN entries in decreasing order of priority. - * In this implementation, returning the very first HPLMN is the PLMN priority list. */ - /* Refer TS 51.011 Section 10.3.37 for encoding. */ - plmn->mcc[ 0 ] = pToken[ 1 ]; - plmn->mcc[ 1 ] = pToken[ 0 ]; - plmn->mcc[ 2 ] = pToken[ 3 ]; - plmn->mnc[ 0 ] = pToken[ 5 ]; - plmn->mnc[ 1 ] = pToken[ 4 ]; - - if( pToken[ 2 ] != 'F' ) - { - plmn->mnc[ 2 ] = pToken[ 2 ]; - plmn->mnc[ 3 ] = '\0'; - } - else - { - plmn->mnc[ 2 ] = '\0'; - } - } - - return parseStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetHplmn( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - bool parseStatus = true; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pCrsmResponse = NULL, * pToken = NULL; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) || - ( pData == NULL ) || ( dataLen != sizeof( CellularPlmnInfo_t ) ) ) - { - LogError( ( "GetHplmn: Response is invalid " ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pCrsmResponse = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pCrsmResponse ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Removing the CRSM prefix in AT Response. */ - atCoreStatus = Cellular_ATRemovePrefix( &pCrsmResponse ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Removing All quotes in the AT Response. */ - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pCrsmResponse ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Getting the next token separated by comma in At Response*/ - atCoreStatus = Cellular_ATGetNextTok( &pCrsmResponse, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - parseStatus = _checkCrsmReadStatus( pToken ); - - if( !parseStatus ) - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pCrsmResponse, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - parseStatus = _checkCrsmMemoryStatus( pToken ); - - if( !parseStatus ) - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pCrsmResponse, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - parseStatus = _parseHplmn( pToken, pData ); - - if( !parseStatus ) - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetSimCardStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - const char * pTokenPtr = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularSimCardState_t * pSimCardState = ( CellularSimCardState_t * ) pData; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetSimStatus: response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( CellularSimCardState_t ) ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pInputLine ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - /* remove the token prefix. */ - pTokenPtr = strtok_r( pInputLine, ":", &pInputLine ); - - /* check the token prefix. */ - if( pTokenPtr == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_RESPONSE; - } - else - { - pktStatus = _Cellular_ParseSimstat( pInputLine, pSimCardState ); - } - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularSimCardLockState_t _getSimLockState( char * pToken ) -{ - CellularSimCardLockState_t tempState = CELLULAR_SIM_CARD_LOCK_UNKNOWN; - - if( pToken != NULL ) - { - if( strcmp( pToken, "READY" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_READY; - } - else if( strcmp( pToken, "SIM PIN" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PIN; - } - else if( strcmp( pToken, "SIM PUK" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PUK; - } - else if( strcmp( pToken, "SIM PIN2" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PIN2; - } - else if( strcmp( pToken, "SIM PUK2" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PUK2; - } - else if( strcmp( pToken, "PH-NET PIN" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PH_NET_PIN; - } - else if( strcmp( pToken, "PH-NET PUK" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PH_NET_PUK; - } - else if( strcmp( pToken, "PH-NETSUB PIN" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PH_NETSUB_PIN; - } - else if( strcmp( pToken, "PH-NETSUB PUK" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_PH_NETSUB_PUK; - } - else if( strcmp( pToken, "PH-SP PIN" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_SP_PIN; - } - else if( strcmp( pToken, "PH-SP PUK" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_SP_PUK; - } - else if( strcmp( pToken, "PH-CORP PIN" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_CORP_PIN; - } - else if( strcmp( pToken, "PH-CORP PUK" ) == 0 ) - { - tempState = CELLULAR_SIM_CARD_CORP_PUK; - } - else - { - LogError( ( "Unknown SIM Lock State %s", pToken ) ); - } - } - - return tempState; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetSimLockStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pToken = NULL, * pInputStr = NULL; - CellularSimCardLockState_t * pSimLockState = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) || - ( pData == NULL ) || ( dataLen != sizeof( CellularSimCardLockState_t ) ) ) - { - LogError( ( " Get SIM lock State: Response data is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputStr = pAtResp->pItm->pLine; - pSimLockState = ( CellularSimCardLockState_t * ) pData; - - if( strlen( pInputStr ) == 0U ) - { - LogError( ( "Get SIM lock State: Input data is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - } - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputStr ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemovePrefix( &pInputStr ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - LogDebug( ( "SIM Lock State: %s", pToken ) ); - *pSimLockState = _getSimLockState( pToken ); - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parsePdnStatusContextId( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MIN ) && - ( tempValue <= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MAX ) ) - { - pPdnStatusBuffers->contextId = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in Processing Context Id. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parsePdnStatusContextState( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - pPdnStatusBuffers->state = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in processing PDN Status Buffer state. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parsePdnStatusContextType( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && ( tempValue < ( int32_t ) CELLULAR_PDN_CONTEXT_TYPE_MAX ) ) - { - /* Variable "tempValue" is ensured that it is valid and within - * a valid range. Hence, assigning the value of the variable to - * pdnContextType with a enum cast. */ - /* coverity[misra_c_2012_rule_10_5_violation] */ - pPdnStatusBuffers->pdnContextType = ( CellularPdnContextType_t ) tempValue; - } - else - { - LogError( ( "Error in processing PDN State Buffer Status. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getPdnStatusParseToken( char * pToken, - uint8_t tokenIndex, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - switch( tokenIndex ) - { - case ( CELLULAR_PDN_STATUS_POS_CONTEXT_ID ): - LogDebug( ( "Context Id: %s", pToken ) ); - atCoreStatus = parsePdnStatusContextId( pToken, pPdnStatusBuffers ); - break; - - case ( CELLULAR_PDN_STATUS_POS_CONTEXT_STATE ): - LogDebug( ( "Context State: %s", pToken ) ); - atCoreStatus = parsePdnStatusContextState( pToken, pPdnStatusBuffers ); - break; - - case ( CELLULAR_PDN_STATUS_POS_CONTEXT_TYPE ): - LogDebug( ( "Context Type: %s", pToken ) ); - atCoreStatus = parsePdnStatusContextType( pToken, pPdnStatusBuffers ); - break; - - case ( CELLULAR_PDN_STATUS_POS_IP_ADDRESS ): - LogDebug( ( "IP address: %s", pToken ) ); - ( void ) memcpy( ( void * ) pPdnStatusBuffers->ipAddress.ipAddress, - ( void * ) pToken, CELLULAR_IP_ADDRESS_MAX_SIZE + 1U ); - - if( pPdnStatusBuffers->pdnContextType == CELLULAR_PDN_CONTEXT_IPV4 ) - { - pPdnStatusBuffers->ipAddress.ipAddressType = CELLULAR_IP_ADDRESS_V4; - } - else if( pPdnStatusBuffers->pdnContextType == CELLULAR_PDN_CONTEXT_IPV6 ) - { - pPdnStatusBuffers->ipAddress.ipAddressType = CELLULAR_IP_ADDRESS_V6; - } - else - { - LogError( ( "Unknown pdnContextType %d", pPdnStatusBuffers->pdnContextType ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - - break; - - default: - LogError( ( "Unknown token in getPdnStatusParseToken %s %d", - pToken, tokenIndex ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getPdnStatusParseLine( char * pRespLine, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - char * pToken = NULL; - char * pLocalRespLine = pRespLine; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - uint8_t tokenIndex = 0; - - atCoreStatus = Cellular_ATRemovePrefix( &pLocalRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pLocalRespLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalRespLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - tokenIndex = 0; - - while( ( pToken != NULL ) && ( atCoreStatus == CELLULAR_AT_SUCCESS ) ) - { - atCoreStatus = getPdnStatusParseToken( pToken, tokenIndex, pPdnStatusBuffers ); - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - LogInfo( ( "getPdnStatusParseToken %s index %d failed", pToken, tokenIndex ) ); - } - - tokenIndex++; - - if( Cellular_ATGetNextTok( &pLocalRespLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetPdnStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pRespLine = NULL; - CellularPdnStatus_t * pPdnStatusBuffers = ( CellularPdnStatus_t * ) pData; - uint8_t numStatusBuffers = ( uint8_t ) dataLen; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const CellularATCommandLine_t * pCommnadItem = NULL; - - if( pContext == NULL ) - { - LogError( ( "GetPdnStatus: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) ) - { - LogError( ( "GetPdnStatus: Response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pPdnStatusBuffers == NULL ) || ( numStatusBuffers < 1U ) ) - { - LogError( ( "GetPdnStatus: PDN Status bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetPdnStatus: no activated PDN" ) ); - pPdnStatusBuffers[ 0 ].contextId = INVALID_PDN_INDEX; - pktStatus = CELLULAR_PKT_STATUS_OK; - } - else - { - pRespLine = pAtResp->pItm->pLine; - - pCommnadItem = pAtResp->pItm; - - while( ( numStatusBuffers != 0U ) && ( pCommnadItem != NULL ) ) - { - pRespLine = pCommnadItem->pLine; - atCoreStatus = getPdnStatusParseLine( pRespLine, pPdnStatusBuffers ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "getPdnStatusParseLine parse %s failed", pRespLine ) ); - break; - } - - pPdnStatusBuffers++; - numStatusBuffers--; - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t buildSocketConnect( CellularSocketHandle_t socketHandle, - char * pCmdBuf ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - char protocol[ 15 ]; - - if( pCmdBuf == NULL ) - { - LogError( ( "buildSocketConnect: Invalid command buffer" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( socketHandle->socketProtocol == CELLULAR_SOCKET_PROTOCOL_TCP ) - { - ( void ) strcpy( protocol, "TCP" ); - } - else - { - ( void ) strcpy( protocol, "UDP SERVICE" ); - } - - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( pCmdBuf, CELLULAR_AT_CMD_MAX_SIZE, - "%s%d,%ld,\"%s\",\"%s\",%d,%d,%d", - "AT+QIOPEN=", - socketHandle->contextId, - socketHandle->socketId, - protocol, - socketHandle->remoteSocketAddress.ipAddress.ipAddress, - socketHandle->remoteSocketAddress.port, - socketHandle->localPort, - socketHandle->dataMode ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pAtResp, - const _socketDataRecv_t * pDataRecv, - uint32_t outBufSize ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const char * pInputLine = NULL; - uint32_t dataLenToCopy = 0; - - /* Check if the received data size is greater than the output buffer size. */ - if( *pDataRecv->pDataLen > outBufSize ) - { - LogError( ( "Data is turncated, received data length %d, out buffer size %d", - *pDataRecv->pDataLen, outBufSize ) ); - dataLenToCopy = outBufSize; - *pDataRecv->pDataLen = outBufSize; - } - else - { - dataLenToCopy = *pDataRecv->pDataLen; - } - - /* Data is stored in the next intermediate response. */ - if( pAtResp->pItm->pNext != NULL ) - { - pInputLine = pAtResp->pItm->pNext->pLine; - - if( ( pInputLine != NULL ) && ( dataLenToCopy > 0U ) ) - { - /* Copy the data to the out buffer. */ - ( void ) memcpy( ( void * ) pDataRecv->pData, ( const void * ) pInputLine, dataLenToCopy ); - } - else - { - LogError( ( "Receive Data: Data pointer NULL" ) ); - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - } - else if( *pDataRecv->pDataLen == 0U ) - { - /* Receive command success but no data. */ - LogDebug( ( "Receive Data: no data" ) ); - } - else - { - LogError( ( "Receive Data: Intermediate response empty" ) ); - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char * pInputLine = NULL, * pToken = NULL; - const _socketDataRecv_t * pDataRecv = ( _socketDataRecv_t * ) pData; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "Receive Data: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "Receive Data: response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pDataRecv == NULL ) || ( pDataRecv->pData == NULL ) || ( pDataRecv->pDataLen == NULL ) ) - { - LogError( ( "Receive Data: Bad param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* parse the datalen. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( int32_t ) 0 ) && ( tempValue < ( ( int32_t ) CELLULAR_MAX_RECV_DATA_LEN + 1 ) ) ) - { - *pDataRecv->pDataLen = ( uint32_t ) tempValue; - } - else - { - LogError( ( "Error in Data Length Processing: No valid digit found. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Process the data buffer. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = getDataFromResp( pAtResp, pDataRecv, dataLen ); - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseQpsmsMode( char * pToken, - CellularPsmSettings_t * pPsmSettings ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - pPsmSettings->mode = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in processing mode. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseQpsmsRau( char * pToken, - CellularPsmSettings_t * pPsmSettings ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( tempValue >= 0 ) - { - pPsmSettings->periodicRauValue = ( uint32_t ) tempValue; - } - else - { - LogError( ( "Error in processing Periodic Processing RAU value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseQpsmsRdyTimer( char * pToken, - CellularPsmSettings_t * pPsmSettings ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( tempValue >= 0 ) - { - pPsmSettings->gprsReadyTimer = ( uint32_t ) tempValue; - } - else - { - LogError( ( "Error in processing Periodic Processing GPRS Ready Timer value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseQpsmsTau( char * pToken, - CellularPsmSettings_t * pPsmSettings ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( tempValue >= 0 ) - { - pPsmSettings->periodicTauValue = ( uint32_t ) tempValue; - } - else - { - LogError( ( "Error in processing Periodic TAU value value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseQpsmsActiveTime( char * pToken, - CellularPsmSettings_t * pPsmSettings ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( tempValue >= 0 ) - { - pPsmSettings->activeTimeValue = ( uint32_t ) tempValue; - } - else - { - LogError( ( "Error in processing Periodic Processing Active time value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseGetPsmToken( char * pToken, - uint8_t tokenIndex, - CellularPsmSettings_t * pPsmSettings ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - switch( tokenIndex ) - { - case QPSMS_POS_MODE: - atCoreStatus = parseQpsmsMode( pToken, pPsmSettings ); - break; - - case QPSMS_POS_RAU: - atCoreStatus = parseQpsmsRau( pToken, pPsmSettings ); - break; - - case QPSMS_POS_RDY_TIMER: - atCoreStatus = parseQpsmsRdyTimer( pToken, pPsmSettings ); - break; - - case QPSMS_POS_TAU: - atCoreStatus = parseQpsmsTau( pToken, pPsmSettings ); - break; - - case QPSMS_POS_ACTIVE_TIME: - atCoreStatus = parseQpsmsActiveTime( pToken, pPsmSettings ); - break; - - default: - LogDebug( ( "Unknown Parameter Position in AT+QPSMS Response" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularRat_t convertRatPriority( char * pRatString ) -{ - CellularRat_t retRat = CELLULAR_RAT_INVALID; - - if( strncmp( pRatString, "01", RAT_PRIOIRTY_STRING_LENGTH ) == 0 ) - { - retRat = CELLULAR_RAT_GSM; - } - else if( strncmp( pRatString, "02", RAT_PRIOIRTY_STRING_LENGTH ) == 0 ) - { - retRat = CELLULAR_RAT_CATM1; - } - else if( strncmp( pRatString, "03", RAT_PRIOIRTY_STRING_LENGTH ) == 0 ) - { - retRat = CELLULAR_RAT_NBIOT; - } - else - { - LogDebug( ( "Invalid RAT string %s", pRatString ) ); - } - - return retRat; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetRatPriority( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularRat_t * pRatPriorities = NULL; - char pTempString[ RAT_PRIOIRTY_STRING_LENGTH + 1 ] = { "\0" }; /* The return RAT has two chars plus NULL char. */ - uint32_t ratIndex = 0; - uint32_t maxRatPriorityLength = ( dataLen > RAT_PRIOIRTY_LIST_LENGTH ? RAT_PRIOIRTY_LIST_LENGTH : dataLen ); - - if( pContext == NULL ) - { - LogError( ( "GetRatPriority: Invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || ( pData == NULL ) || ( dataLen == 0U ) ) - { - LogError( ( "GetRatPriority: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; - pRatPriorities = ( CellularRat_t * ) pData; - - /* Response string +QCFG:"nwscanseq",020301 => pToken : +QCFG:"nwscanseq", pInputLine : 020301. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - /* Response string 020301 => pToken : 020301, pInputLine : NULL. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( strlen( pToken ) != ( RAT_PRIOIRTY_STRING_LENGTH * RAT_PRIOIRTY_LIST_LENGTH ) ) - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - memset( pRatPriorities, CELLULAR_RAT_INVALID, dataLen ); - - for( ratIndex = 0; ratIndex < maxRatPriorityLength; ratIndex++ ) - { - memcpy( pTempString, &pToken[ ratIndex * RAT_PRIOIRTY_STRING_LENGTH ], RAT_PRIOIRTY_STRING_LENGTH ); - pRatPriorities[ ratIndex ] = convertRatPriority( pTempString ); - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetPsmSettings( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL, * pToken = NULL; - uint8_t tokenIndex = 0; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPsmSettings_t * pPsmSettings = NULL; - - if( pContext == NULL ) - { - LogError( ( "GetPsmSettings: Invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || ( pData == NULL ) || ( dataLen != sizeof( CellularPsmSettings_t ) ) ) - { - LogError( ( "GetPsmSettings: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; - pPsmSettings = ( CellularPsmSettings_t * ) pData; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - tokenIndex = 0; - - while( pToken != NULL ) - { - if( tokenIndex == 0 ) - { - atCoreStatus = parseGetPsmToken( pToken, tokenIndex, pPsmSettings ); - } - else - { - parseGetPsmToken( pToken, tokenIndex, pPsmSettings ); - } - - tokenIndex++; - - if( *pInputLine == ',' ) - { - *pInputLine = '\0'; - pToken = pInputLine; - *pToken = '\0'; - pInputLine = &pInputLine[ 1 ]; - } - else if( Cellular_ATGetNextTok( &pInputLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - else - { - /* Empty Else MISRA 15.7 */ - } - } - } - - LogDebug( ( "PSM setting: mode: %d, RAU: %d, RDY_Timer: %d, TAU: %d, Active_time: %d", - pPsmSettings->mode, - pPsmSettings->periodicRauValue, - pPsmSettings->gprsReadyTimer, - pPsmSettings->periodicTauValue, - pPsmSettings->activeTimeValue ) ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t lineLength, - char ** ppDataStart, - uint32_t * pDataLength ) -{ - char * pDataStart = NULL; - uint32_t prefixLineLength = 0U; - int32_t tempValue = 0; - CellularATError_t atResult = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t i = 0; - char pLocalLine[ MAX_QIRD_STRING_PREFIX_STRING + 1 ] = "\0"; - uint32_t localLineLength = MAX_QIRD_STRING_PREFIX_STRING > lineLength ? lineLength : MAX_QIRD_STRING_PREFIX_STRING; - - ( void ) pCallbackContext; - - if( ( pLine == NULL ) || ( ppDataStart == NULL ) || ( pDataLength == NULL ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - /* Check if the message is a data response. */ - if( strncmp( pLine, DATA_PREFIX_STRING, DATA_PREFIX_STRING_LENGTH ) == 0 ) - { - strncpy( pLocalLine, pLine, MAX_QIRD_STRING_PREFIX_STRING ); - pLocalLine[ MAX_QIRD_STRING_PREFIX_STRING ] = '\0'; - pDataStart = pLocalLine; - - /* Add a '\0' char at the end of the line. */ - for( i = 0; i < localLineLength; i++ ) - { - if( ( pDataStart[ i ] == '\r' ) || ( pDataStart[ i ] == '\n' ) ) - { - pDataStart[ i ] = '\0'; - prefixLineLength = i; - break; - } - } - - if( i == localLineLength ) - { - LogDebug( ( "Data prefix invalid line : %s", pLocalLine ) ); - pDataStart = NULL; - } - } - - if( pDataStart != NULL ) - { - atResult = Cellular_ATStrtoi( &pDataStart[ DATA_PREFIX_STRING_LENGTH ], 10, &tempValue ); - - if( ( atResult == CELLULAR_AT_SUCCESS ) && ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) CELLULAR_MAX_RECV_DATA_LEN ) ) - { - if( ( prefixLineLength + DATA_PREFIX_STRING_CHANGELINE_LENGTH ) > lineLength ) - { - /* More data is required. */ - *pDataLength = 0; - pDataStart = NULL; - pktStatus = CELLULAR_PKT_STATUS_SIZE_MISMATCH; - } - else - { - pDataStart = &pLine[ prefixLineLength ]; - pDataStart[ 0 ] = '\0'; - pDataStart = &pDataStart[ DATA_PREFIX_STRING_CHANGELINE_LENGTH ]; - *pDataLength = ( uint32_t ) tempValue; - } - - LogDebug( ( "DataLength %p at pktIo = %d", pDataStart, *pDataLength ) ); - } - else - { - *pDataLength = 0; - pDataStart = NULL; - LogError( ( "Data response received with wrong size" ) ); - } - } - - *ppDataStart = pDataStart; - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t storeAccessModeAndAddress( CellularContext_t * pContext, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pRemoteSocketAddress == NULL ) || ( socketHandle == NULL ) ) - { - LogError( ( "storeAccessModeAndAddress: Invalid socket address" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_ALLOCATED ) - { - LogError( ( "storeAccessModeAndAddress, bad socket state %d", - socketHandle->socketState ) ); - cellularStatus = CELLULAR_INTERNAL_FAILURE; - } - else if( dataAccessMode != CELLULAR_ACCESSMODE_BUFFER ) - { - LogError( ( "storeAccessModeAndAddress, Access mode not supported %d", - dataAccessMode ) ); - cellularStatus = CELLULAR_UNSUPPORTED; - } - else - { - socketHandle->remoteSocketAddress.port = pRemoteSocketAddress->port; - socketHandle->dataMode = dataAccessMode; - socketHandle->remoteSocketAddress.ipAddress.ipAddressType = - pRemoteSocketAddress->ipAddress.ipAddressType; - ( void ) strncpy( socketHandle->remoteSocketAddress.ipAddress.ipAddress, - pRemoteSocketAddress->ipAddress.ipAddress, - CELLULAR_IP_ADDRESS_MAX_SIZE + 1U ); - } - - return cellularStatus; -} - - -/*-----------------------------------------------------------*/ - -static CellularError_t registerDnsEventCallback( cellularModuleContext_t * pModuleContext, - CellularDnsResultEventCallback_t dnsEventCallback, - char * pDnsUsrData ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pModuleContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else - { - pModuleContext->dnsEventCallback = dnsEventCallback; - pModuleContext->pDnsUsrData = pDnsUsrData; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static void _dnsResultCallback( cellularModuleContext_t * pModuleContext, - char * pDnsResult, - char * pDnsUsrData ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pToken = NULL, * pDnsResultStr = pDnsResult; - int32_t dnsResultNumber = 0; - cellularDnsQueryResult_t dnsQueryResult = CELLULAR_DNS_QUERY_UNKNOWN; - - if( pModuleContext != NULL ) - { - if( pModuleContext->dnsResultNumber == ( uint8_t ) 0 ) - { - atCoreStatus = Cellular_ATGetNextTok( &pDnsResultStr, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pDnsResultStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &dnsResultNumber ); - - if( ( atCoreStatus == CELLULAR_AT_SUCCESS ) && ( dnsResultNumber >= 0 ) && - ( dnsResultNumber <= ( int32_t ) UINT8_MAX ) ) - { - pModuleContext->dnsResultNumber = ( uint8_t ) dnsResultNumber; - } - else - { - LogDebug( ( "_dnsResultCallback convert string failed %s", pToken ) ); - } - } - } - else if( ( pModuleContext->dnsIndex < pModuleContext->dnsResultNumber ) && ( pDnsResultStr != NULL ) ) - { - pModuleContext->dnsIndex = pModuleContext->dnsIndex + ( uint8_t ) 1; - - ( void ) strncpy( pDnsUsrData, pDnsResultStr, CELLULAR_IP_ADDRESS_MAX_SIZE ); - ( void ) registerDnsEventCallback( pModuleContext, NULL, NULL ); - dnsQueryResult = CELLULAR_DNS_QUERY_SUCCESS; - - if( xQueueSend( pModuleContext->pktDnsQueue, &dnsQueryResult, ( TickType_t ) 0 ) != pdPASS ) - { - LogDebug( ( "_dnsResultCallback sends pktDnsQueue fail" ) ); - } - } - else - { - LogDebug( ( "_dnsResultCallback spurious DNS response" ) ); - } - } -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetRatPriority( CellularHandle_t cellularHandle, - const CellularRat_t * pRatPriorities, - uint8_t ratPrioritiesLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - uint8_t i = 0; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSetRatPriority = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pRatPriorities == NULL ) || ( ratPrioritiesLength == 0U ) || - ( ratPrioritiesLength > ( uint8_t ) CELLULAR_MAX_RAT_PRIORITY_COUNT ) ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /** Using AT+QCFG="nwscanseq",, to set the RAT priorities while searching. - * can take value 01 for GSM, 02 for CAT M1 and 03 for CAT NB1. - * can take value 0 for take effect after reboot and 1 for take effect immediately. - * If < effect > is omitted, RAT priority takes effect immediately. - * e.g. AT+QCFG="nwscanseq",020301,1 for decreasing RAT Priorities CAT M1, CAT NB1, GSM to take effect immediately. */ - ( void ) strcpy( cmdBuf, "AT+QCFG=\"nwscanseq\"," ); - - while( i < ratPrioritiesLength ) - { - if( pRatPriorities[ i ] == CELLULAR_RAT_GSM ) - { - ( void ) strcat( cmdBuf, "01" ); - } - else if( pRatPriorities[ i ] == CELLULAR_RAT_CATM1 ) - { - ( void ) strcat( cmdBuf, "02" ); - } - else if( pRatPriorities[ i ] == CELLULAR_RAT_NBIOT ) - { - ( void ) strcat( cmdBuf, "03" ); - } - else - { - cellularStatus = CELLULAR_BAD_PARAMETER; - break; - } - - i++; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetRatPriority ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetRatPriority( CellularHandle_t cellularHandle, - CellularRat_t * pRatPriorities, - uint8_t ratPrioritiesLength, - uint8_t * pReceiveRatPrioritesLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t ratIndex = 0; - - CellularAtReq_t atReqSetRatPriority = - { - "AT+QCFG=\"nwscanseq\"", - CELLULAR_AT_WITH_PREFIX, - "+QCFG", - _Cellular_RecvFuncGetRatPriority, - pRatPriorities, - ( uint16_t ) ratPrioritiesLength, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pRatPriorities == NULL ) || ( ratPrioritiesLength == 0U ) || - ( ratPrioritiesLength > ( uint8_t ) CELLULAR_MAX_RAT_PRIORITY_COUNT ) || - ( pReceiveRatPrioritesLength == NULL ) ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetRatPriority ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - for( ratIndex = 0; ratIndex < ratPrioritiesLength; ratIndex++ ) - { - if( pRatPriorities[ ratIndex ] == CELLULAR_RAT_INVALID ) - { - break; - } - } - - *pReceiveRatPrioritesLength = ratIndex; - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetDns( CellularHandle_t cellularHandle, - uint8_t contextId, - const char * pDnsServerAddress ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSetDns = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pDnsServerAddress == NULL ) - { - LogError( ( "Cellular_SetDns: Invalid parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_IsValidPdn( contextId ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s%d,\"%s\"", "AT+QIDNSCFG=", contextId, pDnsServerAddress ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetDns ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SetDns: couldn't set the DNS, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetPsmSettings( CellularHandle_t cellularHandle, - CellularPsmSettings_t * pPsmSettings ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetPsm = - { - "AT+QPSMS?", - CELLULAR_AT_WITH_PREFIX, - "+QPSMS", - _Cellular_RecvFuncGetPsmSettings, - pPsmSettings, - sizeof( CellularPsmSettings_t ), - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pPsmSettings == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* initialize the data. */ - ( void ) memset( pPsmSettings, 0, sizeof( CellularPsmSettings_t ) ); - pPsmSettings->mode = 0xFF; - - /* we should always query the PSMsettings from the network. */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetPsm ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_GetPsmSettings: couldn't retrieve PSM settings" ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static uint32_t appendBinaryPattern( char * cmdBuf, - uint32_t cmdLen, - uint32_t value, - bool endOfString ) -{ - uint32_t retLen = 0; - - if( cmdBuf != NULL ) - { - if( value != 0U ) - { - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, cmdLen, "\"" PRINTF_BINARY_PATTERN_INT8 "\"%c", - PRINTF_BYTE_TO_BINARY_INT8( value ), endOfString ? '\0' : ',' ); - } - else - { - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, cmdLen, "%c", endOfString ? '\0' : ',' ); - } - - retLen = strlen( cmdBuf ); - } - - return retLen; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t socketSendDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t * pBytesRead ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - if( ( pLine == NULL ) || ( pBytesRead == NULL ) ) - { - LogError( ( "socketSendDataPrefix: pLine is invalid or pBytesRead is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pCallbackContext != NULL ) - { - LogError( ( "socketSendDataPrefix: pCallbackContext is not NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( *pBytesRead != 2U ) - { - LogDebug( ( "socketSendDataPrefix: pBytesRead %u %s is not 1", *pBytesRead, pLine ) ); - } - else - { - /* After the data prefix, there should not be any data in stream. - * Cellular commmon processes AT command in lines. Add a '\0' after '>'. */ - if( strcmp( pLine, "> " ) == 0 ) - { - pLine[ 1 ] = '\n'; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetPsmSettings( CellularHandle_t cellularHandle, - const CellularPsmSettings_t * pPsmSettings ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - uint32_t cmdBufLen = 0; - CellularAtReq_t atReqSetPsm = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pPsmSettings == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "AT+QPSMS=%d,", pPsmSettings->mode ); - cmdBufLen = strlen( cmdBuf ); - cmdBufLen = cmdBufLen + appendBinaryPattern( &cmdBuf[ cmdBufLen ], ( CELLULAR_AT_CMD_MAX_SIZE - cmdBufLen ), - pPsmSettings->periodicRauValue, false ); - cmdBufLen = cmdBufLen + appendBinaryPattern( &cmdBuf[ cmdBufLen ], ( CELLULAR_AT_CMD_MAX_SIZE - cmdBufLen ), - pPsmSettings->gprsReadyTimer, false ); - cmdBufLen = cmdBufLen + appendBinaryPattern( &cmdBuf[ cmdBufLen ], ( CELLULAR_AT_CMD_MAX_SIZE - cmdBufLen ), - pPsmSettings->periodicTauValue, false ); - cmdBufLen = cmdBufLen + appendBinaryPattern( &cmdBuf[ cmdBufLen ], ( CELLULAR_AT_CMD_MAX_SIZE - cmdBufLen ), - pPsmSettings->activeTimeValue, true ); - - LogDebug( ( "PSM setting: %s ", cmdBuf ) ); - - if( cmdBufLen < CELLULAR_AT_CMD_MAX_SIZE ) - { - /* we should always query the PSMsettings from the network. */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetPsm ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SetPsmSettings: couldn't set PSM settings" ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - else - { - cellularStatus = CELLULAR_NO_MEMORY; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_DeactivatePdn( CellularHandle_t cellularHandle, - uint8_t contextId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqDeactPdn = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_IsValidPdn( contextId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%d", "AT+QIDEACT=", contextId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqDeactPdn, PDN_DEACTIVATION_PACKET_REQ_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_DeactivatePdn: can't deactivate PDN, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ActivatePdn( CellularHandle_t cellularHandle, - uint8_t contextId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - - CellularAtReq_t atReqActPdn = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_IsValidPdn( contextId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%d", "AT+QIACT=", contextId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqActPdn, PDN_ACTIVATION_PACKET_REQ_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_ActivatePdn: can't activate PDN, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetPdnConfig( CellularHandle_t cellularHandle, - uint8_t contextId, - const CellularPdnConfig_t * pPdnConfig ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSetPdn = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - if( pPdnConfig == NULL ) - { - LogError( ( "Cellular_ATCommandRaw: Input parameter is NULL" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = _Cellular_IsValidPdn( contextId ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s%d,%d,\"%s\",\"%s\",\"%s\",%d", - "AT+QICSGP=", - contextId, - pPdnConfig->pdnContextType, - pPdnConfig->apnName, - pPdnConfig->username, - pPdnConfig->password, - pPdnConfig->pdnAuthType ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetPdn ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SetPdnConfig: can't set PDN, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSignalInfo( CellularHandle_t cellularHandle, - CellularSignalInfo_t * pSignalInfo ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularRat_t rat = CELLULAR_RAT_INVALID; - CellularAtReq_t atReqQuerySignalInfo = - { - "AT+QCSQ", - CELLULAR_AT_WITH_PREFIX, - "+QCSQ", - _Cellular_RecvFuncGetSignalInfo, - pSignalInfo, - sizeof( CellularSignalInfo_t ), - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pSignalInfo == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetCurrentRat( pContext, &rat ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqQuerySignalInfo ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - /* If the convert failed, the API will return CELLULAR_INVALID_SIGNAL_BAR_VALUE in bars field. */ - ( void ) _Cellular_ComputeSignalBars( rat, pSignalInfo ); - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_SocketRecv( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint8_t * pBuffer, - uint32_t bufferLength, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint32_t * pReceivedDataLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - uint32_t recvTimeout = DATA_READ_TIMEOUT_MS; - uint32_t recvLen = bufferLength; - _socketDataRecv_t dataRecv = - { - pReceivedDataLength, - pBuffer, - NULL - }; - CellularAtReq_t atReqSocketRecv = - { - cmdBuf, - CELLULAR_AT_MULTI_DATA_WO_PREFIX, - "+QIRD", - _Cellular_RecvFuncData, - ( void * ) &dataRecv, - bufferLength, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "_Cellular_CheckLibraryStatus failed." ) ); - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketRecv: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pBuffer == NULL ) || ( pReceivedDataLength == NULL ) || ( bufferLength == 0U ) ) - { - LogError( ( "Cellular_SocketRecv: Bad input Param." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_CONNECTED ) - { - /* Check the socket connection state. */ - LogInfo( ( "Cellular_SocketRecv: socket state %d is not connected.", socketHandle->socketState ) ); - - if( ( socketHandle->socketState == SOCKETSTATE_ALLOCATED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - cellularStatus = CELLULAR_SOCKET_NOT_CONNECTED; - } - else - { - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - } - else - { - /* Update recvLen to maximum module length. */ - if( CELLULAR_MAX_RECV_DATA_LEN <= bufferLength ) - { - recvLen = ( uint32_t ) CELLULAR_MAX_RECV_DATA_LEN; - } - - /* Update receive timeout to default timeout if not set with setsocketopt. */ - if( socketHandle->recvTimeoutMs != 0U ) - { - recvTimeout = socketHandle->recvTimeoutMs; - } - - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, - "%s%ld,%ld", "AT+QIRD=", socketHandle->socketId, recvLen ); - pktStatus = _Cellular_TimeoutAtcmdDataRecvRequestWithCallback( pContext, - atReqSocketRecv, recvTimeout, socketRecvDataPrefix, NULL ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - /* Reset data handling parameters. */ - LogError( ( "_Cellular_RecvData: Data Receive fail, pktStatus: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_SocketSend( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - const uint8_t * pData, - uint32_t dataLength, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint32_t * pSentDataLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t sendTimeout = DATA_SEND_TIMEOUT_MS; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketSend = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - CellularAtDataReq_t atDataReqSocketSend = - { - pData, - dataLength, - pSentDataLength, - NULL, - 0 - }; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "_Cellular_CheckLibraryStatus failed." ) ); - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketSend: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( pSentDataLength == NULL ) || ( dataLength == 0U ) ) - { - LogError( ( "Cellular_SocketSend: Invalid parameter." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_CONNECTED ) - { - /* Check the socket connection state. */ - LogInfo( ( "Cellular_SocketSend: socket state %d is not connected.", socketHandle->socketState ) ); - - if( ( socketHandle->socketState == SOCKETSTATE_ALLOCATED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - cellularStatus = CELLULAR_SOCKET_NOT_CONNECTED; - } - else - { - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - } - else - { - /* Send data length check. */ - if( dataLength > ( uint32_t ) CELLULAR_MAX_SEND_DATA_LEN ) - { - atDataReqSocketSend.dataLen = ( uint32_t ) CELLULAR_MAX_SEND_DATA_LEN; - } - - /* Check send timeout. If not set by setsockopt, use default value. */ - if( socketHandle->sendTimeoutMs != 0U ) - { - sendTimeout = socketHandle->sendTimeoutMs; - } - - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%ld,%ld", - "AT+QISEND=", socketHandle->socketId, atDataReqSocketSend.dataLen ); - - pktStatus = _Cellular_AtcmdDataSend( pContext, atReqSocketSend, atDataReqSocketSend, - socketSendDataPrefix, NULL, - PACKET_REQ_TIMEOUT_MS, sendTimeout, 0U ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketSend: Data send fail, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketClose( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSockClose = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( socketHandle == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else - { - if( socketHandle->socketState == SOCKETSTATE_CONNECTING ) - { - LogWarn( ( "Cellular_SocketClose: Socket state is SOCKETSTATE_CONNECTING." ) ); - } - - if( ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) || - ( socketHandle->socketState == SOCKETSTATE_CONNECTED ) || - ( socketHandle->socketState == SOCKETSTATE_DISCONNECTED ) ) - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%ld", "AT+QICLOSE=", socketHandle->socketId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSockClose, - SOCKET_DISCONNECT_PACKET_REQ_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketClose: Socket close failed, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - } - } - - /* Ignore the result from the info, and force to remove the socket. */ - cellularStatus = _Cellular_RemoveSocketData( pContext, socketHandle ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketConnect( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketConnect = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Cellular_SocketConnect: _Cellular_CheckLibraryStatus failed." ) ); - } - else if( pRemoteSocketAddress == NULL ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket address." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( socketHandle->socketState == SOCKETSTATE_CONNECTED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - LogError( ( "Cellular_SocketConnect: Not allowed in state %d.", socketHandle->socketState ) ); - cellularStatus = CELLULAR_NOT_ALLOWED; - } - else - { - cellularStatus = storeAccessModeAndAddress( pContext, socketHandle, dataAccessMode, pRemoteSocketAddress ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Builds the Socket connect command. */ - cellularStatus = buildSocketConnect( socketHandle, cmdBuf ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Set the socket state to connecting state. If cellular modem returns error, - * revert the state to allocated state. */ - socketHandle->socketState = SOCKETSTATE_CONNECTING; - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketConnect, - SOCKET_CONNECT_PACKET_REQ_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketConnect: Socket connect failed, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - /* Revert the state to allocated state. */ - socketHandle->socketState = SOCKETSTATE_ALLOCATED; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_GetPdnStatus( CellularHandle_t cellularHandle, - CellularPdnStatus_t * pPdnStatusBuffers, - uint8_t numStatusBuffers, - uint8_t * pNumStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - const CellularPdnStatus_t * pTempPdnStatusBuffer = pPdnStatusBuffers; - uint8_t numBuffers = 0; - CellularAtReq_t atReqGetPdnStatus = - { - "AT+QIACT?", - CELLULAR_AT_WITH_PREFIX, - "+QIACT", - _Cellular_RecvFuncGetPdnStatus, - pPdnStatusBuffers, - numStatusBuffers, - }; - - if( ( pTempPdnStatusBuffer == NULL ) || ( pNumStatus == NULL ) || ( numStatusBuffers < 1u ) ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - LogWarn( ( "_Cellular_GetPdnStatus: Bad input Parameter " ) ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetPdnStatus ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Populate the Valid number of statuses. */ - *pNumStatus = 0; - numBuffers = numStatusBuffers; - - while( numBuffers != 0U ) - { - /* Check if the PDN state is valid. The context ID of the first - * invalid PDN status is set to FF. */ - if( ( pTempPdnStatusBuffer->contextId <= CELLULAR_PDN_CONTEXT_ID_MAX ) && - ( pTempPdnStatusBuffer->contextId != INVALID_PDN_INDEX ) ) - { - ( *pNumStatus ) += 1U; - } - else - { - break; - } - - numBuffers--; - pTempPdnStatusBuffer++; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSimCardStatus( CellularHandle_t cellularHandle, - CellularSimCardStatus_t * pSimCardStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetSimCardStatus = - { - "AT+QSIMSTAT?", - CELLULAR_AT_WITH_PREFIX, - "+QSIMSTAT", - _Cellular_RecvFuncGetSimCardStatus, - &pSimCardStatus->simCardState, - sizeof( CellularSimCardState_t ), - }; - CellularAtReq_t atReqGetSimLockStatus = - { - "AT+CPIN?", - CELLULAR_AT_WITH_PREFIX, - "+CPIN", - _Cellular_RecvFuncGetSimLockStatus, - &pSimCardStatus->simCardLockState, - sizeof( CellularSimCardLockState_t ), - }; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pSimCardStatus == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Initialize the sim state and the sim lock state. */ - pSimCardStatus->simCardState = CELLULAR_SIM_CARD_UNKNOWN; - pSimCardStatus->simCardLockState = CELLULAR_SIM_CARD_LOCK_UNKNOWN; - - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetSimCardStatus ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetSimLockStatus ); - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - LogDebug( ( "_Cellular_GetSimStatus, Sim Insert State[%d], Lock State[%d]", - pSimCardStatus->simCardState, pSimCardStatus->simCardLockState ) ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSimCardInfo( CellularHandle_t cellularHandle, - CellularSimCardInfo_t * pSimCardInfo ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - CellularAtReq_t atReqGetIccid = - { - "AT+QCCID", - CELLULAR_AT_WITH_PREFIX, - "+QCCID", - _Cellular_RecvFuncGetIccid, - pSimCardInfo->iccid, - CELLULAR_ICCID_MAX_SIZE + 1U, - }; - CellularAtReq_t atReqGetImsi = - { - "AT+CIMI", - CELLULAR_AT_WO_PREFIX, - NULL, - _Cellular_RecvFuncGetImsi, - pSimCardInfo->imsi, - CELLULAR_IMSI_MAX_SIZE + 1U, - }; - CellularAtReq_t atReqGetHplmn = - { - "AT+CRSM=176,28514,0,0,0", - CELLULAR_AT_WITH_PREFIX, - "+CRSM", - _Cellular_RecvFuncGetHplmn, - &pSimCardInfo->plmn, - sizeof( CellularPlmnInfo_t ), - }; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pSimCardInfo == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - ( void ) memset( pSimCardInfo, 0, sizeof( CellularSimCardInfo_t ) ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetImsi ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetHplmn ); - } - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetIccid ); - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - else - { - LogDebug( ( "SimInfo updated: IMSI:%s, Hplmn:%s%s, ICCID:%s", - pSimCardInfo->imsi, pSimCardInfo->plmn.mcc, pSimCardInfo->plmn.mnc, - pSimCardInfo->iccid ) ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcSignalStrengthChangedCallback( CellularHandle_t cellularHandle, - CellularUrcSignalStrengthChangedCallback_t signalStrengthChangedCallback, - void * pCallbackContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - - /* pContext is checked in the common library. */ - cellularStatus = Cellular_CommonRegisterUrcSignalStrengthChangedCallback( - cellularHandle, signalStrengthChangedCallback, pCallbackContext ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( signalStrengthChangedCallback != NULL ) - { - cellularStatus = controlSignalStrengthIndication( pContext, true ); - } - else - { - cellularStatus = controlSignalStrengthIndication( pContext, false ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetHostByName( CellularHandle_t cellularHandle, - uint8_t contextId, - const char * pcHostName, - char * pResolvedAddress ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_QUERY_DNS_MAX_SIZE ]; - cellularDnsQueryResult_t dnsQueryResult = CELLULAR_DNS_QUERY_UNKNOWN; - cellularModuleContext_t * pModuleContext = NULL; - CellularAtReq_t atReqQueryDns = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pcHostName == NULL ) || ( pResolvedAddress == NULL ) ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_IsValidPdn( contextId ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - PlatformMutex_Lock( &pModuleContext->dnsQueryMutex ); - pModuleContext->dnsResultNumber = 0; - pModuleContext->dnsIndex = 0; - ( void ) xQueueReset( pModuleContext->pktDnsQueue ); - cellularStatus = registerDnsEventCallback( pModuleContext, _dnsResultCallback, pResolvedAddress ); - } - - /* Send the AT command and wait the URC result. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_QUERY_DNS_MAX_SIZE, - "AT+QIDNSGIP=%u,\"%s\"", contextId, pcHostName ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqQueryDns ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_GetHostByName: couldn't resolve host name" ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - PlatformMutex_Unlock( &pModuleContext->dnsQueryMutex ); - } - } - - /* URC handler calls the callback to unblock this function. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( xQueueReceive( pModuleContext->pktDnsQueue, &dnsQueryResult, - pdMS_TO_TICKS( DNS_QUERY_TIMEOUT_MS ) ) == pdTRUE ) - { - if( dnsQueryResult != CELLULAR_DNS_QUERY_SUCCESS ) - { - cellularStatus = CELLULAR_UNKNOWN; - } - } - else - { - ( void ) registerDnsEventCallback( pModuleContext, NULL, NULL ); - cellularStatus = CELLULAR_TIMEOUT; - } - - PlatformMutex_Unlock( &pModuleContext->dnsQueryMutex ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -CellularError_t Cellular_Init( CellularHandle_t * pCellularHandle, - const CellularCommInterface_t * pCommInterface ) -{ - CellularTokenTable_t cellularTokenTable = - { - .pCellularUrcHandlerTable = CellularUrcHandlerTable, - .cellularPrefixToParserMapSize = CellularUrcHandlerTableSize, - .pCellularSrcTokenErrorTable = CellularSrcTokenErrorTable, - .cellularSrcTokenErrorTableSize = CellularSrcTokenErrorTableSize, - .pCellularSrcTokenSuccessTable = CellularSrcTokenSuccessTable, - .cellularSrcTokenSuccessTableSize = CellularSrcTokenSuccessTableSize, - .pCellularUrcTokenWoPrefixTable = CellularUrcTokenWoPrefixTable, - .cellularUrcTokenWoPrefixTableSize = CellularUrcTokenWoPrefixTableSize, - .pCellularSrcExtraTokenSuccessTable = NULL, - .cellularSrcExtraTokenSuccessTableSize = 0 - }; - - return Cellular_CommonInit( pCellularHandle, pCommInterface, &cellularTokenTable ); -} - -/*-----------------------------------------------------------*/ diff --git a/modules/bg96/cellular_bg96_urc_handler.c b/modules/bg96/cellular_bg96_urc_handler.c deleted file mode 100644 index 6791a808..00000000 --- a/modules/bg96/cellular_bg96_urc_handler.c +++ /dev/null @@ -1,807 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include -#include - -#include "cellular_platform.h" -#include "cellular_types.h" -#include "cellular_common.h" -#include "cellular_common_api.h" -#include "cellular_common_portable.h" -#include "cellular_bg96.h" - -/*-----------------------------------------------------------*/ - -static void _Cellular_ProcessPowerDown( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessPsmPowerDown( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessModemRdy( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessSocketOpen( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessSocketurc( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessSimstat( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessIndication( CellularContext_t * pContext, - char * pInputLine ); - -/*-----------------------------------------------------------*/ - -/* Try to Keep this map in Alphabetical order. */ -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularAtParseTokenMap_t CellularUrcHandlerTable[] = -{ - { "CEREG", Cellular_CommonUrcProcessCereg }, - { "CGREG", Cellular_CommonUrcProcessCgreg }, - { "CREG", Cellular_CommonUrcProcessCreg }, - { "NORMAL POWER DOWN", _Cellular_ProcessPowerDown }, - { "PSM POWER DOWN", _Cellular_ProcessPsmPowerDown }, - { "QIND", _Cellular_ProcessIndication }, - { "QIOPEN", _Cellular_ProcessSocketOpen }, - { "QIURC", _Cellular_ProcessSocketurc }, - { "QSIMSTAT", _Cellular_ProcessSimstat }, - { "RDY", _Cellular_ProcessModemRdy } -}; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcHandlerTableSize = sizeof( CellularUrcHandlerTable ) / sizeof( CellularAtParseTokenMap_t ); - -/*-----------------------------------------------------------*/ - -/* internal function of _parseSocketOpen to reduce complexity. */ -static CellularPktStatus_t _parseSocketOpenNextTok( const char * pToken, - uint32_t sockIndex, - CellularSocketContext_t * pSocketData ) -{ - int32_t sockStatus = 0; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &sockStatus ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( sockStatus != 0 ) - { - pSocketData->socketState = SOCKETSTATE_DISCONNECTED; - LogError( ( "_parseSocketOpen: Socket open failed, conn %d, status %d", sockIndex, sockStatus ) ); - } - else - { - pSocketData->socketState = SOCKETSTATE_CONNECTED; - LogDebug( ( "_parseSocketOpen: Socket open success, conn %d", sockIndex ) ); - } - - /* Indicate the upper layer about the socket open status. */ - if( pSocketData->openCallback != NULL ) - { - if( sockStatus != 0 ) - { - pSocketData->openCallback( CELLULAR_URC_SOCKET_OPEN_FAILED, - pSocketData, pSocketData->pOpenCallbackContext ); - } - else - { - pSocketData->openCallback( CELLULAR_URC_SOCKET_OPENED, - pSocketData, pSocketData->pOpenCallbackContext ); - } - } - else - { - LogError( ( ( "_parseSocketOpen: Socket open callback for conn %d is not set!!", sockIndex ) ) ); - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessSocketOpen( CellularContext_t * pContext, - char * pInputLine ) -{ - char * pUrcStr = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - uint32_t sockIndex = 0; - int32_t tempValue = 0; - CellularSocketContext_t * pSocketData = NULL; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( pInputLine == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pUrcStr = pInputLine; - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pUrcStr ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pUrcStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue < ( int32_t ) CELLULAR_NUM_SOCKET_MAX ) ) - { - sockIndex = ( uint32_t ) tempValue; - } - else - { - LogError( ( ( "Error processing in Socket index. token %s", pToken ) ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSocketData = _Cellular_GetSocketData( pContext, sockIndex ); - - if( pSocketData != NULL ) - { - atCoreStatus = Cellular_ATGetNextTok( &pUrcStr, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pktStatus = _parseSocketOpenNextTok( pToken, sockIndex, pSocketData ); - } - } - else - { - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogDebug( ( "Socket Open URC Parse failure" ) ); - } -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t _parseUrcIndicationCsq( const CellularContext_t * pContext, - char * pUrcStr ) -{ - char * pToken = NULL; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - int32_t retStrtoi = 0; - int16_t csqRssi = CELLULAR_INVALID_SIGNAL_VALUE, csqBer = CELLULAR_INVALID_SIGNAL_VALUE; - CellularSignalInfo_t signalInfo = { 0 }; - char * pLocalUrcStr = pUrcStr; - - if( ( pContext == NULL ) || ( pUrcStr == NULL ) ) - { - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - else - { - /* Parse the RSSI index from string and convert it. */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalUrcStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &retStrtoi ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( retStrtoi >= INT16_MIN ) && ( retStrtoi <= ( int32_t ) INT16_MAX ) ) - { - cellularStatus = _Cellular_ConvertCsqSignalRssi( ( int16_t ) retStrtoi, &csqRssi ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - /* Parse the BER index from string and convert it. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalUrcStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &retStrtoi ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( retStrtoi >= INT16_MIN ) && - ( retStrtoi <= ( int32_t ) INT16_MAX ) ) - { - cellularStatus = _Cellular_ConvertCsqSignalBer( ( int16_t ) retStrtoi, &csqBer ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - /* Handle the callback function. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - signalInfo.rssi = csqRssi; - signalInfo.rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - signalInfo.rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - signalInfo.ber = csqBer; - signalInfo.bars = CELLULAR_INVALID_SIGNAL_BAR_VALUE; - _Cellular_SignalStrengthChangedCallback( pContext, CELLULAR_URC_EVENT_SIGNAL_CHANGED, &signalInfo ); - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessIndication( CellularContext_t * pContext, - char * pInputLine ) -{ - char * pUrcStr = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - /* Check context status. */ - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( pInputLine == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pUrcStr = pInputLine; - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pUrcStr ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pUrcStr ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pUrcStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( strstr( pToken, "csq" ) != NULL ) - { - pktStatus = _parseUrcIndicationCsq( ( const CellularContext_t * ) pContext, pUrcStr ); - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogDebug( ( "UrcIndication Parse failure" ) ); - } -} - -/*-----------------------------------------------------------*/ - -static void _informDataReadyToUpperLayer( CellularSocketContext_t * pSocketData ) -{ - /* Indicate the upper layer about the data reception. */ - if( ( pSocketData != NULL ) && ( pSocketData->dataReadyCallback != NULL ) ) - { - pSocketData->dataReadyCallback( pSocketData, pSocketData->pDataReadyCallbackContext ); - } - else - { - LogError( ( ( "_parseSocketUrc: Data ready callback not set!!" ) ) ); - } -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t _parseSocketUrcRecv( const CellularContext_t * pContext, - char * pUrcStr ) -{ - char * pToken = NULL; - char * pLocalUrcStr = pUrcStr; - int32_t tempValue = 0; - uint32_t sockIndex = 0; - CellularSocketContext_t * pSocketData = NULL; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - atCoreStatus = Cellular_ATGetNextTok( &pLocalUrcStr, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && ( tempValue < ( int32_t ) CELLULAR_NUM_SOCKET_MAX ) ) - { - sockIndex = ( uint32_t ) tempValue; - } - else - { - LogError( ( ( "Error in processing SockIndex. Token %s", pToken ) ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSocketData = _Cellular_GetSocketData( pContext, sockIndex ); - - if( pSocketData != NULL ) - { - if( pSocketData->dataMode == CELLULAR_ACCESSMODE_BUFFER ) - { - /* Data received indication in buffer mode, need to fetch the data. */ - LogDebug( ( "Data Received on socket Conn Id %d", sockIndex ) ); - _informDataReadyToUpperLayer( pSocketData ); - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t _parseSocketUrcClosed( const CellularContext_t * pContext, - char * pUrcStr ) -{ - char * pToken = NULL; - char * pLocalUrcStr = pUrcStr; - int32_t tempValue = 0; - uint32_t sockIndex = 0; - CellularSocketContext_t * pSocketData = NULL; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - atCoreStatus = Cellular_ATGetNextTok( &pLocalUrcStr, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( tempValue < ( int32_t ) CELLULAR_NUM_SOCKET_MAX ) - { - sockIndex = ( uint32_t ) tempValue; - } - else - { - LogError( ( ( "Error in processing Socket Index. Token %s", pToken ) ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSocketData = _Cellular_GetSocketData( pContext, sockIndex ); - - if( pSocketData != NULL ) - { - pSocketData->socketState = SOCKETSTATE_DISCONNECTED; - LogDebug( ( "Socket closed. Conn Id %d", sockIndex ) ); - - /* Indicate the upper layer about the socket close. */ - if( pSocketData->closedCallback != NULL ) - { - pSocketData->closedCallback( pSocketData, pSocketData->pClosedCallbackContext ); - } - else - { - LogInfo( ( "_parseSocketUrc: Socket close callback not set!!" ) ); - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t _parseSocketUrcAct( const CellularContext_t * pContext, - char * pUrcStr ) -{ - int32_t tempValue = 0; - char * pToken = NULL; - char * pLocalUrcStr = pUrcStr; - uint8_t contextId = 0; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - atCoreStatus = Cellular_ATGetNextTok( &pLocalUrcStr, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( ( tempValue >= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MIN ) && - ( tempValue <= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MAX ) ) ) - { - contextId = ( uint8_t ) tempValue; - - if( _Cellular_IsValidPdn( contextId ) == CELLULAR_SUCCESS ) - { - LogDebug( ( "PDN deactivated. Context Id %d", contextId ) ); - /* Indicate the upper layer about the PDN deactivate. */ - _Cellular_PdnEventCallback( pContext, CELLULAR_URC_EVENT_PDN_DEACTIVATED, contextId ); - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - LogError( ( ( "Error in processing Context Id. Token %s", pToken ) ) ); - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t _parseSocketUrcDns( const CellularContext_t * pContext, - char * pUrcStr ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - cellularModuleContext_t * pModuleContext = NULL; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( pUrcStr == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - } - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - if( pModuleContext->dnsEventCallback != NULL ) - { - pModuleContext->dnsEventCallback( pModuleContext, pUrcStr, pModuleContext->pDnsUsrData ); - } - else - { - LogDebug( ( "_parseSocketUrcDns: spurious DNS response!!" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_DATA; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessSocketurc( CellularContext_t * pContext, - char * pInputLine ) -{ - char * pUrcStr = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( pInputLine == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pUrcStr = pInputLine; - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pUrcStr ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pUrcStr ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pUrcStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Check if this is a data receive indication. */ - - /* this whole if as a function and return pktstatus - * take iotat_getnexttok inside - * convert atcore status to pktstatus. */ - if( strstr( pToken, "recv" ) != NULL ) - { - pktStatus = _parseSocketUrcRecv( pContext, pUrcStr ); - } - else if( strcmp( pToken, "closed" ) == 0 ) - { - pktStatus = _parseSocketUrcClosed( pContext, pUrcStr ); - } - else if( strcmp( pToken, "pdpdeact" ) == 0 ) - { - pktStatus = _parseSocketUrcAct( pContext, pUrcStr ); - } - else if( strcmp( pToken, "dnsgip" ) == 0 ) - { - pktStatus = _parseSocketUrcDns( pContext, pUrcStr ); - } - else - { - /* Empty else MISRA 15.7 */ - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogDebug( ( "Socketurc Parse failure" ) ); - } -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessSimstat( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularSimCardState_t simCardState = CELLULAR_SIM_CARD_UNKNOWN; - - if( pContext != NULL ) - { - ( void ) _Cellular_ParseSimstat( pInputLine, &simCardState ); - } -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessPowerDown( CellularContext_t * pContext, - char * pInputLine ) -{ - /* The token is the pInputLine. No need to process the pInputLine. */ - ( void ) pInputLine; - - if( pContext == NULL ) - { - LogError( ( ( "_Cellular_ProcessPowerDown: Context not set" ) ) ); - } - else - { - LogDebug( ( "_Cellular_ProcessPowerDown: Modem Power down event received" ) ); - _Cellular_ModemEventCallback( pContext, CELLULAR_MODEM_EVENT_POWERED_DOWN ); - } -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessPsmPowerDown( CellularContext_t * pContext, - char * pInputLine ) -{ - /* The token is the pInputLine. No need to process the pInputLine. */ - ( void ) pInputLine; - - if( pContext == NULL ) - { - LogError( ( ( "_Cellular_ProcessPowerDown: Context not set" ) ) ); - } - else - { - LogDebug( ( "_Cellular_ProcessPsmPowerDown: Modem PSM power down event received" ) ); - _Cellular_ModemEventCallback( pContext, CELLULAR_MODEM_EVENT_PSM_ENTER ); - } -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static void _Cellular_ProcessModemRdy( CellularContext_t * pContext, - char * pInputLine ) -{ - /* The token is the pInputLine. No need to process the pInputLine. */ - ( void ) pInputLine; - - if( pContext == NULL ) - { - LogWarn( ( "_Cellular_ProcessModemRdy: Context not set" ) ); - } - else - { - LogDebug( ( "_Cellular_ProcessModemRdy: Modem Ready event received" ) ); - _Cellular_ModemEventCallback( pContext, CELLULAR_MODEM_EVENT_BOOTUP_OR_REBOOT ); - } -} - -/*-----------------------------------------------------------*/ - -/* Cellular common prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularPktStatus_t _Cellular_ParseSimstat( char * pInputStr, - CellularSimCardState_t * pSimState ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pToken = NULL; - char * pLocalInputStr = pInputStr; - int32_t tempValue = 0; - - if( ( pInputStr == NULL ) || ( strlen( pInputStr ) == 0U ) || - ( strlen( pInputStr ) < 2U ) || ( pSimState == NULL ) ) - { - LogError( ( ( "_Cellular_ProcessQsimstat Input data is invalid %s", pInputStr ) ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputStr, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - LogDebug( ( "QSIMSTAT URC Enable: %s", pToken ) ); - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - LogDebug( ( " Sim insert status: %s", pToken ) ); - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue < ( int32_t ) CELLULAR_SIM_CARD_STATUS_MAX ) ) - { - /* Variable "tempValue" is ensured that it is valid and within - * a valid range. Hence, assigning the value at the pointer of - * type cellular_SimCardState_t with an enum cast. */ - /* coverity[misra_c_2012_rule_10_5_violation] */ - *pSimState = ( CellularSimCardState_t ) tempValue; - } - else - { - LogError( ( ( "Error in processing SIM state. token %s", pToken ) ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ diff --git a/modules/bg96/cellular_bg96_wrapper.c b/modules/bg96/cellular_bg96_wrapper.c deleted file mode 100644 index c579ff7c..00000000 --- a/modules/bg96/cellular_bg96_wrapper.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* The config header is always included first. */ -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include - -#include "cellular_platform.h" -#include "cellular_types.h" -#include "cellular_api.h" -#include "cellular_common.h" -#include "cellular_common_api.h" - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_Cleanup( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonCleanup( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcNetworkRegistrationEventCallback( CellularHandle_t cellularHandle, - CellularUrcNetworkRegistrationCallback_t networkRegistrationCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcNetworkRegistrationEventCallback( cellularHandle, networkRegistrationCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcPdnEventCallback( CellularHandle_t cellularHandle, - CellularUrcPdnEventCallback_t pdnEventCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcPdnEventCallback( cellularHandle, pdnEventCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcGenericCallback( CellularHandle_t cellularHandle, - CellularUrcGenericCallback_t genericCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcGenericCallback( cellularHandle, genericCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterModemEventCallback( CellularHandle_t cellularHandle, - CellularModemEventCallback_t modemEventCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterModemEventCallback( cellularHandle, modemEventCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ATCommandRaw( CellularHandle_t cellularHandle, - const char * pATCommandPrefix, - const char * pATCommandPayload, - CellularATCommandType_t atCommandType, - CellularATCommandResponseReceivedCallback_t responseReceivedCallback, - void * pData, - uint16_t dataLen ) -{ - return Cellular_CommonATCommandRaw( cellularHandle, pATCommandPrefix, pATCommandPayload, atCommandType, - responseReceivedCallback, pData, dataLen ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_CreateSocket( CellularHandle_t cellularHandle, - uint8_t pdnContextId, - CellularSocketDomain_t socketDomain, - CellularSocketType_t socketType, - CellularSocketProtocol_t socketProtocol, - CellularSocketHandle_t * pSocketHandle ) -{ - return Cellular_CommonCreateSocket( cellularHandle, pdnContextId, socketDomain, socketType, - socketProtocol, pSocketHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketSetSockOpt( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketOptionLevel_t optionLevel, - CellularSocketOption_t option, - const uint8_t * pOptionValue, - uint32_t optionValueLength ) -{ - return Cellular_CommonSocketSetSockOpt( cellularHandle, socketHandle, optionLevel, option, - pOptionValue, optionValueLength ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterDataReadyCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketDataReadyCallback_t dataReadyCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterDataReadyCallback( cellularHandle, socketHandle, - dataReadyCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterSocketOpenCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketOpenCallback_t socketOpenCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterSocketOpenCallback( cellularHandle, socketHandle, - socketOpenCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterClosedCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketClosedCallback_t closedCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterClosedCallback( cellularHandle, socketHandle, - closedCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RfOn( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonRfOn( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RfOff( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonRfOff( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetIPAddress( CellularHandle_t cellularHandle, - uint8_t contextId, - char * pBuffer, - uint32_t bufferLength ) -{ - return Cellular_CommonGetIPAddress( cellularHandle, contextId, pBuffer, bufferLength ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetModemInfo( CellularHandle_t cellularHandle, - CellularModemInfo_t * pModemInfo ) -{ - return Cellular_CommonGetModemInfo( cellularHandle, pModemInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetEidrxSettings( CellularHandle_t cellularHandle, - CellularEidrxSettingsList_t * pEidrxSettingsList ) -{ - return Cellular_CommonGetEidrxSettings( cellularHandle, pEidrxSettingsList ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetEidrxSettings( CellularHandle_t cellularHandle, - const CellularEidrxSettings_t * pEidrxSettings ) -{ - return Cellular_CommonSetEidrxSettings( cellularHandle, pEidrxSettings ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetRegisteredNetwork( CellularHandle_t cellularHandle, - CellularPlmnInfo_t * pNetworkInfo ) -{ - return Cellular_CommonGetRegisteredNetwork( cellularHandle, pNetworkInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetNetworkTime( CellularHandle_t cellularHandle, - CellularTime_t * pNetworkTime ) -{ - return Cellular_CommonGetNetworkTime( cellularHandle, pNetworkTime ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetServiceStatus( CellularHandle_t cellularHandle, - CellularServiceStatus_t * pServiceStatus ) -{ - return Cellular_CommonGetServiceStatus( cellularHandle, pServiceStatus ); -} - -/*-----------------------------------------------------------*/ diff --git a/modules/hl7802/cellular_hl7802.c b/modules/hl7802/cellular_hl7802.c deleted file mode 100644 index f23239c3..00000000 --- a/modules/hl7802/cellular_hl7802.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* The config header is always included first. */ - -#include - -#include "cellular_config.h" -#include "cellular_config_defaults.h" -#include "cellular_common.h" -#include "cellular_common_portable.h" -#include "cellular_hl7802.h" - -/*-----------------------------------------------------------*/ - -#define ENBABLE_MODULE_UE_RETRY_COUNT ( 6U ) -#define HL7802_MAX_BAND_CFG ( 21U ) -#define HL7802_KSELACQ_CMD_MAX_SIZE ( 19U ) /* The length of AT+KSELACQ=0,1,2,3\0. */ - -/*-----------------------------------------------------------*/ - -typedef struct Hl7802BandConfig -{ - char catm1BandCfg[ HL7802_MAX_BAND_CFG ]; - char nbiotBandCfg[ HL7802_MAX_BAND_CFG ]; - char gsmBandCfg[ HL7802_MAX_BAND_CFG ]; -} Hl7802BandConfig_t; - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq, - uint32_t timeoutMs ); -static CellularError_t getBandCfg( CellularContext_t * pContext, - Hl7802BandConfig_t * pBandCfg ); -static CellularPktStatus_t recvFuncGetBandCfg( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); - -/*-----------------------------------------------------------*/ - -static cellularModuleContext_t cellularHl7802Context = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenErrorTable[] = -{ "ERROR", "BUSY", "NO CARRIER", "NO ANSWER", "NO DIALTONE", "ABORTED", "+CMS ERROR", "+CME ERROR", "SEND FAIL" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenErrorTableSize = sizeof( CellularSrcTokenErrorTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenSuccessTable[] = -{ "OK" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenSuccessTableSize = sizeof( CellularSrcTokenSuccessTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularUrcTokenWoPrefixTable[] = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcTokenWoPrefixTableSize = 0; - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq, - uint32_t timeoutMs ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint8_t tryCount = 0; - - if( pAtReq == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - for( ; tryCount < ENBABLE_MODULE_UE_RETRY_COUNT; tryCount++ ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, *pAtReq, timeoutMs ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t recvFuncGetBandCfg( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - Hl7802BandConfig_t * pBandCfg = NULL; - const CellularATCommandLine_t * pCommnadItem = NULL; - char * pInputLine = NULL; - char * pToken = NULL; - char * pRatBand = NULL; - - if( pContext == NULL ) - { - LogError( ( "recvFuncGetBandCfg: Invalid context." ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pAtResp == NULL ) - { - LogError( ( "recvFuncGetBandCfg: Invalid pAtResp." ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( Hl7802BandConfig_t ) ) ) - { - LogError( ( "recvFuncGetBandCfg: Invalid pData %p or dataLen %u.", pData, dataLen ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pBandCfg = ( Hl7802BandConfig_t * ) pData; - pCommnadItem = pAtResp->pItm; - - while( pCommnadItem != NULL ) - { - pInputLine = pCommnadItem->pLine; - LogDebug( ( "recvFuncGetBandCfg: input line %s", pInputLine ) ); - - /* Remove the line prefix. */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* Parse the RAT field. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - switch( *pToken ) - { - case '0': - pRatBand = pBandCfg->catm1BandCfg; - break; - - case '1': - pRatBand = pBandCfg->nbiotBandCfg; - break; - - case '2': - pRatBand = pBandCfg->gsmBandCfg; - break; - - default: - pRatBand = NULL; - LogError( ( "recvFuncGetBandCfg: unknown RAT %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Copy the band configuration. */ - strncpy( pRatBand, pInputLine, HL7802_MAX_BAND_CFG ); - } - else - { - LogError( ( "recvFuncGetBandCfg process response line error" ) ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - break; - } - - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t getBandCfg( CellularContext_t * pContext, - Hl7802BandConfig_t * pBandCfg ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetBndCfg = - { - "AT+KBNDCFG?", - CELLULAR_AT_MULTI_WITH_PREFIX, - "+KBNDCFG", - recvFuncGetBandCfg, - pBandCfg, - sizeof( Hl7802BandConfig_t ) - }; - - /* pContext and pBandCfg are checked in Cellular_ModuleEnableUe function. */ - ( void ) memset( pBandCfg, 0, sizeof( Hl7802BandConfig_t ) ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetBndCfg, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "getBandCfg: couldn't retrieve band configurations." ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static bool appendRatList( char * pRatList, - CellularRat_t cellularRat ) -{ - bool retValue = true; - - switch( cellularRat ) - { - case CELLULAR_RAT_CATM1: - strcat( pRatList, ",1" ); - break; - - case CELLULAR_RAT_NBIOT: - strcat( pRatList, ",2" ); - break; - - case CELLULAR_RAT_GSM: - strcat( pRatList, ",3" ); - break; - - default: - /* Unsupported RAT. */ - retValue = false; - break; - } - - return retValue; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext, - void ** ppModuleContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t i = 0; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ppModuleContext == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Initialize the module context. */ - ( void ) memset( &cellularHl7802Context, 0, sizeof( cellularModuleContext_t ) ); - - for( i = 0; i < TCP_SESSION_TABLE_LEGNTH; i++ ) - { - cellularHl7802Context.pSessionMap[ i ] = INVALID_SOCKET_INDEX; - } - - *ppModuleContext = ( void * ) &cellularHl7802Context; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - Hl7802BandConfig_t bandCfg = { 0 }; - char ratSelectCmd[ HL7802_KSELACQ_CMD_MAX_SIZE ] = "AT+KSELACQ=0"; - bool retAppendRat = true; - - if( pContext != NULL ) - { - /* Disable echo. */ - atReqGetNoResult.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Disable DTR function. */ - atReqGetNoResult.pAtCmd = "AT&D0"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - #ifndef CELLULAR_CONFIG_DISABLE_FLOW_CONTROL - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Enable RTS/CTS hardware flow control. */ - atReqGetNoResult.pAtCmd = "AT+IFC=2,2"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - #endif - - /* Set Radio Access Technology. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* In the Write format, =0 is used to switch to the first RAT - * in the preferred RAT list (PRL), and fall back to subsequent RATS - * in the PRL if cell coverage is lost. If the PRL is empty, switch to - * CAT-M1. To set the PRL, see AT+KSELACQ. */ - atReqGetNoResult.pAtCmd = "AT+KSRAT=0"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Set Default Radio Access Technology. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT ); - configASSERT( retAppendRat == true ); - - #ifdef CELLULAR_CONFIG_DEFAULT_RAT_2 - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT_2 ); - configASSERT( retAppendRat == true ); - #endif - - #ifdef CELLULAR_CONFIG_DEFAULT_RAT_3 - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT_3 ); - configASSERT( retAppendRat == true ); - #endif - - atReqGetNoResult.pAtCmd = ratSelectCmd; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_KSELACQ_TIMEOUT_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Set Configured LTE Band. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = getBandCfg( pContext, &bandCfg ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( strcmp( bandCfg.catm1BandCfg, CELLULAR_CONFIG_HL7802_CATM1_BAND ) != 0 ) - { - LogInfo( ( "Cellular_ModuleEnableUE : CAT-M1 band desired %s actual %s", - CELLULAR_CONFIG_HL7802_CATM1_BAND, bandCfg.catm1BandCfg ) ); - atReqGetNoResult.pAtCmd = "AT+KBNDCFG=0,"CELLULAR_CONFIG_HL7802_CATM1_BAND; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( strcmp( bandCfg.nbiotBandCfg, CELLULAR_CONFIG_HL7802_NBIOT_BAND ) != 0 ) - { - LogInfo( ( "Cellular_ModuleEnableUE : NBIOT band desired %s actual %s", - CELLULAR_CONFIG_HL7802_NBIOT_BAND, bandCfg.nbiotBandCfg ) ); - atReqGetNoResult.pAtCmd = "AT+KBNDCFG=1,"CELLULAR_CONFIG_HL7802_NBIOT_BAND; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - /* Disable standalone sleep mode. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+KSLEEP=2"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Force initialization of radio to consider new configured bands. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+CFUN=1,1"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_30_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Disable echo after reboot device. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - Platform_Delay( CELLULAR_HL7802_RESET_DELAY_MS ); - atReqGetNoResult.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqGetNoResult.pAtCmd = "AT+COPS=3,2"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_120_SECONDS_MS ); - - atReqGetNoResult.pAtCmd = "AT+CREG=2"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - atReqGetNoResult.pAtCmd = "AT+CEREG=2"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - atReqGetNoResult.pAtCmd = "AT+CTZR=1"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSocketId( CellularContext_t * pContext, - uint8_t sessionId ) -{ - cellularModuleContext_t * pModuleContext = NULL; - uint32_t socketIndex = INVALID_SOCKET_INDEX; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext != NULL ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - else - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( ( cellularStatus == CELLULAR_SUCCESS ) && - ( sessionId >= MIN_TCP_SESSION_ID ) && ( sessionId <= MAX_TCP_SESSION_ID ) ) - { - socketIndex = pModuleContext->pSessionMap[ sessionId ]; - } - - return socketIndex; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSessionId( CellularContext_t * pContext, - uint32_t socketIndex ) -{ - cellularModuleContext_t * pModuleContext = NULL; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t sessionId = INVALID_SESSION_ID; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_GetSessionId invalid cellular context" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogError( ( "_Cellular_GetSessionId invalid socketIndex" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - for( sessionId = 0; sessionId < TCP_SESSION_TABLE_LEGNTH; sessionId++ ) - { - if( pModuleContext->pSessionMap[ sessionId ] == socketIndex ) - { - break; - } - } - - /* Mapping is not found in the session mapping table. */ - if( sessionId == TCP_SESSION_TABLE_LEGNTH ) - { - sessionId = INVALID_SESSION_ID; - } - } - else - { - sessionId = INVALID_SESSION_ID; - } - - return sessionId; -} diff --git a/modules/hl7802/cellular_hl7802.h b/modules/hl7802/cellular_hl7802.h deleted file mode 100644 index a4f5a003..00000000 --- a/modules/hl7802/cellular_hl7802.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#ifndef __CELLULAR_HL7802_H__ -#define __CELLULAR_HL7802_H__ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -#define MIN_TCP_SESSION_ID ( 1U ) -#define MAX_TCP_SESSION_ID ( 6U ) -#define TCP_SESSION_TABLE_LEGNTH ( MAX_TCP_SESSION_ID + 1 ) - -#define INVALID_SOCKET_INDEX ( UINT32_MAX ) -#define INVALID_SESSION_ID ( UINT32_MAX ) - -/* Delay after AT+CFUN=1,1 commands. */ -#ifndef CELLULAR_HL7802_RESET_DELAY_MS - #define CELLULAR_HL7802_RESET_DELAY_MS ( 3000U ) -#endif - -/* AT command recommended timeout value for HL7802. Reference HL7802 AT Commands - * Interface Guide to setup the timeout value for each AT commands. */ -#define CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ( 2000U ) -#define CELLULAR_HL7802_AT_TIMEOUT_5_SECONDS_MS ( 5000U ) -#define CELLULAR_HL7802_AT_TIMEOUT_30_SECONDS_MS ( 30000U ) -#define CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS ( 60000U ) -#define CELLULAR_HL7802_AT_TIMEOUT_120_SECONDS_MS ( 120000U ) - -/* Define the following timeout value since they are content dependent or no recommended value. */ -#ifndef CELLULAR_HL7802_AT_KSELACQ_TIMEOUT_MS - #define CELLULAR_HL7802_AT_KSELACQ_TIMEOUT_MS CELLULAR_HL7802_AT_TIMEOUT_5_SECONDS_MS -#endif - -#ifndef CELLULAR_HL7802_AT_KEDRXCFG_TIMEOUT_MS - #define CELLULAR_HL7802_AT_KEDRXCFG_TIMEOUT_MS CELLULAR_HL7802_AT_TIMEOUT_5_SECONDS_MS -#endif - -#ifndef CELLULAR_HL7802_AT_KCNXUP_TIMEOUT_MS - #define CELLULAR_HL7802_AT_KCNXUP_TIMEOUT_MS CELLULAR_HL7802_AT_TIMEOUT_30_SECONDS_MS -#endif - -#ifndef CELLULAR_HL7802_AT_KCNXDOWN_TIMEOUT_MS - #define CELLULAR_HL7802_AT_KCNXDOWN_TIMEOUT_MS CELLULAR_HL7802_AT_TIMEOUT_30_SECONDS_MS -#endif - -/* Band configuration for HL7802. */ -#ifndef CELLULAR_CONFIG_HL7802_CATM1_BAND - /* Default enable all bands. */ - #define CELLULAR_CONFIG_HL7802_CATM1_BAND "0002000000000F0F1B9F" -#endif - -#ifndef CELLULAR_CONFIG_HL7802_NBIOT_BAND - /* Default enable all bands. */ - #define CELLULAR_CONFIG_HL7802_NBIOT_BAND "0002000000000B0F189F" -#endif - -/*-----------------------------------------------------------*/ - -typedef struct cellularModuleContext -{ - uint32_t pSessionMap[ TCP_SESSION_TABLE_LEGNTH ]; -} cellularModuleContext_t; - -typedef enum tcpSocketState -{ - TCP_SOCKET_STATE_NOT_DEFINED = 0, - TCP_SOCKET_STATE_DEFINED_BUT_NOT_USED = 1, - TCP_SOCKET_STATE_OPENING_AND_CONNECTING = 2, - TCP_SOCKET_STATE_CONNECTION_UP = 3, - TCP_SOCKET_STATE_CONNECTION_CLOSING = 4, - TCP_SOCKET_STATE_CLOSED = 5, - TCP_SOCKET_STATE_MAX -} tcpSocketState_t; - -typedef enum tcpConnectionFailure -{ - TCP_NOTIF_OK = -1, - TCP_NOTIF_NETWORK_ERROR = 0, - TCP_NOTIF_NO_MORE_SOCKETS_AVAILABLE = 1, - TCP_NOTIF_MEMORY_PROBLEM = 2, - TCP_NOTIF_DNS_ERROR = 3, - TCP_NOTIF_TCP_DISCONNECTION = 4, - TCP_NOTIF_TCP_CONNECTION_ERROR = 5, - TCP_NOTIF_GENERIC_ERROR = 6, - TCP_NOTIF_FAIL_TO_ACCEPT_CLIENT_REQUEST = 7, - TCP_NOTIF_KTCPSND_WAITING_FOR_MORE_OR_LESS_CHARACTERS = 8, - TCP_NOTIF_BAD_SESSION_ID = 9, - TCP_NOTIF_SESSION_IS_ALREADY_RUNNING = 10, - TCP_NOTIF_ALL_SESSIONS_ARE_USED = 11, - TCP_NOTIF_SOCKET_CONNECTION_TIMEOUT_ERROR = 12, - TCP_NOTIF_SSL_CONNECTION_ERROR = 13, - TCP_NOTIF_SSL_INITIALIZATION_ERROR = 14, - TCP_NOTIF_MAX, -} tcpConnectionFailure_t; - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSocketId( CellularContext_t * pContext, - uint8_t sessionId ); - -uint32_t _Cellular_GetSessionId( CellularContext_t * pContext, - uint32_t socketIndex ); - -/*-----------------------------------------------------------*/ - -extern CellularAtParseTokenMap_t CellularUrcHandlerTable[]; -extern uint32_t CellularUrcHandlerTableSize; - -extern const char * CellularSrcTokenErrorTable[]; -extern uint32_t CellularSrcTokenErrorTableSize; - -extern const char * CellularSrcTokenSuccessTable[]; -extern uint32_t CellularSrcTokenSuccessTableSize; - -extern const char * CellularUrcTokenWoPrefixTable[]; -extern uint32_t CellularUrcTokenWoPrefixTableSize; - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* ifndef __CELLULAR_HL7802_H__ */ diff --git a/modules/hl7802/cellular_hl7802_api.c b/modules/hl7802/cellular_hl7802_api.c deleted file mode 100644 index e583b1d6..00000000 --- a/modules/hl7802/cellular_hl7802_api.c +++ /dev/null @@ -1,2788 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include -#include -#include - -/* Cellular includes. */ -#include "cellular_types.h" -#include "cellular_api.h" -#include "cellular_common_api.h" -#include "cellular_common.h" -#include "cellular_at_core.h" - -/* Cellular module includes. */ -#include "cellular_hl7802.h" - -/*-----------------------------------------------------------*/ - -#define CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ( 32U ) - -#define SOCKET_END_PATTERN "--EOF--Pattern--" -#define SOCKET_END_PATTERN_LEN ( 16U ) - -#define SOCKET_DATA_CONNECT_TOKEN "CONNECT" -#define SOCKET_DATA_CONNECT_TOKEN_LEN ( 7U ) - -#define CELLULAR_CEDRXS_POS_ACT ( 0U ) -#define CELLULAR_CEDRXS_POS_RAT ( 1U ) -#define CELLULAR_CEDRXS_POS_REQUESTED_EDRX_VALUE ( 2U ) -#define CELLULAR_CEDRXS_POS_NW_PROVIDED_EDRX_VALUE ( 3U ) -#define CELLULAR_CEDRXS_POS_REQUESTED_PTW_VALUE ( 4U ) -#define CELLULAR_CEDRXS_POS_NW_PROVIDED_PTW_VALUE ( 5U ) - -#define RAT_PRIOIRTY_LIST_LENGTH ( 3U ) - -#define SIGNAL_QUALITY_CSQ_UNKNOWN ( 99 ) -#define SIGNAL_QUALITY_CSQ_BER_MIN ( 0 ) -#define SIGNAL_QUALITY_CSQ_BER_MAX ( 7 ) - -#define INVALID_PDN_INDEX ( 0xFFU ) - -#define CELLULAR_PDN_STATUS_POS_CONTEXT_ID ( 0U ) -#define CELLULAR_PDN_STATUS_POS_GPRS ( 1U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_APN ( 2U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_LOGIN ( 3U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_PASSWORD ( 4U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_AF ( 5U ) -#define CELLULAR_PDN_STATUS_POS_IP ( 6U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_DNS1 ( 7U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_DNS2 ( 8U ) /* Ignored pos. */ -#define CELLULAR_PDN_STATUS_POS_STATE ( 9U ) - -#define CELLULAR_PDN_STATE_DISCONNECTED ( 0U ) -#define CELLULAR_PDN_STATE_CONNECTING ( 1U ) -#define CELLULAR_PDN_STATE_CONNECTED ( 2U ) -#define CELLULAR_PDN_STATE_IDLE ( 3U ) -#define CELLULAR_PDN_STATE_DISCONNECTING ( 4U ) - -#define KSELACQ_RAT_CATM_CHAR ( '1' ) -#define KSELACQ_RAT_NBIOT_CHAR ( '2' ) -#define KSELACQ_RAT_GSM_CHAR ( '3' ) - -#define CELLULAR_PORT_NUM_CHAR_LEN ( 6 ) - -#define CELLULAR_REMOTE_IP_ADDR_MAX_LENGTH ( 127 ) - -/*-----------------------------------------------------------*/ - -/** - * @brief Parameters involved in receiving data through sockets - */ -typedef struct _socketDataRecv -{ - uint32_t * pDataLen; - uint8_t * pData; -} _socketDataRecv_t; - -typedef struct socketStat -{ - tcpSocketState_t status; /* TCP socket state. */ - tcpConnectionFailure_t tcpNotif; /* 1 if socket/connection is OK, if an error has happened. */ - uint16_t remData; /* Remaining bytes in the socket buffer, waiting to be sent. */ - uint16_t rcvData; /* Received bytes, can be read with +KTCPRCV command. */ -} socketStat_t; - -/*-----------------------------------------------------------*/ - -static const char * _socketSendSuccesTokenTable[] = { SOCKET_DATA_CONNECT_TOKEN }; -static const uint32_t _socketSendSuccesTokenTableLength = 1; - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t _Cellular_RecvFuncGetSocketStat( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t _Cellular_GetSocketStat( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - socketStat_t * pSocketStat ); -static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t lineLength, - char ** ppDataStart, - uint32_t * pDataLength ); -static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pAtResp, - const _socketDataRecv_t * pDataRecv, - uint32_t outBufSize ); -static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t buildSocketConfig( CellularSocketHandle_t socketHandle, - char * pCmdBuf ); -static CellularError_t storeAccessModeAndAddress( CellularContext_t * pContext, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ); -static CellularPktStatus_t _Cellular_RecvFuncGetTcpCfgSessionId( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t _Cellular_getTcpCfgSessionId( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - uint8_t * pSessionId ); -static CellularATError_t parseEidrxToken( char * pToken, - uint8_t tokenIndex, - CellularEidrxSettingsList_t * pEidrxSettingsList, - uint8_t count ); -static CellularATError_t parseEidrxLine( char * pInputLine, - uint8_t count, - CellularEidrxSettingsList_t * pEidrxSettingsList ); -static CellularPktStatus_t _Cellular_RecvFuncGetEidrxSettings( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularRat_t convertKselacqIndexToRat( char ratIndex ); -static CellularPktStatus_t _Cellular_RecvFuncGetRatPriority( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static int16_t convertCesqSignalRxlev( int32_t rxlevValue ); -static int16_t convertCesqSignalRsrq( int32_t rsrqValue ); -static int16_t convertCesqSignalRsrp( int32_t rsrpValue ); -static bool _parseSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ); -static CellularPktStatus_t _Cellular_RecvFuncGetSignalInfo( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetSocketStat( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL, * pToken = NULL; - socketStat_t * pSocketStat = ( socketStat_t * ) pData; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "GetSocketStat: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pSocketStat == NULL ) || ( dataLen != sizeof( socketStat_t ) ) ) - { - LogError( ( "GetSocketStat: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetSocketStat: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - /* +KTCPSTAT: ,,,,. */ - /* Remove prefix and leading space. */ - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pInputLine ); - } - - /* Get token status. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= TCP_SOCKET_STATE_NOT_DEFINED ) && ( tempValue < TCP_SOCKET_STATE_MAX ) ) - { - pSocketStat->status = ( tcpSocketState_t ) tempValue; - } - else - { - LogError( ( "GetSocketStat unknown status %d", tempValue ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Get token tcp_notif. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= TCP_NOTIF_OK ) && ( tempValue < TCP_NOTIF_MAX ) ) - { - pSocketStat->tcpNotif = ( tcpConnectionFailure_t ) tempValue; - } - else - { - LogError( ( "GetSocketStat unknown tcp_notif %d", tempValue ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Get token rem_data. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && ( tempValue < UINT16_MAX ) ) - { - pSocketStat->remData = ( uint16_t ) tempValue; - } - else - { - LogError( ( "GetSocketStat unknown rem_data %d", tempValue ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Get token rcv_data. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && ( tempValue < UINT16_MAX ) ) - { - pSocketStat->rcvData = ( uint16_t ) tempValue; - } - else - { - LogError( ( "GetSocketStat unknown rcvData %d", tempValue ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t _Cellular_GetSocketStat( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - socketStat_t * pSocketStat ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketStat = - { - cmdBuf, - CELLULAR_AT_WITH_PREFIX, - "+KTCPSTAT", - _Cellular_RecvFuncGetSocketStat, - pSocketStat, - sizeof( socketStat_t ), - }; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - /* Internal function. Caller checks parameters. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "AT+KTCPSTAT=%lu", sessionId ); - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketStat, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t lineLength, - char ** ppDataStart, - uint32_t * pDataLength ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t * pRecvDataLength = ( uint32_t * ) pCallbackContext; - - if( ( pLine == NULL ) || ( ppDataStart == NULL ) || ( pDataLength == NULL ) || ( pCallbackContext == NULL ) ) - { - LogError( ( "socketRecvData: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( lineLength < ( SOCKET_DATA_CONNECT_TOKEN_LEN + 2U ) ) && ( *pRecvDataLength > 0 ) ) - { - /* Need more data to decide the data prefix. */ - pktStatus = CELLULAR_PKT_STATUS_SIZE_MISMATCH; - } - else - { - if( strncmp( pLine, SOCKET_DATA_CONNECT_TOKEN, SOCKET_DATA_CONNECT_TOKEN_LEN ) == 0 ) - { - /* The string length of "CONNECT\r\n". */ - *ppDataStart = ( char * ) &pLine[ SOCKET_DATA_CONNECT_TOKEN_LEN + 2 ]; /* Indicate the data start in pLine. */ - *pDataLength = *pRecvDataLength; /* Return the data length from pCallbackContext. */ - *pRecvDataLength = 0; - } - else - { - /* Prefix string which is not "CONNECT" does't indicate data start. Set data length to 0.*/ - *pDataLength = 0; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pAtResp, - const _socketDataRecv_t * pDataRecv, - uint32_t outBufSize ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const char * pInputLine = NULL; - uint32_t dataLenToCopy = 0; - - /* Check if the received data size is greater than the output buffer size. */ - if( *pDataRecv->pDataLen > outBufSize ) - { - LogError( ( "Data is turncated, received data length %d, out buffer size %d", - *pDataRecv->pDataLen, outBufSize ) ); - dataLenToCopy = outBufSize; - *pDataRecv->pDataLen = outBufSize; - } - else - { - dataLenToCopy = *pDataRecv->pDataLen; - } - - /* Data is stored in the next intermediate response. */ - if( pAtResp->pItm->pNext != NULL ) - { - pInputLine = pAtResp->pItm->pNext->pLine; - - if( ( pInputLine != NULL ) && ( dataLenToCopy > 0U ) ) - { - /* Copy the data to the out buffer. */ - ( void ) memcpy( ( void * ) pDataRecv->pData, ( const void * ) pInputLine, dataLenToCopy ); - } - else - { - LogError( ( "Receive Data: paramerter error, data pointer %p, data to copy %d", - pInputLine, dataLenToCopy ) ); - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - } - else if( *pDataRecv->pDataLen == 0U ) - { - /* Receive command success but no data. */ - LogDebug( ( "Receive Data: no data" ) ); - } - else - { - LogError( ( "Receive Data: Intermediate response empty" ) ); - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char * pInputLine = NULL, * pEndPatternLine = NULL; - const _socketDataRecv_t * pDataRecv = ( _socketDataRecv_t * ) pData; - - if( pContext == NULL ) - { - LogError( ( "Receive Data: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "Receive Data: response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp->pItm->pNext == NULL ) || ( pAtResp->pItm->pNext->pNext == NULL ) ) - { - LogError( ( "Receive Data: response data or end pattern is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pDataRecv == NULL ) || ( pDataRecv->pData == NULL ) || ( pDataRecv->pDataLen == NULL ) ) - { - LogError( ( "Receive Data: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; /* The first item is the data prefix. */ - pEndPatternLine = pAtResp->pItm->pNext->pNext->pLine; /* The third item is the end pattern. */ - - /* Check the data prefix token "CONNECT". */ - if( strncmp( pInputLine, SOCKET_DATA_CONNECT_TOKEN, SOCKET_DATA_CONNECT_TOKEN_LEN ) != 0 ) - { - LogError( ( "response item error in prefix CONNECT" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - - /* Check the data end pattern. */ - if( strncmp( pEndPatternLine, SOCKET_END_PATTERN, SOCKET_END_PATTERN_LEN ) != 0 ) - { - LogError( ( "response item error in end pattern"SOCKET_END_PATTERN ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - - /* Process the data buffer. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = getDataFromResp( pAtResp, pDataRecv, dataLen ); - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t buildSocketConfig( CellularSocketHandle_t socketHandle, - char * pCmdBuf ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - /* +1 size in buffer for ',' */ - char portBuf[ CELLULAR_PORT_NUM_CHAR_LEN + 1 ] = { 0 }; - - if( pCmdBuf == NULL ) - { - LogDebug( ( "buildSocketConfig: Invalid command buffer" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketProtocol != CELLULAR_SOCKET_PROTOCOL_TCP ) - { - LogError( ( "buildSocketConfig: socket protocol unsupported %d", - socketHandle->socketProtocol ) ); - cellularStatus = CELLULAR_UNSUPPORTED; - } - else if( strlen( socketHandle->remoteSocketAddress.ipAddress.ipAddress ) > CELLULAR_REMOTE_IP_ADDR_MAX_LENGTH ) - { - /* The maximum length of domain name is 127 in HL7802. */ - LogError( ( "buildSocketConfig: the remote server's address is too long, length=%u", - strlen( socketHandle->remoteSocketAddress.ipAddress.ipAddress ) ) ); - cellularStatus = CELLULAR_UNSUPPORTED; - } - else - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. - * Reserve buffer for port setting. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( pCmdBuf, CELLULAR_AT_CMD_MAX_SIZE - sizeof( portBuf ), - "AT+KTCPCFG=%u,0,\"%s\",%u", - socketHandle->contextId, - socketHandle->remoteSocketAddress.ipAddress.ipAddress, - socketHandle->remoteSocketAddress.port ); - - /* Set the local port in the end of command buffer string if localPort is not 0. */ - if( socketHandle->localPort > 0 ) - { - ( void ) snprintf( portBuf, sizeof( portBuf ), - ",%u", - socketHandle->localPort ); - - /* Because the length of host's IP address is limited, - * the buffer size must be enough for port setting. */ - strcat( pCmdBuf, portBuf ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t storeAccessModeAndAddress( CellularContext_t * pContext, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pRemoteSocketAddress == NULL ) || ( socketHandle == NULL ) ) - { - LogDebug( ( "storeAccessModeAndAddress: Invalid socket address" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_ALLOCATED ) - { - LogError( ( "storeAccessModeAndAddress, bad socket state %d", - socketHandle->socketState ) ); - cellularStatus = CELLULAR_INTERNAL_FAILURE; - } - else if( dataAccessMode != CELLULAR_ACCESSMODE_BUFFER ) - { - LogError( ( "storeAccessModeAndAddress, Access mode not supported %d", - dataAccessMode ) ); - cellularStatus = CELLULAR_UNSUPPORTED; - } - else - { - socketHandle->remoteSocketAddress.port = pRemoteSocketAddress->port; - socketHandle->dataMode = dataAccessMode; - socketHandle->remoteSocketAddress.ipAddress.ipAddressType = - pRemoteSocketAddress->ipAddress.ipAddressType; - ( void ) strncpy( socketHandle->remoteSocketAddress.ipAddress.ipAddress, - pRemoteSocketAddress->ipAddress.ipAddress, - CELLULAR_IP_ADDRESS_MAX_SIZE + 1U ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetTcpCfgSessionId( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - uint8_t * pSessionId = pData; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "GetTcpCfgSessionId: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pSessionId == NULL ) || ( dataLen != sizeof( uint8_t ) ) ) - { - LogError( ( "GetTcpCfgSessionId: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetTcpCfgSessionId: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pInputLine, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - *pSessionId = ( uint8_t ) tempValue; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t _Cellular_getTcpCfgSessionId( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - uint8_t * pSessionId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketConnect = - { - cmdBuf, - CELLULAR_AT_WITH_PREFIX, - "+KTCPCFG", - _Cellular_RecvFuncGetTcpCfgSessionId, - pSessionId, - sizeof( uint8_t ), - }; - - /* Internal function. Caller checks parameters. */ - cellularStatus = buildSocketConfig( socketHandle, cmdBuf ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketConnect, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketConnect: Socket connect failed, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseEidrxToken( char * pToken, - uint8_t tokenIndex, - CellularEidrxSettingsList_t * pEidrxSettingsList, - uint8_t count ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - switch( tokenIndex ) - { - case CELLULAR_CEDRXS_POS_ACT: - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - pEidrxSettingsList->eidrxList[ count ].mode = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in processing mode value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - break; - - case CELLULAR_CEDRXS_POS_RAT: - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - pEidrxSettingsList->eidrxList[ count ].rat = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in processing Requested rat value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - break; - - - case CELLULAR_CEDRXS_POS_REQUESTED_EDRX_VALUE: - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - pEidrxSettingsList->eidrxList[ count ].requestedEdrxVaue = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in processing Requested Edrx value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - break; - - case CELLULAR_CEDRXS_POS_NW_PROVIDED_EDRX_VALUE: - /* Unused value. */ - break; - - case CELLULAR_CEDRXS_POS_REQUESTED_PTW_VALUE: - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - pEidrxSettingsList->eidrxList[ count ].pagingTimeWindow = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in processing Requested paging time window value. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - break; - - case CELLULAR_CEDRXS_POS_NW_PROVIDED_PTW_VALUE: - /* Unused value. */ - break; - - default: - LogDebug( ( "Unknown Parameter Position %u in AT+CEDRXS Response", tokenIndex ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parseEidrxLine( char * pInputLine, - uint8_t count, - CellularEidrxSettingsList_t * pEidrxSettingsList ) -{ - char * pToken = NULL; - char * pLocalInputLine = pInputLine; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - uint8_t tokenIndex = 0; - - atCoreStatus = Cellular_ATRemovePrefix( &pLocalInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pLocalInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - tokenIndex = 0; - - while( pToken != NULL ) - { - if( parseEidrxToken( pToken, tokenIndex, pEidrxSettingsList, count ) != CELLULAR_AT_SUCCESS ) - { - LogInfo( ( "parseEidrxToken %s index %d failed", pToken, tokenIndex ) ); - } - - tokenIndex++; - - if( Cellular_ATGetNextTok( &pLocalInputLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetEidrxSettings( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - uint8_t count = 0; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularEidrxSettingsList_t * pEidrxSettingsList = NULL; - const CellularATCommandLine_t * pCommnadItem = NULL; - - if( pContext == NULL ) - { - LogError( ( "GetEidrxSettings: Invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || - ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || - ( pData == NULL ) || - ( dataLen != CELLULAR_EDRX_LIST_MAX_SIZE ) ) - { - LogError( ( "GetEidrxSettings: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pEidrxSettingsList = ( CellularEidrxSettingsList_t * ) pData; - pCommnadItem = pAtResp->pItm; - - while( pCommnadItem != NULL ) - { - pInputLine = pCommnadItem->pLine; - atCoreStatus = parseEidrxLine( pInputLine, count, pEidrxSettingsList ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "GetEidrx: Parsing Error encountered, atCoreStatus: %d", atCoreStatus ) ); - } - else - { - LogDebug( ( "GetEidrx setting[%d]: RAT: %d, Value: 0x%x", - count, pEidrxSettingsList->eidrxList[ count ].rat, pEidrxSettingsList->eidrxList[ count ].requestedEdrxVaue ) ); - } - - pCommnadItem = pCommnadItem->pNext; - count++; - pEidrxSettingsList->count = count; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularRat_t convertKselacqIndexToRat( char ratIndex ) -{ - CellularRat_t rat = CELLULAR_RAT_INVALID; - - switch( ratIndex ) - { - case KSELACQ_RAT_CATM_CHAR: - rat = CELLULAR_RAT_CATM1; - break; - - case KSELACQ_RAT_NBIOT_CHAR: - rat = CELLULAR_RAT_NBIOT; - break; - - case KSELACQ_RAT_GSM_CHAR: - rat = CELLULAR_RAT_GSM; - break; - - default: - break; - } - - return rat; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetRatPriority( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularRat_t * pRatPriorities = NULL; - uint32_t ratIndex = 0; - uint32_t maxRatPriorityLength = ( dataLen > RAT_PRIOIRTY_LIST_LENGTH ? RAT_PRIOIRTY_LIST_LENGTH : dataLen ); - - if( pContext == NULL ) - { - LogError( ( "GetRatPriority: Invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || ( pData == NULL ) || ( dataLen == 0U ) ) - { - LogError( ( "GetRatPriority: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; - pRatPriorities = ( CellularRat_t * ) pData; - - /* Response string "+KSELACQ: 1,2,3". */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - for( ratIndex = 0; ratIndex < maxRatPriorityLength; ratIndex++ ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pToken ); - } - - if( ( atCoreStatus == CELLULAR_AT_SUCCESS ) && ( strlen( pToken ) == 1 ) ) - { - pRatPriorities[ ratIndex ] = convertKselacqIndexToRat( pToken[ 0 ] ); - } - else - { - pRatPriorities[ ratIndex ] = CELLULAR_RAT_INVALID; - } - } - } - - for( ; ratIndex < dataLen; ratIndex++ ) - { - pRatPriorities[ ratIndex ] = CELLULAR_RAT_INVALID; - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Received signal strength level (see 3GPP TS 45.008 [20] subclause 8.1.4) - * 0 rssi < -110 dBm : assume -111 dBm to indicate the signal is detectable but fairly week. - * 1 -110 dBm <= rssi < -109 dBm - * 2 -109 dBm <= rssi < -108 dBm - * ... - * 61 -50 dBm <= rssi < -49 dBm - * 62 -49 dBm <= rssi < -48 dBm - * 63 -48 dBm <= rssi - * 99 not known or not detectable */ -static int16_t convertCesqSignalRxlev( int32_t rxlevValue ) -{ - int16_t rssidBm = 0; - - if( ( rxlevValue >= 0 ) && ( rxlevValue <= 63 ) ) - { - rssidBm = ( int16_t ) ( ( -111 ) + ( rxlevValue ) ); - } - else - { - rssidBm = CELLULAR_INVALID_SIGNAL_VALUE; - } - - return rssidBm; -} - -/*-----------------------------------------------------------*/ - -/* 0 rsrq < -19.5 dB - * 1 -19.5 dB <= rsrq < -19 dB - * 2 -19 dB <= rsrq < -18.5 dB - * ... - * 32 -4 dB <= rsrq < -3.5 dB - * 33 -3.5 dB <= rsrq < -3 dB - * 34 -3 dB <= rsrq - * 255 Not known or not detectable. */ -static int16_t convertCesqSignalRsrq( int32_t rsrqValue ) -{ - int16_t rsrqDb = 0; - - if( ( rsrqValue >= 0 ) && ( rsrqValue <= 34 ) ) - { - rsrqDb = ( int16_t ) ( ( -20 ) + ( rsrqValue * 0.5 ) ); - } - else - { - rsrqDb = CELLULAR_INVALID_SIGNAL_VALUE; - } - - return rsrqDb; -} - -/*-----------------------------------------------------------*/ - -/* 0 rsrp < -140 dBm - * 1 -140 dBm <= rsrp < -139 dBm - * 2 -139 dBm <= rsrp < -138 dBm - * ... - * 95 -46 dBm <= rsrp < -45 dBm - * 96 -45 dBm <= rsrp < -44 dBm - * 97 -44 dBm <= rsrp - * 255 Not known or not detectable. */ -static int16_t convertCesqSignalRsrp( int32_t rsrpValue ) -{ - int16_t rsrpDb = 0; - - if( ( rsrpValue >= 0 ) && ( rsrpValue <= 97 ) ) - { - rsrpDb = ( int16_t ) ( ( -141 ) + ( rsrpValue ) ); - } - else - { - rsrpDb = CELLULAR_INVALID_SIGNAL_VALUE; - } - - return rsrpDb; -} - -/*-----------------------------------------------------------*/ - -static bool _parseSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ) -{ - char * pToken = NULL, * pTmpQcsqPayload = pQcsqPayload; - int32_t tempValue = 0; - int16_t berValue = 0; - bool parseStatus = true; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - /* The cesq payload format is ,,,,,. */ - - /* rxlev. */ - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSignalInfo->rssi = convertCesqSignalRxlev( tempValue ); - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RXLEV. Token %s", pToken ) ); - parseStatus = false; - } - } - - /* ber. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( ( atCoreStatus == CELLULAR_AT_SUCCESS ) && ( tempValue <= INT16_MAX ) && ( tempValue >= INT16_MIN ) ) - { - /* As RXQUAL values in the table in 3GPP TS 45.008 [20] subclause 8.2.4. - * The CESQ ber signal value has the same scale with the AT+CSQ ber signal value. */ - cellularStatus = _Cellular_ConvertCsqSignalBer( ( int16_t ) tempValue, &berValue ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pSignalInfo->ber = berValue; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - else - { - LogError( ( "_parseSignalQuality: Error in processing BER. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - /* Skip rscp. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - /* Skip ecno. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - /* rsrq. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSignalInfo->rsrq = convertCesqSignalRsrq( tempValue ); - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RSRQ. Token %s", pToken ) ); - parseStatus = false; - } - } - - /* rsrp. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSignalInfo->rsrp = convertCesqSignalRsrp( tempValue ); - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RSRP. Token %s", pToken ) ); - parseStatus = false; - } - } - - return parseStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetSignalInfo( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularSignalInfo_t * pSignalInfo = ( CellularSignalInfo_t * ) pData; - bool parseStatus = true; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( pContext == NULL ) - { - LogError( ( "GetSignalInfo: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pSignalInfo == NULL ) || ( dataLen != sizeof( CellularSignalInfo_t ) ) ) - { - LogError( ( "GetSignalInfo: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetSignalInfo: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - parseStatus = _parseSignalQuality( pInputLine, pSignalInfo ); - } - - if( parseStatus != true ) - { - pSignalInfo->rssi = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->ber = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->bars = CELLULAR_INVALID_SIGNAL_BAR_VALUE; - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetDns( CellularHandle_t cellularHandle, - uint8_t contextId, - const char * pDnsServerAddress ) -{ - ( void ) cellularHandle; - ( void ) contextId; - ( void ) pDnsServerAddress; - - /* Modem use dynamic DNS addresses. Return unsupported. */ - return CELLULAR_UNSUPPORTED; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_SocketRecv( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint8_t * pBuffer, - uint32_t bufferLength, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint32_t * pReceivedDataLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - uint32_t recvTimeout = CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS; - uint32_t recvLen = bufferLength; - _socketDataRecv_t dataRecv = - { - pReceivedDataLength, - pBuffer - }; - CellularAtReq_t atReqSocketRecv = - { - cmdBuf, - CELLULAR_AT_MULTI_DATA_WO_PREFIX, - "CONNECT", - _Cellular_RecvFuncData, - ( void * ) &dataRecv, - bufferLength, - }; - socketStat_t socketStat = { 0 }; - uint32_t socktCmdDataLength = 0; - uint32_t sessionId = 0; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "_Cellular_CheckLibraryStatus failed." ) ); - } - else if( socketHandle == NULL ) - { - LogError( ( "_Cellular_RecvData: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pBuffer == NULL ) || ( pReceivedDataLength == NULL ) || ( bufferLength == 0U ) ) - { - LogError( ( "_Cellular_RecvData: Bad input Param." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( ( socketHandle->socketState != SOCKETSTATE_CONNECTED ) && ( socketHandle->socketState != SOCKETSTATE_DISCONNECTED ) ) - { - /* Check the socket connection state. */ - /* For SOCKETSTATE_DISCONNECTED, there may be packets that can be read even though socket is disconnected by remote. */ - LogInfo( ( "Cellular_SocketRecv: socket state %d is not connected.", socketHandle->socketState ) ); - - if( ( socketHandle->socketState == SOCKETSTATE_ALLOCATED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - cellularStatus = CELLULAR_SOCKET_NOT_CONNECTED; - } - else - { - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - } - else - { - sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - if( sessionId == INVALID_SESSION_ID ) - { - LogError( ( "Cellular_SocketRecv : invalid session ID for socket index %u", - socketHandle->socketId ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Calculate the read length. */ - cellularStatus = _Cellular_GetSocketStat( cellularHandle, socketHandle, &socketStat ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - socktCmdDataLength = socketStat.rcvData; - } - else - { - socktCmdDataLength = 0; - } - - /* Update recvLen to maximum module length. */ - if( CELLULAR_MAX_RECV_DATA_LEN <= bufferLength ) - { - recvLen = ( uint32_t ) CELLULAR_MAX_RECV_DATA_LEN; - } - - /* Update the recvLen to available data length in cellular module. */ - if( recvLen > socktCmdDataLength ) - { - recvLen = socktCmdDataLength; - } - - *pReceivedDataLength = recvLen; - socktCmdDataLength = recvLen; - - /* Update receive timeout to default timeout if not set with setsocketopt. */ - if( recvLen > 0 ) - { - if( socketHandle->recvTimeoutMs != 0U ) - { - recvTimeout = socketHandle->recvTimeoutMs; - } - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, - "%s%u,%u", "AT+KTCPRCV=", sessionId, recvLen ); - pktStatus = _Cellular_TimeoutAtcmdDataRecvRequestWithCallback( pContext, - atReqSocketRecv, recvTimeout, socketRecvDataPrefix, &socktCmdDataLength ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - /* Reset data handling parameters. */ - LogError( ( "Cellular_SocketRecv: Data Receive fail, pktStatus: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_SocketSend( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - const uint8_t * pData, - uint32_t dataLength, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint32_t * pSentDataLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t sendTimeout = CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketSend = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - CellularAtDataReq_t atDataReqSocketSend = - { - pData, - dataLength, - pSentDataLength, - ( const uint8_t * ) SOCKET_END_PATTERN, - SOCKET_END_PATTERN_LEN - }; - uint32_t sessionId = 0; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "_Cellular_CheckLibraryStatus failed." ) ); - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketSend: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( pSentDataLength == NULL ) || ( dataLength == 0U ) ) - { - LogError( ( "Cellular_SocketSend: Invalid parameter." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_CONNECTED ) - { - /* Check the socket connection state. */ - LogInfo( ( "Cellular_SocketSend: socket state %d is not connected.", socketHandle->socketState ) ); - - if( ( socketHandle->socketState == SOCKETSTATE_ALLOCATED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - cellularStatus = CELLULAR_SOCKET_NOT_CONNECTED; - } - else - { - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - } - else - { - sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - if( sessionId == INVALID_SESSION_ID ) - { - LogError( ( "Cellular_SocketSend : invalid session ID for socket index %u", - socketHandle->socketId ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Send data length check. */ - if( dataLength > ( uint32_t ) CELLULAR_MAX_SEND_DATA_LEN ) - { - atDataReqSocketSend.dataLen = ( uint32_t ) CELLULAR_MAX_SEND_DATA_LEN; - } - - /* Check send timeout. If not set by setsockopt, use default value. */ - if( socketHandle->sendTimeoutMs != 0U ) - { - sendTimeout = socketHandle->sendTimeoutMs; - } - - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%u,%u", - "AT+KTCPSND=", sessionId, atDataReqSocketSend.dataLen ); - - pktStatus = _Cellular_TimeoutAtcmdDataSendSuccessToken( pContext, atReqSocketSend, atDataReqSocketSend, - CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS, sendTimeout, - _socketSendSuccesTokenTable, _socketSendSuccesTokenTableLength ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - if( socketHandle->socketState == SOCKETSTATE_DISCONNECTED ) - { - LogWarn( ( "Cellular_SocketSend: Data send fail. Socket is closed during the send operation." ) ); - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - else - { - LogError( ( "Cellular_SocketSend: Data send fail, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketClose( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketClose = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - uint32_t sessionId = 0U; - cellularModuleContext_t * pModuleContext = NULL; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( socketHandle == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else - { - if( socketHandle->socketState == SOCKETSTATE_CONNECTING ) - { - LogWarn( ( "Cellular_SocketClose: Socket state is SOCKETSTATE_CONNECTING." ) ); - } - - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - if( sessionId == INVALID_SESSION_ID ) - { - LogError( ( "Cellular_SocketSend : invalid session ID for socket index %u", - socketHandle->socketId ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Remove the mapping. */ - pModuleContext->pSessionMap[ sessionId ] = INVALID_SOCKET_INDEX; - - /* Close the socket. */ - if( socketHandle->socketState == SOCKETSTATE_CONNECTED ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%lu,1", - "AT+KTCPCLOSE=", sessionId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketClose, - CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS ); - - /* Delete the socket config. */ - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogWarn( ( "Cellular_SocketClose: AT+KTCPCLOSE fail, PktRet: %d", pktStatus ) ); - } - } - - if( ( socketHandle->socketState == SOCKETSTATE_CONNECTED ) || - ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) || - ( socketHandle->socketState == SOCKETSTATE_DISCONNECTED ) ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%lu", - "AT+KTCPDEL=", sessionId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketClose, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketClose: AT+KTCPDEL fail, PktRet: %d", pktStatus ) ); - } - } - - /* Ignore the result from the info, and force to remove the socket. */ - cellularStatus = _Cellular_RemoveSocketData( pContext, socketHandle ); - } - - return CELLULAR_SUCCESS; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketConnect( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - uint8_t sessionId = 0; - CellularAtReq_t atReqSocketConnect = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - cellularModuleContext_t * pModuleContext = NULL; - - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "_Cellular_CheckLibraryStatus failed." ) ); - } - else if( pRemoteSocketAddress == NULL ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket address." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( socketHandle->socketState == SOCKETSTATE_CONNECTED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - LogError( ( "Cellular_SocketConnect: Not allowed in state %d.", socketHandle->socketState ) ); - cellularStatus = CELLULAR_NOT_ALLOWED; - } - else - { - cellularStatus = storeAccessModeAndAddress( pContext, socketHandle, dataAccessMode, pRemoteSocketAddress ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - /* Set socket config and get session id. The session id is defined by the modem. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Builds the Socket connect command. */ - cellularStatus = _Cellular_getTcpCfgSessionId( pContext, socketHandle, &sessionId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Create the reverse table to store the socketIndex to sessionId. */ - pModuleContext->pSessionMap[ sessionId ] = socketHandle->socketId; - } - } - - /* Start the tcp connection. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Set the socket state to connecting state. If cellular modem returns error, - * revert the state to allocated state. */ - socketHandle->socketState = SOCKETSTATE_CONNECTING; - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, - "AT+KTCPCNX=%u", sessionId ); - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketConnect, - CELLULAR_HL7802_AT_TIMEOUT_30_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketConnect: Socket connect failed, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - /* Revert the state to allocated state. */ - socketHandle->socketState = SOCKETSTATE_ALLOCATED; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSimCardStatus( CellularHandle_t cellularHandle, - CellularSimCardStatus_t * pSimCardStatus ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - /* Parameters are checked in this API. */ - cellularStatus = Cellular_CommonGetSimCardLockStatus( cellularHandle, pSimCardStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = Cellular_CommonGetSimCardLockStatus( cellularHandle, pSimCardStatus ); - - if( ( cellularStatus == CELLULAR_SUCCESS ) && - ( pSimCardStatus->simCardLockState != CELLULAR_SIM_CARD_INVALID ) && - ( pSimCardStatus->simCardLockState != CELLULAR_SIM_CARD_LOCK_UNKNOWN ) ) - { - pSimCardStatus->simCardState = CELLULAR_SIM_CARD_INSERTED; - } - else - { - pSimCardStatus->simCardState = CELLULAR_SIM_CARD_UNKNOWN; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcSignalStrengthChangedCallback( CellularHandle_t cellularHandle, - CellularUrcSignalStrengthChangedCallback_t signalStrengthChangedCallback, - void * pCallbackContext ) -{ - ( void ) cellularHandle; - ( void ) signalStrengthChangedCallback; - ( void ) pCallbackContext; - return CELLULAR_UNSUPPORTED; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetHostByName( CellularHandle_t cellularHandle, - uint8_t contextId, - const char * pcHostName, - char * pResolvedAddress ) -{ - ( void ) cellularHandle; - ( void ) contextId; - ( void ) pcHostName; - ( void ) pResolvedAddress; - return CELLULAR_UNSUPPORTED; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_DeactivatePdn( CellularHandle_t cellularHandle, - uint8_t contextId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - - CellularAtReq_t atReqDeactPdn = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_IsValidPdn( contextId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s=%u", "AT+KCNXDOWN", contextId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqDeactPdn, - CELLULAR_HL7802_AT_KCNXDOWN_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_DeactivatePdn: can't deactivate PDN, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncPacketSwitchStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - bool * pPacketSwitchStatus = ( bool * ) pData; - - if( pContext == NULL ) - { - LogError( ( "PacketSwitchStatus: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( bool ) ) ) - { - LogError( ( "GetPacketSwitchStatus: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetPacketSwitchStatus: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - - /* Remove prefix. */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* Remove leading space. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( *pInputLine == '0' ) - { - *pPacketSwitchStatus = false; - } - else if( *pInputLine == '1' ) - { - *pPacketSwitchStatus = true; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t _Cellular_GetPacketSwitchStatus( CellularHandle_t cellularHandle, - bool * pPacketSwitchStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqPacketSwitchStatus = - { - "AT+CGATT?", - CELLULAR_AT_WITH_PREFIX, - "+CGATT", - _Cellular_RecvFuncPacketSwitchStatus, - pPacketSwitchStatus, - sizeof( bool ), - }; - - /* Internal function. Callee check parameters. */ - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqPacketSwitchStatus, - CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ActivatePdn( CellularHandle_t cellularHandle, - uint8_t contextId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - bool packetSwitchStatus = false; - - CellularAtReq_t atReqActPdn = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_IsValidPdn( contextId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Check packet switch attach first. If not attached, attach packet switch first. */ - cellularStatus = _Cellular_GetPacketSwitchStatus( cellularHandle, &packetSwitchStatus ); - - if( ( cellularStatus == CELLULAR_SUCCESS ) && ( packetSwitchStatus == false ) ) - { - LogError( ( "Activate Packet switch" ) ); - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s", "AT+CGATT=1" ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqActPdn, - CELLULAR_HL7802_AT_TIMEOUT_60_SECONDS_MS ); - } - else if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Packet switch query failed" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - LogInfo( ( "Packet switch attached" ) ); - } - - /* Check the current attach status. If not activated, activate the PDN context ID. */ - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s=%u", "AT+KCNXUP", contextId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqActPdn, - CELLULAR_HL7802_AT_KCNXUP_TIMEOUT_MS ); - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_ActivatePdn: can't activate PDN, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parsePdnStatusContextId( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MIN ) && - ( tempValue <= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MAX ) ) - { - pPdnStatusBuffers->contextId = ( uint8_t ) tempValue; - } - else - { - LogError( ( "Error in Processing Context Id. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parsePdnStatusContextState( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - int32_t tempValue = 0; - CellularATError_t atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && - ( tempValue <= ( int32_t ) UINT8_MAX ) ) - { - /* Remap the status. */ - switch( tempValue ) - { - case CELLULAR_PDN_STATE_CONNECTED: - pPdnStatusBuffers->state = 1; - break; - - case CELLULAR_PDN_STATE_DISCONNECTED: - case CELLULAR_PDN_STATE_CONNECTING: - case CELLULAR_PDN_STATE_IDLE: - case CELLULAR_PDN_STATE_DISCONNECTING: - pPdnStatusBuffers->state = 0; - break; - - default: - LogError( ( "parsePdnStatusContextState unknown status : %d", tempValue ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - } - else - { - LogError( ( "Error in processing PDN Status Buffer state. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t parsePdnStatusContextType( char * pToken, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( strcmp( pToken, "IPV4" ) == 0 ) - { - pPdnStatusBuffers->pdnContextType = CELLULAR_PDN_CONTEXT_IPV4; - pPdnStatusBuffers->ipAddress.ipAddressType = CELLULAR_IP_ADDRESS_V4; - } - else if( strcmp( pToken, "IPV6" ) == 0 ) - { - pPdnStatusBuffers->pdnContextType = CELLULAR_PDN_CONTEXT_IPV6; - pPdnStatusBuffers->ipAddress.ipAddressType = CELLULAR_IP_ADDRESS_V6; - } - else if( strcmp( pToken, "IPV4V6" ) == 0 ) - { - pPdnStatusBuffers->pdnContextType = CELLULAR_PDN_CONTEXT_IPV4V6; - /* The IP address depends on the format returned. */ - } - else - { - LogError( ( "parsePdnStatusContextType : unknown token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getPdnStatusParseToken( char * pToken, - uint8_t tokenIndex, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - switch( tokenIndex ) - { - case ( CELLULAR_PDN_STATUS_POS_CONTEXT_ID ): - LogDebug( ( "CELLULAR_PDN_STATUS_POS_CONTEXT_ID: %s", pToken ) ); - atCoreStatus = parsePdnStatusContextId( pToken, pPdnStatusBuffers ); - break; - - case ( CELLULAR_PDN_STATUS_POS_AF ): - LogDebug( ( "CELLULAR_PDN_STATUS_POS_AF: %s", pToken ) ); - atCoreStatus = parsePdnStatusContextType( pToken, pPdnStatusBuffers ); - break; - - case ( CELLULAR_PDN_STATUS_POS_STATE ): - LogDebug( ( "CELLULAR_PDN_STATUS_POS_STATE: %s", pToken ) ); - atCoreStatus = parsePdnStatusContextState( pToken, pPdnStatusBuffers ); - break; - - case ( CELLULAR_PDN_STATUS_POS_APN ): - case ( CELLULAR_PDN_STATUS_POS_LOGIN ): - case ( CELLULAR_PDN_STATUS_POS_PASSWORD ): - case ( CELLULAR_PDN_STATUS_POS_IP ): - case ( CELLULAR_PDN_STATUS_POS_GPRS ): - case ( CELLULAR_PDN_STATUS_POS_DNS1 ): - case ( CELLULAR_PDN_STATUS_POS_DNS2 ): - LogDebug( ( "CELLULAR_PDN_STATUS Ignored index %d : %s", tokenIndex, pToken ) ); - atCoreStatus = CELLULAR_AT_SUCCESS; - break; - - default: - LogError( ( "Unknown token in getPdnStatusParseToken %s %d", - pToken, tokenIndex ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getPdnStatusParseLine( char * pRespLine, - CellularPdnStatus_t * pPdnStatusBuffers ) -{ - char * pToken = NULL; - char * pLocalRespLine = pRespLine; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - uint8_t tokenIndex = 0; - - atCoreStatus = Cellular_ATRemovePrefix( &pLocalRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pLocalRespLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalRespLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - tokenIndex = 0; - - while( ( pToken != NULL ) && ( atCoreStatus == CELLULAR_AT_SUCCESS ) ) - { - atCoreStatus = getPdnStatusParseToken( pToken, tokenIndex, pPdnStatusBuffers ); - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - LogError( ( "getPdnStatusParseToken %s index %d failed", pToken, tokenIndex ) ); - } - - tokenIndex++; - - if( pLocalRespLine[ 0 ] == ',' ) - { - pToken = pLocalRespLine; - pLocalRespLine[ 0 ] = '\0'; - pLocalRespLine = &pLocalRespLine[ 1 ]; - } - else - { - if( Cellular_ATGetNextTok( &pLocalRespLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - } - } - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetPdnStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pRespLine = NULL; - CellularPdnStatus_t * pPdnStatusBuffers = ( CellularPdnStatus_t * ) pData; - uint8_t numStatusBuffers = ( uint8_t ) dataLen; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const CellularATCommandLine_t * pCommnadItem = NULL; - - if( pContext == NULL ) - { - LogError( ( "GetPdnStatus: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) ) - { - LogError( ( "GetPdnStatus: Response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pPdnStatusBuffers == NULL ) || ( numStatusBuffers < 1U ) ) - { - LogError( ( "GetPdnStatus: PDN Status bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetPdnStatus: no activated PDN" ) ); - pPdnStatusBuffers[ 0 ].contextId = INVALID_PDN_INDEX; - pktStatus = CELLULAR_PKT_STATUS_OK; - } - else - { - pRespLine = pAtResp->pItm->pLine; - - pCommnadItem = pAtResp->pItm; - - while( ( numStatusBuffers != 0U ) && ( pCommnadItem != NULL ) ) - { - pRespLine = pCommnadItem->pLine; - atCoreStatus = getPdnStatusParseLine( pRespLine, pPdnStatusBuffers ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "getPdnStatusParseLine parse %s failed", pRespLine ) ); - break; - } - - pPdnStatusBuffers++; - numStatusBuffers--; - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_GetPdnStatus( CellularHandle_t cellularHandle, - CellularPdnStatus_t * pPdnStatusBuffers, - uint8_t numStatusBuffers, - uint8_t * pNumStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - const CellularPdnStatus_t * pTempPdnStatusBuffer = pPdnStatusBuffers; - uint8_t numBuffers = 0; - CellularAtReq_t atReqGetPdnStatus = - { - "AT+KCNXCFG?", - CELLULAR_AT_WITH_PREFIX, - "+KCNXCFG", - _Cellular_RecvFuncGetPdnStatus, - pPdnStatusBuffers, - numStatusBuffers, - }; - - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pTempPdnStatusBuffer == NULL ) || ( pNumStatus == NULL ) || ( numStatusBuffers < 1u ) ) - { - LogDebug( ( "_Cellular_GetPdnStatus: Bad input Parameter " ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetPdnStatus, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Populate the Valid number of statuses. */ - *pNumStatus = 0; - numBuffers = numStatusBuffers; - - while( numBuffers != 0U ) - { - /* Check if the PDN state is valid. The context ID of the first - * invalid PDN status is set to FF. */ - if( pTempPdnStatusBuffer->contextId <= CELLULAR_PDN_CONTEXT_ID_MAX ) - { - ( *pNumStatus ) += 1U; - } - else - { - break; - } - - numBuffers--; - pTempPdnStatusBuffer++; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetEidrxSettings( CellularHandle_t cellularHandle, - CellularEidrxSettingsList_t * pEidrxSettingsList ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetEidrx = - { - "AT+KEDRXCFG?", - CELLULAR_AT_MULTI_WITH_PREFIX, - "+KEDRXCFG", - _Cellular_RecvFuncGetEidrxSettings, - pEidrxSettingsList, - CELLULAR_EDRX_LIST_MAX_SIZE, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pEidrxSettingsList == NULL ) - { - LogDebug( ( "Cellular_GetEidrxSettings : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - ( void ) memset( pEidrxSettingsList, 0, sizeof( CellularEidrxSettingsList_t ) ); - /* Query the pEidrxSettings from the network. */ - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetEidrx, - CELLULAR_HL7802_AT_KEDRXCFG_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_GetEidrxSettings: couldn't retrieve Eidrx settings" ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetEidrxSettings( CellularHandle_t cellularHandle, - const CellularEidrxSettings_t * pEidrxSettings ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSetEidrx = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pEidrxSettings == NULL ) - { - LogDebug( ( "Cellular_SetEidrxSettings : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s%u,%u,%u,%u", - "AT+KEDRXCFG=", - pEidrxSettings->mode, - pEidrxSettings->rat, - pEidrxSettings->requestedEdrxVaue, - pEidrxSettings->pagingTimeWindow ); - LogDebug( ( "Eidrx setting: %s ", cmdBuf ) ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSetEidrx, - CELLULAR_HL7802_AT_KEDRXCFG_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "_Cellular_SetEidrxSettings: couldn't set Eidrx settings" ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetRatPriority( CellularHandle_t cellularHandle, - const CellularRat_t * pRatPriorities, - uint8_t ratPrioritiesLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - uint8_t i = 0; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSetRatPriority = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pRatPriorities == NULL ) || ( ratPrioritiesLength == 0U ) || - ( ratPrioritiesLength > ( uint8_t ) CELLULAR_MAX_RAT_PRIORITY_COUNT ) ) - { - LogDebug( ( "Cellular_SetRatPriority : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Reboot is required for this command. */ - ( void ) strcpy( cmdBuf, "AT+KSELACQ=0," ); - - for( i = 0; i < ratPrioritiesLength; i++ ) - { - if( pRatPriorities[ i ] == CELLULAR_RAT_CATM1 ) - { - ( void ) strcat( cmdBuf, "1" ); - } - else if( pRatPriorities[ i ] == CELLULAR_RAT_NBIOT ) - { - ( void ) strcat( cmdBuf, "2" ); - } - else if( pRatPriorities[ i ] == CELLULAR_RAT_GSM ) - { - ( void ) strcat( cmdBuf, "3" ); - } - else - { - LogDebug( ( "Cellular_SetRatPriority : unsupported mode %d", pRatPriorities[ i ] ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - break; - } - - if( i != ( ratPrioritiesLength - 1 ) ) - { - ( void ) strcat( cmdBuf, "," ); - } - } - - LogError( ( " setRatPriority cmdbuf %s", cmdBuf ) ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSetRatPriority, - CELLULAR_HL7802_AT_KSELACQ_TIMEOUT_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetRatPriority( CellularHandle_t cellularHandle, - CellularRat_t * pRatPriorities, - uint8_t ratPrioritiesLength, - uint8_t * pReceiveRatPrioritesLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t ratIndex = 0; - - CellularAtReq_t atReqSetRatPriority = - { - "AT+KSELACQ?", - CELLULAR_AT_WITH_PREFIX, - "+KSELACQ", - _Cellular_RecvFuncGetRatPriority, - pRatPriorities, - ( uint16_t ) ratPrioritiesLength, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pRatPriorities == NULL ) || ( ratPrioritiesLength == 0U ) || - ( ratPrioritiesLength > ( uint8_t ) CELLULAR_MAX_RAT_PRIORITY_COUNT ) || - ( pReceiveRatPrioritesLength == NULL ) ) - { - LogDebug( ( "Cellular_GetRatPriority : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSetRatPriority, - CELLULAR_HL7802_AT_KSELACQ_TIMEOUT_MS ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - for( ratIndex = 0; ratIndex < ratPrioritiesLength; ratIndex++ ) - { - if( pRatPriorities[ ratIndex ] == CELLULAR_RAT_INVALID ) - { - break; - } - } - - *pReceiveRatPrioritesLength = ratIndex; - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSignalInfo( CellularHandle_t cellularHandle, - CellularSignalInfo_t * pSignalInfo ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularRat_t rat = CELLULAR_RAT_INVALID; - CellularAtReq_t atReqQuerySignalInfo = - { - "AT+CESQ", - CELLULAR_AT_WITH_PREFIX, - "+CESQ", - _Cellular_RecvFuncGetSignalInfo, - pSignalInfo, - sizeof( CellularSignalInfo_t ), - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "_Cellular_CheckLibraryStatus failed" ) ); - } - else if( pSignalInfo == NULL ) - { - LogDebug( ( "Cellular_GetSignalInfo : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetCurrentRat( pContext, &rat ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Init the signal value. */ - pSignalInfo->rssi = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->ber = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->bars = CELLULAR_INVALID_SIGNAL_BAR_VALUE; - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqQuerySignalInfo, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - /* If the convert failed, the API will return CELLULAR_INVALID_SIGNAL_BAR_VALUE in bars field. */ - ( void ) _Cellular_ComputeSignalBars( rat, pSignalInfo ); - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetPdnConfig( CellularHandle_t cellularHandle, - uint8_t contextId, - const CellularPdnConfig_t * pPdnConfig ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atGprsConnectionConfighReq = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - /* Parameters are also checked in Cellular_CommonSetPdnConfig. */ - cellularStatus = Cellular_CommonSetPdnConfig( cellularHandle, contextId, pPdnConfig ); - - /* Set the GPRS connection configuration. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "AT+KCNXCFG=%u,\"GPRS\",\"%s\"", - contextId, pPdnConfig->apnName ); - LogDebug( ( "cmd %s", cmdBuf ) ); - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atGprsConnectionConfighReq, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_PacketSwitchAttach: failed, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetPsmSettings( CellularHandle_t cellularHandle, - const CellularPsmSettings_t * pPsmSettings ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atKsleepReq = - { - cmdBuf, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - /* Parameters are checked in this function. */ - cellularStatus = Cellular_CommonSetPsmSettings( cellularHandle, pPsmSettings ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Sleep mode driven by a HW signal (DTR). Sleep level is hibernate. - * Can be woken up by WAKE_UP signal or T3412 timer expiration. */ - if( pPsmSettings->mode == 1 ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "AT+KSLEEP=0,2,30" ); - } - else - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "AT+KSLEEP=2" ); - } - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atKsleepReq, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_PacketSwitchAttach: failed, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -CellularError_t Cellular_Init( CellularHandle_t * pCellularHandle, - const CellularCommInterface_t * pCommInterface ) -{ - CellularTokenTable_t cellularTokenTable = - { - .pCellularUrcHandlerTable = CellularUrcHandlerTable, - .cellularPrefixToParserMapSize = CellularUrcHandlerTableSize, - .pCellularSrcTokenErrorTable = CellularSrcTokenErrorTable, - .cellularSrcTokenErrorTableSize = CellularSrcTokenErrorTableSize, - .pCellularSrcTokenSuccessTable = CellularSrcTokenSuccessTable, - .cellularSrcTokenSuccessTableSize = CellularSrcTokenSuccessTableSize, - .pCellularUrcTokenWoPrefixTable = CellularUrcTokenWoPrefixTable, - .cellularUrcTokenWoPrefixTableSize = CellularUrcTokenWoPrefixTableSize, - .pCellularSrcExtraTokenSuccessTable = NULL, - .cellularSrcExtraTokenSuccessTableSize = 0 - }; - - return Cellular_CommonInit( pCellularHandle, pCommInterface, &cellularTokenTable ); -} - -/*-----------------------------------------------------------*/ diff --git a/modules/hl7802/cellular_hl7802_urc_handler.c b/modules/hl7802/cellular_hl7802_urc_handler.c deleted file mode 100644 index b0e9a802..00000000 --- a/modules/hl7802/cellular_hl7802_urc_handler.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include -#include - -#include "cellular_types.h" -#include "cellular_common.h" -#include "cellular_common_api.h" -#include "cellular_common_portable.h" - -/* Cellular module includes. */ -#include "cellular_hl7802.h" - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessKtcpInd( CellularContext_t * pContext, - char * pInputLine ); -static void handleTcpNotif( CellularSocketContext_t * pSocketData, - uint8_t tcpNotif, - uint32_t sessionId ); -static void _cellular_UrcProcessKtcpNotif( CellularContext_t * pContext, - char * pInputLine ); -static void _cellular_UrcProcessKtcpData( CellularContext_t * pContext, - char * pInputLine ); - -/*-----------------------------------------------------------*/ - -/* Try to Keep this map in Alphabetical order. */ -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularAtParseTokenMap_t CellularUrcHandlerTable[] = -{ - { "CEREG", Cellular_CommonUrcProcessCereg }, - { "CREG", Cellular_CommonUrcProcessCreg }, - { "KTCP_DATA", _cellular_UrcProcessKtcpData }, /* TCP data URC. */ - { "KTCP_IND", _cellular_UrcProcessKtcpInd }, /* TCP status URC. */ - { "KTCP_NOTIF", _cellular_UrcProcessKtcpNotif } /* TCP connection failure. */ -}; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcHandlerTableSize = sizeof( CellularUrcHandlerTable ) / sizeof( CellularAtParseTokenMap_t ); - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessKtcpInd( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - CellularSocketContext_t * pSocketData = NULL; - uint8_t sessionId = 0; - uint32_t socketIndex = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +KTCP_IND: , 1 - * This URC indicate connection success. */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - sessionId = ( uint8_t ) tempValue; - socketIndex = _Cellular_GetSocketId( pContext, sessionId ); - } - else - { - LogError( ( "error parsing _cellular_UrcProcessKtcpInd session ID" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Call the callback function of this session. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogWarn( ( "_cellular_UrcProcessKtcpInd : unknown session data received. " - "The session %u may not be closed properly in previous execution.", sessionId ) ); - } - else - { - pSocketData = _Cellular_GetSocketData( pContext, socketIndex ); - - if( pSocketData == NULL ) - { - LogError( ( "_cellular_UrcProcessKtcpInd : invalid socket index %u", socketIndex ) ); - } - else if( pSocketData->openCallback == NULL ) - { - LogDebug( ( "_cellular_UrcProcessKtcpInd : Open callback not set!!" ) ); - } - else - { - LogDebug( ( "Notify session %d with socket opened\r\n", sessionId ) ); - pSocketData->socketState = SOCKETSTATE_CONNECTED; - pSocketData->openCallback( CELLULAR_URC_SOCKET_OPENED, - pSocketData, pSocketData->pOpenCallbackContext ); - } - } - } - } -} - -/*-----------------------------------------------------------*/ - -static void handleTcpNotif( CellularSocketContext_t * pSocketData, - uint8_t tcpNotif, - uint32_t sessionId ) -{ - /* Suppress warning message if log level is not debug. */ - ( void ) sessionId; - - switch( tcpNotif ) - { - case TCP_NOTIF_TCP_DISCONNECTION: /* TCP disconnection by the server or remote client. */ - - pSocketData->socketState = SOCKETSTATE_DISCONNECTED; - - if( pSocketData->closedCallback != NULL ) - { - LogDebug( ( "Notify session %d with socket disconnected\r\n", sessionId ) ); - pSocketData->closedCallback( pSocketData, pSocketData->pClosedCallbackContext ); - } - - break; - - case TCP_NOTIF_TCP_CONNECTION_ERROR: /* TCP connection error. */ - - pSocketData->socketState = SOCKETSTATE_DISCONNECTED; - - if( pSocketData->openCallback != NULL ) - { - LogDebug( ( "Notify session %d with socket open failed\r\n", sessionId ) ); - pSocketData->openCallback( CELLULAR_URC_SOCKET_OPEN_FAILED, - pSocketData, pSocketData->pOpenCallbackContext ); - } - - break; - - default: - break; - } -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessKtcpNotif( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - CellularSocketContext_t * pSocketData = NULL; - uint8_t sessionId = 0; - tcpConnectionFailure_t tcpNotif = TCP_NOTIF_OK; - uint32_t socketIndex = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +KTCP_NOTIF: , - * This URC indicate connection problem. */ - - /* Remove leading space. */ - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pLocalInputLine ); - - /* Parse the session ID. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - sessionId = ( uint8_t ) tempValue; - socketIndex = _Cellular_GetSocketId( pContext, sessionId ); - } - else - { - LogError( ( "error parsing _cellular_UrcProcessKtcpInd session ID" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Parse the tcp notif. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= TCP_NOTIF_OK ) && ( tempValue <= TCP_NOTIF_MAX ) ) - { - tcpNotif = ( tcpConnectionFailure_t ) tempValue; - } - else - { - LogError( ( "error parsing _cellular_UrcProcessKtcpInd session ID" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Call the callback function of this session. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogWarn( ( "_cellular_UrcProcessKtcpNotif : unknown session data received. " - "The session %u may not be closed properly in previous execution.", sessionId ) ); - } - else - { - pSocketData = _Cellular_GetSocketData( pContext, socketIndex ); - - if( pSocketData == NULL ) - { - LogError( ( "_cellular_UrcProcessKtcpNotif : invalid socket index %u", socketIndex ) ); - } - else - { - handleTcpNotif( pSocketData, tcpNotif, sessionId ); - } - } - } - } -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessKtcpData( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - CellularSocketContext_t * pSocketData = NULL; - uint8_t sessionId = 0; - uint32_t socketIndex = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +KTCP_DATA: , - * This URC indicate connection problem. */ - - /* parse the session ID. */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - sessionId = ( uint8_t ) tempValue; - socketIndex = _Cellular_GetSocketId( pContext, sessionId ); - } - else - { - LogError( ( "error parsing _cellular_UrcProcessKtcpData session ID" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Indicate the upper layer about the data reception. */ - /* Call the callback function of this session. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogWarn( ( "_cellular_UrcProcessKtcpData : unknown session data received. " - "The session %u may not be closed properly in previous execution.", sessionId ) ); - } - else - { - pSocketData = _Cellular_GetSocketData( pContext, socketIndex ); - - if( pSocketData == NULL ) - { - LogError( ( "_cellular_UrcProcessKtcpData : invalid socket index %u", socketIndex ) ); - } - else if( pSocketData->dataReadyCallback == NULL ) - { - LogDebug( ( "_cellular_UrcProcessKtcpData : Data ready callback not set!!" ) ); - } - else - { - pSocketData->dataReadyCallback( pSocketData, pSocketData->pDataReadyCallbackContext ); - } - } - } - } -} - -/*-----------------------------------------------------------*/ diff --git a/modules/hl7802/cellular_hl7802_wrapper.c b/modules/hl7802/cellular_hl7802_wrapper.c deleted file mode 100644 index 8a9def28..00000000 --- a/modules/hl7802/cellular_hl7802_wrapper.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* The config header is always included first. */ -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include - -#include "cellular_platform.h" -#include "cellular_types.h" -#include "cellular_api.h" -#include "cellular_common.h" -#include "cellular_common_api.h" - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_Cleanup( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonCleanup( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcNetworkRegistrationEventCallback( CellularHandle_t cellularHandle, - CellularUrcNetworkRegistrationCallback_t networkRegistrationCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcNetworkRegistrationEventCallback( cellularHandle, networkRegistrationCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcPdnEventCallback( CellularHandle_t cellularHandle, - CellularUrcPdnEventCallback_t pdnEventCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcPdnEventCallback( cellularHandle, pdnEventCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcGenericCallback( CellularHandle_t cellularHandle, - CellularUrcGenericCallback_t genericCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcGenericCallback( cellularHandle, genericCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterModemEventCallback( CellularHandle_t cellularHandle, - CellularModemEventCallback_t modemEventCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterModemEventCallback( cellularHandle, modemEventCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ATCommandRaw( CellularHandle_t cellularHandle, - const char * pATCommandPrefix, - const char * pATCommandPayload, - CellularATCommandType_t atCommandType, - CellularATCommandResponseReceivedCallback_t responseReceivedCallback, - void * pData, - uint16_t dataLen ) -{ - return Cellular_CommonATCommandRaw( cellularHandle, pATCommandPrefix, pATCommandPayload, atCommandType, - responseReceivedCallback, pData, dataLen ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_CreateSocket( CellularHandle_t cellularHandle, - uint8_t pdnContextId, - CellularSocketDomain_t socketDomain, - CellularSocketType_t socketType, - CellularSocketProtocol_t socketProtocol, - CellularSocketHandle_t * pSocketHandle ) -{ - return Cellular_CommonCreateSocket( cellularHandle, pdnContextId, socketDomain, socketType, - socketProtocol, pSocketHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketSetSockOpt( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketOptionLevel_t optionLevel, - CellularSocketOption_t option, - const uint8_t * pOptionValue, - uint32_t optionValueLength ) -{ - return Cellular_CommonSocketSetSockOpt( cellularHandle, socketHandle, optionLevel, option, - pOptionValue, optionValueLength ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterDataReadyCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketDataReadyCallback_t dataReadyCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterDataReadyCallback( cellularHandle, socketHandle, - dataReadyCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterSocketOpenCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketOpenCallback_t socketOpenCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterSocketOpenCallback( cellularHandle, socketHandle, - socketOpenCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterClosedCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketClosedCallback_t closedCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterClosedCallback( cellularHandle, socketHandle, - closedCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RfOn( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonRfOn( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RfOff( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonRfOff( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetIPAddress( CellularHandle_t cellularHandle, - uint8_t contextId, - char * pBuffer, - uint32_t bufferLength ) -{ - return Cellular_CommonGetIPAddress( cellularHandle, contextId, pBuffer, bufferLength ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetModemInfo( CellularHandle_t cellularHandle, - CellularModemInfo_t * pModemInfo ) -{ - return Cellular_CommonGetModemInfo( cellularHandle, pModemInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetRegisteredNetwork( CellularHandle_t cellularHandle, - CellularPlmnInfo_t * pNetworkInfo ) -{ - return Cellular_CommonGetRegisteredNetwork( cellularHandle, pNetworkInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetNetworkTime( CellularHandle_t cellularHandle, - CellularTime_t * pNetworkTime ) -{ - return Cellular_CommonGetNetworkTime( cellularHandle, pNetworkTime ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetServiceStatus( CellularHandle_t cellularHandle, - CellularServiceStatus_t * pServiceStatus ) -{ - return Cellular_CommonGetServiceStatus( cellularHandle, pServiceStatus ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSimCardInfo( CellularHandle_t cellularHandle, - CellularSimCardInfo_t * pSimCardInfo ) -{ - return Cellular_CommonGetSimCardInfo( cellularHandle, pSimCardInfo ); -} - -/*-----------------------------------------------------------*/ - - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetPsmSettings( CellularHandle_t cellularHandle, - CellularPsmSettings_t * pPsmSettings ) -{ - return Cellular_CommonGetPsmSettings( cellularHandle, pPsmSettings ); -} - -/*-----------------------------------------------------------*/ diff --git a/modules/sara_r4/cellular_r4.c b/modules/sara_r4/cellular_r4.c deleted file mode 100644 index 8efbc5b9..00000000 --- a/modules/sara_r4/cellular_r4.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -#include - -#include "cellular_platform.h" -#include "cellular_common.h" -#include "cellular_common_portable.h" -#include "cellular_r4.h" - -/*-----------------------------------------------------------*/ - -#define ENBABLE_MODULE_UE_RETRY_COUNT ( 3U ) -#define ENBABLE_MODULE_UE_RETRY_TIMEOUT ( 5000U ) -#define ENBABLE_MODULE_UE_REBOOT_POLL_TIME ( 2000U ) -#define ENBABLE_MODULE_UE_REBOOT_MAX_TIME ( 25000U ) - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq ); - -/*-----------------------------------------------------------*/ - -static cellularModuleContext_t cellularHl7802Context = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenErrorTable[] = -{ "ERROR", "BUSY", "NO CARRIER", "NO ANSWER", "NO DIALTONE", "ABORTED", "+CMS ERROR", "+CME ERROR", "SEND FAIL" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenErrorTableSize = sizeof( CellularSrcTokenErrorTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenSuccessTable[] = -{ "OK", "@" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenSuccessTableSize = sizeof( CellularSrcTokenSuccessTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularUrcTokenWoPrefixTable[] = -{ "RDY" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcTokenWoPrefixTableSize = sizeof( CellularUrcTokenWoPrefixTable ) / sizeof( char * ); - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint8_t tryCount = 0; - - if( pAtReq == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - for( ; tryCount < ENBABLE_MODULE_UE_RETRY_COUNT; tryCount++ ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, *pAtReq, ENBABLE_MODULE_UE_RETRY_TIMEOUT ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext, - void ** ppModuleContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t i = 0; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ppModuleContext == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Initialize the module context. */ - ( void ) memset( &cellularHl7802Context, 0, sizeof( cellularModuleContext_t ) ); - - for( i = 0; i < TCP_SESSION_TABLE_LEGNTH; i++ ) - { - cellularHl7802Context.pSessionMap[ i ] = INVALID_SOCKET_INDEX; - } - - *ppModuleContext = ( void * ) &cellularHl7802Context; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Parse AT response for current MNO profile */ -static CellularPktStatus_t _Cellular_RecvFuncGetCurrentMNOProfile( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - MNOProfileType_t * pCurrentMNOProfile = ( MNOProfileType_t * ) pData; - char * pToken = NULL; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetCurrentMNOProfile: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( MNOProfileType_t ) ) ) - { - LogError( ( "_Cellular_RecvFuncGetCurrentMNOProfile: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "_Cellular_RecvFuncGetCurrentMNOProfile: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - - /* Remove prefix. */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* Remove leading space. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MNO_PROFILE_SW_DEFAULT ) && ( tempValue <= MNO_PROFILE_STANDARD_EUROPE ) ) - { - *pCurrentMNOProfile = tempValue; - LogInfo( ( "_Cellular_RecvFuncGetCurrentMNOProfile: pCurrentMNOProfile [%d]", *pCurrentMNOProfile ) ); - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ -/* Get modem's current MNO profile */ -static CellularError_t _Cellular_GetCurrentMNOProfile( CellularContext_t * pContext, - MNOProfileType_t * pCurrentMNOProfile ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetCurrentMNOProfile = - { - "AT+UMNOPROF?", - CELLULAR_AT_WITH_PREFIX, - "+UMNOPROF", - _Cellular_RecvFuncGetCurrentMNOProfile, - NULL, - sizeof( MNOProfileType_t ), - }; - - atReqGetCurrentMNOProfile.pData = pCurrentMNOProfile; - - /* Internal function. Callee check parameters. */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetCurrentMNOProfile ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Reboot modem and wait for ready state. */ - -CellularError_t rebootCellularModem( CellularContext_t * pContext, - bool disablePsm, - bool disableEidrx ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t count = 0; - - CellularAtReq_t atReqGetNoResult = - { - "AT+CFUN=15", - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - LogInfo( ( "rebootCellularModem: Rebooting Modem." ) ); - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - Platform_Delay( ENBABLE_MODULE_UE_REBOOT_POLL_TIME ); - count = count + ENBABLE_MODULE_UE_REBOOT_POLL_TIME; - - /* wait for modem after reboot*/ - while( count < ENBABLE_MODULE_UE_REBOOT_MAX_TIME ) - { - LogInfo( ( "rebootCellularModem: Use ATE0 command to test modem status." ) ); - - atReqGetNoResult.pAtCmd = "ATE0"; - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, ENBABLE_MODULE_UE_REBOOT_POLL_TIME ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - LogInfo( ( "rebootCellularModem: Modem is now available." ) ); - - Platform_Delay( ENBABLE_MODULE_UE_REBOOT_POLL_TIME * 3 ); - - /* Query current PSM settings. */ - atReqGetNoResult.pAtCmd = "AT+CPSMS?"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - - if( disablePsm && ( cellularStatus == CELLULAR_SUCCESS ) ) - { - LogInfo( ( "rebootCellularModem: Disable +CPSMS setting." ) ); - atReqGetNoResult.pAtCmd = "AT+CPSMS=0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( disableEidrx && ( cellularStatus == CELLULAR_SUCCESS ) ) - { - LogInfo( ( "rebootCellularModem: Disable +CEDRXS setting." ) ); - atReqGetNoResult.pAtCmd = "AT+CEDRXS=0,4"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - break; - } - else - { - LogWarn( ( "rebootCellularModem: Modem is not ready. Retry sending ATE0." ) ); - } - - count = count + ENBABLE_MODULE_UE_REBOOT_POLL_TIME; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - CellularAtReq_t atReqGetWithResult = - { - NULL, - CELLULAR_AT_WO_PREFIX, - NULL, - NULL, - NULL, - 0 - }; - char pAtCmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { 0 }; - - if( pContext != NULL ) - { - /* Disable echo. */ - atReqGetWithResult.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetWithResult ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Disable DTR function. */ - atReqGetNoResult.pAtCmd = "AT&D0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - #ifndef CELLULAR_CONFIG_DISABLE_FLOW_CONTROL - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Enable RTS/CTS hardware flow control. */ - atReqGetNoResult.pAtCmd = "AT+IFC=2,2"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - #endif - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Report verbose mobile termination error. */ - atReqGetNoResult.pAtCmd = "AT+CMEE=2"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Setup mobile network operator profiles. */ - /* Setting +UMNOPROF profile will automatically select suitable values for +URAT and +UBANDMASK. */ - - /* Check current MNO profile first to avoid unneccessary modem reboot. */ - MNOProfileType_t currentMNOProfile = MNO_PROFILE_NOT_SET; - cellularStatus = _Cellular_GetCurrentMNOProfile( pContext, ¤tMNOProfile ); - - LogInfo( ( "Cellular_ModuleEnableUE: currentMNOProfile = [%d], desiredProfile = [%d]", currentMNOProfile, CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ) ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Set MNO profile if not set already */ - if( ( currentMNOProfile != CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ) && ( CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE != MNO_PROFILE_NOT_SET ) ) - { - atReqGetNoResult.pAtCmd = pAtCmdBuf; - ( void ) snprintf( ( char * ) atReqGetNoResult.pAtCmd, CELLULAR_AT_CMD_MAX_SIZE, "%s%d", "AT+COPS=2;+UMNOPROF=", CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ); - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = rebootCellularModem( pContext, true, true ); - } - } - - #ifdef CELLULAR_CONFIG_SARA_R4_REBOOT_ON_INIT - else - { - cellularStatus = rebootCellularModem( pContext, true, true ); - } - #endif - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+COPS=0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+CFUN=1"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqGetNoResult.pAtCmd = "AT+COPS=3,2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CGREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CEREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CTZR=1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* TODO: +CGEV URC enable. */ - /* atReqGetNoResult.pAtCmd = "AT+CGEREP=2,0"; */ - /* (void)_Cellular_AtcmdRequestWithCallback(pContext, atReqGetNoResult); */ - - /* Power saving mode URC enable. */ - atReqGetNoResult.pAtCmd = "AT+UPSMR=1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* Mobile termination event reporting +CIEV URC enable. */ - atReqGetNoResult.pAtCmd = "AT+CMER=1,0,0,2,1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* Enable signal level change indication via +CIEV URC. (To enable all indications, set to 4095) */ - atReqGetNoResult.pAtCmd = "AT+UCIND=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* Enable greeting message "RDY" on modem bootup. */ - atReqGetNoResult.pAtCmd = "AT+CSGT=1,\"RDY\""; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSocketId( CellularContext_t * pContext, - uint8_t sessionId ) -{ - cellularModuleContext_t * pModuleContext = NULL; - uint32_t socketIndex = INVALID_SOCKET_INDEX; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext != NULL ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - else - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( ( cellularStatus == CELLULAR_SUCCESS ) && ( sessionId <= ( ( uint8_t ) MAX_TCP_SESSION_ID ) ) ) - { - socketIndex = pModuleContext->pSessionMap[ sessionId ]; - } - - return socketIndex; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSessionId( CellularContext_t * pContext, - uint32_t socketIndex ) -{ - cellularModuleContext_t * pModuleContext = NULL; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t sessionId = INVALID_SESSION_ID; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_GetSessionId invalid cellular context" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogError( ( "_Cellular_GetSessionId invalid socketIndex" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - for( sessionId = 0; sessionId < TCP_SESSION_TABLE_LEGNTH; sessionId++ ) - { - if( pModuleContext->pSessionMap[ sessionId ] == socketIndex ) - { - break; - } - } - - /* Mapping is not found in the session mapping table. */ - if( sessionId == TCP_SESSION_TABLE_LEGNTH ) - { - sessionId = INVALID_SESSION_ID; - } - } - else - { - sessionId = INVALID_SESSION_ID; - } - - return sessionId; -} diff --git a/modules/sara_r4/cellular_r4.h b/modules/sara_r4/cellular_r4.h deleted file mode 100644 index ff7ff5d5..00000000 --- a/modules/sara_r4/cellular_r4.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#ifndef __CELLULAR_R4_H__ -#define __CELLULAR_R4_H__ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -/*-----------------------------------------------------------*/ - -#define MIN_TCP_SESSION_ID ( 0 ) -#define MAX_TCP_SESSION_ID ( 6 ) -#define TCP_SESSION_TABLE_LEGNTH ( MAX_TCP_SESSION_ID + 1 ) - -#define INVALID_SOCKET_INDEX ( UINT32_MAX ) -#define INVALID_SESSION_ID ( UINT32_MAX ) - -/*-----------------------------------------------------------*/ - -typedef struct cellularModuleContext -{ - uint32_t pSessionMap[ TCP_SESSION_TABLE_LEGNTH ]; -} cellularModuleContext_t; - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSocketId( CellularContext_t * pContext, - uint8_t sessionId ); - -uint32_t _Cellular_GetSessionId( CellularContext_t * pContext, - uint32_t socketIndex ); - -CellularError_t rebootCellularModem( CellularContext_t * pContext, - bool disablePsm, - bool disableEidrx ); - -/*-----------------------------------------------------------*/ - -/** - * @brief Cellular MNO profiles. - */ -typedef enum MNOProfileType -{ - MNO_PROFILE_SW_DEFAULT = 0, - MNO_PROFILE_SIM_ICCID_IMSI_SELECT = 1, - MNO_PROFILE_ATT = 2, - MNO_PROFILE_VERIZON = 3, - MNO_PROFILE_TELSTRA = 4, - MNO_PROFILE_TMOBILE = 5, - MNO_PROFILE_CHINA_TELECOM = 6, - MNO_PROFILE_SPRINT = 8, - MNO_PROFILE_VODAFONE = 19, - MNO_PROFILE_GLOBAL = 90, - MNO_PROFILE_STANDARD_EUROPE = 100, - MNO_PROFILE_NOT_SET = 999 -} MNOProfileType_t; - -/*-----------------------------------------------------------*/ - -/* Select network MNO profile. Default value is MNO_PROFILE_NOT_SET */ -#ifndef CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE - #define CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ( MNO_PROFILE_NOT_SET ) -#endif - -/* - * By default socket is closed in normal mode i.e. flag is 0. - * In normal mode, +USOCL can take time to close socket (Max timeout is 120 sec). - * To avoid wait, socket can be closed in async mode via flag. - * In mode, socket close will be notified via +UUSOCL URC. - * Drawback of mode is that if try to deactivate context (e.g. AT+CGACT=0,1). - * prior to socket close URC, AT command will result in ERROR. - */ -#define CELLULAR_CONFIG_SET_SOCKET_CLOSE_ASYNC_MODE ( 0U ) - -/*-----------------------------------------------------------*/ - -/* MAX valid PDP contexts */ -#define MAX_PDP_CONTEXTS ( 4U ) - -#define DEFAULT_BEARER_CONTEXT_ID ( 1U ) /* SARA-R4 default bearer context */ - -#define CELULAR_PDN_CONTEXT_TYPE_MAX_SIZE ( 7U ) /* The length of IP type e.g. IPV4V6. */ - -/*-----------------------------------------------------------*/ - -/* +CGDCONT PDN context definition tokens */ -#define CELLULAR_PDN_STATUS_POS_CONTEXT_ID ( 0U ) -#define CELLULAR_PDN_STATUS_POS_CONTEXT_TYPE ( 1U ) -#define CELLULAR_PDN_STATUS_POS_APN_NAME ( 2U ) -#define CELLULAR_PDN_STATUS_POS_IP_ADDRESS ( 3U ) - -/* +CGACT PDN context activation tokens */ -#define CELLULAR_PDN_ACT_STATUS_POS_CONTEXT_ID ( 0U ) -#define CELLULAR_PDN_ACT_STATUS_POS_CONTEXT_STATE ( 1U ) - -/** - * @brief Context info from +CGDCONT (Context IP type, APN name, IP Address) - */ -typedef struct CellularPdnContextInfo -{ - bool contextsPresent[ MAX_PDP_CONTEXTS ]; /**< Context present in +CGDCONT response or not. */ - char ipType[ MAX_PDP_CONTEXTS ][ CELULAR_PDN_CONTEXT_TYPE_MAX_SIZE ]; /**< PDN Context type. */ - char apnName[ MAX_PDP_CONTEXTS ][ CELLULAR_APN_MAX_SIZE ]; /**< APN name. */ - char ipAddress[ MAX_PDP_CONTEXTS ][ CELLULAR_IP_ADDRESS_MAX_SIZE ]; /**< IP address. */ -} CellularPdnContextInfo_t; - -/** - * @brief Context state from +CGACT - */ -typedef struct CellularPdnContextActInfo -{ - bool contextsPresent[ MAX_PDP_CONTEXTS ]; /**< Context present in +CGACT response or not. */ - bool contextActState[ MAX_PDP_CONTEXTS ]; /**< Context active state from +CGACT response. */ -} CellularPdnContextActInfo_t; - -/*-----------------------------------------------------------*/ - -extern CellularAtParseTokenMap_t CellularUrcHandlerTable[]; -extern uint32_t CellularUrcHandlerTableSize; - -extern const char * CellularSrcTokenErrorTable[]; -extern uint32_t CellularSrcTokenErrorTableSize; - -extern const char * CellularSrcTokenSuccessTable[]; -extern uint32_t CellularSrcTokenSuccessTableSize; - -extern const char * CellularUrcTokenWoPrefixTable[]; -extern uint32_t CellularUrcTokenWoPrefixTableSize; - -/*-----------------------------------------------------------*/ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* ifndef __CELLULAR_R4_H__ */ diff --git a/modules/sara_r4/cellular_r4_api.c b/modules/sara_r4/cellular_r4_api.c deleted file mode 100644 index cb411130..00000000 --- a/modules/sara_r4/cellular_r4_api.c +++ /dev/null @@ -1,2906 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include -#include - -/* Cellular includes. */ -#include "cellular_platform.h" -#include "cellular_types.h" -#include "cellular_api.h" -#include "cellular_common_api.h" -#include "cellular_common.h" -#include "cellular_at_core.h" - -/* Cellular module incliudes. */ -#include "cellular_r4.h" - -/*-----------------------------------------------------------*/ - -/* TODO : confirm the value. */ -#define PDN_ACT_PACKET_REQ_TIMEOUT_MS ( 150000UL ) - -#define PDN_DEACT_PACKET_REQ_TIMEOUT_MS ( 40000UL ) - -#define GPRS_ATTACH_REQ_TIMEOUT_MS ( 180000UL ) - -#define DNS_QUERY_REQ_TIMEOUT_MS ( 120000UL ) - -#define SOCKET_CLOSE_PACKET_REQ_TIMEOUT_MS ( 120000U ) - -#define SOCKET_CONNECT_PACKET_REQ_TIMEOUT_MS ( 120000U ) - -#define CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ( 32U ) - -#define DATA_SEND_TIMEOUT_MS ( 10000U ) - -#define PACKET_REQ_TIMEOUT_MS ( 10000U ) - -#define DATA_READ_TIMEOUT_MS ( 50000UL ) - -#define SOCKET_DATA_PREFIX_TOKEN "+USORD: " -#define SOCKET_DATA_PREFIX_TOKEN_LEN ( 8U ) -#define SOCKET_DATA_PREFIX_STRING_LENGTH ( SOCKET_DATA_PREFIX_TOKEN_LEN + 9U ) -#define RAT_PRIOIRTY_LIST_LENGTH ( 3U ) - -/** - * @brief Parameters involved in receiving data through sockets - */ -typedef struct _socketDataRecv -{ - uint32_t * pDataLen; - uint8_t * pData; -} _socketDataRecv_t; - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t lineLength, - char ** ppDataStart, - uint32_t * pDataLength ); -static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pAtResp, - const _socketDataRecv_t * pDataRecv, - uint32_t outBufSize ); -static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t storeAccessModeAndAddress( CellularContext_t * pContext, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ); -static CellularPktStatus_t _Cellular_RecvFuncGetSocketId( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t _Cellular_GetSocketNumber( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - uint8_t * pSessionId ); - -CellularError_t Cellular_SetPdnConfig( CellularHandle_t cellularHandle, - uint8_t contextId, - const CellularPdnConfig_t * pPdnConfig ); - -static CellularError_t _Cellular_GetPacketSwitchStatus( CellularHandle_t cellularHandle, - bool * pPacketSwitchStatus ); - -static CellularError_t _Cellular_GetContextActivationStatus( CellularHandle_t cellularHandle, - CellularPdnContextActInfo_t * pPdpContextsActInfo ); - -static bool _parseExtendedSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ); -static bool _parseSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ); -static CellularPktStatus_t _Cellular_RecvFuncGetSignalInfo( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); -static CellularError_t controlSignalStrengthIndication( CellularContext_t * pContext, - bool enable ); - -CellularError_t Cellular_SetPsmSettings( CellularHandle_t cellularHandle, - const CellularPsmSettings_t * pPsmSettings ); - -static CellularError_t _Cellular_isSockOptSupport( CellularSocketOptionLevel_t optionLevel, - CellularSocketOption_t option ); - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t socketRecvDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t lineLength, - char ** ppDataStart, - uint32_t * pDataLength ) -{ - char * pToken = NULL; - int32_t tempValue = 0; - CellularATError_t atResult = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char pLocalLine[ SOCKET_DATA_PREFIX_STRING_LENGTH + 1 ] = { '\0' }; - char * pDataStart = pLocalLine; - - ( void ) lineLength; - - /* pCallbackContext is not used in this function. It should be NULL. */ - if( ( pLine == NULL ) || ( ppDataStart == NULL ) || ( pDataLength == NULL ) || ( pCallbackContext != NULL ) ) - { - LogError( ( "socketRecvData: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( strncmp( pLine, SOCKET_DATA_PREFIX_TOKEN, SOCKET_DATA_PREFIX_TOKEN_LEN ) != 0 ) - { - /* Prefix string which is not SOCKET_DATA_PREFIX_TOKEN does't indicate data start. - * Set data length to 0.*/ - *ppDataStart = NULL; - *pDataLength = 0; - } - else - { - /* The string length of "+USORD: [,],"". */ - strncpy( pLocalLine, pLine, SOCKET_DATA_PREFIX_STRING_LENGTH ); - pDataStart = &pLocalLine[ SOCKET_DATA_PREFIX_TOKEN_LEN ]; - - /* Skip the socket number. */ - atResult = Cellular_ATGetNextTok( &pDataStart, &pToken ); - - /* Parse the receive data length. */ - if( ( atResult == CELLULAR_AT_SUCCESS ) && ( pDataStart[ 0 ] == '"' ) ) - { - /* Peek the next symbol. If it is \", then length is ommited. Received byte is 0. */ - LogDebug( ( "socketRecvData: 0 received bytes." ) ); - *pDataLength = 0U; - *ppDataStart = NULL; - } - else if( atResult == CELLULAR_AT_SUCCESS ) - { - /* Parse the length. */ - atResult = Cellular_ATGetNextTok( &pDataStart, &pToken ); - - if( atResult == CELLULAR_AT_SUCCESS ) - { - atResult = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( ( tempValue < 0 ) && ( ( uint32_t ) tempValue > CELLULAR_MAX_RECV_DATA_LEN ) ) - { - LogError( ( "socketRecvData: Bad parameters" ) ); - atResult = CELLULAR_AT_ERROR; - } - } - - if( atResult == CELLULAR_AT_SUCCESS ) - { - /* Change +USROD: ,," to +USROD: ,,\r. */ - pDataStart = &pLine[ pDataStart - pLocalLine ]; - - if( pDataStart[ 0 ] == '\"' ) - { - *pDataStart = '\r'; - *ppDataStart = ( char * ) &pDataStart[ 1 ]; - *pDataLength = ( uint32_t ) tempValue; - } - } - } - else - { - LogDebug( ( "socketRecvDataPrefix : pLine [%s] with lineLength [%d] is not data prefix", pLine, lineLength ) ); - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularATError_t getDataFromResp( const CellularATCommandResponse_t * pAtResp, - const _socketDataRecv_t * pDataRecv, - uint32_t outBufSize ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const char * pInputLine = NULL; - uint32_t dataLenToCopy = 0; - - /* Check if the received data size is greater than the output buffer size. */ - if( *pDataRecv->pDataLen > outBufSize ) - { - LogError( ( "Data is turncated, received data length %u, out buffer size %u", - *pDataRecv->pDataLen, outBufSize ) ); - dataLenToCopy = outBufSize; - *pDataRecv->pDataLen = outBufSize; - } - else - { - dataLenToCopy = *pDataRecv->pDataLen; - } - - /* Data is stored in the next intermediate response. */ - pInputLine = pAtResp->pItm->pNext->pLine; - - if( ( pInputLine != NULL ) && ( dataLenToCopy > 0U ) ) - { - /* Copy the data to the out buffer. */ - ( void ) memcpy( ( void * ) pDataRecv->pData, ( const void * ) pInputLine, dataLenToCopy ); - } - else - { - LogError( ( "Receive Data: paramerter error, data pointer %p, data to copy %u", - pInputLine, dataLenToCopy ) ); - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - - return atCoreStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncData( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char * pInputLine = NULL, * pToken = NULL; - const _socketDataRecv_t * pDataRecv = ( _socketDataRecv_t * ) pData; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "Receive Data: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "Receive Data: response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pDataRecv == NULL ) || ( pDataRecv->pData == NULL ) || ( pDataRecv->pDataLen == NULL ) ) - { - LogError( ( "Receive Data: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; /* The first item is the data prefix. */ - - /* Check the data prefix token "+USORD: ". */ - if( strncmp( pInputLine, SOCKET_DATA_PREFIX_TOKEN, SOCKET_DATA_PREFIX_TOKEN_LEN ) != 0 ) - { - LogError( ( "response item error in prefix CONNECT" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( pAtResp->pItm->pNext == NULL ) - { - /* Modem return +USORD: 0,"". No data returned since there is no data - * length field in modem response. */ - *pDataRecv->pDataLen = 0; - } - else - { - /* Parse the data length. */ - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( tempValue >= 0 ) - { - *pDataRecv->pDataLen = ( uint32_t ) tempValue; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - /* Process the data buffer. Modem may also return +USORD: 0,0,"" with 0 data length. - * Process the data response only when data length is greater than 0. */ - if( ( atCoreStatus == CELLULAR_AT_SUCCESS ) && ( *pDataRecv->pDataLen > 0U ) ) - { - atCoreStatus = getDataFromResp( pAtResp, pDataRecv, dataLen ); - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t storeAccessModeAndAddress( CellularContext_t * pContext, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pRemoteSocketAddress == NULL ) || ( socketHandle == NULL ) ) - { - LogDebug( ( "storeAccessModeAndAddress: Invalid socket address" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_ALLOCATED ) - { - LogError( ( "storeAccessModeAndAddress, bad socket state %d", - socketHandle->socketState ) ); - cellularStatus = CELLULAR_INTERNAL_FAILURE; - } - else if( dataAccessMode != CELLULAR_ACCESSMODE_BUFFER ) - { - LogError( ( "storeAccessModeAndAddress, Access mode not supported %d", - dataAccessMode ) ); - cellularStatus = CELLULAR_UNSUPPORTED; - } - else - { - socketHandle->remoteSocketAddress.port = pRemoteSocketAddress->port; - socketHandle->dataMode = dataAccessMode; - socketHandle->remoteSocketAddress.ipAddress.ipAddressType = - pRemoteSocketAddress->ipAddress.ipAddressType; - ( void ) strncpy( socketHandle->remoteSocketAddress.ipAddress.ipAddress, - pRemoteSocketAddress->ipAddress.ipAddress, - CELLULAR_IP_ADDRESS_MAX_SIZE + 1U ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library types. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetSocketId( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - uint8_t * pSessionId = pData; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "GetSocketId: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pSessionId == NULL ) || ( dataLen != sizeof( uint8_t ) ) ) - { - LogError( ( "GetSocketId: Bad parameters" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetSocketId: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pInputLine, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - *pSessionId = ( uint8_t ) tempValue; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t _Cellular_GetSocketNumber( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - uint8_t * pSessionId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqSocketConnect = - { - "AT+USOCR=6,0", - CELLULAR_AT_WITH_PREFIX, - "+USOCR", - _Cellular_RecvFuncGetSocketId, - NULL, - sizeof( uint8_t ), - }; - - ( void ) socketHandle; - - atReqSocketConnect.pData = pSessionId; - - /* Internal function. Caller checks parameters. */ - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSocketConnect ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "_Cellular_GetSocketNumber: get socekt number failed PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_SocketRecv( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint8_t * pBuffer, - uint32_t bufferLength, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint32_t * pReceivedDataLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - uint32_t recvTimeout = DATA_READ_TIMEOUT_MS; - uint32_t recvLen = bufferLength; - _socketDataRecv_t dataRecv = { 0 }; - CellularAtReq_t atReqSocketRecv = - { - NULL, - CELLULAR_AT_MULTI_DATA_WO_PREFIX, - "+USORD", - _Cellular_RecvFuncData, - NULL, - 0, - }; - uint32_t sessionId = 0; - - dataRecv.pDataLen = pReceivedDataLength; - dataRecv.pData = pBuffer; - - atReqSocketRecv.pAtCmd = cmdBuf; - atReqSocketRecv.pData = ( void * ) &dataRecv; - atReqSocketRecv.dataLen = bufferLength; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Cellular_SocketRecv: _Cellular_CheckLibraryStatus failed." ) ); - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketRecv: Invalid socketHandle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pBuffer == NULL ) || ( pReceivedDataLength == NULL ) || ( bufferLength == 0U ) ) - { - LogError( ( "Cellular_SocketRecv: Bad input Param." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_CONNECTED ) - { - /* Check the socket connection state. */ - LogInfo( ( "Cellular_SocketRecv: socket state %d is not connected.", socketHandle->socketState ) ); - - if( ( socketHandle->socketState == SOCKETSTATE_ALLOCATED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - cellularStatus = CELLULAR_SOCKET_NOT_CONNECTED; - } - else - { - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - } - else - { - sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - if( sessionId == INVALID_SESSION_ID ) - { - LogError( ( "Cellular_SocketRecv : invalid session ID for socket index %u", - socketHandle->socketId ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Update recvLen to maximum module length. */ - if( CELLULAR_MAX_RECV_DATA_LEN <= bufferLength ) - { - recvLen = ( uint32_t ) CELLULAR_MAX_RECV_DATA_LEN; - } - - /* Update receive timeout to default timeout if not set with setsocketopt. */ - if( recvLen > 0 ) - { - if( socketHandle->recvTimeoutMs != 0U ) - { - recvTimeout = socketHandle->recvTimeoutMs; - } - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, - "%s%u,%u", "AT+USORD=", sessionId, recvLen ); - pktStatus = _Cellular_TimeoutAtcmdDataRecvRequestWithCallback( pContext, - atReqSocketRecv, - recvTimeout, - socketRecvDataPrefix, - NULL ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - /* Reset data handling parameters. */ - LogError( ( "Cellular_SocketRecv: Data Receive fail, pktStatus: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t socketSendDataPrefix( void * pCallbackContext, - char * pLine, - uint32_t * pBytesRead ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - if( ( pLine == NULL ) || ( pBytesRead == NULL ) ) - { - LogError( ( "socketSendDataPrefix: pLine is invalid or pBytesRead is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pCallbackContext != NULL ) - { - LogError( ( "socketSendDataPrefix: pCallbackContext is not NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( *pBytesRead != 1U ) - { - LogDebug( ( "socketSendDataPrefix: pBytesRead %u %s is not 1", *pBytesRead, pLine ) ); - } - else - { - /* After the data prefix, there should not be any data in stream. - * Cellular commmon processes AT command in lines. Add a '\0' after '@'. */ - if( strcmp( pLine, "@" ) == 0 ) - { - pLine[ 1 ] = '\n'; - *pBytesRead = 2; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_SocketSend( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - const uint8_t * pData, - uint32_t dataLength, - /* coverity[misra_c_2012_rule_8_13_violation] */ - uint32_t * pSentDataLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t sendTimeout = DATA_SEND_TIMEOUT_MS; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketSend = { 0 }; - CellularAtDataReq_t atDataReqSocketSend = { 0 }; - uint32_t sessionId = 0; - - atReqSocketSend.atCmdType = CELLULAR_AT_NO_RESULT; - atReqSocketSend.pAtCmd = cmdBuf; - - atDataReqSocketSend.pData = pData; - atDataReqSocketSend.dataLen = dataLength; - atDataReqSocketSend.pSentDataLength = pSentDataLength; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_SocketSend: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( socketHandle == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( pSentDataLength == NULL ) || ( dataLength == 0U ) ) - { - LogDebug( ( "Cellular_SocketSend: Invalid parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle->socketState != SOCKETSTATE_CONNECTED ) - { - /* Check the socket connection state. */ - LogInfo( ( "Cellular_SocketSend: socket state %d is not connected.", socketHandle->socketState ) ); - - if( ( socketHandle->socketState == SOCKETSTATE_ALLOCATED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - cellularStatus = CELLULAR_SOCKET_NOT_CONNECTED; - } - else - { - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - } - else - { - sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - if( sessionId == INVALID_SESSION_ID ) - { - LogError( ( "Cellular_SocketSend : invalid session ID for socket index %u", - socketHandle->socketId ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Send data length check. */ - if( dataLength > ( uint32_t ) CELLULAR_MAX_SEND_DATA_LEN ) - { - atDataReqSocketSend.dataLen = ( uint32_t ) CELLULAR_MAX_SEND_DATA_LEN; - } - - /* Check send timeout. If not set by setsockopt, use default value. */ - if( socketHandle->sendTimeoutMs != 0U ) - { - sendTimeout = socketHandle->sendTimeoutMs; - } - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%u,%u", - "AT+USOWR=", sessionId, atDataReqSocketSend.dataLen ); - - pktStatus = _Cellular_AtcmdDataSend( pContext, atReqSocketSend, atDataReqSocketSend, - socketSendDataPrefix, NULL, - PACKET_REQ_TIMEOUT_MS, sendTimeout, 200U ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - if( socketHandle->socketState == SOCKETSTATE_DISCONNECTED ) - { - LogInfo( ( "Cellular_SocketSend: Data send fail, socket already closed" ) ); - cellularStatus = CELLULAR_SOCKET_CLOSED; - } - else - { - LogError( ( "Cellular_SocketSend: Data send fail, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketClose( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - CellularAtReq_t atReqSocketClose = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - uint32_t sessionId = INVALID_SESSION_ID; - cellularModuleContext_t * pModuleContext = NULL; - - atReqSocketClose.pAtCmd = cmdBuf; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_SocketClose: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( socketHandle == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else - { - if( socketHandle->socketState == SOCKETSTATE_CONNECTING ) - { - LogWarn( ( "Cellular_SocketClose: Socket state is SOCKETSTATE_CONNECTING." ) ); - } - - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - sessionId = _Cellular_GetSessionId( pContext, socketHandle->socketId ); - - if( sessionId == INVALID_SESSION_ID ) - { - LogError( ( "Cellular_SocketClose : invalid session ID for socket index %u", - socketHandle->socketId ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Remove the mapping. */ - pModuleContext->pSessionMap[ sessionId ] = INVALID_SOCKET_INDEX; - - /* Close the socket. */ - if( socketHandle->socketState == SOCKETSTATE_CONNECTED ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "%s%u,%d", - "AT+USOCL=", sessionId, CELLULAR_CONFIG_SET_SOCKET_CLOSE_ASYNC_MODE ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketClose, SOCKET_CLOSE_PACKET_REQ_TIMEOUT_MS ); - - /* Delete the socket config. */ - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogWarn( ( "Cellular_SocketClose: AT+USOCL fail, PktRet: %d", pktStatus ) ); - } - } - - /* Ignore the result from the info, and force to remove the socket. */ - cellularStatus = _Cellular_RemoveSocketData( pContext, socketHandle ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketConnect( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketAccessMode_t dataAccessMode, - const CellularSocketAddress_t * pRemoteSocketAddress ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - uint8_t sessionId = 0; - CellularAtReq_t atReqSocketConnect = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - cellularModuleContext_t * pModuleContext = NULL; - - atReqSocketConnect.pAtCmd = cmdBuf; - - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Cellular_SocketConnect: _Cellular_CheckLibraryStatus failed." ) ); - } - else if( pRemoteSocketAddress == NULL ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket address." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketHandle == NULL ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket handle." ) ); - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( socketHandle->socketProtocol != CELLULAR_SOCKET_PROTOCOL_TCP ) - { - LogError( ( "Cellular_SocketConnect: Invalid socket protocol." ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( ( socketHandle->socketState == SOCKETSTATE_CONNECTED ) || ( socketHandle->socketState == SOCKETSTATE_CONNECTING ) ) - { - LogError( ( "Cellular_SocketConnect: Not allowed in state %d.", socketHandle->socketState ) ); - cellularStatus = CELLULAR_NOT_ALLOWED; - } - else - { - cellularStatus = storeAccessModeAndAddress( pContext, socketHandle, dataAccessMode, pRemoteSocketAddress ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - /* Set socket config and get session id. The session id is defined by the modem. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Builds the Socket connect command. */ - cellularStatus = _Cellular_GetSocketNumber( pContext, socketHandle, &sessionId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Create the reverse table to store the socketIndex to sessionId. */ - pModuleContext->pSessionMap[ sessionId ] = socketHandle->socketId; - } - } - - /* Start the tcp connection. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, - "AT+USOCO=%u,\"%s\",%d,1", - sessionId, - socketHandle->remoteSocketAddress.ipAddress.ipAddress, - socketHandle->remoteSocketAddress.port ); - - /* Set the socket state to connecting state. If cellular modem returns error, - * revert the state to allocated state. */ - socketHandle->socketState = SOCKETSTATE_CONNECTING; - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqSocketConnect, - SOCKET_CONNECT_PACKET_REQ_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SocketConnect: Socket connect failed, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - /* Revert the state to allocated state. */ - socketHandle->socketState = SOCKETSTATE_ALLOCATED; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSimCardStatus( CellularHandle_t cellularHandle, - CellularSimCardStatus_t * pSimCardStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_GetSimCardStatus: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( pSimCardStatus == NULL ) - { - LogWarn( ( "Cellular_GetSimCardStatus: Bad input Parameter " ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Parameters are checked in this API. */ - pSimCardStatus->simCardState = CELLULAR_SIM_CARD_UNKNOWN; - pSimCardStatus->simCardLockState = CELLULAR_SIM_CARD_LOCK_UNKNOWN; - - cellularStatus = Cellular_CommonGetSimCardLockStatus( cellularHandle, pSimCardStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( ( pSimCardStatus->simCardLockState != CELLULAR_SIM_CARD_INVALID ) && - ( pSimCardStatus->simCardLockState != CELLULAR_SIM_CARD_LOCK_UNKNOWN ) ) - { - pSimCardStatus->simCardState = CELLULAR_SIM_CARD_INSERTED; - } - else - { - pSimCardStatus->simCardState = CELLULAR_SIM_CARD_UNKNOWN; - } - - LogInfo( ( "Cellular_GetSimCardStatus, Sim Insert State[%d], Lock State[%d]", - pSimCardStatus->simCardState, pSimCardStatus->simCardLockState ) ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_DeactivatePdn( CellularHandle_t cellularHandle, - uint8_t contextId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - bool packetSwitchStatus = false; - uint32_t i = 0; - - CellularServiceStatus_t serviceStatus = { 0 }; - CellularPdnContextActInfo_t pdpContextsActInfo = { 0 }; - - CellularAtReq_t atReqDeactPdn = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - atReqDeactPdn.pAtCmd = cmdBuf; - - cellularStatus = _Cellular_IsValidPdn( contextId ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Get current network operator settings. */ - cellularStatus = Cellular_CommonGetServiceStatus( cellularHandle, &serviceStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Check the current status of context. */ - cellularStatus = _Cellular_GetContextActivationStatus( cellularHandle, &pdpContextsActInfo ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_DeactivatePdn: Listing operator and context details below." ) ); - - for( i = 0U; i < ( MAX_PDP_CONTEXTS - 1 ); i++ ) - { - /* Print only those contexts that are present in +CGACT response */ - if( pdpContextsActInfo.contextsPresent[ i ] ) - { - LogDebug( ( "Context [%d], Act State [%d], Operator [%d]\r\n", i + 1, - pdpContextsActInfo.contextActState[ i ], serviceStatus.rat ) ); - } - } - - /* Deactivate context if active */ - if( pdpContextsActInfo.contextActState[ contextId - 1 ] == true ) - { - /* Don't deactivate LTE default bearer context */ - /* Otherwise sending AT command "+CGACT=0,1" for deactivation will result in ERROR */ - if( ( serviceStatus.rat >= CELLULAR_RAT_LTE ) && ( contextId == DEFAULT_BEARER_CONTEXT_ID ) ) - { - LogInfo( ( "Cellular_DeactivatePdn: Default Bearer context %d Active. Not allowed to deactivate.", contextId ) ); - cellularStatus = CELLULAR_NOT_ALLOWED; - } - else - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s=0,%u", "AT+CGACT", contextId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqDeactPdn, PDN_DEACT_PACKET_REQ_TIMEOUT_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - if( ( cellularStatus != CELLULAR_SUCCESS ) && ( cellularStatus != CELLULAR_NOT_ALLOWED ) ) - { - LogError( ( "Cellular_DeactivatePdn: can't deactivate PDN, PktRet: %d", pktStatus ) ); - - /* Sometimes +CGACT deactivation fails in 2G. Then check packet switch attach. If attached, detach packet switch. */ - if( ( serviceStatus.rat == CELLULAR_RAT_GSM ) || ( serviceStatus.rat == CELLULAR_RAT_EDGE ) ) - { - cellularStatus = _Cellular_GetPacketSwitchStatus( cellularHandle, &packetSwitchStatus ); - - if( ( cellularStatus == CELLULAR_SUCCESS ) && ( packetSwitchStatus == true ) ) - { - LogError( ( "Deactivate Packet switch" ) ); - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s", "AT+CGATT=0" ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqDeactPdn, GPRS_ATTACH_REQ_TIMEOUT_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - else if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Packet switch query failed" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - else - { - LogInfo( ( "Packet switch detached" ) ); - } - } - } - } - else - { - LogInfo( ( "Cellular_DeactivatePdn: Context id [%d] is already deactive", contextId ) ); - } - } - else - { - LogError( ( "Cellular_DeactivatePdn: Unable to list operator and context details." ) ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library prototype. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncPacketSwitchStatus( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - bool * pPacketSwitchStatus = ( bool * ) pData; - - if( pContext == NULL ) - { - LogError( ( "PacketSwitchStatus: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( bool ) ) ) - { - LogError( ( "GetPacketSwitchStatus: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetPacketSwitchStatus: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - - /* Remove prefix. */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* Remove leading space. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( *pInputLine == '0' ) - { - *pPacketSwitchStatus = false; - } - else if( *pInputLine == '1' ) - { - *pPacketSwitchStatus = true; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Get PDN context Activation state */ - -static CellularPktStatus_t _Cellular_RecvFuncGetPdpContextActState( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pRespLine = NULL; - CellularPdnContextActInfo_t * pPDPContextsActInfo = ( CellularPdnContextActInfo_t * ) pData; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const CellularATCommandLine_t * pCommnadItem = NULL; - uint8_t tokenIndex = 0; - uint8_t contextId = 0; - int32_t tempValue = 0; - char * pToken = NULL; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextActState: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pPDPContextsActInfo == NULL ) || ( dataLen != sizeof( CellularPdnContextActInfo_t ) ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pAtResp == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextActState: Response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextActState: no PDN context available" ) ); - pktStatus = CELLULAR_PKT_STATUS_OK; - } - else - { - pRespLine = pAtResp->pItm->pLine; - - pCommnadItem = pAtResp->pItm; - - while( pCommnadItem != NULL ) - { - pRespLine = pCommnadItem->pLine; - LogDebug( ( "_Cellular_RecvFuncGetPdpContextActState: pRespLine [%s]", pRespLine ) ); - - /* Removing all the Spaces in the AT Response. */ - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemovePrefix( &pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pRespLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pRespLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - tokenIndex = 0; - - while( ( pToken != NULL ) && ( atCoreStatus == CELLULAR_AT_SUCCESS ) ) - { - switch( tokenIndex ) - { - case ( CELLULAR_PDN_ACT_STATUS_POS_CONTEXT_ID ): - LogDebug( ( "_Cellular_RecvFuncGetPdpContextActState: Context Id pToken: %s", pToken ) ); - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MIN ) && - ( tempValue <= ( int32_t ) MAX_PDP_CONTEXTS ) ) - { - contextId = ( uint8_t ) tempValue; - pPDPContextsActInfo->contextsPresent[ contextId - 1 ] = true; - LogDebug( ( "_Cellular_RecvFuncGetPdpContextActState: Context Id: %d", contextId ) ); - } - else - { - LogError( ( "_Cellular_RecvFuncGetPdpContextActState: Invalid Context Id. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - break; - - case ( CELLULAR_PDN_ACT_STATUS_POS_CONTEXT_STATE ): - LogDebug( ( "_Cellular_RecvFuncGetPdpContextActState: Context pToken: %s", pToken ) ); - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pPDPContextsActInfo->contextActState[ contextId - 1 ] = ( bool ) tempValue; - LogDebug( ( "_Cellular_RecvFuncGetPdpContextActState: Context : %d", pPDPContextsActInfo->contextActState[ contextId - 1 ] ) ); - } - - break; - - default: - break; - } - - tokenIndex++; - - if( Cellular_ATGetNextTok( &pRespLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextActState: parse %s failed", pRespLine ) ); - break; - } - - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Check activation status of particular context. */ - -static CellularError_t _Cellular_GetContextActivationStatus( CellularHandle_t cellularHandle, - CellularPdnContextActInfo_t * pPdpContextsActInfo ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - - CellularAtReq_t atReqPacketSwitchStatus = - { - "AT+CGACT?", - CELLULAR_AT_MULTI_WITH_PREFIX, - "+CGACT", - _Cellular_RecvFuncGetPdpContextActState, - NULL, - sizeof( CellularPdnContextActInfo_t ), - }; - - atReqPacketSwitchStatus.pData = pPdpContextsActInfo; - - /* Internal function. Callee check parameters. */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqPacketSwitchStatus ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t _Cellular_GetPacketSwitchStatus( CellularHandle_t cellularHandle, - bool * pPacketSwitchStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqPacketSwitchStatus = - { - "AT+CGATT?", - CELLULAR_AT_WITH_PREFIX, - "+CGATT", - _Cellular_RecvFuncPacketSwitchStatus, - NULL, - sizeof( bool ), - }; - - atReqPacketSwitchStatus.pData = pPacketSwitchStatus; - - /* Internal function. Callee check parameters. */ - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqPacketSwitchStatus, PDN_ACT_PACKET_REQ_TIMEOUT_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ActivatePdn( CellularHandle_t cellularHandle, - uint8_t contextId ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - uint32_t i = 0; - - CellularPdnContextActInfo_t pdpContextsActInfo = { 0 }; - - CellularAtReq_t atReqActPdn = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_IsValidPdn( contextId ); - - atReqActPdn.pAtCmd = cmdBuf; - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Check the current status of context. If not activated, activate the PDN context ID. */ - cellularStatus = _Cellular_GetContextActivationStatus( cellularHandle, &pdpContextsActInfo ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_ActivatePdn: Listing operator and context details below." ) ); - - for( i = 0U; i < ( MAX_PDP_CONTEXTS - 1 ); i++ ) - { - /* Print only those contexts that are present in +CGACT response */ - if( pdpContextsActInfo.contextsPresent[ i ] ) - { - LogDebug( ( "Cellular_ActivatePdn: Context [%d], Act State [%d]\r\n", i + 1, - pdpContextsActInfo.contextActState[ i ] ) ); - } - } - } - - /* Activate context if not already active */ - if( pdpContextsActInfo.contextActState[ contextId - 1 ] == false ) - { - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s=1,%u", "AT+CGACT", contextId ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqActPdn, PDN_ACT_PACKET_REQ_TIMEOUT_MS ); - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_ActivatePdn: can't activate PDN, PktRet: %d", pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - else - { - LogInfo( ( "Cellular_ActivatePdn: Context id [%d] is already active", contextId ) ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -CellularError_t Cellular_GetPdnStatus( CellularHandle_t cellularHandle, - CellularPdnStatus_t * pPdnStatusBuffers, - uint8_t numStatusBuffers, - uint8_t * pNumStatus ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint8_t i = 0; - - CellularPdnContextActInfo_t pdpContextsActInfo = { 0 }; - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( ( pPdnStatusBuffers == NULL ) || ( pNumStatus == NULL ) || ( numStatusBuffers < 1u ) ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - LogWarn( ( "_Cellular_GetPdnStatus: Bad input Parameter " ) ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - *pNumStatus = 0U; - - /* Check the current status of contexts. */ - cellularStatus = _Cellular_GetContextActivationStatus( cellularHandle, &pdpContextsActInfo ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_GetPdnStatus: Listing operator and context details below." ) ); - - for( i = 0U; i < ( MAX_PDP_CONTEXTS - 1 ); i++ ) - { - /* Print only those contexts that are present in +CGACT response. */ - if( pdpContextsActInfo.contextsPresent[ i ] ) - { - LogDebug( ( "Context [%d], Act State [%d]\r\n", i + 1, pdpContextsActInfo.contextActState[ i ] ) ); - - if( *pNumStatus < numStatusBuffers ) - { - pPdnStatusBuffers[ *pNumStatus ].contextId = i + 1U; - pPdnStatusBuffers[ *pNumStatus ].state = pdpContextsActInfo.contextActState[ i ]; - *pNumStatus = *pNumStatus + 1U; - } - } - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetRatPriority( CellularHandle_t cellularHandle, - const CellularRat_t * pRatPriorities, - uint8_t ratPrioritiesLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - uint8_t i = 0; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - - CellularAtReq_t atReqSetRatPriority = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - atReqSetRatPriority.pAtCmd = cmdBuf; - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_SetRatPriority: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pRatPriorities == NULL ) || ( ratPrioritiesLength == 0U ) || - ( ratPrioritiesLength > ( uint8_t ) CELLULAR_MAX_RAT_PRIORITY_COUNT ) ) - { - LogWarn( ( "Cellular_SetRatPriority: Bad input Parameter " ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* In case of +UMNOPROF=0, AT+URAT set commad is not allowed */ - if( CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE != 0 ) - { - ( void ) strcpy( cmdBuf, "AT+CFUN=4;+URAT=" ); - - while( i < ratPrioritiesLength ) - { - if( ( pRatPriorities[ i ] == CELLULAR_RAT_GSM ) || ( pRatPriorities[ i ] == CELLULAR_RAT_EDGE ) ) - { - ( void ) strcat( cmdBuf, "9" ); - } - else if( pRatPriorities[ i ] == CELLULAR_RAT_CATM1 ) - { - ( void ) strcat( cmdBuf, "7" ); - } - else if( pRatPriorities[ i ] == CELLULAR_RAT_NBIOT ) - { - ( void ) strcat( cmdBuf, "8" ); - } - else - { - cellularStatus = CELLULAR_BAD_PARAMETER; - break; - } - - i++; - - if( i < ratPrioritiesLength ) - { - ( void ) strcat( cmdBuf, "," ); - } - } - - ( void ) strcat( cmdBuf, ";+CFUN=1" ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetRatPriority ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - else - { - LogDebug( ( "Cellular_SetRatPriority: Automatic selection as UMNOPROF profile is 0" ) ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Get modem RAT priority setting. */ -/* coverity[misra_c_2012_rule_8_13_violation] */ -static CellularPktStatus_t _Cellular_RecvFuncGetRatPriority( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularRat_t * pRatPriorities = NULL; - uint8_t ratIndex = 0; - uint32_t maxRatPriorityLength = ( dataLen > RAT_PRIOIRTY_LIST_LENGTH ? RAT_PRIOIRTY_LIST_LENGTH : dataLen ); - - if( pContext == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetRatPriority: Invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || - ( pAtResp->pItm->pLine == NULL ) || ( pData == NULL ) || ( dataLen == 0U ) ) - { - LogError( ( "_Cellular_RecvFuncGetRatPriority: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pInputLine = pAtResp->pItm->pLine; - pRatPriorities = ( CellularRat_t * ) pData; - - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - memset( pRatPriorities, CELLULAR_RAT_INVALID, dataLen ); - - /* pInputLine : 7,8,9. */ - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - while( pToken != NULL && ratIndex < maxRatPriorityLength ) - { - LogDebug( ( "_Cellular_RecvFuncGetRatPriority: pToken [%s]", pToken ) ); - - if( strcmp( pToken, "7" ) == 0 ) - { - pRatPriorities[ ratIndex ] = CELLULAR_RAT_CATM1; - LogDebug( ( "_Cellular_RecvFuncGetRatPriority: CELLULAR_RAT_CATM1" ) ); - } - else if( strcmp( pToken, "8" ) == 0 ) - { - pRatPriorities[ ratIndex ] = CELLULAR_RAT_NBIOT; - LogDebug( ( "_Cellular_RecvFuncGetRatPriority: CELLULAR_RAT_NBIOT" ) ); - } - else if( strcmp( pToken, "9" ) == 0 ) - { - pRatPriorities[ ratIndex ] = CELLULAR_RAT_GSM; /* or CELLULAR_RAT_EDGE */ - LogDebug( ( "_Cellular_RecvFuncGetRatPriority: CELLULAR_RAT_GSM" ) ); - } - else - { - LogDebug( ( "_Cellular_RecvFuncGetRatPriority: Invalid RAT string [%s]", pToken ) ); - } - - ratIndex++; - - if( Cellular_ATGetNextTok( &pInputLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetRatPriority( CellularHandle_t cellularHandle, - CellularRat_t * pRatPriorities, - uint8_t ratPrioritiesLength, - uint8_t * pReceiveRatPrioritesLength ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint8_t ratIndex = 0; - - CellularAtReq_t atReqSetRatPriority = - { - "AT+URAT?", - CELLULAR_AT_WITH_PREFIX, - "+URAT", - _Cellular_RecvFuncGetRatPriority, - NULL, - 0U, - }; - - atReqSetRatPriority.pData = pRatPriorities; - atReqSetRatPriority.dataLen = ( uint16_t ) ratPrioritiesLength; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_GetRatPriority: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pRatPriorities == NULL ) || ( ratPrioritiesLength == 0U ) || - ( ratPrioritiesLength > ( uint8_t ) CELLULAR_MAX_RAT_PRIORITY_COUNT ) || - ( pReceiveRatPrioritesLength == NULL ) ) - { - LogWarn( ( "Cellular_GetRatPriority: Bad input Parameter " ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* In case of +UMNOPROF=0, AT+URAT? read commad is not allowed */ - if( CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE != 0 ) - { - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetRatPriority ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - for( ratIndex = 0; ratIndex < ratPrioritiesLength; ratIndex++ ) - { - if( pRatPriorities[ ratIndex ] == CELLULAR_RAT_INVALID ) - { - break; - } - } - - *pReceiveRatPrioritesLength = ratIndex; - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - else - { - LogDebug( ( "Cellular_GetRatPriority: Automatic selection as UMNOPROF profile is 0" ) ); - - pRatPriorities[ ratIndex++ ] = CELLULAR_RAT_CATM1; - pRatPriorities[ ratIndex++ ] = CELLULAR_RAT_NBIOT; - pRatPriorities[ ratIndex++ ] = CELLULAR_RAT_GSM; - *pReceiveRatPrioritesLength = RAT_PRIOIRTY_LIST_LENGTH; - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static bool _parseExtendedSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ) -{ - char * pToken = NULL, * pTmpQcsqPayload = pQcsqPayload; - int32_t tempValue = 0; - bool parseStatus = true; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( ( pSignalInfo == NULL ) || ( pQcsqPayload == NULL ) ) - { - LogError( ( "_parseExtendedSignalQuality: Invalid Input Parameters" ) ); - parseStatus = false; - } - - /* +CESQ: ,,,,,. */ - - /* Skip . */ - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - - /* Parse . */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( ( atCoreStatus == CELLULAR_AT_SUCCESS ) && ( tempValue <= INT16_MAX ) && ( tempValue >= INT16_MIN ) ) - { - /* - * Bit Error Rate (BER): - * 0..7: as RXQUAL values in the table in 3GPP TS 45.008 [124], subclause 8.2.4 - * 99: not known or not detectable - */ - if( ( tempValue >= 0 ) && ( tempValue <= 7 ) ) - { - pSignalInfo->ber = ( int16_t ) tempValue; - } - else - { - pSignalInfo->ber = CELLULAR_INVALID_SIGNAL_VALUE; - } - } - else - { - LogError( ( "_parseExtendedSignalQuality: Error in processing BER. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - /* Skip . */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - /* Skip . */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - /* Parse . */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* - * Reference Signal Received Quality (RSRQ): - * 0: less than -19.5 dB - * 1..33: from -19.5 dB to -3.5 dB with 0.5 dB steps - * 34: -3 dB or greater - * 255: not known or not detectable - */ - if( ( tempValue >= 0 ) && ( tempValue <= 34 ) ) - { - pSignalInfo->rsrq = ( int16_t ) ( ( -20 ) + ( tempValue * 0.5 ) ); - } - else - { - pSignalInfo->rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - } - } - else - { - LogError( ( "_parseExtendedSignalQuality: Error in processing RSRP. Token %s", pToken ) ); - parseStatus = false; - } - } - - /* Parse . */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* - * Reference Signal Received Power(RSRP) : - * 0 : less than - 140 dBm - * 1..96 : from - 140 dBm to - 45 dBm with 1 dBm steps - * 97 : -44 dBm or greater - * 255 : not known or not detectable - */ - if( ( tempValue >= 0 ) && ( tempValue <= 97 ) ) - { - pSignalInfo->rsrp = ( int16_t ) ( ( -141 ) + ( tempValue ) ); - } - else - { - pSignalInfo->rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - } - } - else - { - LogError( ( "_parseExtendedSignalQuality: Error in processing RSRP. Token %s", pToken ) ); - parseStatus = false; - } - } - - return parseStatus; -} - -/*-----------------------------------------------------------*/ - -static bool _parseSignalQuality( char * pQcsqPayload, - CellularSignalInfo_t * pSignalInfo ) -{ - char * pToken = NULL, * pTmpQcsqPayload = pQcsqPayload; - int32_t tempValue = 0; - bool parseStatus = true; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - - if( ( pSignalInfo == NULL ) || ( pQcsqPayload == NULL ) ) - { - LogError( ( "_parseSignalQuality: Invalid Input Parameters" ) ); - parseStatus = false; - } - - /* +CSQ: ,. */ - - /* Parse . */ - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* - * The allowed range is 0-31 and 99. - * 0 RSSI of the network <= -113 dBm - * 1 -111 dBm - * 2...30 -109 dBm <= RSSI of the network <= -53 dBm - * 31 -51 dBm <= RSSI of the network - * 99 Not known or not detectable - */ - if( ( tempValue >= 0 ) && ( tempValue <= 31 ) ) - { - pSignalInfo->rssi = ( int16_t ) ( ( -113 ) + ( tempValue * 2 ) ); - } - else if( tempValue == 99 ) - { - pSignalInfo->rssi = -113; - } - else - { - pSignalInfo->rssi = CELLULAR_INVALID_SIGNAL_VALUE; - } - } - else - { - LogError( ( "_parseSignalQuality: Error in processing RSSI. Token %s", pToken ) ); - parseStatus = false; - } - } - - /* Parse . */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pTmpQcsqPayload, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* - * The allowed range is 0-7 and 99 : - * In 2G RAT CS dedicated and GPRS packet transfer mode indicates the Bit Error Rate (BER) as specified in 3GPP TS 45.008 - */ - if( ( tempValue >= 0 ) && ( tempValue <= 7 ) ) - { - pSignalInfo->ber = ( int16_t ) tempValue; - } - else - { - pSignalInfo->ber = CELLULAR_INVALID_SIGNAL_VALUE; - } - } - else - { - LogError( ( "_parseSignalQuality: Error in processing ber. Token %s", pToken ) ); - parseStatus = false; - } - } - - return parseStatus; -} - -/*-----------------------------------------------------------*/ - -/* parse signal strength response */ - -static CellularPktStatus_t _Cellular_RecvFuncGetSignalInfo( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularSignalInfo_t * pSignalInfo = ( CellularSignalInfo_t * ) pData; - bool parseStatus = true; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - bool isExtendedResponse = false; - - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pSignalInfo == NULL ) || ( dataLen != sizeof( CellularSignalInfo_t ) ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "GetSignalInfo: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - - if( strstr( pInputLine, "+CESQ" ) ) - { - LogDebug( ( "GetSignalInfo: ExtendedResponse received." ) ); - isExtendedResponse = true; - } - - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pInputLine ); - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - if( isExtendedResponse ) - { - parseStatus = _parseExtendedSignalQuality( pInputLine, pSignalInfo ); - } - else - { - parseStatus = _parseSignalQuality( pInputLine, pSignalInfo ); - } - - if( parseStatus != true ) - { - pSignalInfo->rssi = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->ber = CELLULAR_INVALID_SIGNAL_VALUE; - pSignalInfo->bars = CELLULAR_INVALID_SIGNAL_BAR_VALUE; - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -CellularError_t Cellular_GetSignalInfo( CellularHandle_t cellularHandle, - CellularSignalInfo_t * pSignalInfo ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularRat_t rat = CELLULAR_RAT_INVALID; - CellularAtReq_t atReqQuerySignalInfo = - { - "AT+CSQ", - CELLULAR_AT_WITH_PREFIX, - "+CSQ", - _Cellular_RecvFuncGetSignalInfo, - NULL, - sizeof( CellularSignalInfo_t ), - }; - CellularAtReq_t atReqQueryExtendedSignalInfo = - { - "AT+CESQ", - CELLULAR_AT_WITH_PREFIX, - "+CESQ", - _Cellular_RecvFuncGetSignalInfo, - NULL, - sizeof( CellularSignalInfo_t ), - }; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - atReqQuerySignalInfo.pData = pSignalInfo; - atReqQueryExtendedSignalInfo.pData = pSignalInfo; - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_GetSignalInfo: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( pSignalInfo == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetCurrentRat( pContext, &rat ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Get +CSQ response */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqQuerySignalInfo ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - /* Get +CESQ response */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqQueryExtendedSignalInfo ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - /* If the convert failed, the API will return CELLULAR_INVALID_SIGNAL_BAR_VALUE in bars field. */ - ( void ) _Cellular_ComputeSignalBars( rat, pSignalInfo ); - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetDns( CellularHandle_t cellularHandle, - uint8_t contextId, - const char * pDnsServerAddress ) -{ - /* Modem use dynamic DNS addresses. Return unsupported. */ - ( void ) cellularHandle; - ( void ) contextId; - ( void ) pDnsServerAddress; - return CELLULAR_UNSUPPORTED; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t controlSignalStrengthIndication( CellularContext_t * pContext, - bool enable ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ] = { '\0' }; - uint8_t enable_value = 0; - CellularAtReq_t atReqControlSignalStrengthIndication = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - atReqControlSignalStrengthIndication.pAtCmd = cmdBuf; - - if( enable == true ) - { - enable_value = 1; - } - else - { - enable_value = 0; - } - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( enable_value ) - { - /* Enable signal level change indication via +CIEV URC.*/ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "AT+UCIND=2" ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqControlSignalStrengthIndication ); - } - else - { - /* Disable signal level change indication via +CIEV URC.*/ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_TYPICAL_MAX_SIZE, "AT+UCIND=0" ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqControlSignalStrengthIndication ); - } - - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcSignalStrengthChangedCallback( CellularHandle_t cellularHandle, - CellularUrcSignalStrengthChangedCallback_t signalStrengthChangedCallback, - void * pCallbackContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - - /* pContext is checked in the common library. */ - cellularStatus = Cellular_CommonRegisterUrcSignalStrengthChangedCallback( - cellularHandle, signalStrengthChangedCallback, pCallbackContext ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( signalStrengthChangedCallback != NULL ) - { - cellularStatus = controlSignalStrengthIndication( pContext, true ); - } - else - { - cellularStatus = controlSignalStrengthIndication( pContext, false ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Resolve Domain name to IP address */ - -static CellularPktStatus_t _Cellular_RecvFuncResolveDomainToIpAddress( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pRespLine = NULL; - char * pResolvedIpAddress = ( char * ) pData; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const CellularATCommandLine_t * pCommnadItem = NULL; - char * pToken = NULL; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_RecvFuncResolveDomainToIpAddress: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pResolvedIpAddress == NULL ) || ( dataLen != CELLULAR_IP_ADDRESS_MAX_SIZE ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pAtResp == NULL ) - { - LogError( ( "_Cellular_RecvFuncResolveDomainToIpAddress: Response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "_Cellular_RecvFuncResolveDomainToIpAddress: Address not resolved" ) ); - pktStatus = CELLULAR_PKT_STATUS_OK; - } - else - { - pRespLine = pAtResp->pItm->pLine; - - pCommnadItem = pAtResp->pItm; - - while( pCommnadItem != NULL ) - { - pRespLine = pCommnadItem->pLine; - LogDebug( ( "_Cellular_RecvFuncResolveDomainToIpAddress: pRespLine [%s]", pRespLine ) ); - - /* Removing all the Spaces in the AT Response. */ - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemovePrefix( &pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pRespLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pRespLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - ( void ) strncpy( pResolvedIpAddress, pToken, dataLen ); - - LogDebug( ( "_Cellular_RecvFuncResolveDomainToIpAddress: Resolved IP Address: [%s]", pResolvedIpAddress ) ); - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "_Cellular_RecvFuncResolveDomainToIpAddress: parse %s failed", pRespLine ) ); - break; - } - - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - - - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetHostByName( CellularHandle_t cellularHandle, - uint8_t contextId, - const char * pcHostName, - char * pResolvedAddress ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - - CellularAtReq_t atReqQueryDns = - { - NULL, - CELLULAR_AT_MULTI_WITH_PREFIX, - "+UDNSRN", - _Cellular_RecvFuncResolveDomainToIpAddress, - NULL, - CELLULAR_IP_ADDRESS_MAX_SIZE, - }; - - ( void ) contextId; - - /* pContext is checked in _Cellular_CheckLibraryStatus function. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - atReqQueryDns.pAtCmd = cmdBuf; - atReqQueryDns.pData = pResolvedAddress; - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_GetHostByName: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( ( pcHostName == NULL ) || ( pResolvedAddress == NULL ) ) - { - LogError( ( "Cellular_GetHostByName: Bad input Parameter " ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, - "AT+UDNSRN=0,\"%s\"", pcHostName ); - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqQueryDns, DNS_QUERY_REQ_TIMEOUT_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_GetHostByName: couldn't resolve host name" ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Get PDN context APN name*/ - -static CellularPktStatus_t _Cellular_RecvFuncGetPdpContextSettings( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pRespLine = NULL; - CellularPdnContextInfo_t * pPDPContextsInfo = ( CellularPdnContextInfo_t * ) pData; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - const CellularATCommandLine_t * pCommnadItem = NULL; - uint8_t tokenIndex = 0; - uint8_t contextId = 0; - int32_t tempValue = 0; - char * pToken = NULL; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextSettings: invalid context" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pPDPContextsInfo == NULL ) || ( dataLen != sizeof( CellularPdnContextInfo_t ) ) ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pAtResp == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextSettings: Response is invalid" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextSettings: no PDN context available" ) ); - pktStatus = CELLULAR_PKT_STATUS_OK; - } - else - { - pRespLine = pAtResp->pItm->pLine; - - pCommnadItem = pAtResp->pItm; - - while( pCommnadItem != NULL ) - { - pRespLine = pCommnadItem->pLine; - LogDebug( ( "_Cellular_RecvFuncGetPdpContextSettings: pRespLine [%s]", pRespLine ) ); - - /* Removing all the Spaces in the AT Response. */ - atCoreStatus = Cellular_ATRemoveAllWhiteSpaces( pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemovePrefix( &pRespLine ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pRespLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pRespLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - tokenIndex = 0; - - while( ( pToken != NULL ) && ( atCoreStatus == CELLULAR_AT_SUCCESS ) ) - { - switch( tokenIndex ) - { - case ( CELLULAR_PDN_STATUS_POS_CONTEXT_ID ): - LogDebug( ( "_Cellular_RecvFuncGetPdpContextSettings: Context Id pToken: %s", pToken ) ); - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( int32_t ) CELLULAR_PDN_CONTEXT_ID_MIN ) && - ( tempValue <= ( int32_t ) MAX_PDP_CONTEXTS ) ) - { - contextId = ( uint8_t ) tempValue; - pPDPContextsInfo->contextsPresent[ contextId - 1 ] = true; - LogDebug( ( "_Cellular_RecvFuncGetPdpContextSettings: Context Id: %d", contextId ) ); - } - else - { - LogError( ( "_Cellular_RecvFuncGetPdpContextSettings: Invalid Context Id. Token %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - break; - - case ( CELLULAR_PDN_STATUS_POS_CONTEXT_TYPE ): - LogDebug( ( "_Cellular_RecvFuncGetPdpContextSettings: Context Type pToken: %s", pToken ) ); - - ( void ) memcpy( ( void * ) pPDPContextsInfo->ipType[ contextId - 1 ], - ( void * ) pToken, CELULAR_PDN_CONTEXT_TYPE_MAX_SIZE + 1U ); - break; - - case ( CELLULAR_PDN_STATUS_POS_APN_NAME ): - LogDebug( ( "_Cellular_RecvFuncGetPdpContextSettings: Context APN name pToken: %s", pToken ) ); - - ( void ) memcpy( ( void * ) pPDPContextsInfo->apnName[ contextId - 1 ], - ( void * ) pToken, CELLULAR_APN_MAX_SIZE + 1U ); - break; - - case ( CELLULAR_PDN_STATUS_POS_IP_ADDRESS ): - LogDebug( ( "_Cellular_RecvFuncGetPdpContextSettings: Context IP address pToken: %s", pToken ) ); - - ( void ) memcpy( ( void * ) pPDPContextsInfo->ipAddress[ contextId - 1 ], - ( void * ) pToken, CELLULAR_IP_ADDRESS_MAX_SIZE + 1U ); - break; - - default: - break; - } - - tokenIndex++; - - if( Cellular_ATGetNextTok( &pRespLine, &pToken ) != CELLULAR_AT_SUCCESS ) - { - break; - } - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "_Cellular_RecvFuncGetPdpContextSettings: parse %s failed", pRespLine ) ); - break; - } - - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Set PDN APN name and Authentication setting */ - -CellularError_t Cellular_SetPdnConfig( CellularHandle_t cellularHandle, - uint8_t contextId, - const CellularPdnConfig_t * pPdnConfig ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - char pPdpTypeStr[ CELULAR_PDN_CONTEXT_TYPE_MAX_SIZE ] = { '\0' }; - uint32_t i = 0; - - CellularPdnContextInfo_t pdpContextsInfo = { 0 }; - CellularPdnContextInfo_t * pPdpContextsInfo = &pdpContextsInfo; - - CellularAtReq_t atReqSetPdn = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0, - }; - - atReqSetPdn.pAtCmd = cmdBuf; - - if( pPdnConfig == NULL ) - { - LogDebug( ( "Cellular_SetPdnConfig: Input parameter is NULL" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - switch( pPdnConfig->pdnContextType ) - { - case CELLULAR_PDN_CONTEXT_IPV4: - ( void ) strncpy( pPdpTypeStr, "IP", 3U ); /* 3U is the length of "IP" + '\0'. */ - break; - - case CELLULAR_PDN_CONTEXT_IPV6: - ( void ) strncpy( pPdpTypeStr, "IPV6", 5U ); /* 5U is the length of "IPV6" + '\0'. */ - break; - - case CELLULAR_PDN_CONTEXT_IPV4V6: - ( void ) strncpy( pPdpTypeStr, "IPV4V6", 7U ); /* 7U is the length of "IPV4V6" + '\0'. */ - break; - - default: - LogDebug( ( "Cellular_SetPdnConfig: Invalid pdn context type %d", - CELLULAR_PDN_CONTEXT_IPV4V6 ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - break; - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = _Cellular_IsValidPdn( contextId ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Make sure the library is open. */ - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Check current APN name and IP type of contextId first to avoid unneccessary network de-registration. */ - /* TODO: This implementation currently assumes only one context in list. Need to add complete contexts list parsing */ - - CellularAtReq_t atReqGetCurrentApnName = - { - "AT+CGDCONT?", - CELLULAR_AT_MULTI_WITH_PREFIX, - "+CGDCONT", - _Cellular_RecvFuncGetPdpContextSettings, - NULL, - sizeof( CellularPdnContextInfo_t ), - }; - atReqGetCurrentApnName.pData = pPdpContextsInfo; - - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetCurrentApnName ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - LogDebug( ( "Cellular_SetPdnConfig: Listing operator and context details below." ) ); - - for( i = 0U; i < ( MAX_PDP_CONTEXTS - 1 ); i++ ) - { - /* Print only those contexts that are present in +CGDCONT response */ - if( pdpContextsInfo.contextsPresent[ i ] ) - { - LogDebug( ( "Context [%d], IP Type [%s], APN Name [%s], IP Address [%s]\r\n", i + 1, - pdpContextsInfo.ipType[ i ], ( char * ) pdpContextsInfo.apnName, - ( char * ) pdpContextsInfo.ipAddress ) ); - } - } - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Form the AT command. */ - - /* The return value of snprintf is not used. - * The max length of the string is fixed and checked offline. */ - /* coverity[misra_c_2012_rule_21_6_violation]. */ - - if( ( strstr( pdpContextsInfo.apnName[ contextId - 1 ], pPdnConfig->apnName ) == NULL ) || ( strcmp( pdpContextsInfo.ipType[ contextId - 1 ], pPdpTypeStr ) != 0 ) ) - { - if( strcmp( pdpContextsInfo.ipType[ contextId - 1 ], pPdpTypeStr ) != 0 ) - { - LogInfo( ( "Cellular_SetPdnConfig: Setting new IPv (Module IPv:%s != %s)\r\n", pdpContextsInfo.ipType[ contextId - 1 ], pPdpTypeStr ) ); - } - - if( strstr( pdpContextsInfo.apnName[ contextId - 1 ], pPdnConfig->apnName ) == NULL ) - { - LogInfo( ( "Cellular_SetPdnConfig: Setting new APN (Module APN:%s != %s)\r\n", pdpContextsInfo.apnName[ contextId - 1 ], pPdnConfig->apnName ) ); - } - - /* TODO: Add support if + UAUTHREQ is PAP / CHAP */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "%s%d,\"%s\",\"%s\",,0,0;%s%d,%d%s", /*,\"%s\",\"%s\" TODO: add if +UAUTHREQ is PAP/CHAP */ - "AT+COPS=2;+CGDCONT=", - contextId, - pPdpTypeStr, - pPdnConfig->apnName, - "+UAUTHREQ=", - contextId, - pPdnConfig->pdnAuthType, - ";+COPS=0" ); - /*pPdnConfig->username, */ - /*pPdnConfig->password); */ - - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetPdn ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "Cellular_SetPdnConfig: can't set PDN, cmdBuf:%s, PktRet: %d", cmdBuf, pktStatus ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - else - { - LogInfo( ( "Cellular_SetPdnConfig: APN and IPv already set.\r\n" ) ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetPsmSettings( CellularHandle_t cellularHandle, - const CellularPsmSettings_t * pPsmSettings ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - - CellularAtReq_t atReqSetPsm = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqSetPsm.pAtCmd = cmdBuf; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Cellular_SetPsmSettings: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( pPsmSettings == NULL ) - { - LogError( ( "Cellular_SetPsmSettings : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - if( pPsmSettings->mode == 1 ) - { - /* - * SARA-R4: To change the command setting issue AT+COPS=2 or AT+CFUN=0 to deregister the module from - * network, issue the +CPSMS command and reboot the module in order to apply the new configuration. */ - /* After PSM mode active, press "PWR_ON" key to awake modem or T3412 timer is expired. */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "AT+CFUN=0" ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetPsm ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - cellularStatus = Cellular_CommonSetPsmSettings( cellularHandle, pPsmSettings ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = rebootCellularModem( pContext, false, true ); - } - else - { - LogError( ( "Cellular_SetPsmSettings: Unable to set PSM settings." ) ); - } - } - } - else - { - cellularStatus = Cellular_CommonSetPsmSettings( cellularHandle, pPsmSettings ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t _Cellular_isSockOptSupport( CellularSocketOptionLevel_t optionLevel, - CellularSocketOption_t option ) -{ - CellularError_t err = CELLULAR_UNSUPPORTED; - - if( ( optionLevel == CELLULAR_SOCKET_OPTION_LEVEL_TRANSPORT ) && - ( ( option == CELLULAR_SOCKET_OPTION_SEND_TIMEOUT ) || - ( option == CELLULAR_SOCKET_OPTION_RECV_TIMEOUT ) || - ( option == CELLULAR_SOCKET_OPTION_PDN_CONTEXT_ID ) ) ) - { - err = CELLULAR_SUCCESS; - } - else - { - LogWarn( ( "Cellular_SocketSetSockOpt: Option [Level:option=%d:%d] not supported in SARA R4", - optionLevel, option ) ); - } - - return err; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SetEidrxSettings( CellularHandle_t cellularHandle, - const CellularEidrxSettings_t * pEidrxSettings ) -{ - CellularContext_t * pContext = ( CellularContext_t * ) cellularHandle; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - char cmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { '\0' }; - - CellularAtReq_t atReqSetEidrx = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqSetEidrx.pAtCmd = cmdBuf; - - cellularStatus = _Cellular_CheckLibraryStatus( pContext ); - - if( cellularStatus != CELLULAR_SUCCESS ) - { - LogError( ( "Cellular_SetEidrxSettings: _Cellular_CheckLibraryStatus failed" ) ); - } - else if( pEidrxSettings == NULL ) - { - LogError( ( "Cellular_SetEidrxSettings : Bad parameter" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - if( ( pEidrxSettings->mode == 1 ) || ( pEidrxSettings->mode == 2 ) ) - { - /* - * SARA-R4: To change the command setting issue AT+COPS=2 or AT+CFUN=0 to deregister the module from - * network, issue the +CEDRXS command and reboot the module in order to apply the new configuration. - */ - ( void ) snprintf( cmdBuf, CELLULAR_AT_CMD_MAX_SIZE, "AT+CFUN=0" ); - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqSetEidrx ); - - if( pktStatus == CELLULAR_PKT_STATUS_OK ) - { - cellularStatus = Cellular_CommonSetEidrxSettings( cellularHandle, pEidrxSettings ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = rebootCellularModem( pContext, true, false ); - } - else - { - LogError( ( "Cellular_SetEidrxSettings: Unable to set Eidrx settings." ) ); - } - } - } - else - { - cellularStatus = Cellular_CommonSetEidrxSettings( cellularHandle, pEidrxSettings ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -CellularError_t Cellular_Init( CellularHandle_t * pCellularHandle, - const CellularCommInterface_t * pCommInterface ) -{ - CellularTokenTable_t cellularTokenTable = { 0 }; - - cellularTokenTable.pCellularUrcHandlerTable = CellularUrcHandlerTable; - cellularTokenTable.cellularPrefixToParserMapSize = CellularUrcHandlerTableSize; - cellularTokenTable.pCellularSrcTokenErrorTable = CellularSrcTokenErrorTable; - cellularTokenTable.cellularSrcTokenErrorTableSize = CellularSrcTokenErrorTableSize; - cellularTokenTable.pCellularSrcTokenSuccessTable = CellularSrcTokenSuccessTable; - cellularTokenTable.cellularSrcTokenSuccessTableSize = CellularSrcTokenSuccessTableSize; - cellularTokenTable.pCellularUrcTokenWoPrefixTable = CellularUrcTokenWoPrefixTable; - cellularTokenTable.cellularUrcTokenWoPrefixTableSize = CellularUrcTokenWoPrefixTableSize; - cellularTokenTable.pCellularSrcExtraTokenSuccessTable = NULL; - cellularTokenTable.cellularSrcExtraTokenSuccessTableSize = 0; - - return Cellular_CommonInit( pCellularHandle, pCommInterface, &cellularTokenTable ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -CellularError_t Cellular_SocketSetSockOpt( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketOptionLevel_t optionLevel, - CellularSocketOption_t option, - const uint8_t * pOptionValue, - uint32_t optionValueLength ) -{ - CellularError_t err = CELLULAR_SUCCESS; - - err = _Cellular_isSockOptSupport( optionLevel, option ); - - if( err == CELLULAR_SUCCESS ) - { - err = Cellular_CommonSocketSetSockOpt( cellularHandle, socketHandle, optionLevel, option, - pOptionValue, optionValueLength ); - } - - return err; -} - -/*-----------------------------------------------------------*/ diff --git a/modules/sara_r4/cellular_r4_urc_handler.c b/modules/sara_r4/cellular_r4_urc_handler.c deleted file mode 100644 index f326b9ca..00000000 --- a/modules/sara_r4/cellular_r4_urc_handler.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include -#include - -#include "cellular_platform.h" -#include "cellular_types.h" -#include "cellular_common.h" -#include "cellular_common_api.h" -#include "cellular_common_portable.h" - -/* Cellular module includes. */ -#include "cellular_r4.h" - -/*-----------------------------------------------------------*/ - -/* +UUPSMR URC */ -#define PSM_MODE_EXIT ( 0U ) -#define PSM_MODE_ENTER ( 1U ) -#define PSM_MODE_PREVENT_ENTRY ( 2U ) -#define PSM_MODE_PREVENT_DEEP_ENTRY ( 3U ) - -/* +CIEV URC */ -#define CIEV_POS_MIN ( 1U ) -#define CIEV_POS_SIGNAL ( 2U ) -#define CIEV_POS_SERVICE ( 3U ) -#define CIEV_POS_CALL ( 6U ) -#define CIEV_POS_MAX ( 12U ) - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessUusoco( CellularContext_t * pContext, - char * pInputLine ); -static void _cellular_UrcProcessUusord( CellularContext_t * pContext, - char * pInputLine ); -static void _cellular_UrcProcessUusocl( CellularContext_t * pContext, - char * pInputLine ); - -static void _cellular_UrcProcessUupsmr( CellularContext_t * pContext, - char * pInputLine ); -static void _cellular_UrcProcessCiev( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_ProcessModemRdy( CellularContext_t * pContext, - char * pInputLine ); -static CellularPktStatus_t _parseUrcIndicationCsq( CellularContext_t * pContext, - char * pUrcStr ); -static void _Cellular_UrcProcessCereg( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_UrcProcessCgreg( CellularContext_t * pContext, - char * pInputLine ); -static void _Cellular_UrcProcessCreg( CellularContext_t * pContext, - char * pInputLine ); - -/*-----------------------------------------------------------*/ - -/* Try to Keep this map in Alphabetical order. */ -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularAtParseTokenMap_t CellularUrcHandlerTable[] = -{ - { "CEREG", _Cellular_UrcProcessCereg }, - { "CGREG", _Cellular_UrcProcessCgreg }, - /*{ "CGEV", _cellular_UrcProcessCgev }, / * TODO: PS event reporting URC. * / */ - { "CIEV", _cellular_UrcProcessCiev }, /* PS ACT/DEACT and Signal strength status change indication URC. */ - { "CREG", _Cellular_UrcProcessCreg }, - { "RDY", _Cellular_ProcessModemRdy }, /* Modem bootup indication. */ - { "UUPSMR", _cellular_UrcProcessUupsmr }, /* Power saving mode indication URC. */ - { "UUSOCL", _cellular_UrcProcessUusocl }, /* Socket close URC. */ - { "UUSOCO", _cellular_UrcProcessUusoco }, /* Socket connect URC. */ - { "UUSORD", _cellular_UrcProcessUusord } /* Socket receive URC. */ -}; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcHandlerTableSize = sizeof( CellularUrcHandlerTable ) / sizeof( CellularAtParseTokenMap_t ); - -/*-----------------------------------------------------------*/ - -/* Parse PS ACT/DEACT from +CIEV URC indication. */ -/* This URC does not tell which context ID number is ACT/DEACT. */ - -static CellularPktStatus_t _parseUrcIndicationCall( const CellularContext_t * pContext, - char * pUrcStr ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - int32_t isActivated = 0; - /* In SARA-R4, usually context 1 is used for PS. */ - uint8_t contextId = 1; - - if( ( pContext == NULL ) || ( pUrcStr == NULL ) ) - { - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pUrcStr, 10, &isActivated ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( isActivated >= INT16_MIN ) && ( isActivated <= ( int32_t ) INT16_MAX ) ) - { - LogDebug( ( "_parseUrcIndicationCall: PS status isActivated=[%d]", isActivated ) ); - - /* Handle the callback function. */ - if( isActivated ) - { - LogDebug( ( "_parseUrcIndicationCall: PDN activated. Context Id %d", contextId ) ); - _Cellular_PdnEventCallback( pContext, CELLULAR_URC_EVENT_PDN_ACTIVATED, contextId ); - } - else - { - LogDebug( ( "_parseUrcIndicationCall: PDN deactivated. Context Id %d", contextId ) ); - _Cellular_PdnEventCallback( pContext, CELLULAR_URC_EVENT_PDN_DEACTIVATED, contextId ); - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -/* Parse signal level from +CIEV URC indication. */ -/* This URC only gives bar level and not the exact RSSI value. */ - -static CellularPktStatus_t _parseUrcIndicationCsq( CellularContext_t * pContext, - char * pUrcStr ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - int32_t retStrtoi = 0; - int16_t csqBarLevel = CELLULAR_INVALID_SIGNAL_BAR_VALUE; - CellularSignalInfo_t signalInfo = { 0 }; - - if( ( pContext == NULL ) || ( pUrcStr == NULL ) ) - { - atCoreStatus = CELLULAR_AT_BAD_PARAMETER; - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pUrcStr, 10, &retStrtoi ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( retStrtoi >= INT16_MIN ) && ( retStrtoi <= ( int32_t ) INT16_MAX ) ) - { - csqBarLevel = retStrtoi; - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - - /* Handle the callback function. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - LogDebug( ( "_parseUrcIndicationCsq: SIGNAL Strength Bar level [%d]", csqBarLevel ) ); - signalInfo.rssi = CELLULAR_INVALID_SIGNAL_VALUE; - signalInfo.rsrp = CELLULAR_INVALID_SIGNAL_VALUE; - signalInfo.rsrq = CELLULAR_INVALID_SIGNAL_VALUE; - signalInfo.ber = CELLULAR_INVALID_SIGNAL_VALUE; - signalInfo.bars = csqBarLevel; - _Cellular_SignalStrengthChangedCallback( pContext, CELLULAR_URC_EVENT_SIGNAL_CHANGED, &signalInfo ); - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessCiev( CellularContext_t * pContext, - char * pInputLine ) -{ - char * pUrcStr = NULL, * pToken = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - int32_t tempValue = 0; - uint8_t indicatorDescr = 0; - - /* Check context status. */ - if( pContext == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else if( pInputLine == NULL ) - { - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pUrcStr = pInputLine; - atCoreStatus = Cellular_ATRemoveAllDoubleQuote( pUrcStr ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pUrcStr ); - } - - /* Extract indicator */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pUrcStr, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( ( int32_t ) CIEV_POS_MIN ) ) && ( tempValue <= ( ( int32_t ) CIEV_POS_MAX ) ) ) - { - indicatorDescr = ( uint8_t ) tempValue; - - switch( indicatorDescr ) - { - case CIEV_POS_SIGNAL: - LogDebug( ( "_cellular_UrcProcessCiev: CIEV_POS_SIGNAL" ) ); - /* This URC only gives bar level and not the exact RSSI value. */ - - /* - * o 0: < -105 dBm - * o 1 : < -93 dBm - * o 2 : < -81 dBm - * o 3 : < -69 dBm - * o 4 : < -57 dBm - * o 5 : >= -57 dBm - */ - /* Parse the signal Bar level from string. */ - pktStatus = _parseUrcIndicationCsq( pContext, pUrcStr ); - break; - - case CIEV_POS_CALL: - LogDebug( ( "_cellular_UrcProcessCiev: CIEV_POS_CALL" ) ); - /* Parse PS ACT/DEACT from +CIEV URC indication. */ - /* This URC does not tell which context ID number is ACT/DEACT. */ - pktStatus = _parseUrcIndicationCall( ( const CellularContext_t * ) pContext, pUrcStr ); - break; - - default: - break; - } - } - else - { - LogError( ( "_cellular_UrcProcessCiev: parsing failed" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - if( atCoreStatus != CELLULAR_AT_SUCCESS ) - { - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - } - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogDebug( ( "_cellular_UrcProcessCiev: Parse failure" ) ); - } -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessUupsmr( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - uint8_t psmState = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +UUPSMR: [,] */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= ( ( int32_t ) PSM_MODE_EXIT ) ) && ( tempValue <= ( ( int32_t ) PSM_MODE_PREVENT_DEEP_ENTRY ) ) ) - { - psmState = ( uint8_t ) tempValue; - - switch( psmState ) - { - case PSM_MODE_EXIT: - LogInfo( ( "_cellular_UrcProcessUupsmr: PSM_MODE_EXIT" ) ); - break; - - case PSM_MODE_ENTER: - LogInfo( ( "_cellular_UrcProcessUupsmr: PSM_MODE_ENTER event received" ) ); - /* Call the callback function. Indicate the upper layer about the PSM state change. */ - _Cellular_ModemEventCallback( pContext, CELLULAR_MODEM_EVENT_PSM_ENTER ); - break; - - case PSM_MODE_PREVENT_ENTRY: - LogInfo( ( "_cellular_UrcProcessUupsmr: PSM_MODE_PREVENT_ENTRY" ) ); - break; - - case PSM_MODE_PREVENT_DEEP_ENTRY: - LogInfo( ( "_cellular_UrcProcessUupsmr: PSM_MODE_PREVENT_DEEP_ENTRY" ) ); - break; - } - } - else - { - LogError( ( "_cellular_UrcProcessUupsmr: parsing failed" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - } -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessUusoco( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - CellularSocketContext_t * pSocketData = NULL; - uint8_t sessionId = 0; - uint8_t socketError = 0; - uint32_t socketIndex = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +UUSOCO: , - * socket_error = 0 : no error, others : error. */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - sessionId = ( uint8_t ) tempValue; - socketIndex = _Cellular_GetSocketId( pContext, sessionId ); - } - else - { - LogError( ( "parsing _cellular_UrcProcessKtcpInd session ID failed" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= 0 ) && ( tempValue <= UINT8_MAX ) ) - { - socketError = ( uint8_t ) tempValue; - } - else - { - LogError( ( "parsing _cellular_UrcProcessUusoco socket error failed" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Call the callback function of this session. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - pSocketData = _Cellular_GetSocketData( pContext, socketIndex ); - - if( pSocketData == NULL ) - { - LogError( ( "_cellular_UrcProcessUusoco : invalid socket index %u", socketIndex ) ); - } - else - { - if( socketError == 0 ) - { - pSocketData->socketState = SOCKETSTATE_CONNECTED; - LogDebug( ( "Notify session %d with socket opened\r\n", sessionId ) ); - - if( pSocketData->openCallback != NULL ) - { - pSocketData->openCallback( CELLULAR_URC_SOCKET_OPENED, - pSocketData, pSocketData->pOpenCallbackContext ); - } - } - else - { - if( pSocketData->openCallback != NULL ) - { - pSocketData->openCallback( CELLULAR_URC_SOCKET_OPEN_FAILED, - pSocketData, pSocketData->pOpenCallbackContext ); - } - } - } - } - } -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessUusord( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - CellularSocketContext_t * pSocketData = NULL; - uint8_t sessionId = 0; - uint32_t socketIndex = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +UUSOCO: , */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - sessionId = ( uint8_t ) tempValue; - socketIndex = _Cellular_GetSocketId( pContext, sessionId ); - } - else - { - LogError( ( "parsing _cellular_UrcProcessUusord session ID failed" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Skip data length. */ - - /* Call the callback function of this session. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogWarn( ( "_cellular_UrcProcessUusord : unknown session data received. " - "The session %u may not be closed properly in previous execution.", sessionId ) ); - } - else - { - pSocketData = _Cellular_GetSocketData( pContext, socketIndex ); - - if( pSocketData == NULL ) - { - LogError( ( "_cellular_UrcProcessUusord : invalid socket index %d", socketIndex ) ); - } - else - { - /* Indicate the upper layer about the data reception. */ - if( pSocketData->dataReadyCallback != NULL ) - { - pSocketData->dataReadyCallback( pSocketData, pSocketData->pDataReadyCallbackContext ); - } - else - { - LogDebug( ( "_cellular_UrcProcessUusord: Data ready callback not set!!" ) ); - } - } - } - } - } -} - -/*-----------------------------------------------------------*/ - -static void _cellular_UrcProcessUusocl( CellularContext_t * pContext, - char * pInputLine ) -{ - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - char * pLocalInputLine = pInputLine; - char * pToken = NULL; - CellularSocketContext_t * pSocketData = NULL; - uint8_t sessionId = 0; - uint32_t socketIndex = 0; - int32_t tempValue = 0; - - if( ( pContext != NULL ) && ( pInputLine != NULL ) ) - { - /* The inputline is in this format +UUSOCL: */ - atCoreStatus = Cellular_ATGetNextTok( &pLocalInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MIN_TCP_SESSION_ID ) && ( tempValue <= MAX_TCP_SESSION_ID ) ) - { - sessionId = ( uint8_t ) tempValue; - socketIndex = _Cellular_GetSocketId( pContext, sessionId ); - } - else - { - LogError( ( "parsing _cellular_UrcProcessUusocl session ID failed" ) ); - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - /* Call the callback function of this session. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogWarn( ( "_cellular_UrcProcessUusocl : unknown session closed URC received. " - "The session %u may not be closed properly in previous execution.", sessionId ) ); - } - else - { - pSocketData = _Cellular_GetSocketData( pContext, socketIndex ); - - if( pSocketData == NULL ) - { - LogError( ( "_cellular_UrcProcessUusocl : invalid socket index %d", socketIndex ) ); - } - else - { - /* Change the socket state to disconnected. */ - pSocketData->socketState = SOCKETSTATE_DISCONNECTED; - - /* Indicate the upper layer about the data reception. */ - if( pSocketData->closedCallback != NULL ) - { - pSocketData->closedCallback( pSocketData, pSocketData->pClosedCallbackContext ); - } - else - { - LogDebug( ( "_cellular_UrcProcessUusord: Data ready callback not set!!" ) ); - } - } - } - } - } -} - -/*-----------------------------------------------------------*/ - -/* Modem bootup indication. */ - -static void _Cellular_ProcessModemRdy( CellularContext_t * pContext, - char * pInputLine ) -{ - /* The token is the pInputLine. No need to process the pInputLine. */ - ( void ) pInputLine; - - if( pContext == NULL ) - { - LogWarn( ( "_Cellular_ProcessModemRdy: Context not set" ) ); - } - else - { - LogDebug( ( "_Cellular_ProcessModemRdy: Modem Ready event received" ) ); - _Cellular_ModemEventCallback( pContext, CELLULAR_MODEM_EVENT_BOOTUP_OR_REBOOT ); - } -} - -/*-----------------------------------------------------------*/ - -static void _Cellular_UrcProcessCereg( CellularContext_t * pContext, - char * pInputLine ) -{ - ( void ) Cellular_CommonUrcProcessCereg( pContext, pInputLine ); -} - -/*-----------------------------------------------------------*/ - -static void _Cellular_UrcProcessCgreg( CellularContext_t * pContext, - char * pInputLine ) -{ - ( void ) Cellular_CommonUrcProcessCgreg( pContext, pInputLine ); -} - -/*-----------------------------------------------------------*/ - -static void _Cellular_UrcProcessCreg( CellularContext_t * pContext, - char * pInputLine ) -{ - ( void ) Cellular_CommonUrcProcessCreg( pContext, pInputLine ); -} - -/*-----------------------------------------------------------*/ diff --git a/modules/sara_r4/cellular_r4_wrapper.c b/modules/sara_r4/cellular_r4_wrapper.c deleted file mode 100644 index a09ecc98..00000000 --- a/modules/sara_r4/cellular_r4_wrapper.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* The config header is always included first. */ -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -/* Standard includes. */ -#include -#include - -#include "cellular_platform.h" -#include "cellular_types.h" -#include "cellular_api.h" -#include "cellular_common.h" -#include "cellular_common_api.h" - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_Cleanup( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonCleanup( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcNetworkRegistrationEventCallback( CellularHandle_t cellularHandle, - CellularUrcNetworkRegistrationCallback_t networkRegistrationCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcNetworkRegistrationEventCallback( cellularHandle, networkRegistrationCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcPdnEventCallback( CellularHandle_t cellularHandle, - CellularUrcPdnEventCallback_t pdnEventCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcPdnEventCallback( cellularHandle, pdnEventCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterUrcGenericCallback( CellularHandle_t cellularHandle, - CellularUrcGenericCallback_t genericCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterUrcGenericCallback( cellularHandle, genericCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RegisterModemEventCallback( CellularHandle_t cellularHandle, - CellularModemEventCallback_t modemEventCallback, - void * pCallbackContext ) -{ - return Cellular_CommonRegisterModemEventCallback( cellularHandle, modemEventCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ATCommandRaw( CellularHandle_t cellularHandle, - const char * pATCommandPrefix, - const char * pATCommandPayload, - CellularATCommandType_t atCommandType, - CellularATCommandResponseReceivedCallback_t responseReceivedCallback, - void * pData, - uint16_t dataLen ) -{ - return Cellular_CommonATCommandRaw( cellularHandle, pATCommandPrefix, pATCommandPayload, atCommandType, - responseReceivedCallback, pData, dataLen ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_CreateSocket( CellularHandle_t cellularHandle, - uint8_t pdnContextId, - CellularSocketDomain_t socketDomain, - CellularSocketType_t socketType, - CellularSocketProtocol_t socketProtocol, - CellularSocketHandle_t * pSocketHandle ) -{ - return Cellular_CommonCreateSocket( cellularHandle, pdnContextId, socketDomain, socketType, - socketProtocol, pSocketHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterDataReadyCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketDataReadyCallback_t dataReadyCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterDataReadyCallback( cellularHandle, socketHandle, - dataReadyCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterSocketOpenCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketOpenCallback_t socketOpenCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterSocketOpenCallback( cellularHandle, socketHandle, - socketOpenCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_SocketRegisterClosedCallback( CellularHandle_t cellularHandle, - CellularSocketHandle_t socketHandle, - CellularSocketClosedCallback_t closedCallback, - void * pCallbackContext ) -{ - return Cellular_CommonSocketRegisterClosedCallback( cellularHandle, socketHandle, - closedCallback, pCallbackContext ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RfOn( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonRfOn( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_RfOff( CellularHandle_t cellularHandle ) -{ - return Cellular_CommonRfOff( cellularHandle ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetIPAddress( CellularHandle_t cellularHandle, - uint8_t contextId, - char * pBuffer, - uint32_t bufferLength ) -{ - return Cellular_CommonGetIPAddress( cellularHandle, contextId, pBuffer, bufferLength ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetModemInfo( CellularHandle_t cellularHandle, - CellularModemInfo_t * pModemInfo ) -{ - return Cellular_CommonGetModemInfo( cellularHandle, pModemInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetRegisteredNetwork( CellularHandle_t cellularHandle, - CellularPlmnInfo_t * pNetworkInfo ) -{ - return Cellular_CommonGetRegisteredNetwork( cellularHandle, pNetworkInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetNetworkTime( CellularHandle_t cellularHandle, - CellularTime_t * pNetworkTime ) -{ - return Cellular_CommonGetNetworkTime( cellularHandle, pNetworkTime ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetServiceStatus( CellularHandle_t cellularHandle, - CellularServiceStatus_t * pServiceStatus ) -{ - return Cellular_CommonGetServiceStatus( cellularHandle, pServiceStatus ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetSimCardInfo( CellularHandle_t cellularHandle, - CellularSimCardInfo_t * pSimCardInfo ) -{ - return Cellular_CommonGetSimCardInfo( cellularHandle, pSimCardInfo ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetPsmSettings( CellularHandle_t cellularHandle, - CellularPsmSettings_t * pPsmSettings ) -{ - return Cellular_CommonGetPsmSettings( cellularHandle, pPsmSettings ); -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Library API. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_GetEidrxSettings( CellularHandle_t cellularHandle, - CellularEidrxSettingsList_t * pEidrxSettingsList ) -{ - return Cellular_CommonGetEidrxSettings( cellularHandle, pEidrxSettingsList ); -} - -/*-----------------------------------------------------------*/ From a9af14e87190f6276520bba5637068dfdcd039c0 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Mon, 3 Oct 2022 17:22:24 +0800 Subject: [PATCH 03/32] Update README. --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a9aea825..b1bf230d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ## Introduction -The FreeRTOS Cellular Interface exposes the capability of a few popular cellular modems through a uniform API. Currently, this repository contains libraries for these three cellular modems. +The FreeRTOS Cellular Interface exposes the capability of a few popular cellular modems through a uniform API. Currently, this repository supports libraries three cellular modems. * [Quectel BG96](https://www.quectel.com/product/lte-bg96-cat-m1-nb1-egprs/) * [Sierra Wireless HL7802](https://www.sierrawireless.com/products-and-solutions/embedded-solutions/products/hl7802/) @@ -51,7 +51,6 @@ git clone git@github.com/FreeRTOS/FreeRTOS-Cellular-Interface.git At the root of this repository are these folders: * source : reusable common code that implements the standard AT commands defined by 3GPP TS v27.007. -* modules : vendor-specific code that implements non-3GPP AT commands for each cellular modem. * docs : documentations. * test : unit test and cbmc. * tools : tools for Coverity static analysis and CMock. @@ -71,7 +70,7 @@ The FreeRTOS Cellular Interface uses kernel APIs for task synchronization and me FreeRTOS Cellular Interface now supports AT commands, TCP offloaded Cellular abstraction Layer. In order to add support for a new cellular modem, the developer can use the [common component](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/include/common) that has already implemented the 3GPP standard AT commands. -In order to port the [common component](https://www.freertos.org/Documentation/api-ref/cellular_common/index.html): +In order to port the [common component](https://www.freertos.org/Documentation/api-ref/cellular/cellular_porting_module_guide.html): 1. Implement the cellular modem porting interface defined in [cellular_common_portable.h](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/include/common/cellular_common_portable.h) ([Document](https://www.freertos.org/Documentation/api-ref/cellular/cellular__common__portable_8h.html)). 2. Implement the subset of Cellular Library APIs that use vendor-specific (non-3GPP) AT commands. The APIs to be implemented are the ones not marked with an "o" in [this table](https://www.freertos.org/Documentation/api-ref/cellular/cellular_common__a_p_is.html). @@ -82,9 +81,9 @@ It is recommended that you start by cloning the implementation of one of the exi Current Example Implementations: -* [Quectel BG96](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/modules/bg96) -* [Sierra Wireless HL7802](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/modules/hl7802) -* [U-Blox Sara-R4](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/modules/sara_r4) +* [Quectel BG96](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-Quectel-BG96) +* [Sierra Wireless HL7802](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-Sierra-Wireless-HL7802) +* [U-Blox Sara-R4](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-ublox-SARA-R4) ## Building Unit Tests From b181f9e58c8477a757108985bad99339f75ad3d5 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Tue, 4 Oct 2022 07:00:08 +0000 Subject: [PATCH 04/32] Provide modules' repositories for reference implementations. --- docs/doxygen/portingCellularModule.dox | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doxygen/portingCellularModule.dox b/docs/doxygen/portingCellularModule.dox index a4660f2c..1e63f39a 100644 --- a/docs/doxygen/portingCellularModule.dox +++ b/docs/doxygen/portingCellularModule.dox @@ -42,9 +42,9 @@ Reference @subpage cellular_module_urc_handler for detail information. Three cellular module portings can be referenced.
It is recommended that you start by cloning the implementation of one of the existing modems,
then make modifications where your modem's vendor-specific (non-3GPP) AT commands are different.
-- BG96 -- HL7802 -- SARA R4 series +- BG96 +- HL7802 +- SARA R4 series */ /** From d484d036e1cb058766c5310ca1dac539adb68617 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 5 Oct 2022 04:03:25 +0000 Subject: [PATCH 05/32] Update doxygen files. --- docs/doxygen/pages.dox | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox index f5d7399b..0cd5e1d9 100644 --- a/docs/doxygen/pages.dox +++ b/docs/doxygen/pages.dox @@ -10,19 +10,20 @@ FreeRTOS Cellular Library use communication interface to communicate with cellul This library contains the following three components in three folders. | FreeRTOS Cellular Library folders | High Level Description | | :--------------------| :--------------------- | -| include | FreeRTOS Cellular Library APIs definitions help to abstract the control of cellular module. | -| common | FreeRTOS Cellular Library APIs implemenation with 3GPP TS v27.007 AT commands. | -| modules | FreeRTOS Cellular Library APIs implemenation with cellular module specific AT commands. | +| source | Reusable common code that implements the standard AT commands defined by 3GPP TS v27.007. | +| docs | Documentations. | +| test | Unit test and cbmc. | +| tools | tools for Coverity static analysis and CMock. | - Supported cellular modules
Three cellular modules are supported in this library. | Cellular module | | :--------------------| -| quectel BG96 | -| Sierra HL7802 | -| Ublox SARA R4 series | +| [Quectel BG96](https://github.com/FreeRTOS/Lab-FreeRTOS-Cellular-Interface-Reference-Quectel-BG96) | +| [Sierra HL7802](https://github.com/FreeRTOS/Lab-FreeRTOS-Cellular-Interface-Reference-Sierra-Wireless-HL7802) | +| [Ublox SARA R4 series](https://github.com/FreeRTOS/Lab-FreeRTOS-Cellular-Interface-Reference-ublox-SARA-R4) | New cellular module can reference these module porting to be integrated into FreeRTOS Cellular Library.
-Please reference cellular common library document for detail information about porting new cellular module. +Please reference [Porting module Guide](https://www.freertos.org/Documentation/api-ref/cellular/cellular_porting_module_guide.html) document for detail information about porting new cellular module. - Currently Supported Features in FreeRTOS Cellular Library - User of FreeRTOS Cellular Library is able to use Cat-M1 cellular technology to connect to network. - User of FreeRTOS Cellular Library is able to perform control plane operations like (initialize modem, register on a network etc.) in a vendor agnostic way. From d83656eb409b6b50559c1f8751fe57f0265875db Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 5 Oct 2022 04:05:38 +0000 Subject: [PATCH 06/32] Update HL7802 link in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1bf230d..8a27430b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The FreeRTOS Cellular Interface exposes the capability of a few popular cellular modems through a uniform API. Currently, this repository supports libraries three cellular modems. * [Quectel BG96](https://www.quectel.com/product/lte-bg96-cat-m1-nb1-egprs/) -* [Sierra Wireless HL7802](https://www.sierrawireless.com/products-and-solutions/embedded-solutions/products/hl7802/) +* [Sierra Wireless HL7802](https://www.sierrawireless.com/iot-modules/lpwa-modules/hl7802/) * [U-Blox Sara-R4](https://www.u-blox.com/en/product/sara-r4-series) The current version of the FreeRTOS Cellular Interface encapsulates the TCP stack offered by those cellular modems. They all implement the same uniform [Cellular Library API](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/include/cellular_api.h). That API hides the complexity of AT commands, and exposes a socket-like interface to C programmers. From d6c61e1c805f66567ccc7291bf42a067531aac51 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 5 Oct 2022 04:13:29 +0000 Subject: [PATCH 07/32] Fix spelling. --- lexicon.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/lexicon.txt b/lexicon.txt index c101ded0..5f93f048 100644 --- a/lexicon.txt +++ b/lexicon.txt @@ -150,6 +150,7 @@ closedcallback cmakelists cmd cmdbuf +cmock com comm commad From 8dc37772af40389032845ea49e16a4bbbe9c0ea4 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 5 Oct 2022 05:28:24 +0000 Subject: [PATCH 08/32] Align introduction. --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 8a27430b..af11ced7 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,6 @@ ## Introduction -The FreeRTOS Cellular Interface exposes the capability of a few popular cellular modems through a uniform API. Currently, this repository supports libraries three cellular modems. - -* [Quectel BG96](https://www.quectel.com/product/lte-bg96-cat-m1-nb1-egprs/) -* [Sierra Wireless HL7802](https://www.sierrawireless.com/iot-modules/lpwa-modules/hl7802/) -* [U-Blox Sara-R4](https://www.u-blox.com/en/product/sara-r4-series) - The current version of the FreeRTOS Cellular Interface encapsulates the TCP stack offered by those cellular modems. They all implement the same uniform [Cellular Library API](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/include/cellular_api.h). That API hides the complexity of AT commands, and exposes a socket-like interface to C programmers. Even though applications can choose to use the FreeRTOS Cellular Interface API directly, the API is not designed for such a purpose. In a typical FreeRTOS system, applications use high level libraries, such as the [coreMQTT](https://github.com/FreeRTOS/coreMQTT) library and the [coreHTTP](https://github.com/FreeRTOS/coreHTTP) library, to communicate with other end points. Those high level libraries use an abstract interface, the [Transport Interface](https://github.com/FreeRTOS/coreMQTT/blob/main/source/interface/transport_interface.h), to send and receive data. A Transport Interface can be implemented on top of the FreeRTOS Cellular Interface. From 4eb42b6d33707dad45ef9654d905683539c71cce Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 5 Oct 2022 08:14:14 +0000 Subject: [PATCH 09/32] Remove Lab- prefix at url links --- docs/doxygen/pages.dox | 6 +++--- docs/doxygen/portingCellularModule.dox | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox index 0cd5e1d9..224a7538 100644 --- a/docs/doxygen/pages.dox +++ b/docs/doxygen/pages.dox @@ -19,9 +19,9 @@ This library contains the following three components in three folders. Three cellular modules are supported in this library. | Cellular module | | :--------------------| -| [Quectel BG96](https://github.com/FreeRTOS/Lab-FreeRTOS-Cellular-Interface-Reference-Quectel-BG96) | -| [Sierra HL7802](https://github.com/FreeRTOS/Lab-FreeRTOS-Cellular-Interface-Reference-Sierra-Wireless-HL7802) | -| [Ublox SARA R4 series](https://github.com/FreeRTOS/Lab-FreeRTOS-Cellular-Interface-Reference-ublox-SARA-R4) | +| [Quectel BG96](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-Quectel-BG96) | +| [Sierra HL7802](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-Sierra-Wireless-HL7802) | +| [Ublox SARA R4 series](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-ublox-SARA-R4) | New cellular module can reference these module porting to be integrated into FreeRTOS Cellular Library.
Please reference [Porting module Guide](https://www.freertos.org/Documentation/api-ref/cellular/cellular_porting_module_guide.html) document for detail information about porting new cellular module. - Currently Supported Features in FreeRTOS Cellular Library diff --git a/docs/doxygen/portingCellularModule.dox b/docs/doxygen/portingCellularModule.dox index 1e63f39a..89360a6c 100644 --- a/docs/doxygen/portingCellularModule.dox +++ b/docs/doxygen/portingCellularModule.dox @@ -42,9 +42,9 @@ Reference @subpage cellular_module_urc_handler for detail information. Three cellular module portings can be referenced.
It is recommended that you start by cloning the implementation of one of the existing modems,
then make modifications where your modem's vendor-specific (non-3GPP) AT commands are different.
-- BG96 -- HL7802 -- SARA R4 series +- BG96 +- HL7802 +- SARA R4 series */ /** From f415db7df1928e3ddbd03574f93dff006ae697fa Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Thu, 6 Oct 2022 04:32:36 +0000 Subject: [PATCH 10/32] Update README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af11ced7..851ca919 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ## Introduction -The current version of the FreeRTOS Cellular Interface encapsulates the TCP stack offered by those cellular modems. They all implement the same uniform [Cellular Library API](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/include/cellular_api.h). That API hides the complexity of AT commands, and exposes a socket-like interface to C programmers. +The Cellular Interface library implement a simple unified [Application Programing Interfaces (APIs)](https://www.freertos.org/Documentation/api-ref/cellular/index.html) that hide the complexity of AT commands. The cellular modems to be interchangeable with the popular options built upon TCP stack and exposes a socket-like interface to C programmers. Even though applications can choose to use the FreeRTOS Cellular Interface API directly, the API is not designed for such a purpose. In a typical FreeRTOS system, applications use high level libraries, such as the [coreMQTT](https://github.com/FreeRTOS/coreMQTT) library and the [coreHTTP](https://github.com/FreeRTOS/coreHTTP) library, to communicate with other end points. Those high level libraries use an abstract interface, the [Transport Interface](https://github.com/FreeRTOS/coreMQTT/blob/main/source/interface/transport_interface.h), to send and receive data. A Transport Interface can be implemented on top of the FreeRTOS Cellular Interface. From 77c0c5d35e585aef2ad76cee131aebfd5a2bcb89 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Fri, 7 Oct 2022 08:22:59 +0800 Subject: [PATCH 11/32] Create Community-Supported-Ports Merged conflict. --- modules/ThirdParty/Community-Supported-Ports | 1 + 1 file changed, 1 insertion(+) create mode 160000 modules/ThirdParty/Community-Supported-Ports diff --git a/modules/ThirdParty/Community-Supported-Ports b/modules/ThirdParty/Community-Supported-Ports new file mode 160000 index 00000000..0f5e3703 --- /dev/null +++ b/modules/ThirdParty/Community-Supported-Ports @@ -0,0 +1 @@ +Subproject commit 0f5e3703aab3357b50bc6266e2dbd9f9ccd0b92c From 6ccb942adac7f082cc3f308bdbc856f3aa3ff0b4 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:22:51 +0800 Subject: [PATCH 12/32] Handle undefined message when sending AT command (#110) * Update pktio to handle undefined message when sending AT command * Undefined message handler is moved to pkthandler * Use PktRespMutex in pktio thread to keep data consistency * Add test cases to cover the undefined message handle flow * Update ATE0 handling in SARA R4 and HL7802. ATE0 may still echo back ATE0. Change the AT command type to CELLULAR_AT_WO_PREFIX --- docs/doxygen/include/size_table.md | 14 +- lexicon.txt | 3 + source/cellular_common.c | 3 + source/cellular_common_api.c | 10 + source/cellular_pkthandler.c | 102 +++- source/cellular_pktio.c | 140 ++++-- source/include/cellular_config_defaults.h | 12 + .../private/cellular_common_internal.h | 5 +- .../include/private/cellular_pktio_internal.h | 2 +- test/unit-test/cellular_pkthandler_utest.c | 112 ++++- test/unit-test/cellular_pktio_utest.c | 440 +++++++++++++++++- 11 files changed, 768 insertions(+), 75 deletions(-) diff --git a/docs/doxygen/include/size_table.md b/docs/doxygen/include/size_table.md index 5e8032d3..18d9c478 100644 --- a/docs/doxygen/include/size_table.md +++ b/docs/doxygen/include/size_table.md @@ -24,27 +24,27 @@ cellular_common_api.c +
0.7K
0.6K
-
0.5K
cellular_common.c -
1.6K
+
1.7K
1.5K
cellular_pkthandler.c -
1.5K
-
1.4K
+
1.7K
+
1.6K
cellular_pktio.c +
2.0K
1.8K
-
1.6K
Total estimates -
14.2K
-
12.9K
+
14.8K
+
13.4K
diff --git a/lexicon.txt b/lexicon.txt index 5f93f048..fe0cf001 100644 --- a/lexicon.txt +++ b/lexicon.txt @@ -548,6 +548,8 @@ pktioreadthread pktiosendatcmd pktiosenddata pktioshutdown +pktrequestmutex +pktrespmutex pktrespqueue pktrxcallback pktstatus @@ -800,6 +802,7 @@ technoloyg tempvalue testindex testresultnumber +threadreturn threadroutine ticktype timeoutatcmddatarecvrequestwithcallback diff --git a/source/cellular_common.c b/source/cellular_common.c index 03852666..911cc536 100644 --- a/source/cellular_common.c +++ b/source/cellular_common.c @@ -1115,6 +1115,7 @@ CellularError_t _Cellular_RegisterUndefinedRespCallback( CellularContext_t * pCo else { /* undefinedRespCallback can be set to NULL to unregister the callback. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->undefinedRespCallback = undefinedRespCallback; if( pContext->undefinedRespCallback != NULL ) @@ -1125,6 +1126,8 @@ CellularError_t _Cellular_RegisterUndefinedRespCallback( CellularContext_t * pCo { pContext->pUndefinedRespCBContext = NULL; } + + PlatformMutex_Unlock( &pContext->PktRespMutex ); } return cellularStatus; diff --git a/source/cellular_common_api.c b/source/cellular_common_api.c index c936b22d..5c010d54 100644 --- a/source/cellular_common_api.c +++ b/source/cellular_common_api.c @@ -206,8 +206,10 @@ CellularError_t Cellular_CommonRegisterUrcNetworkRegistrationEventCallback( Cell } else { + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->cbEvents.networkRegistrationCallback = networkRegistrationCallback; pContext->cbEvents.pNetworkRegistrationCallbackContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); } return cellularStatus; @@ -231,8 +233,10 @@ CellularError_t Cellular_CommonRegisterUrcPdnEventCallback( CellularHandle_t cel } else { + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->cbEvents.pdnEventCallback = pdnEventCallback; pContext->cbEvents.pPdnEventCallbackContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); } return cellularStatus; @@ -256,8 +260,10 @@ CellularError_t Cellular_CommonRegisterUrcSignalStrengthChangedCallback( Cellula } else { + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->cbEvents.signalStrengthChangedCallback = signalStrengthChangedCallback; pContext->cbEvents.pSignalStrengthChangedCallbackContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); } return cellularStatus; @@ -281,8 +287,10 @@ CellularError_t Cellular_CommonRegisterUrcGenericCallback( CellularHandle_t cell } else { + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->cbEvents.genericCallback = genericCallback; pContext->cbEvents.pGenericCallbackContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); } return cellularStatus; @@ -306,8 +314,10 @@ CellularError_t Cellular_CommonRegisterModemEventCallback( CellularHandle_t cell } else { + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->cbEvents.modemEventCallback = modemEventCallback; pContext->cbEvents.pModemEventCallbackContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); } return cellularStatus; diff --git a/source/cellular_pkthandler.c b/source/cellular_pkthandler.c index dd591129..13e99427 100644 --- a/source/cellular_pkthandler.c +++ b/source/cellular_pkthandler.c @@ -81,6 +81,8 @@ static void _Cellular_ProcessGenericUrc( const CellularContext_t * pContext, static CellularPktStatus_t _atParseGetHandler( CellularContext_t * pContext, const char * pTokenPtr, char * pSavePtr ); +static CellularPktStatus_t _handleUndefinedMessage( CellularContext_t * pContext, + const char * pLine ); /*-----------------------------------------------------------*/ @@ -93,7 +95,6 @@ static CellularPktStatus_t _convertAndQueueRespPacket( CellularContext_t * pCont if( ( pBuf != NULL ) ) { pAtResp = ( const CellularATCommandResponse_t * ) pBuf; - PlatformMutex_Lock( &pContext->PktRespMutex ); if( pAtResp->status == false ) { @@ -115,8 +116,6 @@ static CellularPktStatus_t _convertAndQueueRespPacket( CellularContext_t * pCont pktStatus = CELLULAR_PKT_STATUS_FAILURE; LogError( ( "_convertAndQueueRespPacket: Got a response when the Resp Q is full!!" ) ); } - - PlatformMutex_Unlock( &pContext->PktRespMutex ); } else { @@ -217,12 +216,16 @@ static CellularPktStatus_t _Cellular_AtcmdRequestTimeoutWithCallbackRaw( Cellula } else { + LogDebug( ( ">>>>>Start sending [%s]<<<<<", atReq.pAtCmd ) ); + /* Fill in request info structure. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->pktRespCB = atReq.respCallback; - LogDebug( ( ">>>>>Start sending [%s]<<<<<", atReq.pAtCmd ) ); pContext->pPktUsrData = atReq.pData; pContext->PktUsrDataLen = ( uint16_t ) atReq.dataLen; pContext->pCurrentCmd = atReq.pAtCmd; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + pktStatus = _Cellular_PktioSendAtCmd( pContext, atReq.pAtCmd, atReq.atCmdType, atReq.pAtRspPrefix ); if( pktStatus != CELLULAR_PKT_STATUS_OK ) @@ -252,9 +255,11 @@ static CellularPktStatus_t _Cellular_AtcmdRequestTimeoutWithCallbackRaw( Cellula } /* No command is waiting response. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->PktioAtCmdType = CELLULAR_AT_NO_COMMAND; pContext->pktRespCB = NULL; pContext->pCurrentCmd = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); LogDebug( ( "<<<<>>>>Start sending Data <<<<<" ) ); + + /* Send the packet. Data send is regarded as CELLULAR_AT_NO_RESULT. Only + * success or error token is expected in the result. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->PktioAtCmdType = CELLULAR_AT_NO_RESULT; - /* Send the packet. */ + PlatformMutex_Unlock( &pContext->PktRespMutex ); + *dataReq.pSentDataLength = _Cellular_PktioSendData( pContext, dataReq.pData, dataReq.dataLen ); if( *dataReq.pSentDataLength != dataReq.dataLen ) @@ -331,7 +341,11 @@ static CellularPktStatus_t _Cellular_DataSendWithTimeoutDelayRaw( CellularContex LogError( ( "pkt_recv status=%d, data sending timed out", pktStatus ) ); } + /* Set AT command type to CELLULAR_AT_NO_COMMAND for timeout case here. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->PktioAtCmdType = CELLULAR_AT_NO_COMMAND; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + LogDebug( ( "<<<<>>>>", pktStatus ) ); } @@ -479,6 +493,41 @@ static CellularPktStatus_t _atParseGetHandler( CellularContext_t * pContext, /*-----------------------------------------------------------*/ +/* + * @brief Handle AT_UNDEFINED message type. + */ +static CellularPktStatus_t _handleUndefinedMessage( CellularContext_t * pContext, + const char * pLine ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + + LogInfo( ( "AT_UNDEFINED message received %s\r\n", pLine ) ); + + /* undefined message received. Try to handle it with cellular module + * specific handler. */ + if( pContext->undefinedRespCallback == NULL ) + { + LogError( ( "No undefined callback for AT_UNDEFINED type message %s received.", + pLine ) ); + pktStatus = CELLULAR_PKT_STATUS_INVALID_DATA; + } + else + { + pktStatus = pContext->undefinedRespCallback( pContext->pUndefinedRespCBContext, pLine ); + + if( pktStatus != CELLULAR_PKT_STATUS_OK ) + { + LogError( ( "undefinedRespCallback returns error %d for AT_UNDEFINED type message %s received.", + pktStatus, pLine ) ); + pktStatus = CELLULAR_PKT_STATUS_INVALID_DATA; + } + } + + return pktStatus; +} + +/*-----------------------------------------------------------*/ + void _Cellular_PktHandlerCleanup( CellularContext_t * pContext ) { if( ( pContext != NULL ) && ( pContext->pktRespQueue != NULL ) ) @@ -513,6 +562,11 @@ CellularPktStatus_t _Cellular_HandlePacket( CellularContext_t * pContext, pktStatus = _processUrcPacket( pContext, pBuf ); break; + case AT_UNDEFINED: + pktStatus = _handleUndefinedMessage( pContext, pBuf ); + + break; + default: pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; LogError( ( "_Cellular_HandlePacket Callback type (%d) error", atRespType ) ); @@ -573,11 +627,21 @@ CellularPktStatus_t _Cellular_AtcmdRequestSuccessToken( CellularContext_t * pCon else { _Cellular_PktHandlerAcquirePktRequestMutex( pContext ); + + /* Set the extra Token table for this AT command. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->tokenTable.pCellularSrcExtraTokenSuccessTable = pCellularSrcTokenSuccessTable; pContext->tokenTable.cellularSrcExtraTokenSuccessTableSize = cellularSrcTokenSuccessTableSize; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + pktStatus = _Cellular_AtcmdRequestTimeoutWithCallbackRaw( pContext, atReq, atTimeoutMS ); + + /* Clear the extra Token table for this AT command. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->tokenTable.cellularSrcExtraTokenSuccessTableSize = 0; pContext->tokenTable.pCellularSrcExtraTokenSuccessTable = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + _Cellular_PktHandlerReleasePktRequestMutex( pContext ); } @@ -602,11 +666,21 @@ CellularPktStatus_t _Cellular_TimeoutAtcmdDataRecvRequestWithCallback( CellularC else { _Cellular_PktHandlerAcquirePktRequestMutex( pContext ); + + /* Set the data receive prefix. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->pktDataPrefixCB = pktDataPrefixCallback; pContext->pDataPrefixCBContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + pktStatus = _Cellular_AtcmdRequestTimeoutWithCallbackRaw( pContext, atReq, timeoutMS ); + + /* Clear the data receive prefix. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->pktDataPrefixCB = NULL; pContext->pDataPrefixCBContext = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + _Cellular_PktHandlerReleasePktRequestMutex( pContext ); } @@ -634,11 +708,20 @@ CellularPktStatus_t _Cellular_AtcmdDataSend( CellularContext_t * pContext, else { _Cellular_PktHandlerAcquirePktRequestMutex( pContext ); + + /* Set the data send prefix callback. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->pktDataSendPrefixCB = pktDataSendPrefixCallback; pContext->pDataSendPrefixCBContext = pCallbackContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + pktStatus = _Cellular_AtcmdRequestTimeoutWithCallbackRaw( pContext, atReq, atTimeoutMS ); + + /* Clear the data send prefix callback. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->pDataSendPrefixCBContext = NULL; pContext->pktDataSendPrefixCB = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); if( pktStatus == CELLULAR_PKT_STATUS_OK ) { @@ -682,11 +765,20 @@ CellularPktStatus_t _Cellular_TimeoutAtcmdDataSendSuccessToken( CellularContext_ else { _Cellular_PktHandlerAcquirePktRequestMutex( pContext ); + + /* Set the extra token table. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->tokenTable.pCellularSrcExtraTokenSuccessTable = pCellularSrcTokenSuccessTable; pContext->tokenTable.cellularSrcExtraTokenSuccessTableSize = cellularSrcTokenSuccessTableSize; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + pktStatus = _Cellular_AtcmdRequestTimeoutWithCallbackRaw( pContext, atReq, atTimeoutMS ); + + /* Clear the extra token table. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); pContext->tokenTable.cellularSrcExtraTokenSuccessTableSize = 0; pContext->tokenTable.pCellularSrcExtraTokenSuccessTable = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); if( pktStatus == CELLULAR_PKT_STATUS_OK ) { diff --git a/source/cellular_pktio.c b/source/cellular_pktio.c index 9f006564..687d9760 100644 --- a/source/cellular_pktio.c +++ b/source/cellular_pktio.c @@ -75,18 +75,17 @@ static void _saveATData( char * pLine, CellularATCommandResponse_t * pResp ); static CellularPktStatus_t _processIntermediateResponse( char * pLine, CellularATCommandResponse_t * pResp, - CellularATCommandType_t atType, - const char * pRespPrefix ); + CellularATCommandType_t atType ); static CellularATCommandResponse_t * _Cellular_AtResponseNew( void ); static void _Cellular_AtResponseFree( CellularATCommandResponse_t * pResp ); -static CellularPktStatus_t _Cellular_ProcessLine( const CellularContext_t * pContext, +static CellularPktStatus_t _Cellular_ProcessLine( CellularContext_t * pContext, char * pLine, CellularATCommandResponse_t * pResp, CellularATCommandType_t atType, const char * pRespPrefix ); static bool urcTokenWoPrefix( const CellularContext_t * pContext, const char * pLine ); -static _atRespType_t _getMsgType( const CellularContext_t * pContext, +static _atRespType_t _getMsgType( CellularContext_t * pContext, const char * pLine, const char * pRespPrefix ); static CellularCommInterfaceError_t _Cellular_PktRxCallBack( void * pUserData, @@ -182,13 +181,10 @@ static void _saveATData( char * pLine, static CellularPktStatus_t _processIntermediateResponse( char * pLine, CellularATCommandResponse_t * pResp, - CellularATCommandType_t atType, - const char * pRespPrefix ) + CellularATCommandType_t atType ) { CellularPktStatus_t pkStatus = CELLULAR_PKT_STATUS_PENDING_DATA; - ( void ) pRespPrefix; - switch( atType ) { case CELLULAR_AT_WO_PREFIX: @@ -240,10 +236,17 @@ static CellularPktStatus_t _processIntermediateResponse( char * pLine, break; case CELLULAR_AT_MULTI_DATA_WO_PREFIX: - default: _saveATData( pLine, pResp ); pkStatus = CELLULAR_PKT_STATUS_PENDING_BUFFER; break; + + default: + /* Unexpected message received when sending the AT command. */ + LogInfo( ( "Undefind message received %s when sending AT command type %d.", + pLine, atType ) ); + + pkStatus = CELLULAR_PKT_STATUS_INVALID_DATA; + break; } return pkStatus; @@ -295,7 +298,7 @@ static void _Cellular_AtResponseFree( CellularATCommandResponse_t * pResp ) /*-----------------------------------------------------------*/ -static CellularPktStatus_t _Cellular_ProcessLine( const CellularContext_t * pContext, +static CellularPktStatus_t _Cellular_ProcessLine( CellularContext_t * pContext, char * pLine, CellularATCommandResponse_t * pResp, CellularATCommandType_t atType, @@ -310,6 +313,12 @@ static CellularPktStatus_t _Cellular_ProcessLine( const CellularContext_t * pCon uint32_t tokenErrorTableSize = 0; uint32_t tokenExtraTableSize = 0; + /* This variable is used in warning message. */ + ( void ) pRespPrefix; + + /* Lock the response mutex when processing the input line. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); + if( ( pContext->tokenTable.pCellularSrcTokenErrorTable != NULL ) && ( pContext->tokenTable.pCellularSrcTokenSuccessTable != NULL ) ) { @@ -357,7 +366,7 @@ static CellularPktStatus_t _Cellular_ProcessLine( const CellularContext_t * pCon } else { - pkStatus = _processIntermediateResponse( pLine, pResp, atType, pRespPrefix ); + pkStatus = _processIntermediateResponse( pLine, pResp, atType ); } } } @@ -371,6 +380,8 @@ static CellularPktStatus_t _Cellular_ProcessLine( const CellularContext_t * pCon pkStatus ) ); } + PlatformMutex_Unlock( &pContext->PktRespMutex ); + return pkStatus; } @@ -398,7 +409,7 @@ static bool urcTokenWoPrefix( const CellularContext_t * pContext, /*-----------------------------------------------------------*/ -static _atRespType_t _getMsgType( const CellularContext_t * pContext, +static _atRespType_t _getMsgType( CellularContext_t * pContext, const char * pLine, const char * pRespPrefix ) { @@ -407,6 +418,9 @@ static _atRespType_t _getMsgType( const CellularContext_t * pContext, bool inputWithPrefix = false; bool inputWithSrcPrefix = false; + /* Lock the response mutex when deciding message type. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); + if( pContext->tokenTable.pCellularUrcTokenWoPrefixTable == NULL ) { atStatus = CELLULAR_AT_ERROR; @@ -453,6 +467,8 @@ static _atRespType_t _getMsgType( const CellularContext_t * pContext, } } + PlatformMutex_Unlock( &pContext->PktRespMutex ); + return atRespType; } @@ -686,45 +702,75 @@ static CellularPktStatus_t _handleMsgType( CellularContext_t * pContext, if( pkStatus == CELLULAR_PKT_STATUS_OK ) { + /* This command is completed. Call the user callback to parse the result. */ if( pContext->pPktioHandlepktCB != NULL ) { ( void ) pContext->pPktioHandlepktCB( pContext, AT_SOLICITED, *ppAtResp ); } + /* Reset the command type. Further response from cellular modem won't be + * regarded as AT_SOLICITED response. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); + pContext->PktioAtCmdType = CELLULAR_AT_NO_COMMAND; + pContext->pRespPrefix = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + FREE_AT_RESPONSE_AND_SET_NULL( *ppAtResp ); } else if( pkStatus == CELLULAR_PKT_STATUS_PENDING_BUFFER ) { - /* Check data prefix first then store the data if this command has data response. */ + /* This command expects raw data to be appended to buffer. Check data + * prefix first then store the data if this command has data response. */ + } + else if( pkStatus == CELLULAR_PKT_STATUS_PENDING_DATA ) + { + /* The command expects more response line. */ } else { - if( pkStatus != CELLULAR_PKT_STATUS_PENDING_DATA ) - { - ( void ) memset( pContext->pktioReadBuf, 0, PKTIO_READ_BUFFER_SIZE + 1U ); - pContext->pPktioReadPtr = NULL; - FREE_AT_RESPONSE_AND_SET_NULL( *ppAtResp ); - /* pContext->pCurrentCmd is not NULL since it is a solicited response. */ - LogError( ( "processLine ERROR, cleaning up! Current command %s", pContext->pCurrentCmd ) ); - } + /* A unexpected message received when sending the AT command.Try to + * handle it with undefined response callback. */ + pContext->recvdMsgType = AT_UNDEFINED; } } else + { + /* This is AT_UNDEFINED when not sending the AT command. */ + } + + if( pContext->recvdMsgType == AT_UNDEFINED ) { /* Pktio receives AT_UNDEFINED response from modem. This could be module specific - * response. Cellular module registers the callback function through _Cellular_RegisterUndefinedRespCallback - * to handle the response. */ - if( ( pContext->undefinedRespCallback == NULL ) || - ( pContext->undefinedRespCallback( pContext->pUndefinedRespCBContext, pLine ) != CELLULAR_PKT_STATUS_OK ) ) + * response. Call the packet handler callback to handle this message. */ + if( pContext->pPktioHandlepktCB != NULL ) + { + pkStatus = pContext->pPktioHandlepktCB( pContext, AT_UNDEFINED, pLine ); + } + + if( pkStatus != CELLULAR_PKT_STATUS_OK ) { LogError( ( "recvdMsgType is AT_UNDEFINED for Message: %s, cmd %s", pLine, ( pContext->pCurrentCmd != NULL ? pContext->pCurrentCmd : "NULL" ) ) ); + + /* Reset the command type. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); + pContext->PktioAtCmdType = CELLULAR_AT_NO_COMMAND; + pContext->pRespPrefix = NULL; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + + /* Clean the read buffer and read pointer. */ ( void ) memset( pContext->pktioReadBuf, 0, PKTIO_READ_BUFFER_SIZE + 1U ); pContext->pPktioReadPtr = NULL; pContext->partialDataRcvdLen = 0; FREE_AT_RESPONSE_AND_SET_NULL( *ppAtResp ); - pkStatus = CELLULAR_PKT_STATUS_BAD_PARAM; + + /* Return invalid data error code. */ + pkStatus = CELLULAR_PKT_STATUS_INVALID_DATA; + } + else + { + /* The undefined response callback handle this message without problem. */ } } @@ -779,6 +825,19 @@ static bool _preprocessLine( CellularContext_t * pContext, bool keepProcess = true; CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularATCommandDataPrefixCallback_t pktDataPrefixCB = NULL; + void * pDataPrefixCBContext = NULL; + CellularATCommandDataSendPrefixCallback_t pktDataSendPrefixCB = NULL; + void * pDataSendPrefixCBContext = NULL; + + /* Acquire the response lock to keep consistency. */ + PlatformMutex_Lock( &pContext->PktRespMutex ); + pktDataPrefixCB = pContext->pktDataPrefixCB; + pDataPrefixCBContext = pContext->pDataPrefixCBContext; + pktDataSendPrefixCB = pContext->pktDataSendPrefixCB; + pDataSendPrefixCBContext = pContext->pDataSendPrefixCBContext; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + /* The line only has change line. */ if( *pBytesRead <= 0U ) { @@ -788,13 +847,13 @@ static bool _preprocessLine( CellularContext_t * pContext, } else { - if( pContext->pktDataSendPrefixCB != NULL ) + if( pktDataSendPrefixCB != NULL ) { /* Check if the AT command response is the data send prefix. * Data send prefix is an SRC success token for data send AT commmand. * It is used to indicate modem can receive data now. */ /* This function may fix the data stream if the data send prefix is not a line. */ - pktStatus = pContext->pktDataSendPrefixCB( pContext->pDataSendPrefixCBContext, pTempLine, pBytesRead ); + pktStatus = pktDataSendPrefixCB( pDataSendPrefixCBContext, pTempLine, pBytesRead ); if( pktStatus != CELLULAR_PKT_STATUS_OK ) { @@ -802,7 +861,7 @@ static bool _preprocessLine( CellularContext_t * pContext, keepProcess = false; } } - else if( pContext->pktDataPrefixCB != NULL ) + else if( pktDataPrefixCB != NULL ) { /* Check if the AT command response is the data receive prefix. * Data receive prefix is an SRC success token for data receive AT commnad. @@ -811,9 +870,9 @@ static bool _preprocessLine( CellularContext_t * pContext, /* This function may fix the data stream if the AT response and data * received are in the same line. */ - pktStatus = pContext->pktDataPrefixCB( pContext->pDataPrefixCBContext, - pTempLine, *pBytesRead, - ppStartOfData, &pContext->dataLength ); + pktStatus = pktDataPrefixCB( pDataPrefixCBContext, + pTempLine, *pBytesRead, + ppStartOfData, &pContext->dataLength ); if( pktStatus == CELLULAR_PKT_STATUS_OK ) { @@ -1205,7 +1264,18 @@ CellularPktStatus_t _Cellular_PktioSendAtCmd( CellularContext_t * pContext, } else { - pContext->pRespPrefix = pAtRspPrefix; + PlatformMutex_Lock( &pContext->PktRespMutex ); + + if( pAtRspPrefix != NULL ) + { + ( void ) strncpy( pContext->pktRespPrefixBuf, pAtRspPrefix, CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH ); + pContext->pRespPrefix = pContext->pktRespPrefixBuf; + } + else + { + pContext->pRespPrefix = NULL; + } + pContext->PktioAtCmdType = atType; newCmdLen = cmdLen; newCmdLen += 1U; /* Include space for \r. */ @@ -1213,6 +1283,8 @@ CellularPktStatus_t _Cellular_PktioSendAtCmd( CellularContext_t * pContext, ( void ) strncpy( pContext->pktioSendBuf, pAtCmd, cmdLen ); pContext->pktioSendBuf[ cmdLen ] = '\r'; + PlatformMutex_Unlock( &pContext->PktRespMutex ); + ( void ) pContext->pCommIntf->send( pContext->hPktioCommIntf, ( const uint8_t * ) &pContext->pktioSendBuf, newCmdLen, CELLULAR_COMM_IF_SEND_TIMEOUT_MS, &sentLen ); @@ -1225,7 +1297,7 @@ CellularPktStatus_t _Cellular_PktioSendAtCmd( CellularContext_t * pContext, /*-----------------------------------------------------------*/ /* Sends data to the modem. */ -uint32_t _Cellular_PktioSendData( const CellularContext_t * pContext, +uint32_t _Cellular_PktioSendData( CellularContext_t * pContext, const uint8_t * pData, uint32_t dataLen ) { diff --git a/source/include/cellular_config_defaults.h b/source/include/cellular_config_defaults.h index f8e7303a..10b08705 100644 --- a/source/include/cellular_config_defaults.h +++ b/source/include/cellular_config_defaults.h @@ -387,6 +387,18 @@ #define CELLULAR_AT_COMMAND_RAW_TIMEOUT_MS ( 5000U ) #endif +/** + * @brief Cellular AT command response prefix string length.
+ * + * The maximum length of AT command response prefix string. + * + * Possible values:`Any positive integer`
+ * Default value (if undefined): 32 + */ +#ifndef CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH + #define CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH ( 32U ) +#endif + /** * @brief Macro that is called in the cellular library for logging "Error" level * messages. diff --git a/source/include/private/cellular_common_internal.h b/source/include/private/cellular_common_internal.h index 798560dc..4d8011e7 100644 --- a/source/include/private/cellular_common_internal.h +++ b/source/include/private/cellular_common_internal.h @@ -113,8 +113,8 @@ struct CellularContext CellularTokenTable_t tokenTable; /* Packet handler. */ - PlatformMutex_t pktRequestMutex; - PlatformMutex_t PktRespMutex; + PlatformMutex_t pktRequestMutex; /* The mutex for sending request. */ + PlatformMutex_t PktRespMutex; /* The mutex for parsing the response from modem. */ QueueHandle_t pktRespQueue; CellularATCommandResponseReceivedCallback_t pktRespCB; CellularATCommandDataPrefixCallback_t pktDataPrefixCB; /* Data prefix callback function for socket receive function. */ @@ -135,6 +135,7 @@ struct CellularContext char pktioReadBuf[ PKTIO_READ_BUFFER_SIZE + 1 ]; char * pPktioReadPtr; const char * pRespPrefix; + char pktRespPrefixBuf[ CELLULAR_CONFIG_MAX_PREFIX_STRING_LENGTH ]; CellularATCommandType_t PktioAtCmdType; _atRespType_t recvdMsgType; CellularUndefinedRespCallback_t undefinedRespCallback; diff --git a/source/include/private/cellular_pktio_internal.h b/source/include/private/cellular_pktio_internal.h index 2ec8e51f..9d4771e0 100644 --- a/source/include/private/cellular_pktio_internal.h +++ b/source/include/private/cellular_pktio_internal.h @@ -129,7 +129,7 @@ CellularPktStatus_t _Cellular_PktioSendAtCmd( CellularContext_t * pContext, * * @return The data actually send to the comm interface. */ -uint32_t _Cellular_PktioSendData( const CellularContext_t * pContext, +uint32_t _Cellular_PktioSendData( CellularContext_t * pContext, const uint8_t * pData, uint32_t dataLen ); diff --git a/test/unit-test/cellular_pkthandler_utest.c b/test/unit-test/cellular_pkthandler_utest.c index 49ca2579..bc16e8b6 100644 --- a/test/unit-test/cellular_pkthandler_utest.c +++ b/test/unit-test/cellular_pkthandler_utest.c @@ -56,12 +56,15 @@ #define CELLULAR_SAMPLE_PREFIX_STRING_LARGE_INPUT "+CPIN:Story for Littel Red Riding Hood: Once upon a time there was a dear little girl who was loved by every one who looked at her, but most of all by her grandmother, and there was nothing that she would not have given to the child. Once she gave her a little cap of red velvet, which suited her so well that she would never wear anything else. So she was always called Little Red Riding Hood." #define CELLULAR_AT_CMD_TYPICAL_MAX_SIZE ( 32U ) +#define CELLULAR_AT_UNDEFINED_STRING_RESP "undefined_string" + static uint16_t queueData = CELLULAR_PKT_STATUS_BAD_PARAM; static int32_t queueReturnFail = 0; static int32_t queueCreateFail = 0; static int32_t pktRespCBReturn = 0; static bool passCompareString = false; static char * pCompareString = NULL; +static int32_t undefinedCallbackContext = 0; void cellularAtParseTokenHandler( CellularContext_t * pContext, char * pInputStr ); @@ -393,6 +396,30 @@ static char * getStringAfterColon( char * pInputStr ) return ret ? ret + 1 : pInputStr + strlen( pInputStr ); } +static CellularPktStatus_t undefinedRespCallback( void * pCallbackContext, + const char * pLine ) +{ + CellularPktStatus_t undefineReturnStatus = CELLULAR_PKT_STATUS_OK; + + /* Verify pCallbackContext. */ + TEST_ASSERT_EQUAL_PTR( &undefinedCallbackContext, pCallbackContext ); + + /* Verify pLine. */ + if( strcmp( CELLULAR_AT_UNDEFINED_STRING_RESP, pLine ) == 0 ) + { + *( ( int32_t * ) pCallbackContext ) = 1; + undefineReturnStatus = CELLULAR_PKT_STATUS_OK; + } + else + { + *( ( int32_t * ) pCallbackContext ) = 0; + undefineReturnStatus = CELLULAR_PKT_STATUS_FAILURE; + } + + return undefineReturnStatus; +} + + /* ========================================================================== */ /** @@ -651,7 +678,7 @@ void test__Cellular_HandlePacket_AT_UNSOLICITED_Input_String_Less_Than_Urc_Token } /** - * @brief Test that null buffer AT_UNDEFINED case for _Cellular_HandlePacket. + * @brief Test that null buffer invalid message type case for _Cellular_HandlePacket. */ void test__Cellular_HandlePacket_Wrong_RespType( void ) { @@ -660,11 +687,92 @@ void test__Cellular_HandlePacket_Wrong_RespType( void ) memset( &context, 0, sizeof( CellularContext_t ) ); - pktStatus = _Cellular_HandlePacket( &context, AT_UNDEFINED, NULL ); + /* Send invalid message type. */ + pktStatus = _Cellular_HandlePacket( &context, AT_UNDEFINED + 1, NULL ); TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_BAD_PARAM, pktStatus ); } +/** + * @brief Test _Cellular_HandlePacket function with AT_UNDEFINED message type. + * + * AT_UNDEFINED message type is received. A callback function handles the message + * without problem. CELLULAR_PKT_STATUS_OK should be returned. + */ +void test__Cellular_HandlePacket_AT_UNDEFINED_with_undefined_callback_okay( void ) +{ + CellularContext_t context; + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + char undefinedCallbackStr[] = CELLULAR_AT_UNDEFINED_STRING_RESP; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Set undefined response callback. */ + undefinedCallbackContext = 0; + context.undefinedRespCallback = undefinedRespCallback; + context.pUndefinedRespCBContext = &undefinedCallbackContext; + + /* Send AT_UNDEFINED message. */ + pktStatus = _Cellular_HandlePacket( &context, AT_UNDEFINED, undefinedCallbackStr ); + + /* CELLULAR_PKT_STATUS_OK should be returned, since it is handled. */ + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); + + /* Verify undefinedRespCallback is called and the expected string is received. */ + TEST_ASSERT_EQUAL_INT32( 1, undefinedCallbackContext ); +} + +/** + * @brief Test _Cellular_HandlePacket function with AT_UNDEFINED message type. + * + * AT_UNDEFINED message type is received. A callback function handles the message + * but fail to recognized the undefined response. CELLULAR_PKT_STATUS_INVALID_DATA + * should be returned. + */ +void test__Cellular_HandlePacket_AT_UNDEFINED_with_undefined_callback_fail( void ) +{ + CellularContext_t context; + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + char undefinedCallbackStr[] = "RandomString"; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Set undefined response callback. */ + undefinedCallbackContext = 1; + context.undefinedRespCallback = undefinedRespCallback; + context.pUndefinedRespCBContext = &undefinedCallbackContext; + + /* Send AT_UNDEFINED message. */ + pktStatus = _Cellular_HandlePacket( &context, AT_UNDEFINED, undefinedCallbackStr ); + + /* CELLULAR_PKT_STATUS_INVALID_DATA should be returned. */ + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_INVALID_DATA, pktStatus ); + + /* Verify undefinedRespCallback is called and the expected string is received. */ + TEST_ASSERT_EQUAL_INT32( 0, undefinedCallbackContext ); +} + +/** + * @brief Test _Cellular_HandlePacket function with AT_UNDEFINED message type. + * + * AT_UNDEFINED message type is received. No callback function is registered to handle + * the undefined message. CELLULAR_PKT_STATUS_INVALID_DATA should be returned. + */ +void test__Cellular_HandlePacket_AT_UNDEFINED_without_undefined_callback( void ) +{ + CellularContext_t context; + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + char undefinedCallbackStr[] = CELLULAR_AT_UNDEFINED_STRING_RESP; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Send AT_UNDEFINED message. */ + pktStatus = _Cellular_HandlePacket( &context, AT_UNDEFINED, undefinedCallbackStr ); + + /* CELLULAR_PKT_STATUS_INVALID_DATA should be returned. */ + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_INVALID_DATA, pktStatus ); +} + /** * @brief Test that URC with colon for _Cellular_HandlePacket when token is not in the token table. */ diff --git a/test/unit-test/cellular_pktio_utest.c b/test/unit-test/cellular_pktio_utest.c index 86a76cc8..fabf0a86 100644 --- a/test/unit-test/cellular_pktio_utest.c +++ b/test/unit-test/cellular_pktio_utest.c @@ -83,6 +83,12 @@ struct _cellularCommContext int test3; }; +typedef enum commIfRecvType +{ + COMM_IF_RECV_CUSTOM_STRING, + COMM_IF_RECV_NORMAL +} commIfRecvType_t; + static uint16_t pktioEvtMask = 0x0000U; static MockPlatformEventGroup_t evtGroup = { 0 }; @@ -113,6 +119,11 @@ static int setpktDataPrefixCBReturn = 0; static int32_t customCallbackContext = 0; +static commIfRecvType_t testCommIfRecvType = COMM_IF_RECV_NORMAL; +static char * pCommIntfRecvCustomString = NULL; + +static bool atCmdStatusUndefindTest = false; + /* Try to Keep this map in Alphabetical order. */ /* FreeRTOS Cellular Common Library porting interface. */ /* coverity[misra_c_2012_rule_8_7_violation] */ @@ -208,6 +219,9 @@ void setUp() setpktDataPrefixCBReturn = 0; testInfiniteLoop = 0; evtGroupHandle = &evtGroup; + + testCommIfRecvType = COMM_IF_RECV_NORMAL; + pCommIntfRecvCustomString = NULL; } /* Called after each test method. */ @@ -233,6 +247,16 @@ void dummyDelay( uint32_t milliseconds ) ( void ) milliseconds; } +void MockPlatformMutex_Unlock( PlatformMutex_t * pMutex ) +{ + ( void ) pMutex; +} + +void MockPlatformMutex_Lock( PlatformMutex_t * pMutex ) +{ + ( void ) pMutex; +} + void * mock_malloc( size_t size ) { return ( void * ) malloc( size ); @@ -360,9 +384,9 @@ bool Platform_CreateDetachedThread( void ( * threadRoutine )( void * pArgument ) return threadReturn; } -static CellularCommInterfaceError_t _prvCommIntfOpen( CellularCommInterfaceReceiveCallback_t receiveCallback, - void * pUserData, - CellularCommInterfaceHandle_t * pCommInterfaceHandle ) +static CellularCommInterfaceError_t prvCommIntfOpen( CellularCommInterfaceReceiveCallback_t receiveCallback, + void * pUserData, + CellularCommInterfaceHandle_t * pCommInterfaceHandle ) { CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; @@ -376,9 +400,9 @@ static CellularCommInterfaceError_t _prvCommIntfOpen( CellularCommInterfaceRecei return commIntRet; } -static CellularCommInterfaceError_t _prvCommIntfOpenCallrecvCallbackNullContext( CellularCommInterfaceReceiveCallback_t receiveCallback, - void * pUserData, - CellularCommInterfaceHandle_t * pCommInterfaceHandle ) +static CellularCommInterfaceError_t prvCommIntfOpenCallrecvCallbackNullContext( CellularCommInterfaceReceiveCallback_t receiveCallback, + void * pUserData, + CellularCommInterfaceHandle_t * pCommInterfaceHandle ) { CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; @@ -394,7 +418,7 @@ static CellularCommInterfaceError_t _prvCommIntfOpenCallrecvCallbackNullContext( return commIntRet; } -static CellularCommInterfaceError_t _prvCommIntfClose( CellularCommInterfaceHandle_t commInterfaceHandle ) +static CellularCommInterfaceError_t prvCommIntfClose( CellularCommInterfaceHandle_t commInterfaceHandle ) { CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; @@ -403,11 +427,11 @@ static CellularCommInterfaceError_t _prvCommIntfClose( CellularCommInterfaceHand return commIntRet; } -static CellularCommInterfaceError_t _prvCommIntfSend( CellularCommInterfaceHandle_t commInterfaceHandle, - const uint8_t * pData, - uint32_t dataLength, - uint32_t timeoutMilliseconds, - uint32_t * pDataSentLength ) +static CellularCommInterfaceError_t prvCommIntfSend( CellularCommInterfaceHandle_t commInterfaceHandle, + const uint8_t * pData, + uint32_t dataLength, + uint32_t timeoutMilliseconds, + uint32_t * pDataSentLength ) { CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; @@ -422,11 +446,11 @@ static CellularCommInterfaceError_t _prvCommIntfSend( CellularCommInterfaceHandl return commIntRet; } -static CellularCommInterfaceError_t _prvCommIntfReceive( CellularCommInterfaceHandle_t commInterfaceHandle, - uint8_t * pBuffer, - uint32_t bufferLength, - uint32_t timeoutMilliseconds, - uint32_t * pDataReceivedLength ) +static CellularCommInterfaceError_t prvCommIntfReceiveNormal( CellularCommInterfaceHandle_t commInterfaceHandle, + uint8_t * pBuffer, + uint32_t bufferLength, + uint32_t timeoutMilliseconds, + uint32_t * pDataReceivedLength ) { CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; @@ -566,12 +590,70 @@ static CellularCommInterfaceError_t _prvCommIntfReceive( CellularCommInterfaceHa return commIntRet; } + +static CellularCommInterfaceError_t prvCommIntfReceiveCustomString( CellularCommInterfaceHandle_t commInterfaceHandle, + uint8_t * pBuffer, + uint32_t bufferLength, + uint32_t timeoutMilliseconds, + uint32_t * pDataReceivedLength ) +{ + CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS; + + ( void ) commInterfaceHandle; + ( void ) pBuffer; + ( void ) bufferLength; + ( void ) timeoutMilliseconds; + ( void ) pDataReceivedLength; + + if( recvCount > 0 ) + { + recvCount--; + + ( void ) strncpy( ( char * ) pBuffer, pCommIntfRecvCustomString, bufferLength ); + *pDataReceivedLength = strlen( pCommIntfRecvCustomString ); + } + else + { + *pDataReceivedLength = 0; + } + + return commIntRet; +} + +static CellularCommInterfaceError_t prvCommIntfReceive( CellularCommInterfaceHandle_t commInterfaceHandle, + uint8_t * pBuffer, + uint32_t bufferLength, + uint32_t timeoutMilliseconds, + uint32_t * pDataReceivedLength ) +{ + CellularCommInterfaceError_t commIfRet; + + if( testCommIfRecvType == COMM_IF_RECV_CUSTOM_STRING ) + { + commIfRet = prvCommIntfReceiveCustomString( commInterfaceHandle, + pBuffer, + bufferLength, + timeoutMilliseconds, + pDataReceivedLength ); + } + else + { + commIfRet = prvCommIntfReceiveNormal( commInterfaceHandle, + pBuffer, + bufferLength, + timeoutMilliseconds, + pDataReceivedLength ); + } + + return commIfRet; +} + static CellularCommInterface_t CellularCommInterface = { - .open = _prvCommIntfOpen, - .send = _prvCommIntfSend, - .recv = _prvCommIntfReceive, - .close = _prvCommIntfClose + .open = prvCommIntfOpen, + .send = prvCommIntfSend, + .recv = prvCommIntfReceive, + .close = prvCommIntfClose }; static void _shutdownCallback( CellularContext_t * pContext ) @@ -582,6 +664,56 @@ static void _shutdownCallback( CellularContext_t * pContext ) } } +static CellularPktStatus_t prvUndefinedHandlePacket( CellularContext_t * pContext, + _atRespType_t atRespType, + const void * pBuf ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + const CellularATCommandResponse_t * pAtResp = NULL; + char * pLine = NULL; + + if( pContext != NULL ) + { + switch( atRespType ) + { + case AT_SOLICITED: + pAtResp = ( const CellularATCommandResponse_t * ) pBuf; + atCmdStatusUndefindTest = pAtResp->status; + break; + + case AT_UNSOLICITED: + break; + + default: + pLine = ( char * ) pBuf; + + /* undefined message received. Try to handle it with cellular module + * specific handler. */ + if( pContext->undefinedRespCallback == NULL ) + { + pktStatus = CELLULAR_PKT_STATUS_INVALID_DATA; + } + else + { + pktStatus = pContext->undefinedRespCallback( pContext->pUndefinedRespCBContext, pLine ); + + if( pktStatus != CELLULAR_PKT_STATUS_OK ) + { + pktStatus = CELLULAR_PKT_STATUS_INVALID_DATA; + } + } + + break; + } + } + else + { + pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; + } + + return pktStatus; +} + CellularPktStatus_t PktioHandlePacketCallback_t( CellularContext_t * pContext, _atRespType_t atRespType, const void * pBuffer ) @@ -822,7 +954,7 @@ void test__Cellular_PktioInit_Thread_Comm_Open_ReceiveCallback_Null_Context_Fail context.pPktioShutdownCB = _shutdownCallback; /* Assign the comm interface to pContext. */ - commIntf.open = _prvCommIntfOpenCallrecvCallbackNullContext; + commIntf.open = prvCommIntfOpenCallrecvCallbackNullContext; /* Check that CELLULAR_PKT_STATUS_OK is returned. */ pktStatus = _Cellular_PktioInit( &context, PktioHandlePacketCallback_t ); TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); @@ -1261,7 +1393,7 @@ void test__Cellular_PktioInit_Thread_Rx_Data_Event_AT_UNDEFINED_callback_okay( v ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); /* Check that CELLULAR_PKT_STATUS_OK is returned. */ - pktStatus = _Cellular_PktioInit( &context, PktioHandlePacketCallback_t ); + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); /* Verify undefinedRespCallback is called and the expected string is received. */ @@ -1296,13 +1428,202 @@ void test__Cellular_PktioInit_Thread_Rx_Data_Event_AT_UNDEFINED_callback_fail( v ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); /* Check that CELLULAR_PKT_STATUS_OK is returned. */ - pktStatus = _Cellular_PktioInit( &context, PktioHandlePacketCallback_t ); + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); /* Verify undefinedRespCallback is called and the expected string is not received. */ TEST_ASSERT_EQUAL_INT32( 0, customCallbackContext ); } +/** + * @brief Test undefined message callback handling okay in pktio thread when sending AT command. + * + * The following sequence should have no error : + * 1. Sending CELLULAR_AT_NO_RESULT type message ( for example, AT+CFUN=1 ) + * 2. Receiving "OK\r\n", CELLULAR_AT_UNDEFINED_STRING_RESP"\r\n" + * 3. The AT command should success. The UNKNOW_TOKEN should cause a call to undefined callback. + * 4. Okay is returned in the undefined response callback. + */ +void test__Cellular_PktioInit_Thread_Rx_Data_Event_SRC_AT_undefined_callback( void ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularContext_t context; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Assign the comm interface to pContext. */ + context.pCommIntf = pCommIntf; + context.pPktioShutdownCB = _shutdownCallback; + + /* Test the rx_data event with CELLULAR_AT_NO_RESULT type AT command. */ + atCmdStatusUndefindTest = false; + pktioEvtMask = PKTIO_EVT_MASK_RX_DATA; + recvCount = 1; + atCmdType = CELLULAR_AT_NO_RESULT; + testCommIfRecvType = COMM_IF_RECV_CUSTOM_STRING; + pCommIntfRecvCustomString = "OK\r\n"CELLULAR_AT_UNDEFINED_STRING_RESP "\r\n"; + + /* Setup the callback to handle the undefined message. */ + context.undefinedRespCallback = undefinedRespCallback; + customCallbackContext = 0; + context.pUndefinedRespCBContext = &customCallbackContext; + + /* Copy the token table. */ + ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); + + /* Check that CELLULAR_PKT_STATUS_OK is returned. */ + threadReturn = true; /* Set pktio thread return flag. */ + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); + + /* Verify the command should return success. */ + TEST_ASSERT_EQUAL( atCmdStatusUndefindTest, true ); + + /* Verify undefinedRespCallback is called and the expected string is received. */ + TEST_ASSERT_EQUAL_INT32( 1, customCallbackContext ); +} + +/** + * @brief Test undefined message callback handling okay in pktio thread when sending AT command. + * + * The following sequence should have no error : + * 1. Sending CELLULAR_AT_NO_RESULT type message ( for example, AT+CFUN=1 ) + * 2. Receiving CELLULAR_AT_UNDEFINED_STRING_RESP"\r\n", "OK\r\n" + * 3. The AT command should success. The UNKNOW_TOKEN should cause a call to undefined callback. + * 4. Okay is returned in the undefined response callback. + */ +void test__Cellular_PktioInit_Thread_Rx_Data_Event_SRC_AT_undefined_callback_okay( void ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularContext_t context; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Assign the comm interface to pContext. */ + context.pCommIntf = pCommIntf; + context.pPktioShutdownCB = _shutdownCallback; + + /* Test the rx_data event with CELLULAR_AT_NO_RESULT type AT command. */ + atCmdStatusUndefindTest = false; + pktioEvtMask = PKTIO_EVT_MASK_RX_DATA; + recvCount = 1; + atCmdType = CELLULAR_AT_NO_RESULT; + testCommIfRecvType = COMM_IF_RECV_CUSTOM_STRING; + pCommIntfRecvCustomString = CELLULAR_AT_UNDEFINED_STRING_RESP "\r\nOK\r\n"; + + /* Setup the callback to handle the undefined message. */ + context.undefinedRespCallback = undefinedRespCallback; + customCallbackContext = 0; + context.pUndefinedRespCBContext = &customCallbackContext; + + /* Copy the token table. */ + ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); + + /* Check that CELLULAR_PKT_STATUS_OK is returned. */ + threadReturn = true; /* Set pktio thread return flag. */ + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); + + /* Verify the command should return success. */ + TEST_ASSERT_EQUAL( atCmdStatusUndefindTest, true ); + + /* Verify undefinedRespCallback is called and the expected string is received. */ + TEST_ASSERT_EQUAL_INT32( 1, customCallbackContext ); +} + +/** + * @brief Test undefined message callback handling error in pktio thread when sending AT command. + * + * The following sequence should have no error : + * 1. Sending CELLULAR_AT_NO_RESULT type message ( for example, AT+CFUN=1 ) + * 2. Receiving CELLULAR_AT_UNDEFINED_STRING_RESP"\r\n", "OK\r\n" + * 3. The AT command should success. The UNKNOW_TOKEN should cause a call to undefined callback. + * 4. Error is returned in the undefined response callback. This would flush the + * pktio read buffer. + */ +void test__Cellular_PktioInit_Thread_Rx_Data_Event_SRC_AT_undefined_callback_fail( void ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularContext_t context; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Assign the comm interface to pContext. */ + context.pCommIntf = pCommIntf; + context.pPktioShutdownCB = _shutdownCallback; + + /* Test the rx_data event with CELLULAR_AT_NO_RESULT type AT command. */ + atCmdStatusUndefindTest = false; + pktioEvtMask = PKTIO_EVT_MASK_RX_DATA; + recvCount = 1; + atCmdType = CELLULAR_AT_NO_RESULT; + testCommIfRecvType = COMM_IF_RECV_CUSTOM_STRING; + pCommIntfRecvCustomString = "UNKNOWN_UNDEFINED\r\nOK\r\n"; + + /* Setup the callback to handle the undefined message. */ + context.undefinedRespCallback = undefinedRespCallback; + customCallbackContext = 1; + context.pUndefinedRespCBContext = &customCallbackContext; + + /* Copy the token table. */ + ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); + + /* Check that CELLULAR_PKT_STATUS_OK is returned. */ + threadReturn = true; /* Set pktio thread return flag. */ + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); + + /* Verify the command should has error. */ + TEST_ASSERT_EQUAL( atCmdStatusUndefindTest, false ); + + /* Verify undefinedRespCallback is called but the expected string is not received. */ + TEST_ASSERT_EQUAL_INT32( 0, customCallbackContext ); +} + +/** + * @brief Test undefined message no callback in pktio thread when sending AT command. + * + * The following sequence should have no error : + * 1. Sending CELLULAR_AT_NO_RESULT type message ( for example, AT+CFUN=1 ) + * 2. Receiving CELLULAR_AT_UNDEFINED_STRING_RESP"\r\n", "OK\r\n" + * 3. The AT command should success. The UNKNOW_TOKEN should cause a call to undefined callback. + * 4. The command callback won't be called. This would cause a timeout in pkthandler. + */ +void test__Cellular_PktioInit_Thread_Rx_Data_Event_SRC_AT_undefined_no_callback_fail( void ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularContext_t context; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Assign the comm interface to pContext. */ + context.pCommIntf = pCommIntf; + context.pPktioShutdownCB = _shutdownCallback; + + /* Test the rx_data event with CELLULAR_AT_NO_RESULT type AT command. */ + atCmdStatusUndefindTest = false; + pktioEvtMask = PKTIO_EVT_MASK_RX_DATA; + recvCount = 1; + atCmdType = CELLULAR_AT_NO_RESULT; + testCommIfRecvType = COMM_IF_RECV_CUSTOM_STRING; + pCommIntfRecvCustomString = "UNKNOWN_UNDEFINED\r\nOK\r\n"; + + /* Copy the token table. */ + ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); + + /* Check that CELLULAR_PKT_STATUS_OK is returned. */ + threadReturn = true; /* Set pktio thread return flag. */ + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); + + /* Verify the command should has error. */ + TEST_ASSERT_EQUAL( atCmdStatusUndefindTest, false ); +} + /** * @brief Test thread receiving rx data event with CELLULAR_AT_MULTI_WO_PREFIX resp for _Cellular_PktioInit to return CELLULAR_PKT_STATUS_OK. */ @@ -1620,6 +1941,49 @@ void test__Cellular_PktioInit_Thread_Rx_Data_Event_URC_TOKEN_STRING_RESP( void ) TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); } +/** + * @brief Test RX data event _handle_data function. + * + * pktio read thread is in data mode and expects more data to be received. Modem returns + * not enough data to pktio. These data will be stored as partial data. + */ +void test__Cellular_PktioInit_Thread_Rx_Data_Event_handle_data( void ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularContext_t context; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + + memset( &context, 0, sizeof( CellularContext_t ) ); + + /* Assign the comm interface to pContext. */ + context.pCommIntf = pCommIntf; + context.pPktioShutdownCB = _shutdownCallback; + + /* Test the rx_data event with CELLULAR_AT_NO_RESULT type AT command. */ + pktioEvtMask = PKTIO_EVT_MASK_RX_DATA; + recvCount = 1; + atCmdType = CELLULAR_AT_NO_RESULT; + testCommIfRecvType = COMM_IF_RECV_CUSTOM_STRING; + pCommIntfRecvCustomString = "12345"; + + /* Copy the token table. */ + ( void ) memcpy( &context.tokenTable, &tokenTable, sizeof( CellularTokenTable_t ) ); + + /* Pktio read thread enter data mode by setting dataLength. */ + context.dataLength = 10; + + /* Check that CELLULAR_PKT_STATUS_OK is returned. */ + threadReturn = true; /* Set pktio thread return flag. */ + pktStatus = _Cellular_PktioInit( &context, prvUndefinedHandlePacket ); + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); + + /* Store 5 bytes in the partial data. */ + TEST_ASSERT_EQUAL_UINT( context.partialDataRcvdLen, 5 ); + + /* The data is incomplete. pPktioReadPtr should be the same pktioReadBuf. */ + TEST_ASSERT_EQUAL( context.pPktioReadPtr, context.pktioReadBuf ); +} + /** * @brief Test pkio aborted event case for _Cellular_PktioInit to return CELLULAR_PKT_STATUS_FAILURE. */ @@ -1848,6 +2212,34 @@ void test__Cellular_PktioSendAtCmd_Happy_Path( void ) TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); } +/** + * @brief Test that happy path for _Cellular_PktioSendAtCmd. + */ +void test__Cellular_PktioSendAtCmd_Happy_Path_No_Prefix( void ) +{ + CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; + CellularContext_t context; + CellularCommInterface_t * pCommIntf = &CellularCommInterface; + struct _cellularCommContext commInterfaceHandle = { 0 }; + CellularAtReq_t atReqSetRatPriority = + { + "ATE0", + CELLULAR_AT_NO_RESULT, + NULL, + NULL, + NULL, + 0, + }; + + memset( &context, 0, sizeof( CellularContext_t ) ); + context.pCommIntf = pCommIntf; + context.hPktioCommIntf = ( CellularCommInterfaceHandle_t ) &commInterfaceHandle; + pktStatus = _Cellular_PktioSendAtCmd( &context, atReqSetRatPriority.pAtCmd, + atReqSetRatPriority.atCmdType, + atReqSetRatPriority.pAtRspPrefix ); + TEST_ASSERT_EQUAL( CELLULAR_PKT_STATUS_OK, pktStatus ); +} + /** * @brief Test that any NULL parameter for _Cellular_PktioSendData. */ From 606aa5dd77855e8d73b465c787f98436ed8764fb Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Thu, 6 Oct 2022 18:21:01 +0800 Subject: [PATCH 13/32] Reset the AT command type before calling callback (#113) * Reset the AT command type before calling pkthandler callback --- source/cellular_pktio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/cellular_pktio.c b/source/cellular_pktio.c index 687d9760..c9cc593f 100644 --- a/source/cellular_pktio.c +++ b/source/cellular_pktio.c @@ -702,12 +702,6 @@ static CellularPktStatus_t _handleMsgType( CellularContext_t * pContext, if( pkStatus == CELLULAR_PKT_STATUS_OK ) { - /* This command is completed. Call the user callback to parse the result. */ - if( pContext->pPktioHandlepktCB != NULL ) - { - ( void ) pContext->pPktioHandlepktCB( pContext, AT_SOLICITED, *ppAtResp ); - } - /* Reset the command type. Further response from cellular modem won't be * regarded as AT_SOLICITED response. */ PlatformMutex_Lock( &pContext->PktRespMutex ); @@ -715,6 +709,12 @@ static CellularPktStatus_t _handleMsgType( CellularContext_t * pContext, pContext->pRespPrefix = NULL; PlatformMutex_Unlock( &pContext->PktRespMutex ); + /* This command is completed. Call the user callback to parse the result. */ + if( pContext->pPktioHandlepktCB != NULL ) + { + ( void ) pContext->pPktioHandlepktCB( pContext, AT_SOLICITED, *ppAtResp ); + } + FREE_AT_RESPONSE_AND_SET_NULL( *ppAtResp ); } else if( pkStatus == CELLULAR_PKT_STATUS_PENDING_BUFFER ) From 4e3dce085d6c641f3c044eb3b65a7050fa634ea8 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Fri, 7 Oct 2022 08:42:34 +0800 Subject: [PATCH 14/32] Remove thirdparty folder. --- modules/ThirdParty/Community-Supported-Ports | 1 - 1 file changed, 1 deletion(-) delete mode 160000 modules/ThirdParty/Community-Supported-Ports diff --git a/modules/ThirdParty/Community-Supported-Ports b/modules/ThirdParty/Community-Supported-Ports deleted file mode 160000 index 0f5e3703..00000000 --- a/modules/ThirdParty/Community-Supported-Ports +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0f5e3703aab3357b50bc6266e2dbd9f9ccd0b92c From 47ab4867f9efc3791363d593ede2496ec328039d Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Fri, 7 Oct 2022 09:42:07 +0800 Subject: [PATCH 15/32] Remove modules folder. --- modules/hl7802/cellular_hl7802.c | 594 ------------------------------- modules/sara_r4/cellular_r4.c | 570 ----------------------------- 2 files changed, 1164 deletions(-) delete mode 100644 modules/hl7802/cellular_hl7802.c delete mode 100644 modules/sara_r4/cellular_r4.c diff --git a/modules/hl7802/cellular_hl7802.c b/modules/hl7802/cellular_hl7802.c deleted file mode 100644 index 99cd9873..00000000 --- a/modules/hl7802/cellular_hl7802.c +++ /dev/null @@ -1,594 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -/* The config header is always included first. */ - -#include - -#include "cellular_config.h" -#include "cellular_config_defaults.h" -#include "cellular_common.h" -#include "cellular_common_portable.h" -#include "cellular_hl7802.h" - -/*-----------------------------------------------------------*/ - -#define ENBABLE_MODULE_UE_RETRY_COUNT ( 6U ) -#define HL7802_MAX_BAND_CFG ( 21U ) -#define HL7802_KSELACQ_CMD_MAX_SIZE ( 19U ) /* The length of AT+KSELACQ=0,1,2,3\0. */ - -/*-----------------------------------------------------------*/ - -typedef struct Hl7802BandConfig -{ - char catm1BandCfg[ HL7802_MAX_BAND_CFG ]; - char nbiotBandCfg[ HL7802_MAX_BAND_CFG ]; - char gsmBandCfg[ HL7802_MAX_BAND_CFG ]; -} Hl7802BandConfig_t; - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq, - uint32_t timeoutMs ); -static CellularError_t getBandCfg( CellularContext_t * pContext, - Hl7802BandConfig_t * pBandCfg ); -static CellularPktStatus_t recvFuncGetBandCfg( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ); - -/*-----------------------------------------------------------*/ - -static cellularModuleContext_t cellularHl7802Context = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenErrorTable[] = -{ "ERROR", "BUSY", "NO CARRIER", "NO ANSWER", "NO DIALTONE", "ABORTED", "+CMS ERROR", "+CME ERROR", "SEND FAIL" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenErrorTableSize = sizeof( CellularSrcTokenErrorTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenSuccessTable[] = -{ "OK" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenSuccessTableSize = sizeof( CellularSrcTokenSuccessTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularUrcTokenWoPrefixTable[] = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcTokenWoPrefixTableSize = 0; - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq, - uint32_t timeoutMs ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint8_t tryCount = 0; - - if( pAtReq == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - for( ; tryCount < ENBABLE_MODULE_UE_RETRY_COUNT; tryCount++ ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, *pAtReq, timeoutMs ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularPktStatus_t recvFuncGetBandCfg( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - Hl7802BandConfig_t * pBandCfg = NULL; - const CellularATCommandLine_t * pCommnadItem = NULL; - char * pInputLine = NULL; - char * pToken = NULL; - char * pRatBand = NULL; - - if( pContext == NULL ) - { - LogError( ( "recvFuncGetBandCfg: Invalid context." ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( pAtResp == NULL ) - { - LogError( ( "recvFuncGetBandCfg: Invalid pAtResp." ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( Hl7802BandConfig_t ) ) ) - { - LogError( ( "recvFuncGetBandCfg: Invalid pData %p or dataLen %u.", pData, dataLen ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else - { - pBandCfg = ( Hl7802BandConfig_t * ) pData; - pCommnadItem = pAtResp->pItm; - - while( pCommnadItem != NULL ) - { - pInputLine = pCommnadItem->pLine; - LogDebug( ( "recvFuncGetBandCfg: input line %s", pInputLine ) ); - - /* Remove the line prefix. */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* Parse the RAT field. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pToken ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - switch( *pToken ) - { - case '0': - pRatBand = pBandCfg->catm1BandCfg; - break; - - case '1': - pRatBand = pBandCfg->nbiotBandCfg; - break; - - case '2': - pRatBand = pBandCfg->gsmBandCfg; - break; - - default: - pRatBand = NULL; - LogError( ( "recvFuncGetBandCfg: unknown RAT %s", pToken ) ); - atCoreStatus = CELLULAR_AT_ERROR; - break; - } - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - /* Copy the band configuration. */ - strncpy( pRatBand, pInputLine, HL7802_MAX_BAND_CFG ); - } - else - { - LogError( ( "recvFuncGetBandCfg process response line error" ) ); - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - break; - } - - pCommnadItem = pCommnadItem->pNext; - } - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ - -static CellularError_t getBandCfg( CellularContext_t * pContext, - Hl7802BandConfig_t * pBandCfg ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetBndCfg = - { - "AT+KBNDCFG?", - CELLULAR_AT_MULTI_WITH_PREFIX, - "+KBNDCFG", - recvFuncGetBandCfg, - pBandCfg, - sizeof( Hl7802BandConfig_t ) - }; - - /* pContext and pBandCfg are checked in Cellular_ModuleEnableUe function. */ - ( void ) memset( pBandCfg, 0, sizeof( Hl7802BandConfig_t ) ); - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetBndCfg, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( pktStatus != CELLULAR_PKT_STATUS_OK ) - { - LogError( ( "getBandCfg: couldn't retrieve band configurations." ) ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -static bool appendRatList( char * pRatList, - CellularRat_t cellularRat ) -{ - bool retValue = true; - - switch( cellularRat ) - { - case CELLULAR_RAT_CATM1: - strcat( pRatList, ",1" ); - break; - - case CELLULAR_RAT_NBIOT: - strcat( pRatList, ",2" ); - break; - - case CELLULAR_RAT_GSM: - strcat( pRatList, ",3" ); - break; - - default: - /* Unsupported RAT. */ - retValue = false; - break; - } - - return retValue; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext, - void ** ppModuleContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t i = 0; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ppModuleContext == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Initialize the module context. */ - ( void ) memset( &cellularHl7802Context, 0, sizeof( cellularModuleContext_t ) ); - - for( i = 0; i < TCP_SESSION_TABLE_LEGNTH; i++ ) - { - cellularHl7802Context.pSessionMap[ i ] = INVALID_SOCKET_INDEX; - } - - *ppModuleContext = ( void * ) &cellularHl7802Context; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetWoPrefix = - { - NULL, - CELLULAR_AT_WO_PREFIX, - NULL, - NULL, - NULL, - 0 - }; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - Hl7802BandConfig_t bandCfg = { 0 }; - char ratSelectCmd[ HL7802_KSELACQ_CMD_MAX_SIZE ] = "AT+KSELACQ=0"; - bool retAppendRat = true; - - if( pContext != NULL ) - { - /* Disable echo. */ - atReqGetWoPrefix.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetWoPrefix, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Disable DTR function. */ - atReqGetNoResult.pAtCmd = "AT&D0"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - #ifndef CELLULAR_CONFIG_DISABLE_FLOW_CONTROL - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Enable RTS/CTS hardware flow control. */ - atReqGetNoResult.pAtCmd = "AT+IFC=2,2"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - #endif - - /* Set Radio Access Technology. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* In the Write format, =0 is used to switch to the first RAT - * in the preferred RAT list (PRL), and fall back to subsequent RATS - * in the PRL if cell coverage is lost. If the PRL is empty, switch to - * CAT-M1. To set the PRL, see AT+KSELACQ. */ - atReqGetNoResult.pAtCmd = "AT+KSRAT=0"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Set Default Radio Access Technology. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT ); - configASSERT( retAppendRat == true ); - - #ifdef CELLULAR_CONFIG_DEFAULT_RAT_2 - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT_2 ); - configASSERT( retAppendRat == true ); - #endif - - #ifdef CELLULAR_CONFIG_DEFAULT_RAT_3 - retAppendRat = appendRatList( ratSelectCmd, CELLULAR_CONFIG_DEFAULT_RAT_3 ); - configASSERT( retAppendRat == true ); - #endif - - atReqGetNoResult.pAtCmd = ratSelectCmd; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_KSELACQ_TIMEOUT_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Set Configured LTE Band. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = getBandCfg( pContext, &bandCfg ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( strcmp( bandCfg.catm1BandCfg, CELLULAR_CONFIG_HL7802_CATM1_BAND ) != 0 ) - { - LogInfo( ( "Cellular_ModuleEnableUE : CAT-M1 band desired %s actual %s", - CELLULAR_CONFIG_HL7802_CATM1_BAND, bandCfg.catm1BandCfg ) ); - atReqGetNoResult.pAtCmd = "AT+KBNDCFG=0,"CELLULAR_CONFIG_HL7802_CATM1_BAND; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - if( strcmp( bandCfg.nbiotBandCfg, CELLULAR_CONFIG_HL7802_NBIOT_BAND ) != 0 ) - { - LogInfo( ( "Cellular_ModuleEnableUE : NBIOT band desired %s actual %s", - CELLULAR_CONFIG_HL7802_NBIOT_BAND, bandCfg.nbiotBandCfg ) ); - atReqGetNoResult.pAtCmd = "AT+KBNDCFG=1,"CELLULAR_CONFIG_HL7802_NBIOT_BAND; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - } - - /* Disable standalone sleep mode. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+KSLEEP=2"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Force initialization of radio to consider new configured bands. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+CFUN=1,1"; - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_30_SECONDS_MS ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - } - - /* Disable echo after reboot device. */ - if( cellularStatus == CELLULAR_SUCCESS ) - { - Platform_Delay( CELLULAR_HL7802_RESET_DELAY_MS ); - atReqGetWoPrefix.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetWoPrefix, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqGetNoResult.pAtCmd = "AT+COPS=3,2"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_120_SECONDS_MS ); - - atReqGetNoResult.pAtCmd = "AT+CREG=2"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - atReqGetNoResult.pAtCmd = "AT+CEREG=2"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - atReqGetNoResult.pAtCmd = "AT+CTZR=1"; - ( void ) _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetNoResult, - CELLULAR_HL7802_AT_TIMEOUT_2_SECONDS_MS ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSocketId( CellularContext_t * pContext, - uint8_t sessionId ) -{ - cellularModuleContext_t * pModuleContext = NULL; - uint32_t socketIndex = INVALID_SOCKET_INDEX; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext != NULL ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - else - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( ( cellularStatus == CELLULAR_SUCCESS ) && - ( sessionId >= MIN_TCP_SESSION_ID ) && ( sessionId <= MAX_TCP_SESSION_ID ) ) - { - socketIndex = pModuleContext->pSessionMap[ sessionId ]; - } - - return socketIndex; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSessionId( CellularContext_t * pContext, - uint32_t socketIndex ) -{ - cellularModuleContext_t * pModuleContext = NULL; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t sessionId = INVALID_SESSION_ID; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_GetSessionId invalid cellular context" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogError( ( "_Cellular_GetSessionId invalid socketIndex" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - for( sessionId = 0; sessionId < TCP_SESSION_TABLE_LEGNTH; sessionId++ ) - { - if( pModuleContext->pSessionMap[ sessionId ] == socketIndex ) - { - break; - } - } - - /* Mapping is not found in the session mapping table. */ - if( sessionId == TCP_SESSION_TABLE_LEGNTH ) - { - sessionId = INVALID_SESSION_ID; - } - } - else - { - sessionId = INVALID_SESSION_ID; - } - - return sessionId; -} diff --git a/modules/sara_r4/cellular_r4.c b/modules/sara_r4/cellular_r4.c deleted file mode 100644 index 07b4e444..00000000 --- a/modules/sara_r4/cellular_r4.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * FreeRTOS-Cellular-Interface v1.3.0 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - */ - -#include "cellular_config.h" -#include "cellular_config_defaults.h" - -#include - -#include "cellular_platform.h" -#include "cellular_common.h" -#include "cellular_common_portable.h" -#include "cellular_r4.h" - -/*-----------------------------------------------------------*/ - -#define ENBABLE_MODULE_UE_RETRY_COUNT ( 3U ) -#define ENBABLE_MODULE_UE_RETRY_TIMEOUT ( 5000U ) -#define ENBABLE_MODULE_UE_REBOOT_POLL_TIME ( 2000U ) -#define ENBABLE_MODULE_UE_REBOOT_MAX_TIME ( 25000U ) - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq ); - -/*-----------------------------------------------------------*/ - -static cellularModuleContext_t cellularHl7802Context = { 0 }; - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenErrorTable[] = -{ "ERROR", "BUSY", "NO CARRIER", "NO ANSWER", "NO DIALTONE", "ABORTED", "+CMS ERROR", "+CME ERROR", "SEND FAIL" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenErrorTableSize = sizeof( CellularSrcTokenErrorTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularSrcTokenSuccessTable[] = -{ "OK", "@" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularSrcTokenSuccessTableSize = sizeof( CellularSrcTokenSuccessTable ) / sizeof( char * ); - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -const char * CellularUrcTokenWoPrefixTable[] = -{ "RDY" }; -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -uint32_t CellularUrcTokenWoPrefixTableSize = sizeof( CellularUrcTokenWoPrefixTable ) / sizeof( char * ); - -/*-----------------------------------------------------------*/ - -static CellularError_t sendAtCommandWithRetryTimeout( CellularContext_t * pContext, - const CellularAtReq_t * pAtReq ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint8_t tryCount = 0; - - if( pAtReq == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - for( ; tryCount < ENBABLE_MODULE_UE_RETRY_COUNT; tryCount++ ) - { - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, *pAtReq, ENBABLE_MODULE_UE_RETRY_TIMEOUT ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - break; - } - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext, - void ** ppModuleContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t i = 0; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - else if( ppModuleContext == NULL ) - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - /* Initialize the module context. */ - ( void ) memset( &cellularHl7802Context, 0, sizeof( cellularModuleContext_t ) ); - - for( i = 0; i < TCP_SESSION_TABLE_LEGNTH; i++ ) - { - cellularHl7802Context.pSessionMap[ i ] = INVALID_SOCKET_INDEX; - } - - *ppModuleContext = ( void * ) &cellularHl7802Context; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext == NULL ) - { - cellularStatus = CELLULAR_INVALID_HANDLE; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Parse AT response for current MNO profile */ -static CellularPktStatus_t _Cellular_RecvFuncGetCurrentMNOProfile( CellularContext_t * pContext, - const CellularATCommandResponse_t * pAtResp, - void * pData, - uint16_t dataLen ) -{ - char * pInputLine = NULL; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularATError_t atCoreStatus = CELLULAR_AT_SUCCESS; - MNOProfileType_t * pCurrentMNOProfile = ( MNOProfileType_t * ) pData; - char * pToken = NULL; - int32_t tempValue = 0; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_RecvFuncGetCurrentMNOProfile: Invalid handle" ) ); - pktStatus = CELLULAR_PKT_STATUS_INVALID_HANDLE; - } - else if( ( pData == NULL ) || ( dataLen != sizeof( MNOProfileType_t ) ) ) - { - LogError( ( "_Cellular_RecvFuncGetCurrentMNOProfile: Invalid param" ) ); - pktStatus = CELLULAR_PKT_STATUS_BAD_PARAM; - } - else if( ( pAtResp == NULL ) || ( pAtResp->pItm == NULL ) || ( pAtResp->pItm->pLine == NULL ) ) - { - LogError( ( "_Cellular_RecvFuncGetCurrentMNOProfile: Input Line passed is NULL" ) ); - pktStatus = CELLULAR_PKT_STATUS_FAILURE; - } - else - { - pInputLine = pAtResp->pItm->pLine; - - /* Remove prefix. */ - atCoreStatus = Cellular_ATRemovePrefix( &pInputLine ); - - /* Remove leading space. */ - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATRemoveLeadingWhiteSpaces( &pInputLine ); - } - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATGetNextTok( &pInputLine, &pToken ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - atCoreStatus = Cellular_ATStrtoi( pToken, 10, &tempValue ); - - if( atCoreStatus == CELLULAR_AT_SUCCESS ) - { - if( ( tempValue >= MNO_PROFILE_SW_DEFAULT ) && ( tempValue <= MNO_PROFILE_STANDARD_EUROPE ) ) - { - *pCurrentMNOProfile = tempValue; - LogInfo( ( "_Cellular_RecvFuncGetCurrentMNOProfile: pCurrentMNOProfile [%d]", *pCurrentMNOProfile ) ); - } - } - else - { - atCoreStatus = CELLULAR_AT_ERROR; - } - } - } - - pktStatus = _Cellular_TranslateAtCoreStatus( atCoreStatus ); - } - - return pktStatus; -} - -/*-----------------------------------------------------------*/ -/* Get modem's current MNO profile */ -static CellularError_t _Cellular_GetCurrentMNOProfile( CellularContext_t * pContext, - MNOProfileType_t * pCurrentMNOProfile ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - CellularAtReq_t atReqGetCurrentMNOProfile = - { - "AT+UMNOPROF?", - CELLULAR_AT_WITH_PREFIX, - "+UMNOPROF", - _Cellular_RecvFuncGetCurrentMNOProfile, - NULL, - sizeof( MNOProfileType_t ), - }; - - atReqGetCurrentMNOProfile.pData = pCurrentMNOProfile; - - /* Internal function. Callee check parameters. */ - pktStatus = _Cellular_AtcmdRequestWithCallback( pContext, atReqGetCurrentMNOProfile ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* Reboot modem and wait for ready state. */ - -CellularError_t rebootCellularModem( CellularContext_t * pContext, - bool disablePsm, - bool disableEidrx ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularPktStatus_t pktStatus = CELLULAR_PKT_STATUS_OK; - uint32_t count = 0; - CellularAtReq_t atReqGetWoPrefix = - { - NULL, - CELLULAR_AT_WO_PREFIX, - NULL, - NULL, - NULL, - 0 - }; - CellularAtReq_t atReqGetNoResult = - { - "AT+CFUN=15", - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - LogInfo( ( "rebootCellularModem: Rebooting Modem." ) ); - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - Platform_Delay( ENBABLE_MODULE_UE_REBOOT_POLL_TIME ); - count = count + ENBABLE_MODULE_UE_REBOOT_POLL_TIME; - - /* wait for modem after reboot*/ - while( count < ENBABLE_MODULE_UE_REBOOT_MAX_TIME ) - { - LogInfo( ( "rebootCellularModem: Use ATE0 command to test modem status." ) ); - - atReqGetWoPrefix.pAtCmd = "ATE0"; - - pktStatus = _Cellular_TimeoutAtcmdRequestWithCallback( pContext, atReqGetWoPrefix, ENBABLE_MODULE_UE_REBOOT_POLL_TIME ); - cellularStatus = _Cellular_TranslatePktStatus( pktStatus ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - LogInfo( ( "rebootCellularModem: Modem is now available." ) ); - - Platform_Delay( ENBABLE_MODULE_UE_REBOOT_POLL_TIME * 3 ); - - /* Query current PSM settings. */ - atReqGetNoResult.pAtCmd = "AT+CPSMS?"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - - if( disablePsm && ( cellularStatus == CELLULAR_SUCCESS ) ) - { - LogInfo( ( "rebootCellularModem: Disable +CPSMS setting." ) ); - atReqGetNoResult.pAtCmd = "AT+CPSMS=0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( disableEidrx && ( cellularStatus == CELLULAR_SUCCESS ) ) - { - LogInfo( ( "rebootCellularModem: Disable +CEDRXS setting." ) ); - atReqGetNoResult.pAtCmd = "AT+CEDRXS=0,4"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - break; - } - else - { - LogWarn( ( "rebootCellularModem: Modem is not ready. Retry sending ATE0." ) ); - } - - count = count + ENBABLE_MODULE_UE_REBOOT_POLL_TIME; - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - CellularAtReq_t atReqGetWithResult = - { - NULL, - CELLULAR_AT_WO_PREFIX, - NULL, - NULL, - NULL, - 0 - }; - char pAtCmdBuf[ CELLULAR_AT_CMD_MAX_SIZE ] = { 0 }; - - if( pContext != NULL ) - { - /* Disable echo. */ - atReqGetWithResult.pAtCmd = "ATE0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetWithResult ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Disable DTR function. */ - atReqGetNoResult.pAtCmd = "AT&D0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - #ifndef CELLULAR_CONFIG_DISABLE_FLOW_CONTROL - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Enable RTS/CTS hardware flow control. */ - atReqGetNoResult.pAtCmd = "AT+IFC=2,2"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - #endif - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Report verbose mobile termination error. */ - atReqGetNoResult.pAtCmd = "AT+CMEE=2"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Setup mobile network operator profiles. */ - /* Setting +UMNOPROF profile will automatically select suitable values for +URAT and +UBANDMASK. */ - - /* Check current MNO profile first to avoid unneccessary modem reboot. */ - MNOProfileType_t currentMNOProfile = MNO_PROFILE_NOT_SET; - cellularStatus = _Cellular_GetCurrentMNOProfile( pContext, ¤tMNOProfile ); - - LogInfo( ( "Cellular_ModuleEnableUE: currentMNOProfile = [%d], desiredProfile = [%d]", currentMNOProfile, CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ) ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - /* Set MNO profile if not set already */ - if( ( currentMNOProfile != CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ) && ( CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE != MNO_PROFILE_NOT_SET ) ) - { - atReqGetNoResult.pAtCmd = pAtCmdBuf; - ( void ) snprintf( ( char * ) atReqGetNoResult.pAtCmd, CELLULAR_AT_CMD_MAX_SIZE, "%s%d", "AT+COPS=2;+UMNOPROF=", CELLULAR_CONFIG_SARA_R4_SET_MNO_PROFILE ); - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - - if( cellularStatus == CELLULAR_SUCCESS ) - { - cellularStatus = rebootCellularModem( pContext, true, true ); - } - } - - #ifdef CELLULAR_CONFIG_SARA_R4_REBOOT_ON_INIT - else - { - cellularStatus = rebootCellularModem( pContext, true, true ); - } - #endif - } - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+COPS=0"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - atReqGetNoResult.pAtCmd = "AT+CFUN=1"; - cellularStatus = sendAtCommandWithRetryTimeout( pContext, &atReqGetNoResult ); - } - } - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -/* FreeRTOS Cellular Common Library porting interface. */ -/* coverity[misra_c_2012_rule_8_7_violation] */ -CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext ) -{ - CellularError_t cellularStatus = CELLULAR_SUCCESS; - CellularAtReq_t atReqGetNoResult = - { - NULL, - CELLULAR_AT_NO_RESULT, - NULL, - NULL, - NULL, - 0 - }; - - atReqGetNoResult.pAtCmd = "AT+COPS=3,2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CGREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CEREG=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - atReqGetNoResult.pAtCmd = "AT+CTZR=1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* TODO: +CGEV URC enable. */ - /* atReqGetNoResult.pAtCmd = "AT+CGEREP=2,0"; */ - /* (void)_Cellular_AtcmdRequestWithCallback(pContext, atReqGetNoResult); */ - - /* Power saving mode URC enable. */ - atReqGetNoResult.pAtCmd = "AT+UPSMR=1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* Mobile termination event reporting +CIEV URC enable. */ - atReqGetNoResult.pAtCmd = "AT+CMER=1,0,0,2,1"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* Enable signal level change indication via +CIEV URC. (To enable all indications, set to 4095) */ - atReqGetNoResult.pAtCmd = "AT+UCIND=2"; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - /* Enable greeting message "RDY" on modem bootup. */ - atReqGetNoResult.pAtCmd = "AT+CSGT=1,\"RDY\""; - ( void ) _Cellular_AtcmdRequestWithCallback( pContext, atReqGetNoResult ); - - return cellularStatus; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSocketId( CellularContext_t * pContext, - uint8_t sessionId ) -{ - cellularModuleContext_t * pModuleContext = NULL; - uint32_t socketIndex = INVALID_SOCKET_INDEX; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - - if( pContext != NULL ) - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - else - { - cellularStatus = CELLULAR_BAD_PARAMETER; - } - - if( ( cellularStatus == CELLULAR_SUCCESS ) && ( sessionId <= ( ( uint8_t ) MAX_TCP_SESSION_ID ) ) ) - { - socketIndex = pModuleContext->pSessionMap[ sessionId ]; - } - - return socketIndex; -} - -/*-----------------------------------------------------------*/ - -uint32_t _Cellular_GetSessionId( CellularContext_t * pContext, - uint32_t socketIndex ) -{ - cellularModuleContext_t * pModuleContext = NULL; - CellularError_t cellularStatus = CELLULAR_SUCCESS; - uint32_t sessionId = INVALID_SESSION_ID; - - if( pContext == NULL ) - { - LogError( ( "_Cellular_GetSessionId invalid cellular context" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else if( socketIndex == INVALID_SOCKET_INDEX ) - { - LogError( ( "_Cellular_GetSessionId invalid socketIndex" ) ); - cellularStatus = CELLULAR_BAD_PARAMETER; - } - else - { - cellularStatus = _Cellular_GetModuleContext( pContext, ( void ** ) &pModuleContext ); - } - - if( cellularStatus == CELLULAR_SUCCESS ) - { - for( sessionId = 0; sessionId < TCP_SESSION_TABLE_LEGNTH; sessionId++ ) - { - if( pModuleContext->pSessionMap[ sessionId ] == socketIndex ) - { - break; - } - } - - /* Mapping is not found in the session mapping table. */ - if( sessionId == TCP_SESSION_TABLE_LEGNTH ) - { - sessionId = INVALID_SESSION_ID; - } - } - else - { - sessionId = INVALID_SESSION_ID; - } - - return sessionId; -} From 05e04a0c0723ae785b78fb381f012e46180c6621 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Fri, 7 Oct 2022 12:31:25 +0800 Subject: [PATCH 16/32] Update README doc for integrating library with cellular modems. --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 851ca919..43d748f2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ * [Folder Structure](#Folder-Structure) * [Integrate FreeRTOS Cellular Interface with MCU platforms](#Integrate-FreeRTOS-Cellular-Interface-with-MCU-platforms) * [Adding support for new cellular modems](#Adding-support-for-new-cellular-modems) +* [Integrate FreeRTOS Cellular Interface with Cellular Modules](#integrate-freertos-cellular-interface-with-cellular-modules) * [Building Unit Tests](#Building-Unit-Tests) * [Generating documentation](#Generating-documentation) * [Contributing](#Contributing) @@ -79,6 +80,16 @@ It is recommended that you start by cloning the implementation of one of the exi * [Sierra Wireless HL7802](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-Sierra-Wireless-HL7802) * [U-Blox Sara-R4](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-ublox-SARA-R4) +## Integrate FreeRTOS Cellular Interface with Cellular Modules + +FreeRTOS Cellular Interface provides common interface for modems, but it needs cellular modem to be implemented for different modems. You can follow [Adding support for new cellular modems](#adding-support-for-new-cellular-modems) to add a new cellular modem, or take example implementations (BG96 / HL7802 / Sara-R4) as cellular modem into your project. Follow below steps to integrate FreeRTOS Cellular Interface into your project: + +1. Clone this repository into your project. +2. Clone modem repository or follow [Adding support for new cellular modems](#adding-support-for-new-cellular-modems) to implement your own cellular modem on your project. +3. Build and execute! + +We also provide [Demos for FreeRTOS-Cellular-Interface on Windows simulator](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator) as references for these three example Implementations. + ## Building Unit Tests ### Checkout CMock Submodule From a1fc8c15bdad66b76c11325e0d0d3cd39189cbea Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Fri, 7 Oct 2022 12:46:17 +0800 Subject: [PATCH 17/32] Remove Transport interface part in README. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 43d748f2..d67a0230 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,6 @@ The Cellular Interface library implement a simple unified [Application Programing Interfaces (APIs)](https://www.freertos.org/Documentation/api-ref/cellular/index.html) that hide the complexity of AT commands. The cellular modems to be interchangeable with the popular options built upon TCP stack and exposes a socket-like interface to C programmers. -Even though applications can choose to use the FreeRTOS Cellular Interface API directly, the API is not designed for such a purpose. In a typical FreeRTOS system, applications use high level libraries, such as the [coreMQTT](https://github.com/FreeRTOS/coreMQTT) library and the [coreHTTP](https://github.com/FreeRTOS/coreHTTP) library, to communicate with other end points. Those high level libraries use an abstract interface, the [Transport Interface](https://github.com/FreeRTOS/coreMQTT/blob/main/source/interface/transport_interface.h), to send and receive data. A Transport Interface can be implemented on top of the FreeRTOS Cellular Interface. - Most cellular modems implement more or less the AT commands defined by the [3GPP TS v27.007](https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1515) standard. This project provides an implementation of such standard AT commands in a [reusable common component](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/include/common). The three Cellular libraries in this project all take advantage of that common code. The library for each modem only implements the vendor-specific AT commands, then exposes the complete Cellular API. The common component that implements the 3GPP TS v27.007 standard has been written in compliance of the following code quality criteria: From 482611528622318202c1b9e48f71a1454200bebe Mon Sep 17 00:00:00 2001 From: Ching-Hsin Lee Date: Fri, 7 Oct 2022 16:16:00 +0800 Subject: [PATCH 18/32] Update README.md --- README.md | 18 ++++++++++++------ docs/plantuml/images/cellular_components.png | Bin 0 -> 32011 bytes 2 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 docs/plantuml/images/cellular_components.png diff --git a/README.md b/README.md index d67a0230..b0675f67 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ At the root of this repository are these folders: * test : unit test and cbmc. * tools : tools for Coverity static analysis and CMock. -## Integrate FreeRTOS Cellular Interface with MCU platforms +## Implement Comm Interface with MCU platforms The FreeRTOS Cellular Interface runs on MCUs. It uses an abstracted interface - the [Comm Interface](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/tree/main/source/interface/cellular_comm_interface.h), to communicate with cellular modems. A Comm Interface must be implemented as well on the MCU platform. The most common implementations of the Comm Interface are over UART hardware, but it can be implemented over other physical interfaces such as SPI as well. The documentation of the Comm Interface is found within the [Cellular API References](https://www.freertos.org/Documentation/api-ref/cellular/cellular_porting.html#cellular_porting_comm_if). These are example implementations of the Comm Interface: @@ -78,15 +78,21 @@ It is recommended that you start by cloning the implementation of one of the exi * [Sierra Wireless HL7802](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-Sierra-Wireless-HL7802) * [U-Blox Sara-R4](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Reference-ublox-SARA-R4) -## Integrate FreeRTOS Cellular Interface with Cellular Modules +## Integrate FreeRTOS Cellular Interface with application -FreeRTOS Cellular Interface provides common interface for modems, but it needs cellular modem to be implemented for different modems. You can follow [Adding support for new cellular modems](#adding-support-for-new-cellular-modems) to add a new cellular modem, or take example implementations (BG96 / HL7802 / Sara-R4) as cellular modem into your project. Follow below steps to integrate FreeRTOS Cellular Interface into your project: +Once comm interface and cellular module implementation are ready, we can start to integrate +FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: +


+Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. -2. Clone modem repository or follow [Adding support for new cellular modems](#adding-support-for-new-cellular-modems) to implement your own cellular modem on your project. -3. Build and execute! +2. Clone one of the refenerce cellular module implementations ( BG96 / HL7802 / SARA-R4 ) +or create your own cellular module implementaion in your project. +3. Implement comm interface. +4. Build these software components with your application and execute. -We also provide [Demos for FreeRTOS-Cellular-Interface on Windows simulator](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator) as references for these three example Implementations. +We also provide [Demos for FreeRTOS-Cellular-Interface on Windows simulator](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator) +as references for these three example Implementations. ## Building Unit Tests diff --git a/docs/plantuml/images/cellular_components.png b/docs/plantuml/images/cellular_components.png new file mode 100644 index 0000000000000000000000000000000000000000..328fdbd4b727192c7375e69eda5c0054ad535d05 GIT binary patch literal 32011 zcmeFYcT`i~w=arczkpIirAfEYt8}Fbib#>rq!*E10wTR6C`AMWq=WR{t09z71O%ja z0tpZS>4ZoNB_!P7@q6z%zjMwT_r5XSA8(ACF&M19_F8N2x#pZ}&iR>hM`&xQQd2Nf zkdTm2t37+7OG0v)mxScf>J>6#PijONEAihY4_#GdlB!|W4dTV$_Dau{NJwg9DbK7( ziPu+OKQs0qAz|RU_`9U0%lV6hBrr$qiITpr1v=9!mGuRp?PRN=ZGa*Q27{6Mg#WnC z`KTr|)K_`#netpF=Yzi~KZRbOGiNY1VlYLywI{iOj?Ok8%DauEslV_U@qDg3-;}-8 zT%A@bWAS3G1@OXa#N^tY(Cf-q?u5R%OGR<<|GF}-bZ5@(Kb`mfZ|DE_8Bwi%SQ~c6oEAI@!)EC#1RAi*KxpTJ?ah3$hi;l_rx9AeX?h^%zgyhrJi}o99 zZ3Y#df4eFCyTe8sd?8MMCZF9(Ov$5Vx#)0WprYtkZW84^`VSNS{c8WdOwl+g&&PDqX_eHxuTB(Ugrt}iABgeZVCr2=mBV7{)frLO{iKgxKN$92-1+?y6a@WX%f3cY-_tx^=FRY zZ(c0!bnAkqTXYxg?|=Vmn@FpV+!5u)%@V8oyu6evy*Y9$nKKt1+F$;mL;k;et&3MI zd5g?C>94GxHrYu>5vtN#e?D&bwIOnI;u1+k-#;s$nJ(V$#D)+#(xP;uYgKN?P6S_y zQa~^I%+DGgcxHwVV;vb3@Kfr3hUAa!MGn!-5};bsUz3axjwB>?WPb>J(_Lu(o<903 zQ;Mhiesa*~sGRd@9%kzP=d>6PadtnHTgufMbOJ-`;zaj;)irO#)=N|o&}X*ydC;-E z^m*S1E%Bvnt`bG&4iyE-Pco)BuW3}ltzSXss$0$OKJAH7If@dzAf7o>30^}i>vBV7 z!`Q0p_rcz|Z7z<=#0JS3Kg{F6R_W(vKeOk)9dY=d&4SOt;n~|yMFM+RT78*G-d6l( zHA_g{FGo@yk{WJto7I~f`fjj+wjCJiJnkGn&Z64L6bt^83VtEx=9jOuAx^N62JPa& zxa~p?*rG=YOksJ){oZQjYma1bo$kW)%U=0w{2u`+i`~%BLEoR3rC;_xt~zRj&CkFr z_Rz7#mq@-dU$FI|7_a4}ugt?%Jein~9opfhezebw8sTXENU`&I%aP=Hq^@q(i|&>c zMH;Gp`8dAg2vn8#kpK4MbK^u~4FwZh^c?sI4>BEYs!K`tJZBL=!)ZC>S9D;jg1B!& zzI#zg<0K?D)PMAibWDw!#94Sh`*b|$adPmE^XYSM_?$%FIpNSPaA00y11xQ-R(Y&-uxND7G zk>+mONhPN7af~AJuyMs(T14!IL3sbev!9faXhzv>@LL%8#{oC67RrjB}6}iC-|4DC=*{MsqQL zb8K%O3X^_a-T}|zUuGWSp%aMtA4QuX3$;Iv1_zo?@jO{R^)zRPxMbPwooS>m<#|AE z3n)+5mNGV7J!)Is;+v|fX}cUN zGe2|y2w@&dj!x731V*G9%RcGt5N~0slOw5FeRpwEDUz*}u74wYE1BF%^KgN@iJ~ri z*ko1lvHPSW`V0#6St$PXFp?+lw(R$O9!>^Ufzh^R%oF%>vaDIPs83VEFs!H%vn>$N zlokuVMLHKZ`(Y2*Zn}8LTig3i6{Zzp-<;Jjw=wI5>WaeY4`!1o~yMC`Ibe)dRK1FAS4;>=g2}5o;x6@|#BpFh6$L|x&{oC1hBS8<^yssuFPf>&x>Aw*{E=VjGS*i0$fyYj}=qZ_sZ5WwK zk5y6dsRM2yoWbIq%&&EE(C4@~CLQBfE;dq6g?)RXV+X%w^eTEy+?~jkqKcu4L6l19 zvHQahBR6Yh$hCqdhkUp1p~9KsW_7b6_`v}fu5OAwjWMYhi=9OCk7W3}3*_*9i%ElZmm(5v-~71wE9d97BD*!iPlw=y_RLHDej3~w(ZsQJA|!l$nJvAeP$R)j68lDYL<{U z&YrrLzkcp3qOQKehQvnl9-A|eu5#ee9{DfLFEwI87;;7Ld-M*f9W5)em3OWvuFrg# zd!0r?iloLpfyYrsz4K`2qhSo*bbyf}?dvg%Jq!CzHWYb}V0T7Zcz-CYENOwyxlPgQ z?}tnm2Qt}i(UG3&-3`e*n7s}F3Fu03_Tm)XAPQ7>W_Xhn zPZlP7dtI#?3*-1?RD6ZH|8IQA_Z&eh>w6)2?s_;F>P<1Kh(}8-IN{#CTW*F8It}z& ziL0(g!6{g@yAH)FpD#d7bkEx5{T+j>5 zt}Egd=tt|PBZxP((s8ZM^|t#IohciVMLl(}=;qechNENL++;ZF2$}x((dpomPpTQy zRbNomSl_OLncg-RfdTSG8WknqL?~|kYt9o;+U^V>y#Vb#VD7pX;(vD%67%UAh+FCe zTgBNaqjI89AtyCG?Ik@o$O7Gn4Q$j^(4ejUq7QPkzD(lG{>K+wy>RU+{8)pu!e6~M zjWIux?Tm&UQA_)DGb*^<3PrJ!E`G^-^iUAD#~yaRSH(lt$|LyZVtdi2fnm^WdQxOq zG0StL=l9*UV|)PHn--P=nr&60x;dw>Gm$PP2b4-4Mz5*r{g_jB-3&i+is;z^0HpkM`bx28Y@?6PR9y3QfdnJc-(QiSZtn4wUV`6xm3BWJ?X?41&+Z8+5u7IG93%OHb>JRG-C)`rtgbTp>+c5;id` z_wl0Ar!kBm_IjaGt+AUSHrG1CrNJ~)+_NrWZ{UO+!@+|-epM4(r*N=xfUxS<;Ul%4C zKLNPg<|}FE6Zs`M?P4t+i_iQ;hF#V{i{PZDe@IYil;fQq5XQ&Q5ec+JtFMf zPDH#w>?!J`E*<}E&DHLD=+TGZ*Y!#pFsWOK&+mnZ-4^4WATqX2cw7JYZCjE!sE?;@ zsDHv^u5~ALzbc~tY|;zpOa0vXwQ<9k>sekyAji`uMX##gyZsdfXTmC>7^GIS;E`x) z7nf_1RFVCn(!{%$)OSfH?6iWTIoE9k}-|jI_GcxHEmk z9Ar7>`)z{n6RL3WJYhY(jrh*-G)qEP;EDo?H%2kYo#yQG?GIqa0QSHPnEOxQ!tr;9 z5;;n!G@|8K;$wg&1g*LSB)Slte(+`sS_XRLBr8!~^%#PFNX>X|y<(p#9GNbuJT>*| zKhyO8CEu`Uhh&%lei>-%rs)+JLQq@!vC^C&y&TV+P}EY$9$?GLwVfZ!BaZi#EjgL# zfE)_vObrV?rVRU=YO$M?xGEmidAFtkmbl|oqB!Qz{i9hG#}p*fx9t?ij$gE_naz(- zr@`)0R0Snxc%LxtoW3s>diA5C_ujo(vd2_gqPos`c%TK%GuLOZ}JzP6B+D%32 zxYczjL`*nNDPr8X?UHzMb7}16)yQD%$lc3(kc_jY7;Yr;ud zHbf5*wQT#Tpl?+zhlZjTzF2Yf+QY>bZnSRZ>Brcf+O2ijdwTnU3CmX2-gdaGh3#2y zOFIYcSLnarN>cuby^MqgO$bdio&hnikwfP8@6o0Q$nX-1QcXs_;S^Z#JvbMF-j1;4` z1&OLk=R!WMoBq!mQPdetgDIs%@5F^59@cF0_ub1m=>B3*e?GMDyC-|?S1%^N^y>2S z11{G=dAH*q7Iw}*(IQW6<<=*zXo%bFB(!OzW%ETT3SzCMm$RGPk6Jed3}8vBCz3_X zriCxqSCSlc{GC%aS-jQ;c8W@}r-jGR$*>kbozoi3tECXk$uj2w49K`R^9^~G#F^nj zMu@RhUxA7QHI5d zx1vWa7J`O;JtF={@);*U>IkCzhuL9?Ji-;N+j`0*ZR}J$I2ejU?Y>v`Dxm^?kqJeV zVo#x}8U4Q;RD z*?08(x@#RDNG*c@mn9eb9glzR;=}&UCC1yuD7RK5@Br|Pu{c6$%wF#%F&=uf|4(TD z=2(qZvGr(ww!7@yXxu9~v^k8oz3Ou*~5* zvbOPX@sjl7yKK&)OC)bsLoVEPX);?oq7OnM5xx<3C+*iLxvQDYgCaSsxU}_2O2o#J zrunHywtb+DR*?{1P?QLyNO1fYz<_vi(Eox-E&^ua&*rZ`@!!Tk``^Utx6J>9=ERHN z*u%f#5Rl&gX5a-#G5P<5U?kdF{zY8%5%mR4S3)k@Bx!H|(D&woKH^RE1(NcwH+BF0 zO=9q3>-aCwiS4U@KjL4fEC2hO7t_`Lb$Z}`7$HrBUUDpEPYRqPInm@KB|O*544Urq zUb&+`V&Ys`A9;ZmmOzYzZYY-|g()c!QAB>maxUd7^>r76LbX?3)jzqCYrsH8O2ik- z%qo(v+?nkEH;^$YYU<{lP!r=@bQf#9sWrJ9sx3en5=_J-UkDp$gkE>DwbCYD12iOGeY;}0Fj=a{0?lzcgrV@mhnrIapmQAR z$QrhiYN= zE34Ij0tY0tBx4c)3Xacon&J_8;08!bT(Q4PMkOYbvC z?-ffJ>{tY#UufDRL;uR*47-%PQr~>|<)ON>Mq?%7k?hci0-#&zo}G4`Q~05P>l;&3 z@4(LiS}Vq4bejor-qC5FWksGX%6%}XtZOlN;D5oBy6(Dq#z7N{RG?K9`G9|O&h4Jl z7n>2vT<=P$-lbhFj7=#%tq@Xv%9|K`2WZIT{-qc+)Z|>=Tqz{Ry$fCUb%J3H^Cj-Z zLt6{$+yx{F<;qDJ|E#U{(#bJ?^D2Ft$xUYR0RNlP!a{NND%_kx&nB== zTb()j#Zyz&{t~=c8*O-E8b%imi3W||Dj1@?l{i%_SWO?pej$i1wJvDVFHMwRgt+^8 z1bsg!l4{@1fh;h~+d!cI^%3BnC(p zX3*srn|8uS_>*D`kIT|_?rymOV+V$#j%SL1(jG;7@iqX+Qg3IB)%bC_@X8mSrv`2& zC}8_AJq#(VPWq(?vi}uP40Sl`!mbmLK_mgArJR!ovdKiAE4 z)HT&tm5W7OceD4v>1%o8OR4&XztjNSORIDp<72!YfZa=}WvaWDEu31G>Yyd(g~J;4 zx#L?C1!59X$*LP(AAuQ5@bn}Olxy8`vIJc6XvWFZccDb_6giG?S6B8k`3>~f*LC(a zOTKWj(ux=2$LdAJFj(Rx952*)zT*hP_V&*1bvJ~+Gt&)7 z(2Rr%WKI~+zF2nk3I$%>cVO+ppE?3{nTnD#Fi;eNF1gafOfjJ!QtZeq zE`ZuI@weJgE;ZX~NMc&O8nTvrP@1vrU-wp~rRp#s-X&1qC%z(j(On~*{6+X7s%Ma( zMY*@Ei+C-l-~J(68exx1njXFrC*d|T6Y6&WL)bs%taw}}v5V#w5Rt3W)rbMgwH~Sh z6Zl&VKL1X15XEGPv9c5r_V79MII2KJtu9P}{a0v|8KQHRC?E_g)P;`*_YzIlD;6N6 zNCtmX{eeD2fyyi$R;gszmqa_FLTHzeoWN#HO5*;-?p+*$g&Cp zu4C`R7rnylp(ffzZQlyfPjw#|s;?k;JgK^{sSy;h^?a3<+~w6=@DI;qt0!V&3*MR_ zm)9(AvG(@Lw#0PqKi-(c{t9$b%kEdRW^qeNO0v7|vYpWLXvHD>%JZt|^eeV&rZcXG zszHVbMgc?4%oGD3jVizmcEC!*?u}h3gs8f6fNq+uM{H%iESL%+uaLrTDHo)1acJin zBy+puOVSH_nrJQ+2yyR{P85*p;_4l^`Zo1ui;{oFRS2n-fRY4#`Sms?#*>j8hQ28> zi9P*P?{f*<@>icF)N`?OCMHa!8>A$$ka0O$TkIHpYe=t%IeuW$rrs+}b$_`Ios>*p zW`^^uSXzS-pfX*x3F?RCg=?^SQQ*fyNXv?iPi+_2NOq#?P+JJC$2VI~Co+-6$(^R( z*P~#OGR&5gq+e7I2(1$Zh%qGf_dl0mEJ!xXPUh(=*)*En{RnroEv#3;EqT@doI!{_ z6CckN1e&D(!(0g~mdeuCR$9s(Y9()?B1mcai%A7yNUwBG#>>Uma}C;W90WAwsMpCk z;`tgBg<&4N@ddk3Slv^usK&`TXsU!lf3dqhle614SZJp_~tSiV`N-ML0b zN1#&-zaori73-f#HAPM9BRVsRhyH1?h)1ELDlD078UcMsHbEefA+#i9*s z^dl;suWU}wn^AsMpW^68+{8BAG-g}5g86~)yKy0-y}BK7R2h3L z>LN?(NQ(%QafQCU?#tb}CoYx`m)5jR%yY+M0KB9Ke~My>r@CKFt1!7Hh+>H_ZqC5g z0sYOZ$|k0hfJ}f|M_qLK2Z5H{9QW}Vu6n-bjw_#Cf*y8mO+X7XDL2cpy|Ly9Z#~^6 zA$jQH5Oc1(rc-rN_H@x|iLId`(db9gYi(DS>QZ{d_X}}DEh()Eoz&R*gtGs-PTAN$ ze<;}S(v&TU%z$A~-^oF6R5yUAj`3J0jn9dy1*GC?b^CV}ppM7^wl0V}G;kL!F#ydU7K=P_AV z&O!8ky6gJPAVvK`gYHSDnl3>e3}1-4q`op?u7wt`7wi|B!LqmT`oJL%d%jO*?9w3P z4~P^90zCe@?Q9t6k`9|slp6M?>OwQy1HYhm+YoJy<50uARftI9N>nVcG!QBRtQb!; zFf7sS?FfF7w&csCW-DEsNz|Xup7Uib>K`nfg&d=z(|Nhfm%VB4_OWu6nl(Y&C*7mV z&DdqLcK1hmxZCCv^<52!GFE)0dgBdIzD&Fi?}c7hpUhKV85Qn`F4*d|jyTUXsa!uGf)Z5IU)sg5PqK~ z+q9Dbz-uq~Ej31tAkE5!Y#e=?nljP}{Zfz3`cCG?6}U>r>$Y2BEK{VgYSy2)S)_F$ z>NJt@TN5!URr`(nO$+g>b+6~T_HPeZr+a24H5+^`Pd3LB{ZWH>&0d6aHJWFA-WyqI z<-DB7tqDXx_*`)Z695*dLGh~aV3HuW_mQ6BGUaE2!NM<)Qz@5Ug^=UB4?^z?8NeEP zWr~Xllu7h7(+3S{v^U&}|B_4M7%8rm-q$N5Xj_@m*?j9&w?!Bs+V00v>6jrnIPS@c zELo>R%|RMvkAXGV559`%TknyT*P^3??cB?qVa=@rzAl6fffgDcT0B{fy|vrpYT;yz@P56MGiyb%mp;_CKZpxrQumQ5UIT#Z%d?g^h=* zBZb4bhY&Wl>9rqXJrE~!*lvWAt??*pN}*ds#hE(NzAkY0tyV{By(;>J3|^xCXCRDEW83UgpMN0 zwb@XsLSc=N6>`$f*=O7@JsF^gK05XrowH`a_MW~9>W#KbbO!n*ew+?VS zq|x*d7{o;Vn_mU_Y)Prjr5h)(!r+2bfZlOJPqM9)$8QkziO z;(V(%!vn*cE)I918vqVUFH9kdYRMvI1uCVryu}4jhYAS>NA&2elHvQK+UfdQaKyz)nA&oVH*fT2E!H8hUPxisaV=q(bfq3@VoZ^^o!V`?VRBbiYIoTRJu$**+~)g; z$FT({7~k)(bK>gdNHtynQqPB|QN+e-n>!V=Wfy>FQhP^ORw7u=lg*BDx6jHB9w2tF z;+&D{LzM2utxnFonJ|7HR`IDMsccR)KmHAXM-@QLnvLiq=$Y1=pFo7b!)gc)3)B8; zPej#ez0d}$^KflFG|cfZKsTV^4P3qOB6QP!AAf1q<;zfH!WXI!c;O|oryDnjCpKr2 z81Er5NK?LITk(s&>H(ICK9{DCc$6qR{to#1H5Z-D)Yc#G$;lJrM1A$&abKDmM__Dv z{3m(=1BrqsL=BDq9YrRVBI=zR;ze&1XZbrlrXa4tYkqpYWjgve1uzM_2rVboBZJU2 z-}juuE}rdAcM)Kk=$u;e<|;*;r}zg-xU%nVO{`>s}G&nw_DAk?| z5}AG_*YhI$a-hHB@jLP?3cQu5*!nvlufL|u#LGjr^5P;oFY&tG|L9Mt0a>WnA1I*i zQZCh>S_YR#yqAfPA@O&c<^K--|Jx2EI{Aq)E0dG};;T+fI7{6~v~ir~m~xg-F>O!p zwMS|^zLhywmlD!QwB3Gs?YdnZ)FU}0CnKGzz0W(f#7JNw_D^Oisjc55nIsnC==TzX zQ%Xw3N1$LL#wAAtdAtOv)az@0U7qA2%FuW5KSQFpKg8xo{6(@ELWyih{HQ8PiTOW|U;w{8{hJ6z`4NGy z|K=_J(~z;hcPC0Os83f?+x$PH{(onKERTyx9<}QDka6Y4l4!$-I3pWnh^~;}8Ob5B z)`et`SR?hD2c4ZX+SxC)Np6q)GX%VtO+|9}be<_ORN=4RSlWNjgS`Ju9{eZjcPY;~ zNlK(QhjTa&Zjd-J{_pePKeOqqQ}G7LW^}VS@74b(3E>&9C*L8Ph*d}f@*pJjPPQVG zp?84BF(#Zg(AYWXh-D|XI`+*uI4JN{b2CYZZi-xeO@d-LK-S6dD5b&G{ru#mavxgA z)+i+b=hhn5=r@I-#*_~_{dH1c4}}D2V7=c=DR%X ze!ky7WZTdX8q_8|oWivbm{W|~XUV6Xm?Ay2(~duFB&!QtI3%3S`@o0h04Z3Hpdfpf ziwC~!r496B8|Y#@>CSIITs?v^hI#3&5Q_h{$@=@XV`g# zwa-xkkU1O;i^dJ4H#7#Vx!gG$!O@`9^4!@FCU zk;aclMAE8RHw|%6aw$GTykP*{aRbCGe@MX;Cl-$Kjl`{ZJRWd$ySmw4Z;me=P(gjo zsbKKLd$|QAB0=HNk!uJ$7Q*OZ`;IRM#7RM|-;i%$)og8G&bl{xp5^H1mxo;`T1W-` z!Vj&58ew5KmsQ&^p&jB|WSzkvmgg-|%z9(D5EE3netOF~=$Vwq`xTq8A3s~g|KqM4 zhgl|gZ&~|U!&Dy9-Y#C$I0|gtkm<&jaX>+9K&jV? zmZG;!NP1x@J8ffZE%0PlOs2F@(F+9)77UCb_lV&rhGBGUr$OYJfWkB*%h_>2wfM)aO{cE1eHFw5?(hjtSgeG&`Po)obk>->D?g_RQ)?^xnNF z+Y&S91R&BDNj<*?xORXC@aNxj5uGmQY7caMHj5Tors%}jdQ=_SI4m>6~4QnRSKFMat&c&3}~(|Rl8_V;7+~k6S&@7 zL)-58S=*ObR9ErTQYpAZak@dYRZAq<9Vdj2wEeKQv%byvMI?*)X9#6soak8I!7oU8 z;E&o@ghQ~^bfz(-Hx%_o-pygK;QO6LDfaarHzEl&(DvM`ow@T?U2 zFxYSXr3$;BQI*7QNLOXv8eF*FIPQFZ__K|6=hk5jh;sj{9}jv3yx&<9Fa20paf>7y zyBT&GqPW(4ig2oS_F}n4|fdm&%2wD3(MaOKeYy#N|b_XsnW;<9-l2HrGs8p7qcL$ zZ$Evn40wF-L@laz>S#9d9YMGBM5LF{Q> Y2}_bwIWzXJBov*5HDGatQ2tEUJ*rKkRJ}uf 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 J@N+k#{|8Lz`u+d_ literal 0 HcmV?d00001 From c5f70ca53b773c20de279de6734e4bf5d0d95d3e Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Fri, 7 Oct 2022 16:22:58 +0800 Subject: [PATCH 19/32] Update README.md Fix typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b0675f67..f40b3158 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. @@ -92,7 +92,7 @@ or create your own cellular module implementaion in your project. 4. Build these software components with your application and execute. We also provide [Demos for FreeRTOS-Cellular-Interface on Windows simulator](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator) -as references for these three example Implementations. +as references for these three cellular modems example implementations. ## Building Unit Tests From 8f07d135cf17dba97a9b99afdcbd2ec88e7ebf98 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 06:57:45 +0800 Subject: [PATCH 20/32] Convert PNG to SVG. --- README.md | 2 +- docs/plantuml/images/cellular_components.png | Bin 32011 -> 0 bytes docs/plantuml/images/cellular_components.svg | 3071 ++++++++++++++++++ 3 files changed, 3072 insertions(+), 1 deletion(-) delete mode 100644 docs/plantuml/images/cellular_components.png create mode 100644 docs/plantuml/images/cellular_components.svg diff --git a/README.md b/README.md index f40b3158..b8a63af0 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.png b/docs/plantuml/images/cellular_components.png deleted file mode 100644 index 328fdbd4b727192c7375e69eda5c0054ad535d05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32011 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 Y2}_bwIWzXJBov*5HDGatQ2tEUJ*rKkRJ}uf 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
ZfxNh$GLRaWqs8AWR{3;h(P>yuUQOhNMzi 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 J@N+k#{|8Lz`u+d_ diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg new file mode 100644 index 00000000..45b77cfe --- /dev/null +++ b/docs/plantuml/images/cellular_components.svg @@ -0,0 +1,3071 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 086bb2699abc02d9abe8a3279ef9e41416b4934b Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 07:00:50 +0800 Subject: [PATCH 21/32] Change image. --- docs/plantuml/images/cellular_components.svg | 3072 +----------------- 1 file changed, 1 insertion(+), 3071 deletions(-) diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg index 45b77cfe..2e53bbcc 100644 --- a/docs/plantuml/images/cellular_components.svg +++ b/docs/plantuml/images/cellular_components.svg @@ -1,3071 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file From 727e96ea0e0ad1c610e81b459759da0b06a16d2c Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 07:56:11 +0800 Subject: [PATCH 22/32] Revert back to PNG format. --- README.md | 2 +- docs/plantuml/images/cellular_components.png | Bin 0 -> 32011 bytes docs/plantuml/images/cellular_components.svg | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 docs/plantuml/images/cellular_components.png delete mode 100644 docs/plantuml/images/cellular_components.svg diff --git a/README.md b/README.md index b8a63af0..f40b3158 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.png b/docs/plantuml/images/cellular_components.png new file mode 100644 index 0000000000000000000000000000000000000000..328fdbd4b727192c7375e69eda5c0054ad535d05 GIT binary patch literal 32011 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 Y2}_bwIWzXJBov*5HDGatQ2tEUJ*rKkRJ}uf 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
ZfxNh$GLRaWqs8AWR{3;h(P>yuUQOhNMzi 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 J@N+k#{|8Lz`u+d_ literal 0 HcmV?d00001 diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg deleted file mode 100644 index 2e53bbcc..00000000 --- a/docs/plantuml/images/cellular_components.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 53ab4bfc557148fe67a7655dc124ab697c39334e Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 16:52:31 +0800 Subject: [PATCH 23/32] Update image to odg format. --- README.md | 2 +- docs/plantuml/images/cellular_components.odg | Bin 0 -> 13613 bytes docs/plantuml/images/cellular_components.png | Bin 32011 -> 0 bytes 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/plantuml/images/cellular_components.odg delete mode 100644 docs/plantuml/images/cellular_components.png diff --git a/README.md b/README.md index f40b3158..48724695 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.odg b/docs/plantuml/images/cellular_components.odg new file mode 100644 index 0000000000000000000000000000000000000000..c23648c6c18751ef986158d255ee74d78c8e8234 GIT binary patch literal 13613 zcmb`u1#lfn(k^<07T98Di@{>Hn3^<9`X(hsI}R zX=q~PVEZp9J349|Jv{?+gO5WiTk3zd#Qhsf6AK+913PM76MG9CYrFqqjPWU}vYR^WU2LcXzb2*Rgl_|FJ{+hnD{LyZxP&p}Ccgy}|!! z8?CLZ9jrh8Oo#vSRQ~R6zfJyZBLoD*zsAx>Xa1K!eQ0*}F6IVyRL&OW`|4_Tt4+wB z7nNJag&w&s)l>->Mn=rX1&Qk4Z5rr3R(ynod3h1A;A+g@LpXoE-z6e_LPdxZ4wXk@ zb7*g!fI0-QY&HY2cwg@fwldgQ(o#T-R|s_naM@a;Oeg98{5f5j>1k6b$kp+(4&9>q z1A#MHn5-Sgf@KmlL&z?zcmaB3LG$R@PRax4n3I&?_|AB= z2222q3w<{n{iV=lODY(2m4{W$j%L*g#mdHfn?pYtXek=>WKvliy3RR`#Yq->2%8E++) zfc5nKw%#4YsO>a5%O)WA&0+7xK$Nv|W=-t|x5A{{j&z^JbGO9kQ?XbHzeo3T5!2z8 zZIhV^DEZ!&9FP5G3IrzswNoJ_kDzRdY3grhIPtm%Y6-$$cZYf*1E~T~)j{)9D^#$U za}bC-Zuz3h|Mb!|}&_IdIX6tmNnJLv{Y{rZ`s$3T>pkAL>6($Vt4vm+& zC=lsaK+-B}LXB2(vdJ9FQKRh%9KN_h6KYHOIaMkk3SaUAb-3R-}xBOQ$V1qLb$)*D;63;jV#bS=U@B`Br>4=X5rh* z2DRNd^?r7!ALg)`gyiCTu94bbeKeRo(ep@d>g&py>_7X6$mh{ZGtpAD@|mM+B4OHo z2EYViG)v>ITZJnIYvKQ76AdD@YqGZ2bwdMji3svaB8kxQvqyFJ2!wec)&*p3-`R0L zDiib^a~<5}_mKL$TJeMr7ezle^VQCZ_0Y~42{GJ(1Y{X=x-F_-a7oAqd6i>)=HY}hf8HUx(lh&6+t{At6ssBs*ktys!@%(CkNjFMh1`8%56h`Ne z3SCeOG$2d@jTwpMJ;wa3fFbZwpGs?i$&fINHtj5Hf?NoQN1wwnAO<*b1mRFUTRsJ~ z%FZlEp$4P^q;3_sm5r8Qz1h~bTx6o5iCBIWNZ43)2KpNBXq)A*hSJAdz-$_H6?_^l z1cceBXRmVuEBt4uALYoesL#l-;TFzwpH=%^5%}De&_XlD;WXR1(h$i_Av@UU%!cP# ztVGtMUz5dVv^Jv1pXYSD(FR~X=NtZrszIxEW?)yh=k#-i-<|UBBVhA)Bn;dMz|GIi z{gEFNQ5utb>5e6>^lT?w86DM(%oLmAs>^Pua!+s()zxlIZ$(M z@DvqFQQeu7hdr&MqhLv(@tY!#w4a>rA5`GzyOt$uStD6?$3hCmj|30 zGx~ERjPo}W&iJSrmC(lk4u7rePtB%HVr@B}F^Sl@zG!4f@cCTd7!_t;p)=awePd)` zO%3b`yQ-a=x;4jWaZh+kPM6}EWRTKIm*CqqN+~=vnwz>AoAvQxLY8=IM5q^7AYrOJ z+nQHVhO-NsoxlK;%K3Bh9tqm{7B!a0iME%sXB`=;;4Ep+YsDAvm(F4R00ZrJl`p(T zfM}v0k&TnjwI+`2KLKXTML*9sF(Yr;$J2GGsTG#B@6fSt-Dql=F_N+w>btn%$VeFR zXCJ<39c^r7*sv?#5?$n$PvucuEM>*R!P|hUrB%4AcF+x6HBn2wvVYN`nwYF$ku<82 zoKtS6?T-#L8vwaYx$FBWINN?UGd)G|r2)w;j@%;Wvy?>n&n{W1PkimSv(~uo-o^Ty zSB6a(Sqj)hLan@_2`KS#w~qOBRl=3MCLKH@9GGC%nYLmqDeNAC;d=^;jNOerMVkz#_ZUd7SOA z$1VdbJSQHkdHp)1ewBZkb#7YDM~^&iwcI=h+fYq;dIsKx1ox_hn`_sgV=3H1^Z;kI zmvY~|f^+v8fPiY!fM6WG_ov13hsP?O_4j>KK6A(1l`rc}j|9CrRZNj4*IC}4A zgOY(nWkDRbea&+8B=S>=Gj>|RfVj~jU)X6kPKassM74yrk1!t%p3uM1y!;&e$`t0gJ+FLb?6OdXR zSL2{^L-Q2avpC7fcDcxcqXJ}l4utVgaXkik@SqGP_Z&M*LfbEd<)x>@ASKSWwWxxl z0^)jYmF*8(^7MFyaD3&&iTb86b-gf{$fYGiL37!1Q@;J3b~oWW)&swEd&z~~e5eD< zX(YSa4kztw284QN)dfhKE;dXXV{Uwv)QAa*??UC-vv-AZkl(qe0nxc!tP1WC$Ef)e zqbII|eA(;Vm16J%#Oj`-xmJ4p9*A+(!Ri8eg}%*3hJ2L*)c3$y&+jUnP`KAe2u3z~ zoe7Nz{ekCe7J^M3m>3o1i$zOy{cST!>APzf^cnDBDlq-`zdEuCxOyloA5sbM7vaK@ z%ub;mj}sQB-d@wWOt(xrM&j>ld2U`$HEUb$zF=5+NR*~YrBbD7j14-rHt&4#3max9 zzlgRK^rs^unBUa?k@bxVzuK)TPM^o5@wSx(_E*HGlpvA{8t!7W)~haYF(eNa`Ul&3 z&d3rgf!koE%6Y?-=p5hCp{B|XKT>WU#I<>)%(F@%(z*S65}2d-HV@}H1NrF*j1Ulz zT#-*gp)%D06!qfR$L$_iqGTA~j+zYf7f*m(kR{_|6{*ZU+y?5y%{;p8q!Kl6v@Wi% zJEg@wL6E=``aXX|#5jTg!2f*n{9VWl{Sh+jSy|fu{K&pylit|WFiCv^~Q3{14MJ>KHx5{RI zc?6mJrR+N(TXdQZrz1Xuf;!!q!_3RW4ynWF&saxaB5q;|^20}z>{kl4krlYFF z93|L4wJIyEd>JRAf9w(QJx-8yW5_TqK>0TB{#bRcxdt2uT-a(2R*|AIsEri!>Bpv&btXzjHu6Q@I&i_$R;mQ`%}JaLO!@N$ z$p|q@1Nrd|8zw%l=%64=^yBq*^^hIl=kF&;V#4$u>(wN3@}30j>g)uZnB()-wyHLr z6)kvQK#3z#h0CHLK%fzZ<4L0x;$_~HJlnR!TR&0 zvNZI&tf&yNd>I@MMN?_!BBEM%U`@omaGXxXpPVvvcZM)j_+D9qT#$?XIr$o|M>{2z zhugv!7)5%?kH_&mXJSvX+{w52hw!ivAg`e$Cp(rGPVHXbr}+*ecxUjZ8S*bZ%9f~0 zx-1de?+T*lFi9c{tyouRy^ZX+b&!!xTE8Hg5(qC8TP|-!3(e{&&H`G#v-hyV$9&$$j>Oji>N-G~=HI#j2?Qt4mC@S`&(yW% zf)@;=T(ETy-F6T1;(IR({FHYYjwahoi9T_@&s8It^b5N~fHiblCVJs*Rqur`*K9pk z_3Ch=s^o|WN`h-60$yZ0f}iQ4T7DL5`XmDu$n^Tu^UdK)VgNscyiKB zv05W4>E1qrF?kaY_TnZ%8HAp@2fLt{O&`m?H}^gOX#_mYJen7!=A{?L7Jy4glZDS6 z^FS5+b5s}tMYyL3nc;hIugkl&zyT&(DC^G428nj|7uV?3&i9YqE zDA#%{Xoz=c^}8I>DvM|OGS~B6pe!><*zLpA4mOw1M{Y+9Odf(~^roFGa}%81J8Yoi z%Q>G?8Xgo{S@>=_3cx4$xCI|Wfss6^tlt{h_q4Acqn3BPofae5QX8P#d0}a|@-K3Z zHD#) zNHg2vo{uo5UhHPYvz1@Pf(}-&4)YloGtTiOP~S3+WH&0~!bplBskYi_ zScNf8z?&g1J454QAs3+}G-7(#JpGveW$ozdn;{3w)-37C*c(A0D1V*e&Gi$GaXUIT zpiR9z&87R+?fYBSoaak67zKoZmbgClTp=!oimrll-Sjp0gmYTAt+c9V5jEG2_g3Cv z)P6-!^@cMawmdy-TUt{TGj~VD{$3WIbCS7Jk`E5(-~|j*hI*@K358A2utyqVO1Ax> zo1l#5NFk1GC9MBzsDKQm`tU-W{FUm0^qGu4EaEE4pfi*#vF)yfSE)!G`O&f)=`=_v z5`EVdjLOKGEVo&J?$&?{M}yGF8v_QTBM6*$vEm>CpAe;}*uD z4KLrJ-tduQl_bXrU^Z_HB<&O$+zgpgTP1d}wPMy)ZfqztJs<2m-Q;#Fil(z2*B6Mr zlV74??r!#xhw09QJi&XkE*IXmPa`TrS7=zYZYo;?1j9uFv)#+Sq)3YvRTDEj`dwOS z+EcHY+S*Ah5RK>ohsr=o&zqka>~-TRN&fJ1yQtigl-+V7AP_ZvJi~|LEKXgWM&3!q zt_&EfpISOWez&dnGUH;L80Z|;!=9g(nMLG+D3S%mA*i;FBZ{nk0!t_Gok=bvT-O}d zVXd?(!bgZ|E&p1?jT`a0EOXil>;2li2k08I(h2Ea zllq*b(B>k!fu60e{j8|V$$VDh8`9C_STP5BV22aN)23YbX2rMz9^Vtlot` z#m}CMJ{72lgx6?iu!YMCU{#rT@VA^ejP<>mMQunIO@?arto#S(Fa{{nfFj2x|h*aENm)tVjIX zBVAJJJ`qQ1(f!HA}>5iFr9AI=U8EBmZ=^qs77`pbP6PQagx-W zZ-Ug5UixvHT+h}_sb>?MYVY%sl9DCA&S$6YCODOCe(kIl1RAtjd>Q4W4jA&Bat{qE zq%qDgG*fvgmHtv4@+1AU=BpW~vF)o*&nc^`Z=1_|`b|1{tqvumK3>e$aX|)&bF3{k z14X@G?r!YtiCLagwv$eo-8L*tl&Igk00GB1-zFC;3%S)Z^3*WH;!|(??#flcLwph; z@(6*mzi~XY;bW`8q4wU;BQZ*E8De=-ab2G@L<%vDsb$6kxyhVNGMD0(5HAfLyKy9> zoHTeRC79OT71I=3$)pG!Twp$g=4c(EYn1p_$`IuK2yV#ZYCaYeS;JPr>U1aENkd=Q zhKegNEZ z<7W*`%@XYMv*wBe#>A+P8%xJH`N zlPeAxpgqMwI^yLYY~>=EzRn9~as>ws#$SN6!Rd`fPy4gS-{0=j`<}Wwrzh(Agyiib z2-4AbDsvcgaozqe4vjR$n5su%QQF>%K>lpK^9 z{%W|M8ZUy*DcCR%#j^0F6-gGXefqA2+g!Lb>I^C)Ce!nrofl#m#%MHy5M<7$=Nry=Z#L{!rRcA*RP2sY8O&va&PL)p(U(-2L7A<&hX`FxE%OO;_YlLn&w3l7Lh0;71F znj8BUwgc0T2hcLp_RkJ}2R-QGq|9f0M*d^`t-W~n#3NgX>NsVjFHmk`LIecD_ zE+^#Zoj!X^X1`={PVCRVcBt3R-!4!1Hx2eXlduqMw?{<|(haUS!RL!e=RF?tsogTo z|EzO#@uf%&_!5+;gq_fvwfW!*rh^V1=cC2-r3m#|0(^k~lybc(g-F=`6CnaABzxHt zMzAQ+=f_eGA)Jx85W?ZQ%z^64Ju`x{$vB!4rFG4M zRTCW^$11wiOls}%vzTUK=sqDtsdZ#_AIO9hgM^$hmlI}GQgp#6!lq2wK98y66BT_k z%}>eD?-NR#9@hXrGC@3&I2Yq;f|vV#D>2JQR>Tn@(UYJgrHvE!cyGxE-b4-5bxApXNS|FOg>AlQoX0t*2A z-hMBp$s0RZ=vwNSnA=g?|DjS@TN;H(OA38~!uY*%_C-XPUlsrW`cMG_5Fj6WDANiN z000CaEiNwr4h9MXkBo?jh)Y6BjEhW8h($%i_?__^8xtKZ3oj$545x?+m$)IDjD-v{ zjtB>ZI2WxrFTFf3wUP*r1IUZ$YHC{<= z5d|YLH799xQyDF5F&#HG0}Dk1XMGiZJym&oO>Q%N2~#~~7ef&zGetK$6%%6 z8M;2XdVZy*zS)++`G&zY7SYZ25yc+Sg--Dewu!y&*^_=6On$nY!KQ-Ywh}>(iZPag z3HGA#?h5{{27&JOxh`V4o-$EBnkl|2k$!rizHW&@`Uyd<>GAgEK2k*iO3h)4?a^xa z;kv~!#)YYl4e2}3go{a@={qY)oDf%-Rx+6KJT}95*`R0pdb{o}}b9HW873PO6 zuE$*-S3MqYbFKja0fCW;p|PpaQIUy1LJ|`by`!=MV)K3CO9N9XL*nxzQgXx7Dgx5# zW76`XGpa(eo04)$fe+EWXwQ;X}z0%1r&Ai2Gn;19TG!)Rck>&Ea$9HfJC;j2XX@JevpRP&x^@b?CiA=3 zih37|de&QeN1KKg^LqA*2M)@H4l72EY9>xPW_JcEy$9+8`>WFzTLVX$i+eiTciVke zxLH6Qnf9F4}@jD*}wM8B;Dy)7hcPquDPwZCtLzwIWxAD8y@ z^mmWUj7^V^&aBLj^{>thuCK2TE*;LU?@w-Dt?r*p?_Mt*-mV|tEuB6bEf4Om&Hmh7 zemn2EJz0Cd8a+Bb**(2JySckL+kbsHzrDS=xqrHSdVT(N_55`A_V)JiBD}x9YYHOZ z0RW#HMfiE-ombA%J*1I@P`V=S)8)@?F%ZL9{SJW9oDwUEz~P~72W~<|)xp8x*yXk1 zfeDY`IZ@(TXX)Yi^5w;+`esE1C}KjJg?)E%PsVr|_?OboC(PAA+4uhbSetC3og^p-mM;syNCJ1z4*)>i&PSu|t8+it%U~dVyDC5epkhXc%EYabX6IZr z1U$8_X-O@fV?@r{g22d|B3B?JMo>LDkc_0V~lKV__7mQpWqLYgeM!E}JmrNJs z1H^}&m&AuV6`ofoEvzb+BNYMZLkHNyJZy)g>EZ4M&hvE~BfyG|==qpc!78K~I0{O! zXV&WB%tUqRdA@PC=sps==5jb--lc=K8FG`=K**9K5CPUsTgXKc7i}GceeWvVlm@@= zXQ_4|V796KLh{I4rD;xpj`9~M5oBS}=|r4M^|!?%ylxXyQgINzY^ePag8J#r{QJbs zI`J(0Hn;w`fVyU>ZIPNMBI;&Z^gVA>lSEnT7)gp~<$Tmbal6nQI9}7c`Q9p~1c|Fe zK?XPHp5SI9tZ!L}Ai;YQ*zwr;Ki7u~O0}<2NjStxHrEdc_rBs1yP&5i@-2j@PYwz{dj);=S+p*`SX66TH zr)1M_Thl@UfbN&%C$s5S4n~JpX5dHviWEfmq5Rq~*Uod8o{_nGO^CB&^zgDrhH9fX zrTEhCd{mHPLdIT%m7NXyt3z)YXBus9tw;1>2-J7(imRKwu;Atp#jyJ>K;9Wrr>AG6 zXTc9`mO|+rwS|Qww_N$AK$mxO#T-2&PX6x&vF}cgV4hMAizXecM}1%4oM?n?v)L}azR_CWT76u1Tm4k>)1T~N z~%=&tq2F$qjm6+ zZ0dg9dFT#aRS&JAPtV#N5FSekq-|XTa`bz~UjS5n?5Qrj60G(mG*B-06U+5tve8!r zZJ10g?q0B3MK?gz;7u|4sBCyxQh;_2jDwr^TE44iA=lgJ4LPC$Vr-p|m_cKThJXj~ zEdkMk*f_*S1pZq&JBTjzisShw66Njn01}0bod4Vv_6*0*%QIzv4W^r45VCImN{{2*>L#738W>4Nb;I9_;Qe$FG_BWACoPatTD zUIUeg-2yfRo;oOhI+p_S0gwQa1P5wboKt~J>^2D_=u;4@GE(v$Z6v;1W^^Z96#(_G zFpLf_#r9y8xvF~;g)y zN}I;PlxwyBvZ)|%LY?W04I|~nt@9!xWPVkqe(RJtGo@joLmf;Noak*%@-6Z zg8E_Kz;d7kltRM*6e$hXX8qJT;I47t({Jdhy)pV?2TuiepeCc_!9?ZB4+ynO;&Cec z$~Qx&iQk5ThvLR`XNK~BfCbxC18h{P8mbgA&GyU2Nu5X>!PekTahR73EyqnGEp`^l z>QS^wxF3RPa-4NJ!C4<2U0b@ssQcjQWe*vp#6*V1ReqF^rAa=;7E{Q2n9oM6gu zh`S8S%|u8d7Tn!%biR!U{W_+C_Rl>A=jJs&JjEwSV?A`~nWM5}o2Z61>vE`P2g`E{ zqYg!6M)g9iWaW@EZ=t(Z2hmSYA1yK`P3x`L;~O%-Xm$PO9dDu706GnEnj;$1!Z$#j z5Tnwn=B?)vXCJG`>R!-PO%;^qVM2~v4zzcQYUY5P1rMLK~?MHG8!%buGJ^AQfrkdZTaJ#{I#eW zKM4TfblE$~h869-U!;QCM0%64@2d$$3oKS{V?BX&=yYwMayRjq%So0}3LK=#-wq=0 z-Asl67!Rb@QHC3yc)nM%B1Hr>~Q z&5_(&xQ64jU-z6M0=fpHWafVAWIiZS?Zv1_cBWY^INng)ZBZhQn~u+~=yi zD+_zMZx$%E1s4;GZ{{NbOm9~WxjJF-Uw$c^t)j@an#21cj<AhVN6~k&i65h>2@p+nEa6YE0+^5Q7I2iIYUSQ2q`T{&+bk;PKg8u(nx7^b7AY z&76I4|DL;pl|Atwg^l0n&uSWj+&bEb+*cFskasO@I>_H6;{T3Z62!d&^F9+ z)?@D=nd_%kz21X?V8&FGv@g?d>KU?6TufT*w%c0x#{@+29=WN@_WPGXzh7N43co&I z%T;7#fbRQ~tu(5yWbHRx3zjhGOOoY7y)Ums0rI%|DY&&%v?7XLpGL(LOa1S5na2G0m%y# z43WLeb!p2-N{0mWj||b@Re>OXj0y<>c^*m;NkM809ZM5K1G|6KgOtZgnD)}Z1>Ca+ zOmE1hD!|*+klunG1IfGWeI6pn&fHq-s0l$#Law?Q?ti1RVZ%(+OdO4-G#i(RGHZkXrs3MGGV-I$wf@_W*ak-&ZKnc`rXn3Jy~dHFZo<+IJ7M6WN} z(&8-Vd%6-drWd+t?D$BGqHU5@<40~4Ai!aP1`}##(ETv>d}+wenCCsf{7_ElaHyO> zh}G2G;w8Tz!g{Rpd7~(#Q{i9~v^5ry@a>3GX3}kq&by$-ab-t}mt9>Q4{0a%`bVl= z<#~?vjXtpxEQazux~(O90?E#oHkA`_-C-+1cX0j=tKQauzx2& z{4>s9yZ1W*`JXs{B}Du)(qCKj{cn)|ognegIKMNde~Rtj;Qa2{|Bw;>cTtM|2IWrz z#XqC`wND#=gYxf$ihsuWYoAa)!jS)b%6}3p{s-j`Px0@SWWN)|e~S1A%AbUbKZfuh zcK^O~_`A;RPx1Qlm#VY>H2n9p_V1O&KV<;*uj`C|SpHMm`%grq!*E10wTR6C`AMWq=WR{t09z71O%ja z0tpZS>4ZoNB_!P7@q6z%zjMwT_r5XSA8(ACF&M19_F8N2x#pZ}&iR>hM`&xQQd2Nf zkdTm2t37+7OG0v)mxScf>J>6#PijONEAihY4_#GdlB!|W4dTV$_Dau{NJwg9DbK7( ziPu+OKQs0qAz|RU_`9U0%lV6hBrr$qiITpr1v=9!mGuRp?PRN=ZGa*Q27{6Mg#WnC z`KTr|)K_`#netpF=Yzi~KZRbOGiNY1VlYLywI{iOj?Ok8%DauEslV_U@qDg3-;}-8 zT%A@bWAS3G1@OXa#N^tY(Cf-q?u5R%OGR<<|GF}-bZ5@(Kb`mfZ|DE_8Bwi%SQ~c6oEAI@!)EC#1RAi*KxpTJ?ah3$hi;l_rx9AeX?h^%zgyhrJi}o99 zZ3Y#df4eFCyTe8sd?8MMCZF9(Ov$5Vx#)0WprYtkZW84^`VSNS{c8WdOwl+g&&PDqX_eHxuTB(Ugrt}iABgeZVCr2=mBV7{)frLO{iKgxKN$92-1+?y6a@WX%f3cY-_tx^=FRY zZ(c0!bnAkqTXYxg?|=Vmn@FpV+!5u)%@V8oyu6evy*Y9$nKKt1+F$;mL;k;et&3MI zd5g?C>94GxHrYu>5vtN#e?D&bwIOnI;u1+k-#;s$nJ(V$#D)+#(xP;uYgKN?P6S_y zQa~^I%+DGgcxHwVV;vb3@Kfr3hUAa!MGn!-5};bsUz3axjwB>?WPb>J(_Lu(o<903 zQ;Mhiesa*~sGRd@9%kzP=d>6PadtnHTgufMbOJ-`;zaj;)irO#)=N|o&}X*ydC;-E z^m*S1E%Bvnt`bG&4iyE-Pco)BuW3}ltzSXss$0$OKJAH7If@dzAf7o>30^}i>vBV7 z!`Q0p_rcz|Z7z<=#0JS3Kg{F6R_W(vKeOk)9dY=d&4SOt;n~|yMFM+RT78*G-d6l( zHA_g{FGo@yk{WJto7I~f`fjj+wjCJiJnkGn&Z64L6bt^83VtEx=9jOuAx^N62JPa& zxa~p?*rG=YOksJ){oZQjYma1bo$kW)%U=0w{2u`+i`~%BLEoR3rC;_xt~zRj&CkFr z_Rz7#mq@-dU$FI|7_a4}ugt?%Jein~9opfhezebw8sTXENU`&I%aP=Hq^@q(i|&>c zMH;Gp`8dAg2vn8#kpK4MbK^u~4FwZh^c?sI4>BEYs!K`tJZBL=!)ZC>S9D;jg1B!& zzI#zg<0K?D)PMAibWDw!#94Sh`*b|$adPmE^XYSM_?$%FIpNSPaA00y11xQ-R(Y&-uxND7G zk>+mONhPN7af~AJuyMs(T14!IL3sbev!9faXhzv>@LL%8#{oC67RrjB}6}iC-|4DC=*{MsqQL zb8K%O3X^_a-T}|zUuGWSp%aMtA4QuX3$;Iv1_zo?@jO{R^)zRPxMbPwooS>m<#|AE z3n)+5mNGV7J!)Is;+v|fX}cUN zGe2|y2w@&dj!x731V*G9%RcGt5N~0slOw5FeRpwEDUz*}u74wYE1BF%^KgN@iJ~ri z*ko1lvHPSW`V0#6St$PXFp?+lw(R$O9!>^Ufzh^R%oF%>vaDIPs83VEFs!H%vn>$N zlokuVMLHKZ`(Y2*Zn}8LTig3i6{Zzp-<;Jjw=wI5>WaeY4`!1o~yMC`Ibe)dRK1FAS4;>=g2}5o;x6@|#BpFh6$L|x&{oC1hBS8<^yssuFPf>&x>Aw*{E=VjGS*i0$fyYj}=qZ_sZ5WwK zk5y6dsRM2yoWbIq%&&EE(C4@~CLQBfE;dq6g?)RXV+X%w^eTEy+?~jkqKcu4L6l19 zvHQahBR6Yh$hCqdhkUp1p~9KsW_7b6_`v}fu5OAwjWMYhi=9OCk7W3}3*_*9i%ElZmm(5v-~71wE9d97BD*!iPlw=y_RLHDej3~w(ZsQJA|!l$nJvAeP$R)j68lDYL<{U z&YrrLzkcp3qOQKehQvnl9-A|eu5#ee9{DfLFEwI87;;7Ld-M*f9W5)em3OWvuFrg# zd!0r?iloLpfyYrsz4K`2qhSo*bbyf}?dvg%Jq!CzHWYb}V0T7Zcz-CYENOwyxlPgQ z?}tnm2Qt}i(UG3&-3`e*n7s}F3Fu03_Tm)XAPQ7>W_Xhn zPZlP7dtI#?3*-1?RD6ZH|8IQA_Z&eh>w6)2?s_;F>P<1Kh(}8-IN{#CTW*F8It}z& ziL0(g!6{g@yAH)FpD#d7bkEx5{T+j>5 zt}Egd=tt|PBZxP((s8ZM^|t#IohciVMLl(}=;qechNENL++;ZF2$}x((dpomPpTQy zRbNomSl_OLncg-RfdTSG8WknqL?~|kYt9o;+U^V>y#Vb#VD7pX;(vD%67%UAh+FCe zTgBNaqjI89AtyCG?Ik@o$O7Gn4Q$j^(4ejUq7QPkzD(lG{>K+wy>RU+{8)pu!e6~M zjWIux?Tm&UQA_)DGb*^<3PrJ!E`G^-^iUAD#~yaRSH(lt$|LyZVtdi2fnm^WdQxOq zG0StL=l9*UV|)PHn--P=nr&60x;dw>Gm$PP2b4-4Mz5*r{g_jB-3&i+is;z^0HpkM`bx28Y@?6PR9y3QfdnJc-(QiSZtn4wUV`6xm3BWJ?X?41&+Z8+5u7IG93%OHb>JRG-C)`rtgbTp>+c5;id` z_wl0Ar!kBm_IjaGt+AUSHrG1CrNJ~)+_NrWZ{UO+!@+|-epM4(r*N=xfUxS<;Ul%4C zKLNPg<|}FE6Zs`M?P4t+i_iQ;hF#V{i{PZDe@IYil;fQq5XQ&Q5ec+JtFMf zPDH#w>?!J`E*<}E&DHLD=+TGZ*Y!#pFsWOK&+mnZ-4^4WATqX2cw7JYZCjE!sE?;@ zsDHv^u5~ALzbc~tY|;zpOa0vXwQ<9k>sekyAji`uMX##gyZsdfXTmC>7^GIS;E`x) z7nf_1RFVCn(!{%$)OSfH?6iWTIoE9k}-|jI_GcxHEmk z9Ar7>`)z{n6RL3WJYhY(jrh*-G)qEP;EDo?H%2kYo#yQG?GIqa0QSHPnEOxQ!tr;9 z5;;n!G@|8K;$wg&1g*LSB)Slte(+`sS_XRLBr8!~^%#PFNX>X|y<(p#9GNbuJT>*| zKhyO8CEu`Uhh&%lei>-%rs)+JLQq@!vC^C&y&TV+P}EY$9$?GLwVfZ!BaZi#EjgL# zfE)_vObrV?rVRU=YO$M?xGEmidAFtkmbl|oqB!Qz{i9hG#}p*fx9t?ij$gE_naz(- zr@`)0R0Snxc%LxtoW3s>diA5C_ujo(vd2_gqPos`c%TK%GuLOZ}JzP6B+D%32 zxYczjL`*nNDPr8X?UHzMb7}16)yQD%$lc3(kc_jY7;Yr;ud zHbf5*wQT#Tpl?+zhlZjTzF2Yf+QY>bZnSRZ>Brcf+O2ijdwTnU3CmX2-gdaGh3#2y zOFIYcSLnarN>cuby^MqgO$bdio&hnikwfP8@6o0Q$nX-1QcXs_;S^Z#JvbMF-j1;4` z1&OLk=R!WMoBq!mQPdetgDIs%@5F^59@cF0_ub1m=>B3*e?GMDyC-|?S1%^N^y>2S z11{G=dAH*q7Iw}*(IQW6<<=*zXo%bFB(!OzW%ETT3SzCMm$RGPk6Jed3}8vBCz3_X zriCxqSCSlc{GC%aS-jQ;c8W@}r-jGR$*>kbozoi3tECXk$uj2w49K`R^9^~G#F^nj zMu@RhUxA7QHI5d zx1vWa7J`O;JtF={@);*U>IkCzhuL9?Ji-;N+j`0*ZR}J$I2ejU?Y>v`Dxm^?kqJeV zVo#x}8U4Q;RD z*?08(x@#RDNG*c@mn9eb9glzR;=}&UCC1yuD7RK5@Br|Pu{c6$%wF#%F&=uf|4(TD z=2(qZvGr(ww!7@yXxu9~v^k8oz3Ou*~5* zvbOPX@sjl7yKK&)OC)bsLoVEPX);?oq7OnM5xx<3C+*iLxvQDYgCaSsxU}_2O2o#J zrunHywtb+DR*?{1P?QLyNO1fYz<_vi(Eox-E&^ua&*rZ`@!!Tk``^Utx6J>9=ERHN z*u%f#5Rl&gX5a-#G5P<5U?kdF{zY8%5%mR4S3)k@Bx!H|(D&woKH^RE1(NcwH+BF0 zO=9q3>-aCwiS4U@KjL4fEC2hO7t_`Lb$Z}`7$HrBUUDpEPYRqPInm@KB|O*544Urq zUb&+`V&Ys`A9;ZmmOzYzZYY-|g()c!QAB>maxUd7^>r76LbX?3)jzqCYrsH8O2ik- z%qo(v+?nkEH;^$YYU<{lP!r=@bQf#9sWrJ9sx3en5=_J-UkDp$gkE>DwbCYD12iOGeY;}0Fj=a{0?lzcgrV@mhnrIapmQAR z$QrhiYN= zE34Ij0tY0tBx4c)3Xacon&J_8;08!bT(Q4PMkOYbvC z?-ffJ>{tY#UufDRL;uR*47-%PQr~>|<)ON>Mq?%7k?hci0-#&zo}G4`Q~05P>l;&3 z@4(LiS}Vq4bejor-qC5FWksGX%6%}XtZOlN;D5oBy6(Dq#z7N{RG?K9`G9|O&h4Jl z7n>2vT<=P$-lbhFj7=#%tq@Xv%9|K`2WZIT{-qc+)Z|>=Tqz{Ry$fCUb%J3H^Cj-Z zLt6{$+yx{F<;qDJ|E#U{(#bJ?^D2Ft$xUYR0RNlP!a{NND%_kx&nB== zTb()j#Zyz&{t~=c8*O-E8b%imi3W||Dj1@?l{i%_SWO?pej$i1wJvDVFHMwRgt+^8 z1bsg!l4{@1fh;h~+d!cI^%3BnC(p zX3*srn|8uS_>*D`kIT|_?rymOV+V$#j%SL1(jG;7@iqX+Qg3IB)%bC_@X8mSrv`2& zC}8_AJq#(VPWq(?vi}uP40Sl`!mbmLK_mgArJR!ovdKiAE4 z)HT&tm5W7OceD4v>1%o8OR4&XztjNSORIDp<72!YfZa=}WvaWDEu31G>Yyd(g~J;4 zx#L?C1!59X$*LP(AAuQ5@bn}Olxy8`vIJc6XvWFZccDb_6giG?S6B8k`3>~f*LC(a zOTKWj(ux=2$LdAJFj(Rx952*)zT*hP_V&*1bvJ~+Gt&)7 z(2Rr%WKI~+zF2nk3I$%>cVO+ppE?3{nTnD#Fi;eNF1gafOfjJ!QtZeq zE`ZuI@weJgE;ZX~NMc&O8nTvrP@1vrU-wp~rRp#s-X&1qC%z(j(On~*{6+X7s%Ma( zMY*@Ei+C-l-~J(68exx1njXFrC*d|T6Y6&WL)bs%taw}}v5V#w5Rt3W)rbMgwH~Sh z6Zl&VKL1X15XEGPv9c5r_V79MII2KJtu9P}{a0v|8KQHRC?E_g)P;`*_YzIlD;6N6 zNCtmX{eeD2fyyi$R;gszmqa_FLTHzeoWN#HO5*;-?p+*$g&Cp zu4C`R7rnylp(ffzZQlyfPjw#|s;?k;JgK^{sSy;h^?a3<+~w6=@DI;qt0!V&3*MR_ zm)9(AvG(@Lw#0PqKi-(c{t9$b%kEdRW^qeNO0v7|vYpWLXvHD>%JZt|^eeV&rZcXG zszHVbMgc?4%oGD3jVizmcEC!*?u}h3gs8f6fNq+uM{H%iESL%+uaLrTDHo)1acJin zBy+puOVSH_nrJQ+2yyR{P85*p;_4l^`Zo1ui;{oFRS2n-fRY4#`Sms?#*>j8hQ28> zi9P*P?{f*<@>icF)N`?OCMHa!8>A$$ka0O$TkIHpYe=t%IeuW$rrs+}b$_`Ios>*p zW`^^uSXzS-pfX*x3F?RCg=?^SQQ*fyNXv?iPi+_2NOq#?P+JJC$2VI~Co+-6$(^R( z*P~#OGR&5gq+e7I2(1$Zh%qGf_dl0mEJ!xXPUh(=*)*En{RnroEv#3;EqT@doI!{_ z6CckN1e&D(!(0g~mdeuCR$9s(Y9()?B1mcai%A7yNUwBG#>>Uma}C;W90WAwsMpCk z;`tgBg<&4N@ddk3Slv^usK&`TXsU!lf3dqhle614SZJp_~tSiV`N-ML0b zN1#&-zaori73-f#HAPM9BRVsRhyH1?h)1ELDlD078UcMsHbEefA+#i9*s z^dl;suWU}wn^AsMpW^68+{8BAG-g}5g86~)yKy0-y}BK7R2h3L z>LN?(NQ(%QafQCU?#tb}CoYx`m)5jR%yY+M0KB9Ke~My>r@CKFt1!7Hh+>H_ZqC5g z0sYOZ$|k0hfJ}f|M_qLK2Z5H{9QW}Vu6n-bjw_#Cf*y8mO+X7XDL2cpy|Ly9Z#~^6 zA$jQH5Oc1(rc-rN_H@x|iLId`(db9gYi(DS>QZ{d_X}}DEh()Eoz&R*gtGs-PTAN$ ze<;}S(v&TU%z$A~-^oF6R5yUAj`3J0jn9dy1*GC?b^CV}ppM7^wl0V}G;kL!F#ydU7K=P_AV z&O!8ky6gJPAVvK`gYHSDnl3>e3}1-4q`op?u7wt`7wi|B!LqmT`oJL%d%jO*?9w3P z4~P^90zCe@?Q9t6k`9|slp6M?>OwQy1HYhm+YoJy<50uARftI9N>nVcG!QBRtQb!; zFf7sS?FfF7w&csCW-DEsNz|Xup7Uib>K`nfg&d=z(|Nhfm%VB4_OWu6nl(Y&C*7mV z&DdqLcK1hmxZCCv^<52!GFE)0dgBdIzD&Fi?}c7hpUhKV85Qn`F4*d|jyTUXsa!uGf)Z5IU)sg5PqK~ z+q9Dbz-uq~Ej31tAkE5!Y#e=?nljP}{Zfz3`cCG?6}U>r>$Y2BEK{VgYSy2)S)_F$ z>NJt@TN5!URr`(nO$+g>b+6~T_HPeZr+a24H5+^`Pd3LB{ZWH>&0d6aHJWFA-WyqI z<-DB7tqDXx_*`)Z695*dLGh~aV3HuW_mQ6BGUaE2!NM<)Qz@5Ug^=UB4?^z?8NeEP zWr~Xllu7h7(+3S{v^U&}|B_4M7%8rm-q$N5Xj_@m*?j9&w?!Bs+V00v>6jrnIPS@c zELo>R%|RMvkAXGV559`%TknyT*P^3??cB?qVa=@rzAl6fffgDcT0B{fy|vrpYT;yz@P56MGiyb%mp;_CKZpxrQumQ5UIT#Z%d?g^h=* zBZb4bhY&Wl>9rqXJrE~!*lvWAt??*pN}*ds#hE(NzAkY0tyV{By(;>J3|^xCXCRDEW83UgpMN0 zwb@XsLSc=N6>`$f*=O7@JsF^gK05XrowH`a_MW~9>W#KbbO!n*ew+?VS zq|x*d7{o;Vn_mU_Y)Prjr5h)(!r+2bfZlOJPqM9)$8QkziO z;(V(%!vn*cE)I918vqVUFH9kdYRMvI1uCVryu}4jhYAS>NA&2elHvQK+UfdQaKyz)nA&oVH*fT2E!H8hUPxisaV=q(bfq3@VoZ^^o!V`?VRBbiYIoTRJu$**+~)g; z$FT({7~k)(bK>gdNHtynQqPB|QN+e-n>!V=Wfy>FQhP^ORw7u=lg*BDx6jHB9w2tF z;+&D{LzM2utxnFonJ|7HR`IDMsccR)KmHAXM-@QLnvLiq=$Y1=pFo7b!)gc)3)B8; zPej#ez0d}$^KflFG|cfZKsTV^4P3qOB6QP!AAf1q<;zfH!WXI!c;O|oryDnjCpKr2 z81Er5NK?LITk(s&>H(ICK9{DCc$6qR{to#1H5Z-D)Yc#G$;lJrM1A$&abKDmM__Dv z{3m(=1BrqsL=BDq9YrRVBI=zR;ze&1XZbrlrXa4tYkqpYWjgve1uzM_2rVboBZJU2 z-}juuE}rdAcM)Kk=$u;e<|;*;r}zg-xU%nVO{`>s}G&nw_DAk?| z5}AG_*YhI$a-hHB@jLP?3cQu5*!nvlufL|u#LGjr^5P;oFY&tG|L9Mt0a>WnA1I*i zQZCh>S_YR#yqAfPA@O&c<^K--|Jx2EI{Aq)E0dG};;T+fI7{6~v~ir~m~xg-F>O!p zwMS|^zLhywmlD!QwB3Gs?YdnZ)FU}0CnKGzz0W(f#7JNw_D^Oisjc55nIsnC==TzX zQ%Xw3N1$LL#wAAtdAtOv)az@0U7qA2%FuW5KSQFpKg8xo{6(@ELWyih{HQ8PiTOW|U;w{8{hJ6z`4NGy z|K=_J(~z;hcPC0Os83f?+x$PH{(onKERTyx9<}QDka6Y4l4!$-I3pWnh^~;}8Ob5B z)`et`SR?hD2c4ZX+SxC)Np6q)GX%VtO+|9}be<_ORN=4RSlWNjgS`Ju9{eZjcPY;~ zNlK(QhjTa&Zjd-J{_pePKeOqqQ}G7LW^}VS@74b(3E>&9C*L8Ph*d}f@*pJjPPQVG zp?84BF(#Zg(AYWXh-D|XI`+*uI4JN{b2CYZZi-xeO@d-LK-S6dD5b&G{ru#mavxgA z)+i+b=hhn5=r@I-#*_~_{dH1c4}}D2V7=c=DR%X ze!ky7WZTdX8q_8|oWivbm{W|~XUV6Xm?Ay2(~duFB&!QtI3%3S`@o0h04Z3Hpdfpf ziwC~!r496B8|Y#@>CSIITs?v^hI#3&5Q_h{$@=@XV`g# zwa-xkkU1O;i^dJ4H#7#Vx!gG$!O@`9^4!@FCU zk;aclMAE8RHw|%6aw$GTykP*{aRbCGe@MX;Cl-$Kjl`{ZJRWd$ySmw4Z;me=P(gjo zsbKKLd$|QAB0=HNk!uJ$7Q*OZ`;IRM#7RM|-;i%$)og8G&bl{xp5^H1mxo;`T1W-` z!Vj&58ew5KmsQ&^p&jB|WSzkvmgg-|%z9(D5EE3netOF~=$Vwq`xTq8A3s~g|KqM4 zhgl|gZ&~|U!&Dy9-Y#C$I0|gtkm<&jaX>+9K&jV? zmZG;!NP1x@J8ffZE%0PlOs2F@(F+9)77UCb_lV&rhGBGUr$OYJfWkB*%h_>2wfM)aO{cE1eHFw5?(hjtSgeG&`Po)obk>->D?g_RQ)?^xnNF z+Y&S91R&BDNj<*?xORXC@aNxj5uGmQY7caMHj5Tors%}jdQ=_SI4m>6~4QnRSKFMat&c&3}~(|Rl8_V;7+~k6S&@7 zL)-58S=*ObR9ErTQYpAZak@dYRZAq<9Vdj2wEeKQv%byvMI?*)X9#6soak8I!7oU8 z;E&o@ghQ~^bfz(-Hx%_o-pygK;QO6LDfaarHzEl&(DvM`ow@T?U2 zFxYSXr3$;BQI*7QNLOXv8eF*FIPQFZ__K|6=hk5jh;sj{9}jv3yx&<9Fa20paf>7y zyBT&GqPW(4ig2oS_F}n4|fdm&%2wD3(MaOKeYy#N|b_XsnW;<9-l2HrGs8p7qcL$ zZ$Evn40wF-L@laz>S#9d9YMGBM5LF{Q> Y2}_bwIWzXJBov*5HDGatQ2tEUJ*rKkRJ}uf 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
ZfxNh$GLRaWqs8AWR{3;h(P>yuUQOhNMzi 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 J@N+k#{|8Lz`u+d_ From 9792e93bae020acaa00c928c95942056c161e856 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 16:54:06 +0800 Subject: [PATCH 24/32] Update image to svg format. --- README.md | 2 +- docs/plantuml/images/cellular_components.odg | Bin 13613 -> 0 bytes docs/plantuml/images/cellular_components.svg | 166 +++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) delete mode 100644 docs/plantuml/images/cellular_components.odg create mode 100644 docs/plantuml/images/cellular_components.svg diff --git a/README.md b/README.md index 48724695..b8a63af0 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.odg b/docs/plantuml/images/cellular_components.odg deleted file mode 100644 index c23648c6c18751ef986158d255ee74d78c8e8234..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13613 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Comm Interface + + + + + + + + + + + + + + + + Application + + + + + + FreeRTOS Cellular Interface API request + + + + + + + + + + + + + + + + + + + + + + + FreeRTOS-Cellular-Interface library + + + + + + + + + + + + + + + + Cellular Module implementation + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 6ead2bba53c09decae816fd079b8e1cabc432193 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 16:56:55 +0800 Subject: [PATCH 25/32] Update image to png format. --- README.md | 2 +- docs/plantuml/images/cellular_components.png | Bin 0 -> 32011 bytes docs/plantuml/images/cellular_components.svg | 166 ------------------- 3 files changed, 1 insertion(+), 167 deletions(-) create mode 100644 docs/plantuml/images/cellular_components.png delete mode 100644 docs/plantuml/images/cellular_components.svg diff --git a/README.md b/README.md index b8a63af0..f40b3158 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.png b/docs/plantuml/images/cellular_components.png new file mode 100644 index 0000000000000000000000000000000000000000..328fdbd4b727192c7375e69eda5c0054ad535d05 GIT binary patch literal 32011 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 Y2}_bwIWzXJBov*5HDGatQ2tEUJ*rKkRJ}uf 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
ZfxNh$GLRaWqs8AWR{3;h(P>yuUQOhNMzi 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 J@N+k#{|8Lz`u+d_ literal 0 HcmV?d00001 diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg deleted file mode 100644 index 368d5397..00000000 --- a/docs/plantuml/images/cellular_components.svg +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Comm Interface - - - - - - - - - - - - - - - - Application - - - - - - FreeRTOS Cellular Interface API request - - - - - - - - - - - - - - - - - - - - - - - FreeRTOS-Cellular-Interface library - - - - - - - - - - - - - - - - Cellular Module implementation - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 7c42bafbf19f7649c3e565dc0eaf14a4c7d4fb80 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 18:31:08 +0800 Subject: [PATCH 26/32] Try SVG format --- README.md | 2 +- docs/plantuml/images/cellular_components.png | Bin 32011 -> 0 bytes docs/plantuml/images/cellular_components.svg | 166 +++++++++++++++++++ 3 files changed, 167 insertions(+), 1 deletion(-) delete mode 100644 docs/plantuml/images/cellular_components.png create mode 100644 docs/plantuml/images/cellular_components.svg diff --git a/README.md b/README.md index f40b3158..b8a63af0 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.png b/docs/plantuml/images/cellular_components.png deleted file mode 100644 index 328fdbd4b727192c7375e69eda5c0054ad535d05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32011 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 Y2}_bwIWzXJBov*5HDGatQ2tEUJ*rKkRJ}uf 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
ZfxNh$GLRaWqs8AWR{3;h(P>yuUQOhNMzi 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 J@N+k#{|8Lz`u+d_ diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg new file mode 100644 index 00000000..368d5397 --- /dev/null +++ b/docs/plantuml/images/cellular_components.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Comm Interface + + + + + + + + + + + + + + + + Application + + + + + + FreeRTOS Cellular Interface API request + + + + + + + + + + + + + + + + + + + + + + + FreeRTOS-Cellular-Interface library + + + + + + + + + + + + + + + + Cellular Module implementation + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0249cae98ee6c834fc56f736dc5cf1b9bf74d7be Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 18:34:21 +0800 Subject: [PATCH 27/32] Update image. --- docs/plantuml/images/cellular_components.svg | 14379 ++++++++++++++++- 1 file changed, 14281 insertions(+), 98 deletions(-) diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg index 368d5397..5b945109 100644 --- a/docs/plantuml/images/cellular_components.svg +++ b/docs/plantuml/images/cellular_components.svg @@ -1,42 +1,98 @@ - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + - - - - - - - - - - - + + + @@ -69,98 +125,14225 @@ - - - - - - - - - - - - - - - Comm Interface - - - - - - - - - - - - - - - - Application - + + + + + - - - - FreeRTOS Cellular Interface API request + + + - - - - - - + + + + + 10/12/22 + - - - - - - - - - - - - + + + - - FreeRTOS-Cellular-Interface library - - - - - - - - - - - - + + + + <number> - - Cellular Module implementation - - - - - + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + Comm Interface + + + + + + + + + + + + + + + + Application + + + + + + FreeRTOS Cellular Interface APIs request + + + + + + + + + + + + + + + + + + + + + + + FreeRTOS-Cellular-Interface library + + + + + + + + + + + + + + + + Cellular Module implementation + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b96a271f7bf2136a6832181e836c0ad6d3207bf0 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 18:43:27 +0800 Subject: [PATCH 28/32] Update image. --- docs/plantuml/images/cellular_components.svg | 14387 +---------------- 1 file changed, 42 insertions(+), 14345 deletions(-) diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg index 5b945109..bccff083 100644 --- a/docs/plantuml/images/cellular_components.svg +++ b/docs/plantuml/images/cellular_components.svg @@ -1,14349 +1,46 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10/12/22 - - - - - - - - - - - <number> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Comm Interface - - - - - - - - - - - - - - - - Application - - - - - - FreeRTOS Cellular Interface APIs request - - - - - - - - - - - - - - - - - - - - - - - FreeRTOS-Cellular-Interface library - - - - - - - - - - - - - - - - Cellular Module implementation - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + Comm InterfaceComm Interface + + + ApplicationApplication + FreeRTOS Cellular Interface APIs request + + + + FreeRTOS-FreeRTOS-Cellular-InterfaceCellular-Interface librarylibrary + + + Cellular ModuleCellular Module implementationimplementation + + + - - - \ No newline at end of file From d5768e16ce74c115e7ce90a9a01060d266e811a1 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 18:51:12 +0800 Subject: [PATCH 29/32] Update image. --- docs/plantuml/images/cellular_components.svg | 45 ++++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg index bccff083..68e0bae9 100644 --- a/docs/plantuml/images/cellular_components.svg +++ b/docs/plantuml/images/cellular_components.svg @@ -1,18 +1,18 @@  - + - + - + - + @@ -22,25 +22,24 @@ - - - - - Comm InterfaceComm Interface - - - ApplicationApplication - FreeRTOS Cellular Interface APIs request - - - - FreeRTOS-FreeRTOS-Cellular-InterfaceCellular-Interface librarylibrary - - - Cellular ModuleCellular Module implementationimplementation - - - + + + + Comm InterfaceComm Interface + + + ApplicationApplication + FreeRTOS Cellular Interface APIs request + + + + FreeRTOS-Cellular-InterfaceFreeRTOS-Cellular-Interface librarylibrary + + + Cellular Module implementationCellular Module implementation + + + \ No newline at end of file From e0d0c66cdf308a55bb1d74f7b5df30c6a6bd59af Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 18:56:12 +0800 Subject: [PATCH 30/32] Update image. --- docs/plantuml/images/cellular_components.svg | 44 ++++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg index 68e0bae9..05566e29 100644 --- a/docs/plantuml/images/cellular_components.svg +++ b/docs/plantuml/images/cellular_components.svg @@ -1,18 +1,18 @@  - + - + - + - + @@ -22,24 +22,24 @@ - - - - Comm InterfaceComm Interface - - - ApplicationApplication - FreeRTOS Cellular Interface APIs request - - - - FreeRTOS-Cellular-InterfaceFreeRTOS-Cellular-Interface librarylibrary - - - Cellular Module implementationCellular Module implementation - - - + + + + Comm InterfaceComm Interface + + + ApplicationApplication + FreeRTOS Cellular Interface APIs request + + + + FreeRTOS-Cellular-FreeRTOS-Cellular-Interface libraryInterface library + + + Cellular ModuleCellular Module implementationimplementation + + + \ No newline at end of file From 4688213a0630e95149b8192d2b7f6032ae932c0e Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 18:57:55 +0800 Subject: [PATCH 31/32] Update image. --- README.md | 2 +- docs/plantuml/images/cellular_components.svg | 60 ++++++++++---------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index b8a63af0..94127364 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project. diff --git a/docs/plantuml/images/cellular_components.svg b/docs/plantuml/images/cellular_components.svg index 05566e29..42f77152 100644 --- a/docs/plantuml/images/cellular_components.svg +++ b/docs/plantuml/images/cellular_components.svg @@ -1,45 +1,43 @@  - + - - - - + + + + - - - - + + + + - + - - + + - - - - Comm InterfaceComm Interface - - - ApplicationApplication - FreeRTOS Cellular Interface APIs request - - - - FreeRTOS-Cellular-FreeRTOS-Cellular-Interface libraryInterface library - - - Cellular ModuleCellular Module implementationimplementation - - - - + + + + Comm InterfaceComm Interface + + + ApplicationApplication + FreeRTOS Cellular Interface APIs request + + + + FreeRTOS-Cellular-FreeRTOS-Cellular-Interface libraryInterface library + + + Cellular ModuleCellular Module implementationimplementation + + \ No newline at end of file From f1b96acca8ceac70a44faa0073da15e157061a70 Mon Sep 17 00:00:00 2001 From: ActoryOu Date: Wed, 12 Oct 2022 19:03:26 +0800 Subject: [PATCH 32/32] Resize. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 94127364..b8a63af0 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ It is recommended that you start by cloning the implementation of one of the exi Once comm interface and cellular module implementation are ready, we can start to integrate FreeRTOS Cellular Interface. The following diagram depicts the relationship of these software components: -


+


Follow these steps to integrate FreeRTOS Cellular Interface into your project: 1. Clone this repository into your project.