OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr, OCRepPayload** payload) { OCRepPayload *tempPayload = OCRepPayloadCreate(); if (!resourcePtr) { OCRepPayloadDestroy(tempPayload); return OC_STACK_INVALID_PARAM; } if(!tempPayload) { return OC_STACK_NO_MEMORY; } OCRepPayloadSetUri(tempPayload, resourcePtr->uri); OCResourceType *resType = resourcePtr->rsrcType; while(resType) { OCRepPayloadAddResourceType(tempPayload, resType->resourcetypename); resType = resType->next; } OCResourceInterface *resInterface = resourcePtr->rsrcInterface; while(resInterface) { OCRepPayloadAddInterface(tempPayload, resInterface->name); resInterface = resInterface->next; } OCAttribute *resAttrib = resourcePtr->rsrcAttributes; while(resAttrib) { OCRepPayloadSetPropString(tempPayload, resAttrib->attrName, resAttrib->attrValue); resAttrib = resAttrib->next; } if(!*payload) { *payload = tempPayload; } else { OCRepPayloadAppend(*payload, tempPayload); } return OC_STACK_OK; }
void /*OCRepPayload */ *create_payload(struct things_resource_s *res, char *query) { // To provide identical pattern for handling the result // allocating new memory for the payload to delete later OCRepPayload *payload = OCRepPayloadClone((OCRepPayload *)(res->rep->payload)); THINGS_LOG_D(TAG, "Query : %s", query); if (query == NULL || (query != NULL && strlen(query) < 1) || strstr(query, OIC_INTERFACE_ACTUATOR) != NULL || strstr(query, OIC_INTERFACE_SENSOR) != NULL) { THINGS_LOG_D(TAG, "Including properties & its values only"); // Do nothing.. } else if (strstr(query, OIC_INTERFACE_BASELINE)) { THINGS_LOG_D(TAG, "Including all the properties & its values"); uint8_t index = 0; uint8_t number_of_interfaces = 0; uint8_t number_of_resource_type = 0; OCGetNumberOfResourceInterfaces((OCResourceHandle) res->resource_handle, &number_of_interfaces); THINGS_LOG_D(TAG, "@@ IF # : %d ", number_of_interfaces); //2.a Find interface type(s) & insert it/them into payload for (index = 0; index < number_of_interfaces; index++) { const char *interface = OCGetResourceInterfaceName((OCResourceHandle) res->resource_handle, index); THINGS_LOG_D(TAG, "=====> IF : %s ", interface); OCRepPayloadAddInterface(payload, interface); } //3.a Find resource type & insert it into payload OCGetNumberOfResourceTypes((OCResourceHandle) res->resource_handle, &number_of_resource_type); THINGS_LOG_D(TAG, "@@ RT # : %d ", number_of_resource_type); for (index = 0; index < number_of_resource_type; index++) { const char *rt = OCGetResourceTypeName((OCResourceHandle) res->resource_handle, index); THINGS_LOG_D(TAG, "=====> RT : %s ", rt); OCRepPayloadAddResourceType(payload, rt); } } else if (strstr(query, OC_RSRVD_INTERFACE_BATCH)) { THINGS_LOG_D(TAG, "Batch only supported by Collection Resource"); } else if (strstr(query, OC_RSRVD_INTERFACE_LL)) { THINGS_LOG_D(TAG, "Link-List only supported by Collection Resource"); } else { THINGS_LOG_D(TAG, "Not supporting Interface type : %s", query); } return payload; }
OCRepPayload* icd_payload_representation_from_gvariant(GVariant *var) { int ret; GVariant *child; OCRepPayload *repr, *cur; char *uri_path, *resource_iface, *resource_type; GVariantIter *resource_types, *resource_ifaces, *repr_gvar, *children; repr = OCRepPayloadCreate(); g_variant_get(var, "(&sasasa{sv}av)", &uri_path, &resource_ifaces, &resource_types, &repr_gvar, &children); if (IC_STR_EQUAL != strcmp(IC_STR_NULL, uri_path)) OCRepPayloadSetUri(repr, uri_path); while (g_variant_iter_loop(resource_ifaces, "s", &resource_iface)) OCRepPayloadAddInterface(repr, resource_iface); while (g_variant_iter_loop(resource_types, "s", &resource_type)) OCRepPayloadAddResourceType(repr, resource_type); ret = _icd_state_value_from_gvariant(repr, repr_gvar); if (IOTCON_ERROR_NONE != ret) { ERR("_icd_state_value_from_gvariant() Fail(%d)", ret); OCRepPayloadDestroy(repr); return NULL; } cur = repr; while (g_variant_iter_loop(children, "v", &child)) { cur->next = icd_payload_representation_from_gvariant(child); if (NULL == cur->next) { ERR("icd_payload_representation_from_gvariant() Fail"); OCRepPayloadDestroy(repr); return NULL; } cur = cur->next; } return repr; }
static bool OCParseSingleRepPayload(OCRepPayload** outPayload, CborValue* repParent) { if (!outPayload) { return false; } *outPayload = OCRepPayloadCreate(); OCRepPayload* curPayload = *outPayload; bool err = false; if(!*outPayload) { return CborErrorOutOfMemory; } size_t len; CborValue curVal; err = err || cbor_value_map_find_value(repParent, OC_RSRVD_HREF, &curVal); if(cbor_value_is_valid(&curVal)) { err = err || cbor_value_dup_text_string(&curVal, &curPayload->uri, &len, NULL); } err = err || cbor_value_map_find_value(repParent, OC_RSRVD_PROPERTY, &curVal); if(cbor_value_is_valid(&curVal)) { CborValue insidePropValue = {0}; err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_RESOURCE_TYPE, &insidePropValue); if(cbor_value_is_text_string(&insidePropValue)) { char* allRt = NULL; err = err || cbor_value_dup_text_string(&insidePropValue, &allRt, &len, NULL); char* savePtr; if (allRt) { char* curPtr = strtok_r(allRt, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] != '\0') { OCRepPayloadAddResourceType(curPayload, curPtr); } curPtr = strtok_r(NULL, " ", &savePtr); } } OICFree(allRt); } err = err || cbor_value_map_find_value(&curVal, OC_RSRVD_INTERFACE, &insidePropValue); if(cbor_value_is_text_string(&insidePropValue)) { char* allIf = NULL; err = err || cbor_value_dup_text_string(&insidePropValue, &allIf, &len, NULL); char* savePtr; if (allIf) { char* curPtr = strtok_r(allIf, " ", &savePtr); while (curPtr) { char* trimmed = InPlaceStringTrim(curPtr); if (trimmed[0] != '\0') { OCRepPayloadAddInterface(curPayload, curPtr); } curPtr = strtok_r(NULL, " ", &savePtr); } } OICFree(allIf); } } err = err || cbor_value_map_find_value(repParent, OC_RSRVD_REPRESENTATION, &curVal); if(cbor_value_is_map(&curVal)) { CborValue repMap; err = err || cbor_value_enter_container(&curVal, &repMap); while(!err && cbor_value_is_valid(&repMap)) { char* name; err = err || cbor_value_dup_text_string(&repMap, &name, &len, NULL); err = err || cbor_value_advance(&repMap); int64_t intval = 0; bool boolval = false; char* strval = NULL; double doubleval = 0; OCRepPayload* pl; switch(cbor_value_get_type(&repMap)) { case CborNullType: err = !OCRepPayloadSetNull(curPayload, name); break; case CborIntegerType: err = err || cbor_value_get_int64(&repMap, &intval); if (!err) { err = !OCRepPayloadSetPropInt(curPayload, name, intval); } break; case CborDoubleType: err = err || cbor_value_get_double(&repMap, &doubleval); if (!err) { err = !OCRepPayloadSetPropDouble(curPayload, name, doubleval); } break; case CborBooleanType: err = err || cbor_value_get_boolean(&repMap, &boolval); if (!err) { err = !OCRepPayloadSetPropBool(curPayload, name, boolval); } break; case CborTextStringType: err = err || cbor_value_dup_text_string(&repMap, &strval, &len, NULL); if (!err) { err = !OCRepPayloadSetPropStringAsOwner(curPayload, name, strval); } break; case CborMapType: err = err || OCParseSingleRepPayload(&pl, &repMap); if (!err) { err = !OCRepPayloadSetPropObjectAsOwner(curPayload, name, pl); } break; case CborArrayType: err = err || OCParseArray(curPayload, name, &repMap); break; default: OC_LOG_V(ERROR, TAG, "Parsing rep property, unknown type %d", repMap.type); err = true; } err = err || cbor_value_advance(&repMap); OICFree(name); } err = err || cbor_value_leave_container(&curVal, &repMap); } if(err) { OCRepPayloadDestroy(*outPayload); *outPayload = NULL; } return err; }
/* * Adds the common properties of resource such as 'rt', 'if'. * 'links' property will be added in the response payload for collection resources. * If it fails for any reason, the resp_payload which is partially updated by this function will not be reset. * The caller of this method will have to release the payload and return an error response to the client. */ bool add_common_props(things_resource_s *rsrc, bool collection, OCRepPayload *resp_payload) { RET_FALSE_IF_PARAM_IS_NULL(TAG, rsrc); RET_FALSE_IF_PARAM_IS_NULL(TAG, resp_payload); // Set resource types. int rt_count = 0; char **res_types = NULL; if (!get_resource_types(rsrc, &res_types, &rt_count)) { THINGS_LOG_E(TAG, "Failed to get the resource types of the given resource(%s).", rsrc->uri); return false; } for (int i = 0; i < rt_count; i++) { if (!OCRepPayloadAddResourceType(resp_payload, res_types[i])) { THINGS_LOG_E(TAG, "Failed to add the resource type in the response payload."); // Release memory allocated for resource types. things_free_str_array(res_types, rt_count); return false; } } things_free_str_array(res_types, rt_count); // Set interface types. int if_count = 0; char **if_types = NULL; if (!get_interface_types(rsrc, &if_types, &if_count)) { THINGS_LOG_E(TAG, "Failed to get the interface types of the given resource(%s).", rsrc->uri); return false; } for (int i = 0; i < if_count; i++) { if (!OCRepPayloadAddInterface(resp_payload, if_types[i])) { THINGS_LOG_E(TAG, "Failed to add the interface type in the response payload."); // Release memory allocated for interface types. things_free_str_array(if_types, if_count); return false; } } things_free_str_array(if_types, if_count); #ifdef CONFIG_ST_THINGS_COLLECTION // Set "links"(only for collection). if (collection) { size_t count = 0; OCRepPayload **links = NULL; if (!form_collection_links(rsrc, &links, &count)) { THINGS_LOG_E(TAG, "Failed to form links for the given collection resource(%s).", rsrc->uri); return false; } THINGS_LOG_D(TAG, "Formed links for collection."); size_t dimensions[MAX_REP_ARRAY_DEPTH] = { count, 0, 0 }; bool result = OCRepPayloadSetPropObjectArray(resp_payload, OC_RSRVD_LINKS, links, dimensions); if (!result) { THINGS_LOG_E(TAG, "Failed to add the links in the response payload."); for (size_t i = 0; i < count && NULL != links[i]; i++) { OCRepPayloadDestroy(links[i]); } things_free(links); return false; } } #endif return true; }