2025-04-10 17:31:33 +08:00

945 lines
37 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
*
* Copy right: 2017-, Copyrigths of EigenComm Ltd.
* File name: cisAsynEntry.c
* Description: EC618 CMCC cis dm entry source file
* History: Rev1.0 2019-3-6
*
****************************************************************************/
#include <cis_def.h>
#if CIS_ENABLE_DM
#include <stdio.h>
#include <stdlib.h>
#include <cis_if_sys.h>
#include <cis_log.h>
#include <cis_list.h>
#include <cis_api.h>
#include "cmcc_dm.h"
#include <string.h>
#include "osasys.h"
#include "dm_utils/dm_endpoint.h"
#include "networkmgr.h"
#include "ps_event_callback.h"
#include "ps_lib_api.h"
#include "cmips.h"
#include "cis_def.h"
#include "dm_task.h"
#include DEBUG_LOG_HEADER_FILE
#include "version.h"
#include "cJSON.h"
#define CMDM_SOFTVER "V"SDK_MAJOR_VERSION"."SDK_MINOR_VERSION"."SDK_PATCH_VERSION
#define DMCONN_TASK_STACK_SIZE 1024
#define DM_MACHINESTATE(S) \
((S) == DM_INIT_STATE ? "DM_INIT_STATE" : \
((S) == DM_SIM_READY ? "DM_SIM_READY" : \
((S) == DM_NOT_RIGHT_SIM ? "DM_NOT_RIGHT_SIM" : \
((S) == DM_IPREADY_STATE ? "DM_IPREADY_STATE" : \
((S) == DM_HEART_BEAT_ARRIVED ? "DM_HEART_BEAT_ARRIVED" : \
((S) == DM_HEART_BEAT_UPDATE ? "DM_HEART_BEAT_UPDATE" : \
((S) == DM_IDLE_STATE ? "DM_IDLE_STATE" : \
"Unknown")))))))
#define CMDM_BRAND "EiGENCOMM"
#define CMDM_MODEL "EC616"
#define CMDM_SDKV "4.0.1"
#define CMDM_APIV "4.0.1"
#define CMDM_TEMPID "TY000123"
typedef struct{
uint32_t reportTime;
uint32_t heartBeatTime;
uint32_t reportNum;
uint16_t retryInter;
uint16_t retryNum;
}ruleCfg_t;
static const uint8_t dm_config_hex[] = {
0x13,0x00,0x43,
0xf1,0x00,0x03,
0xf2,0x00,0x35,
0x05,0x00 /*mtu*/,0x11 /*Link & bind type*/,0x00 /*NO BS NO DTLS*/,
0x00,0x05 /*apn length*/,0x43,0x4d,0x49,0x4f,0x54 /*apn: CMIOT*/,
0x00, 0x00 /*username length*/, /*username*/
0x00, 0x00 /*password length*/, /*password*/
0x00,0x10 /*host length*/,0x31,0x31,0x37,0x2e,0x31,0x36,0x31,0x2e,0x32,0x2e,0x37,0x5e,0x35,0x36,0x38,0x33/*host: 117.161.2.7^5683*/,
0x00,0x0F /*userdata length*/,0x41,0x75,0x74,0x68,0x43,0x6f,0x64,0x65,0x3a,0x3b,0x50,0x53,0x4B,0x3A,0x3B/*userdata: AuthCode:;PSK:;*/,
0xf3,0x00,0x8,
0xe4 /*log config*/,0x00,0xc8 /*LogBufferSize: 200*/,
0x00, 0x00 /*userdata length*//*userdata*/
};
static const uint8_t dm_m_config_hex[] = {
0x13,0x00,0x44,
0xf1,0x00,0x03,
0xf2,0x00,0x36,
0x05,0x00 /*mtu*/,0x11 /*Link & bind type*/,0x00 /*NO BS NO DTLS*/,
0x00,0x05 /*apn length*/,0x43,0x4d,0x49,0x4f,0x54 /*apn: CMIOT*/,
0x00, 0x00 /*username length*/, /*username*/
0x00, 0x00 /*password length*/, /*password*/
0x00,0x11 /*host length*/,0x31,0x31,0x37,0x2e,0x31,0x36,0x31,0x2e,0x32,0x2e,0x34,0x31,0x5e,0x35,0x36,0x38,0x33/*host: 117.161.2.41^5683*/,
0x00,0x0F /*userdata length*/,0x41,0x75,0x74,0x68,0x43,0x6f,0x64,0x65,0x3a,0x3b,0x50,0x53,0x4B,0x3A,0x3B/*userdata: AuthCode:;PSK:;*/,
0xf3,0x00,0x8,
0xe4 /*log config*/,0x00,0xc8 /*LogBufferSize: 200*/,
0x00, 0x00 /*userdata length*//*userdata*/
};
static UINT8 cmccDmSlpHandler = 0xff;
static dmStateMachine_t stateMachine = DM_INIT_STATE;
static BOOL needRestoreDMTask = FALSE;
static StaticTask_t dmconnTask;
static UINT8 dmconnTaskStack[DMCONN_TASK_STACK_SIZE];
static BOOL running = FALSE;
static MWNvmCfgDmCmccParam *dmCmccParam = NULL;
static MWNvmCfgDmCmccParam2 *dmCmccParam2 = NULL;
static UINT8 curRetryTimes = 0;
static char constDeviceInfo[20] = "EC616";
static char constMAC[20] = "***";
static char constROM[20] = "4M";
static char constRAM[20] = "256K";
static char constCPU[20] = "ARM Cortex-M3";
static char constSysVer[20] = "FreeRTOS V9.0.0";
static char constSoftVer[20] = "v1.1.1";
static char constSoftNam[20] = "EC616";
static char constVolte[20] = "0";
static char constNetType[20] = "NB-IoT";
static char constPhoneNumber[20] = "***";
extern BOOL bTestSim;
static void prv_dm_readResponse(void* context, cis_uri_t* uri, cis_mid_t mid);
static void prv_dm_discoverResponse(void* context, cis_uri_t* uri, cis_mid_t mid);
static void prv_dm_writeResponse(void* context, cis_uri_t* uri, const cis_data_t* value, cis_attrcount_t count, cis_mid_t mid);
static cis_coapret_t dm_onRead(void* context, cis_uri_t* uri, cis_mid_t mid);
static cis_coapret_t dm_onWrite(void* context, cis_uri_t* uri, const cis_data_t* value, cis_attrcount_t attrcount, cis_mid_t mid);
static cis_coapret_t dm_onExec(void* context, cis_uri_t* uri, const uint8_t* value, uint32_t length, cis_mid_t mid);
static cis_coapret_t dm_onObserve(void* context, cis_uri_t* uri, bool flag, cis_mid_t mid);
static cis_coapret_t dm_onParams(void* context, cis_uri_t* uri, cis_observe_attr_t parameters, cis_mid_t mid);
static cis_coapret_t dm_onDiscover(void* context, cis_uri_t* uri, cis_mid_t mid);
static void dm_onEvent(void* context, cis_evt_t eid, void* param);
static BOOL dmCheckifNetworkReady(void);
static dm_device_object g_objectList[DM_SAMPLE_OBJECT_MAX];
static dm_instance g_instList_read;
static dm_instance g_instList_write;
static Options dm_config;
static void* g_dmcontext = NULL;
static bool g_doRegisterdm = false;
static CHAR *defaultDmLocalPort = "49260";
static bool g_needUpdate = false;
static INT32 g_lifeTime = 3600;
static UINT8 imsiStr[IMSI_LEN+1] = {0};
void prvMakeUserdata()
{
int i = 0;
for (i= 0;i < DM_SAMPLE_OBJECT_MAX; i++)
{
dm_device_object* obj = &g_objectList[i];
switch(i){
case 0:
{
obj->oid = DM_SAMPLE_OID_READ;
obj->instBitmap = DM_SAMPLE_INSTANCE_BITMAP;
g_instList_read.instId = 0;
g_instList_read.enabled = true;
g_instList_read.instance.boolVal = true;
g_instList_read.instance.intVal = cissys_rand() % 100;
strcpy(g_instList_read.instance.strVal,"temp test");
obj->attrCount = 1;
}
break;
case 1:
{
obj->oid = DM_SAMPLE_OID_WRITE;
obj->instBitmap = DM_SAMPLE_INSTANCE_BITMAP;
g_instList_write.instId = 0;
g_instList_write.enabled = true;
g_instList_write.instance.boolVal = true;
g_instList_write.instance.intVal = cissys_rand() % 100;
strcpy(g_instList_write.instance.strVal,"temp test");
obj->attrCount = 1;
}
break;
}
}
}
void dm_sample_dm_entry(void* arg)
{
int index = 0;
et_client_state_t curStatus = PUMP_STATE_INITIAL;
BOOL hasNetwork = FALSE;
int waittimems = 0;
UINT32 ret = 0;
cis_callback_t callback;
callback.onRead = dm_onRead;
callback.onWrite = dm_onWrite;
callback.onExec = dm_onExec;
callback.onObserve = dm_onObserve;
callback.onSetParams = dm_onParams;
callback.onEvent = dm_onEvent;
callback.onDiscover = dm_onDiscover;
g_lifeTime = dmCmccParam->lifeTime * 60;
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_1, P_SIG, "lifetime:%d, testmode:%d", dmCmccParam->lifeTime*60, dmCmccParam->platform);
if(strlen(dmCmccParam->appKey)!=0){
memset(dm_config.szAppKey, 0, 64);
memcpy(dm_config.szAppKey, dmCmccParam->appKey, strlen(dmCmccParam->appKey));
}
if(strlen(dmCmccParam->secret)!=0){
memset(dm_config.szPwd, 0, 64);
memcpy(dm_config.szPwd, dmCmccParam->secret, strlen(dmCmccParam->secret));
}
strncpy(dm_config.brand, CMDM_BRAND, 31);
strncpy(dm_config.model, CMDM_MODEL, 31);
strncpy(dm_config.sdkversion, CMDM_SDKV, 31);
strncpy(dm_config.apiversion, CMDM_APIV, 31);
strncpy(dm_config.templateId, CMDM_TEMPID, 31);
prvMakeUserdata();
if(dmCmccParam->platform == 0){
if (cis_init(&g_dmcontext, (void *)dm_config_hex, sizeof(dm_config_hex), &dm_config, defaultDmLocalPort) != CIS_RET_OK) {
if (g_dmcontext != NULL)
cis_deinit(&g_dmcontext);
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_1_1, P_INFO, "cis entry init failed.");
goto exit;
}
}else{
if (cis_init(&g_dmcontext, (void *)dm_m_config_hex, sizeof(dm_m_config_hex), &dm_config, defaultDmLocalPort) != CIS_RET_OK) {
if (g_dmcontext != NULL)
cis_deinit(&g_dmcontext);
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_1_2, P_INFO, "cis entry init failed.");
goto exit;
}
}
//log_config(false, 1, 10, 1024);//For debug
((st_context_t*)g_dmcontext)->regTimeout = 120;//set register timeout 120 seconds
if (needRestoreDMTask) {
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_2, P_INFO, "needRestore ignoreRegistration");
((st_context_t*)g_dmcontext)->stateStep = PUMP_STATE_CONNECTING;
((st_context_t*)g_dmcontext)->ignoreRegistration = TRUE;
((st_context_t*)g_dmcontext)->location = mallocEc(strlen(dmCmccParam->location) + 1);
strcpy(((st_context_t*)g_dmcontext)->location,dmCmccParam->location );
}
for (index = 0; index < DM_SAMPLE_OBJECT_MAX; index++)
{
cis_inst_bitmap_t bitmap;
cis_res_count_t rescount;
cis_instcount_t instCount, instBytes;
const char* instAsciiPtr;
uint8_t * instPtr;
cis_oid_t oid;
int16_t i;
dm_device_object* obj = &g_objectList[index];
oid = obj->oid;
instCount = utils_strlen(obj->instBitmap);//ʵ<><CAB5><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ܵ<EFBFBD>ʵ<EFBFBD><CAB5>
instBytes = (instCount - 1) / 8 + 1;//Ҫ<>ö<EFBFBD><C3B6>ٸ<EFBFBD><D9B8>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>ʾʵ<CABE><CAB5><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>ʵ<EFBFBD><CAB5>ռ<EFBFBD><D5BC>һλ
instAsciiPtr = obj->instBitmap;
instPtr = (uint8_t*)cis_malloc(instBytes);
if(instPtr == NULL){
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_2_1, P_INFO, "no mem");
continue;
}
cis_memset(instPtr, 0, instBytes);
for (i = 0; i < instCount; i++)//<2F><>һ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˼<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>"1101"<22>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1101
{
cis_instcount_t instBytePos = i / 8;
cis_instcount_t instByteOffset = 7 - (i % 8);
if (instAsciiPtr[i] == '1') {
instPtr[instBytePos] += 0x01 << instByteOffset;
}
}
bitmap.instanceCount = instCount;
bitmap.instanceBitmap = instPtr;
bitmap.instanceBytes = instBytes;
rescount.attrCount = obj->attrCount;
rescount.actCount = obj->actCount;
cis_addobject(g_dmcontext, oid, &bitmap, &rescount);
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_3, P_INFO, "cis_addobject obj=%d",oid);
cis_free(instPtr);
}
//register enabled
g_doRegisterdm = true;
while (1)
{
/*
*wait press keyboard for register test;
*do register press 'o'
*do unregister press 'r'
**/
if (g_doRegisterdm)
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4, P_INFO, 0, "to register client");
hasNetwork = dmCheckifNetworkReady();
if(!hasNetwork){
if(curRetryTimes < dmCmccParam2->retryNum)
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_1, P_INFO, 2, "no network wait %d minutes to retry---%d", dmCmccParam2->retryInter, curRetryTimes);
waittimems = dmCmccParam2->retryInter * 60 * 1000;
cissys_sleepms(waittimems);
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_2, P_INFO, 0, "time's up");
curRetryTimes += 1;
continue;
}
else
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_3, P_INFO, 0, "still no network , reach the max retry times.");
cis_unregister(g_dmcontext);
g_doRegisterdm = false;
}
}else{
g_doRegisterdm = false;
cis_register(g_dmcontext, dmCmccParam->lifeTime*60, &callback);//<2F><><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>SDK<44><4B>
}
}
/*pump function*/
ret = cis_pump(g_dmcontext);
if(ret == PUMP_RET_FAULT)
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_4, P_INFO, 0, "cis_pump return PUMP_RET_FAULT");
dmCmccParam->bConnected = DM_REG_FAIL_STATE;
//slpManPlatVoteEnableSleep(cmccDmSlpHandler, SLP_SLP2_STATE);
if(curRetryTimes < dmCmccParam2->retryNum)
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_5, P_INFO, 2, "wait %d minutes to retry %d times", dmCmccParam2->retryInter, curRetryTimes);
waittimems = dmCmccParam2->retryInter * 60 * 1000;
cissys_sleepms(waittimems);
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_6, P_INFO, 0, "time's up");
((st_context_t*)g_dmcontext)->stateStep = PUMP_STATE_INITIAL;
g_doRegisterdm = true;
continue;
}
else
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_4_7, P_INFO, 0, "reach the max retyr times.");
goto exit;
}
}
curStatus = ((st_context_t*)g_dmcontext)->stateStep;
if(g_needUpdate && curStatus == PUMP_STATE_READY)
{
g_needUpdate = FALSE;
curRetryTimes = 0;
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_5, P_INFO, "g_needUpdate = %d,PUMP_STATE_READY call cis_update_reg", g_needUpdate);
hasNetwork = dmCheckifNetworkReady();
if(!hasNetwork){
if(curRetryTimes < dmCmccParam2->retryNum)
{
waittimems = dmCmccParam2->retryInter * 60 * 1000;
ECPLAT_PRINTF(UNILOG_DM, _dm_sample_dm_entry_5_1, P_INFO, "no network wait (%d)ms retry ", waittimems);
cissys_sleepms(waittimems);
curRetryTimes += 1;
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_5_2, P_INFO, 0, "time's up");
g_doRegisterdm = true;
continue;
}
else
{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_5_3, P_INFO, 0, "reach the max retyr times.");
cis_unregister(g_dmcontext);
g_doRegisterdm = false;
}
}else{
ECOMM_TRACE(UNILOG_DM, _dm_sample_dm_entry_5_4, P_INFO, 0, "call cis_update_reg");
cis_update_reg(g_dmcontext,dmCmccParam->lifeTime*60,FALSE,2);
}
}
cissys_sleepms(200);
}
exit:
osThreadExit();
}
//private funcation;
//static void prv_dm_observeNotify(void* context, cis_uri_t* uri, cis_mid_t mid)
//{
//}
static void prv_dm_readResponse(void* context, cis_uri_t* uri, cis_mid_t mid)
{
if(!CIS_URI_IS_SET_RESOURCE(uri)) // one object
{
ECPLAT_PRINTF(UNILOG_DM, prv_dm_readResponse_1, P_INFO, "read all object:%d", uri->objectId);
switch(uri->objectId)
{
case DM_SAMPLE_OID_READ:
{
dm_instance *inst = &g_instList_read;
if(inst != NULL && inst->enabled == true)
{
cis_data_t tmpdata;
tmpdata.type = cis_data_type_string;
tmpdata.asBuffer.buffer = cis_malloc(1024);
uint32_t temLen = 0;
uint8_t* encIMSI = genEncodeValue((char*)imsiStr, &temLen, &dm_config);
uint8_t* encDeviceInfo = genEncodeValue(constDeviceInfo, &temLen, &dm_config);
uint8_t* encMAC = genEncodeValue(constMAC, &temLen, &dm_config);
uint8_t* encROM = genEncodeValue(constROM, &temLen, &dm_config);
uint8_t* encRAM = genEncodeValue(constRAM, &temLen, &dm_config);
uint8_t* encCPU = genEncodeValue(constCPU, &temLen, &dm_config);
uint8_t* encSysver = genEncodeValue(constSysVer, &temLen, &dm_config);
uint8_t* encSoftver = genEncodeValue(constSoftVer, &temLen, &dm_config);
uint8_t* encSoftname = genEncodeValue(constSoftNam, &temLen, &dm_config);
uint8_t* encVolte= genEncodeValue(constVolte, &temLen, &dm_config);
uint8_t* encNettpye = genEncodeValue(constNetType, &temLen, &dm_config);
uint8_t* encPhoneNum = genEncodeValue(constPhoneNumber, &temLen, &dm_config);
snprintf((char*)tmpdata.asBuffer.buffer,1024,"{\"imsi\":\"%s\",\"sn\":\"%s\",\"mac\":\"%s\",\"rom\":\"%s\",\"ram\":\"%s\",\
\"cpu\":\"%s\",\"sysVersion\":\"%s\",\"softwareVer\":\"%s\",\"softwareName\":\"%s\",\"volte\":\"%s\",\"netType\":\"%s\",\
\"phoneNumber\":\"%s\", \"batterCapacity\":\"%s\", \"screenSize\":\"%s\", \"networkStatus\":\"%s\", \"wearingstatus\":\"%s\", \
\"routerMac\":\"%s\",\"bluetoothMac\":\"%s\", \"gpu\":\"%s\", \"board\":\"%s\", \"resolution\":\"%s\", }",
encIMSI,encDeviceInfo,encMAC,encROM,encRAM,encCPU,encSysver,encSoftver,encSoftname,encVolte,encNettpye,\
encPhoneNum, encMAC, encMAC, encMAC,encMAC, encMAC, encMAC,encMAC, encMAC, encMAC);
tmpdata.asBuffer.length = strlen((char*)tmpdata.asBuffer.buffer);
uri->resourceId = 1;
uri->instanceId = inst->instId;
cis_uri_update(uri);
cis_response(context,uri,&tmpdata,mid,CIS_RESPONSE_READ,0);
cis_free(tmpdata.asBuffer.buffer);
cis_free(encIMSI);
cis_free(encDeviceInfo);
cis_free(encMAC);
cis_free(encROM);
cis_free(encRAM);
cis_free(encCPU);
cis_free(encSysver);
cis_free(encSoftver);
cis_free(encSoftname);
cis_free(encVolte);
cis_free(encNettpye);
cis_free(encPhoneNum);
}
}
break;
}
}
}
static void prv_dm_discoverResponse(void* context, cis_uri_t* uri, cis_mid_t mid)
{
switch(uri->objectId)
{
case DM_SAMPLE_OID_WRITE:
{
uri->objectId = DM_SAMPLE_OID_WRITE;
uri->instanceId = 0;
uri->resourceId = attributeWrite_fieldConfig;
cis_uri_update(uri);
cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE,0);
uri->objectId = DM_SAMPLE_OID_WRITE;
uri->instanceId = 0;
uri->resourceId = attributeWrite_ruleConfig;
cis_uri_update(uri);
cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE,0);
uri->objectId = DM_SAMPLE_OID_WRITE;
uri->instanceId = 0;
uri->resourceId = attributeWrite_addressConfig;
cis_uri_update(uri);
cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE,0);
break;
}
case DM_SAMPLE_OID_READ:
{
uri->objectId = DM_SAMPLE_OID_READ;
uri->instanceId = 0;
uri->resourceId = 1;
cis_uri_update(uri);
cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE,0);
break;
}
}
cis_response(context,NULL,NULL,mid,CIS_RESPONSE_DISCOVER,0);
}
/**
\fn int dmGecRuleCfgFromPlat(uint8_t* payload, ruleCfg_t* config)
\brief parse the payload of 668/0 resouce id 2
\param[in] uint8_t* payload
\param[out] ruleCfg_t* rulecfg
\returns int -1:failed; 0:no rulecfg; 1:has rulecfg
*/
static int dmGecRuleCfgFromPlat(uint8_t* payload, ruleCfg_t* config)
{
cJSON *pPayload = NULL;
cJSON *pReportTime = NULL;//reportTime
cJSON *pHeartBeat = NULL;//heartBeatTime
cJSON *pReportNum = NULL;//reportNum
cJSON *pRetryInt = NULL;//retryInterval
cJSON *pRetryNum = NULL;//retryNum
int ret = -1;
if(payload == NULL){
return ret;
}
pPayload = cJSON_Parse((char*)payload);
if(pPayload)
{
ret = 0;
pReportTime = cJSON_GetObjectItem(pPayload, "reportTime");
if(pReportTime != NULL && pReportTime->type == cJSON_Number){
config->reportTime = pReportTime->valueint;
ret = 1;
ECOMM_TRACE(UNILOG_DM, dmGecRuleCfgFromPlat_1, P_INFO, 1, "get reportTime=%d.", config->reportTime);
}
pHeartBeat = cJSON_GetObjectItem(pPayload, "heartBeatTime");
if(pHeartBeat != NULL || pHeartBeat->type == cJSON_Number){
ret = 1;
config->heartBeatTime = pHeartBeat->valueint;
ECOMM_TRACE(UNILOG_DM, dmGecRuleCfgFromPlat_2, P_INFO, 1, "get heartBeatTime=%d.", config->heartBeatTime);
}
pReportNum = cJSON_GetObjectItem(pPayload, "reportNum");
if(pReportNum != NULL && pReportNum->type == cJSON_Number){
ret = 1;
config->reportNum = pReportNum->valueint;
ECOMM_TRACE(UNILOG_DM, dmGecRuleCfgFromPlat_3, P_INFO, 1, "get reportNum=%d.", config->reportNum);
}
pRetryInt = cJSON_GetObjectItem(pPayload, "retryInterval");
if(pRetryInt != NULL && pRetryInt->type == cJSON_Number){
ret = 1;
config->retryInter = pRetryInt->valueint;
ECOMM_TRACE(UNILOG_DM, dmGecRuleCfgFromPlat_4, P_INFO, 1, "get retryInter=%d.", config->retryInter);
}
pRetryNum = cJSON_GetObjectItem(pPayload, "retryNum");
if(pRetryNum != NULL && pRetryNum->type == cJSON_Number){
ret = 1;
config->retryNum = pRetryNum->valueint;
ECOMM_TRACE(UNILOG_DM, dmGecRuleCfgFromPlat_5, P_INFO, 1, "get retryNum=%d.", config->retryNum);
}
}
cJSON_Delete(pPayload);
return ret;
}
static void prv_dm_writeResponse(void* context, cis_uri_t* uri, const cis_data_t* data, cis_attrcount_t count, cis_mid_t mid)
{
cis_rescount_t resIndex = 0;
ruleCfg_t ruleConfig = {0};
int result = -1;
ECOMM_TRACE(UNILOG_DM, prv_dm_writeResponse_1, P_INFO, 2, "write object:%d,type:%d count:%d", uri->objectId, count);
if(!CIS_URI_IS_SET_RESOURCE(uri)) // one object
{
ECOMM_TRACE(UNILOG_DM, prv_dm_writeResponse_2, P_INFO, 1, "write all object");
switch(uri->objectId)
{
case DM_SAMPLE_OID_WRITE:
{
for (resIndex = 0;resIndex< count;resIndex++)
{
ECOMM_TRACE(UNILOG_DM, prv_dm_writeResponse_3, P_INFO, 2, "data[%d].id = %d", resIndex, data[resIndex].id);
if(data[resIndex].id == 2){
ECOMM_TRACE(UNILOG_DM, prv_dm_writeResponse_4, P_INFO, 0, "handle rulecofing");
result = dmGecRuleCfgFromPlat(data[resIndex].asBuffer.buffer, &ruleConfig);
}
}
}
break;
}
}
cis_response(context,NULL,NULL,mid,CIS_RESPONSE_WRITE,0);
if(result == 1){
if(ruleConfig.heartBeatTime * 60 != g_lifeTime){
g_lifeTime = ruleConfig.heartBeatTime * 60;
ECOMM_TRACE(UNILOG_DM, prv_dm_writeResponse_5, P_INFO, 1, "DMP's heartBeatTime is different with UE's set update lifetime update it=%d", g_lifeTime);
st_context_t* ctx = (st_context_t*)context;
ctx->lifetime = g_lifeTime;
}
if(dmCmccParam2 != NULL){
ECOMM_TRACE(UNILOG_DM, prv_dm_writeResponse_6, P_INFO, 0, "update ruleconfig");
dmCmccParam2->reportTime = ruleConfig.reportTime;
dmCmccParam->lifeTime = ruleConfig.heartBeatTime * 60;
dmCmccParam2->reportNum = ruleConfig.reportNum;
dmCmccParam2->retryInter = ruleConfig.retryInter;
dmCmccParam2->retryNum = ruleConfig.retryNum;
mwNvmCfgSetAndSaveDmCmccParam(dmCmccParam);
mwNvmCfgSetAndSaveDmCmccParam2(dmCmccParam2);
}
}
}
static cis_coapret_t dm_onRead(void* context, cis_uri_t* uri, cis_mid_t mid)
{
ECOMM_TRACE(UNILOG_DM, dm_onRead, P_INFO, 3, "Read:(%d/%d/%d)", uri->objectId, uri->instanceId, uri->resourceId);
prv_dm_readResponse(g_dmcontext, uri, mid);
return CIS_CALLBACK_CONFORM;
}
static cis_coapret_t dm_onDiscover(void* context, cis_uri_t* uri, cis_mid_t mid)
{
ECOMM_TRACE(UNILOG_DM, dm_onDiscover, P_INFO, 3, "Discover:(%d/%d/%d)", uri->objectId, uri->instanceId, uri->resourceId);
prv_dm_discoverResponse(g_dmcontext, uri, mid);
return CIS_CALLBACK_CONFORM;
}
static cis_coapret_t dm_onWrite(void* context, cis_uri_t* uri, const cis_data_t* value, cis_attrcount_t attrcount, cis_mid_t mid)
{
ECOMM_TRACE(UNILOG_DM, dm_onWrite, P_INFO, 3, "Write:(%d/%d/%d)", uri->objectId, uri->instanceId, uri->resourceId);
prv_dm_writeResponse(g_dmcontext, uri, value, attrcount, mid);
return CIS_CALLBACK_CONFORM;
}
static cis_coapret_t dm_onExec(void* context, cis_uri_t* uri, const uint8_t* value, uint32_t length, cis_mid_t mid)
{
return CIS_CALLBACK_CONFORM;
}
static cis_coapret_t dm_onObserve(void* context, cis_uri_t* uri, bool flag, cis_mid_t mid)
{
return CIS_CALLBACK_CONFORM;
}
static cis_coapret_t dm_onParams(void* context, cis_uri_t* uri, cis_observe_attr_t parameters, cis_mid_t mid)
{
return CIS_CALLBACK_CONFORM;
}
void dm_onEvent(void* context, cis_evt_t eid, void* param)
{
switch (eid)
{
case CIS_EVENT_UPDATE_NEED:
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_1, P_SIG, "DM need to update,reserve time:%ds", (int32_t)param);
if(!g_needUpdate){
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_1_1, P_INFO, "no deepSleepTimer auto update reg", (int32_t)param);
cis_update_reg(g_dmcontext, LIFETIME_INVALID, false, 2);
}else{
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_1_2, P_INFO, "deepSleepTimer is work not update reg", (int32_t)param);
}
break;
case CIS_EVENT_REG_SUCCESS:
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_2, P_SIG, "DM register success. save context, start deep sleep timer");
dmCmccParam->bConnected = DM_REG_SUC_STATE;
mwNvmCfgSetAndSaveDmCmccParam(dmCmccParam);
slpManDeepSlpTimerStart(DEEPSLP_TIMER_ID8, (g_lifeTime-10)*1000);
curRetryTimes = 0;
break;
case CIS_EVENT_REG_FAILED:
case CIS_EVENT_REG_TIMEOUT:
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_3, P_SIG, "DM register failed(%d). save regstat DM_REG_FAIL_STATE, enable sleeep",eid);
dmCmccParam->bConnected = DM_REG_FAIL_STATE;
mwNvmCfgSetAndSaveDmCmccParam(dmCmccParam);
break;
case CIS_EVENT_UPDATE_SUCCESS:
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_4, P_SIG, "DM update success, start deep sleep timer, enable sleep");
slpManDeepSlpTimerStart(DEEPSLP_TIMER_ID8, (g_lifeTime-10)*1000);
slpManPlatVoteEnableSleep(cmccDmSlpHandler, SLP_SLP2_STATE);
break;
case CIS_EVENT_UPDATE_FAILED:
case CIS_EVENT_UPDATE_TIMEOUT:
ECOMM_TRACE(UNILOG_DM, _dm_onEvent_5, P_SIG, 0, "DM update failed");
dmCmccParam->bConnected = DM_REG_FAIL_STATE;
mwNvmCfgSetAndSaveDmCmccParam(dmCmccParam);
//slpManDeepSlpTimerStart(DEEPSLP_TIMER_ID8, (g_lifeTime-10)*1000);
//slpManPlatVoteEnableSleep(cmccDmSlpHandler, SLP_SLP2_STATE);
//ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_5, P_SIG, "DM update failed, save regstat DM_REG_FAIL_STATE, enable sleep");
default:
ECPLAT_PRINTF(UNILOG_DM, _dm_onEvent_6, P_SIG, "event:%d,param:%d", eid, (int32_t)param);
break;
}
}
BOOL ifNeedRestoreDMTask(void)
{
BOOL needRestoreTask = FALSE;
if(dmCmccParam->bConnected == DM_REG_SUC_STATE){
ECPLAT_PRINTF(UNILOG_DM, ifNeedTask_1, P_INFO, "before has dm connected, need restore task");
needRestoreTask = TRUE;
}
return needRestoreTask;
}
static INT32 dmPSUrcCallback(PsEventID eventID, void *param, UINT32 paramLen)
{
NmAtiNetInfoInd *netif = NULL;
CmiSimImsiStr *imsi = NULL;
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] == '0'))||
((imsiStr[3] == '0')&&(imsiStr[4] == '2'))||
((imsiStr[3] == '0')&&(imsiStr[4] == '4'))||
((imsiStr[3] == '0')&&(imsiStr[4] == '7'))||
((imsiStr[3] == '0')&&(imsiStr[4] == '8'))))
{
stateMachine = DM_SIM_READY;
ECPLAT_PRINTF(UNILOG_DM, dmPSUrcCallback_1_1, P_INFO, "sim is ready and it's cmcc card");
}
else
{
stateMachine = DM_NOT_RIGHT_SIM;
ECPLAT_PRINTF(UNILOG_DM, dmPSUrcCallback_1_2, P_INFO, "it's not cmcc card, abort autoreg");
}
*/
if(!bTestSim)
{
stateMachine = DM_SIM_READY;
ECPLAT_PRINTF(UNILOG_DM, dmPSUrcCallback_1_1, P_INFO, "sim is ready:%s", imsiStr);
slpManPlatVoteDisableSleep(cmccDmSlpHandler, SLP_SLP2_STATE);
}
else
{
stateMachine = DM_NOT_RIGHT_SIM;
ECPLAT_PRINTF(UNILOG_DM, dmPSUrcCallback_1_2, P_INFO, "it's test card, abort autoreg");
}
break;
}
case PS_URC_ID_PS_NETINFO:
{
netif = (NmAtiNetInfoInd *)param;
if (netif->netifInfo.netStatus == NM_NETIF_ACTIVATED)
{
ECPLAT_PRINTF(UNILOG_DM, dmPSUrcCallback_2_1, P_INFO, "PSIF network active change statemachine to DM_IPREADY_STATE");
if(stateMachine != DM_NOT_RIGHT_SIM){
stateMachine = DM_IPREADY_STATE;
}
}
else if (netif->netifInfo.netStatus == NM_NETIF_OOS)
{
ECPLAT_PRINTF(UNILOG_DM, dmPSUrcCallback_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, dmPSUrcCallback_2_3, P_INFO, "PSIF network deactive");
}
break;
}
default:break;
}
return 0;
}
static BOOL dmCheckifNetworkReady()
{
NmAtiNetifInfo netInfo;
appGetNetInfoSync(0, &netInfo);
if(netInfo.netStatus == NM_NETIF_ACTIVATED)
{
ECOMM_TRACE(UNILOG_DM, dmCheckifNetworkReady_1, P_INFO, 0, "network active");
return TRUE;
}
else
{
return FALSE;
}
}
static bool dmCheckNetworkReady(UINT8 waitTime)
{
bool result = TRUE;
NmAtiNetifInfo netInfo;
UINT32 start, end;
start = cissys_gettime()/osKernelGetTickFreq();
end = start;
// Check network for waitTime*2 seconds
UINT8 network=0;
while(end-start < waitTime)
{
appGetNetInfoSync(0, &netInfo);
if(netInfo.netStatus == NM_NETIF_ACTIVATED)
{
ECPLAT_PRINTF(UNILOG_DM, checkNetworkReady_1, P_INFO, "network ready");
network = 1;
break;
}
cissys_sleepms(500);
end = cissys_gettime()/osKernelGetTickFreq();
}
if(network == 0){
ECPLAT_PRINTF(UNILOG_DM, checkNetworkReady_2, P_INFO, "no network ");
result = FALSE;
}
return result;
}
static void dmConnectTask(void *arg)
{
while (running)
{
char logbuf[64] = {0};
snprintf(logbuf,64,"%s",DM_MACHINESTATE(stateMachine));
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_0, P_INFO, "handle stateMachine:%s", (uint8_t *)logbuf);
switch(stateMachine)
{
case DM_INIT_STATE:
case DM_SIM_READY:
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_0_1, P_INFO, "waiting for network ready");
osDelay(500/portTICK_PERIOD_MS);
break;
case DM_HEART_BEAT_UPDATE://to heartbeat
case DM_IPREADY_STATE://poweron to register
{
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_1, P_INFO, "network ready start dmTask and exit dmConnectTask");
osThreadAttr_t task_attr;
memset(&task_attr, 0, sizeof(task_attr));
task_attr.name = "dmtask";
task_attr.stack_mem = NULL;
task_attr.stack_size = DM_TASK_STACK_SIZE;
task_attr.priority = osPriorityBelowNormal7;
task_attr.cb_mem = NULL;
task_attr.cb_size = 0;
#ifdef TYPE_EC718M
task_attr.reserved = osThreadDynamicStackAlloc;
#endif
osThreadNew(dm_sample_dm_entry, NULL, &task_attr);
running = FALSE;
break;
}
case DM_HEART_BEAT_ARRIVED:
{
// wait 60s for network
if(dmCheckNetworkReady(120) != TRUE)
{
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_2_1, P_ERROR, "app update network connect error enable sleep go idle");
slpManPlatVoteEnableSleep(cmccDmSlpHandler, SLP_SLP2_STATE);
stateMachine = DM_IDLE_STATE;
}
else
{
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_2, P_INFO, "network ok send heartbeat");
stateMachine = DM_HEART_BEAT_UPDATE;
}
break;
}
case DM_NOT_RIGHT_SIM:
{
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_3, P_INFO, "not cmcc card exit connecttask");
slpManGivebackPlatVoteHandle(cmccDmSlpHandler);
running = FALSE;
break;
}
case DM_IDLE_STATE://nothing to do can handle key event
{
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_4, P_INFO, "nothing to do exit connecttask");
running = FALSE;
break;
}
default:
{
ECPLAT_PRINTF(UNILOG_DM, dmConnectTask_5, P_INFO, "unknown state exit connecttask");
running = FALSE;
break;
}
}
}
deregisterPSEventCallback((psEventCallback_t)dmPSUrcCallback);
osThreadExit();
}
void dmStartConncetTask()
{
osThreadAttr_t task_attr;
memset(&task_attr,0,sizeof(task_attr));
memset(dmconnTaskStack, 0xA5, DMCONN_TASK_STACK_SIZE);
task_attr.name = "dmConnTask";
task_attr.stack_mem = dmconnTaskStack;
task_attr.stack_size = DMCONN_TASK_STACK_SIZE;
task_attr.priority = osPriorityNormal;
task_attr.cb_mem = &dmconnTask;//task control block
task_attr.cb_size = sizeof(StaticTask_t);//size of task control block
#ifdef TYPE_EC718M
task_attr.reserved = osThreadDynamicStackAlloc;
#endif
running = TRUE;
osThreadNew(dmConnectTask, NULL, &task_attr);
}
void dmDeepSleepCb(uint8_t id)
{
ECPLAT_PRINTF(UNILOG_DM, deepSleepCb_1, P_SIG, "callback ID:%d come, disable slp2", id);
slpManPlatVoteDisableSleep(cmccDmSlpHandler, SLP_SLP2_STATE);
stateMachine = DM_HEART_BEAT_ARRIVED;
g_needUpdate = TRUE;
}
void dmDeepSleepTimerCbRegister(void)
{
slpManDeepSlpTimerRegisterExpCb(DEEPSLP_TIMER_ID8, (slpManUsrDeepSlpTimerCb_Func)dmDeepSleepCb);
}
void cmccAutoRegisterInit(MWNvmCfgDmCmccParam* pDmCmccParam, slpManSlpState_t slpState)
{
slpManApplyPlatVoteHandle("CMCC_DM",&cmccDmSlpHandler);
registerPSEventCallback(PS_GROUP_ALL_MASK, dmPSUrcCallback);
dmStartConncetTask();
dmCmccParam = pDmCmccParam;
if(dmCmccParam != NULL){
return;
}
if(dmCmccParam2 == NULL){
dmCmccParam2 = mallocEc(sizeof(MWNvmCfgDmCmccParam));
}
mwNvmCfgGetDmCmccParam2(dmCmccParam2);
needRestoreDMTask = ifNeedRestoreDMTask();
ECPLAT_PRINTF(UNILOG_DM, cmccAutoRegisterInit_0, P_INFO, "slpState = %d,needRestoreDMTask=%d",slpState,needRestoreDMTask);
if(slpState == SLP_HIB_STATE || slpState == SLP_SLP2_STATE)//wakeup from deep sleep
{
ECPLAT_PRINTF(UNILOG_DM, cmccAutoRegisterInit_0_1, P_INFO, "wakeup from deep sleep");
}
else
{
ECPLAT_PRINTF(UNILOG_DM, cmccAutoRegisterInit_0_2, P_INFO, "system reset, register DM");
if(needRestoreDMTask == TRUE){
dmCmccParam->bConnected = 0;
memset(dmCmccParam->location, 0, MID_WARE_DM_LOCATION_LEN);
mwNvmCfgSetAndSaveDmCmccParam(dmCmccParam);
needRestoreDMTask = FALSE;
}
}
}
#endif