945 lines
37 KiB
C
Raw Normal View History

2025-04-10 17:31:33 +08:00
/****************************************************************************
*
* 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