495 lines
17 KiB
C
Raw Normal View History

2025-04-10 17:31:33 +08:00
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of EigenComm Ltd.
* File name: plat_config.c
* Description: platform configuration source file
* History: Rev1.0 2019-01-18
*
****************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include "lfs_port.h"
#include "ctcc_dm.h"
#include "osasys.h"
#include "ostask.h"
#include DEBUG_LOG_HEADER_FILE
#include "networkmgr.h"
#include "dm_task.h"
#include "ps_event_callback.h"
#include "ps_lib_api.h"
#include "HTTPClient.h"
#include "base64.h"
#define CTDMCONN_TASK_STACK_SIZE 1024
#define CTDM_MODULE_URL "http://zzhc.vnet.cn:9999/"
#define CTDM_SMART_URL "http://zzhc.vnet.cn:9998/"
#define CTDM_CONTTYPE "application/encrypted-json"
#define CTDM_HTTP_RECV_BUF_SIZE (300)
#define CTDM_HTTP_HEAD_BUF_SIZE (400)
#define CTDM_MACHINESTATE(S) \
((S) == CTDM_INIT_STATE ? "CTDM_INIT_STATE" : \
((S) == CTDM_SIM_READY ? "CTDM_SIM_READY" : \
((S) == CTDM_NOT_RIGHT_SIM ? "CTDM_NOT_RIGHT_SIM" : \
((S) == CTDM_IPREADY_STATE ? "CTDM_IPREADY_STATE" : \
((S) == CTDM_IDLE_STATE ? "CTDM_IDLE_STATE" : \
((S) == CTDM_TIME_TO_RETRY ? "CTDM_TIME_TO_RETRY" : \
((S) == CTDM_WAIT_IPREADY ? "CTDM_WAIT_IPREADY" : \
"Unknown")))))))
extern uint32_t mwGetSimCcidValue(uint8_t *ccid, uint8_t len);
extern uint32_t mwSetSimCcidValue(uint8_t *ccid, uint8_t len);
extern uint8_t mwGetCtccAutoRegFlag(void);
extern void mwSetCtccAutoRegFlag(uint8_t autoReg);
extern INT32 psSetEpsAttached (uint32_t atHandle, bool fAttached);
extern int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen );
static uint8_t ctccDmSlpHandler = 0xff;
static uint8_t curImei[IMEI_LEN+1] = {0};
static uint8_t curImsi[IMSI_LEN+1] = {0};
static uint8_t curCCID[MID_WARE_DM_SIM_CCID_LEN+1] = {0};
static bool running = false;
static ctdmStateMachine_t stateMachine = CTDM_INIT_STATE;
static HttpClientContext gHttpClient = {0};
static MWNvmCfgDmCtccParam* dmCtccParam = NULL;
static INT32 ctdmPSUrcCallback(PsEventID eventID, void *param, uint32_t paramLen)
{
NmAtiNetInfoInd *netif = NULL;
CmiSimImsiStr *imsi = NULL;
uint8_t imsiStr[IMSI_LEN+1] = {0};
switch(eventID)
{
case PS_URC_ID_SIM_READY:
{
imsi = (CmiSimImsiStr *)param;
memcpy(imsiStr, imsi->contents, imsi->length);
if((imsiStr[0] == '4')&&(imsiStr[1] == '6')&&(imsiStr[2] == '0')&&
(((imsiStr[3] == '0')&&(imsiStr[4] == '3'))||
((imsiStr[3] == '0')&&(imsiStr[4] == '5'))||
((imsiStr[3] == '1')&&(imsiStr[4] == '1'))))
{
stateMachine = CTDM_SIM_READY;
ECPLAT_PRINTF(UNILOG_DM, ctdmPSUrcCallback_1_1, P_INFO, "sim is ready and it's ctcc card");
}
else
{
stateMachine = CTDM_NOT_RIGHT_SIM;
ECPLAT_PRINTF(UNILOG_DM, ctdmPSUrcCallback_1_2, P_INFO, "it's not ctcc card, abort autoreg");
}
break;
}
case PS_URC_ID_PS_NETINFO:
{
netif = (NmAtiNetInfoInd *)param;
if (netif->netifInfo.netStatus == NM_NETIF_ACTIVATED)
{
if(stateMachine == CTDM_WAIT_IPREADY){
ECPLAT_PRINTF(UNILOG_DM, ctdmPSUrcCallback_2, P_INFO, "PSIF network active change statemachine to DM_IPREADY_STATE");
stateMachine = CTDM_IPREADY_STATE;
}else{
ECPLAT_PRINTF(UNILOG_DM, ctdmPSUrcCallback_2_1, P_INFO, "PSIF network active but state is:%d",stateMachine);
}
}
else if (netif->netifInfo.netStatus == NM_NETIF_OOS)
{
ECPLAT_PRINTF(UNILOG_DM, ctdmPSUrcCallback_2_2, P_INFO, "PSIF network OOS");
}
else if (netif->netifInfo.netStatus == NM_NO_NETIF_OR_DEACTIVATED ||
netif->netifInfo.netStatus == NM_NO_NETIF_NOT_DIAL)
{
ECPLAT_PRINTF(UNILOG_DM, ctdmPSUrcCallback_2_3, P_INFO, "PSIF network deactive");
}
break;
}
default:break;
}
return 0;
}
bool checkNetworkReadyTimeOut(uint8_t times)
{
uint8_t number = 0;
NmAtiNetifInfo netInfo;
while(number < times)
{
appGetNetInfoSync(0, &netInfo);
if(netInfo.netStatus == NM_NETIF_ACTIVATED)
{
return true;
}
else
{
osDelay(500);
}
number++;
}
return false;
}
static uint32_t ctdmGetCellid()
{
uint32_t cellID = 6888;
CmiDevGetExtStatusCnf ueExtStatusInfo;
memset(&ueExtStatusInfo, 0, sizeof(CmiDevGetExtStatusCnf));
if(appGetUeExtStatusInfoSync(UE_EXT_STATUS_ERRC, &ueExtStatusInfo) == CMS_RET_SUCC)
{
cellID = ueExtStatusInfo.rrcStatus.cellId;
ECPLAT_PRINTF(UNILOG_DM, ctdmGetCellid_1, P_INFO, "Cell ID = %d", cellID);
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctdmGetCellid_2, P_INFO, "get cellid failed use default");
}
return cellID;
}
static HTTPResult ctdmhttppost(char* postbuf, uint32_t postlen, uint8_t portType)
{
HTTPResult ret = HTTP_OK;
HttpClientData clientData = {0};
uint8_t code = 0;
char *responseBuf = NULL;
char * curUrl = NULL;
if(portType == 1){
curUrl = CTDM_SMART_URL;
}else{
curUrl = CTDM_MODULE_URL;
}
clientData.respBuf = mallocEc(CTDM_HTTP_RECV_BUF_SIZE);
clientData.respBufLen = CTDM_HTTP_RECV_BUF_SIZE;
clientData.headerBuf = mallocEc(CTDM_HTTP_HEAD_BUF_SIZE);
memset(clientData.headerBuf, 0, CTDM_HTTP_HEAD_BUF_SIZE);
clientData.headerBufLen = CTDM_HTTP_HEAD_BUF_SIZE;
clientData.postBuf = postbuf;
clientData.postBufLen = postlen;
clientData.postContentType = CTDM_CONTTYPE;
ret = httpConnect(&gHttpClient, curUrl);
if(ret == HTTP_OK)
{
ret = httpSendRequest(&gHttpClient, curUrl, HTTP_POST, &clientData);
if (ret != HTTP_OK){
goto exit;
}
do {
memset(clientData.respBuf, 0, CTDM_HTTP_RECV_BUF_SIZE);
memset(clientData.headerBuf, 0, CTDM_HTTP_HEAD_BUF_SIZE);
ret = httpRecvResponse(&gHttpClient, &clientData);
ECPLAT_PRINTF(UNILOG_DM, ctdmhttppost_1, P_INFO, "respCode=%d,recvContentLength=%d", gHttpClient.httpResponseCode, clientData.recvContentLength);
if(ret == HTTP_OK)
{
responseBuf = mallocEc(clientData.recvContentLength+1);
memset(responseBuf, 0, clientData.recvContentLength+1);
memcpy(responseBuf, clientData.respBuf, clientData.blockContentLen);
}
} while (ret == HTTP_MOREDATA || ret == HTTP_CONN );
}
if(ret != HTTP_OK)
{
ECOMM_TRACE(UNILOG_DM, ctdmhttppost_2, P_INFO, 1, "ret=%d", ret);
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctdmhttppost_3, P_INFO, "resp:%s", (uint8_t*)responseBuf);
char* strPtr = strstr(responseBuf, "resultCode");
strPtr += 12;
if( sscanf(strPtr, "\"%d\"%*[^\"]", &code) != 1 ) {
//Cannot match string, error
ECPLAT_PRINTF(UNILOG_DM, ctdmhttppost_3_1, P_INFO, "parse resposne fail");
ret = HTTP_PARSE;
}else{
if(code == 0){
ECPLAT_PRINTF(UNILOG_DM, ctdmhttppost_4, P_INFO, "autoreg success");
ret = HTTP_OK;//HTTP_INTERNAL;
}else{
ECPLAT_PRINTF(UNILOG_DM, ctdmhttppost_5, P_INFO, "autoreg code=%d ", code);
ret = HTTP_PARSE;
}
}
}
exit:
freeEc(clientData.respBuf);
freeEc(clientData.headerBuf);
if(responseBuf != NULL){
freeEc(responseBuf);
}
return ret;
}
int8_t ctdmAutoRegHttp(uint8_t *IMEI, uint8_t *ICCID, uint8_t *IMSI)
{
char rawPayload[SRC_DATA_LEN] = {0};
char extrPayload[50] = {0};
int rawPayloadLen = 0;
char *encodePayload = NULL;
int encodePayloadLen = 0;
int outLen = 0;
uint32_t cellid = 0;
char time[20] = {0};
utc_timer_value_t timeUtc;
int8_t ret = 0;
HTTPResult result = HTTP_OK;
MWNvmCfgDmCtccParam2 param2 = {0};
ret = appGetSystemTimeUtcSync(&timeUtc);//appCheckSystemTimeSync
if(ret == 0)
{
snprintf(time, 20, "%d-%02d-%02d %02d:%02d:%02d", timeUtc.UTCtimer1>>16, (timeUtc.UTCtimer1&0xFF00)>>8, (timeUtc.UTCtimer1&0xFF), (timeUtc.UTCtimer2>>24)+8, (timeUtc.UTCtimer2&0xFF0000)>>16, (timeUtc.UTCtimer2&0xFF00)>>8);
}
else
{
snprintf(time, 20, "2021-05-20 15:12:43");
}
cellid = ctdmGetCellid();
ECPLAT_PRINTF(UNILOG_DM, ctdmAutoRegHttp_1, P_INFO, "time=%s", (uint8_t*)time);
sprintf((char*)rawPayload, "{\"REGVER\":\"5.0\",\"MEID\":\"\",\"MODEL\":\"%s\",\"SWVER\":\"%s\",\"IMEI1\":\"%s\",\"SIM1CDMAIMSI\":\"\",\"SIM1ICCID\":\"%s\",\"SIM1LTEIMSI\":\"%s\",\"SIM1CELLID\":\"%d\",\"REGDATE\":\"%s\"", dmCtccParam->model, dmCtccParam->swver, IMEI, ICCID, IMSI, cellid, time);
mwNvmCfgGetDmCtccParam2(&param2);
if(strlen((char*)param2.ueType) != 0)
{
sprintf(extrPayload, ",\"UETYPE\":\"%s\",\"OSVER\":\"%s\"}", param2.ueType, param2.osVer);
strcat(rawPayload, extrPayload);
}
else
{
strcat(rawPayload, "}");
}
rawPayloadLen = strlen(rawPayload);
ECPLAT_PRINTF(UNILOG_DM, ctdmAutoRegHttp_3, P_INFO, "rawpayload=%s", (uint8_t*)rawPayload);
encodePayload = mallocEc(DST_DATA_LEN);
memset(encodePayload, 0, DST_DATA_LEN);
mbedtls_base64_encode((unsigned char *)encodePayload, (size_t)DST_DATA_LEN, (size_t*)&outLen, (unsigned char *)rawPayload,(size_t)rawPayloadLen);
encodePayloadLen = strlen(encodePayload);
ECPLAT_PRINTF(UNILOG_DM, ctdmAutoRegHttp_2, P_INFO, "terminaltype=%d", dmCtccParam->terminaltype);
result = ctdmhttppost(encodePayload, encodePayloadLen, dmCtccParam->terminaltype);
if(result == HTTP_OK){
ret = 0;
}else{
ret = -1;
}
freeEc(encodePayload);
return ret;
}
bool ctdmIfAutoRegister()
{
bool result = false;
UINT8 cfun = 0xff;
OsaGetImeiNumSync((char *)curImei);
appGetImsiNumSync((char *)curImsi);
appGetIccidNumSync((char *)curCCID);
ECPLAT_PRINTF(UNILOG_DM, ctdmIfAutoRegister_1_1, P_INFO, "current iccid is %s", (uint8_t *)curCCID);
ECPLAT_PRINTF(UNILOG_DM, ctdmIfAutoRegister_1_2, P_INFO, "previous iccid is %s", (uint8_t *)dmCtccParam->ccid);
/* check ccid, and start auto register */
if(strcmp((char *)dmCtccParam->ccid, (char *)curCCID) != 0)
{
ECPLAT_PRINTF(UNILOG_DM, ctdmIfAutoRegister_2, P_INFO, "new sim iccid, need auto register");
result = true;
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctdmIfAutoRegister_3, P_INFO, "same iccid, has autoreg=%d", dmCtccParam->hasReg);
if(dmCtccParam->hasReg == 0)
{
result = true;
}
}
appGetCFUN(&cfun);
if(cfun == 0)
{
result = false;
}
return result;
}
void ctdmAutoRegisterTask(void *argument)
{
int8_t result = 0;
result = ctdmAutoRegHttp(curImei, curCCID, curImsi);
if(result == 0)
{
memcpy(dmCtccParam->ccid, curCCID, MID_WARE_DM_SIM_CCID_LEN);
dmCtccParam->hasReg = 1;
mwNvmCfgSetAndSaveDmCtccParam(dmCtccParam);
ECPLAT_PRINTF(UNILOG_DM, ctccAutoRegisterTask_1_1, P_INFO, "autoReg sucess,record current iccid to NV");
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctccAutoRegisterTask_1_2, P_INFO, "autoReg failed, start deeptimer retry autoreg after 1 hour");
slpManDeepSlpTimerStart(DEEPSLP_TIMER_ID9, 3600*1000);
}
slpManPlatVoteEnableSleep(ctccDmSlpHandler,SLP_SLP2_STATE); //open the sleep2 gate, it can go to sleep2 and hib state
slpManGivebackPlatVoteHandle(ctccDmSlpHandler);
ECPLAT_PRINTF(UNILOG_DM, ctccAutoRegisterTask_2, P_INFO, "give back vote handle, ctdmAutoRegisterTask exit");
osThreadExit();
}
static void ctdmConnectTask(void *arg)
{
bool needAutoReg = false;
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_0_0, P_INFO, "running=%d", running);
while (running)
{
char logbuf[64] = {0};
snprintf(logbuf,64,"%s",CTDM_MACHINESTATE(stateMachine));
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_0, P_INFO, "handle stateMachine:%s", (uint8_t *)logbuf);
switch(stateMachine)
{
case CTDM_INIT_STATE:
case CTDM_WAIT_IPREADY:
osDelay(500/portTICK_PERIOD_MS);
break;
case CTDM_SIM_READY:
needAutoReg = ctdmIfAutoRegister();
if(needAutoReg)
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_0_1, P_INFO, "need autoreg disable sleep");
slpManPlatVoteDisableSleep(ctccDmSlpHandler,SLP_SLP2_STATE);
stateMachine = CTDM_WAIT_IPREADY;
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_0_2, P_INFO, "no need autoreg exit connectTask");
running = false;
}
break;
case CTDM_IPREADY_STATE://poweron to register
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_1, P_INFO, "start ctccAutoReg task and exit connectTask");
osThreadAttr_t task_attr;
memset(&task_attr, 0, sizeof(task_attr));
task_attr.name = "ctccAutoReg";
task_attr.stack_size = CTCC_AUTO_REG_TASK_STACK_SIZE;
#if defined FEATURE_LITEOS_ENABLE
task_attr.priority = osPriorityBelowNormal2;
#elif defined FEATURE_FREERTOS_ENABLE
task_attr.priority = osPriorityBelowNormal5;
#endif
#ifdef TYPE_EC718M
task_attr.reserved = osThreadDynamicStackAlloc;
#endif
osThreadNew(ctdmAutoRegisterTask, NULL,&task_attr);
running = false;
break;
}
case CTDM_NOT_RIGHT_SIM:
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_2, P_INFO, "not cmcc card give back vote handle exit connecttask");
slpManGivebackPlatVoteHandle(ctccDmSlpHandler);
running = false;
break;
}
case CTDM_IDLE_STATE://nothing to do can handle key event
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_3, P_INFO, "nothing to do exit connecttask");
running = false;
break;
}
case CTDM_TIME_TO_RETRY://time up retry autoregister
{
// wait 60s for network
if(checkNetworkReadyTimeOut(120) != true)
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_4_1, P_INFO, "network not ready give up autoreg this time");
slpManPlatVoteEnableSleep(ctccDmSlpHandler, SLP_SLP2_STATE);
stateMachine = CTDM_IDLE_STATE;
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_4, P_INFO, "network ok go IPREADY_STATE");
stateMachine = CTDM_IPREADY_STATE;
needAutoReg = true;
}
break;
}
default:
{
ECPLAT_PRINTF(UNILOG_DM, ctdmConnectTask_5, P_INFO, "unknown state exit connecttask");
running = false;
break;
}
}
}
deregisterPSEventCallback((psEventCallback_t)ctdmPSUrcCallback);
osThreadExit();
}
static void ctdmStartConncetTask()
{
osThreadAttr_t task_attr;
memset(&task_attr,0,sizeof(task_attr));
task_attr.name = "ctdmConn";
task_attr.stack_size = CTDMCONN_TASK_STACK_SIZE;
#if defined FEATURE_LITEOS_ENABLE
task_attr.priority = osPriorityNormal1;
#elif defined FEATURE_FREERTOS_ENABLE
task_attr.priority = osPriorityNormal;
#endif
#ifdef TYPE_EC718M
task_attr.reserved = osThreadDynamicStackAlloc;
#endif
running = true;
osThreadNew(ctdmConnectTask, NULL, &task_attr);
}
void ctdmAutoregRetryTimeExpCallback(void)
{
slpManPlatVoteDisableSleep(ctccDmSlpHandler,SLP_SLP2_STATE);
stateMachine = CTDM_TIME_TO_RETRY;
}
void ctdmDeepSleepTimerCbRegister(void)
{
slpManDeepSlpTimerRegisterExpCb(DEEPSLP_TIMER_ID9, (slpManUsrDeepSlpTimerCb_Func)ctdmAutoregRetryTimeExpCallback);
}
void ctccAutoRegisterInit(MWNvmCfgDmCtccParam* ctccParam, slpManSlpState_t slpState)
{
ECPLAT_PRINTF(UNILOG_DM, ctccAutoRegisterInit, P_INFO, "start connect task");
dmCtccParam = ctccParam;
slpManApplyPlatVoteHandle("CTCC_DM",&ctccDmSlpHandler);
registerPSEventCallback(PS_GROUP_ALL_MASK, (psEventCallback_t)ctdmPSUrcCallback);
ctdmStartConncetTask();
if(slpState == SLP_HIB_STATE || slpState == SLP_SLP2_STATE)//wakeup from deep sleep
{
ECPLAT_PRINTF(UNILOG_DM, ctccAutoRegisterInit_0_1, P_INFO, "wakeup from deep sleep");
}
else
{
ECPLAT_PRINTF(UNILOG_DM, ctccAutoRegisterInit_0_2, P_INFO, "system reset");
}
}