/**************************************************************************** * * Copy right: 2017-, Copyrigths of EigenComm Ltd. * File name: cisAsynEntry.c * Description: EC616 onenet cis async entry source file * History: Rev1.0 2018-10-12 * ****************************************************************************/ #include #include #include "cisAsynEntry.h" #include "osasys.h" #include "task.h" #if defined CHIP_EC616 || defined CHIP_EC616_Z0 #include "slpman_ec616.h" #include "Flash_ec616_rt.h" #elif defined CHIP_EC617 #include "slpman_ec617.h" #include "Flash_ec617_rt.h" #endif #include "lfs_port.h" #include "debug_log.h" //#define DEBUG_SLEEP_BACKUP #define USE_PLAIN_BOOTSTRAP (0) #define ONENET_TASK_STACK_SIZE (1024*3) #define CIS_ENABLE_CONTEXT_RESTORE (1) #if 0 //authcode:EC616 psk:EIGENCOMM 183.230.40.39:5684 static const uint8_t config_hex[] = { 0x13, 0x00, 0x53, 0xf1, 0x00, 0x03, 0xf2, 0x00, 0x45, 0x05, 0x00 /*mtu*/, 0x11 /*Link & bind type*/, 0xC0 /*BS DTLS ENABLED*/, 0x00, 0x05 /*apn length*/, 0x43, 0x4d, 0x49, 0x4f, 0x54 /*apn: CMIOT*/, 0x00, 0x00 /*username length*/, /*username*/ 0x00, 0x00 /*password length*/, /*password*/ 0x00, 0x12 /*host length*/, 0x31, 0x38, 0x33, 0x2e, 0x32, 0x33, 0x30, 0x2e, 0x34, 0x30, 0x2e, 0x33, 0x39, 0x3a, 0x35, 0x36, 0x38, 0x34 /*host: 183.230.40.39:5684*/, 0x00, 0x1D /*userdata length*/, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x3a, 0x45, 0x43, 0x36, 0x31, 0x36, 0x3b, 0x50, 0x53, 0x4b, 0x3a, 0x45, 0x49, 0x47, 0x45, 0x4E, 0x43, 0x4F, 0x4D, 0x4D,0x3b /*userdata: AuthCode:EC616;PSK:EIGENCOMM;*/, 0xf3, 0x00, 0x08,0xe4 /*log config*/, 0x00, 0xc8 /*LogBufferSize: 200*/, 0x00, 0x00 /*userdata length*//*userdata*/ }; //authcode:EC616 psk:EIGENCOMM 183.230.40.40:5683 static const uint8_t config_hex[] = { 0x13, 0x00, 0x53, 0xf1, 0x00, 0x03, 0xf2, 0x00, 0x45, 0x05, 0x00 /*mtu*/, 0x11 /*Link & bind type*/, 0x00 /*BS DTLS DISABLED*/, 0x00, 0x05 /*apn length*/, 0x43, 0x4d, 0x49, 0x4f, 0x54 /*apn: CMIOT*/, 0x00, 0x00 /*username length*/, /*username*/ 0x00, 0x00 /*password length*/, /*password*/ 0x00, 0x12 /*host length*/, 0x31, 0x38, 0x33, 0x2e, 0x32, 0x33, 0x30, 0x2e, 0x34, 0x30, 0x2e, 0x34, 0x30, 0x3a, 0x35, 0x36, 0x38, 0x33 /*host: 183.230.40.40:5683*/, 0x00, 0x1D /*userdata length*/, 0x41, 0x75, 0x74, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x3a, 0x45, 0x43, 0x36, 0x31, 0x36, 0x3b, 0x50, 0x53, 0x4b, 0x3a, 0x45, 0x49, 0x47, 0x45, 0x4E, 0x43, 0x4F, 0x4D, 0x4D,0x3b /*userdata: AuthCode:EC616;PSK:EIGENCOMM;*/, 0xf3, 0x00, 0x08,0xe4 /*log config*/, 0x00, 0xc8 /*LogBufferSize: 200*/, 0x00, 0x00 /*userdata length*//*userdata*/ }; #endif //authcode: psk: 183.230.40.39:5683 enable bootstrap static const uint8_t config_hex[] = { 0x13, 0x00, 0x45, 0xf1, 0x00, 0x03, 0xf2, 0x00, 0x37, 0x05, 0x00 /*mtu*/, 0x11 /*Link & bind type*/, 0x80 /*BS ENABLE DTLS DISABLED*/, 0x00, 0x05 /*apn length*/, 0x43, 0x4d, 0x49, 0x4f, 0x54 /*apn: CMIOT*/, 0x00, 0x00 /*username length*/, /*username*/ 0x00, 0x00 /*password length*/, /*password*/ 0x00, 0x12 /*host length*/, 0x31, 0x38, 0x33, 0x2e, 0x32, 0x33, 0x30, 0x2e, 0x34, 0x30, 0x2e, 0x33, 0x39, 0x3a, 0x35, 0x36, 0x38, 0x33 /*host: 183.230.40.40: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, 0x08,0xe4 /*log config*/, 0x00, 0xc8 /*LogBufferSize: 200*/, 0x00, 0x00 /*userdata length*//*userdata*/ }; static StaticTask_t onenetTask; static osThreadId_t onenetTaskId = NULL; static uint8_t onenetTaskStack[ONENET_TASK_STACK_SIZE]; static void* gCisContext = NULL; static bool g_shutdown = false; static cis_time_t g_lifetimeLast = 0; static cis_time_t g_lifetime = 0; static cis_time_t g_notifyLast = 0; static bool gNotifyOngoing = false; static bool gNotifyOnceSuccess = false; static struct st_callback_info* g_callbackList = NULL; static struct st_observe_info* g_observeList = NULL; static st_sample_object g_objectList[SAMPLE_OBJECT_MAX]; static st_instance_a g_instList_a[SAMPLE_A_INSTANCE_COUNT]; static CHAR *defaultLocalPort = "40962"; static onenet_context_t gOnenetContextRunning; extern observed_backup_t g_observed_backup[MAX_OBSERVED_COUNT]; ////////////////////////////////////////////////////////////////////////// //private funcation; static void prvObserveNotify(void* context,cis_uri_t* uri,cis_mid_t mid) { uint8_t index; st_sample_object* object = NULL; cis_data_t value; for (index = 0;index < SAMPLE_OBJECT_MAX;index++) { if(g_objectList[index].oid == uri->objectId){ object = &g_objectList[index]; } } if(object == NULL){ ECOMM_TRACE(UNILOG_PLA_APP, prv_observeNotify_0, P_ERROR, 0, "prv_observeNotify return"); return; } ECOMM_TRACE(UNILOG_PLA_APP, prv_observeNotify_1, P_INFO, 0, "prv_observeNotify called"); if(!CIS_URI_IS_SET_INSTANCE(uri) && !CIS_URI_IS_SET_RESOURCE(uri)) { switch(uri->objectId) { case SAMPLE_OID_A: { for(index=0;indexenabled == true) { cis_data_t tmpdata[4]; tmpdata[0].type = cis_data_type_integer; tmpdata[0].value.asInteger = inst->instance.intValue; uri->instanceId = inst->instId; uri->resourceId = attributeA_intValue; cis_uri_update(uri); cis_notify_ec(context,uri,&tmpdata[0],mid,CIS_NOTIFY_CONTINUE,true, PS_SOCK_RAI_NO_INFO); tmpdata[2].type = cis_data_type_bool; tmpdata[2].value.asBoolean = inst->instance.boolValue; uri->resourceId = attributeA_boolValue; uri->instanceId = inst->instId; cis_uri_update(uri); cis_notify_ec(context,uri,&tmpdata[2],mid,CIS_NOTIFY_CONTINUE,true, PS_SOCK_RAI_NO_INFO); tmpdata[3].type = cis_data_type_string; tmpdata[3].asBuffer.length = strlen(inst->instance.strValue); tmpdata[3].asBuffer.buffer = (uint8_t*)(inst->instance.strValue); uri->resourceId = attributeA_stringValue; uri->instanceId = inst->instId; cis_uri_update(uri); cis_notify_ec(context,uri,&tmpdata[3],mid,CIS_NOTIFY_CONTENT,true, PS_SOCK_RAI_NO_INFO); } } } break; } }else if(CIS_URI_IS_SET_INSTANCE(uri)) { switch(object->oid) { case SAMPLE_OID_A: { if(uri->instanceId > SAMPLE_A_INSTANCE_COUNT){ return; } st_instance_a *inst = &g_instList_a[uri->instanceId]; if(inst == NULL || inst->enabled == false){ return; } if(CIS_URI_IS_SET_RESOURCE(uri)){ if(uri->resourceId == attributeA_intValue) { value.type = cis_data_type_integer; value.value.asInteger = inst->instance.intValue; } else if(uri->resourceId == attributeA_boolValue) { value.type = cis_data_type_bool; value.value.asBoolean = inst->instance.boolValue; } else if(uri->resourceId == attributeA_stringValue) { value.type = cis_data_type_string; value.asBuffer.length = strlen(inst->instance.strValue); value.asBuffer.buffer = (uint8_t*)(inst->instance.strValue); }else{ return; } cis_notify_ec(context,uri,&value,mid,CIS_NOTIFY_CONTENT,true, PS_SOCK_RAI_NO_INFO); }else{ cis_data_t tmpdata[4]; tmpdata[0].type = cis_data_type_integer; tmpdata[0].value.asInteger = inst->instance.intValue; uri->resourceId = attributeA_intValue; cis_uri_update(uri); cis_notify_ec(context,uri,&tmpdata[0],mid,CIS_NOTIFY_CONTINUE,true, PS_SOCK_RAI_NO_INFO); tmpdata[2].type = cis_data_type_bool; tmpdata[2].value.asBoolean = inst->instance.boolValue; uri->resourceId = attributeA_boolValue; cis_uri_update(uri); cis_notify_ec(context,uri,&tmpdata[2],mid,CIS_NOTIFY_CONTINUE,true, PS_SOCK_RAI_NO_INFO); tmpdata[3].type = cis_data_type_string; tmpdata[3].asBuffer.length = strlen(inst->instance.strValue); tmpdata[3].asBuffer.buffer = (uint8_t*)(inst->instance.strValue); uri->resourceId = attributeA_stringValue; cis_uri_update(uri); cis_notify_ec(context,uri,&tmpdata[3],mid,CIS_NOTIFY_CONTENT,true, PS_SOCK_RAI_NO_INFO); } } break; } } } static void prvReadResponse(void* context,cis_uri_t* uri,cis_mid_t mid) { uint8_t index; st_sample_object* object = NULL; cis_data_t value; for (index = 0;index < SAMPLE_OBJECT_MAX;index++) { if(g_objectList[index].oid == uri->objectId){ object = &g_objectList[index]; } } if(object == NULL){ return; } if(!CIS_URI_IS_SET_INSTANCE(uri) && !CIS_URI_IS_SET_RESOURCE(uri)) // one object { switch(uri->objectId) { case SAMPLE_OID_A: { for(index=0;indexenabled == true) { cis_data_t tmpdata[4]; tmpdata[0].type = cis_data_type_integer; tmpdata[0].value.asInteger = inst->instance.intValue; uri->instanceId = inst->instId; uri->resourceId = attributeA_intValue; cis_uri_update(uri); cis_response(context,uri,&tmpdata[0],mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); tmpdata[2].type = cis_data_type_bool; tmpdata[2].value.asBoolean = inst->instance.boolValue; uri->resourceId = attributeA_boolValue; uri->instanceId = inst->instId; cis_uri_update(uri); cis_response(context,uri,&tmpdata[2],mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); tmpdata[3].type = cis_data_type_string; tmpdata[3].asBuffer.length = strlen(inst->instance.strValue); tmpdata[3].asBuffer.buffer = (uint8_t*)strdup(inst->instance.strValue); uri->resourceId = attributeA_stringValue; uri->instanceId = inst->instId; cis_uri_update(uri); cis_response(context,uri,&tmpdata[3],mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); } } } break; } cis_response(context,NULL,NULL,mid,CIS_RESPONSE_READ, PS_SOCK_RAI_NO_INFO); }else { switch(object->oid) { case SAMPLE_OID_A: { if(uri->instanceId > SAMPLE_A_INSTANCE_COUNT){ return; } st_instance_a *inst = &g_instList_a[uri->instanceId]; if(inst == NULL || inst->enabled == false){ return; } if(CIS_URI_IS_SET_RESOURCE(uri)){ if(uri->resourceId == attributeA_intValue) { value.type = cis_data_type_integer; value.value.asInteger = inst->instance.intValue; } else if(uri->resourceId == attributeA_boolValue) { value.type = cis_data_type_bool; value.value.asBoolean = inst->instance.boolValue; } else if(uri->resourceId == attributeA_stringValue) { value.type = cis_data_type_string; value.asBuffer.length = strlen(inst->instance.strValue); value.asBuffer.buffer = (uint8_t*)strdup(inst->instance.strValue); }else{ return; } cis_response(context,uri,&value,mid,CIS_RESPONSE_READ, PS_SOCK_RAI_NO_INFO); }else{ cis_data_t tmpdata[4]; tmpdata[0].type = cis_data_type_integer; tmpdata[0].value.asInteger = inst->instance.intValue; uri->resourceId = attributeA_intValue; cis_uri_update(uri); cis_response(context,uri,&tmpdata[0],mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); tmpdata[2].type = cis_data_type_bool; tmpdata[2].value.asBoolean = inst->instance.boolValue; uri->resourceId = attributeA_boolValue; cis_uri_update(uri); cis_response(context,uri,&tmpdata[2],mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); tmpdata[3].type = cis_data_type_string; tmpdata[3].asBuffer.length = strlen(inst->instance.strValue); tmpdata[3].asBuffer.buffer = (uint8_t*)strdup(inst->instance.strValue); uri->resourceId = attributeA_stringValue; cis_uri_update(uri); cis_response(context,uri,&tmpdata[3],mid,CIS_RESPONSE_READ, PS_SOCK_RAI_NO_INFO); } } break; } } } static void prvDiscoverResponse(void* context,cis_uri_t* uri,cis_mid_t mid) { uint8_t index; st_sample_object* object = NULL; for (index = 0;index < SAMPLE_OBJECT_MAX;index++) { if(g_objectList[index].oid == uri->objectId){ object = &g_objectList[index]; } } if(object == NULL){ return; } switch(uri->objectId) { case SAMPLE_OID_A: { uri->objectId = SAMPLE_OID_A; uri->instanceId = 0; uri->resourceId = attributeA_intValue; cis_uri_update(uri); cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); uri->objectId = SAMPLE_OID_A; uri->instanceId = 0; uri->resourceId = attributeA_boolValue; cis_uri_update(uri); cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); uri->objectId = SAMPLE_OID_A; uri->instanceId = 0; uri->resourceId = attributeA_stringValue; cis_uri_update(uri); cis_response(context,uri,NULL,mid,CIS_RESPONSE_CONTINUE, PS_SOCK_RAI_NO_INFO); } break; } cis_response(context,NULL,NULL,mid,CIS_RESPONSE_DISCOVER, PS_SOCK_RAI_NO_INFO); } static void prvWriteResponse(void* context,cis_uri_t* uri,const cis_data_t* value,cis_attrcount_t count,cis_mid_t mid) { uint8_t index; st_sample_object* object = NULL; if(!CIS_URI_IS_SET_INSTANCE(uri)) { return; } for (index = 0;index < SAMPLE_OBJECT_MAX;index++) { if(g_objectList[index].oid == uri->objectId){ object = &g_objectList[index]; } } if(object == NULL){ return; } switch(object->oid) { case SAMPLE_OID_A: { if(uri->instanceId > SAMPLE_A_INSTANCE_COUNT){ return; } st_instance_a *inst = &g_instList_a[uri->instanceId]; if(inst == NULL || inst->enabled == false){ return; } for (int i=0;iobjectId,uri->instanceId,value[i].id); switch(value[i].id) { case attributeA_intValue: { if(value[i].type == cis_data_type_string){ inst->instance.intValue = atoi((const char*)value[i].asBuffer.buffer); }else{ inst->instance.intValue = value[i].value.asInteger; } } break; case attributeA_boolValue: { if(value[i].type == cis_data_type_string){ inst->instance.boolValue = atoi((const char*)value[i].asBuffer.buffer); }else{ inst->instance.boolValue = value[i].value.asBoolean; } } break; case attributeA_stringValue: { memset(inst->instance.strValue,0,sizeof(inst->instance.strValue)); strncpy(inst->instance.strValue,(char*)value[i].asBuffer.buffer,value[i].asBuffer.length); } break; } } } break; } cis_response(context,NULL,NULL,mid,CIS_RESPONSE_WRITE, PS_SOCK_RAI_NO_INFO); } static void prvExecResponse(void* context,cis_uri_t* uri,const uint8_t* value,uint32_t length,cis_mid_t mid) { uint8_t index; st_sample_object* object = NULL; for (index = 0;index < SAMPLE_OBJECT_MAX;index++) { if(g_objectList[index].oid == uri->objectId){ object = &g_objectList[index]; } } if(object == NULL){ return; } switch(object->oid) { case SAMPLE_OID_A: { if(uri->instanceId > SAMPLE_A_INSTANCE_COUNT){ return; } st_instance_a *inst = &g_instList_a[uri->instanceId]; if(inst == NULL || inst->enabled == false){ return; } if(uri->resourceId == actionA_1) { /* *\call action; */ ECOMM_TRACE(UNILOG_PLA_APP, prvExecResponse_1, P_INFO, 0, "exec actionA_action"); cis_response(context,NULL,NULL,mid,CIS_RESPONSE_EXECUTE, PS_SOCK_RAI_NO_INFO); }else{ return; } } break; } }; static void prvParamsResponse (void* context, cis_uri_t* uri, cis_observe_attr_t parameters, cis_mid_t mid) { uint8_t index; st_sample_object* object = NULL; if(CIS_URI_IS_SET_RESOURCE(uri)){ ECOMM_TRACE(UNILOG_PLA_APP, prvParamsResponse_1, P_INFO, 3, "prvParamsResponse (%d/%d/%d)", uri->objectId,uri->instanceId,uri->resourceId); } if(!CIS_URI_IS_SET_INSTANCE(uri)) { return; } for (index = 0;index < SAMPLE_OBJECT_MAX;index++) { if(g_objectList[index].oid == uri->objectId){ object = &g_objectList[index]; } } if(object == NULL){ return; } /*set parameter to observe resource*/ ECOMM_TRACE(UNILOG_PLA_APP, prvParamsResponse_2, P_INFO, 2, "prvParamsResponse set:%x,clr:%x", parameters.toSet, parameters.toClear); ECOMM_TRACE(UNILOG_PLA_APP, prvParamsResponse_3, P_INFO, 5, "prvParamsResponse min:%d,max:%d,gt:%f,lt:%f,st:%f", parameters.minPeriod,parameters.maxPeriod,parameters.greaterThan,parameters.lessThan,parameters.step); cis_response(context,NULL,NULL,mid,CIS_RESPONSE_OBSERVE_PARAMS, PS_SOCK_RAI_NO_INFO); } static cis_data_t* prvDataDup(const cis_data_t* value,cis_attrcount_t attrcount) { cis_attrcount_t index; cis_data_t* newData; newData =(cis_data_t*)cissys_malloc(attrcount * sizeof(cis_data_t)); if(newData == NULL) { return NULL; } for (index =0;index < attrcount;index++) { newData[index].id = value[index].id; newData[index].type = value[index].type; newData[index].asBuffer.length = value[index].asBuffer.length; newData[index].asBuffer.buffer = (uint8_t*)cissys_malloc(value[index].asBuffer.length); memcpy(newData[index].asBuffer.buffer,value[index].asBuffer.buffer,value[index].asBuffer.length); memcpy(&newData[index].value.asInteger,&value[index].value.asInteger,sizeof(newData[index].value)); } return newData; } static void prvUpdateObserveContext() { struct st_observe_info* node = g_observeList; uint8_t i = 0; while(node != NULL) { ECOMM_TRACE(UNILOG_PLA_APP, prvUpdateObserveContext_0, P_INFO, 1, "prvUpdateObserveContext mid=%d", node->mid); node = node->next; i++; } gOnenetContextRunning.observeObjNum = i; #ifdef DEBUG_SLEEP_BACKUP printf("prvUpdateObserveContext:"); for(int j= 0; j < sizeof(observed_backup_t); j ++) printf("%d ", ((UINT8*)&(g_observed_backup[0]))[j]); printf("\n"); #endif memcpy((uint8_t *)&(gOnenetContextRunning.gObservedBackup[0]), &(g_observed_backup[0]), MAX_OBSERVED_COUNT*sizeof(observed_backup_t)); if(BSP_QSPI_Erase_Safe(APP_BACKUP_NONXIP_ADDR, APP_BACKUP_SIZE) != QSPI_OK) //erase { ECOMM_TRACE(UNILOG_PLA_APP, prvUpdateObserveContext_1, P_ERROR, 0, "erase flash error!!!"); } ECOMM_TRACE(UNILOG_PLA_APP, prvUpdateObserveContext_2, P_INFO, 0, "prvUpdateObserveContext BSP_QSPI_Write_Safe"); if(BSP_QSPI_Write_Safe((uint8_t *)&gOnenetContextRunning, APP_BACKUP_NONXIP_ADDR, sizeof(onenet_context_t))!=QSPI_OK) //programe { ECOMM_TRACE(UNILOG_PLA_APP, prvUpdateObserveContext_3, P_ERROR, 0, "write flash error!!!"); } } void prvMakeUserdata() { int i = 0; cis_instcount_t instIndex; cis_instcount_t instCount; for (i= 0;i < SAMPLE_OBJECT_MAX; i++) { st_sample_object* obj = &g_objectList[i]; switch(i){ case 0: { obj->oid = SAMPLE_OID_A; obj->instBitmap = SAMPLE_A_INSTANCE_BITMAP; instCount = SAMPLE_A_INSTANCE_COUNT; for (instIndex = 0;instIndex < instCount;instIndex++) { if(obj->instBitmap[instIndex] != '1'){ g_instList_a[instIndex].instId = instIndex; g_instList_a[instIndex].enabled = false; } else { g_instList_a[instIndex].instId = instIndex; g_instList_a[instIndex].enabled = true; g_instList_a[instIndex].instance.boolValue = true; g_instList_a[instIndex].instance.intValue = cissys_rand() % 100; strcpy(g_instList_a[instIndex].instance.strValue,"temp test"); } } obj->attrCount = sizeof(const_AttrIds_a) / sizeof(cis_rid_t); obj->attrListPtr = const_AttrIds_a; obj->actCount = 0; obj->actListPtr = NULL; } break; } } } ////////////////////////////////////////////////////////////////////////// cis_coapret_t cisAsynOnRead(void* context,cis_uri_t* uri,cis_mid_t mid) { struct st_callback_info* newNode = (struct st_callback_info*)cissys_malloc(sizeof(struct st_callback_info)); newNode->next = NULL; newNode->flag = (et_callback_type_t)CIS_CALLBACK_READ; newNode->mid = mid; newNode->uri = *uri; g_callbackList = (struct st_callback_info*)CIS_LIST_ADD(g_callbackList,newNode); ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnRead_1, P_SIG, 3, "cisAsynOnRead (%d/%d/%d)", uri->objectId,uri->instanceId,uri->resourceId); return CIS_CALLBACK_CONFORM; } cis_coapret_t cisAsynOnDiscover(void* context,cis_uri_t* uri,cis_mid_t mid) { struct st_callback_info* newNode = (struct st_callback_info*)cissys_malloc(sizeof(struct st_callback_info)); newNode->next = NULL; newNode->flag = (et_callback_type_t)CIS_CALLBACK_DISCOVER; newNode->mid = mid; newNode->uri = *uri; g_callbackList = (struct st_callback_info*)CIS_LIST_ADD(g_callbackList,newNode); ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnDiscover_1, P_SIG, 3, "cisAsynOnDiscover (%d/%d/%d)", uri->objectId,uri->instanceId,uri->resourceId); return CIS_CALLBACK_CONFORM; } cis_coapret_t cisAsynOnWrite(void* context,cis_uri_t* uri,const cis_data_t* value,cis_attrcount_t attrcount,cis_mid_t mid) { if(CIS_URI_IS_SET_RESOURCE(uri)){ ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnWrite_1, P_SIG, 3, "cisAsynOnWrite (%d/%d/%d)", uri->objectId,uri->instanceId,uri->resourceId); } else{ ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnWrite_2, P_SIG, 2, "cisAsynOnWrite (%d/%d)", uri->objectId,uri->instanceId); } struct st_callback_info* newNode = (struct st_callback_info*)cissys_malloc(sizeof(struct st_callback_info)); newNode->next = NULL; newNode->flag = (et_callback_type_t)CIS_CALLBACK_WRITE; newNode->mid = mid; newNode->uri = *uri; newNode->param.asWrite.count = attrcount; newNode->param.asWrite.value = prvDataDup(value,attrcount); g_callbackList = (struct st_callback_info*)CIS_LIST_ADD(g_callbackList,newNode); return CIS_CALLBACK_CONFORM; } cis_coapret_t cisAsynOnExec(void* context,cis_uri_t* uri,const uint8_t* value,uint32_t length,cis_mid_t mid) { if(CIS_URI_IS_SET_RESOURCE(uri)) { ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnExec_1, P_SIG, 3, "cisAsynOnExec (%d/%d/%d)", uri->objectId,uri->instanceId,uri->resourceId); } else{ return CIS_CALLBACK_METHOD_NOT_ALLOWED; } if(!CIS_URI_IS_SET_INSTANCE(uri)) { return CIS_CALLBACK_BAD_REQUEST; } struct st_callback_info* newNode = (struct st_callback_info*)cissys_malloc(sizeof(struct st_callback_info)); newNode->next = NULL; newNode->flag = (et_callback_type_t)CIS_CALLBACK_EXECUTE; newNode->mid = mid; newNode->uri = *uri; newNode->param.asExec.buffer = (uint8_t*)cissys_malloc(length); newNode->param.asExec.length = length; memcpy(newNode->param.asExec.buffer,value,length); g_callbackList = (struct st_callback_info*)CIS_LIST_ADD(g_callbackList,newNode); return CIS_CALLBACK_CONFORM; } cis_coapret_t cisAsynOnObserve(void* context,cis_uri_t* uri,bool flag,cis_mid_t mid) { ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnObserve_1, P_SIG, 3, "cisAsynOnObserve mid:%d uri:(%d/%d/%d)",mid,uri->objectId,uri->instanceId,uri->resourceId); if(!CIS_URI_IS_SET_INSTANCE(uri)) { return CIS_CALLBACK_BAD_REQUEST; } struct st_callback_info* newNode = (struct st_callback_info*)cissys_malloc(sizeof(struct st_callback_info)); newNode->next = NULL; newNode->flag = (et_callback_type_t)CIS_CALLBACK_OBSERVE; newNode->mid = mid; newNode->uri = *uri; newNode->param.asObserve.flag = flag; g_callbackList = (struct st_callback_info*)CIS_LIST_ADD(g_callbackList,newNode); return CIS_CALLBACK_CONFORM; } cis_coapret_t cisAsynOnParams(void* context,cis_uri_t* uri,cis_observe_attr_t parameters,cis_mid_t mid) { if(CIS_URI_IS_SET_RESOURCE(uri)){ ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnParams_0, P_SIG, 3, "cisAsynOnParams=(%d/%d/%d)", uri->objectId,uri->instanceId,uri->resourceId); } if(!CIS_URI_IS_SET_INSTANCE(uri)) { return CIS_CALLBACK_BAD_REQUEST; } struct st_callback_info* newNode = (struct st_callback_info*)cissys_malloc(sizeof(struct st_callback_info)); newNode->next = NULL; newNode->flag = (et_callback_type_t)CIS_CALLBACK_SETPARAMS; newNode->mid = mid; newNode->uri = *uri; newNode->param.asObserveParam.params = parameters; g_callbackList = (struct st_callback_info*)CIS_LIST_ADD(g_callbackList,newNode); return CIS_CALLBACK_CONFORM; } void cisAsynOnEvent(void* context,cis_evt_t eid,void* param) { ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnEvent_0, P_SIG, 1, "cisAsynOnEvent=%d", eid); switch(eid) { case CIS_EVENT_RESPONSE_FAILED: case CIS_EVENT_NOTIFY_FAILED: gNotifyOngoing = false; ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnEvent_2, P_INFO, 1, "cisAsynOnEvent response failed mid:%d", (int32_t)param); break; case CIS_EVENT_NOTIFY_SUCCESS: gNotifyOngoing = false; cisAsynSetNotifyOnceStatus(true); break; case CIS_EVENT_UPDATE_NEED: ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnEvent_3, P_INFO, 1, "cisAsynOnEvent need to update,reserve time:%ds", (int32_t)param); cis_update_reg(gCisContext,LIFETIME_INVALID,false, PS_SOCK_RAI_NO_INFO); break; case CIS_EVENT_REG_SUCCESS: { ECOMM_TRACE(UNILOG_PLA_APP, cisAsynOnEvent_4, P_INFO, 1, "cisAsynOnEvent=CIS_EVENT_REG_SUCCESS, will clean g_observeList"); struct st_observe_info* delnode; while(g_observeList != NULL){ g_observeList =(struct st_observe_info *)CIS_LIST_RM((cis_list_t *)g_observeList,g_observeList->mid,(cis_list_t **)&delnode); cissys_free(delnode); } } break; case CIS_EVENT_OBSERVE_ADD: case CIS_EVENT_OBSERVE_CANCEL: prvUpdateObserveContext(); break; default: break; } } bool cisAsynGetShutdown(void) { return g_shutdown; } void cisAsynSetShutdown(bool shutdown) { g_shutdown = shutdown; } bool cisAsynGetNotifyOnceStatus(void) { return gNotifyOnceSuccess; } void cisAsynSetNotifyOnceStatus(bool success) { gNotifyOnceSuccess = success; } static void cisAsyncProcessTask(void* lpParam) { while(1) { struct st_callback_info* node; if(g_callbackList == NULL || g_shutdown == TRUE) { cissys_sleepms(1000); continue; } node = g_callbackList; g_callbackList = g_callbackList->next; switch (node->flag) { case 0: break; case CIS_CALLBACK_READ: { ECOMM_TRACE(UNILOG_PLA_APP, cisProcessThread_0, P_SIG, 0, "cisProcessThread CIS_CALLBACK_READ"); cis_uri_t uriLocal; uriLocal = node->uri; prvReadResponse(gCisContext,&uriLocal,node->mid); } break; case CIS_CALLBACK_DISCOVER: { ECOMM_TRACE(UNILOG_PLA_APP, cisProcessThread_1, P_SIG, 0, "cisProcessThread CIS_CALLBACK_DISCOVER"); cis_uri_t uriLocal; uriLocal = node->uri; prvDiscoverResponse(gCisContext,&uriLocal,node->mid); } break; case CIS_CALLBACK_WRITE: { ECOMM_TRACE(UNILOG_PLA_APP, cisProcessThread_2, P_SIG, 0, "cisProcessThread CIS_CALLBACK_WRITE"); prvWriteResponse(gCisContext,&node->uri,node->param.asWrite.value,node->param.asWrite.count,node->mid); cis_data_t* data = node->param.asWrite.value; cis_attrcount_t count = node->param.asWrite.count; for (int i=0;iuri,node->param.asExec.buffer,node->param.asExec.length,node->mid); cissys_free(node->param.asExec.buffer); } break; case CIS_CALLBACK_SETPARAMS: { ECOMM_TRACE(UNILOG_PLA_APP, cisProcessThread_4, P_SIG, 0, "cisProcessThread CIS_CALLBACK_SETPARAMS"); //set parameters and notify prvParamsResponse(gCisContext,&node->uri,node->param.asObserveParam.params,node->mid); } break; case CIS_CALLBACK_OBSERVE: { LOGD("observe callback mid=%d flag=%d\r\n", node->mid, node->param.asObserve.flag); if(node->param.asObserve.flag) { uint16_t count = 0; struct st_observe_info* observe_new = (struct st_observe_info*)cissys_malloc(sizeof(struct st_observe_info)); observe_new->mid = node->mid; observe_new->uri = node->uri; observe_new->next = NULL; // mid change every time once register g_observeList = (struct st_observe_info*)cis_list_add((cis_list_t*)g_observeList,(cis_list_t*)observe_new); cis_response(gCisContext,NULL,NULL,node->mid,CIS_RESPONSE_OBSERVE, PS_SOCK_RAI_NO_INFO); ECOMM_TRACE(UNILOG_PLA_APP, cisProcessThread_5, P_INFO, 4, "cisProcessThread CIS_CALLBACK_OBSERVE set(%d): %d/%d/%d", count, observe_new->uri.objectId, CIS_URI_IS_SET_INSTANCE(&observe_new->uri)?observe_new->uri.instanceId:-1, CIS_URI_IS_SET_RESOURCE(&observe_new->uri)?observe_new->uri.resourceId:-1); } else { struct st_observe_info* delnode = g_observeList; while (delnode) { if (node->uri.flag == delnode->uri.flag && node->uri.objectId == delnode->uri.objectId) { if (node->uri.instanceId == delnode->uri.instanceId) { if (node->uri.resourceId == delnode->uri.resourceId) { break; } } } delnode = delnode->next; } if (delnode != NULL) { g_observeList = (struct st_observe_info *)cis_list_remove((cis_list_t *)g_observeList, delnode->mid, (cis_list_t **)&delnode); ECOMM_TRACE(UNILOG_PLA_APP, cisProcessThread_6, P_INFO, 3, "cis_on_observe cancel: %d/%d/%d\n", delnode->uri.objectId, CIS_URI_IS_SET_INSTANCE(&delnode->uri) ? delnode->uri.instanceId : -1, CIS_URI_IS_SET_RESOURCE(&delnode->uri) ? delnode->uri.resourceId : -1); cis_free(delnode); cis_response(gCisContext, NULL, NULL, node->mid, CIS_RESPONSE_OBSERVE, PS_SOCK_RAI_NO_INFO); } else { return; } } } break; default: break; } cissys_free(node); } } void cisAsyncUpdatePumpState(et_client_state_t state) { if(gOnenetContextRunning.pumpState != state) gOnenetContextRunning.pumpState = state; } void cisAsyncAddObject() { int index = 0; for (index= 0;index < 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; st_sample_object* obj = &g_objectList[index]; oid = obj->oid; instCount = strlen(obj->instBitmap); instBytes = (instCount - 1) / 8 + 1; instAsciiPtr = obj->instBitmap; instPtr = (uint8_t*)cissys_malloc(instBytes); memset(instPtr,0,instBytes); for (i = 0;i < instCount;i++) { 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(gCisContext,oid,&bitmap,&rescount); cissys_free(instPtr); } } void cisAsyncRegister() { g_lifetime = 36000; cis_callback_t callback; callback.onRead = cisAsynOnRead; callback.onWrite = cisAsynOnWrite; callback.onExec = cisAsynOnExec; callback.onObserve = cisAsynOnObserve; callback.onSetParams = cisAsynOnParams; callback.onEvent = cisAsynOnEvent; callback.onDiscover = cisAsynOnDiscover; cis_register(gCisContext,g_lifetime,&callback); } bool cisAsyncCheckNotificationReady() { if (gCisContext == NULL) return FALSE; else return ((((st_context_t*)gCisContext)->stateStep == PUMP_STATE_READY) && (((st_context_t*)gCisContext)->observedList != NULL)); } void cisAsyncBackup(void *pdata, slpManLpState state) { ECOMM_TRACE(UNILOG_PLA_APP, cisAsyncBackup_0, P_ERROR, 0, "Enter cisAsyncBackup"); memcpy((uint8_t *)&(gOnenetContextRunning.gObservedBackup[0]), &(g_observed_backup[0]), MAX_OBSERVED_COUNT*sizeof(observed_backup_t)); #if USE_LITTLEFS int32_t ret; lfs_file_t file; ret = LFS_FileOpen(&file, "cisSlpCntxt", LFS_O_WRONLY); OsaCheck(ret == 0,0,0,0); ret = LFS_FileWrite(&file, &gOnenetContextRunning, sizeof(onenet_context_t)); OsaCheck(ret == sizeof(onenet_context_t),ret,0,0); LFS_FileClose(&file); #endif } void cisAsyncRestore() { uint8_t i; ECOMM_TRACE(UNILOG_PLA_APP, cisAsyncRestore_0, P_SIG, 0, "Enter cisAsyncRestore"); #if USE_LITTLEFS int32_t ret; lfs_file_t file; ret = LFS_FileOpen(&file, "cisSlpCntxt", LFS_O_RDONLY | LFS_O_CREAT); OsaCheck(ret == 0,0,0,0); ret = LFS_FileRead(&file, &gOnenetContextRunning, sizeof(onenet_context_t)); OsaCheck(ret >= 0,ret,0,0); LFS_FileClose(&file); #else memcpy((uint8_t *)&gOnenetContextRunning,(void*)APP_BACKUP_XIP_ADDR,sizeof(onenet_context_t)); #endif // Restore for cis core using memcpy((uint8_t *)(&(g_observed_backup[0])), (uint8_t *)&(gOnenetContextRunning.gObservedBackup[0]), MAX_OBSERVED_COUNT*sizeof(observed_backup_t)); // Restore for cis app using LOGD("observeObjNum =%d\r\n", gOnenetContextRunning.observeObjNum); for (i = 0; i < gOnenetContextRunning.observeObjNum; i++) { struct st_observe_info* observe_new = (struct st_observe_info*)cissys_malloc(sizeof(struct st_observe_info)); memset((uint8_t *)observe_new, 0, sizeof(struct st_observe_info)); observe_new->mid = g_observed_backup[i].msgid; LOGD("mid=%d\r\n", observe_new->mid); cis_memcpy(&(observe_new->uri), &(g_observed_backup[i].uri), sizeof(st_uri_t)); cis_memcpy(&(observe_new->params), &(g_observed_backup[i].params), sizeof(cis_observe_attr_t)); observe_new->next = NULL; g_observeList = (struct st_observe_info*)cis_list_add((cis_list_t*)g_observeList,(cis_list_t*)observe_new); } } void cisDataObserveReport() { uint32_t nowtime; /*data observe data report*/ nowtime = cissys_gettime(); struct st_observe_info* node = g_observeList; if (node == NULL) return; ECOMM_TRACE(UNILOG_PLA_APP, cisDataObserveReport_0, P_INFO, 2, "cisDataObserveReport g_notifyLast=%d nowtime=%d", g_notifyLast, nowtime); // if diff time is more than 10S, continue to allow to report if((nowtime - g_notifyLast > 10*1000) && (!gNotifyOngoing)) { g_notifyLast = nowtime; while(node != NULL) { if(node->mid == 0) { ECOMM_TRACE(UNILOG_PLA_APP, cisDataObserveReport_1, P_INFO, 0, "cisDataObserveReport mid = 0"); node = node->next; continue; } if(node->uri.flag == 0) { ECOMM_TRACE(UNILOG_PLA_APP, cisDataObserveReport_2, P_INFO, 0, "cisDataObserveReport uri flag = 0"); node = node->next; continue; } cis_uri_t uriLocal; uriLocal = node->uri; prvObserveNotify(gCisContext,&uriLocal,node->mid); node = node->next; ECOMM_TRACE(UNILOG_PLA_APP, cisDataObserveReport_3, P_INFO, 0, "cisDataObserveReport"); gNotifyOngoing = true; } } if ((nowtime - g_notifyLast > 20*100)&&(gNotifyOngoing)) { ECOMM_TRACE(UNILOG_PLA_APP, cisDataObserveReport_4, P_ERROR, 0, "cisDataObserveReport too long reset gNotifyOngoing"); gNotifyOngoing = false; } } void cisAsyncProcess(void *arg) { if(cis_init(&gCisContext,(void *)config_hex,sizeof(config_hex),NULL, defaultLocalPort) != CIS_RET_OK){ ECOMM_TRACE(UNILOG_PLA_APP, cis_sample_entry_1, P_ERROR, 0, "cis entry init failed."); LOGD("cis entry init failed.\n"); if (gCisContext != NULL) cis_deinit(&gCisContext); return; } if(pmuBWakeupFromHib() || pmuBWakeupFromSleep2()) { cisAsyncRestore(); ECOMM_TRACE(UNILOG_PLA_APP, cis_sample_entry_0, P_INFO, 1, "wakeup from hib continue pumpState=%d", gOnenetContextRunning.pumpState); if (gOnenetContextRunning.pumpState == PUMP_STATE_READY || gOnenetContextRunning.pumpState == PUMP_STATE_CONNECTING) { #if CIS_ENABLE_CONTEXT_RESTORE ((st_context_t*)gCisContext)->ignoreRegistration = true; ((st_context_t*)gCisContext)->stateStep = PUMP_STATE_CONNECTING; #else ((st_context_t*)gCisContext)->stateStep = PUMP_STATE_INITIAL; #endif cisAsyncUpdatePumpState(((st_context_t*)gCisContext)->stateStep); } observe_read_retention_data(gCisContext); cisAsyncAddObject(); cisAsyncRegister(); } else { cisAsyncAddObject(); cisAsyncRegister(); } g_shutdown = false; xTaskCreate(cisAsyncProcessTask,"cisAsyncProc", 512, NULL, osPriorityBelowNormal7, NULL); while(1) { uint32_t nowtime; if (g_shutdown) { cissys_sleepms(3000); continue; } /*pump function*/ cis_pump(gCisContext); cisAsyncUpdatePumpState(((st_context_t*)gCisContext)->stateStep); cissys_sleepms(1000); /*update lifetime*/ nowtime = cissys_gettime(); if(nowtime - g_lifetimeLast > ((g_lifetime * 1000) * 0.6)){ g_lifetimeLast = cissys_gettime(); cis_update_reg(gCisContext,LIFETIME_INVALID,false, PS_SOCK_RAI_NO_INFO); } } } void cisAsyncTask(void *arg) { while(1) { cisAsyncProcess(arg); cissys_sleepms(1000); } } void cisOnenetInit() { osThreadAttr_t task_attr; slpManRet_t ret; ret = slpManRegisterUsrdefinedBackupCb(cisAsyncBackup, NULL,SLPMAN_HIBERNATE_STATE); OsaCheck(ret == RET_TRUE,0,0,0); memset(&task_attr, 0, sizeof(osThreadAttr_t)); task_attr.name = "cisAsyncTask"; task_attr.stack_mem = onenetTaskStack; task_attr.stack_size = ONENET_TASK_STACK_SIZE; task_attr.priority = osPriorityBelowNormal7; task_attr.cb_mem = &onenetTask; task_attr.cb_size = sizeof(StaticTask_t); memset(onenetTaskStack, 0xA5, ONENET_TASK_STACK_SIZE); memset((uint8_t *)&gOnenetContextRunning, 0x00, sizeof(gOnenetContextRunning)); onenetTaskId = osThreadNew(cisAsyncTask, NULL,&task_attr); } void cisOnenetDeinit() { slpManUnregisterUsrdefinedBackupCb(cisAsyncBackup); osThreadTerminate(onenetTaskId); onenetTaskId = NULL; }