[修改] 增加freeRTOS

1. 版本FreeRTOSv202212.01,命名为kernel;
This commit is contained in:
2023-05-06 16:43:01 +00:00
commit a345df017b
20944 changed files with 11094377 additions and 0 deletions

View File

@ -0,0 +1,4 @@
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.

View File

@ -0,0 +1,59 @@
# Contributing Guidelines
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
documentation, we greatly value feedback and contributions from our community.
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
information to effectively respond to your bug report or contribution.
## Reporting Bugs/Feature Requests
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
* A reproducible test case or series of steps
* The version of our code being used
* Any modifications you've made relevant to the bug
* Anything unusual about your environment or deployment
## Contributing via Pull Requests
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
1. You are working against the latest source on the *main* branch.
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
To send us a pull request, please:
1. Fork the repository.
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
3. Ensure local tests pass.
4. Commit to your fork using clear commit messages.
5. Send us a pull request, answering any default questions in the pull request interface.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
## Finding contributions to work on
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.
## Security issue notifications
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
## Licensing
See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Amazon.com, Inc. or its affiliates
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.

View File

@ -0,0 +1,21 @@
# FreeRTOS Cellular Interface Reference Quectel BG96
## Introduction
This repository provides the reference implementation as cellular module ports for [Quectel BG96](https://www.quectel.com/product/lte-bg96-cat-m1-nb1-egprs/). This repository should be used with [FreeRTOS-Cellular-Interface](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface). See [FreeRTOS-Cellular-Interface README](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/blob/main/README.md) for more details.
## Use Case
There is also an use case at [MQTT_Mutual_Auth_Demo_with_BG96](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_BG96) as a demonstration to run BG96 with FreeRTOS Windows Simulator.
## How Does Community Members to Contribute a Cellular Module Port
We provide a repository, [FreeRTOS-Cellular-Interface-Community-Supported-Ports](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports), for community members to contribute their modules. See [How to Contribute a Cellular Module Port](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports#how-to-contribute-a-cellular-module-port) for more details.
## Security
See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
## License
The FreeRTOS Cellular Interface library is distributed under MIT open source license. The code in this repository is licensed under the MIT License. See the [LICENSE](LICENSE) file.

View File

@ -0,0 +1,358 @@
/*
* 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 <stdint.h>
#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;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,106 @@
/*
* 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__ */

View File

@ -0,0 +1,807 @@
/*
* 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 <stdlib.h>
#include <string.h>
#include <limits.h>
#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;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,268 @@
/*
* 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 <stdio.h>
#include <string.h>
#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 );
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,4 @@
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.

View File

@ -0,0 +1,59 @@
# Contributing Guidelines
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
documentation, we greatly value feedback and contributions from our community.
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
information to effectively respond to your bug report or contribution.
## Reporting Bugs/Feature Requests
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
* A reproducible test case or series of steps
* The version of our code being used
* Any modifications you've made relevant to the bug
* Anything unusual about your environment or deployment
## Contributing via Pull Requests
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
1. You are working against the latest source on the *main* branch.
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
To send us a pull request, please:
1. Fork the repository.
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
3. Ensure local tests pass.
4. Commit to your fork using clear commit messages.
5. Send us a pull request, answering any default questions in the pull request interface.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
## Finding contributions to work on
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.
## Security issue notifications
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
## Licensing
See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Amazon.com, Inc. or its affiliates
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.

View File

@ -0,0 +1,21 @@
# FreeRTOS Cellular Interface Reference Sierra Wireless HL7802
## Introduction
This repository provides the reference implementation as cellular module ports for [Sierra Wireless HL7802](https://www.sierrawireless.com/iot-modules/lpwa-modules/hl7802/). This repository should be used with [FreeRTOS-Cellular-Interface](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface). See [FreeRTOS-Cellular-Interface README](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/blob/main/README.md) for more details.
## Use Case
There is also an use case at [MQTT_Mutual_Auth_Demo_with_HL7802](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_HL7802) as a demonstration to run HL7802 with FreeRTOS Windows Simulator.
## How Does Community Members to Contribute a Cellular Module Port
We provide a repository, [FreeRTOS-Cellular-Interface-Community-Supported-Ports](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports), for community members to contribute their modules. See [How to Contribute a Cellular Module Port](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports#how-to-contribute-a-cellular-module-port) for more details.
## Security
See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
## License
The FreeRTOS Cellular Interface library is distributed under MIT open source license. The code in this repository is licensed under the MIT License. See the [LICENSE](LICENSE) file.

View File

@ -0,0 +1,594 @@
/*
* 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 <stdint.h>
#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, <mode>=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;
}

View File

@ -0,0 +1,150 @@
/*
* 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__ */

View File

@ -0,0 +1,349 @@
/*
* 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 <stdlib.h>
#include <string.h>
#include <limits.h>
#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: <session_id>, 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: <session_id>, <tcp_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: <session_id>, <bytes_received>
* 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 );
}
}
}
}
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,269 @@
/*
* 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 <stdio.h>
#include <string.h>
#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 );
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,4 @@
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.

View File

@ -0,0 +1,59 @@
# Contributing Guidelines
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
documentation, we greatly value feedback and contributions from our community.
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
information to effectively respond to your bug report or contribution.
## Reporting Bugs/Feature Requests
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
* A reproducible test case or series of steps
* The version of our code being used
* Any modifications you've made relevant to the bug
* Anything unusual about your environment or deployment
## Contributing via Pull Requests
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
1. You are working against the latest source on the *main* branch.
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
To send us a pull request, please:
1. Fork the repository.
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
3. Ensure local tests pass.
4. Commit to your fork using clear commit messages.
5. Send us a pull request, answering any default questions in the pull request interface.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
## Finding contributions to work on
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.
## Security issue notifications
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
## Licensing
See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Amazon.com, Inc. or its affiliates
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.

View File

@ -0,0 +1,21 @@
# FreeRTOS Cellular Interface Reference U-Blox Sara-R4
## Introduction
This repository provides the reference implementation as cellular module ports for [U-Blox Sara-R4](https://www.u-blox.com/en/product/sara-r4-series). This repository should be used with [FreeRTOS-Cellular-Interface](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface). See [FreeRTOS-Cellular-Interface README](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface/blob/main/README.md) for more details.
## Use Case
There is also an use case at [MQTT_Mutual_Auth_Demo_with_SARA_R4](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Cellular_Interface_Windows_Simulator/MQTT_Mutual_Auth_Demo_with_SARA_R4) as a demonstration to run BG96 with FreeRTOS Windows Simulator.
## How Does Community Members to Contribute a Cellular Module Port
We provide a repository, [FreeRTOS-Cellular-Interface-Community-Supported-Ports](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports), for community members to contribute their modules. See [How to Contribute a Cellular Module Port](https://github.com/FreeRTOS/FreeRTOS-Cellular-Interface-Community-Supported-Ports#how-to-contribute-a-cellular-module-port) for more details.
## Security
See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
## License
The FreeRTOS Cellular Interface library is distributed under MIT open source license. The code in this repository is licensed under the MIT License. See the [LICENSE](LICENSE) file.

View File

@ -0,0 +1,570 @@
/*
* 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 <stdint.h>
#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, &currentMNOProfile );
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;
}

View File

@ -0,0 +1,164 @@
/*
* 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. <async_close> 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 <async_close> flag.
* In <async_close> mode, socket close will be notified via +UUSOCL URC.
* Drawback of <async_close> 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 <Act> 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__ */

View File

@ -0,0 +1,656 @@
/*
* 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 <stdlib.h>
#include <string.h>
#include <limits.h>
#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 <descr> */
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 <descr> 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: <state>[,<param1>] */
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 <state> 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>,<socket_error>
* 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: <socket>,<data_length> */
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: <socket> */
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 );
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,263 @@
/*
* 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 <stdio.h>
#include <string.h>
#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 );
}
/*-----------------------------------------------------------*/