void set_device_info(things_server_builder_s *builder, char *device_name, char *device_type)
{
	THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY);

	THINGS_LOG_D(TAG, "[/oic/d] name :%s", device_name);
	THINGS_LOG_D(TAG, "[/oic/d] type :%s", device_type);

	OCDeviceInfo device_info;
	device_info.deviceName = NULL;
	device_info.types = NULL;
	device_info.specVersion = NULL;
	device_info.dataModelVersions = NULL;

	things_string_duplicate(device_name, &device_info.deviceName);
	things_string_duplicate(OC_SPEC_VERSION, &device_info.specVersion);
	device_info.dataModelVersions = OCCreateOCStringLL(DEFAULT_DATA_MODEL_VERSIONS);
	device_info.types = OCCreateOCStringLL(device_type);
	OCResourcePayloadAddStringLL(&device_info.types, OC_RSRVD_RESOURCE_TYPE_DEVICE);

	iotivity_api_lock();

	OCSetDeviceInfo(device_info);

	iotivity_api_unlock();

	// OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, KEY_ATTR_DEVICE_NAME, device_name);

	things_free(device_info.deviceName);
	things_free(device_info.specVersion);
	OCFreeOCStringLL(device_info.dataModelVersions);
	OCFreeOCStringLL(device_info.types);

	THINGS_LOG_D(TAG, THINGS_FUNC_EXIT);
}
static int handle_post_req_on_single_rsrc(things_resource_s *single_rsrc)
{
	RET_VAL_IF_PARAM_IS_NULL(TAG, single_rsrc, 0);

	// Retrieve the request representation. This representation will hold all the input properties of post request.
	// Payload in this representation will be used to form the request message which will be given to the application.
	struct things_representation_s *req_rep = NULL;
	bool rep_exist = single_rsrc->things_get_representation(single_rsrc, &req_rep);
	if (!rep_exist || NULL == req_rep || NULL == req_rep->payload) {
		THINGS_LOG_E(TAG, "Empty payload in POST request.");
		return 0;				// TODO: When a post request comes with empty payload, how do we handle?
	}
	// Setup the response representation. This representation will be handed over to the underlying stack.
	// The payload which is passed as a parameter will be updated with the common properties.
	things_representation_s *resp_rep = things_create_representation_inst(NULL);
	RET_VAL_IF_NULL(TAG, resp_rep, "Failed to create response representation.", 0);

	if (!OCRepPayloadSetUri(resp_rep->payload, single_rsrc->uri)) {
		THINGS_LOG_E(TAG, "Failed to set the resource uri(%s) in response payload.", single_rsrc->uri);
		things_release_representation_inst(resp_rep);
		return 0;
	}

	THINGS_LOG_D(TAG, "Resource uri(%s) is set in the response payload.", single_rsrc->uri);

	// Get interface type from query parameter
	char *if_type = NULL;
	if (NULL != single_rsrc->query && strlen(single_rsrc->query) > 0) {
		bool found = false;
		bool result = get_query_value_internal(single_rsrc->query, OC_RSRVD_INTERFACE, &if_type, &found);
		if (found && !result) {	// If query is present but API returns false.
			THINGS_LOG_E(TAG, "Failed to get the interface type from query parameter(%s).", single_rsrc->query);
			things_release_representation_inst(resp_rep);
			return 0;
		}
	}
	// Set the common properties in the payload (Only for baseline interface).
	// The payload which is passed as a parameter will be updated with the common properties.
	if (NULL == if_type || !strncmp(if_type, OC_RSRVD_INTERFACE_DEFAULT, strlen(OC_RSRVD_INTERFACE_DEFAULT))) {
		if (!add_common_props(single_rsrc, false, resp_rep->payload)) {
			THINGS_LOG_E(TAG, "Failed to add the common properties in response payload.");
			things_release_representation_inst(resp_rep);
			things_free(if_type);
			return 0;
		}
		THINGS_LOG_D(TAG, "Added common properties in response payload.");
	}
	// Give the request properties to application and get the response back.
	bool res = handle_post_req_helper(single_rsrc->uri, single_rsrc->query, req_rep->payload, resp_rep->payload);
	if (res) {
		// Set the response representation in the resource.
		single_rsrc->things_set_representation(single_rsrc, resp_rep);
	} else {
		things_release_representation_inst(resp_rep);
	}
	things_free(if_type);
	return res ? 1 : 0;
}
static int handle_get_req_on_single_rsrc(things_resource_s *single_rsrc)
{
	RET_VAL_IF_PARAM_IS_NULL(TAG, single_rsrc, 0);

	// Setup the response representation. This representation will be handed over to the underlying stack.
	things_representation_s *resp_rep = things_create_representation_inst(NULL);
	RET_VAL_IF_NULL(TAG, resp_rep, "Failed to create response representation.", 0);

	bool result = OCRepPayloadSetUri(resp_rep->payload, single_rsrc->uri);
	if (!result) {
		THINGS_LOG_E(TAG, "Failed to set the resource uri(%s) in response payload.", single_rsrc->uri);
		things_release_representation_inst(resp_rep);
		return 0;
	}

	THINGS_LOG_D(TAG, "Resource uri(%s) is set in the response payload.", single_rsrc->uri);

	// Set the common properties in the payload (Only for baseline interface).
	char *if_type = NULL;
	if (NULL != single_rsrc->query && strlen(single_rsrc->query) > 0) {
		bool found = false;
		bool result = get_query_value_internal(single_rsrc->query, OC_RSRVD_INTERFACE, &if_type, &found);
		if (found && !result) {	// If query is present but API returns false.
			THINGS_LOG_E(TAG, "Failed to get the interface type from query parameter(%s).", single_rsrc->query);
			things_release_representation_inst(resp_rep);
			return 0;
		}
	}

	if (NULL == if_type || strlen(if_type) < 1 || !strncmp(if_type, OC_RSRVD_INTERFACE_DEFAULT, strlen(OC_RSRVD_INTERFACE_DEFAULT))) {
		if (!add_common_props(single_rsrc, false, resp_rep->payload)) {
			THINGS_LOG_E(TAG, "Failed to add the common properties in response payload.");
			things_release_representation_inst(resp_rep);
			things_free(if_type);
			return 0;
		}
		THINGS_LOG_D(TAG, "Added common properties in response payload.");
	}
	// Get the resource's properties from the application.
	result = handle_get_req_helper(single_rsrc->uri, single_rsrc->query, resp_rep->payload);
	if (!result) {
		things_release_representation_inst(resp_rep);
		things_free(if_type);
		return 0;
	}
	// Set the response representation in the resource.
	single_rsrc->things_set_representation(single_rsrc, resp_rep);

	things_free(if_type);
	return 1;
}
Example #4
0
void release_handler_instance(struct things_request_handler_s *handler)
{
	if (handler) {
		handler->deinit_module();
		things_free(handler);
	}
}
static void destroy_req_msg_inst_for_get(st_things_get_request_message_s *req_msg)
{
	RET_IF_PARAM_IS_NULL(TAG, req_msg);

	things_free(req_msg->resource_uri);
	things_free(req_msg->query);
	things_free(req_msg->property_key);

	req_msg->query = NULL;
	req_msg->resource_uri = NULL;
	req_msg->property_key = NULL;
	req_msg->get_query_value = NULL;
	req_msg->has_property_key = NULL;

	things_free(req_msg);
}
Example #6
0
void deinit_handler()
{
	g_quit_flag = 1;

	int iter = 0;
	if (g_handle_res_list != NULL) {
		for (iter = 0; iter < g_handle_res_cnt; iter++) {
			if (g_handle_res_list[iter] != NULL) {
				things_free(g_handle_res_list[iter]);
				g_handle_res_list[iter] = NULL;
			}
		}
		things_free(g_handle_res_list);
		g_handle_res_list = NULL;
	}
	g_handle_res_cnt = 0;
}
Example #7
0
void release_resource_inst_impl(things_resource_s *res)
{
	if (res != NULL) {
		if (res->uri != NULL) {
			things_free(res->uri);
			res->uri = NULL;
		}
		if (res->res_type != NULL) {
			things_free(res->res_type);
			res->res_type = NULL;
		}
		if (res->interface_type != NULL) {
			things_free(res->interface_type);
			res->interface_type = NULL;
		}
		if (res->cmd_id != NULL) {
			things_free(res->cmd_id);
			res->cmd_id = NULL;
		}
		if (res->query != NULL) {
			things_free(res->query);
			res->query = NULL;
		}
		if (res->rep != NULL) {
			things_release_representation_inst(res->rep);
		}
		if (res->dev_addr != NULL) {
			things_free(res->dev_addr);
		}
		things_free(res);
		res = NULL;
	}
}
static void destroy_req_msg_inst_for_post(st_things_set_request_message_s *req_msg, bool destroy_payload)
{
	RET_IF_PARAM_IS_NULL(TAG, req_msg);

	things_free(req_msg->resource_uri);
	things_free(req_msg->query);

	if (NULL != req_msg->rep) {
		destroy_representation_inst_internal(req_msg->rep, destroy_payload);
	}

	req_msg->resource_uri = NULL;
	req_msg->query = NULL;
	req_msg->rep = NULL;
	req_msg->get_query_value = NULL;

	things_free(req_msg);
}
Example #9
0
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;
}
Example #10
0
bool things_get_byte_value(struct things_representation_s *rep, char *key, uint8_t **value, size_t *size)
{
	OCByteString b_val = { NULL, 0 };
	bool ret = OCRepPayloadGetPropByteString((OCRepPayload *) rep->payload, key, &b_val);

	if (true == ret) {
		(*size) = b_val.len;
		(*value) = (uint8_t *) things_malloc((*size) + 1);
		memcpy((*value), b_val.bytes, b_val.len);

		if (b_val.bytes != NULL) {
			things_free(b_val.bytes);
			b_val.bytes = NULL;
		}
	}

	return ret;
}
void release_builder_instance(things_server_builder_s *builder)
{
	if (builder) {
		//    Thread should be terminated first..
		if (!g_quit_flag) {
			builder->deinit_module(builder);
		}

		if (builder->res_num > 0) {
			for (size_t iter = 0; iter < builder->res_num; iter++) {
				if (builder->gres_arr[iter] != NULL) {
					/*! Added by st_things for memory Leak fix*/
					release_resource_inst_impl(builder->gres_arr[iter]);
					builder->gres_arr[iter] = NULL;
				}
			}
		}

		things_free(builder);
		g_builder = NULL;
	}
}
Example #12
0
void things_release_representation_inst(things_representation_s *rep)
{
	if (rep != NULL) {
		if (rep->children_payload != NULL) {
			THINGS_LOG_D(TAG, "Representation has %lld Children.", rep->num_children);
			for (int64_t iter = 0; iter < rep->num_children; iter++) {
				if ((rep->children_payload[iter]) != NULL) {
					THINGS_LOG_D(TAG, "\t RELEASED.");
					OCPayloadDestroy((OCPayload *)(rep->children_payload[iter]));
					rep->children_payload[iter] = NULL;
				}
			}
		}
		if (rep->payload != NULL) {
			OCPayloadDestroy((OCPayload *)(rep->payload));
			rep->payload = NULL;
		}

		things_free(rep);
		rep = NULL;
	}
}
Example #13
0
bool things_get_arrayvalue(struct things_representation_s *mother, char *key, int *length, struct things_representation_s ***children)
{
	//THINGS_LOG_E(TAG, "NOt Supported This Function Yet");
	bool find_value = false;
	THINGS_LOG_D(TAG, "There're (%d) Number of children resources in the Payload : %d", mother->num_children);

	// if( OCRepPayloadGetPropInt((OCRepPayload*)(mother->payload), SEC_ATTRIBUTE_LENGTH, &(mother->num_children) ) )
	OCRepPayloadValue *payload_value = things_rep_payload_find_values((OCRepPayload *)(mother->payload), key);
	if (NULL != payload_value) {
		OCRepPayload **payload_values = NULL;
		size_t dimension_size = calcDimTotal(payload_value->arr.dimensions);
		size_t dimensions[3] = { dimension_size, 0, 0 };

		THINGS_LOG_D(TAG, "Dimension size in the Payload : %d", dimension_size);
		//    This is testing code only... will be removed...
		find_value = OCRepPayloadGetPropObjectArray((OCRepPayload *)(mother->payload), key, &payload_values, dimensions);
		THINGS_LOG_D(TAG, "Find Value : %d", find_value);
		if (find_value) {
			*children = (things_representation_s **) things_malloc(sizeof(things_representation_s *) *dimension_size);

			for (int iter = 0; iter < dimension_size; iter++) {
				(*children)[iter] = things_create_representation_inst(payload_values[iter]);
				/*! Added by st_things for memory Leak fix
				 */
				OCRepPayloadDestroy(payload_values[iter]);
			}
			/*! Added by st_things for memory Leak fix
			 */
			things_free(payload_values);
			*length = mother->num_children = dimension_size;
		}
	} else {
		THINGS_LOG_E(TAG, "DATA NOT EXIST~!!!!");
	}

	return find_value;
}
Example #14
0
void set_uri(struct things_resource_s *res, const char *key)
{
	//THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY);

	if (key == NULL) {
		return;
	}

	if (res->uri != NULL) {
		things_free(res->uri);
		res->uri = NULL;
	}
	res->uri = (char *)things_malloc(sizeof(char) *strlen(key) + 1);
	memset(res->uri, 0, strlen(key) + 1);
	things_strncpy(res->uri, key, strlen(key) + 1);

	if (NULL != res->rep) {
		OCRepPayloadSetUri(res->rep->payload, key);
	} else {
		THINGS_LOG_E(TAG, "Set URI Failed, No Representation Yet");
	}

	//THINGS_LOG_D(TAG, THINGS_FUNC_EXIT);
}
// 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;
}
/*
 * Helper method to get the response from application for POST requests.
 * The 'resp_payload' parameter will be used to get the response.
 * Common properties of the resource such as rt, if and links will not be set by this method.
 */
bool handle_post_req_helper(const char *res_uri, const char *query, OCRepPayload *req_payload, OCRepPayload *resp_payload)
{
	RET_FALSE_IF_PARAM_IS_NULL(TAG, req_payload);
	RET_FALSE_IF_PARAM_IS_NULL(TAG, resp_payload);
	RET_FALSE_IF_NULL(TAG, g_handle_set_req_cb, "Request callback for SET is NULL.");

	// Setup the response representation for application. This representation will be handed over to the application.
	st_things_representation_s *things_resp_rep = create_representation_inst_internal(resp_payload);
	RET_FALSE_IF_NULL(TAG, things_resp_rep, "Failed to create response representation.");

	// Setup the request message.
	st_things_set_request_message_s *req_msg = create_req_msg_inst_for_post(res_uri, query, NULL);
	if (NULL == req_msg) {
		THINGS_LOG_E(TAG, "Failed to create the request message for SET.");
		destroy_representation_inst_internal(things_resp_rep, false);
		return false;
	}

	/* Based on the resource type of the request (specified in the query parameters like rt=oic.r.switch.binary) and
	   interface type in the query parameter, add proper set of properties in the request representation.
	   Application's response representation should include
	   only the properties present in the request representation. */

	char *res_type = NULL;
	int count = 0;
	bool destroy_props = false;
	struct things_attribute_info_s **properties = NULL;

	// Get resource type from query parameter
	if (NULL != query && strlen(query) > 0) {
		bool found = false;
		bool result = get_query_value_internal(query, OC_RSRVD_RESOURCE_TYPE, &res_type, &found);
		if (found && !result) {	// If query is present but API returns false.
			THINGS_LOG_E(TAG, "Failed to get the resource type from query parameter(%s).", query);
			destroy_representation_inst_internal(things_resp_rep, false);
			destroy_req_msg_inst_for_post(req_msg, true);
			return false;
		}
	}
	// Get necessary set of properties.
	bool res = get_supported_properties(res_type, res_uri, &count, &properties, &destroy_props);
	if (!res) {
		THINGS_LOG_E(TAG, "Failed to get the resource properties based on its type or uri.");
		destroy_representation_inst_internal(things_resp_rep, false);
		destroy_req_msg_inst_for_post(req_msg, true);
		things_free(res_type);
		return false;
	}

	THINGS_LOG_D(TAG, "Total number of supported properties: %d.", count);

	res = true;
	// Check whether the request has all mandatory properties.
	for (int index = 0; index < count; index++) {
		if (NULL == properties[index]) {
			THINGS_LOG_E(TAG, "Property at index(%d) is NULL.", index);
			res = false;
			break;
		}

		if (!IS_WRITABLE(properties[index]->rw)) {
			if (OCRepPayloadIsNull(req_payload, properties[index]->key)) {
				THINGS_LOG_E(TAG, "(%s) is not present in the request.", properties[index]->key);
				res = false;
				break;
			}
		}
	}

	if (!res) {
		if (destroy_props) {
			things_free(properties);
		}
		destroy_representation_inst_internal(things_resp_rep, false);
		destroy_req_msg_inst_for_post(req_msg, true);
		things_free(res_type);
		return false;
	}

	for (int index = 0; index < count && NULL != properties[index]; index++) {
		bool exist = (false == OCRepPayloadIsNull(req_payload, properties[index]->key));
		THINGS_LOG_D(TAG, "Is property(%s) present in request payload?: %s", properties[index]->key, exist ? "Yes" : "No");
		if (exist && IS_WRITABLE(properties[index]->rw)) {
			res = add_property_in_post_req_msg(req_msg, req_payload, properties[index]);
			if (!res) {
				break;
			}
		}
	}

	if (res) {
		// Remove 'rt' and 'if' from query parameters.
		if (strstr(req_msg->query, OC_RSRVD_RESOURCE_TYPE) != NULL) {
			remove_query_parameter(req_msg->query, OC_RSRVD_RESOURCE_TYPE);
		}
		if (strstr(req_msg->query, OC_RSRVD_INTERFACE) != NULL) {
			remove_query_parameter(req_msg->query, OC_RSRVD_INTERFACE);
		}
		res = g_handle_set_req_cb(req_msg, things_resp_rep);
		THINGS_LOG_D(TAG, "The result of application's callback : %s", res ? "true" : "false");
	} else {
		THINGS_LOG_E(TAG, "Failed to add properties in request message.");
	}

	if (destroy_props) {
		things_free(properties);
	}
	destroy_req_msg_inst_for_post(req_msg, true);
	destroy_representation_inst_internal(things_resp_rep, false);
	things_free(res_type);
	return true;
}
/*
 * Helper method to get the response from application for GET requests.
 * The 'resp_payload' parameter will be used to get the response.
 * Common properties of the resource such as rt, if and links will not be set by this method.
 */
bool handle_get_req_helper(const char *res_uri, const char *query, OCRepPayload *resp_payload)
{
	RET_FALSE_IF_PARAM_IS_NULL(TAG, resp_payload);
	RET_FALSE_IF_NULL(TAG, g_handle_get_req_cb, "Request callback for GET is NULL.");

	// Setup the request message.
	st_things_get_request_message_s *req_msg = create_req_msg_inst_for_get(res_uri, query);
	RET_FALSE_IF_NULL(TAG, req_msg, "Failed to create request message for GET.");

	/* Based on the resource type of the request (specified in the query parameters like rt=oic.r.switch.binary) and
	   interface type in the query parameter, add proper set of property keys in the request message.
	   Application's response representation should include
	   only those properties which are present in the request message. */
	char *res_type = NULL;
	int count = 0;
	bool destroy_props = false;
	struct things_attribute_info_s **properties = NULL;

	// Get resource type from query parameter
	if (NULL != query && strlen(query) > 0) {
		bool found = false;
		bool result = get_query_value_internal(query, OC_RSRVD_RESOURCE_TYPE, &res_type, &found);
		if (found && !result) {	// If query is present but API returns false.
			THINGS_LOG_E(TAG, "Failed to get the resource type from query parameter(%s).", query);
			destroy_req_msg_inst_for_get(req_msg);
			return false;
		}
	}
	// Get supported set of properties based on resource type query parameter.
	// If resource type is not available, then get the properties based on resource uri.
	bool res = get_supported_properties(res_type, res_uri, &count, &properties, &destroy_props);
	if (!res) {
		THINGS_LOG_E(TAG, "Failed to get the resource properties based on its type or uri.");
		destroy_req_msg_inst_for_get(req_msg);
		things_free(res_type);
		return false;
	}
	// Calculate the length of all property keys
	int total_length_of_prop_keys = 0;
	for (int index = 0; index < count; index++) {
		if (NULL != properties[index]) {
			total_length_of_prop_keys += strlen(properties[index]->key);
		}
	}
	total_length_of_prop_keys += count;	// For delimiter
	total_length_of_prop_keys += 1;	// For null character

	// Allocate memory for holding property keys with delimiters
	req_msg->property_key = (char *)things_calloc(total_length_of_prop_keys, sizeof(char));
	if (!req_msg->property_key) {
		THINGS_LOG_E(TAG, "Failed to allocate memory for property key in GET request message.");
		if (destroy_props) {
			things_free(properties);
		}
		destroy_req_msg_inst_for_get(req_msg);
		things_free(res_type);
		return false;
	}
	// Get interface type from query parameter.
	char *if_type = NULL;
	if (NULL != query && strlen(query) > 0) {
		bool found = false;
		bool result = get_query_value_internal(query, OC_RSRVD_INTERFACE, &if_type, &found);
		if (found && !result) {	// If query is present but API returns false.
			THINGS_LOG_E(TAG, "Failed to get the interface type from query parameter(%s).", query);
			if (destroy_props) {
				things_free(properties);
			}
			destroy_req_msg_inst_for_get(req_msg);
			things_free(res_type);
			return false;
		}
	}

	bool handled = false;
	if (NULL != if_type && strlen(if_type) > 0) {
		THINGS_LOG_D(TAG, "Interface type is (%s).", if_type);
		if (0 == strncmp(if_type, OC_RSRVD_INTERFACE_READ, strlen(OC_RSRVD_INTERFACE_READ))) {
			// Add all the attributes which are readable.
			for (int index = 0; index < count; index++) {
				if (NULL != properties[index] && IS_READABLE(properties[index]->rw)) {
					add_property_key_in_get_req_msg(req_msg, properties[index]->key);
				}
			}
			handled = true;
		} else if (0 == strncmp(if_type, ST_THINGS_RSRVD_INTERFACE_READWRITE, strlen(ST_THINGS_RSRVD_INTERFACE_READWRITE))) {
			// Add all the attributes which are readable and writable.
			for (int index = 0; index < count; index++) {
				if (NULL != properties[index] && IS_READABLE(properties[index]->rw) && IS_WRITABLE(properties[index]->rw)) {
					add_property_key_in_get_req_msg(req_msg, properties[index]->key);
				}
			}
			handled = true;
		}
	}

	if (!handled) {				// For all other cases, add all the property keys.
		for (int index = 0; index < count; index++) {
			if (NULL != properties[index]) {
				add_property_key_in_get_req_msg(req_msg, properties[index]->key);
			}
		}
	}
	// Remove 'rt' and 'if' from query parameters
	if (NULL != query && strlen(query) > 0) {
		if (strstr(req_msg->query, OC_RSRVD_RESOURCE_TYPE) != NULL) {
			remove_query_parameter(req_msg->query, OC_RSRVD_RESOURCE_TYPE);
		}
		if (strstr(req_msg->query, OC_RSRVD_INTERFACE) != NULL) {
			remove_query_parameter(req_msg->query, OC_RSRVD_INTERFACE);
		}
	}
	// Setup the response representation for application. This representation will be handed over to the application.
	st_things_representation_s *things_resp_rep = create_representation_inst_internal(resp_payload);
	if (NULL != things_resp_rep) {
		res = g_handle_get_req_cb(req_msg, things_resp_rep);
		THINGS_LOG_D(TAG, "The result of application's callback : %s.", res ? "true" : "false");
		destroy_representation_inst_internal(things_resp_rep, false);
	} else {
		THINGS_LOG_E(TAG, "Failed to create response representation.");
		res = false;
	}

	destroy_req_msg_inst_for_get(req_msg);
	if (destroy_props) {
		things_free(properties);
	}
	things_free(res_type);
	things_free(if_type);

	return res;
}
bool get_query_value_internal(const char *query, const char *key, char **value, bool *found)
{
	RET_FALSE_IF_EXPR_IS_TRUE(TAG, (NULL == query || strlen(query) < 1), "Invalid query.");
	RET_FALSE_IF_EXPR_IS_TRUE(TAG, (NULL == key || strlen(key) < 1), "Invalid key.");
	RET_FALSE_IF_PARAM_IS_NULL(TAG, value);

	*value = NULL;
	if (NULL != found) {
		*found = false;
	}

	int query_len = strlen(query);
	int key_len = strlen(key);
	char *p_buff = NULL;
	char *p_origin = NULL;
	char *p_ptr = NULL;

	p_origin = p_buff = (char *)things_malloc(query_len + 1);
	if (NULL == p_origin) {
		THINGS_LOG_E(TAG, "Failed to allocate memory to get a specific value from query.");
		return false;
	}

	memset(p_buff, 0, query_len + 1);
	memcpy(p_buff, query, query_len);

	p_ptr = strtok(p_buff, QUERY_DELIMITER);
	if (NULL == p_ptr) {
		THINGS_LOG_E(TAG, "Failed to tokenize the query.");
		things_free(p_origin);
		return false;
	}

	bool res = false;
	while (p_ptr != NULL) {
		if (strncmp(p_ptr, key, key_len) == 0) {
			THINGS_LOG_D(TAG, "Key(%s) exists in query parameter(%s).", key, query);
			if (NULL != found) {
				*found = true;
			}

			*value = things_clone_string(p_ptr + key_len + 1);
			if (NULL == *value) {
				THINGS_LOG_E(TAG, "Failed to clone the query value.");
				things_free(p_origin);
				return false;
			} else {
				res = true;
			}
			break;
		}

		p_ptr = strtok(NULL, QUERY_DELIMITER);
	}

	if (NULL == p_ptr) {
		THINGS_LOG_D(TAG, "Key(%s) doesn't exist in query(%s).", key, query);
	}

	things_free(p_origin);

	return res;
}
Example #19
0
bool get_query(struct things_resource_s *res, char *key, char **value)
{
	THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY);

	if (NULL == key) {
		return 0;
	} else if (NULL == res) {
		return 0;
	} else if (NULL == res->query) {
		return 0;
	} else if (strlen(res->query) < 1) {
		return 0;
	}

	THINGS_LOG_D(TAG, "Query is %s.", res->query);

	*value = NULL;

	char *p_buff = NULL, *p_origin = NULL;
	char *p_ptr = NULL;
	char *p_ptr2 = NULL;

	p_origin = p_buff = (char *)things_malloc(strlen(res->query) + 1);

	if (NULL == p_buff || NULL == p_origin) {
		return 0;
	}

	memset(p_buff, 0, strlen(res->query) + 1);
	THINGS_LOG_D(TAG, "p_buff is initialized by 0.");
	memcpy(p_buff, res->query, strlen(res->query) + 1);
	THINGS_LOG_D(TAG, "p_buff is Initialized as", res->query);

	p_ptr = strtok(p_buff, QUERY_DELIMITER);
	if (p_ptr != NULL) {
		p_ptr2 = p_ptr;
	} else {
		things_free(p_origin);
		return 0;
	}
	//while (p_ptr != NULL)
	while (p_ptr2 != NULL) {
		if (strncmp(p_ptr2, key, strlen(key)) == 0) {
			THINGS_LOG_D(TAG, "\tFind Query : %s", p_ptr2 + strlen(key) + 1);

			things_string_duplicate(p_ptr2 + strlen(key) + 1, value);
			if (NULL == *value) {
				things_free(p_origin);
				return 1;
			}
			THINGS_LOG_D(TAG, "\tRESULT : %s", *value);
			break;
		}

		p_ptr2 = strtok(NULL, QUERY_DELIMITER);
	}

	things_free(p_origin);

	THINGS_LOG_D(TAG, THINGS_FUNC_EXIT);

	return 1;
}
/*
 * 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;
}
Example #21
0
int fmwup_http_download_file(const char *download_url)
{
	THINGS_LOG_D(TAG, THINGS_FUNC_ENTRY);

	download_state = FOTA_DOWNLOAD_STATE_JSON;
	json_str = (char *)things_malloc(FOTA_REC_JSON_SIZE); 
	recv_size = 0;
	
	is_link_fail = false;

	// parsing json
	if (wget_from_url(download_url) < 0) {
		THINGS_LOG_E(TAG, "wget_from_url error");
		things_free(json_str);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}

	json_str[recv_size] = 0;

	if (is_link_fail) {
		things_free(json_str);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}

	THINGS_LOG_D(TAG, "[recv:JSON] state : %d / recv_size : %u / total size : %u / json = %s", download_state, recv_size, total_size, json_str);

	if (recv_size != total_size) {
		THINGS_LOG_E(TAG, "[recv:JSON] file size error");
		things_free(json_str);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}

	fotahal_handle = fotahal_open();
	if (fotahal_handle == NULL) {
		fotahal_close(fotahal_handle);
		things_free(json_str);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}
	download_state = FOTA_DOWNLOAD_STATE_BINARY;


	cJSON *root = cJSON_Parse((const char *)json_str);
	cJSON *url = cJSON_GetObjectItem(root, KEY_URL);
	recv_size = 0;

	is_link_fail = false;

	if (wget_from_url(url->valuestring) < 0) {
		THINGS_LOG_E(TAG, "wget_from_url error");

		if (root != NULL) {
			cJSON_Delete(root);
		}
		fotahal_erase(fotahal_handle);
		fotahal_close(fotahal_handle);
		things_free(json_str);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}

	if (is_link_fail) {
		things_free(json_str);
		fotahal_erase(fotahal_handle);
		fotahal_close(fotahal_handle);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}

	THINGS_LOG_D(TAG, "[recv:BINARY] state : %d / recv_size : %u / total size : %u", download_state, recv_size, total_size, total_size);

	if (recv_size != total_size) {
		THINGS_LOG_E(TAG, "[recv:BINARY] file size error");
		fotahal_erase(fotahal_handle);
		fotahal_close(fotahal_handle);
		things_free(json_str);
		download_state = FOTA_DOWNLOAD_STATE_NONE;
		return -1;
	}

	if (root != NULL) {
		cJSON_Delete(root);
	}
	things_free(json_str);

	download_state = FOTA_DOWNLOAD_STATE_DONE;

	fotahal_close(fotahal_handle);

	return 0;
}
static bool add_property_in_post_req_msg(st_things_set_request_message_s *req_msg, OCRepPayload *req_payload, things_attribute_info_s *prop)
{
	RET_FALSE_IF_PARAM_IS_NULL(TAG, req_msg);
	RET_FALSE_IF_PARAM_IS_NULL(TAG, req_msg->rep);
	RET_FALSE_IF_PARAM_IS_NULL(TAG, req_msg->rep->payload);
	RET_FALSE_IF_PARAM_IS_NULL(TAG, req_payload);
	RET_FALSE_IF_PARAM_IS_NULL(TAG, prop);

	OCRepPayload *resp_payload = req_msg->rep->payload;

	THINGS_LOG_D(TAG, "Property Key is %s", prop->key);
	THINGS_LOG_D(TAG, "Property type is %d", prop->type);

	// Based on the property type, call appropriate methods to copy
	// the property from request payload to request representation.
	bool result = false;
	switch (prop->type) {
	case BOOL_ID: {
		bool value = false;
		if (OCRepPayloadGetPropBool(req_payload, prop->key, &value)) {
			result = OCRepPayloadSetPropBool(resp_payload, prop->key, value);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the boolean value of '%s' in request message.", prop->key);
			}
		} else {
			THINGS_LOG_E(TAG, "Failed to get the boolean value of '%s' for request message.", prop->key);
		}
	}
	break;
	case INT_ID: {
		int64_t value = 0;
		if (OCRepPayloadGetPropInt(req_payload, prop->key, &value)) {
			result = OCRepPayloadSetPropInt(resp_payload, prop->key, value);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the integer value of '%s' in request message", prop->key);
			}
		} else {
			THINGS_LOG_E(TAG, "Failed to get the integer value of '%s' for request message", prop->key);
		}
	}
	break;
	case DOUBLE_ID: {
		double value = 0.0;
		if (OCRepPayloadGetPropDouble(req_payload, prop->key, &value)) {
			result = OCRepPayloadSetPropDouble(resp_payload, prop->key, value);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the double value of '%s' in request message", prop->key);
			}
		} else {
			THINGS_LOG_E(TAG, "Failed to get the double value of '%s' for request message", prop->key);
		}
	}
	break;
	case STRING_ID: {
		char *value = NULL;
		if (OCRepPayloadGetPropString(req_payload, prop->key, &value)) {
			result = OCRepPayloadSetPropString(resp_payload, prop->key, value);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the string value of '%s' in request message", prop->key);
			}

			things_free(value);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the string value of '%s' for request message", prop->key);
		}
	}
	break;
	case OBJECT_ID: {
		OCRepPayload *value = NULL;
		if (OCRepPayloadGetPropObject(req_payload, prop->key, &value)) {
			result = OCRepPayloadSetPropObject(resp_payload, prop->key, value);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the object value of '%s' in request message", prop->key);
			}

			OCRepPayloadDestroy(value);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the object value of '%s' for request message", prop->key);
		}
	}
	break;
	case BYTE_ID: {
		OCByteString byte_value;
		if (OCRepPayloadGetPropByteString(req_payload, prop->key, &byte_value)) {
			result = OCRepPayloadSetPropByteString(resp_payload, prop->key, byte_value);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the byte string value of '%s' in request message", prop->key);
			}

			things_free(byte_value.bytes);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the byte string value of '%s' for request message", prop->key);
		}
	}
	break;
	case INT_ARRAY_ID: {
		int64_t *value = NULL;
		size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
		if (OCRepPayloadGetIntArray(req_payload, prop->key, &value, dimensions)) {
			result = OCRepPayloadSetIntArray(resp_payload, prop->key, value, dimensions);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the integer array value of '%s' in request message", prop->key);
			}

			things_free(value);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the integer array value of '%s' for request message", prop->key);
		}
	}
	break;
	case DOUBLE_ARRAY_ID: {
		double *value = NULL;
		size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
		if (OCRepPayloadGetDoubleArray(req_payload, prop->key, &value, dimensions)) {
			result = OCRepPayloadSetDoubleArray(resp_payload, prop->key, value, dimensions);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the double array value of '%s' in request message", prop->key);
			}

			things_free(value);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the double array value of '%s' for request message", prop->key);
		}
	}
	break;
	case STRING_ARRAY_ID: {
		char **value = NULL;
		size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
		if (OCRepPayloadGetStringArray(req_payload, prop->key, &value, dimensions)) {
			result = OCRepPayloadSetStringArray(resp_payload, prop->key, value, dimensions);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the string array value of '%s' in request message", prop->key);
			}

			size_t len = calcDimTotal(dimensions);
			things_free_str_array(value, len);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the string array value of '%s' for request message", prop->key);
		}
	}
	break;
	case OBJECT_ARRAY_ID: {
		OCRepPayload **value = NULL;
		size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
		if (OCRepPayloadGetPropObjectArray(req_payload, prop->key, &value, dimensions)) {
			result = OCRepPayloadSetPropObjectArray(resp_payload, prop->key, value, dimensions);
			if (!result) {
				THINGS_LOG_E(TAG, "Failed to set the object array value of '%s' in request message", prop->key);
			}

			size_t len = calcDimTotal(dimensions);
			for (size_t index = 0; index < len; index++) {
				OCRepPayloadDestroy(value[index]);
			}
			things_free(value);
		} else {
			THINGS_LOG_E(TAG, "Failed to get the object array value of '%s' for request message", prop->key);
		}
	}
	break;
	default:
		THINGS_LOG_E(TAG, "Invalid property type (%d).", prop->type);
		break;
	}

	return result;
}