/**************************************************************************** * * 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 #if CIS_ENABLE_DM #include #include #include #include #include #include #include "cmcc_dm.h" #include #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);//实例的个数包括不使能的实例 instBytes = (instCount - 1) / 8 + 1;//要用多少个字节来表示实例,每个实例占用一位 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++)//这一段代码的意思是把类似"1101"的二进制字符串转换为二进制数据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);//将回调函数注册进SDK内 } } /*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