void uartRecv_thread(void *inContext) { user_uart_log_trace(); mico_Context_t *Context = inContext; int recvlen; uint8_t *inDataBuffer; OSStatus err = kUnknownErr; inDataBuffer = malloc(UART_ONE_PACKAGE_LENGTH); require(inDataBuffer, exit); while(1) { // get msg from uart recvlen = _uart_get_one_packet(inDataBuffer, UART_ONE_PACKAGE_LENGTH); if (recvlen <= 0) continue; user_uart_log("UART => Module: [%d]=%.*s", recvlen, recvlen, inDataBuffer); // transfer msg to cloud err = MicoFogCloudMsgSend(Context, NULL, 0, inDataBuffer, recvlen); if(kNoErr == err){ user_uart_log("Msg send to cloud success!"); } else{ user_uart_log("Msgsend to cloud failed! err=%d.", err); } } exit: if(inDataBuffer) free(inDataBuffer); }
OSStatus _properties_notify(mico_Context_t * const inContext, struct mico_service_t service_table[]) { OSStatus err = kUnknownErr; json_object *notify_obj = NULL; const char *notify_json_string = NULL; require_action(inContext, exit, err = kParamErr); notify_obj = json_object_new_object(); require_action(notify_obj, exit, err = kParamErr); // properties update check err = mico_properties_notify_check(inContext, service_table, notify_obj); require_noerr(err, exit); // send notify message to cloud if( NULL != (json_object_get_object(notify_obj)->head) ){ notify_json_string = json_object_to_json_string(notify_obj); // notify to topic: <device_id>/out/read err = MicoFogCloudMsgSend(inContext, FOGCLOUD_MSG_TOPIC_OUT_NOTIFY, (unsigned char*)notify_json_string, strlen(notify_json_string)); } else{ // no update msg err = kNoErr; } exit: if(kNoErr != err){ msg_dispatch_log("ERROR: _properties_notify error, err = %d", err); } if(NULL != notify_obj){ json_object_put(notify_obj); notify_obj = NULL; } return err; }
// handle cloud msg here, for example: send to USART or echo to cloud OSStatus mico_fogcloud_msg_dispatch(mico_Context_t* context, struct mico_service_t service_table[], mico_fogcloud_msg_t *cloud_msg, int* ret_status) { msg_dispatch_log_trace(); OSStatus err = kNoErr; char* recv_sub_topic_ptr = NULL; int recv_sub_topic_len = 0; json_object *recv_json_object = NULL; char* response_sub_topic = NULL; json_object *response_json_obj = NULL; const char *response_json_string = NULL; json_object *response_services_obj = NULL; json_object *response_prop_obj = NULL; json_object *response_err_obj = NULL; *ret_status = MSG_PROP_UNPROCESSED; if((NULL == context) || (NULL == cloud_msg->topic) || (0 == cloud_msg->topic_len) ) { return kParamErr; } // strip "<device_id>/in" to get response sub-topic, then response to: "<device_id>/out/<sub-topic>" recv_sub_topic_len = (int)cloud_msg->topic_len - (strlen(context->flashContentInRam.appConfig.fogcloudConfig.deviceId) + strlen(FOGCLOUD_MSG_TOPIC_IN)); if(recv_sub_topic_len <= 0){ // unsupported topic msg_dispatch_log("ERROR: Message from unsupported topic: %.*s \t data[%d]: %s, ignored.", cloud_msg->topic_len, cloud_msg->topic, cloud_msg->data_len, cloud_msg->data); err = kUnsupportedErr; goto exit; } recv_sub_topic_ptr = (char*)(cloud_msg->topic) + strlen(context->flashContentInRam.appConfig.fogcloudConfig.deviceId) + strlen(FOGCLOUD_MSG_TOPIC_IN); response_sub_topic = (char*)malloc(recv_sub_topic_len); // response to where msg come from, remove leading '/' if(NULL == response_sub_topic){ msg_dispatch_log("malloc reponse topic memory err!"); err = kNoMemoryErr; goto exit; } memset(response_sub_topic, '\0', recv_sub_topic_len); strncpy(response_sub_topic, recv_sub_topic_ptr + 1, recv_sub_topic_len-1); // remove leading '/' as send sub-topic //msg_dispatch_log("recv_sub_topic[%d]=[%.*s]", recv_sub_topic_len, recv_sub_topic_len, recv_sub_topic_ptr); //msg_dispatch_log("response_sub_topic[%d]=[%s]", strlen(response_sub_topic), response_sub_topic); // parse sub topic string if( 0 == strncmp((char*)FOGCLOUD_MSG_TOPIC_IN_READ, recv_sub_topic_ptr, strlen((char*)FOGCLOUD_MSG_TOPIC_IN_READ)) ){ // from /read msg_dispatch_log("Recv read cmd: %.*s, data[%d]: %s", recv_sub_topic_len, recv_sub_topic_ptr, cloud_msg->data_len, cloud_msg->data); // parse input json data recv_json_object = json_tokener_parse((const char*)(cloud_msg->data)); if (NULL == recv_json_object){ // input json format error, response to sub-topic "err" with error code response_err_obj = json_object_new_object(); require( response_err_obj, exit ); json_object_object_add(response_err_obj, MICO_PROP_KEY_RESP_STATUS, json_object_new_int(MICO_PROP_CODE_DATA_FORMAT_ERR)); response_json_string = json_object_to_json_string(response_err_obj); err = MicoFogCloudMsgSend(context, FOGCLOUD_MSG_TOPIC_OUT_ERROR, (unsigned char*)response_json_string, strlen(response_json_string)); goto exit; } //msg_dispatch_log("Recv read object=%s", json_object_to_json_string(recv_json_object)); // read properties, return "services/read/err" sub-obj in response_json_obj response_json_obj = mico_read_properties(service_table, recv_json_object); // send reponse for read data if(NULL == response_json_obj){ // read failed msg_dispatch_log("ERROR: read properties error!"); json_object_object_add(response_err_obj, MICO_PROP_KEY_RESP_STATUS, json_object_new_int(MICO_PROP_CODE_READ_FAILED)); response_json_string = json_object_to_json_string(response_err_obj); err = MicoFogCloudMsgSend(context, FOGCLOUD_MSG_TOPIC_OUT_ERROR, (unsigned char*)response_json_string, strlen(response_json_string)); } else { // send err code response_err_obj = json_object_object_get(response_json_obj, MICO_PROP_KEY_RESP_ERROR); if( (NULL != response_err_obj) && (NULL != json_object_get_object(response_err_obj)->head) ){ response_json_string = json_object_to_json_string(response_err_obj); err = MicoFogCloudMsgSend(context, FOGCLOUD_MSG_TOPIC_OUT_ERROR, (unsigned char*)response_json_string, strlen(response_json_string)); } // send services info msg response_services_obj = json_object_object_get(response_json_obj, MICO_PROP_KEY_RESP_SERVICES); if(NULL != response_services_obj){ json_object_object_del(response_json_obj, MICO_PROP_KEY_RESP_ERROR); // remove "err" sub-obj response_json_string = json_object_to_json_string(response_json_obj); err = MicoFogCloudMsgSend(context, response_sub_topic, (unsigned char*)response_json_string, strlen(response_json_string)); } // send read ok value response_prop_obj = json_object_object_get(response_json_obj, MICO_PROP_KEY_RESP_READ); if( (NULL != response_prop_obj) && (NULL != json_object_get_object(response_prop_obj)->head) ){ response_json_string = json_object_to_json_string(response_prop_obj); err = MicoFogCloudMsgSend(context, response_sub_topic, (unsigned char*)response_json_string, strlen(response_json_string)); } // return process result *ret_status = MSG_PROP_READ; } } else if( 0 == strncmp((char*)FOGCLOUD_MSG_TOPIC_IN_WRITE, recv_sub_topic_ptr, strlen((char*)FOGCLOUD_MSG_TOPIC_IN_WRITE)) ){ // from /write msg_dispatch_log("Recv write cmd: %.*s, data[%d]: %s", recv_sub_topic_len, recv_sub_topic_ptr, cloud_msg->data_len, cloud_msg->data); // parse input json data recv_json_object = json_tokener_parse((const char*)(cloud_msg->data)); if (NULL == recv_json_object){ // input json format error, response to sub-topic "err" with error code response_err_obj = json_object_new_object(); require( response_err_obj, exit ); json_object_object_add(response_err_obj, MICO_PROP_KEY_RESP_STATUS, json_object_new_int(MICO_PROP_CODE_DATA_FORMAT_ERR)); response_json_string = json_object_to_json_string(response_err_obj); err = MicoFogCloudMsgSend(context, FOGCLOUD_MSG_TOPIC_OUT_ERROR, (unsigned char*)response_json_string, strlen(response_json_string)); goto exit; } //msg_dispatch_log("Recv write object=%s", json_object_to_json_string(recv_json_object)); // write properties, return "write/err" sub-obj in response_json_obj response_json_obj = mico_write_properties(service_table, recv_json_object); // send reponse for write data if(NULL == response_json_obj){ // write failed msg_dispatch_log("ERROR: write properties error!"); json_object_object_add(response_err_obj, MICO_PROP_KEY_RESP_STATUS, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED)); response_json_string = json_object_to_json_string(response_err_obj); err = MicoFogCloudMsgSend(context, FOGCLOUD_MSG_TOPIC_OUT_ERROR, (unsigned char*)response_json_string, strlen(response_json_string)); } else { // send err code response_err_obj = json_object_object_get(response_json_obj, MICO_PROP_KEY_RESP_ERROR); if( (NULL != response_err_obj) && (NULL != json_object_get_object(response_err_obj)->head) ){ response_json_string = json_object_to_json_string(response_err_obj); err = MicoFogCloudMsgSend(context, FOGCLOUD_MSG_TOPIC_OUT_ERROR, (unsigned char*)response_json_string, strlen(response_json_string)); } // send write ok value response_prop_obj = json_object_object_get(response_json_obj, MICO_PROP_KEY_RESP_WRITE); if( (NULL != response_prop_obj) && (NULL != json_object_get_object(response_prop_obj)->head) ){ response_json_string = json_object_to_json_string(response_prop_obj); err = MicoFogCloudMsgSend(context, response_sub_topic, (unsigned char*)response_json_string, strlen(response_json_string)); } // return process result *ret_status = MSG_PROP_WROTE; } } else{ // unknown topic, ignore msg err = kUnsupportedErr; msg_dispatch_log("ERROR: Message from unknown topic: %.*s \t data[%d]: %s, ignored.", recv_sub_topic_len, cloud_msg->topic, cloud_msg->data_len, cloud_msg->data); } exit: if(NULL != recv_json_object){ json_object_put(recv_json_object); recv_json_object = NULL; } if(NULL != response_json_obj){ json_object_put(response_json_obj); response_json_obj = NULL; } if(NULL != response_sub_topic){ free(response_sub_topic); response_sub_topic = NULL; } return err; }
/* Message upload thread * Get DHT11 temperature/humidity data && upload to cloud */ void user_upstream_thread(void* arg) { user_log_trace(); OSStatus err = kUnknownErr; mico_Context_t *mico_context = (mico_Context_t *)arg; json_object *send_json_object = NULL; const char *upload_data = NULL; uint8_t ret = 0; require(mico_context, exit); /* init humiture sensor DHT11 */ /* do{ ret = DHT11_Init(); if(0 != ret){ // init error user_log("DHT11 init failed!"); err = kNoResourcesErr; mico_thread_sleep(1); // sleep 1s then retry } else{ err = kNoErr; break; } }while(kNoErr != err); */ /* thread loop */ while(1){ // do data acquisition /* ret = DHT11_Read_Data(&dht11_temperature, &dht11_humidity); if(0 != ret){ err = kReadErr; } else */ { err = kNoErr; dht11_temperature = 25; dht11_humidity = 30; // create json object to format upload data send_json_object = json_object_new_object(); if(NULL == send_json_object){ user_log("create json object error!"); err = kNoMemoryErr; } else{ // add temperature/humidity data into a json oject json_object_object_add(send_json_object, "dht11_temperature", json_object_new_int(dht11_temperature)); json_object_object_add(send_json_object, "dht11_humidity", json_object_new_int(dht11_humidity)); upload_data = json_object_to_json_string(send_json_object); if(NULL == upload_data){ user_log("create upload data string error!"); err = kNoMemoryErr; } else{ // check fogcloud connect status if(mico_context->appStatus.fogcloudStatus.isCloudConnected){ // upload data string to fogcloud, the seconde param(NULL) means send to defalut topic: '<device_id>/out' MicoFogCloudMsgSend(mico_context, NULL, (unsigned char*)upload_data, strlen(upload_data)); user_log("upload data success! \t topic=%s/out \t dht11_temperature=%d, dht11_humidity=%d", mico_context->flashContentInRam.appConfig.fogcloudConfig.deviceId, dht11_temperature, dht11_humidity); err = kNoErr; } } // free json object memory json_object_put(send_json_object); send_json_object = NULL; } } mico_thread_sleep(2); // data acquisition && upload every 2 seconds } exit: if(kNoErr != err){ user_log("ERROR: user_uptream exit with err=%d", err); } mico_rtos_delete_thread(NULL); // delete current thread }