int notify_things_observers(const char *uri, const char *query) { THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY); int res = 0; THINGS_LOG_D(TAG, "uri = %s", uri); if (NULL != uri) { int remainLen = MAX_RESOURCE_LEN - 1; char tempUri[MAX_RESOURCE_LEN] = { 0 }; if (NULL != g_get_notify_obs_uri) { char *temp = g_get_notify_obs_uri(uri, query); if (NULL != temp) { things_strncpy(tempUri, temp, remainLen); remainLen -= strnlen(tempUri, MAX_RESOURCE_LEN - 1); things_free(temp); } } if (strnlen(tempUri, MAX_RESOURCE_LEN - 1) < 1) { things_strncpy(tempUri, uri, remainLen); remainLen -= strnlen(tempUri, MAX_RESOURCE_LEN - 1); } THINGS_LOG_D(TAG, "%s resource notifies to observers.", tempUri); for (int iter = 0; iter < g_builder->res_num; iter++) { if (strstr(g_builder->gres_arr[iter]->uri, tempUri) != NULL) { OCStackResult ret2 = OCNotifyAllObservers((OCResourceHandle) g_builder->gres_arr[iter]->resource_handle, OC_MEDIUM_QOS); THINGS_LOG_D(TAG, "%s resource has notified to observers.", g_builder->gres_arr[iter]->uri); if (OC_STACK_OK == ret2) { THINGS_LOG_V(TAG, "Success: Sent notification to Observers"); } else { THINGS_LOG_V(TAG, "Failed: No Observers to notify : %d ", ret2); } res = 1; break; } } } THINGS_LOG_D(TAG, THINGS_FUNC_EXIT); return res; }
struct things_resource_s *create_collection_resource(struct things_server_builder_s *builder, char *uri, char *type) { things_resource_s *res = NULL; OCResourceHandle hd = NULL; uint8_t rsc_properties = OC_DISCOVERABLE | OC_OBSERVABLE; if (builder->handler == NULL) { THINGS_LOG_E(TAG, "Handler for serverbuilder is not registered"); return res; } #ifdef __SECURED__ rsc_properties |= OC_SECURE; #endif //#ifdef __SECURED__ iotivity_api_lock(); OCStackResult ret = OCCreateResource(&hd, type, OIC_INTERFACE_LINKEDLIST, uri, builder->handler, NULL, rsc_properties); if (ret != OC_STACK_OK) { THINGS_LOG_V(TAG, "Resource Creation Failed - ret = %d, %s", ret, uri); iotivity_api_unlock(); return NULL; } OCBindResourceTypeToResource(hd, OIC_RTYPE_COLLECTION_WK); OCBindResourceInterfaceToResource(hd, OIC_INTERFACE_BATCH); iotivity_api_unlock(); res = things_create_resource_inst(NULL, hd, NULL, NULL); if (NULL == res) { THINGS_LOG_E(TAG, "things_create_resource_inst is failed"); return res; } res->res_type = things_strdup(type); builder->gres_arr[builder->res_num++] = res; THINGS_LOG_V(TAG, "Created hd [%x], prop [0x%X] uri : %s", res->resource_handle, rsc_properties, uri); return res; }
OCEntityHandlerResult handle_message(things_resource_s *target_resource) { OCEntityHandlerResult eh_result = OC_EH_ERROR; if (NULL == target_resource) { THINGS_LOG_D(TAG, "Request Item is NULL."); return OC_EH_ERROR; } THINGS_LOG_D(TAG, "Request Handle : %x, Resource Handle : %x", target_resource->request_handle, target_resource->resource_handle); if (target_resource->req_type == OC_REST_GET) { THINGS_LOG_V(TAG, "\t\tReq. : GET on %s", target_resource->uri); THINGS_LOG_V(TAG, "\t\tQuery: %s", target_resource->query); eh_result = process_get_request(target_resource); } else if (target_resource->req_type == OC_REST_POST) { THINGS_LOG_V(TAG, "\t\tReq. : POST on %s", target_resource->uri); THINGS_LOG_V(TAG, "\t\tQuery: %s", target_resource->query); eh_result = process_post_request(&target_resource); } else { THINGS_LOG_E(TAG, " Invalid Request Received : %d", target_resource->req_type); } THINGS_LOG_D(TAG, " @@@@@ target_resource ->size : %d", target_resource->size); if (is_can_not_response_case(target_resource, target_resource->req_type, eh_result) == false) { if (eh_result != OC_EH_OK && eh_result != OC_EH_SLOW) { THINGS_LOG_E(TAG, "Handing Request Failed, Sending ERROR Response"); send_response(target_resource->request_handle, target_resource->resource_handle, eh_result, target_resource->uri, NULL); eh_result = OC_EH_OK; } else { OCRepPayload *rep_payload = target_resource->things_get_rep_payload(target_resource); eh_result = send_response(target_resource->request_handle, // reqInfo->reqHandle, target_resource->resource_handle, // reqInfo->resHandle, target_resource->error, target_resource->uri, rep_payload); OCPayloadDestroy((OCPayload *) rep_payload); rep_payload = NULL; } } // Need to design How to release memory allocated for the things_resource_s list. things_release_resource_inst(target_resource); return eh_result; }
struct things_resource_s *create_resource(struct things_server_builder_s *builder, char *uri, char *type, char *interface, int isDiscoverable, int isObserable, int isSecure) { things_resource_s *res = NULL; OCResourceHandle hd = NULL; uint8_t rsc_properties = OC_DISCOVERABLE; if (builder->handler == NULL) { THINGS_LOG_E(TAG, "Handler for serverbuilder is not registered"); return res; } if (1 != isDiscoverable) { rsc_properties = OC_ACTIVE; } if (1 == isObserable) { rsc_properties |= OC_OBSERVABLE; } if (1 == isSecure) { #ifdef __SECURED__ rsc_properties |= OC_SECURE; #else THINGS_LOG_D(TAG, "Stack is in UNSECURED Mode"); #endif } iotivity_api_lock(); OCStackResult ret = OCCreateResource(&hd, type, interface, uri, builder->handler, NULL, rsc_properties); iotivity_api_unlock(); if (ret != OC_STACK_OK) { THINGS_LOG_V(TAG, "Resource Creation Failed - ret = %d, %s", ret, uri); return NULL; } res = things_create_resource_inst(NULL, hd, NULL, NULL); if (NULL == res) { THINGS_LOG_E(TAG, "things_create_resource_inst is failed"); return res; } res->res_type = things_strdup(type); builder->gres_arr[builder->res_num++] = res; THINGS_LOG_D(TAG, "Created hd [%x], prop [0x%X] uri : %s", res->resource_handle, rsc_properties, res->uri); THINGS_LOG_D(TAG, "DISCOVERABLE : %s", (isDiscoverable == 1 ? "YES" : "NO")); THINGS_LOG_D(TAG, "OBSERABLE : %s", (isObserable == 1 ? "YES" : "NO")); THINGS_LOG_D(TAG, "SECURE : %s", (isSecure == 1 ? "YES" : "NO")); return res; }
int wget_from_url(char *download_url) { THINGS_LOG_V(TAG, "download url : %s\n", download_url); struct http_client_request_t request; struct http_keyvalue_list_t headers; struct http_client_response_t response; struct http_client_ssl_config_t *ssl_config = NULL; int ret; ret = -1; if (webclient_init_request(download_url, &request) != 0) { THINGS_LOG_E(TAG, "webclient_init_request error"); return NULL; } ssl_config = g_https ? &g_config : NULL; /* before sending request, * must initialize keyvalue list for request headers */ http_keyvalue_list_init(&headers); http_keyvalue_list_add(&headers, headerfield_connect, headerfield_close); http_keyvalue_list_add(&headers, headerfield_useragent, headerfield_tinyara); request.headers = &headers; /* before sending request by sync function, * must initialize response structure */ if (http_client_send_request_async(&request, ssl_config, (wget_callback_t)callback)) { THINGS_LOG_E(TAG, "fail to send request"); goto release_out; } /* sleep for end request */ while (request.async_flag > 0) { usleep(100000); } if (request.async_flag < 0) { THINGS_LOG_E(TAG, "fail to send request"); goto release_out; } ret = 1; release_out: /* before finish of app, * must release keyvalue list for request headers */ http_keyvalue_list_release(&headers); THINGS_LOG_D(TAG, "end request"); return ret; }
OCEntityHandlerResult send_response(OCRequestHandle request_handle, OCResourceHandle resource, OCEntityHandlerResult result, const char *uri, void *payload) { THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY); OCEntityHandlerResult eh_result = OC_EH_OK; OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, {}, {0}, false }; THINGS_LOG_D(TAG, "Creating Response with Request Handle : %x,Resource Handle : %x", request_handle, resource); response.numSendVendorSpecificHeaderOptions = 0; memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions); memset(response.resourceUri, 0, sizeof(response.resourceUri)); if (NULL != request_handle && NULL != resource) { response.requestHandle = request_handle; //eh_request->request_handle; response.resourceHandle = resource; //eh_request->resource; response.persistentBufferFlag = 0; response.ehResult = result; if (payload != NULL) { THINGS_LOG_D(TAG, "Payload is Not NULL"); response.payload = (OCPayload *) payload; } else { THINGS_LOG_D(TAG, "No Payload"); response.payload = NULL; } THINGS_LOG_V(TAG, "\t\t\tRes. : %s ( %d )", (response.ehResult == OC_EH_OK ? "NORMAL" : "ERROR"), response.ehResult); OCStackResult ret = OCDoResponse(&response); THINGS_LOG_V(TAG, "\t\t\tMsg. Out? : (%s)", (ret == OC_STACK_OK) ? "SUCCESS" : "FAIL"); if (ret != OC_STACK_OK) { eh_result = OC_EH_ERROR; } } else { eh_result = OC_EH_ERROR; } // THINGS_LOG_D(TAG, THINGS_FUNC_EXIT); return eh_result; }
void init_builder(struct things_server_builder_s *builder, request_handler_cb cb) { OCTransportAdapter m_transport = (OC_ADAPTER_IP | OC_ADAPTER_TCP); if (OC_STACK_OK != OCInit2(OC_CLIENT_SERVER, OC_IP_USE_V4, OC_IP_USE_V4, m_transport)) { THINGS_LOG_E(TAG, "RESOURCE SERVER START FAILED"); return; } THINGS_LOG_V(TAG, "Resource Server IS NOW STARTING..."); g_quit_flag = 0; pthread_create_rtos(&g_thread_id_server, NULL, server_execute_loop, (void *)NULL, THINGS_STACK_SERVEREXCETUE_LOOP_THREAD); register_req_handler(builder, cb); }
void things_bind(struct things_resource_s *res, struct things_resource_s *bind) { if (res == NULL || bind == NULL) { THINGS_LOG_E(TAG, "Invalid Resource"); return; } if (res->resource_handle == bind->resource_handle) { THINGS_LOG_D(TAG, "It's identical resource"); return; } iotivity_api_lock(); OCStackResult ret = OCBindResource((OCResourceHandle)(res->resource_handle), (OCResourceHandle)(bind->resource_handle)); iotivity_api_unlock(); if (ret != OC_STACK_OK) { THINGS_LOG_V(TAG, "bind Failed "); } }
static OCEntityHandlerResult trigger_reset_request(things_resource_s *target_resource, bool reset) { OCEntityHandlerResult eh_result = OC_EH_ERROR; things_resource_s *clone_resource = NULL; bool isOwned; OCGetDeviceOwnedState(&isOwned); if (isOwned == false) { return OC_EH_NOT_ACCEPTABLE; } THINGS_LOG_D(TAG, "==> RESET : %s", (reset == true ? "YES" : "NO")); if (reset == true) { int res = -1; clone_resource = clone_resource_inst(target_resource); res = things_reset((void *)clone_resource, RST_NEED_CONFIRM); switch (res) { case 1: THINGS_LOG_D(TAG, "Reset Thread create is success."); eh_result = OC_EH_SLOW; break; case 0: THINGS_LOG_V(TAG, "Already Run Reset-Process."); eh_result = OC_EH_NOT_ACCEPTABLE; default: things_release_resource_inst(clone_resource); clone_resource = NULL; break; } } else { THINGS_LOG_D(TAG, "reset = %d, So, can not reset start.", reset); eh_result = OC_EH_OK; } return eh_result; }
OCEntityHandlerResult entity_handler(OCEntityHandlerFlag flag, OCEntityHandlerRequest *entity_handler_request, void *callback) { THINGS_LOG_V(TAG, THINGS_FUNC_ENTRY); OCEntityHandlerResult eh_result = OC_EH_ERROR; // Validate pointer if (!entity_handler_request) { THINGS_LOG_E(TAG, "Invalid request pointer"); return eh_result; } const char *uri = OCGetResourceUri(entity_handler_request->resource); // Observe Request Handling if (flag & OC_OBSERVE_FLAG) { if (OC_OBSERVE_REGISTER == entity_handler_request->obsInfo.action) { THINGS_LOG_V(TAG, "Observe Requset on : %s ", uri); // 1. Check whether it's Observe request on the Collection Resource if (NULL != strstr(uri, URI_DEVICE_COL)) { //2. Check whether the query carriese the if=oic.if.b if ((strstr(entity_handler_request->query, OIC_INTERFACE_BATCH) == NULL)) { //3. If not batch then error THINGS_LOG_E(TAG, "Collection Resource Requires BATCH for Observing : %s", entity_handler_request->query); eh_result = OC_EH_BAD_REQ; goto RESPONSE_ERROR; } else { THINGS_LOG_E(TAG, "Receiving Observe Request Collection Resource"); } } } else if (OC_OBSERVE_DEREGISTER == entity_handler_request->obsInfo.action) { THINGS_LOG_V(TAG, "CancelObserve Request on : %s", uri); } } // Get/Post Request Handling if (flag & OC_REQUEST_FLAG) { if (things_get_reset_mask(RST_CONTROL_MODULE_DISABLE) == true) { THINGS_LOG_V(TAG, "Control Module Disable."); eh_result = OC_EH_NOT_ACCEPTABLE; } else if ((OC_REST_GET == entity_handler_request->method) || (OC_REST_POST == entity_handler_request->method)) { THINGS_LOG_V(TAG, "Request Handle : %x, Resource Handle : %x", entity_handler_request->requestHandle, entity_handler_request->resource); if (verify_request(entity_handler_request, uri, (int)entity_handler_request->method) > 0) { // IoTivity Stack Destroy the payload after receving result from this function // Therefore, we need to copy/clone the payload for the later use.. things_resource_s *resource = things_create_resource_inst(entity_handler_request->requestHandle, entity_handler_request->resource, entity_handler_request->query, entity_handler_request->payload); resource->things_set_dev_addr(resource, &(entity_handler_request->devAddr)); resource->req_type = entity_handler_request->method; eh_result = handle_message(resource); } else { THINGS_LOG_E(TAG, "Invalid Query in the Request : %s", entity_handler_request->query); } } else if (OC_REST_DELETE == entity_handler_request->method || OC_REST_PUT == entity_handler_request->method) { THINGS_LOG_E(TAG, "Delete/PUT Req. Handling is not supported Yet"); } else { THINGS_LOG_D(TAG, "Received unsupported method from client"); } } RESPONSE_ERROR: if (eh_result != OC_EH_SLOW && eh_result != OC_EH_OK) { // If the result is OC_EH_ERROR, the stack will remove the // received request in the stack. // If the reusult is OC_EH_SLOW, then the request will be // stored in the stack till the response goes out eh_result = send_response(entity_handler_request->requestHandle, entity_handler_request->resource, eh_result, uri, NULL); // Currently this code will not do anything... // Need to refactor later.. } THINGS_LOG_D(TAG, THINGS_FUNC_EXIT); return eh_result; }
// To get the properties of a resource based on either resource type or resource uri. static bool get_supported_properties(const char *res_type, const char *res_uri, int *count, things_attribute_info_s ***properties, bool *destroy_props) { RET_FALSE_IF_PARAM_IS_NULL(TAG, count); RET_FALSE_IF_PARAM_IS_NULL(TAG, properties); RET_FALSE_IF_PARAM_IS_NULL(TAG, destroy_props); *destroy_props = false; // Get the properties based on resource type. if (NULL != res_type && strlen(res_type) > 0) { int res = things_get_attributes_by_resource_type(res_type, count, properties); THINGS_LOG_D(TAG, "Get attributes by resource type(%s): %s.", res_type, (1 == res) ? "Success" : "Failed"); return res ? true : false; } char **res_types = NULL; int *prop_count = NULL; things_attribute_info_s ***props = NULL; // Get the properties based on resource uri. if (NULL != res_uri && strlen(res_uri) > 0) { int type_count = 0; // 1. Get the resource types. if (!things_get_resource_type(res_uri, &type_count, &res_types)) { THINGS_LOG_E(TAG, "Failed to get the resource types based on resource uri(%s).", res_uri); return false; } if (type_count < 1 || NULL == res_types) { THINGS_LOG_E(TAG, "No resource types for the given resource(%s).", res_uri); return false; } THINGS_LOG_D(TAG, "Resource(%s) has %d resource type(s).", res_uri, type_count); // 2. Get the properties for each resource type. props = (things_attribute_info_s ***) things_calloc(type_count, sizeof(things_attribute_info_s **)); if (NULL == props) { THINGS_LOG_E(THINGS_ERROR, TAG, "Failed to allocate memory for resource properties."); goto EXIT_WITH_ERROR; } prop_count = (int *)things_calloc(type_count, sizeof(int)); if (NULL == prop_count) { THINGS_LOG_E(THINGS_ERROR, TAG, "Failed to allocate memory for resource properties."); goto EXIT_WITH_ERROR; } for (int index = 0; index < type_count; index++) { if (!things_get_attributes_by_resource_type(res_types[index], &prop_count[index], &props[index])) { THINGS_LOG_V(THINGS_ERROR, TAG, "Failed to get the properties of resource type (%s).", res_types[index]); goto EXIT_WITH_ERROR; } THINGS_LOG_D(TAG, "Number of properties of resource type(%s): %d.", res_types[index], prop_count[index]); *count += prop_count[index]; } THINGS_LOG_D(TAG, "Total number of properties: %d.", *count); *properties = (things_attribute_info_s **) things_calloc(*count, sizeof(things_attribute_info_s *)); if (NULL == *properties) { THINGS_LOG_E(THINGS_ERROR, TAG, "Failed to allocate memory for resource properties."); goto EXIT_WITH_ERROR; } int cur_index = 0; for (int index = 0; index < type_count; index++) { if (NULL == props[index]) { THINGS_LOG_V(THINGS_ERROR, TAG, "Resource type(%s) doesn't have any properties.", res_types[index]); goto EXIT_WITH_ERROR; } for (int sub_index = 0; sub_index < prop_count[index]; sub_index++) { things_attribute_info_s *prop = *(props[index] + sub_index); if (NULL == prop) { THINGS_LOG_E(THINGS_ERROR, TAG, "NULL Property."); goto EXIT_WITH_ERROR; } // If this prop is already added, then ignore it and decrement the total count by 1. bool exist = false; for (int i = 0; i < cur_index; i++) { if (0 == strncmp(((*properties)[i])->key, prop->key, strlen(prop->key))) { THINGS_LOG_D(TAG, "Property(%s) is already added in the request message.", prop->key); exist = true; break; } } if (exist) { (*count)--; } else { (*properties)[cur_index++] = prop; } } } *destroy_props = true; things_free(prop_count); things_free(props); } else { THINGS_LOG_E(TAG, "Resource type and URI are invalid."); return false; } return true; EXIT_WITH_ERROR: res_types = NULL; things_free(prop_count); prop_count = NULL; things_free(props); props = NULL; things_free(properties); properties = NULL; *count = 0; return false; }