+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _APPFW_DATA_CONTROL_BULK_H_
-#define _APPFW_DATA_CONTROL_BULK_H_
-
-#include <data_control_types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int datacontrol_bulk_data_get_data(data_control_bulk_data_h bulk_data_h, int idx, bundle **data);
-int datacontrol_bulk_data_get_count(data_control_bulk_data_h bulk_data_h, int *count);
-int datacontrol_bulk_data_add(data_control_bulk_data_h bulk_data_h, bundle *data);
-int datacontrol_bulk_data_create(data_control_bulk_data_h *bulk_data_h);
-int datacontrol_bulk_data_destroy(data_control_bulk_data_h bulk_data_h);
-
-int datacontrol_bulk_result_data_get_result_data(data_control_bulk_result_data_h result_data_h, int idx, bundle **data, int *result);
-int datacontrol_bulk_result_data_get_count(data_control_bulk_result_data_h result_data_h, int *count);
-int datacontrol_bulk_result_data_add(data_control_bulk_result_data_h result_data_h, bundle *result_data, int result);
-int datacontrol_bulk_result_data_create(data_control_bulk_result_data_h *result_data_h);
-int datacontrol_bulk_result_data_destroy(data_control_bulk_result_data_h result_data_h);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _APPFW_DATA_CONTROL_BULK_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file data-control-map.h
- * @brief This is the header file for the key-value structured data control.
- */
-
-#ifndef _APPFW_DATA_CONTROL_MAP_H_
-#define _APPFW_DATA_CONTROL_MAP_H_
-
-#include <data-control-types.h>
-#include <data_control_types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Called when the response is received from the key-value structured data control provider.
- *
- * @param [in] request_id The request ID that identifies the data control
- * @param [in] provider The provider handle
- * @param [in] provider_result Set to true if the data control provider successfully processed @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_map_add_bulk_data_response_cb)(int request_id, datacontrol_h provider,
- data_control_bulk_result_data_h bulk_results,
- bool provider_result, const char *error, void *user_data);
-
-
-
-/**
- * @brief Called when the result value list is received from the key-value structured data control provider.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] result_value_list The result value list of the data control request that gets the matching values
- * @param [in] result_value_count The number of the values
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_map_get_response_cb)(int request_id, datacontrol_h provider,
- char **result_value_list, int result_value_count, bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when the response is received from the key-value structured data control provider.
- *
- * @param [in] request_id The request ID that identifies the data control
- * @param [in] provider The provider handle
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_map_set_response_cb)(int request_id, datacontrol_h provider,
- bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when the response is received from the key-value structured data control provider.
- *
- * @param [in] request_id The request ID that identifies the data control
- * @param [in] provider The provider handle
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_map_add_response_cb)(int request_id, datacontrol_h provider,
- bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when the response is received from the key-value structured data control provider.
- *
- * @param [in] request_id The request ID that identifies the data control
- * @param [in] provider The provider handle
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_map_remove_response_cb)(int request_id, datacontrol_h provider,
- bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief The structure type to contain the set of callback functions for handling the response events
- * of the key-value structured data control.
- * @see datacontrol_map_get_response_cb()
- * @see datacontrol_map_set_response_cb()
- * @see datacontrol_map_add_response_cb()
- * @see datacontrol_map_remove_response_cb()
- * @see datacontrol_map_add_bulk_data_response_cb()
- */
-typedef struct {
- datacontrol_map_get_response_cb get;
- datacontrol_map_set_response_cb set;
- datacontrol_map_add_response_cb add;
- datacontrol_map_remove_response_cb remove;
- datacontrol_map_add_bulk_data_response_cb bulk_add;
-} datacontrol_map_response_cb;
-
-/**
- * @brief Creates a provider handle.
- * @param [out] provider The provider handle
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_map_destroy()
- *
- * The following example demonstrates how to use the %datacontrol_map_create() method.
- *
- * @code
- *
- * int main()
- * {
- * const char *provider_id = "http://tizen.org/datacontrol/provider/example";
- * const char *data_id = "table";
- * datacontrol_h provider;
- * int result = 0;
- *
- * result = datacontrol_map_create(&provider);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Creating data control provider is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_map_set_provider_id(provider, provider_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Setting providerID is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_map_set_data_id(provider, data_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Setting dataID is failed with error: %d", result);
- * return result;
- * }
- *
- * // Executes some operations
- *
- * result = datacontrol_map_destroy(provider);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Destroying data control provider is failed with error: %d", result);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_map_create(datacontrol_h *provider);
-
-/**
- * @brief Destroys the provider handle and releases all its resources.
- * @param [in] provider The provider handle
- * @return 0 on success, otherwise a negative error value.
- * @remark When operations of data control are finished, this function must be called to prevent memory leak.
- * @see datacontrol_map_create()
- */
-EXPORT_API int datacontrol_map_destroy(datacontrol_h provider);
-
-/**
- * @brief Sets the Provider ID.
- * @param [in] provider The provider handle
- * @param [in] provider_id The data control provider ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_map_get_provider_id()
- */
-EXPORT_API int datacontrol_map_set_provider_id(datacontrol_h provider, const char *provider_id);
-
-/**
- * @brief Gets the Provider ID.
- * @param [in] provider The provider handle
- * @param [out] provider_id The data control provider ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_map_set_provider_id()
- */
-EXPORT_API int datacontrol_map_get_provider_id(datacontrol_h provider, char **provider_id);
-
-/**
- * @brief Sets the Data ID.
- * @param [in] provider The provider handle
- * @param [in] data_id A string for identifying a specific table to operate. @n
- * The string consists of one or more components separated by a slash('/').
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_map_get_data_id()
- */
-EXPORT_API int datacontrol_map_set_data_id(datacontrol_h provider, const char *data_id);
-
-/**
- * @brief Gets the Data ID.
- * @param [in] provider The provider handle
- * @param [out] data_id A string for identifying a specific table to operate. @n
- * The string consists of one or more components separated by a slash('/').
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_map_set_data_id()
- */
-EXPORT_API int datacontrol_map_get_data_id(datacontrol_h provider, char **data_id);
-
-/**
- * @brief Registers a callback function for the key-value structured data control response. @n
- * The application is notified when a data control response is received from the @c provider.
- * @param [in] provider The provider handle
- * @param [in] callback The callback function to be called when a response is received.
- * @param [in] user_data The user data to be passed to the callback function
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_map_unregister_response_cb()
- */
-EXPORT_API int datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_response_cb *callback, void *user_data);
-
-/**
- * @brief Unregisters the callback function in @c provider.
- * @param [in] provider The provider handle
- * @return 0 on success, otherwise a negative error value.
- */
-EXPORT_API int datacontrol_map_unregister_response_cb(datacontrol_h provider);
-
-/**
- * @brief Gets the value list associated with the specified @c key from the key-values map owned by the key-value structured data control provider.
- *
- * @param [in] provider The provider handle
- * @param [in] key The key of the value list to obtain
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- *
- * The following example demonstrates how to use the %datacontrol_map_get() method.
- *
- * @code
- *
- * void map_get_response_cb(int request_id, datacontrol_h provider,
- * char **result_value_list, int result_value_count, bool provider_result, const char *error)
- * {
- * if (provider_result) {
- * LOGI("The get operation is successful");
- * }
- * else {
- * LOGI("The get operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_map_response_cb map_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * char *key = "key";
- *
- * map_callback.get = map_get_response_cb;
- * result = datacontrol_map_register_response_cb(provider, &map_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_map_get(provider, key, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Getting the value list of the key(%s) is failed with error: %d", key, result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_map_get(datacontrol_h provider, const char *key, int *request_id);
-
-/**
- * @brief Gets the value list associated with the specified @c key from the key-values map owned by the key-value structured data control provider.
- *
- * @param [in] provider The provider handle
- * @param [in] key The key of the value list to obtain
- * @param [out] request_id The request ID
- * @param [in] page_number The page number of the value set @n
- * It starts from 1.
- * @param [in] count_per_page The desired maximum count of the data items per page
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- */
-EXPORT_API int datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *request_id, int page_number, int count_per_page);
-
-/**
- * @brief Sets the value associated with the specified @c key to a new value.
- *
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to replace
- * @param [in] old_value The value to replace
- * @param [in] new_value The new value that replaces the existing value
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- *
- * The following example demonstrates how to use the %datacontrol_map_set() method.
- *
- * @code
- *
- * void map_set_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error)
- * {
- * if (provider_result) {
- * LOGI("The set operation is successful");
- * }
- * else {
- * LOGI("The set operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_map_response_cb map_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * char *key = "key";
- * char *old_value = "old value";
- * char *new_value = "new value";
- *
- * map_callback.set = map_set_response_cb;
- * result = datacontrol_map_register_response_cb(provider, &map_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_map_set(provider, key, old_value, new_value, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Replacing old_value(%s) with new_value(%s) is failed with error: %d", old_value, new_value, result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_value, const char *new_value, int *request_id);
-
-/**
- * @brief Adds the @c value associated with the specified @c key to the key-values map owned by the key-value structured data control provider.
- *
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to add
- * @param [in] value The value to add
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- *
- * The following example demonstrates how to use the %datacontrol_map_add() method.
- *
- * @code
- *
- * void map_add_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
- * if (provider_result) {
- * LOGI("The add operation is successful");
- * }
- * else {
- * LOGI("The add operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_map_response_cb map_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * const char *key = "key";
- * const char *value = "value";
- *
- * map_callback.add = map_add_response_cb;
- * result = datacontrol_map_register_response_cb(provider, &map_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_map_add(provider, key, value, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Adding %s-%s pair is failed with error: %d", key, value, result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int *request_id);
-
-/**
- * @brief Removes the @c value associated with the specified @c key from the key-values map owned by the key-value structured data control provider.
- *
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to remove
- * @param [in] value The value to remove
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- *
- * The following example demonstrates how to use the %datacontrol_map_remove() method.
- *
- * @code
- *
- * void map_remove_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
- * if (provider_result) {
- * LOGI("The remove operation is successful");
- * }
- * else {
- * LOGI("The remove operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_map_response_cb map_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * const char *key = "key";
- * const char *value = "value";
- *
- * ...
- *
- * map_callback.remove = map_remove_response_cb;
- * result = datacontrol_map_register_response_cb(provider, &map_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_map_remove(provider, key, value, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Removing %s-%s pair is failed with error: %d", key, value, result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_map_remove(datacontrol_h provider, const char *key, const char *value, int *request_id);
-EXPORT_API int datacontrol_map_add_bulk_data(datacontrol_h provider, data_control_bulk_data_h bulk_data_h, int *request_id);
-EXPORT_API bool datacontrol_map_cb_is_registered(char *provider_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _APPFW_DATA_CONTROL_MAP_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _APPFW_DATA_CONTROL_DATA_CHANGE_H_
-#define _APPFW_DATA_CONTROL_DATA_CHANGE_H_
-
-#include <data_control_types.h>
-#include <data_control_noti.h>
-#include <data-control-types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Adds data changed callback which called when provider's data is changed.
- * @param [in] provider Target provider handle
- * @param [in] callback The callback function to be called when consumer receive data changed notification
- * @param [in] user_data The user data to be passed to the callback function
- * @param [in] result_callback The callback function to be called when consumer receive add data changed callback process result
- * @param [in] result_cb_user_data The user data to be passed to the result_callback function
- * @param [out] callback_id Added callback ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- */
-EXPORT_API int datacontrol_add_data_change_cb(datacontrol_h provider,
- data_control_data_change_cb callback,
- void *user_data,
- data_control_add_callback_result_cb result_callback,
- void *result_cb_user_data,
- int *callback_id);
-
-/**
- * @brief Removes the data changed callback function.
- * @param [in] provider Target provider handle
- * @param [in] callback_id Target callback ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- */
-EXPORT_API int datacontrol_remove_data_change_cb(datacontrol_h provider, int callback_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _APPFW_DATA_CONTROL_DATA_CHANGE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file data-control-provider.h
- * @brief This is the header file for the data control provider.
- */
-
-#ifndef _APPFW_DATA_CONTROL_PROVIDER_H_
-#define _APPFW_DATA_CONTROL_PROVIDER_H_
-
-#include <data-control-types.h>
-#include <data_control_types.h>
-#include <data_control_provider.h>
-#include <data-control-sql-cursor.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Called when the insert request is received from an application using SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] bulk_results The column-value pairs to insert @n
- * If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_sql_bulk_insert_request_cb)(int request_id, datacontrol_h provider,
- data_control_bulk_data_h bulk_data, void *user_data);
-
-/**
- * @brief Called when the insert request is received from an application using SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] insert_data The column-value pairs to insert @n
- * If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_sql_insert_request_cb)(int request_id, datacontrol_h provider,
- bundle *insert_data, void *user_data);
-
-/**
- * @brief Called when the update request is received from an application using SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] update_data The column-value pairs to update @n
- * If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
- * @param [in] where A filter to select the desired rows to update. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_sql_update_request_cb)(int request_id, datacontrol_h provider,
- bundle *update_data, const char *where, void *user_data);
-
-/**
- * @brief Called when the delete request is received from an application using SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] where A filter to select the desired rows to delete. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_sql_delete_request_cb)(int request_id, datacontrol_h provider,
- const char *where, void *user_data);
-
-/**
- * @brief Called when the select request is received from an application using SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] column_list The column list to query
- * @param [in] column_count The total number of columns to be queried
- * @param [in] where A filter to select the desired rows. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [in] order The sorting order of the rows to query. @n
- * It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_sql_select_request_cb)(int request_id, datacontrol_h provider,
- const char **column_list, int column_count, const char *where, const char *order, void *user_data);
-
-/**
- * @brief Called when the request for obtaining the value list is received from the key-value structured data control consumer.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] key The key of the value list to obtain
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_map_get_value_request_cb)(int request_id, datacontrol_h provider, const char *key, void *user_data);
-
-/**
- * @brief Called when the request for replacing the value is received from the key-value structured data control consumer.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to replace
- * @param [in] old_value The value to replace
- * @param [in] new_value The new value that replaces the existing value
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_map_set_value_request_cb)(int request_id, datacontrol_h provider, const char *key,
- const char *old_value, const char *new_value, void *user_data);
-
-/**
- * @brief Called when the request for adding the value is received from the key-value structured data control consumer.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to add
- * @param [in] value The value to add
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_map_add_value_request_cb)(int request_id, datacontrol_h provider, const char *key,
- const char *value, void *user_data);
-
-/**
- * @brief Called when the request for removing the value is received from the key-value structured data control consumer.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to remove
- * @param [in] value The value to remove
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_map_remove_value_request_cb)(int request_id, datacontrol_h provider, const char *key,
- const char *value, void *user_data);
-
-/**
- * @brief Called when the request for removing the value is received from the key-value structured data control consumer.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] key The key of the value to remove
- * @param [in] value The value to remove
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_provider_map_bulk_add_value_request_cb)(int request_id, datacontrol_h provider,
- data_control_bulk_data_h bulk_data, void *user_data);
-
-/**
- * @brief The structure type to contain the set of callback functions for handling the request events
- * of SQL-friendly interface based data control.
- * @see datacontrol_provider_sql_select_request_cb()
- * @see datacontrol_provider_sql_insert_request_cb()
- * @see datacontrol_provider_sql_update_request_cb()
- * @see datacontrol_provider_sql_delete_request_cb()
- */
-typedef struct {
- datacontrol_provider_sql_insert_request_cb insert;
- datacontrol_provider_sql_select_request_cb select;
- datacontrol_provider_sql_update_request_cb update;
- datacontrol_provider_sql_delete_request_cb delete;
- datacontrol_provider_sql_bulk_insert_request_cb bulk_insert;
-} datacontrol_provider_sql_cb;
-
-/**
- * @brief The structure type to contain the set of callback functions for handling the request events
- * from the key-value structured data control consumer.
- * @see datacontrol_provider_map_get_value_request_cb()
- * @see datacontrol_provider_map_set_value_request_cb()
- * @see datacontrol_provider_map_add_value_request_cb()
- * @see datacontrol_provider_map_remove_value_request_cb()
- */
-typedef struct {
- datacontrol_provider_map_get_value_request_cb get;
- datacontrol_provider_map_set_value_request_cb set;
- datacontrol_provider_map_add_value_request_cb add;
- datacontrol_provider_map_remove_value_request_cb remove;
- datacontrol_provider_map_bulk_add_value_request_cb bulk_add;
-} datacontrol_provider_map_cb;
-
-/**
- * @brief Registers a callback function for the sql data control request.
- * The provider is notified when a data control request is received from the client applications.
- * @param [in] callback The callback function to be called when a data control request is received
- * @param [in] user_data The user data to be passed to the callback function
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data);
-
-/**
- * @brief Unregisters the callback functions.
- * @return 0 on success, otherwise a negative error value.
- */
-EXPORT_API int datacontrol_provider_sql_unregister_cb(void);
-
-/**
- * @brief Registers a callback function for the map data control request.
- * The provider is notified when a data control request is received from the client applications.
- * @param [in] callback The callback function to be called when a data control request is received
- * @param [in] user_data The user data to be passed to the callback function
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_map_register_cb(datacontrol_provider_map_cb *callback, void *user_data);
-
-/**
- * @brief Unregisters the callback functions.
- * @return 0 on success, otherwise a negative error value.
- */
-EXPORT_API int datacontrol_provider_map_unregister_cb(void);
-
-/**
- * @brief Gets the application ID which sends the data control request.
- * @param [in] request_id The request ID
- * @param [out] appid The application ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_get_client_appid(int request_id, char **appid);
-
-/**
- * @brief Sends the success result and the result set of the select request to the client application.
- * @param [in] request_id The request ID
- * @param [in] db_handle The result db handle for the result set
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_select_result(int request_id, void *db_handle);
-
-/**
- * @brief Sends the success result of the insert request and the last inserted row ID to the client application.
- * @param [in] request_id The request ID
- * @param [in] row_id The row ID of the database changed by the insert request
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_insert_result(int request_id, long long row_id);
-
-/**
- * @brief Sends the success result of the update request the client application.
- * @param [in] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_update_result(int request_id);
-
-/**
- * @brief Sends the success result of the delete request the client application.
- * @param [in] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_delete_result(int request_id);
-
-/**
- * @brief Sends the provider error message to the client application.
- * @param [in] request_id The request ID
- * @param [in] error The provider-defined error message
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_error(int request_id, const char *error);
-
-/**
- * @brief Sends the success result of the request for setting, adding and removing the key-value structured data the client application.
- * @param [in] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_map_result(int request_id);
-
-/**
- * @brief Sends the success result of the request for getting the value list the client application.
- * @param [in] request_id The request ID
- * @param [in] value_list The result value list
- * @param [in] value_count The number of the values
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count);
-
-/**
- * @brief Send data changed notification to consumer apps which are successfully add data changed callback.
- * @param[in] provider Target provider handle
- * @param[in] type Changed data type
- * @param[in] data Customized data, intend to contains information about changed data
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_provider_send_data_change_noti(
- datacontrol_h provider,
- datacontrol_data_change_type_e type,
- bundle *data);
-
-/**
- * @brief Add consumer filter for add data changed callback process.
- * @param[in] callback Consumer filter callback filtering consumers which try to add data changed callback
- * @param[in] user_data The user data to be passed to the list_cb function
- * @param[out] callback_id Added callback ID
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_provider_add_data_change_consumer_filter_cb(
- data_control_provider_data_change_consumer_filter_cb callback,
- void *user_data,
- int *callback_id);
-
-/**
- * @brief Remove consumer filter for add data changed callback process.
- * @param[in] callback_id Target callback ID
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_provider_remove_data_change_consumer_filter_cb(int callback_id);
-
-/**
- * @brief Get consumer list which successfully add data changed callback.
- * @param[in] provider The provider handle
- * @param[in] list_cb Callback for each consumer info
- * @param[in] user_data The user data to be passed to the list_cb function
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_provider_foreach_data_change_consumer(
- datacontrol_h provider,
- data_control_provider_data_change_consumer_cb list_cb,
- void *user_data);
-
-EXPORT_API int datacontrol_provider_send_bulk_insert_result(
- int request_id,
- data_control_bulk_result_data_h bulk_results);
-
-EXPORT_API int datacontrol_provider_send_map_bulk_add_result(
- int request_id,
- data_control_bulk_result_data_h bulk_results);
-
-EXPORT_API bool datacontrol_provider_map_is_registered();
-EXPORT_API bool datacontrol_provider_sql_is_registered();
-
-/**
- * @brief Sends select result without selected data.
- * @details This API is made for C# API. C# API has a different select flow. \n
- * It will send select result after provider's select callback and \n
- * do not get db handle for sending result to remove db dependancy. \n
- * So, this API just send provider's select callback result and pass \n
- * connected socket fd for sending selected data to consumer.
- *
- * @param[in] request_id The request ID
- * @param[out] fd The socket fd
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_send_select_result_without_data(int request_id, int *fd);
-
-/**
- * @brief Writes data to socket.
- * @details This API is made for C# API. C# API has a different select flow. \n
- * It will send select result after provider's select callback and \n
- * do not get db handle for sending result to remove db dependancy. \n
- * So, C# API need native API which get buffer and send it to the consumer.
- *
- * @param[in] fd The socket fd
- * @param[in] buffer The data for sending to the consumer application
- * @param[in] nbytes The data size
- * @param[out] bytes_write The data size of sent successfully to the consumer
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_provider_write_socket(int fd, void *buffer, unsigned int nbytes,
- unsigned int *bytes_write);
-
-/**
- * @brief Gets select request page info.
- * @details This API is made for C# API. C# API can control selected page in proivder's callback. \n
- * This API provide request page info to the provider application so that provider application \n
- * can manage which page should be sent to the consumer.
- *
- * @param[in] request_id The request ID
- * @param[out] page_num The requested page number
- * @param[out] count_per_page The requested count per page
- *
- * @return @c 0 on success,
- * otherwise a negative error value
- *
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_provider_get_select_page_info(int request_id, int *page_num, int *count_per_page);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _APPFW_DATA_CONTROL_PROVIDER_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file data-control-sql-cursor.h
- * @brief This is the header file for the cursor of the SQL-friendly interface based data control.
- */
-
-#ifndef _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_
-#define _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_
-
-#include <stdio.h>
-#include <sqlite3.h>
-#include "data-control-types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief The structure type to represent a sql result set. This type can be used to enumerate through the result set of an SQL query.
- */
-typedef struct {
- int resultset_fd;
- sqlite3_int64 resultset_row_count;
- int resultset_col_count;
- off_t resultset_col_type_offset;
- off_t resultset_col_name_offset;
- off_t resultset_content_offset;
- off_t resultset_current_offset;
- sqlite3_int64 resultset_current_row_count;
- char *resultset_path;
- off_t *row_offset_list;
-} resultset_cursor;
-
-/**
- * @brief Creates a cursor to enumerate through an SQL result set
- *
- * @param [in] path The path of the file containing the SQL result set
- * @return A pointer to struct @c resultset_cursor
- */
-resultset_cursor *datacontrol_sql_get_cursor();
-
-/**
- * @brief Moves the cursor to the first position
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- *
- * The following example demonstrates how to use the %datacontrol_sql_step_first() method.
- *
- * @code
- *
- * void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *cursor, bool provider_result, const char *error)
- * {
- * char person_name[32] = {0,};
- * long long person_number = -1;
- *
- * datacontrol_sql_step_first(cursor);
- * datacontrol_sql_get_text_data(cursor, 0, person_name);
- * datacontrol_sql_get_int64_data(cursor, 1, &person_number);
- * printf("The person %s has the number %l", person_name, person_number);
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_step_first(resultset_cursor *cursor);
-
-/**
- * @brief Moves the cursor to the last position
- *
- * @param [in] cursor Navigates the result of data control select request
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- *
- * The following example demonstrates how to use the %datacontrol_sql_step_last() method.
- *
- * @code
- *
- * void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *cursor, bool provider_result, const char *error)
- * {
- * char person_name[32] = {0,};
- * long long person_number = -1;
- *
- * datacontrol_sql_step_last(cursor);
- * datacontrol_sql_get_text_data(cursor, 0, person_name);
- * datacontrol_sql_get_int64_data(cursor, 1, &person_number);
- * printf("The person %s has the number %l", person_name, person_number);
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_step_last(resultset_cursor *cursor);
-
-/**
- * @brief Moves the cursor to the next position
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- *
- * The following example demonstrates how to use the %datacontrol_sql_step_next() method.
- *
- * @code
- *
- * void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *cursor, bool provider_result, const char *error)
- * {
- * char person_name[32] = {0,};
- * long long person_number = -1;
- * while (datacontrol_sql_step_next(cursor) == DATACONTROL_ERROR_NONE) {
- * datacontrol_sql_get_text_data(cursor, 0, person_name);
- * datacontrol_sql_get_int64_data(cursor, 1, &person_number);
- * printf("The person %s has the number %l", person_name, person_number);
- * }
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_step_next(resultset_cursor *cursor);
-
-/**
- * @brief Moves the cursor to the previous position
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_sql_step_previous(resultset_cursor *cursor);
-
-/**
- * @brief Gets the number of columns for this cursor
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @return The number of columns in the calling cursor
- */
-EXPORT_API int datacontrol_sql_get_column_count(resultset_cursor *cursor);
-
-/**
- * @brief Gets the name of the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] name The name of the destination column
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_sql_get_column_name(resultset_cursor *cursor, int column_index, char *name);
-
-/**
- * @brief Gets the size of data in the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @return The size of data in the column indicated by the specified index. @n
- * If an error is occurred, a negative value is returned.
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_sql_get_column_item_size(resultset_cursor *cursor, int column_index);
-
-/**
- * @brief Gets the type of the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] type The type of the destination column
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_index, datacontrol_sql_column_type* type);
-
-/**
- * @brief Gets a blob data from the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] data The blob value obtained from the column
- * @param [out] size The size of the data
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- */
-EXPORT_API int datacontrol_sql_get_blob_data(resultset_cursor *cursor, int column_index, void *data, int size);
-
-/**
- * @brief Gets an int value from the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] data The integer value obtained from the column
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_sql_get_int_data(resultset_cursor *cursor, int column_index, int *data);
-
-/**
- * @brief Gets a long long value from the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] data The 64-bit integer value obtained from the column
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_sql_get_int64_data(resultset_cursor *cursor, int column_index, long long *data);
-
-/**
- * @brief Gets a double value from the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] data The value obtained from the column as double
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- */
-EXPORT_API int datacontrol_sql_get_double_data(resultset_cursor *cursor, int column_index, double *data);
-
-/**
- * @brief Gets a text value from the column indicated by the specified index
- *
- * @param [in] cursor Navigates the result of the request for the select operation
- * @param [in] column_index The index of the destination column
- * @param [out] data The value obtained from the column as text
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- */
-EXPORT_API int datacontrol_sql_get_text_data(resultset_cursor *cursor, int column_index, char *data);
-
-/**
- * @brief Removes the @c cursor containing SQL result set
- *
- * @param [in] cursor A pointer to the result set cursor to be removed
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- */
-EXPORT_API int datacontrol_sql_remove_cursor(resultset_cursor *cursor);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file data-control-sql.h
- * @brief This is the header file for the SQL-friendly interface based data control.
- */
-
-#ifndef _APPFW_DATA_CONTROL_SQL_H_
-#define _APPFW_DATA_CONTROL_SQL_H_
-
-#include <data-control-types.h>
-#include <data_control_types.h>
-#include <data-control-sql-cursor.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/**
- * @brief Called when response is received for insert operation from an application using the SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] bulk_results The inserted row ID set by the data control
- * @param [in] provider_result Set to true if the data control provider successfully processed @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_sql_insert_bulk_data_response_cb)(int request_id, datacontrol_h provider,
- data_control_bulk_result_data_h bulk_results, bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when response is received for insert operation from an application using the SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] inserted_row_id The inserted row ID set by the data control
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_sql_insert_response_cb)(int request_id, datacontrol_h provider,
- long long inserted_row_id, bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when response is received for delete operation from an application using the SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID that identifies the data control
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_sql_delete_response_cb)(int request_id, datacontrol_h provider,
- bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when response is received for select operation from an application using the SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] enumerator Navigates the result of data control select request
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_sql_select_response_cb)(int request_id, datacontrol_h provider,
- resultset_cursor *enumerator, bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief Called when response is received for update operation from an application using the SQL-friendly interface based data control.
- *
- * @param [in] request_id The request ID
- * @param [in] provider The provider handle
- * @param [in] provider_result Set to true if the data control provider successfully processed. @n
- * false otherwise.
- * @param [in] error The error message from the data control provider
- * @param [in] user_data The user data passed from the register function
- */
-typedef void (*datacontrol_sql_update_response_cb)(int request_id, datacontrol_h provider,
- bool provider_result, const char *error, void *user_data);
-
-/**
- * @brief The structure type to contain the set of callback functions for handling the response events
- * of SQL-friendly interface based data control.
- * @see datacontrol_sql_select_response_cb()
- * @see datacontrol_sql_insert_response_cb()
- * @see datacontrol_sql_update_response_cb()
- * @see datacontrol_sql_delete_response_cb()
- * @see datacontrol_sql_insert_bulk_data_response_cb()
- */
-typedef struct {
- datacontrol_sql_select_response_cb select;
- datacontrol_sql_insert_response_cb insert;
- datacontrol_sql_update_response_cb update;
- datacontrol_sql_delete_response_cb delete;
- datacontrol_sql_insert_bulk_data_response_cb bulk_insert;
-} datacontrol_sql_response_cb;
-
-/**
- * @brief Creates a provider handle.
- * @param [out] provider The provider handle
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_destroy()
- *
- * The following example demonstrates how to use the %datacontrol_sql_create() method.
- *
- * @code
- *
- * int main()
- * {
- * const char *provider_id = "http://tizen.org/datacontrol/provider/example";
- * const char *data_id = "table";
- * datacontrol_h provider;
- * int result = 0;
- *
- * result = datacontrol_sql_create(&provider);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Creating data control provider is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_sql_set_provider_id(provider, provider_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Setting providerID is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_sql_set_data_id(provider, data_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Setting dataID is failed with error: %d", result);
- * return result;
- * }
- *
- * // Executes some operations
- *
- * result = datacontrol_sql_destroy(provider);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Destroying data control provider is failed with error: %d", result);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_create(datacontrol_h *provider);
-
-/**
- * @brief Destroys the provider handle and releases all its resources.
- * @param [in] provider The provider handle
- * @return 0 on success, otherwise a negative error value.
- * @remark When operations of data control are finished, this function must be called to prevent memory leak.
- * @see datacontrol_sql_create()
- */
-EXPORT_API int datacontrol_sql_destroy(datacontrol_h provider);
-
-/**
- * @brief Sets the Provider ID.
- * @param [in] provider The provider handle
- * @param [in] provider_id The data control provider ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_get_provider_id()
- */
-EXPORT_API int datacontrol_sql_set_provider_id(datacontrol_h provider, const char *provider_id);
-
-/**
- * @brief Gets the Provider ID.
- * @param [in] provider The provider handle
- * @param [out] provider_id The data control provider ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_set_provider_id()
- */
-EXPORT_API int datacontrol_sql_get_provider_id(datacontrol_h provider, char **provider_id);
-
-/**
- * @brief Sets the Data ID.
- * @param [in] provider The provider handle
- * @param [in] data_id A string for identifying a specific table to operate. @n
- * The string consists of one or more components separated by a slash('/').
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_get_data_id()
- */
-EXPORT_API int datacontrol_sql_set_data_id(datacontrol_h provider, const char *data_id);
-
-/**
- * @brief Gets the Data ID.
- * @param [in] provider The provider handle
- * @param [out] data_id A string for identifying a specific table to operate. @n
- * The string consists of one or more components separated by a slash('/').
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_set_data_id()
- */
-EXPORT_API int datacontrol_sql_get_data_id(datacontrol_h provider, char **data_id);
-
-/**
- * @brief Registers a callback function for the sql data control response. @n
- * The application is notified when a data control response is received from the @c provider.
- * @param [in] provider The provider handle
- * @param [in] callback The callback function to be called when a response is received.
- * @param [in] user_data The user data to be passed to the callback function
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_unregister_response_cb()
- */
-EXPORT_API int datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_response_cb *callback, void *user_data);
-
-/**
- * @brief Unregisters the callback function in @c provider.
- * @param [in] provider The provider handle
- * @return 0 on success, otherwise a negative error value.
- */
-EXPORT_API int datacontrol_sql_unregister_response_cb(datacontrol_h provider);
-
-/**
- * @brief Deletes rows of a table owned by the SQL-type data control provider
- *
- * @remarks If the value is a string, the value must be wrapped in single quotes, else it does not need to be wrapped in single quotes.
- * @param [in] provider The provider handle
- * @param [in] where A filter to select the desired rows to delete. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- *
- * The following example demonstrates how to use the %datacontrol_sql_delete() method.
- *
- * @code
- *
- * void sql_delete_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
- * if (provider_result) {
- * LOGI("The delete operation is successful");
- * }
- * else {
- * LOGI("The delete operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_sql_response_cb sql_callback;
- *
- * int main()
- * {
- * const char *where = "group = 'friend'";
- * int result = 0;
- * int req_id = 0;
- *
- * sql_callback.delete = sql_delete_response_cb;
- * result = datacontrol_sql_register_response_cb(provider, &sql_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_sql_delete(provider, where, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Deleting is failed with error: %d", result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_id);
-
-/**
- * @brief Inserts new rows in a table owned by the SQL-type data control provider
- *
- * @param [in] provider The provider handle
- * @param [in] insert_data The column-value pairs to insert. @n
- * If the value is a string, the value must be wrapped in single quotes,
- * else it does not need to be wrapped in single quotes.
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- *
- * The following example demonstrates how to use the %datacontrol_sql_insert() method.
- *
- * @code
- *
- * void sql_insert_response_cb(int request_id, datacontrol_h provider, long long inserted_row_id, bool provider_result, const char *error) {
- * if (provider_result) {
- * LOGI("The insert operation is successful");
- * }
- * else {
- * LOGI("The insert operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_sql_response_cb sql_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * bundle *b = NULL;
- *
- * sql_callback.insert = sql_insert_response_cb;
- * result = datacontrol_sql_register_response_cb(provider, &sql_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * b = bundle_create();
- * bundle_add_str(b, "WORD", "test");
- * bundle_add_str(b, "WORD_DESC", "test description");
- *
- * result = datacontrol_sql_insert(provider, b, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Inserting is failed with error: %d", result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * bundle_free(b);
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_insert(datacontrol_h provider, const bundle *insert_data, int *request_id);
-
-/**
- * @brief Selects the specified columns to be queried
- *
- * @param [in] provider The provider handle
- * @param [in] column_list The column list to query
- * @param [in] column_count The total number of columns to be queried
- * @param [in] where A filter to select the desired rows. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [in] order The sorting order of the rows to query. @n
- * It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- *
- * The following example demonstrates how to use the %datacontrol_sql_select() method.
- *
- * @code
- *
- * void sql_select_response_cb(int request_id, datacontrol_h provider, resultset_cursor *enumerator, bool provider_result, const char *error) {
- * if (provider_result) {
- * LOGI("The select operation is successful");
- * }
- * else {
- * LOGI("The select operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_sql_response_cb sql_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * char *column_list[2];
- * column_list[0] = "WORD";
- * column_list[1] = "WORD_DESC";
- * const char *where = "WORD = 'test'";
- * const char *order = "WORD ASC";
- *
- * sql_callback.select = sql_select_response_cb;
- * result = datacontrol_sql_register_response_cb(provider, &sql_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * result = datacontrol_sql_select(provider, column_list, 2, where, order, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Selecting is failed with error: %d", result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_select(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id);
-
-/**
- * @brief Selects the specified columns to be queried
- *
- * @param [in] provider The provider handle
- * @param [in] column_list The column list to query
- * @param [in] column_count The total number of columns to be queried
- * @param [in] where A filter to select the desired rows. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [in] order The sorting order of the rows to query. @n
- * It is an SQL 'ORDER BY' clause excluding the 'ORDER BY' itself.
- * @param [in] page_number The page number of the result set @n
- * It starts from 1.
- * @param [in] count_per_page The desired maximum count of rows on a page
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @see datacontrol_sql_select()
- */
-EXPORT_API int datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id);
-
-/**
- * @brief Updates values of a table owned by the SQL-type data control provider.
- *
- * @param [in] provider The provider handle
- * @param [in] update_data The column-value pairs to update. @n
- * If the value is a string, the value must be wrapped in single quotes,
- * else it does not need to be wrapped in single quotes.
- * @param [in] where A filter to select the desired rows to update. @n
- * It is an SQL 'WHERE' clause excluding the 'WHERE' itself such as column1 = 'stringValue' and column2 = numericValue.
- * @param [out] request_id The request ID
- * @return 0 on success, otherwise a negative error value.
- * @retval #DATACONTROL_ERROR_NONE Successful
- * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
- * @retval #DATACONTROL_ERROR_OUT_OF_MEMORY Out of memory
- * @retval #DATACONTROL_ERROR_MAX_EXCEEDED Too long argument
- *
- * The following example demonstrates how to use the %datacontrol_sql_update() method.
- *
- * @code
- *
- * void sql_update_response_cb(int request_id, datacontrol_h provider, bool provider_result, const char *error) {
- * if (provider_result) {
- * LOGI("The update operation is successful");
- * }
- * else {
- * LOGI("The update operation for the request %d is failed. error message: %s", request_id, error);
- * }
- * }
- *
- * datacontrol_sql_response_cb sql_callback;
- *
- * int main()
- * {
- * int result = 0;
- * int req_id = 0;
- * const char *where = "WORD = 'test'";
- * bundle *b = NULL;
- *
- * sql_callback.update = sql_update_response_cb;
- * result = datacontrol_sql_register_response_cb(provider, &sql_callback);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Registering the callback function is failed with error: %d", result);
- * return result;
- * }
- *
- * b = bundle_create();
- * bundle_add_str(b, "WORD", "test_new");
- *
- * result = datacontrol_sql_update(provider, b, where, &req_id);
- * if (result != DATACONTROL_ERROR_NONE) {
- * LOGE("Updating is failed with error: %d", result);
- * }
- * else {
- * LOGI("req_id is %d", req_id);
- * }
- *
- * bundle_free(b);
- * return result;
- * }
- *
- * @endcode
- */
-EXPORT_API int datacontrol_sql_update(datacontrol_h provider, const bundle *update_data, const char *where, int *request_id);
-EXPORT_API int datacontrol_sql_insert_bulk_data(datacontrol_h provider, data_control_bulk_data_h bulk_data_h, int *request_id);
-EXPORT_API bool datacontrol_sql_cb_is_registered(char *provider_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _APPFW_DATA_CONTROL_SQL_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file data-control-types.h
- * @brief This is the header file for data types of the data-control.
- */
-
-#ifndef _APPFW_DATA_CONTROL_TYPES_H_
-#define _APPFW_DATA_CONTROL_TYPES_H_
-#include <glib.h>
-
-#include <errno.h>
-#include <bundle.h>
-
-
-#ifdef __GNUC__
-# ifndef EXPORT_API
-# define EXPORT_API __attribute__((visibility("default")))
-# endif
-#else
-# define EXPORT_API
-#endif
-
-typedef struct {
- bundle *result_data;
- int result;
-} data_control_bulk_result_data_item_s;
-
-struct data_control_bulk_result_data_s {
- GList *data_list;
-};
-
-struct data_control_bulk_data_s {
- GList *data_list;
-};
-
-/**
- * @brief Provider handle
- */
-typedef struct datacontrol_s *datacontrol_h;
-
-/**
- * @brief Enumerations of different types of columns in an SQL table.
- */
-typedef enum {
- DATACONTROL_SQL_COLUMN_TYPE_UNDEFINED = 0,
- DATACONTROL_SQL_COLUMN_TYPE_INT64,
- DATACONTROL_SQL_COLUMN_TYPE_DOUBLE,
- DATACONTROL_SQL_COLUMN_TYPE_TEXT,
- DATACONTROL_SQL_COLUMN_TYPE_BLOB,
- DATACONTROL_SQL_COLUMN_TYPE_NULL
-} datacontrol_sql_column_type;
-
-/**
- * @brief Enumerations of the various error-codes an API can return.
- */
-typedef enum {
- DATACONTROL_ERROR_NONE = 0, /**< Successful */
- DATACONTROL_ERROR_OUT_OF_MEMORY = -ENOMEM, /**< Out of memory */
- DATACONTROL_ERROR_IO_ERROR = -EIO, /**< I/O error */
- DATACONTROL_ERROR_INVALID_PARAMETER = -EINVAL, /**< Invalid parameter */
- DATACONTROL_ERROR_PERMISSION_DENIED = -EACCES, /**< Permission denied */
- DATACONTROL_ERROR_MAX_EXCEEDED = -EMSGSIZE /**< Too long argument */
-} datacontrol_error_e;
-
-/**
- * @brief Enumerations of different type of data control requests.
- */
-typedef enum
-{
- DATACONTROL_TYPE_ERROR = -1,
- DATACONTROL_TYPE_UNDEFINED,
- DATACONTROL_TYPE_SQL_SELECT,
- DATACONTROL_TYPE_SQL_INSERT,
- DATACONTROL_TYPE_SQL_UPDATE,
- DATACONTROL_TYPE_SQL_DELETE,
- DATACONTROL_TYPE_SQL_BULK_INSERT,
- DATACONTROL_TYPE_MAP_GET,
- DATACONTROL_TYPE_MAP_SET,
- DATACONTROL_TYPE_MAP_ADD,
- DATACONTROL_TYPE_MAP_REMOVE,
- DATACONTROL_TYPE_MAP_BULK_ADD,
- DATACONTROL_TYPE_ADD_DATA_CHANGED_CB,
- DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB,
- DATACONTROL_TYPE_MAX = 255
-} datacontrol_request_type;
-
-
-/**
- * @brief Enumerations of the various datacontrol noti type.
- */
-typedef enum {
- DATACONTROL_DATA_CHANGE_SQL_UPDATE,
- DATACONTROL_DATA_CHANGE_SQL_INSERT,
- DATACONTROL_DATA_CHANGE_SQL_DELETE,
- DATACONTROL_DATA_CHANGE_MAP_SET,
- DATACONTROL_DATA_CHANGE_MAP_ADD,
- DATACONTROL_DATA_CHANGE_MAP_REMOVE,
- DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT,
- DATACONTROL_DATA_CHANGE_CALLBACK_REMOVE_RESULT
-} datacontrol_data_change_type_e;
-
-
-#endif /* _APPFW_DATA_CONTROL_TYPES_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file data-control.h
- * @brief This is the header file for the data control.
- */
-
-#ifndef _APPFW_DATA_CONTROL_H_
-#define _APPFW_DATA_CONTROL_H_
-
-#include <data-control-sql.h>
-#include <data-control-sql-cursor.h>
-#include <data-control-provider.h>
-#include <data-control-noti.h>
-#include <data-control-bulk.h>
-
-#endif /* _APPFW_DATA_CONTROL_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __TIZEN_APPFW_DATA_CONTROL_INTERNAL_H__
-#define __TIZEN_APPFW_DATA_CONTROL_INTERNAL_H__
-
-#include <data-control-types.h>
-#include "data_control_types.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- PRIVILEGE_PROVIDER,
- PRIVILEGE_CONSUMER
-} privilege_type;
-
-typedef enum {
- CERT_UNCHECKED,
- CERT_MATCH,
- CERT_MISMATCH
-} cert_status_type;
-
-int convert_to_tizen_error(datacontrol_error_e error);
-int datacontrol_check_privilege(privilege_type check_type);
-int datacontrol_check_cert(const char *provider_id, bool is_map,
- const char *consumer_appid);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TIZEN_APPFW_DATA_CONTROL_INTERNAL_H__ */
-
--- /dev/null
+/*
+ * Copyright (c) 2013 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file data-control-provider.h
+ * @brief This is the header file for the data control provider.
+ */
+
+#ifndef _APPFW_DATA_CONTROL_PROVIDER_H_
+#define _APPFW_DATA_CONTROL_PROVIDER_H_
+
+#include <data_control_types.h>
+#include <data_control_provider.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Sends select result without selected data.
+ * @details This API is made for C# API. C# API has a different select flow. \n
+ * It will send select result after provider's select callback and \n
+ * do not get db handle for sending result to remove db dependancy. \n
+ * So, this API just send provider's select callback result and pass \n
+ * connected socket fd for sending selected data to consumer.
+ *
+ * @param[in] request_id The request ID
+ * @param[out] fd The socket fd
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #DATACONTROL_ERROR_NONE Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_send_select_result_without_data(int request_id, int *fd);
+
+/**
+ * @brief Writes data to socket.
+ * @details This API is made for C# API. C# API has a different select flow. \n
+ * It will send select result after provider's select callback and \n
+ * do not get db handle for sending result to remove db dependancy. \n
+ * So, C# API need native API which get buffer and send it to the consumer.
+ *
+ * @param[in] fd The socket fd
+ * @param[in] buffer The data for sending to the consumer application
+ * @param[in] nbytes The data size
+ * @param[out] bytes_write The data size of sent successfully to the consumer
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #DATACONTROL_ERROR_NONE Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ */
+EXPORT_API int datacontrol_provider_write_socket(int fd, void *buffer, unsigned int nbytes,
+ unsigned int *bytes_write);
+
+/**
+ * @brief Gets select request page info.
+ * @details This API is made for C# API. C# API can control selected page in proivder's callback. \n
+ * This API provide request page info to the provider application so that provider application \n
+ * can manage which page should be sent to the consumer.
+ *
+ * @param[in] request_id The request ID
+ * @param[out] page_num The requested page number
+ * @param[out] count_per_page The requested count per page
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @retval #DATACONTROL_ERROR_NONE Successful
+ * @retval #DATACONTROL_ERROR_IO_ERROR I/O error
+ * @retval #DATACONTROL_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+EXPORT_API int datacontrol_provider_get_select_page_info(int request_id, int *page_num, int *count_per_page);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _APPFW_DATA_CONTROL_PROVIDER_H_ */
+
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include <dlog.h>
-#include <appsvc/appsvc.h>
-#include <aul/aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-
-#include "data_control_log.h"
-#include "data-control-bulk.h"
-#include "data-control-types.h"
-
-static void __free_bulk_result_data(gpointer data)
-{
- data_control_bulk_result_data_item_s *result_data_item = (data_control_bulk_result_data_item_s *)data;
- bundle_free(result_data_item->result_data);
- free(result_data_item);
-}
-
-static void __free_bulk_data(gpointer data)
-{
- bundle *bulk_data = (bundle *)data;
- bundle_free(bulk_data);
-}
-
-int datacontrol_bulk_data_get_data(data_control_bulk_data_h bulk_data_h, int idx, bundle **data)
-{
- bundle *ret_data;
-
- if (bulk_data_h->data_list == NULL) {
- LOGE("NULL data_list");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- ret_data = (bundle *)g_list_nth_data(bulk_data_h->data_list, idx);
- if (ret_data == NULL) {
- LOGE("no data at index %d", idx);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- *data = ret_data;
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_data_get_count(data_control_bulk_data_h bulk_data_h, int *count)
-{
- *count = g_list_length(bulk_data_h->data_list);
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_data_add(data_control_bulk_data_h bulk_data_h, bundle *data)
-{
- bulk_data_h->data_list = g_list_append(bulk_data_h->data_list, bundle_dup(data));
- LOGI("append bulk data : %d", g_list_length(bulk_data_h->data_list));
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_data_create(data_control_bulk_data_h *bulk_data_h)
-{
- *bulk_data_h = (struct data_control_bulk_data_s *)calloc(1, sizeof(struct data_control_bulk_data_s));
- if (*bulk_data_h == NULL) {
- LOGE("Fail to create bulk data. Out of memory.");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_data_destroy(data_control_bulk_data_h bulk_data_h)
-{
- g_list_free_full(bulk_data_h->data_list, __free_bulk_data);
- free(bulk_data_h);
- LOGI("bulk data destroy done");
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_result_data_get_result_data(data_control_bulk_result_data_h result_data_h,
- int idx, bundle **result_data, int *result)
-{
- data_control_bulk_result_data_item_s *result_data_item;
-
- if (result_data_h->data_list == NULL) {
- LOGE("NULL result data_list");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- result_data_item = (data_control_bulk_result_data_item_s *)g_list_nth_data(result_data_h->data_list, idx);
- if (result_data)
- *result_data = result_data_item->result_data;
- *result = result_data_item->result;
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_result_data_get_count(data_control_bulk_result_data_h result_data_h, int *count)
-{
- *count = g_list_length(result_data_h->data_list);
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_result_data_add(data_control_bulk_result_data_h result_data_h, bundle *result_data, int result)
-{
- data_control_bulk_result_data_item_s *result_data_item =
- (data_control_bulk_result_data_item_s *)calloc(1, sizeof(data_control_bulk_result_data_item_s));
- if (result_data_item == NULL) {
- LOGE("fail to alloc bulk_result_data");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- if (result_data != NULL) {
- result_data_item->result_data = bundle_dup(result_data);
- if (result_data_item->result_data == NULL) {
- free(result_data_item);
- LOGE("fail to alloc result_data");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
- }
- result_data_item->result = result;
-
- result_data_h->data_list = g_list_append(result_data_h->data_list, result_data_item);
- LOGI("append bulk result data : %d", g_list_length(result_data_h->data_list));
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_result_data_create(data_control_bulk_result_data_h *result_data_h)
-{
- *result_data_h = (struct data_control_bulk_result_data_s *)calloc(1, sizeof(struct data_control_bulk_result_data_s));
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_bulk_result_data_destroy(data_control_bulk_result_data_h result_data_h)
-{
- g_list_free_full(result_data_h->data_list, __free_bulk_result_data);
- free(result_data_h);
- LOGI("bulk result data destroy done");
- return DATACONTROL_ERROR_NONE;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _GNU_SOURCE
-
-#include <sqlite3.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-#include <gio/gio.h>
-#include <pthread.h>
-#include <sys/socket.h>
-
-#include <dlog.h>
-#include <appsvc/appsvc.h>
-#include <aul/aul.h>
-
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-
-#include <sys/socket.h>
-
-#include <sqlite3.h>
-
-#include "data-control-sql-cursor.h"
-#include "data-control-internal.h"
-#include "data-control-types.h"
-#include "data-control-bulk.h"
-
-#define MAX_STATEMENT_SIZE 1024
-#define RESULT_VALUE_COUNT "RESULT_VALUE_COUNT"
-#define MAX_COUNT_PER_PAGE "MAX_COUNT_PER_PAGE"
-#define RESULT_PAGE_NUMBER "RESULT_PAGE_NUMBER"
-#define MAX_RETRY 10
-
-#define ERR_BUFFER_SIZE 1024
-#define BUFSIZE 512
-#define DATA_CONTROL_DBUS_PATH_PREFIX "/org/tizen/data_control_service_"
-#define DATA_CONTROL_OBJECT_PATH "/org/tizen/data_control_service"
-#define DATA_CONTROL_INTERFACE_NAME "org.tizen.data_control_service"
-#define DATA_CONTROL_DB_NAME_PREFIX "._data_control_list_"
-#define DATA_CONTROL_DB_NAME "DATA_CONTROL_DATA_CHANGE_TABLE"
-
-static GDBusConnection *_gdbus_conn = NULL;
-
-void _bundle_foreach_check_arg_size_cb(const char *key, const int type,
- const bundle_keyval_t *kv, void *arg_size)
-{
- char *value = NULL;
- size_t value_len = 0;
- bundle_keyval_get_basic_val((bundle_keyval_t *)kv, (void **)&value, &value_len);
-
- arg_size += (strlen(key) + value_len) * sizeof(wchar_t);
- return;
-}
-
-int _datacontrol_send_async(int sockfd, bundle *kb, void *extra_data, datacontrol_request_type type, void *data)
-{
- bundle_raw *kb_data = NULL;
- bundle_raw *extra_kb_data = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- int datalen = 0;
- int extra_kb_datalen = 0;
- char *buf = NULL;
- int total_len = 0;
- unsigned int nb = 0;
- int i;
- int count;
- bundle *bulk_data;
- data_control_bulk_data_h bulk_data_h = NULL;
- bundle_raw *encode_data = NULL;
- int encode_datalen = 0;
-
- LOGD("send async ~~~");
-
- bundle_encode_raw(kb, &kb_data, &datalen);
- if (kb_data == NULL) {
- LOGE("bundle encode error");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (DATACONTROL_TYPE_SQL_INSERT == type ||
- DATACONTROL_TYPE_SQL_UPDATE == type) {
- bundle_encode_raw((bundle *)extra_data, &extra_kb_data, &extra_kb_datalen);
- if (extra_kb_data == NULL) {
- LOGE("bundle encode error");
- goto out;
- }
- }
-
- total_len = sizeof(datalen) + datalen;
- if (extra_kb_datalen > 0)
- total_len += sizeof(extra_kb_datalen) + extra_kb_datalen;
-
- /* encoded bundle + encoded bundle size */
- buf = (char *)calloc(total_len, sizeof(char));
- if (buf == NULL) {
- bundle_free_encoded_rawdata(&kb_data);
- LOGE("Out of memory.");
- goto out;
- }
-
- memcpy(buf, &datalen, sizeof(datalen));
- memcpy(buf + sizeof(datalen), kb_data, datalen);
- if (extra_kb_datalen > 0) {
- memcpy(buf + sizeof(datalen) + datalen, &extra_kb_datalen, sizeof(extra_kb_datalen));
- memcpy(buf + sizeof(datalen) + datalen + sizeof(extra_kb_datalen), extra_kb_data, extra_kb_datalen);
- }
-
- LOGI("write : %d", total_len);
- if (_write_socket(sockfd, buf, total_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("write data fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (DATACONTROL_TYPE_SQL_BULK_INSERT == type ||
- DATACONTROL_TYPE_MAP_BULK_ADD == type) {
- bulk_data_h = (data_control_bulk_data_h)extra_data;
- datacontrol_bulk_data_get_count(bulk_data_h, &count);
-
- if (_write_socket(sockfd, &count, sizeof(count), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("write bulk count fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- LOGI("write bulk count %d ", count);
- for (i = 0; i < count; i++) {
- datacontrol_bulk_data_get_data(bulk_data_h, i, &bulk_data);
- bundle_encode_raw(bulk_data, &encode_data, &encode_datalen);
- if (_write_socket(sockfd, &encode_datalen, sizeof(encode_datalen), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("write bulk encode_datalen fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- LOGI("write encode_datalen %d ", encode_datalen);
-
- if (_write_socket(sockfd, encode_data, encode_datalen, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("write bulk encode_data fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- encode_datalen = 0;
- bundle_free_encoded_rawdata(&encode_data);
- }
- }
-
-out:
- if (buf)
- free(buf);
- bundle_free_encoded_rawdata(&kb_data);
- bundle_free_encoded_rawdata(&extra_kb_data);
- bundle_free_encoded_rawdata(&encode_data);
-
- return ret;
-}
-
-int _recv_bulk_process(int fd, data_control_bulk_result_data_h *result_data_h)
-{
- int bulk_results_size;
- guint nb;
- int retval = DATACONTROL_ERROR_NONE;
- int i;
- int bulk_result = 0;
- char *encode_data = NULL;
- int encode_datalen = 0;
- bundle *result_data = NULL;
-
- datacontrol_bulk_result_data_create(result_data_h);
- if (_read_socket(fd, (char *)&bulk_results_size, sizeof(bulk_results_size), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: bulk_results_size");
- goto out;
- }
-
- LOGI("##### bulk result size : %d", bulk_results_size);
- for (i = 0; i < bulk_results_size; i++) {
- if (_read_socket(fd, (char *)&bulk_result, sizeof(bulk_result), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: bulk_result");
- goto out;
- }
- LOGI("##### bulk result : %d", bulk_result);
- if (_read_socket(fd, (char *)&encode_datalen, sizeof(encode_datalen), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: encode_datalen");
- goto out;
- }
- LOGI("##### encode_datalen : %d", encode_datalen);
- if (encode_datalen <= 0 || encode_datalen >= MAX_REQUEST_ARGUMENT_SIZE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("Invalid encode_datalen %d", encode_datalen);
- goto out;
- }
- encode_data = (char *)calloc(encode_datalen, sizeof(char));
- if (encode_data == NULL) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("FAIL to alloc encode data");
- goto out;
- }
- if (_read_socket(fd, encode_data, encode_datalen, &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: encode_data");
- free(encode_data);
- goto out;
- }
- result_data = bundle_decode_raw((bundle_raw *)encode_data, encode_datalen);
- datacontrol_bulk_result_data_add(*result_data_h, result_data, bulk_result);
- if (encode_data) {
- free(encode_data);
- encode_data = NULL;
- }
- bundle_free(result_data);
- }
-
-out:
- return retval;
-}
-
-datacontrol_data_change_type_e _get_internal_noti_type(data_control_data_change_type_e type)
-{
- datacontrol_data_change_type_e ret_type = DATACONTROL_DATA_CHANGE_SQL_UPDATE;
- switch (type) {
- case DATA_CONTROL_DATA_CHANGE_SQL_UPDATE:
- ret_type = DATACONTROL_DATA_CHANGE_SQL_UPDATE;
- break;
- case DATA_CONTROL_DATA_CHANGE_SQL_INSERT:
- ret_type = DATACONTROL_DATA_CHANGE_SQL_INSERT;
- break;
- case DATA_CONTROL_DATA_CHANGE_SQL_DELETE:
- ret_type = DATACONTROL_DATA_CHANGE_SQL_DELETE;
- break;
- case DATA_CONTROL_DATA_CHANGE_MAP_SET:
- ret_type = DATACONTROL_DATA_CHANGE_MAP_SET;
- break;
- case DATA_CONTROL_DATA_CHANGE_MAP_ADD:
- ret_type = DATACONTROL_DATA_CHANGE_MAP_ADD;
- break;
- case DATA_CONTROL_DATA_CHANGE_MAP_REMOVE:
- ret_type = DATACONTROL_DATA_CHANGE_MAP_REMOVE;
- break;
- default:
- LOGE("Invalid noti type");
- break;
- }
- return ret_type;
-}
-
-data_control_data_change_type_e _get_public_noti_type(datacontrol_data_change_type_e type)
-{
- data_control_data_change_type_e ret_type = DATA_CONTROL_DATA_CHANGE_SQL_UPDATE;
- switch (type) {
- case DATACONTROL_DATA_CHANGE_SQL_UPDATE:
- ret_type = DATA_CONTROL_DATA_CHANGE_SQL_UPDATE;
- break;
- case DATACONTROL_DATA_CHANGE_SQL_INSERT:
- ret_type = DATA_CONTROL_DATA_CHANGE_SQL_INSERT;
- break;
- case DATACONTROL_DATA_CHANGE_SQL_DELETE:
- ret_type = DATA_CONTROL_DATA_CHANGE_SQL_DELETE;
- break;
- case DATACONTROL_DATA_CHANGE_MAP_SET:
- ret_type = DATA_CONTROL_DATA_CHANGE_MAP_SET;
- break;
- case DATACONTROL_DATA_CHANGE_MAP_ADD:
- ret_type = DATA_CONTROL_DATA_CHANGE_MAP_ADD;
- break;
- case DATACONTROL_DATA_CHANGE_MAP_REMOVE:
- ret_type = DATA_CONTROL_DATA_CHANGE_MAP_REMOVE;
- break;
- default:
- LOGE("Invalid noti type");
- break;
- }
- return ret_type;
-}
-
-int _consumer_request_compare_cb(gconstpointer a, gconstpointer b)
-{
- datacontrol_consumer_request_info *key1 = (datacontrol_consumer_request_info *)a;
- datacontrol_consumer_request_info *key2 = (datacontrol_consumer_request_info *)b;
- if (key1->request_id == key2->request_id)
- return 0;
-
- return 1;
-}
-
-int _create_datacontrol_h(datacontrol_h *provider)
-{
- struct datacontrol_s *request;
-
- if (provider == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- request = malloc(sizeof(struct datacontrol_s));
- if (request == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- request->provider_id = NULL;
- request->data_id = NULL;
-
- *provider = request;
-
- return 0;
-}
-
-int _destroy_datacontrol_h(datacontrol_h provider)
-{
- if (provider == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL)
- free(provider->provider_id);
-
- if (provider->data_id != NULL)
- free(provider->data_id);
-
- free(provider);
- return 0;
-}
-
-int _set_provider_id(datacontrol_h provider, const char *provider_id)
-{
- if (provider == NULL || provider_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL)
- free(provider->provider_id);
-
- provider->provider_id = strdup(provider_id);
- if (provider->provider_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- return 0;
-}
-
-int _set_data_id(datacontrol_h provider, const char *data_id)
-{
- if (provider == NULL || data_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->data_id != NULL)
- free(provider->data_id);
-
- provider->data_id = strdup(data_id);
- if (provider->data_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- return 0;
-}
-
-int _write_socket(int fd, void *buffer, unsigned int nbytes,
- unsigned int *bytes_write)
-{
- unsigned int left = nbytes;
- gsize nb;
- int retry_cnt = 0;
-
- *bytes_write = 0;
- while (left && (retry_cnt < MAX_RETRY)) {
- nb = write(fd, buffer, left);
- LOGI("_write_socket: ...from %d: nb %d left %d\n", fd, nb, left - nb);
-
- if (nb == -1) {
- if (errno == EINTR) {
- LOGE("_write_socket: EINTR error continue ...");
- retry_cnt++;
- continue;
- }
- LOGE("_write_socket: ...error fd %d: errno %d\n", fd, errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- left -= nb;
- buffer += nb;
- *bytes_write += nb;
- retry_cnt = 0;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int _read_socket(int fd, char *buffer, unsigned int nbytes,
- unsigned int *bytes_read)
-{
- unsigned int left = nbytes;
- gsize nb;
- int retry_cnt = 0;
- const struct timespec TRY_SLEEP_TIME = { 0, 500 * 1000 * 1000 };
-
- *bytes_read = 0;
- while (left && (retry_cnt < MAX_RETRY)) {
- nb = read(fd, buffer, left);
- LOGI("_read_socket: ...from %d: nb %d left %d\n", fd, nb, left - nb);
- if (nb == 0) {
- LOGE("_read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
- return DATACONTROL_ERROR_IO_ERROR;
- } else if (nb == -1) {
- /* wrt(nodejs) could change socket to none-blocking socket :-( */
- if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
- LOGE("_read_socket: %d errno, sleep and retry ...", errno);
- retry_cnt++;
- nanosleep(&TRY_SLEEP_TIME, 0);
- continue;
- }
- LOGE("_read_socket: ...error fd %d: errno %d\n", fd, errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- left -= nb;
- buffer += nb;
- *bytes_read += nb;
- retry_cnt = 0;
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-int _datacontrol_create_request_id(void)
-{
- static int id = 0;
- g_atomic_int_inc(&id);
-
- return id;
-}
-
-int _datacontrol_get_data_changed_callback_id(void)
-{
- static int id = 0;
- g_atomic_int_inc(&id);
-
- return id;
-}
-
-int _datacontrol_get_data_changed_filter_callback_id(void)
-{
- static int id = 0;
- g_atomic_int_inc(&id);
-
- return id;
-}
-
-void _socket_info_free(gpointer socket)
-{
- GError *error = NULL;
- datacontrol_socket_info *socket_info = (datacontrol_socket_info *)socket;
-
- if (socket_info != NULL) {
- if (socket_info->gio_read != NULL) {
- LOGE("shutdown socketpair !!!! %d ", socket_info->socket_fd);
- g_io_channel_shutdown(socket_info->gio_read, TRUE, &error);
- if (error) {
- LOGE("g_io_channel_shutdown error : %s", error->message);
- g_error_free(error);
- }
- g_io_channel_unref(socket_info->gio_read);
- socket_info->gio_read = NULL;
- }
- if (socket_info->g_src_id != 0) {
- g_source_remove(socket_info->g_src_id);
- socket_info->g_src_id = 0;
- }
- free(socket_info);
- socket_info = NULL;
- }
-
-}
-
-int _add_watch_on_socket_info(const char *caller_id,
- const char *callee_id, const char *type, const char *provider_id,
- const char *data_type, GIOFunc cb, void *data,
- datacontrol_socket_info **socket_info)
-{
- char err_buf[ERR_BUFFER_SIZE];
- int socketpair = 0;
- int g_src_id;
- int ret;
-
- datacontrol_socket_info *_socket_info = NULL;
- bundle *sock_bundle = bundle_create();
- bundle_add_str(sock_bundle, AUL_K_CALLER_APPID, caller_id);
- bundle_add_str(sock_bundle, AUL_K_CALLEE_APPID, callee_id);
- bundle_add_str(sock_bundle, "DATA_CONTROL_TYPE", type);
- if (provider_id)
- bundle_add_str(sock_bundle, OSP_K_DATACONTROL_PROVIDER, provider_id);
- if (data_type)
- bundle_add_str(sock_bundle, "DATA_CONTROL_DATA_TYPE", data_type);
-
- ret = aul_request_data_control_socket_pair(sock_bundle, &socketpair);
- bundle_free(sock_bundle);
- if (ret != AUL_R_OK) {
- if (ret == AUL_R_EILLACC) {
- LOGE("Permission denied. Consumer need privilege.");
- return DATACONTROL_ERROR_PERMISSION_DENIED;
- }
-
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("consumer socket pair : %d", socketpair);
-
- if (socketpair > 0) {
- GIOChannel *gio_read = NULL;
- gio_read = g_io_channel_unix_new(socketpair);
- if (!gio_read) {
- LOGE("Error is %s\n", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- g_src_id = g_io_add_watch(gio_read, G_IO_IN | G_IO_HUP,
- cb, data);
- if (g_src_id == 0) {
- g_io_channel_unref(gio_read);
- LOGE("fail to add watch on socket");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- _socket_info = (datacontrol_socket_info *)calloc(1, sizeof(datacontrol_socket_info));
- if (_socket_info == NULL) {
- g_io_channel_unref(gio_read);
- g_source_remove(g_src_id);
- LOGE("fail to calloc socket_info");
- return DATACONTROL_ERROR_IO_ERROR;
- }
- _socket_info->socket_fd = socketpair;
- _socket_info->gio_read = gio_read;
- _socket_info->g_src_id = g_src_id;
- LOGI("Watch on socketpair done.");
- } else {
- LOGE("fail to get socket pair");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- *socket_info = _socket_info;
- return DATACONTROL_ERROR_NONE;
-}
-
-int _request_appsvc_run(const char *caller_id, const char *callee_id)
-{
- int pid = -1;
- int count = 0;
- const int TRY_COUNT = 4;
- const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 };
- bundle *arg_list = bundle_create();
-
- if (!arg_list) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT);
- appsvc_set_appid(arg_list, callee_id);
- bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP);
- bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
- bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_id);
- bundle_add_str(arg_list, AUL_K_CALLEE_APPID, callee_id);
- bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1");
- LOGI("caller_id %s, callee_id %s", caller_id, callee_id);
-
- /* For DataControl CAPI */
- bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE");
-
- do {
- pid = appsvc_run_service(arg_list, 0, NULL, NULL);
- if (pid >= 0) {
- LOGI("Launch the provider app successfully: %d", pid);
- bundle_free(arg_list);
- break;
- } else if (pid == APPSVC_RET_EINVAL) {
- LOGE("not able to launch service: %d", pid);
- bundle_free(arg_list);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- count++;
-
- nanosleep(&TRY_SLEEP_TIME, 0);
- } while (count < TRY_COUNT);
-
- if (count >= TRY_COUNT) {
- bundle_free(arg_list);
- LOGE("unable to launch service: %d", pid);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-char *_get_encoded_db_path()
-{
- char db_path[PATH_MAX];
- char *dup_db_path = NULL;
- char *encoded_appid = NULL;
- char provider_appid[255];
- if (aul_app_get_appid_bypid(getpid(), provider_appid, sizeof(provider_appid)) != 0) {
- LOGE("Failed to get appid by pid");
- return NULL;
- }
-
- encoded_appid = g_compute_checksum_for_string(G_CHECKSUM_MD5, provider_appid, -1);
- snprintf(db_path, sizeof(db_path), "/run/user/%d/%s%s.db",
- getuid(), DATA_CONTROL_DB_NAME_PREFIX, encoded_appid);
- dup_db_path = strdup(db_path);
- if (dup_db_path == NULL)
- LOGE("fail to dup db path. out of memory.");
-
- free(encoded_appid);
- LOGI("dup db path : %s ", dup_db_path);
- return dup_db_path;
-}
-
-char *_get_encoded_path(datacontrol_h provider, char *consumer_appid)
-{
- int prefix_len = strlen(DATA_CONTROL_DBUS_PATH_PREFIX);
- char *encoded_path;
- char *full_path;
- int path_len = strlen(provider->provider_id) + strlen(provider->data_id) + strlen(consumer_appid) + 3;
- int full_path_len = path_len + prefix_len;
- char *path = (char *)calloc(path_len, sizeof(char));
- if (path == NULL) {
- LOGE("path calloc failed");
- return 0;
- }
-
- snprintf(path, path_len, "%s_%s_%s", provider->provider_id, provider->data_id, consumer_appid);
- encoded_path = g_compute_checksum_for_string(G_CHECKSUM_MD5, path, -1);
-
- full_path = (char *)calloc(full_path_len, sizeof(char));
- snprintf(full_path, full_path_len, "%s%s", DATA_CONTROL_DBUS_PATH_PREFIX, encoded_path);
-
- free(path);
- free(encoded_path);
- LOGI("full path : %s ", full_path);
- return full_path;
-}
-
-int _dbus_init()
-{
- int ret = DATACONTROL_ERROR_NONE;
- GError *error = NULL;
-
- if (_gdbus_conn == NULL) {
- _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
-
- if (_gdbus_conn == NULL) {
- if (error != NULL) {
- LOGE("Failed to get dbus [%s]", error->message);
- g_error_free(error);
- }
- return DATACONTROL_ERROR_IO_ERROR;
- }
- ret = DATACONTROL_ERROR_NONE;
- }
- return ret;
-}
-
-GDBusConnection *_get_dbus_connection()
-{
- int result = _dbus_init();
- if (result != DATACONTROL_ERROR_NONE) {
- LOGE("Can't init dbus %d", result);
- return NULL;
- }
- return _gdbus_conn;
-}
-
-int _dbus_signal_init(int *monitor_id, char *path, GDBusSignalCallback callback)
-{
- int id;
- id = g_dbus_connection_signal_subscribe(
- _get_dbus_connection(),
- NULL,
- DATA_CONTROL_INTERFACE_NAME, /* interface */
- NULL, /* member */
- path, /* path */
- NULL, /* arg0 */
- G_DBUS_SIGNAL_FLAGS_NONE,
- callback,
- NULL,
- NULL);
-
- LOGI("subscribe id : %d", id);
- if (id == 0) {
- return DATACONTROL_ERROR_IO_ERROR;
- LOGE("Failed to _register_noti_dbus_interface");
- } else {
- *monitor_id = id;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dlog.h>
-#include <errno.h>
-#include <search.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-
-#include <appsvc/appsvc.h>
-#include <aul/aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-
-#include "data-control-map.h"
-#include "data-control-internal.h"
-#include "data-control-bulk.h"
-
-typedef struct {
- char *provider_id;
- char *app_id;
- char *data_id;
- char *access_info;
- void *user_data;
- GList *request_info_list;
- datacontrol_map_response_cb *map_response_cb;
-} map_response_cb_s;
-
-static void *datacontrol_map_tree_root = NULL;
-static GHashTable *__socket_pair_hash = NULL;
-
-static void __map_call_cb(const char *provider_id, int request_id, datacontrol_request_type type,
- const char *data_id, bool provider_result, const char *error, char **result_value_list, int result_value_count,
- data_control_bulk_result_data_h bulk_results, void *data)
-{
- LOGI("__map_call_cb, dataID: %s", data_id);
-
- datacontrol_map_response_cb *callback = NULL;
-
- map_response_cb_s *map_dc = NULL;
- map_dc = (map_response_cb_s *)data;
- callback = map_dc->map_response_cb;
- if (!callback) {
- LOGE("no listener set");
- return;
- }
-
- datacontrol_h provider;
- datacontrol_map_create(&provider);
-
- datacontrol_map_set_provider_id(provider, provider_id);
- datacontrol_map_set_data_id(provider, data_id);
-
- switch (type) {
- case DATACONTROL_TYPE_MAP_BULK_ADD:
- LOGI("ADD VALUE");
- if (callback != NULL && callback->bulk_add != NULL)
- callback->bulk_add(request_id, provider, bulk_results, provider_result, error, map_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_MAP_GET:
- LOGI("GET VALUE");
- if (callback != NULL && callback->get != NULL)
- callback->get(request_id, provider, result_value_list, result_value_count, provider_result, error, map_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_MAP_SET:
- LOGI("SET VALUE");
- if (callback != NULL && callback->set != NULL)
- callback->set(request_id, provider, provider_result, error, map_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_MAP_ADD:
- LOGI("ADD VALUE");
- if (callback != NULL && callback->add != NULL)
- callback->add(request_id, provider, provider_result, error, map_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_MAP_REMOVE:
- LOGI("REMOVE VALUE");
- if (callback != NULL && callback->remove != NULL)
- callback->remove(request_id, provider, provider_result, error, map_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- default:
- break;
- }
-
- datacontrol_map_destroy(provider);
-}
-
-static void __map_instance_free(void *datacontrol_map_instance)
-{
- map_response_cb_s *dc = (map_response_cb_s *)datacontrol_map_instance;
- if (dc) {
- free(dc->provider_id);
- free(dc->data_id);
- free(dc->app_id);
- free(dc->access_info);
- free(datacontrol_map_instance);
- }
-
- return;
-}
-
-static int __map_instance_compare(const void *l_datacontrol_map_instance, const void *r_datacontrol_map_instance)
-{
- map_response_cb_s *dc_left = (map_response_cb_s *)l_datacontrol_map_instance;
- map_response_cb_s *dc_right = (map_response_cb_s *)r_datacontrol_map_instance;
- return strcmp(dc_left->provider_id, dc_right->provider_id);
-}
-
-static char **__map_get_value_list(int fd, int *value_count)
-{
- char **value_list = NULL;
- int i = 0;
- int count = 0;
- int nbytes = 0;
- unsigned int nb = 0;
- int j;
-
- if (_read_socket(fd, (char *)&count, sizeof(count), &nb)) {
- LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd);
- return NULL;
- }
-
- if (count < 0 || count > MAX_VALUE_COUNT) {
- LOGE("invalid count %d", count);
- return NULL;
- }
-
- value_list = (char **)calloc(count, sizeof(char *));
- if (value_list == NULL) {
- LOGE("Failed to create value list");
- return NULL;
- }
-
- for (i = 0; i < count; i++) {
- if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) {
- LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd);
- goto ERROR;
- }
- if (nbytes < 0 || nbytes > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("invalid nbytes %d", nbytes);
- goto ERROR;
- }
-
- LOGI("nbytes : %d %d" , nbytes , nb);
- value_list[i] = (char *)calloc(nbytes + 1, sizeof(char));
-
- if (_read_socket(fd, value_list[i], nbytes, &nb)) {
- LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd);
- goto ERROR;
- }
- LOGI("value_list[i] : %s %d" , value_list[i] , nb);
- }
- *value_count = count;
-
- return value_list;
-
- /* LCOV_EXCL_START */
-ERROR:
- if (value_list) {
- for (j = 0; j < i; j++) {
- if (value_list[j] != NULL)
- free(value_list[j]);
- }
- free(value_list);
- }
-
- return NULL;
- /* LCOV_EXCL_STOP */
-}
-
-static void __remove_map_request_info(int request_id, map_response_cb_s *map_dc)
-{
-
- datacontrol_consumer_request_info temp_request_info;
- datacontrol_consumer_request_info *data;
-
- temp_request_info.request_id = request_id;
- GList *list = g_list_find_custom(map_dc->request_info_list, &temp_request_info,
- (GCompareFunc)_consumer_request_compare_cb);
- if (list != NULL) {
- data = (datacontrol_consumer_request_info *)list->data;
- map_dc->request_info_list = g_list_remove(map_dc->request_info_list, list->data);
- free(data);
- }
-}
-
-static int __map_handle_cb(int fd, bundle *b, int request_type, int request_id, appsvc_result_val res, void *data)
-{
- int ret = 0;
- const char **result_list = NULL;
- const char *provider_id = NULL;
- const char *data_id = NULL;
- const char *error_message = NULL;
- int result_list_len = 0;
- int provider_result = 0;
- int value_count = 0;
- int i;
- char **value_list = NULL;
- const char *p = NULL;
- data_control_bulk_result_data_h bulk_results = NULL;
-
- LOGI("__map_handle_cb, request_type: %d", request_type);
-
- if (!b) {
- LOGE("the bundle returned from datacontrol-provider-service is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- /* result list */
- result_list = bundle_get_str_array(b, OSP_K_ARG, &result_list_len);
- if (!result_list) {
- LOGE("Invalid Bundle: arguement list is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- p = result_list[0]; /* result list[0] = provider_result */
- if (!p) {
- LOGE("Invalid Bundle: provider_result is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Provider result: %s", p);
-
- provider_result = atoi(p);
-
- error_message = result_list[1]; /* result list[1] = error */
- if (!error_message) {
- LOGE("Invalid Bundle: error_message is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Error message: %s", error_message);
-
- provider_id = bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
- if (!provider_id) {
- LOGE("Invalid Bundle: provider_id is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- data_id = bundle_get_val(b, OSP_K_DATACONTROL_DATA);
- if (!data_id) {
- LOGE("Invalid Bundle: data_id is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type);
-
- switch (request_type) {
- case DATACONTROL_TYPE_MAP_BULK_ADD:
- LOGI("BULK ADD RESPONSE");
- if (provider_result) {
- if (_recv_bulk_process(fd, &bulk_results)
- != DATACONTROL_ERROR_NONE) {
- if (bulk_results)
- datacontrol_bulk_result_data_destroy(bulk_results);
-
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
- break;
- case DATACONTROL_TYPE_MAP_GET:
- LOGI("GET RESPONSE");
- if (provider_result) {
- value_list = __map_get_value_list(fd, &value_count);
-
- if (value_list == NULL && value_count != 0) {
- LOGE("Invalid data: value_list is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- }
- break;
- case DATACONTROL_TYPE_MAP_SET:
- case DATACONTROL_TYPE_MAP_ADD:
- case DATACONTROL_TYPE_MAP_REMOVE:
- LOGI("SET or ADD or REMOVE RESPONSE");
- break;
- default:
- break;
- }
-
- if (request_type >= DATACONTROL_TYPE_MAP_GET && request_type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
- __map_call_cb(provider_id, request_id, request_type, data_id, provider_result,
- error_message, value_list, value_count, bulk_results, data);
- ret = DATACONTROL_ERROR_NONE;
- } else {
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (bulk_results)
- datacontrol_bulk_result_data_destroy(bulk_results);
-
- if (value_list) {
- for (i = 0; i < value_count; i++) {
- if (value_list[i] != NULL)
- free(value_list[i]);
- }
- free(value_list);
- }
-
- return ret;
-}
-
-static gboolean __recv_map_message(GIOChannel *channel,
- GIOCondition cond,
- gpointer data)
-{
- char *buf = NULL;
- int nbytes;
- guint nb;
- int request_type = 0;
- const char *request_code = NULL;
- const char *p = NULL;
- int request_id = -1;
- bundle *kb = NULL;
- gint fd = g_io_channel_unix_get_fd(channel);
- map_response_cb_s *map_dc;
- GList *itr;
- datacontrol_consumer_request_info *request_info;
-
- LOGI("__recv_map_message: ...from %d:%s%s%s%s\n", fd,
- (cond & G_IO_ERR) ? " ERR" : "",
- (cond & G_IO_HUP) ? " HUP" : "",
- (cond & G_IO_IN) ? " IN" : "",
- (cond & G_IO_PRI) ? " PRI" : "");
-
- if (cond & (G_IO_ERR | G_IO_HUP))
- goto error;
-
- if (cond & G_IO_IN) {
- if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) {
- LOGE("Fail to read nbytes from socket");
- goto error;
- }
- LOGI("nbytes : %d", nbytes);
-
- if (nb == 0) {
- LOGE("__recv_map_message: ...from %d: socket closed\n", fd);
- goto error;
- }
-
- LOGI("__recv_map_message: ...from %d: %d bytes\n", fd, nbytes);
- if (nbytes > 0 && nbytes < MAX_REQUEST_ARGUMENT_SIZE) {
- buf = (char *) calloc(nbytes + 1, sizeof(char));
- if (buf == NULL) {
- LOGE("Malloc failed!!");
- goto error;
- }
- if (_read_socket(fd, buf, nbytes, &nb)) {
- LOGE("Fail to read buf from socket");
- goto error;
- }
-
- if (nb == 0) {
- LOGE("__recv_map_message: ...from %d: socket closed\n", fd);
- goto error;
- }
-
- kb = bundle_decode_raw((bundle_raw *)buf, nbytes);
- if (kb == NULL) {
- LOGE("__recv_map_message: Unable to decode the bundle\n");
- goto error;
- }
-
- LOGI("__recv_map_message: ...from %d: OK\n", fd);
- LOGI("__recv_map_message: ...caller appid %s: OK\n", bundle_get_val(kb, AUL_K_CALLER_APPID));
-
- p = bundle_get_val(kb, OSP_K_REQUEST_ID);
- if (!p) {
- LOGE("Invalid Bundle: request_id is null");
- goto error;
- } else {
- request_id = atoi(p);
- }
- LOGI("Request ID: %d", request_id);
-
- if (data) {
- request_code = bundle_get_val(kb, OSP_K_DATACONTROL_REQUEST_TYPE);
- if (!request_code) {
- LOGE("Invalid Bundle: data-control request type is null");
- goto error;
- }
- request_type = atoi(request_code);
-
- if (__map_handle_cb(fd, kb, request_type, request_id, 0, data) != DATACONTROL_ERROR_NONE)
- goto error;
- } else {
- LOGE("error: listener information is null");
- goto error;
- }
- __remove_map_request_info(request_id, data);
-
- if (kb)
- bundle_free(kb);
- if (buf)
- free(buf);
- }
- }
- return TRUE;
-error:
- /* LCOV_EXCL_START */
- if (kb)
- bundle_free(kb);
- if (buf)
- free(buf);
-
- if (((map_response_cb_s *)data) != NULL) {
- map_dc = (map_response_cb_s *)data;
- g_hash_table_remove(__socket_pair_hash, map_dc->provider_id);
-
- itr = g_list_first(map_dc->request_info_list);
- while (itr != NULL) {
- request_info = (datacontrol_consumer_request_info *)itr->data;
- __map_call_cb(map_dc->provider_id, request_info->request_id, request_info->type, map_dc->data_id, false,
- "provider IO Error", NULL, 0, NULL, data);
- itr = g_list_next(itr);
- }
- if (map_dc->request_info_list) {
- LOGI("free map request_info_list");
- g_list_free_full(map_dc->request_info_list, free);
- map_dc->request_info_list = NULL;
- }
- }
- return FALSE;
- /* LCOV_EXCL_STOP */
-}
-
-static int __map_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *request_data, void *extra_data, int request_id)
-{
- char *app_id = NULL;
- void *data = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- void *map_dc_returned = NULL;
- char caller_app_id[255];
- char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, };
- char req_id[32] = {0,};
- int count = 0;
- const int TRY_COUNT = 2;
- const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 };
- bundle *send_data;
-
- LOGI("Map Data control request, type: %d, request id: %d", type, request_id);
-
- if (type < DATACONTROL_TYPE_MAP_GET || type > DATACONTROL_TYPE_MAP_BULK_ADD) {
- LOGE("Invalid request type: %d", (int)type);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (__socket_pair_hash == NULL)
- __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, _socket_info_free);
-
- if (!datacontrol_map_tree_root) {
- LOGE("The listener tree is empty");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(1, sizeof(map_response_cb_s));
- if (!map_dc_temp) {
- LOGE("Failed to create map datacontrol");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- map_dc_temp->provider_id = strdup(provider->provider_id);
- if (!map_dc_temp->provider_id) {
- LOGE("Failed to assign provider id to map data control: %d", errno);
- free(map_dc_temp);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- map_dc_temp->data_id = strdup(provider->data_id);
- if (!map_dc_temp->data_id) {
- LOGE("Failed to assign data id to map data control: %d", errno);
- free(map_dc_temp->provider_id);
- free(map_dc_temp);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- map_dc_temp->app_id = NULL;
- map_dc_temp->access_info = NULL;
- map_dc_temp->user_data = NULL;
- map_dc_temp->map_response_cb = NULL;
-
- map_dc_returned = tfind(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare);
-
- __map_instance_free(map_dc_temp);
-
- if (!map_dc_returned) {
- LOGE("Finding the map datacontrol in the listener tree is failed.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- map_response_cb_s *map_dc = *(map_response_cb_s **)map_dc_returned;
- app_id = map_dc->app_id;
- datacontrol_consumer_request_info *request_info = (datacontrol_consumer_request_info *)calloc(sizeof(datacontrol_consumer_request_info), 1);
- request_info->request_id = request_id;
- request_info->type = type;
- map_dc->request_info_list = g_list_append(map_dc->request_info_list, request_info);
- data = map_dc;
-
- LOGI("Map datacontrol appid: %s", map_dc->app_id);
-
- pid_t pid = getpid();
- if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
- LOGE("Failed to get appid by pid(%d).", pid);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- send_data = bundle_dup(request_data);
- if (send_data == NULL) {
- LOGE("fail to alloc result_data");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(send_data, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
- bundle_add_str(send_data, AUL_K_CALLER_APPID, caller_app_id);
-
- snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type));
- bundle_add_str(send_data, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation);
-
- snprintf(req_id, 32, "%d", request_id);
- bundle_add_str(send_data, OSP_K_REQUEST_ID, req_id);
-
- LOGI("caller_id %s, app_id %s", caller_app_id, app_id);
-
- do {
- datacontrol_socket_info *socket_info = g_hash_table_lookup(__socket_pair_hash, provider->provider_id);
- if (socket_info == NULL) {
- ret = _add_watch_on_socket_info(caller_app_id, app_id,
- "consumer", provider->provider_id, "Map",
- __recv_map_message, data,
- &socket_info);
- if (ret != DATACONTROL_ERROR_NONE) {
- bundle_free(send_data);
- return ret;
- }
-
- ret = _request_appsvc_run(caller_app_id, app_id);
- if (ret != DATACONTROL_ERROR_NONE) {
- _socket_info_free(socket_info);
- bundle_free(send_data);
- return ret;
- }
-
- g_hash_table_insert(__socket_pair_hash, strdup(provider->provider_id), socket_info);
- }
-
- LOGI("send data from consumer !!!");
- ret = _datacontrol_send_async(socket_info->socket_fd, send_data, extra_data, type, NULL);
- if (ret != DATACONTROL_ERROR_NONE)
- g_hash_table_remove(__socket_pair_hash, provider->provider_id);
- else
- break;
- count++;
- nanosleep(&TRY_SLEEP_TIME, 0);
- } while (ret != DATACONTROL_ERROR_NONE && count < TRY_COUNT);
-
- bundle_free(send_data);
- return ret;
-}
-
-int datacontrol_map_create(datacontrol_h *provider)
-{
- struct datacontrol_s *request;
-
- if (provider == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- request = malloc(sizeof(struct datacontrol_s));
- if (request == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- request->provider_id = NULL;
- request->data_id = NULL;
-
- *provider = request;
-
- return 0;
-}
-
-int datacontrol_map_destroy(datacontrol_h provider)
-{
- if (provider == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL)
- free(provider->provider_id);
-
- if (provider->data_id != NULL)
- free(provider->data_id);
-
- free(provider);
-
- return 0;
-}
-
-int datacontrol_map_set_provider_id(datacontrol_h provider, const char *provider_id)
-{
- if (provider == NULL || provider_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL)
- free(provider->provider_id);
-
- provider->provider_id = strdup(provider_id);
- if (provider->provider_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- return 0;
-}
-
-int datacontrol_map_get_provider_id(datacontrol_h provider, char **provider_id)
-{
- if (provider == NULL || provider_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL) {
- *provider_id = strdup(provider->provider_id);
- if (*provider_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- } else {
- *provider_id = NULL;
- }
-
- return 0;
-}
-
-int datacontrol_map_set_data_id(datacontrol_h provider, const char *data_id)
-{
- if (provider == NULL || data_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->data_id != NULL)
- free(provider->data_id);
-
- provider->data_id = strdup(data_id);
- if (provider->data_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- return 0;
-}
-
-int datacontrol_map_get_data_id(datacontrol_h provider, char **data_id)
-{
- if (provider == NULL || data_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->data_id != NULL) {
- *data_id = strdup(provider->data_id);
- if (*data_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- } else {
- *data_id = NULL;
- }
-
- return 0;
-}
-
-bool datacontrol_map_cb_is_registered(char *provider_id)
-{
- map_response_cb_s map_dc_temp;
- map_dc_temp.provider_id = provider_id;
-
- if (tfind(&map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare) != NULL)
- return true;
- return false;
-}
-
-int datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_response_cb *callback, void *user_data)
-{
- int ret = 0;
- char *app_id = NULL;
- char *access = NULL;
- void *map_dc_returned = NULL;
-
- ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id, "Map", getuid(), &app_id, &access);
- if (ret != PMINFO_R_OK) {
- LOGE("unable to get map data control information: %d", ret);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("data control provider appid = %s", app_id);
-
- map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(1, sizeof(map_response_cb_s));
- if (!map_dc_temp) {
- LOGE("unable to create a temporary map data control");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- map_dc_temp->provider_id = strdup(provider->provider_id);
- if (!map_dc_temp->provider_id) {
- LOGE("unable to assign provider_id to map data control: %d", errno);
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- map_dc_temp->data_id = strdup(provider->data_id);
- if (!map_dc_temp->data_id) {
- LOGE("unable to assign data_id to map data control: %d", errno);
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- map_dc_temp->app_id = app_id;
- map_dc_temp->access_info = access;
- map_dc_temp->user_data = user_data;
- map_dc_temp->map_response_cb = callback;
-
- map_dc_returned = tsearch(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare);
-
- map_response_cb_s *map_dc = *(map_response_cb_s **)map_dc_returned;
- if (map_dc != map_dc_temp) {
- map_dc->map_response_cb = callback;
- map_dc->user_data = user_data;
- LOGI("the data control is already set");
- __map_instance_free(map_dc_temp);
- }
-
- return DATACONTROL_ERROR_NONE;
-
- /* LCOV_EXCL_START */
-EXCEPTION:
- if (access)
- free(access);
- if (app_id)
- free(app_id);
- if (map_dc_temp) {
- if (map_dc_temp->provider_id)
- free(map_dc_temp->provider_id);
- if (map_dc_temp->data_id)
- free(map_dc_temp->data_id);
- free(map_dc_temp);
- }
-
- return ret;
- /* LCOV_EXCL_STOP */
-}
-
-int datacontrol_map_unregister_response_cb(datacontrol_h provider)
-{
- int ret = DATACONTROL_ERROR_NONE;
- map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(1, sizeof(map_response_cb_s));
- map_response_cb_s *map_dc_returned = NULL;
- char *tmp_provider_id;
-
- g_hash_table_remove(__socket_pair_hash, provider->provider_id);
-
- if (!map_dc_temp) {
- LOGE("unable to create a temporary map data control");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- map_dc_temp->provider_id = strdup(provider->provider_id);
- if (!map_dc_temp->provider_id) {
- LOGE("unable to assign provider_id to map data control: %d", errno);
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- if (datacontrol_map_tree_root == NULL) {
- LOGE("The listener tree is empty");
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- goto EXCEPTION;
- }
-
- map_dc_returned = *(map_response_cb_s **)tfind(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare);
- if (map_dc_returned == NULL) {
- LOGE("invalid parameter");
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- goto EXCEPTION;
- }
-
- if (map_dc_returned->app_id)
- free(map_dc_returned->app_id);
- if (map_dc_returned->data_id)
- free(map_dc_returned->data_id);
- if (map_dc_returned->access_info)
- free(map_dc_returned->access_info);
- if (map_dc_returned->request_info_list)
- g_list_free_full(map_dc_returned->request_info_list, free);
-
- tmp_provider_id = map_dc_returned->provider_id;
- tdelete(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare);
- free(tmp_provider_id);
-
- /* LCOV_EXCL_START */
-EXCEPTION:
- if (map_dc_temp) {
- if (map_dc_temp->provider_id)
- free(map_dc_temp->provider_id);
- free(map_dc_temp);
- }
-
- return ret;
- /* LCOV_EXCL_STOP */
-}
-
-int datacontrol_map_get(datacontrol_h provider, const char *key, int *request_id)
-{
- return datacontrol_map_get_with_page(provider, key, request_id, 1, 20);
-}
-
-int datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *request_id, int page_number, int count_per_page)
-{
- unsigned int arg_size;
- int ret = 0;
- const char *arg_list[4];
- char page_no_str[32];
- char count_per_page_str[32];
- int reqId;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Gets the value list from provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
-
- arg_size = (strlen(provider->data_id) + strlen(key)) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of sending argument (%u) exceeds the maximum limit.", arg_size);
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- bundle *b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
- arg_list[1] = key;
-
- ret = snprintf(page_no_str, sizeof(page_no_str), "%d", page_number);
- if (ret < 0) {
- LOGE("unable to convert page no to string: %d", errno);
- bundle_free(b);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- ret = snprintf(count_per_page_str, sizeof(count_per_page_str), "%d", count_per_page);
- if (ret < 0) {
- LOGE("unable to convert count per page no to string: %d", errno);
- bundle_free(b);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- arg_list[2] = page_no_str;
- arg_list[3] = count_per_page_str;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
-
- /* Set the request id */
- reqId = _datacontrol_create_request_id();
- *request_id = reqId;
-
- ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_GET, b, NULL, reqId);
- bundle_free(b);
-
- return ret;
-}
-
-int datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_value, const char *new_value, int *request_id)
-{
- unsigned int arg_size;
- bundle *b;
- const char *arg_list[4];
- int reqId;
- int ret;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || old_value == NULL || new_value == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Sets the old value to new value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
-
- arg_size = (strlen(provider->data_id) + strlen(key) + strlen(old_value) + strlen(new_value)) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of sending argument (%u) exceeds the maximum limit.", arg_size);
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
- arg_list[1] = key;
- arg_list[2] = old_value;
- arg_list[3] = new_value;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
-
- /* Set the request id */
- reqId = _datacontrol_create_request_id();
- *request_id = reqId;
-
- ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_SET, b, NULL, reqId);
- bundle_free(b);
-
- return ret;
-}
-
-int datacontrol_map_add_bulk_data(datacontrol_h provider, data_control_bulk_data_h bulk_data_h, int *request_id)
-{
- unsigned int arg_size = 0;
- bundle *b;
- bundle *data;
- const char *arg_list[3];
- int ret;
- int count;
- int i;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Adds the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
- datacontrol_bulk_data_get_count(bulk_data_h, &count);
- for (i = 0; i < count; i++) {
- datacontrol_bulk_data_get_data(bulk_data_h, i, &data);
- bundle_foreach(data, _bundle_foreach_check_arg_size_cb, &arg_size);
- }
-
- arg_size += (strlen(provider->data_id) + strlen(provider->provider_id)) * sizeof(char);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of sending argument (%u) exceeds the maximum limit.", arg_size);
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 1);
- *request_id = _datacontrol_create_request_id();
-
- ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_BULK_ADD, b, bulk_data_h, *request_id);
- bundle_free(b);
-
- return ret;
-}
-
-
-int datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int *request_id)
-{
- unsigned int arg_size;
- bundle *b;
- const char *arg_list[3];
- int reqId;
- int ret;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Adds the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
-
- arg_size = (strlen(provider->data_id) + strlen(key) + strlen(value)) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of sending argument (%u) exceeds the maximum limit.", arg_size);
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
- arg_list[1] = key;
- arg_list[2] = value;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
-
- /* Set the request id */
- reqId = _datacontrol_create_request_id();
- *request_id = reqId;
-
- ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_ADD, b, NULL, reqId);
- bundle_free(b);
-
- return ret;
-}
-
-int datacontrol_map_remove(datacontrol_h provider, const char *key, const char *value, int *request_id)
-{
- unsigned int arg_size;
- bundle *b;
- const char *arg_list[3];
- int reqId;
- int ret;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Removes the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
-
- arg_size = (strlen(provider->data_id) + strlen(key) + strlen(value)) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of sending argument (%u) exceeds the maximum limit.", arg_size);
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
- arg_list[1] = key;
- arg_list[2] = value;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
-
- /* Set the request id */
- reqId = _datacontrol_create_request_id();
- *request_id = reqId;
-
- ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_REMOVE, b, NULL, reqId);
- bundle_free(b);
-
- return ret;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <search.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <gio/gio.h>
-#include <sys/socket.h>
-
-#include <dlog.h>
-#include <appsvc/appsvc.h>
-#include <aul/aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-
-#include "data_control_log.h"
-#include "data-control-noti.h"
-#include "data-control-internal.h"
-
-
-typedef struct {
- GList *cb_list;
- char *provider_appid;
- char *provider_id;
- char *data_id;
- int monitor_id;
-} provider_info_s;
-
-typedef struct {
- void *user_data;
- int callback_id;
- data_control_data_change_cb changed_cb;
-} changed_cb_info_s;
-
-typedef struct {
- void *user_data;
- int callback_id;
- char *provider_id;
- char *data_id;
- int timeout_id;
- data_control_add_callback_result_cb callback;
-} add_callback_result_cb_info_s;
-
-static GList *__add_callback_result_cb_list = NULL;
-static GList *__changed_provider_list = NULL;
-
-static int __callback_result_info_compare_cb(gconstpointer a, gconstpointer b)
-{
- add_callback_result_cb_info_s *key1 =
- (add_callback_result_cb_info_s *)a;
- add_callback_result_cb_info_s *key2 =
- (add_callback_result_cb_info_s *)b;
-
- return !(key1->callback_id == key2->callback_id);
-}
-
-static int __provider_info_compare_cb(gconstpointer a, gconstpointer b)
-{
- provider_info_s *key1 = (provider_info_s *)a;
- provider_info_s *key2 = (provider_info_s *)b;
- return (strcmp(key1->provider_id, key2->provider_id) || strcmp(key1->data_id, key2->data_id));
-}
-
-static int __changed_cb_info_compare_cb(gconstpointer a, gconstpointer b)
-{
- changed_cb_info_s *key1 = (changed_cb_info_s *)a;
- changed_cb_info_s *key2 = (changed_cb_info_s *)b;
-
- return !(key1->callback_id == key2->callback_id);
-}
-
-static void __free_result_cb_info(
- add_callback_result_cb_info_s *result_cb_info)
-{
- if (result_cb_info) {
- if (result_cb_info->provider_id)
- free(result_cb_info->provider_id);
- if (result_cb_info->data_id)
- free(result_cb_info->data_id);
- if (result_cb_info->timeout_id > 0)
- g_source_remove(result_cb_info->timeout_id);
- free(result_cb_info);
- }
-}
-
-static void __free_provider_info(
- provider_info_s *provider_info)
-{
- if (provider_info) {
- if (provider_info->provider_appid)
- free(provider_info->provider_appid);
- if (provider_info->provider_id)
- free(provider_info->provider_id);
- if (provider_info->data_id)
- free(provider_info->data_id);
- if (provider_info->monitor_id > 0)
- g_dbus_connection_signal_unsubscribe(_get_dbus_connection(), provider_info->monitor_id);
- g_list_free_full(provider_info->cb_list, free);
- free(provider_info);
- }
-}
-
-static void __noti_process(GVariant *parameters)
-{
- char *provider_id = NULL;
- char *data_id = NULL;
- bundle_raw *raw = NULL;
- bundle *noti_data = NULL;
- int len = 0;
- datacontrol_h provider = NULL;
- GList *find_list;
- changed_cb_info_s *cb_info = NULL;
- provider_info_s find_info;
- provider_info_s *provider_info;
- GList *callback_list = NULL;
- datacontrol_data_change_type_e type;
-
- g_variant_get(parameters, "(i&s&s&si)", &type, &provider_id, &data_id, &raw, &len);
- LOGI("__noti_process : %d %s %s %d", type, provider_id, data_id, len);
-
- if (provider_id == NULL || data_id == NULL)
- return;
-
- find_info.provider_id = provider_id;
- find_info.data_id = data_id;
-
- find_list = g_list_find_custom(__changed_provider_list, &find_info,
- (GCompareFunc)__provider_info_compare_cb);
- if (find_list != NULL) {
- _create_datacontrol_h(&provider);
- _set_provider_id(provider, provider_id);
- _set_data_id(provider, data_id);
- noti_data = bundle_decode(raw, len);
- provider_info = (provider_info_s *)find_list->data;
- callback_list = g_list_first(provider_info->cb_list);
- for (; callback_list != NULL; callback_list = callback_list->next) {
- cb_info = callback_list->data;
- cb_info->changed_cb((data_control_h)provider, _get_public_noti_type(type), noti_data, cb_info->user_data);
- LOGI("callback called: %s, %s", provider_info->provider_id, provider_info->data_id);
- }
- bundle_free(noti_data);
- _destroy_datacontrol_h(provider);
-
- } else {
- LOGE("data_control_data_change_cb is null");
- }
- LOGI("__noti_process done");
-}
-
-static void __call_result_callback(int callback_id, int callback_result)
-{
- add_callback_result_cb_info_s *result_cb_info;
- add_callback_result_cb_info_s find_info;
- datacontrol_h provider;
- GList *find_list;
-
- find_info.callback_id = callback_id;
- find_list = g_list_find_custom(__add_callback_result_cb_list, &find_info,
- (GCompareFunc)__callback_result_info_compare_cb);
-
- if (find_list != NULL) {
- result_cb_info = (add_callback_result_cb_info_s *)find_list->data;
- if (result_cb_info->callback) {
- _create_datacontrol_h(&provider);
- _set_provider_id(provider, result_cb_info->provider_id);
- _set_data_id(provider, result_cb_info->data_id);
-
- result_cb_info->callback(
- (data_control_h)provider,
- callback_result,
- callback_id,
- result_cb_info->user_data);
-
- _destroy_datacontrol_h(provider);
- } else {
- LOGE("data_control_add_callback_result_cb is null");
- }
-
- __add_callback_result_cb_list = g_list_remove(__add_callback_result_cb_list, find_list->data);
- __free_result_cb_info(result_cb_info);
- } else {
- LOGE("add_callback_result_cb_info_s is null");
- }
-}
-
-/* LCOV_EXCL_START */
-static gboolean __add_callback_result_timeout_handler(gpointer user_data)
-{
- LOGE("add data changed callback time out !!!");
- add_callback_result_cb_info_s *result_cb_info =
- (add_callback_result_cb_info_s *)user_data;
- __call_result_callback(result_cb_info->callback_id, DATA_CONTROL_ERROR_IO_ERROR);
- return FALSE;
-}
-/* LCOV_EXCL_STOP */
-
-static void __noti_add_remove_data_changed_cb_result_process(
- GVariant *parameters)
-{
- int callback_id;
- data_control_error_e callback_result;
- datacontrol_data_change_type_e type;
-
- g_variant_get(parameters, "(iii)", &type, &callback_id, &callback_result);
- LOGI("__noti_add_remove_data_changed_cb_result_process: %d %d %d", type, callback_id, callback_result);
-
- if (type == DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT)
- __call_result_callback(callback_id, callback_result);
-}
-
-static void __handle_noti(GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- LOGI("signal_name: %s", signal_name);
-
- if (g_strcmp0(signal_name, "noti_data_changed") == 0)
- __noti_process(parameters);
- else if (g_strcmp0(signal_name, "noti_add_remove_result") == 0)
- __noti_add_remove_data_changed_cb_result_process(parameters);
-}
-
-static int __noti_request_appsvc_run(const char *callee_id,
- char *provider_id, char *data_id, const char *unique_id, int callback_id, int request_type)
-{
- int pid = -1;
- char callback_id_str[32] = {0,};
- char request_type_str[MAX_LEN_DATACONTROL_REQ_TYPE] = {0,};
- bundle *arg_list = bundle_create();
- if (!arg_list) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- snprintf(callback_id_str, 32, "%d", callback_id);
- snprintf(request_type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(request_type));
-
- appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT);
- appsvc_set_appid(arg_list, callee_id);
-
- bundle_add_str(arg_list, OSP_K_DATACONTROL_REQUEST_TYPE, request_type_str);
- bundle_add_str(arg_list, OSP_K_DATACONTROL_UNIQUE_NAME, unique_id);
- bundle_add_str(arg_list, OSP_K_DATACONTROL_PROVIDER, provider_id);
- bundle_add_str(arg_list, OSP_K_DATACONTROL_DATA, data_id);
- bundle_add_str(arg_list, OSP_K_DATA_CHANGED_CALLBACK_ID, callback_id_str);
-
- bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP);
- bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
- bundle_add_str(arg_list, AUL_K_CALLEE_APPID, callee_id);
- bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1");
- LOGI("callee_id %s", callee_id);
- LOGI("provider_id %s, data_id %s", provider_id, data_id);
-
- /* For DataControl CAPI */
- bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE");
-
- pid = appsvc_run_service(arg_list, 0, NULL, NULL);
- if (pid >= 0) {
- LOGI("Launch the provider app successfully: %d", pid);
- bundle_free(arg_list);
- } else if (pid == APPSVC_RET_EINVAL) {
- LOGE("not able to launch service: %d", pid);
- bundle_free(arg_list);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- } else {
- LOGE("unable to launch service: %d", pid);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_add_data_change_cb(datacontrol_h provider,
- data_control_data_change_cb callback,
- void *user_data,
- data_control_add_callback_result_cb result_callback,
- void *result_cb_user_data,
- int *callback_id)
-{
- int ret = DATACONTROL_ERROR_NONE;
- changed_cb_info_s *cb_info = NULL;
- provider_info_s *provider_info = NULL;
- provider_info_s find_provider_info;
- int monitor_id = 0;
- GList *find_list;
- char *path = NULL;
- const char *unique_id = NULL;
- char caller_app_id[255];
- pid_t pid;
- add_callback_result_cb_info_s *result_cb_info = NULL;
- char *provider_app_id = NULL;
- char *access = NULL;
-
- LOGI("provider_id : %s, data_id : %s", provider->provider_id, provider->data_id);
- ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id, "Sql", getuid(), &provider_app_id, &access);
- if (ret != PMINFO_R_OK) {
- LOGE("unable to get sql data control information, retry with map: %d", ret);
- ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id, "Map", getuid(), &provider_app_id, &access);
- if (ret != PMINFO_R_OK) {
- LOGE("unable to get map data control information: %d", ret);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- *callback_id = _datacontrol_get_data_changed_callback_id();
- unique_id = g_dbus_connection_get_unique_name(_get_dbus_connection());
- LOGI("unique_id : %s, callback_id %d", unique_id, *callback_id);
-
- find_provider_info.provider_id = provider->provider_id;
- find_provider_info.data_id = provider->data_id;
- find_list = g_list_find_custom(__changed_provider_list, &find_provider_info,
- (GCompareFunc)__provider_info_compare_cb);
- if (find_list == NULL) {
-
- pid = getpid();
- if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
- LOGE("Failed to get appid by pid(%d).", pid);
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- goto err;
- }
- path = _get_encoded_path(provider, caller_app_id);
- if (path == NULL) {
- LOGE("cannot get encoded path. out of memory.");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto err;
- }
-
- ret = _dbus_signal_init(&monitor_id, path, __handle_noti);
- if (ret != DATACONTROL_ERROR_NONE) {
- LOGE("fail to init dbus signal.");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto err;
- }
-
- provider_info = (provider_info_s *)calloc(1, sizeof(provider_info_s));
- if (provider_info == NULL) {
- LOGE("provider_info_s alloc fail out of memory.");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto err;
- }
- provider_info->provider_appid = strdup(provider_app_id);
- provider_info->provider_id = strdup(provider->provider_id);
- provider_info->data_id = strdup(provider->data_id);
- provider_info->monitor_id = monitor_id;
- if (provider_info->provider_id == NULL || provider_info->data_id == NULL) {
- LOGE("data_id alloc fail out of memory.");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- __free_provider_info(provider_info);
- goto err;
- }
- __changed_provider_list = g_list_append(__changed_provider_list, provider_info);
- } else {
- provider_info = (provider_info_s *)find_list->data;
- }
-
- ret = __noti_request_appsvc_run(
- provider_app_id,
- provider_info->provider_id,
- provider_info->data_id,
- unique_id,
- *callback_id,
- DATACONTROL_TYPE_ADD_DATA_CHANGED_CB);
- if (ret != DATACONTROL_ERROR_NONE) {
- LOGE("__noti_request_appsvc_run error !!!");
- goto err;
- }
-
- cb_info = (changed_cb_info_s *)calloc(1,
- sizeof(changed_cb_info_s));
- if (cb_info == NULL) {
- LOGE("changed_cb_info_s alloc fail out of memory.");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto err;
- }
-
- cb_info->changed_cb = callback;
- cb_info->user_data = user_data;
- cb_info->callback_id = *callback_id;
- provider_info->cb_list = g_list_append(
- provider_info->cb_list, cb_info);
-
- result_cb_info =
- (add_callback_result_cb_info_s *)calloc(1, sizeof(add_callback_result_cb_info_s));
- result_cb_info->callback_id = *callback_id;
- result_cb_info->callback = result_callback;
- result_cb_info->user_data = result_cb_user_data;
- result_cb_info->provider_id = strdup(provider_info->provider_id);
- result_cb_info->data_id = strdup(provider_info->data_id);
- result_cb_info->timeout_id = g_timeout_add(5000, __add_callback_result_timeout_handler, result_cb_info);
- __add_callback_result_cb_list = g_list_append(__add_callback_result_cb_list, result_cb_info);
- LOGI("datacontrol_add_data_change_cb done");
-
- /* LCOV_EXCL_START */
-err:
- if (access)
- free(access);
- if (provider_app_id)
- free(provider_app_id);
- if (path)
- free(path);
- if (ret != DATACONTROL_ERROR_NONE) {
- if (monitor_id > 0)
- g_dbus_connection_signal_unsubscribe(_get_dbus_connection(), monitor_id);
- }
-
- return ret;
- /* LCOV_EXCL_STOP */
-}
-
-int datacontrol_remove_data_change_cb(datacontrol_h provider, int callback_id)
-{
- changed_cb_info_s *removed_cb_info = NULL;
- changed_cb_info_s cb_info;
- provider_info_s info;
- provider_info_s *target_provider_info;
- add_callback_result_cb_info_s result_cb_info;
- add_callback_result_cb_info_s *tmp;
- GList *provider_list = NULL;
- GList *callback_list = NULL;
- GList *result_cb_list = NULL;
- const char *unique_id = NULL;
- int ret = DATACONTROL_ERROR_NONE;
-
- info.provider_id = provider->provider_id;
- info.data_id = provider->data_id;
-
- provider_list = g_list_find_custom(__changed_provider_list, &info,
- (GCompareFunc)__provider_info_compare_cb);
- if (provider_list == NULL) {
- LOGE("Cannot find provider info");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- cb_info.callback_id = callback_id;
- target_provider_info = (provider_info_s *)provider_list->data;
- callback_list = g_list_find_custom(
- target_provider_info->cb_list,
- &cb_info,
- (GCompareFunc)__changed_cb_info_compare_cb);
- if (callback_list == NULL) {
- LOGE("Cannot find changed callback info");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- removed_cb_info = (changed_cb_info_s *)callback_list->data;
- target_provider_info->cb_list
- = g_list_remove(target_provider_info->cb_list, removed_cb_info);
- free(removed_cb_info);
-
- if (g_list_length(target_provider_info->cb_list) == 0) {
- unique_id = g_dbus_connection_get_unique_name(_get_dbus_connection());
- LOGI("unique_id : %s", unique_id);
- ret = __noti_request_appsvc_run(
- target_provider_info->provider_appid,
- target_provider_info->provider_id,
- target_provider_info->data_id,
- unique_id,
- callback_id,
- DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB);
- if (ret != DATACONTROL_ERROR_NONE) {
- LOGE("__sql_request_provider fail %d", ret);
- return ret;
- }
-
- __changed_provider_list = g_list_remove(__changed_provider_list, target_provider_info);
- __free_provider_info(target_provider_info);
- }
-
- result_cb_info.callback_id = callback_id;
- result_cb_list = g_list_find_custom(__add_callback_result_cb_list, &result_cb_info,
- (GCompareFunc)__callback_result_info_compare_cb);
- if (result_cb_list) {
- tmp = (add_callback_result_cb_info_s *)result_cb_list->data;
- __add_callback_result_cb_list = g_list_remove(__add_callback_result_cb_list, result_cb_list->data);
- __free_result_cb_info(tmp);
- }
- return DATACONTROL_ERROR_NONE;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <search.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-#include <pthread.h>
-#include <sqlite3.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-
-#include <dlog.h>
-#include <appsvc/appsvc.h>
-#include <aul/aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-
-#include "data-control-sql.h"
-#include "data-control-provider.h"
-#include "data-control-internal.h"
-#include "data-control-bulk.h"
-
-#define QUERY_MAXLEN 4096
-#define ROW_ID_SIZE 32
-#define RESULT_PATH_MAX 512
-
-#define RESULT_PAGE_NUMBER "RESULT_PAGE_NUMBER"
-#define MAX_COUNT_PER_PAGE "MAX_COUNT_PER_PAGE"
-#define RESULT_VALUE_COUNT "RESULT_VALUE_COUNT"
-
-#define PACKET_INDEX_REQUEST_RESULT 0
-#define PACKET_INDEX_ERROR_MSG 1
-#define PACKET_INDEX_SELECT_RESULT_FILE 2
-#define PACKET_INDEX_ROW_ID 2
-#define PACKET_INDEX_VALUE_COUNT 2
-#define PACKET_INDEX_GET_RESULT_FILE 3
-
-#define PACKET_INDEX_DATAID 0
-#define PACKET_INDEX_MAP 2
-
-#define PACKET_INDEX_UPDATEWHERE 1
-#define PACKET_INDEX_DELETEWHERE 1
-
-#define PACKET_INDEX_MAP_KEY 1
-#define PACKET_INDEX_MAP_VALUE_1ST 2
-#define PACKET_INDEX_MAP_VALUE_2ND 3
-#define PACKET_INDEX_MAP_PAGE_NO 2
-#define PACKET_INDEX_MAP_COUNT_PER_PAGE 3
-
-#define DATA_CONTROL_BUS_NAME "org.tizen.data_control_service"
-#define DATA_CONTROL_OBJECT_PATH "/org/tizen/data_control_service"
-#define DATA_CONTROL_INTERFACE_NAME "org.tizen.data_control_service"
-#define DATA_CONTROL_DATA_CHANGE_DATA_CHANGED "noti_data_changed"
-#define DATA_CONTROL_DATA_CHANGE_ADD_REMOVE_RESULT "noti_add_remove_result"
-
-static GHashTable *__request_table = NULL;
-static GHashTable *__socket_pair_hash = NULL;
-static sqlite3 *__provider_db = NULL;
-
-void *provider_sql_user_data;
-void *provider_map_user_data;
-
-/* static pthread_mutex_t provider_lock = PTHREAD_MUTEX_INITIALIZER; */
-typedef int (*provider_handler_cb) (bundle *b, int request_id, void *data);
-
-typedef struct {
- void *user_data;
- int callback_id;
- data_control_provider_data_change_consumer_filter_cb callback;
-} changed_noti_consumer_filter_info_s;
-
-static datacontrol_provider_sql_cb *provider_sql_cb = NULL;
-static datacontrol_provider_map_cb *provider_map_cb = NULL;
-
-static GList *__noti_consumer_app_list = NULL;
-static GList *__noti_consumer_filter_info_list = NULL;
-static int __create_consumer_list_db();
-static int __delete_consumer_list_db_info(char *unique_id);
-
-static int __data_changed_filter_cb_info_compare_cb(gconstpointer a, gconstpointer b)
-{
- changed_noti_consumer_filter_info_s *key1 = (changed_noti_consumer_filter_info_s *)a;
- changed_noti_consumer_filter_info_s *key2 = (changed_noti_consumer_filter_info_s *)b;
-
- return !(key1->callback_id == key2->callback_id);
-}
-
-static int __noti_consumer_app_list_compare_cb(gconstpointer a, gconstpointer b)
-{
- datacontrol_consumer_info *info_a = (datacontrol_consumer_info *)a;
- datacontrol_consumer_info *info_b = (datacontrol_consumer_info *)b;
-
- return strcmp(info_a->unique_id, info_b->unique_id);
-}
-
-static void __free_consumer_info(const gchar *name)
-{
- datacontrol_consumer_info find_key;
- datacontrol_consumer_info *info;
- GList *find_list = NULL;
- int result;
-
- find_key.unique_id = (char *)name;
- find_list = g_list_find_custom(__noti_consumer_app_list, &find_key,
- (GCompareFunc)__noti_consumer_app_list_compare_cb);
- if (find_list == NULL) {
- LOGI("__free_consumer_info %s not exist", name);
- return;
- }
-
- info = (datacontrol_consumer_info *)find_list->data;
- result = __delete_consumer_list_db_info(info->unique_id);
- if (result != DATACONTROL_ERROR_NONE)
- LOGE("__delete_consumer_list_db_info fail %d", result);
-
- if (info->appid)
- free(info->appid);
- if (info->object_path)
- free(info->object_path);
- if (info->unique_id)
- free(info->unique_id);
- g_bus_unwatch_name(info->monitor_id);
-
- __noti_consumer_app_list = g_list_remove(__noti_consumer_app_list, find_list->data);
-
- free(info);
- LOGI("__free_consumer_info done");
-}
-
-static void __free_bundle_data(gpointer data)
-{
- if (data) {
- bundle_free(data);
- data = NULL;
- }
-}
-
-static void __free_data(gpointer data)
-{
- if (data) {
- free(data);
- data = NULL;
- }
-}
-
-static void __initialize_provider(void)
-{
- int result;
- __request_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_data, __free_bundle_data);
- __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, _socket_info_free);
- result = __create_consumer_list_db();
- if (result != DATACONTROL_ERROR_NONE)
- LOGE("fail to create consumer list db");
-}
-
-static int __provider_new_request_id(void)
-{
- static int id = 0;
- g_atomic_int_inc(&id);
- return id;
-}
-
-static int __send_select_result(int fd, bundle *b, void *data)
-{
- /*
- In this function, the result set is written in socket as specific form.
- [sizeof(int)] column count
- [sizeof(int)] column type x N
- [ variant ] (column name leng, column name) x N
- [sieeof(int)] total size of column names
- [sizeof(int)] row count
- [ variant ] (type, size, content) x N
- */
-
- sqlite3_stmt *state = (sqlite3_stmt *)data;
- int column_count = DATACONTROL_RESULT_NO_DATA;
- int i = 0;
- char *column_name = NULL;
- int total_len_of_column_names = 0;
- int count_per_page = 0;
- int page_number = 1;
- int offset = 0;
- sqlite3_int64 offset_idx = 0;
- sqlite3_int64 row_count = 0;
- unsigned int nb = 0;
- int type = 0;
- int column_name_len;
- const char *page_number_str;
- int size = 0;
- void *value = NULL;
- int column_type;
- long long tmp_long = 0;
- double tmp_double = 0.0;
- void *buf = NULL;
- int buf_len = 0;
- const char *count_per_page_str;
-
- LOGI("__send_select_result");
- if (b == NULL || data == NULL) {
- LOGE("The input param is invalid.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (sqlite3_reset(state) != SQLITE_OK) {
- LOGE("sqlite3_reset() is failed.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (sqlite3_step(state) != SQLITE_ROW) {
- LOGE("The DB does not have another row.");
- if (_write_socket(fd, &column_count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a column_count to a file descriptor is failed.");
- return DATACONTROL_ERROR_IO_ERROR;
- }
- return DATACONTROL_ERROR_NONE;
- }
-
- /* 1. column count */
- column_count = sqlite3_column_count(state);
- if (_write_socket(fd, &column_count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("Writing a column_count %d", column_count);
-
- /*
- 2. column type x column_count
- #define SQLITE_INTEGER 1
- #define SQLITE_FLOAT 2
- #define SQLITE_TEXT 3
- #define SQLITE_BLOB 4
- #define SQLITE_NULL 5
- */
- for (i = 0; i < column_count; i++) {
- type = sqlite3_column_type(state, i);
- if (_write_socket(fd, &type, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("Writing a type to a file descriptor is failed.");
- return DATACONTROL_ERROR_IO_ERROR;
- }
- LOGI("Writing a column_type %d", type);
- }
-
- /* 3. column name x column_count */
- for (i = 0; i < column_count; i++) {
- column_name = (char *)sqlite3_column_name(state, i);
- if (column_name == NULL) {
- LOGI("sqlite3_column_name is failed. errno = %d", errno);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- } else {
- column_name_len = strlen(column_name) + 1;
- if (_write_socket(fd, &column_name_len, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("Writing a column_name_len to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("Writing a column_name_len %d", column_name_len);
-
- if (_write_socket(fd, column_name, column_name_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("Writing a column_name to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- total_len_of_column_names += strlen(column_name);
- LOGI("Writing a column_name %s", column_name);
- }
- }
-
- /* 4. total length of column names */
- if (_write_socket(fd, &total_len_of_column_names, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("Writing a total_len_of_column_names %d", total_len_of_column_names);
-
- page_number_str = bundle_get_val(b, RESULT_PAGE_NUMBER);
- count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE);
-
- LOGI("page_number: %s, per_page: %s", page_number_str, count_per_page_str);
-
- /* 5. type, size and value of each element */
- if (page_number_str != NULL)
- page_number = atoi(page_number_str);
- else
- page_number = 1;
-
- if (count_per_page_str != NULL)
- count_per_page = atoi(count_per_page_str);
- else
- count_per_page = 20;
-
- offset = (page_number - 1) * count_per_page;
-
- LOGI("page_number: %d, count_per_page: %d, offset: %d", page_number, count_per_page, offset);
-
- if (sqlite3_reset(state) != SQLITE_OK) {
- LOGE("sqlite3_reset() is failed.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (sqlite3_step(state) != SQLITE_ROW) {
- LOGE("The DB does not have another row.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- do {
- offset_idx++;
- if (offset_idx > offset)
- ++row_count;
- } while (sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page);
-
- /* 6. row count */
- if (_write_socket(fd, &row_count, sizeof(row_count), &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("Writing a row_count to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- LOGI("Writing a row_count %lld", row_count);
-
- row_count = 0;
- offset_idx = 0;
- if (sqlite3_reset(state) != SQLITE_OK) {
- LOGI("sqlite3_reset() is failed.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (sqlite3_step(state) != SQLITE_ROW) {
- LOGE("The DB does not have another row.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- do {
- offset_idx++;
- if (offset_idx > offset) {
- ++row_count;
- for (i = 0; i < column_count; ++i) {
- column_type = sqlite3_column_type(state, i);
-
- switch (column_type) {
- case SQLITE_INTEGER:
- type = 1;
- size = sizeof(long long);
- tmp_long = sqlite3_column_int64(state, i);
- value = &tmp_long;
- break;
- case SQLITE_FLOAT:
- type = 2;
- size = sizeof(double);
- tmp_double = sqlite3_column_double(state, i);
- value = &tmp_double;
- break;
- case SQLITE_TEXT:
- type = 3;
- value = (char *)sqlite3_column_text(state, i);
- if (value)
- size = strlen(value) + 1;
- else
- size = 0;
- break;
- case SQLITE_BLOB:
- type = 4;
- size = sqlite3_column_bytes(state, i);
- value = (char *)sqlite3_column_blob(state, i);
- break;
- case SQLITE_NULL:
- type = 5;
- size = 0;
- break;
- default:
- LOGI("The column type is invalid.");
- break;
- }
-
- if (value == NULL && type != 5)
- return DATACONTROL_ERROR_IO_ERROR;
-
- buf_len = sizeof(int) * 2 + size;
- buf = calloc(buf_len, sizeof(void));
- if (buf == NULL) {
- LOGE("calloc failed");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
- memcpy(buf, &type, sizeof(int));
- memcpy(buf + sizeof(int), &size, sizeof(int));
- if (size > 0)
- memcpy(buf + sizeof(int) + sizeof(int), value, size);
-
- if (_write_socket(fd, buf, buf_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a size to a file descriptor is failed. errno = %d", errno);
- free(buf);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- free(buf);
-
- }
- LOGI("row_count ~~~~ %lld", row_count);
-
- }
-
- } while (sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page);
-
- return DATACONTROL_ERROR_NONE;
-}
-
-static int _get_int_from_str(const char *str)
-{
- int result = 0;
- char *pend;
- errno = 0;
- result = strtol(str, &pend, 10);
- if ((result == LONG_MIN || result == LONG_MAX)
- && errno != 0) {
- result = 0;
- }
-
- if (*pend != '\0')
- result = 0;
-
- return result;
-}
-
-static int __send_get_value_result(int fd, bundle *b, void *data)
-{
- int i = 0;
- char **value_list = (char **)data;
- const char *page_num_str = bundle_get_val(b, RESULT_PAGE_NUMBER);
- const char *count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE);
- const char *value_count_str = bundle_get_val(b, RESULT_VALUE_COUNT);
- int page_number = 0;
- int count_per_page = 0;
- int value_count = 0;
- int current_offset = 0;
- int remain_count = 0;
- unsigned int nb;
- int add_value_count;
- int length;
-
- LOGI("page num: %s, count_per_page: %s, value_count %s", page_num_str, count_per_page_str, value_count_str);
-
- page_number = _get_int_from_str(page_num_str);
- count_per_page = _get_int_from_str(count_per_page_str);
- value_count = _get_int_from_str(value_count_str);
-
- current_offset = (page_number - 1) * count_per_page;
- remain_count = value_count - current_offset;
- remain_count = (remain_count > 0) ? remain_count : 0; /* round off to zero if the negative num is found */
-
- add_value_count = (count_per_page > remain_count) ? remain_count : count_per_page;
-
- LOGI("add_value_count: %d, current_offset: %d, remain_count %d", add_value_count, current_offset, remain_count);
-
- if (_write_socket(fd, &add_value_count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a length to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- add_value_count += current_offset;
-
- for (i = current_offset; i < add_value_count; i++) {
- length = strlen(value_list[i]);
- LOGI("length = %d", length);
- if (_write_socket(fd, &length, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a length to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("value_list = %s", value_list[i]);
- if (_write_socket(fd, value_list[i], length, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a value_list to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-
-static int __send_bulk_result(int fd, void *data)
-{
- data_control_bulk_result_data_h bulk_results = (data_control_bulk_result_data_h)data;
- int count;
- int i;
- int result;
- bundle_raw *encode_data = NULL;
- int encode_datalen = 0;
- bundle *result_data;
- unsigned int nb = 0;
-
- datacontrol_bulk_result_data_get_count(bulk_results, &count);
- if (_write_socket(fd, &count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a result count to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- LOGD("__send_bulk_result %d", count);
-
- for (i = 0; i < count; i++) {
- datacontrol_bulk_result_data_get_result_data(bulk_results, i, &result_data, &result);
- if (_write_socket(fd, &result, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a result to a file descriptor is failed. errno = %d", errno);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (result_data != NULL) {
- bundle_encode_raw(result_data, &encode_data, &encode_datalen);
- if (encode_data == NULL) {
- LOGE("bundle encode error");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
- }
-
- if (_write_socket(fd, &encode_datalen, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a encode_datalen to a file descriptor is failed. errno = %d", errno);
- free(encode_data);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (_write_socket(fd, encode_data, encode_datalen, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Writing a encode_data to a file descriptor is failed. errno = %d", errno);
- free(encode_data);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGE("result %d, encode_datalen %d", result, encode_datalen);
- free(encode_data);
- encode_data = NULL;
- encode_datalen = 0;
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-int __datacontrol_send_async(int sockfd, bundle *kb, datacontrol_request_type type, void *data)
-{
- bundle_raw *kb_data = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- int datalen = 0;
- char *buf;
- int total_len = 0;
- unsigned int nb = 0;
-
- LOGI("send async ~~~");
- bundle_encode_raw(kb, &kb_data, &datalen);
- if (kb_data == NULL) {
- LOGE("bundle encode error");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- /* encoded bundle + encoded bundle len */
- buf = (char *)calloc(datalen + 4, sizeof(char));
- if (buf == NULL) {
- LOGE("buf calloc error");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
- memcpy(buf, &datalen, sizeof(datalen));
- memcpy(buf + sizeof(datalen), kb_data, datalen);
-
- total_len = sizeof(datalen) + datalen;
-
- LOGI("write : %d", datalen);
- if (_write_socket(sockfd, buf, total_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("write data fail ");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (DATACONTROL_TYPE_SQL_SELECT == type)
- ret = __send_select_result(sockfd, kb, data);
- else if (DATACONTROL_TYPE_MAP_GET == type)
- ret = __send_get_value_result(sockfd, kb, data);
- else if (DATACONTROL_TYPE_SQL_BULK_INSERT == type ||
- DATACONTROL_TYPE_MAP_BULK_ADD == type)
- ret = __send_bulk_result(sockfd, data);
-
-out:
- free(buf);
- bundle_free_encoded_rawdata(&kb_data);
-
- return ret;
-}
-
-static bundle *__get_bundle_data_from_fd(int fd)
-{
- bundle *b = NULL;
- int len = 0;
- int ret;
- char *buf;
-
- ret = read(fd, &len, sizeof(int));
- if (ret < sizeof(int)) {
- LOGE("read error :%d", ret);
- return NULL;
- }
- LOGD("read len : %d", len);
-
- if (len > 0 && len < MAX_REQUEST_ARGUMENT_SIZE) {
- buf = (char *)calloc(len, sizeof(char));
- if (buf == NULL) {
- LOGE("calloc fail");
- return NULL;
- }
- ret = read(fd, buf, len);
- if (ret < len) {
- LOGE("read error :%d", ret);
- if (buf)
- free(buf);
- return NULL;
- }
- b = bundle_decode_raw((bundle_raw *)buf, len);
-
- if (buf)
- free(buf);
- } else {
- LOGE("__get_bundle_data_from_fd read count : %d", len);
- }
-
- return b;
-}
-
-static data_control_bulk_data_h __get_bulk_data_from_fd(int fd)
-{
- data_control_bulk_data_h ret_bulk_data_h = NULL;
- int size = 0;
- int ret;
- int i;
- bundle *data = NULL;
-
- datacontrol_bulk_data_create(&ret_bulk_data_h);
- ret = read(fd, &size, sizeof(int));
- if (ret < sizeof(int)) {
- LOGE("read error :%d", ret);
- datacontrol_bulk_data_destroy(ret_bulk_data_h);
- return NULL;
- }
-
- LOGI("bulk data size : %d", size);
- if (size < 0 || size >= MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("Invalid data size");
- datacontrol_bulk_data_destroy(ret_bulk_data_h);
- return NULL;
- }
-
- for (i = 0; i < size; i++) {
- LOGI("bulk data : %d", i);
- data = __get_bundle_data_from_fd(fd);
- if (data == NULL) {
- LOGE("get bundle data from fd fail");
- datacontrol_bulk_data_destroy(ret_bulk_data_h);
- return NULL;
- }
- datacontrol_bulk_data_add(ret_bulk_data_h, data);
- bundle_free(data);
- }
- return ret_bulk_data_h;
-}
-
-static bundle *__set_result(bundle *b, datacontrol_request_type type, void *data)
-{
- bundle *res = bundle_create();
-
- /* Set the type */
- char type_str[MAX_LEN_DATACONTROL_REQ_TYPE] = {0,};
- const char *request_type;
- const char *provider_id;
- const char *data_id;
- const char *request_id;
- const char *caller_appid;
- const char *list[3];
- const char *page_num = bundle_get_val(b, RESULT_PAGE_NUMBER);
- const char *count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE);
-
- if (type == DATACONTROL_TYPE_UNDEFINED || type == DATACONTROL_TYPE_ERROR) {
- request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
- strncpy(type_str, request_type, MAX_LEN_DATACONTROL_REQ_TYPE);
- LOGI("type is %s", type_str);
-
- } else {
- snprintf(type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)type);
- }
-
- bundle_add_str(res, OSP_K_DATACONTROL_REQUEST_TYPE, type_str);
-
- /* Set the provider id */
- provider_id = bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
- bundle_add_str(res, OSP_K_DATACONTROL_PROVIDER, provider_id);
-
- /* Set the data id */
- data_id = bundle_get_val(b, OSP_K_DATACONTROL_DATA);
- bundle_add_str(res, OSP_K_DATACONTROL_DATA, data_id);
-
- /* Set the caller request id */
- request_id = bundle_get_val(b, OSP_K_REQUEST_ID);
- bundle_add_str(res, OSP_K_REQUEST_ID, request_id);
-
- caller_appid = bundle_get_val(b, AUL_K_CALLER_APPID);
- bundle_add_str(res, AUL_K_CALLER_APPID, caller_appid);
-
- switch (type) {
- case DATACONTROL_TYPE_SQL_SELECT:
- {
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
- list[PACKET_INDEX_SELECT_RESULT_FILE] = DATACONTROL_EMPTY;
-
- page_num = bundle_get_val(b, RESULT_PAGE_NUMBER);
- count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE);
-
- LOGI("page num: %s, count_per_page: %s", page_num, count_per_page);
-
- bundle_add_str(res, RESULT_PAGE_NUMBER, page_num);
- bundle_add_str(res, MAX_COUNT_PER_PAGE, count_per_page);
-
- bundle_add_str_array(res, OSP_K_ARG, list, 3);
-
- break;
- }
- case DATACONTROL_TYPE_SQL_BULK_INSERT:
- {
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- break;
- }
- case DATACONTROL_TYPE_SQL_INSERT:
- {
- long long row_id = *(long long *)data;
-
- const char *list[3];
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
-
- /* Set the row value */
- char row_str[ROW_ID_SIZE] = {0,};
- snprintf(row_str, ROW_ID_SIZE, "%lld", row_id);
-
- list[PACKET_INDEX_ROW_ID] = row_str;
- bundle_add_str_array(res, OSP_K_ARG, list, 3);
- break;
- }
- case DATACONTROL_TYPE_SQL_UPDATE:
- case DATACONTROL_TYPE_SQL_DELETE:
- {
- const char *list[2];
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
-
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- break;
- }
- case DATACONTROL_TYPE_MAP_BULK_ADD:
- {
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- break;
- }
- case DATACONTROL_TYPE_MAP_GET:
- {
- const char *list[4];
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
-
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- const char *page_num = bundle_get_val(b, RESULT_PAGE_NUMBER);
- const char *count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE);
- const char *value_count = bundle_get_val(b, RESULT_VALUE_COUNT);
-
- bundle_add_str(res, RESULT_PAGE_NUMBER, page_num);
- bundle_add_str(res, MAX_COUNT_PER_PAGE, count_per_page);
- bundle_add_str(res, RESULT_VALUE_COUNT, value_count);
-
- break;
- }
- case DATACONTROL_TYPE_ADD_DATA_CHANGED_CB:
- {
- const char *list[2];
- char result_str[2] = {0,};
- bool result = *(bool *)data;
- snprintf(result_str, 2, "%d", result);
-
- list[PACKET_INDEX_REQUEST_RESULT] = result_str; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
-
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- break;
- }
- case DATACONTROL_TYPE_UNDEFINED: /* DATACONTROL_TYPE_MAP_SET || ADD || REMOVE */
- {
- const char *list[2];
- list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
-
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- break;
- }
- default: /* Error */
- {
- const char *list[2];
- list[PACKET_INDEX_REQUEST_RESULT] = "0"; /* request result */
- list[PACKET_INDEX_ERROR_MSG] = (char *)data; /* error string */
-
- bundle_add_str_array(res, OSP_K_ARG, list, 2);
- break;
- }
- }
-
- return res;
-}
-
-static int __send_result(bundle *b, datacontrol_request_type type, void *data)
-{
- datacontrol_socket_info *socket_info;
- char *caller_app_id = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
- int ret = DATACONTROL_ERROR_NONE;
-
- LOGI("__datacontrol_send_async caller_app_id : %s ", caller_app_id);
-
- socket_info = g_hash_table_lookup(__socket_pair_hash, caller_app_id);
- if (socket_info == NULL) {
- LOGE("__socket_pair_hash lookup fail");
- return DATACONTROL_ERROR_IO_ERROR;
- }
- ret = __datacontrol_send_async(socket_info->socket_fd, b, type, data);
- LOGI("__datacontrol_send_async result : %d ", ret);
- if (ret != DATACONTROL_ERROR_NONE)
- g_hash_table_remove(__socket_pair_hash, caller_app_id);
-
- return ret;
-}
-
-static int __insert_consumer_list_db_info(char *app_id, char *provider_id, char *data_id, char *unique_id, char *object_path)
-{
- int r;
- int result = DATACONTROL_ERROR_NONE;
- char query[QUERY_MAXLEN];
- sqlite3_stmt *stmt = NULL;
- sqlite3_snprintf(QUERY_MAXLEN, query,
- "INSERT OR REPLACE INTO data_control_consumer_path_list(app_id, provider_id, data_id, unique_id, object_path)" \
- "VALUES (?,?,?,?,?)");
- LOGI("consumer list db insert sql : %s", query);
- r = sqlite3_prepare(__provider_db, query, sizeof(query), &stmt, NULL);
- if (r != SQLITE_OK) {
- LOGE("sqlite3_prepare error(%d , %d, %s)", r, sqlite3_extended_errcode(__provider_db), sqlite3_errmsg(__provider_db));
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_bind_text(stmt, 1, app_id, strlen(app_id), SQLITE_STATIC);
- if (r != SQLITE_OK) {
- LOGE("app_id bind error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_bind_text(stmt, 2, provider_id, strlen(provider_id), SQLITE_STATIC);
- if (r != SQLITE_OK) {
- LOGE("provider_id bind error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_bind_text(stmt, 3, data_id, strlen(data_id), SQLITE_STATIC);
- if (r != SQLITE_OK) {
- LOGE("data_id bind error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_bind_text(stmt, 4, unique_id, strlen(unique_id), SQLITE_STATIC);
- if (r != SQLITE_OK) {
- LOGE("unique_id bind error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_bind_text(stmt, 5, object_path, strlen(object_path), SQLITE_STATIC);
- if (r != SQLITE_OK) {
- LOGE("object_path bind error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_step(stmt);
- if (r != SQLITE_DONE) {
- LOGE("step error(%d) \n", r);
- LOGE("sqlite3_step error(%d, %s)",
- sqlite3_extended_errcode(__provider_db),
- sqlite3_errmsg(__provider_db));
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
-out:
- if (stmt)
- sqlite3_finalize(stmt);
-
- return result;
-}
-
-static int __delete_consumer_list_db_info(char *unique_id)
-{
- int r;
- char query[QUERY_MAXLEN];
- int result = DATACONTROL_ERROR_NONE;
- sqlite3_stmt *stmt = NULL;
- sqlite3_snprintf(QUERY_MAXLEN, query,
- "DELETE FROM data_control_consumer_path_list WHERE unique_id = ?");
- LOGI("consumer list db DELETE : %s, unique_id : %s", query, unique_id);
- r = sqlite3_prepare(__provider_db, query, sizeof(query), &stmt, NULL);
- if (r != SQLITE_OK) {
- LOGE("sqlite3_prepare error(%d , %d, %s)", r,
- sqlite3_extended_errcode(__provider_db), sqlite3_errmsg(__provider_db));
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_bind_text(stmt, 1, unique_id, strlen(unique_id), SQLITE_STATIC);
- if (r != SQLITE_OK) {
- LOGE("caller bind error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- r = sqlite3_step(stmt);
- if (r != SQLITE_DONE) {
- LOGE("step error(%d) \n", r);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
-out:
- if (stmt)
- sqlite3_finalize(stmt);
-
- LOGI("__delete_consumer_list_db_info done");
- return result;
-}
-
-static void __on_name_appeared(GDBusConnection *connection,
- const gchar *name,
- const gchar *name_owner,
- gpointer user_data)
-{
- LOGI("name appeared : %s", name);
-}
-
-static void __on_name_vanished(GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
-{
- LOGI("name vanished : %s", name);
- __free_consumer_info(name);
-}
-
-static int __init_changed_noti_consumer_list()
-{
- char *app_id = NULL;
- char *unique_id = NULL;
- char *object_path = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- sqlite3_stmt *stmt = NULL;
- char query[QUERY_MAXLEN];
- datacontrol_consumer_info *consumer_info = NULL;
-
- sqlite3_snprintf(QUERY_MAXLEN, query,
- "SELECT app_id, object_path, unique_id " \
- "FROM data_control_consumer_path_list");
-
- LOGI("__init_changed_noti_consumer_list query : %s", query);
- ret = sqlite3_prepare_v2(__provider_db, query, -1, &stmt, NULL);
- if (ret != SQLITE_OK) {
- LOGE("prepare stmt fail");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- while (SQLITE_ROW == sqlite3_step(stmt)) {
- app_id = (char *)sqlite3_column_text(stmt, 0);
- if (!app_id) {
- LOGE("Failed to get package name\n");
- continue;
- }
-
- object_path = (char *)sqlite3_column_text(stmt, 1);
- if (!object_path) {
- LOGE("Failed to get object_path\n");
- continue;
- }
-
- unique_id = (char *)sqlite3_column_text(stmt, 2);
- if (!unique_id) {
- LOGE("Failed to get unique_id\n");
- continue;
- }
- LOGI("sql : app_id : %s, object_path : %s, unique_id : %s",
- app_id, object_path, unique_id);
-
- consumer_info = (datacontrol_consumer_info *)
- calloc(1, sizeof(datacontrol_consumer_info));
- consumer_info->appid = strdup(app_id);
- consumer_info->object_path = strdup(object_path);
- consumer_info->unique_id = strdup(unique_id);
-
- consumer_info->monitor_id = g_bus_watch_name_on_connection(
- _get_dbus_connection(),
- consumer_info->unique_id,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- __on_name_appeared,
- __on_name_vanished,
- consumer_info,
- NULL);
-
- if (consumer_info->monitor_id == 0) {
- LOGE("g_bus_watch_name_on_connection fail");
-
- free(consumer_info->appid);
- free(consumer_info->object_path);
- free(consumer_info->unique_id);
- free(consumer_info);
- continue;
- }
-
- LOGI("noti consumer_app_list append %s", consumer_info->object_path);
- __noti_consumer_app_list =
- g_list_append(__noti_consumer_app_list, consumer_info);
- }
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
-
- return ret;
-}
-
-static int __create_consumer_list_db()
-{
- char *db_path = NULL;
- int ret = SQLITE_OK;
- int open_flags = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
- char *table_command =
- "CREATE TABLE IF NOT EXISTS data_control_consumer_path_list" \
- "(app_id TEXT NOT NULL, provider_id TEXT NOT NULL, data_id TEXT NOT NULL, " \
- "unique_id TEXT NOT NULL, object_path TEXT NOT NULL, " \
- "PRIMARY KEY(object_path))";
-
- if (__provider_db == NULL) {
- db_path = _get_encoded_db_path();
- if (db_path == NULL)
- return DATACONTROL_ERROR_IO_ERROR;
- LOGI("data-control provider db path : %s", db_path);
-
- ret = sqlite3_open_v2(db_path, &__provider_db, open_flags, NULL);
- free(db_path);
- if (ret != SQLITE_OK) {
- LOGE("database creation failed with error: %d", ret);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- ret = sqlite3_exec(__provider_db, table_command, NULL, NULL, NULL);
- if (ret != SQLITE_OK) {
- LOGE("database table creation failed with error: %d", ret);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- ret = __init_changed_noti_consumer_list();
- if (ret != DATACONTROL_ERROR_NONE) {
- LOGE("__init_changed_noti_consumer_list fail %d", ret);
- return ret;
- }
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-static int __set_consumer_app_list(
- char *caller,
- char *object_path,
- char *unique_id)
-{
- datacontrol_consumer_info find_key;
- datacontrol_consumer_info *consumer_info;
- GList *find_list = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- LOGI("set consumer_app_list caller : %s, path : %s, unique_id : %s",
- caller, object_path, unique_id);
-
- find_key.unique_id = unique_id;
- find_list = g_list_find_custom(__noti_consumer_app_list,
- &find_key,
- (GCompareFunc)__noti_consumer_app_list_compare_cb);
-
- if (!find_list) {
- consumer_info = (datacontrol_consumer_info *)
- calloc(1, sizeof(datacontrol_consumer_info));
- consumer_info->appid = strdup(caller);
- consumer_info->object_path = strdup(object_path);
- consumer_info->unique_id = strdup(unique_id);
-
- consumer_info->monitor_id = g_bus_watch_name_on_connection(
- _get_dbus_connection(),
- consumer_info->unique_id,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- __on_name_appeared,
- __on_name_vanished,
- consumer_info,
- NULL);
- if (consumer_info->monitor_id == 0) {
- LOGE("g_bus_watch_name_on_connection fail");
-
- free(consumer_info->appid);
- free(consumer_info->object_path);
- free(consumer_info->unique_id);
- free(consumer_info);
-
- return DATACONTROL_ERROR_IO_ERROR;
- }
- LOGI("new noti consumer_app_list append %s", consumer_info->object_path);
- __noti_consumer_app_list = g_list_append(__noti_consumer_app_list, consumer_info);
- }
- return ret;
-}
-
-int __provider_process(bundle *b, int fd, const char *consumer_appid)
-{
- int ret;
- int len = 0;
- const char **arg_list = NULL;
- const char **column_list = NULL;
- datacontrol_h provider = NULL;
- int provider_req_id = 0;
- int *key = NULL;
- bool is_map;
- char *provider_id;
- char *caller_appid;
- bundle *value = NULL;
-
- const char *request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
- if (request_type == NULL) {
- LOGE("Invalid data control request");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- /* Get the request type */
- datacontrol_request_type type = atoi(request_type);
- if (type >= DATACONTROL_TYPE_SQL_SELECT && type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
- is_map = false;
- if (provider_sql_cb == NULL) {
- LOGE("SQL callback is not registered.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- } else if (type >= DATACONTROL_TYPE_MAP_GET && type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
- is_map = true;
- if (provider_map_cb == NULL) {
- LOGE("Map callback is not registered.");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- } else {
- LOGE("Invalid request type");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- caller_appid = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
- if (caller_appid && strncmp(caller_appid,
- consumer_appid, strlen(consumer_appid)) != 0) {
- LOGE("The passed appid(%s) is different from the registered appid(%s).",
- caller_appid, consumer_appid);
- return DATACONTROL_ERROR_NONE;
- }
-
- provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
- ret = datacontrol_check_cert(provider_id, is_map, consumer_appid);
- if (ret != DATA_CONTROL_ERROR_NONE) {
- if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
- LOGE("The consumer (%s) is not signed with the same certificate",
- consumer_appid);
- return DATACONTROL_ERROR_NONE;
- } else {
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- arg_list = bundle_get_str_array(b, OSP_K_ARG, &len);
-
- provider = malloc(sizeof(struct datacontrol_s));
- if (provider == NULL) {
- LOGE("Out of memory. fail to alloc provider.");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* Set the provider ID */
- provider->provider_id = provider_id;
-
- /* Set the data ID */
- provider->data_id = (char *)arg_list[PACKET_INDEX_DATAID];
-
- /* Set the request ID */
- provider_req_id = __provider_new_request_id();
-
- LOGI("Provider ID: %s, data ID: %s, request type: %s", provider->provider_id, provider->data_id, request_type);
-
- /* Add the data to the table */
- key = malloc(sizeof(int));
- if (key == NULL) {
- LOGE("Out of memory. fail to malloc key");
- goto err;
- }
- *key = provider_req_id;
-
- value = bundle_dup(b);
- if (value == NULL) {
- LOGE("Fail to dup value");
- goto err;
- }
- g_hash_table_insert(__request_table, key, value);
-
- switch (type) {
- case DATACONTROL_TYPE_SQL_SELECT:
- {
- int i = 1;
- int current = 0;
- int column_count = _get_int_from_str(arg_list[i++]); /* Column count */
-
- if (column_count <= 0 || column_count > MAX_COLUMN_COUNT) {
- LOGE("Invalid column count %d", column_count);
- goto err;
- }
-
- LOGI("SELECT column count: %d", column_count);
- column_list = (const char **)malloc(column_count * (sizeof(char *)));
- if (column_list == NULL) {
- LOGE("Out of memory. Fail to malloc column_list.");
- goto err;
- }
-
- while (current < column_count) {
- column_list[current++] = arg_list[i++]; /* Column data */
- LOGI("Column %d: %s", current, column_list[current-1]);
- }
-
- const char *where = arg_list[i++]; /* where */
- const char *order = arg_list[i++]; /* order */
- LOGI("where: %s, order: %s", where, order);
-
- if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
- where = NULL;
-
- if (strncmp(order, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
- order = NULL;
-
- const char *page_number = arg_list[i++];
- const char *per_page = arg_list[i];
-
- LOGI("page_number: %s, per_page: %s", page_number, per_page);
- bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
- bundle_add_str(value, MAX_COUNT_PER_PAGE, per_page);
- provider_sql_cb->select(provider_req_id, provider, column_list, column_count, where, order, provider_sql_user_data);
- free(column_list);
- break;
- }
- case DATACONTROL_TYPE_SQL_INSERT:
- case DATACONTROL_TYPE_SQL_UPDATE:
- {
- LOGI("INSERT / UPDATE handler");
- bundle *sql = __get_bundle_data_from_fd(fd);
- if (sql == NULL) {
- LOGE("__get_bundle_data_from_fd fail");
- goto err;
- }
- if (type == DATACONTROL_TYPE_SQL_INSERT) {
- provider_sql_cb->insert(provider_req_id, provider, sql, provider_sql_user_data);
- } else {
- const char *where = arg_list[PACKET_INDEX_UPDATEWHERE];
- LOGI("UPDATE from where: %s", where);
- if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
- where = NULL;
- provider_sql_cb->update(provider_req_id, provider, sql, where, provider_sql_user_data);
- }
- bundle_free(sql);
- break;
- }
- case DATACONTROL_TYPE_SQL_BULK_INSERT:
- {
- LOGI("BULK INSERT handler");
- data_control_bulk_data_h data = __get_bulk_data_from_fd(fd);
- if (data == NULL) {
- LOGE("__get_bulk_data_from_fd fail");
- goto err;
- }
-
- provider_sql_cb->bulk_insert(provider_req_id, provider, data, provider_sql_user_data);
-
- LOGI("bulk_insert callback call done");
- datacontrol_bulk_data_destroy(data);
- break;
- }
- case DATACONTROL_TYPE_SQL_DELETE:
- {
- const char *where = arg_list[PACKET_INDEX_DELETEWHERE];
- LOGI("DELETE from where: %s", where);
- if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
- where = NULL;
- provider_sql_cb->delete(provider_req_id, provider, where, provider_sql_user_data);
- break;
- }
- case DATACONTROL_TYPE_MAP_GET:
- {
- const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
- const char *page_number = arg_list[PACKET_INDEX_MAP_PAGE_NO];
- const char *count_per_page = arg_list[PACKET_INDEX_MAP_COUNT_PER_PAGE];
- bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
- bundle_add_str(value, MAX_COUNT_PER_PAGE, count_per_page);
- LOGI("Gets the value list related with the key(%s) from Map datacontrol. ", map_key);
- provider_map_cb->get(provider_req_id, provider, map_key, provider_map_user_data);
- break;
- }
- case DATACONTROL_TYPE_MAP_SET:
- {
- const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
- const char *old_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
- const char *new_value = arg_list[PACKET_INDEX_MAP_VALUE_2ND];
- LOGI("Sets the old value(%s) of the key(%s) to the new value(%s) in Map datacontrol.", old_value, map_key, new_value);
- provider_map_cb->set(provider_req_id, provider, map_key, old_value, new_value, provider_map_user_data);
- break;
- }
- case DATACONTROL_TYPE_MAP_ADD:
- {
- const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
- const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
- LOGI("Adds the %s-%s in Map datacontrol.", map_key, map_value);
- provider_map_cb->add(provider_req_id, provider, map_key, map_value, provider_map_user_data);
- break;
- }
- case DATACONTROL_TYPE_MAP_BULK_ADD:
- {
- LOGI("BULK ADD handler");
- data_control_bulk_data_h data = __get_bulk_data_from_fd(fd);
- if (data == NULL) {
- LOGE("__get_bulk_data_from_fd fail");
- goto err;
- }
-
- provider_map_cb->bulk_add(provider_req_id, provider, data, provider_map_user_data);
- LOGI("bulk_add callback call done");
- datacontrol_bulk_data_destroy(data);
- break;
- }
- case DATACONTROL_TYPE_MAP_REMOVE:
- {
- const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
- const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
- LOGI("Removes the %s-%s in Map datacontrol.", map_key, map_value);
- provider_map_cb->remove(provider_req_id, provider, map_key, map_value, provider_map_user_data);
- break;
- }
- default:
- break;
- }
-
- free(provider);
-
- return DATACONTROL_ERROR_NONE;
-err:
-
- if (provider)
- free(provider);
- if (key)
- free(key);
- if (value)
- bundle_free(value);
-
- return DATACONTROL_ERROR_IO_ERROR;
-}
-
-gboolean __provider_recv_message(GIOChannel *channel,
- GIOCondition cond,
- gpointer data)
-{
- char *buf = NULL;
- int data_len;
- char *consumer_appid = (char *)data;
- guint nb;
-
- gint fd = g_io_channel_unix_get_fd(channel);
- gboolean retval = TRUE;
-
- LOGI("__provider_recv_message : ...from %d:%s%s%s%s\n", fd,
- (cond & G_IO_ERR) ? " ERR" : "",
- (cond & G_IO_HUP) ? " HUP" : "",
- (cond & G_IO_IN) ? " IN" : "",
- (cond & G_IO_PRI) ? " PRI" : "");
-
- if (cond & (G_IO_ERR | G_IO_HUP))
- goto error;
-
- if (cond & G_IO_IN) {
- if (_read_socket(fd, (char *)&data_len, sizeof(data_len), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail : data_len");
- goto error;
- }
-
- LOGI("data_len : %d", data_len);
-
- if (nb == 0) {
- LOGI("__provider_recv_message : ...from %d: EOF\n", fd);
- goto error;
- }
-
- LOGI("__provider_recv_message: ...from %d: %d bytes\n", fd, data_len);
- if (data_len > 0 && data_len < MAX_REQUEST_ARGUMENT_SIZE) {
- bundle *kb = NULL;
-
- buf = (char *)calloc(data_len + 1, sizeof(char));
- if (buf == NULL) {
- LOGE("calloc failed");
- goto error;
- }
-
- if (_read_socket(fd, buf, data_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("read socket fail : data_len\n");
- goto error;
- }
-
- if (nb == 0) {
- LOGI("__provider_recv_message: nb 0 : EOF\n");
- goto error;
- }
-
- kb = bundle_decode_raw((bundle_raw *)buf, data_len);
- if (__provider_process(kb, fd, consumer_appid) != DATACONTROL_ERROR_NONE) {
- bundle_free(kb);
- goto error;
- }
- bundle_free(kb);
- }
- }
- if (buf)
- free(buf);
-
- return retval;
-error:
- if (consumer_appid != NULL)
- g_hash_table_remove(__socket_pair_hash, consumer_appid);
- if (buf)
- free(buf);
-
- return FALSE;
-}
-
-static int __send_add_callback_result(
- datacontrol_data_change_type_e result_type,
- char *unique_id,
- char *path,
- int callback_id,
- int callback_result)
-{
- GError *err = NULL;
- int result = DATACONTROL_ERROR_NONE;
- gboolean signal_result = TRUE;
- LOGI("add callback_result type : %d, callback_id : %d, result : %d",
- result_type, callback_id, callback_result);
-
- signal_result = g_dbus_connection_emit_signal(
- _get_dbus_connection(),
- unique_id,
- path,
- DATA_CONTROL_INTERFACE_NAME,
- DATA_CONTROL_DATA_CHANGE_ADD_REMOVE_RESULT,
- g_variant_new("(iii)",
- result_type,
- callback_id,
- callback_result), &err);
- if (signal_result == FALSE) {
- LOGE("g_dbus_connection_emit_signal() is failed");
- if (err != NULL) {
- LOGE("g_dbus_connection_emit_signal() err : %s",
- err->message);
- g_error_free(err);
- }
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("Send __send_add_callback_result done %d", result);
- return result;
-}
-
-
-static int __get_sender_pid(const char *sender_name)
-{
- GDBusMessage *msg = NULL;
- GDBusMessage *reply = NULL;
- GError *err = NULL;
- GVariant *body;
- int pid = 0;
-
- msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
- "org.freedesktop.DBus", "GetConnectionUnixProcessID");
- if (!msg) {
- LOGE("Can't allocate new method call");
- goto out;
- }
-
- g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
- reply = g_dbus_connection_send_message_with_reply_sync(_get_dbus_connection(), msg,
- G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
-
- if (!reply) {
- if (err != NULL) {
- LOGE("Failed to get pid [%s]", err->message);
- g_error_free(err);
- }
- goto out;
- }
-
- body = g_dbus_message_get_body(reply);
- g_variant_get(body, "(u)", &pid);
-
-out:
- if (msg)
- g_object_unref(msg);
- if (reply)
- g_object_unref(reply);
-
- return pid;
-}
-
-static int __provider_noti_process(bundle *b, datacontrol_request_type type)
-{
- datacontrol_h provider = NULL;
- bool noti_allow = true;
- char *path = NULL;
- int result = DATACONTROL_ERROR_NONE;
- char *unique_id = NULL;
- datacontrol_data_change_type_e result_type = DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT;
- char *callback_id_str = NULL;
- int callback_id = -1;
- GList *filter_iter;
- changed_noti_consumer_filter_info_s *filter_info;
- char caller_app_id[255];
- const char *pid_str;
- int pid;
- int sender_pid;
-
- pid_str = bundle_get_val(b, AUL_K_CALLER_PID);
- if (pid_str == NULL) {
- LOGE("fail to get caller pid");
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- pid = atoi(pid_str);
- if (pid <= 1) {
- LOGE("invalid caller pid %s", pid_str);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
- LOGE("Failed to get appid by pid");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- unique_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_UNIQUE_NAME);
- LOGI("unique_id : %s", unique_id);
- sender_pid = __get_sender_pid(unique_id);
- if (sender_pid != pid) {
- LOGE("invalid unique id. sender does not have unique_id %s", unique_id);
- return DATACONTROL_ERROR_PERMISSION_DENIED;
- }
-
- result = __create_consumer_list_db();
- if (result != DATACONTROL_ERROR_NONE) {
- LOGE("fail to create consumer list db");
- return result;
- }
-
- provider = malloc(sizeof(struct datacontrol_s));
- if (provider == NULL) {
- LOGE("Out of memory. fail to alloc provider.");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
- provider->provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
- provider->data_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_DATA);
- if (provider->provider_id == NULL || provider->data_id == NULL) {
- LOGE("invalid provider value %s, %s", provider->provider_id, provider->data_id);
- free(provider);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Noti Provider ID: %s, data ID: %s, request type: %d", provider->provider_id, provider->data_id, type);
- path = _get_encoded_path(provider, caller_app_id);
- if (path == NULL) {
- LOGE("can not get encoded path out of memory");
- free(provider);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- callback_id_str = (char *)bundle_get_val(b, OSP_K_DATA_CHANGED_CALLBACK_ID);
- if (callback_id_str == NULL) {
- LOGE("callback_id is NULL");
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- callback_id = atoi(callback_id_str);
-
- switch (type) {
- case DATACONTROL_TYPE_ADD_DATA_CHANGED_CB:
- {
- LOGI("DATACONTROL_TYPE_ADD_DATA_CHANGED_CB called");
- result_type = DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT;
- filter_iter = g_list_first(__noti_consumer_filter_info_list);
- for (; filter_iter != NULL; filter_iter = filter_iter->next) {
- filter_info = (changed_noti_consumer_filter_info_s *)filter_iter->data;
- noti_allow = filter_info->callback((data_control_h)provider, caller_app_id, filter_info->user_data);
- if (!noti_allow)
- break;
- }
- LOGI("provider_sql_consumer_filter_cb result %d", noti_allow);
-
- if (noti_allow) {
- result = __insert_consumer_list_db_info(
- caller_app_id,
- provider->provider_id,
- provider->data_id,
- unique_id,
- path);
- if (result != DATACONTROL_ERROR_NONE) {
- LOGE("fail to set consumer list db info %d", result);
- result = DATACONTROL_ERROR_PERMISSION_DENIED;
- break;
- }
-
- result = __set_consumer_app_list(
- caller_app_id,
- path,
- unique_id);
- if (result != DATACONTROL_ERROR_NONE)
- LOGE("fail to __set_consumer_app_list");
-
- } else {
- result = DATACONTROL_ERROR_PERMISSION_DENIED;
- break;
- }
- break;
- }
- case DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB:
- {
- LOGI("DATACONTROL_NOTI_REMOVE_DATA_CHANGED_CB called");
- result_type = DATACONTROL_DATA_CHANGE_CALLBACK_REMOVE_RESULT;
- if (__noti_consumer_app_list) {
- __free_consumer_info(unique_id);
- LOGI("unregister %s from __noti_consumer_app_list", unique_id);
- } else {
- LOGI("empty __consumer_app_list");
- }
- result = __delete_consumer_list_db_info(unique_id);
- if (result != DATACONTROL_ERROR_NONE) {
- LOGE("__delete_consumer_list_db_info fail %d", result);
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- break;
- }
- default:
- break;
- }
-
-out:
- __send_add_callback_result(
- result_type, unique_id, path, callback_id, result);
-
- if (provider)
- free(provider);
- if (path)
- free(path);
-
- return result;
-}
-
-int __datacontrol_handler_cb(bundle *b, int request_id, void *data)
-{
- datacontrol_socket_info *socket_info;
- int ret = DATACONTROL_ERROR_NONE;
- const char *caller;
- const char *callee;
- char *dup_caller;
-
- const char *request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
- if (request_type == NULL) {
- caller = bundle_get_val(b, AUL_K_CALLER_APPID);
- callee = bundle_get_val(b, AUL_K_CALLEE_APPID);
-
- if (caller == NULL) {
- LOGE("Invalid data control request caller is NULL");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- dup_caller = strdup(caller);
- socket_info = g_hash_table_lookup(__socket_pair_hash, dup_caller);
-
- if (socket_info != NULL)
- g_hash_table_remove(__socket_pair_hash, dup_caller);
-
- ret = _add_watch_on_socket_info(dup_caller, callee, "provider",
- NULL, NULL, __provider_recv_message,
- dup_caller, &socket_info);
- if (ret != DATACONTROL_ERROR_NONE)
- return ret;
-
- g_hash_table_insert(__socket_pair_hash, dup_caller, socket_info);
- } else {
- /* Get the request type */
- datacontrol_request_type type = atoi(request_type);
- if (type == DATACONTROL_TYPE_ADD_DATA_CHANGED_CB ||
- type == DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB) {
- __provider_noti_process(b, type);
- } else {
- LOGE("Invalid data control request");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- }
-
- return ret;
-}
-
-bool datacontrol_provider_sql_is_registered()
-{
- return provider_sql_cb == NULL ? false : true;
-}
-
-int datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data)
-{
- int ret = DATACONTROL_ERROR_NONE;
-
- if (callback == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (__request_table == NULL)
- __initialize_provider();
-
- LOGI("datacontrol_provider_sql_register_cb");
-
- provider_sql_cb = callback;
- provider_sql_user_data = user_data;
-
- /* If the provider_map_cb was registered(not NULL), __datacontrol_handler_cb is set already. */
- if (provider_map_cb == NULL)
- ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
-
- return ret;
-}
-
-int datacontrol_provider_sql_unregister_cb(void)
-{
- /* When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible. */
- if (provider_map_cb == NULL)
- aul_unset_data_control_provider_cb();
-
- provider_sql_cb = NULL;
- provider_sql_user_data = NULL;
-
- return DATACONTROL_ERROR_NONE;
-}
-
-bool datacontrol_provider_map_is_registered()
-{
- return provider_map_cb == NULL ? false : true;
-}
-
-int datacontrol_provider_map_register_cb(datacontrol_provider_map_cb *callback, void *user_data)
-{
- int ret = DATACONTROL_ERROR_NONE;
-
- if (callback == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (__request_table == NULL)
- __initialize_provider();
-
- LOGI("datacontrol_provider_map_register_cb");
-
- provider_map_cb = callback;
- provider_map_user_data = user_data;
-
- /* If the provider_sql_cb was registered(not NULL), __datacontrol_handler_cb is set already. */
- if (provider_sql_cb == NULL)
- ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
-
- return ret;
-}
-
-int datacontrol_provider_map_unregister_cb(void)
-{
- /* When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible. */
- if (provider_sql_cb == NULL)
- aul_unset_data_control_provider_cb();
-
- provider_map_cb = NULL;
- provider_map_user_data = NULL;
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_provider_get_client_appid(int request_id, char **appid)
-{
- const char *caller;
- bundle *b;
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- caller = bundle_get_val(b, AUL_K_CALLER_APPID);
- if (!caller) {
- LOGE("No appid for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Request ID: %d, caller appid: %s", request_id, caller);
-
- *appid = strdup(caller);
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_provider_write_socket(int fd, void *buffer, unsigned int nbytes,
- unsigned int *bytes_write)
-{
- int ret = _write_socket(fd, buffer, nbytes, bytes_write);
- return ret;
-}
-
-int datacontrol_provider_send_select_result_without_data(int request_id, int *fd)
-{
- int ret;
- bundle *res;
- bundle *b;
- datacontrol_socket_info *socket_info;
- char *caller_app_id;
-
- LOGI("Send select result by byte array for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, NULL);
- ret = __send_result(res, DATACONTROL_TYPE_UNDEFINED, NULL);
- bundle_free(res);
-
- caller_app_id = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
- socket_info = g_hash_table_lookup(__socket_pair_hash, caller_app_id);
- if (socket_info == NULL) {
- LOGE("__socket_pair_hash lookup fail");
- return DATACONTROL_ERROR_IO_ERROR;
- }
- *fd = socket_info->socket_fd;
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_get_select_page_info(int request_id, int *page_num, int *count_per_page)
-{
- bundle *b;
- const char *page_num_str;
- const char *count_per_page_str;
-
- if (__request_table == NULL) {
- LOGE("__request_table is NULL");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- page_num_str = bundle_get_val(b, RESULT_PAGE_NUMBER);
- count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE);
- if (page_num_str == NULL || count_per_page_str == NULL) {
- LOGE("No page data for the request id: %d, ", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- *page_num = _get_int_from_str(page_num_str);
- *count_per_page = _get_int_from_str(count_per_page_str);
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_provider_send_bulk_insert_result(int request_id, data_control_bulk_result_data_h bulk_result_data)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send an insert result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- res = __set_result(b, DATACONTROL_TYPE_SQL_BULK_INSERT, NULL);
- ret = __send_result(res, DATACONTROL_TYPE_SQL_BULK_INSERT, (void *)bulk_result_data);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_send_select_result(int request_id, void *db_handle)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send a select result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, db_handle);
- ret = __send_result(res, DATACONTROL_TYPE_SQL_SELECT, db_handle);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_send_insert_result(int request_id, long long row_id)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send an insert result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- res = __set_result(b, DATACONTROL_TYPE_SQL_INSERT, (void *)&row_id);
-
- ret = __send_result(res, DATACONTROL_TYPE_SQL_INSERT, NULL);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-
-}
-
-int datacontrol_provider_send_update_result(int request_id)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send an update result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- res = __set_result(b, DATACONTROL_TYPE_SQL_UPDATE, NULL);
-
- ret = __send_result(res, DATACONTROL_TYPE_SQL_UPDATE, NULL);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_send_delete_result(int request_id)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send a delete result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- res = __set_result(b, DATACONTROL_TYPE_SQL_DELETE, NULL);
-
- ret = __send_result(res, DATACONTROL_TYPE_SQL_DELETE, NULL);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_send_error(int request_id, const char *error)
-{
- bundle *res;
- bundle *b;
- int ret;
-
- LOGI("Send an error for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- res = __set_result(b, DATACONTROL_TYPE_ERROR, (void *)error);
- ret = __send_result(res, DATACONTROL_TYPE_ERROR, NULL);
- bundle_free(res);
-
- return ret;
-}
-
-
-int datacontrol_provider_send_map_bulk_add_result(int request_id, data_control_bulk_result_data_h bulk_result_data)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send bulk add result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- res = __set_result(b, DATACONTROL_TYPE_MAP_BULK_ADD, NULL);
- ret = __send_result(res, DATACONTROL_TYPE_MAP_BULK_ADD, (void *)bulk_result_data);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_send_map_result(int request_id)
-{
- int ret;
- bundle *res;
- bundle *b;
-
- LOGI("Send a set/add/remove result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- res = __set_result(b, DATACONTROL_TYPE_UNDEFINED, NULL);
-
- ret = __send_result(res, DATACONTROL_TYPE_UNDEFINED, NULL);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-int datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count)
-{
- int ret;
- char value_count_str[32];
- bundle *b;
- bundle *res;
-
- LOGI("Send a get result for request id: %d", request_id);
-
- if (__request_table == NULL)
- __initialize_provider();
-
- b = g_hash_table_lookup(__request_table, &request_id);
- if (!b) {
- LOGE("No data for the request id: %d", request_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- snprintf(value_count_str, 32, "%d", value_count);
- bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str);
-
- res = __set_result(b, DATACONTROL_TYPE_MAP_GET, value_list);
-
- ret = __send_result(res, DATACONTROL_TYPE_MAP_GET, value_list);
- bundle_free(res);
- g_hash_table_remove(__request_table, &request_id);
-
- return ret;
-}
-
-static int __send_signal_to_consumer(datacontrol_h provider,
- char *unique_id,
- char *path,
- datacontrol_data_change_type_e type,
- bundle *data)
-{
- int result = DATACONTROL_ERROR_NONE;
- int len = 0;
- bundle_raw *raw = NULL;
- GError *err = NULL;
- gboolean signal_result = TRUE;
-
- if (data) {
- if (bundle_encode(data, &raw, &len) != BUNDLE_ERROR_NONE) {
- LOGE("bundle_encode fail");
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- }
-
- LOGI("emit signal to object path %s", path);
- signal_result = g_dbus_connection_emit_signal(
- _get_dbus_connection(),
- unique_id,
- path,
- DATA_CONTROL_INTERFACE_NAME,
- DATA_CONTROL_DATA_CHANGE_DATA_CHANGED,
- g_variant_new("(isssi)",
- type,
- provider->provider_id,
- provider->data_id,
- ((raw) ? (char *)raw : ""),
- len), &err);
-
- if (signal_result == FALSE) {
- LOGE("g_dbus_connection_emit_signal() is failed");
- if (err != NULL) {
- LOGE("g_dbus_connection_emit_signal() err : %s",
- err->message);
- g_error_free(err);
- }
- result = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
-out:
- if (raw)
- free(raw);
-
- return result;
-}
-
-static int __check_consumer_cert(const char *provider_id,
- const char *consumer_appid,
- datacontrol_data_change_type_e type)
-{
- bool is_map;
-
- if (consumer_appid == NULL)
- return DATACONTROL_ERROR_IO_ERROR;
-
- if (type >= DATACONTROL_DATA_CHANGE_SQL_UPDATE &&
- type <= DATACONTROL_DATA_CHANGE_SQL_DELETE)
- is_map = false;
- else
- is_map = true;
-
- return datacontrol_check_cert(provider_id, is_map, consumer_appid);
-}
-
-int datacontrol_provider_send_data_change_noti(
- datacontrol_h provider,
- datacontrol_data_change_type_e type,
- bundle *data)
-{
- int result = DATACONTROL_ERROR_NONE;
- GList *consumer_iter = NULL;
- datacontrol_consumer_info *consumer_info = NULL;
-
- LOGE("datacontrol_provider_send_data_change_noti %d, %d", g_list_length(__noti_consumer_app_list), type);
- consumer_iter = g_list_first(__noti_consumer_app_list);
- for (; consumer_iter != NULL; consumer_iter = consumer_iter->next) {
- consumer_info = (datacontrol_consumer_info *)consumer_iter->data;
- if (__check_consumer_cert(provider->provider_id,
- consumer_info->appid,
- type) != DATACONTROL_ERROR_NONE)
- continue;
- result = __send_signal_to_consumer(
- provider,
- consumer_info->unique_id,
- consumer_info->object_path,
- type,
- data);
- if (result != DATACONTROL_ERROR_NONE) {
- LOGE("__send_signal_to_consumer fail : %d", result);
- break;
- }
- }
- return result;
-}
-
-int datacontrol_provider_add_data_change_consumer_filter_cb(
- data_control_provider_data_change_consumer_filter_cb callback,
- void *user_data,
- int *callback_id)
-{
- changed_noti_consumer_filter_info_s *filter_info = (changed_noti_consumer_filter_info_s *)calloc(1,
- sizeof(changed_noti_consumer_filter_info_s));
-
- *callback_id = _datacontrol_get_data_changed_filter_callback_id();
-
- filter_info->callback_id = *callback_id;
- filter_info->callback = callback;
- filter_info->user_data = user_data;
- __noti_consumer_filter_info_list = g_list_append(__noti_consumer_filter_info_list, filter_info);
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_provider_remove_data_change_consumer_filter_cb(int callback_id)
-{
- GList *find_list;
- changed_noti_consumer_filter_info_s filter_info;
- changed_noti_consumer_filter_info_s *temp;
-
- filter_info.callback_id = callback_id;
- find_list = g_list_find_custom(__noti_consumer_filter_info_list, &filter_info,
- (GCompareFunc)__data_changed_filter_cb_info_compare_cb);
- if (find_list != NULL) {
- temp = (changed_noti_consumer_filter_info_s *)find_list->data;
- __noti_consumer_filter_info_list = g_list_remove(__noti_consumer_filter_info_list, find_list->data);
- free(temp);
- } else {
- LOGE("invalid callback_id : %d", callback_id);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_provider_foreach_data_change_consumer(
- datacontrol_h provider,
- data_control_provider_data_change_consumer_cb list_cb,
- void *user_data)
-{
- char *app_id = NULL;
- char *unique_id = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- sqlite3_stmt *stmt = NULL;
- char query[QUERY_MAXLEN];
- bool callback_result;
- data_control_provider_data_change_consumer_cb consumer_list_cb;
- consumer_list_cb = list_cb;
-
- sqlite3_snprintf(QUERY_MAXLEN, query,
- "SELECT app_id, unique_id " \
- "FROM data_control_consumer_path_list WHERE provider_id = ? AND data_id = ?");
- LOGI("get_changed_noti_consumer_list query : %s", query);
-
- ret = sqlite3_prepare_v2(__provider_db, query, -1, &stmt, NULL);
- if (ret != SQLITE_OK) {
- LOGE("prepare stmt fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- ret = sqlite3_bind_text(stmt, 1, provider->provider_id, -1, SQLITE_TRANSIENT);
- if (ret != SQLITE_OK) {
- LOGE("bind provider id fail: %s", sqlite3_errmsg(__provider_db));
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- ret = sqlite3_bind_text(stmt, 2, provider->data_id, -1, SQLITE_TRANSIENT);
- if (ret != SQLITE_OK) {
- LOGE("bind data id fail: %s", sqlite3_errmsg(__provider_db));
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- while (SQLITE_ROW == sqlite3_step(stmt)) {
-
- app_id = (char *)sqlite3_column_text(stmt, 0);
- if (!app_id) {
- LOGE("Failed to get package name\n");
- continue;
- }
- unique_id = (char *)sqlite3_column_text(stmt, 1);
- callback_result = consumer_list_cb((data_control_h)provider, app_id, user_data);
- LOGI("app_id : %s, unique_id : %s, result : %d ", app_id, unique_id, callback_result);
- if (!callback_result)
- break;
- }
-out:
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
- sqlite3_finalize(stmt);
- }
-
- return ret;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _GNU_SOURCE
-
-#include <dlog.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-#include "data-control-sql-cursor.h"
-#include "data-control-internal.h"
-
-#undef LOG_TAG
-#ifndef LOG_TAG
-#define LOG_TAG "DATA_CONTROL"
-#endif
-
-#define ERR_BUFFER_SIZE 1024
-
-resultset_cursor *datacontrol_sql_get_cursor()
-{
- resultset_cursor *cursor = (resultset_cursor *)calloc(1, sizeof(resultset_cursor));
- if (!cursor) {
- LOGE("unable to create cursor");
- return NULL;
- }
- return cursor;
-
-}
-
-int datacontrol_sql_step_next(resultset_cursor *cursor)
-{
- if (cursor == NULL || cursor->resultset_row_count == 0) {
- LOGE("Reached to the end of the result set");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (cursor->resultset_current_offset == 0) {
- cursor->resultset_current_offset = cursor->resultset_content_offset;
- } else {
- if (!(cursor->resultset_current_row_count < (cursor->resultset_row_count - 1))) {
- LOGE("Reached to the end of the result set");
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- cursor->resultset_current_offset =
- cursor->row_offset_list[cursor->resultset_current_row_count + 1];
- cursor->resultset_current_row_count++;
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_step_last(resultset_cursor *cursor)
-{
- int ret = 0;
- int i = 0;
-
- if (cursor->resultset_current_row_count == (cursor->resultset_row_count - 1))
- return DATACONTROL_ERROR_NONE; /* Already @ last row */
-
- if (!cursor->row_offset_list) {
- ret = datacontrol_sql_step_next(cursor); /* make a first move */
- if (ret != DATACONTROL_ERROR_NONE)
- return ret;
- }
-
- /* check if the rowOffsetList contains last row offset */
- if (cursor->row_offset_list && cursor->row_offset_list[cursor->resultset_row_count - 1] != 0) {
- cursor->resultset_current_offset = cursor->row_offset_list[cursor->resultset_row_count - 1];
- cursor->resultset_current_row_count = cursor->resultset_row_count - 1;
- } else {
- /* Move till last row offset. */
- for (i = (cursor->resultset_current_row_count + 1); i < cursor->resultset_row_count; i++) {
- ret = datacontrol_sql_step_next(cursor); /* move till last row data offset */
- if (ret != DATACONTROL_ERROR_NONE)
- return ret;
- }
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_step_first(resultset_cursor *cursor)
-{
- if (cursor->resultset_current_offset > 0) {
- cursor->resultset_current_offset = cursor->resultset_content_offset;
- cursor->resultset_current_row_count = 0;
- return DATACONTROL_ERROR_NONE;
- }
-
- /* MoveFirst is called for the first time before MoveNext() or MoveLast() */
- cursor->resultset_current_offset = 0;
- return datacontrol_sql_step_next(cursor);
-}
-
-int datacontrol_sql_step_previous(resultset_cursor *cursor)
-{
- if ((cursor->resultset_current_row_count - 1) < 0) {
- LOGE("invalid request");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
- cursor->resultset_current_offset = cursor->row_offset_list[cursor->resultset_current_row_count - 1];
- cursor->resultset_current_row_count--;
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_get_column_count(resultset_cursor *cursor)
-{
- return cursor->resultset_col_count;
-}
-
-int datacontrol_sql_get_column_name(resultset_cursor *cursor, int column_index, char *name)
-{
- char *col_name = NULL;
- int i = 0;
- int ret = 0;
- int column_len = 0;
- int fd = cursor->resultset_fd;
- char err_buf[ERR_BUFFER_SIZE];
-
- ret = lseek(fd, cursor->resultset_col_name_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %d %s", cursor->resultset_current_offset,
- strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- for (i = 0; i < column_index + 1; i++) {
- ret = read(fd, &column_len, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read column_len: %d", column_len);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (column_len < 0 || column_len > MAX_COLUMN_SIZE) {
- LOGE("Invalid column_len: %d", column_len);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (i == column_index) {
- col_name = (char *)calloc(column_len, sizeof(char));
- ret = read(fd, col_name, column_len);
- if (ret == 0) {
- LOGE("unable to read col_name : %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- free(col_name);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- } else {
- ret = lseek(fd, column_len, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
- }
- memset(name, 0, column_len);
- memcpy(name, col_name, column_len);
- free(col_name);
- LOGI("The column name is %s", name);
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_get_column_item_size(resultset_cursor *cursor, int column_index)
-{
- int type = -1;
- int size = 0;
- int i = 0;
- int ret = 0;
- char err_buf[ERR_BUFFER_SIZE];
- int fd = cursor->resultset_fd;
-
- ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %d %s", cursor->resultset_current_offset,
- strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* move to column index */
- for (i = 0; i < column_index; i++) {
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = lseek(fd, size, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- return size;
-}
-
-int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_index,
- datacontrol_sql_column_type *col_type)
-{
- int type = -1;
- int i = 0;
- int size = 0;
- int ret = 0;
- char err_buf[ERR_BUFFER_SIZE];
- int fd = cursor->resultset_fd;
-
- ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* move to column index */
- for (i = 0; i < column_index; i++) {
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = lseek(fd, size, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- switch (type) {
- case DATACONTROL_SQL_COLUMN_TYPE_INT64:
- *col_type = DATACONTROL_SQL_COLUMN_TYPE_INT64;
- break;
- case DATACONTROL_SQL_COLUMN_TYPE_DOUBLE:
- *col_type = DATACONTROL_SQL_COLUMN_TYPE_DOUBLE;
- break;
- case DATACONTROL_SQL_COLUMN_TYPE_TEXT:
- *col_type = DATACONTROL_SQL_COLUMN_TYPE_TEXT;
- break;
- case DATACONTROL_SQL_COLUMN_TYPE_BLOB:
- *col_type = DATACONTROL_SQL_COLUMN_TYPE_BLOB;
- break;
- case DATACONTROL_SQL_COLUMN_TYPE_NULL:
- *col_type = DATACONTROL_SQL_COLUMN_TYPE_NULL;
- break;
- default:
- *col_type = DATACONTROL_SQL_COLUMN_TYPE_UNDEFINED;
- break;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_get_blob_data(resultset_cursor *cursor, int column_index, void *buffer, int data_size)
-{
- int type = -1;
- int size = 0;
- int i = 0;
- int ret = 0;
- char err_buf[ERR_BUFFER_SIZE];
- int fd = cursor->resultset_fd;
- char *data;
-
- ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* move to column index */
- for (i = 0; i < column_index; i++) {
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = lseek(fd, size, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_BLOB) {
- LOGE("type mismatch: requested for BLOB type but %d present:", type);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read size in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (size > data_size) {
- LOGE("size is more than the size requested");
- return DATACONTROL_ERROR_MAX_EXCEEDED; /* overflow */
- }
-
- if (size > 0 && size < MAX_REQUEST_ARGUMENT_SIZE) {
- data = (char *)malloc((size + 1) * (sizeof(char)));
- memset(data, 0, size + 1);
-
- ret = read(fd, data, size);
- if (ret < size) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- free(data);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- memcpy(buffer, data, size + 1);
- free(data);
- } else {
- LOGE("Invalid size %d", size);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_get_int_data(resultset_cursor *cursor, int column_index, int *data)
-{
- long long long_value = 0;
- int ret = -1;
-
- ret = datacontrol_sql_get_int64_data(cursor, column_index, &long_value);
- if (ret == 0)
- *data = (int) long_value;
-
- return ret;
-}
-
-int datacontrol_sql_get_int64_data(resultset_cursor *cursor, int column_index, long long *data)
-{
- int type = -1;
- int size = 0;
- int i = 0;
- int ret = 0;
- char err_buf[ERR_BUFFER_SIZE];
- int fd = cursor->resultset_fd;
-
- ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* move to column index */
- for (i = 0; i < column_index; i++) {
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = lseek(fd, size, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_INT64) {
- LOGE("type mismatch: requested for int type but %d present:", type);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, data, size);
- if (ret < size) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_get_double_data(resultset_cursor *cursor, int column_index, double *data)
-{
- int type = -1;
- int size = 0;
- int i = 0;
- int ret = 0;
- char err_buf[ERR_BUFFER_SIZE];
- int fd = cursor->resultset_fd;
-
- ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* move to column index */
- for (i = 0; i < column_index; i++) {
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = lseek(fd, size, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_DOUBLE) {
- LOGE("type mismatch: requested for double type but %d present:", type);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, data, size);
- if (ret < size) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-
-int datacontrol_sql_get_text_data(resultset_cursor *cursor, int column_index, char *buffer)
-{
- int type = -1;
- int size = 0;
- int i = 0;
- int ret = 0;
- char err_buf[ERR_BUFFER_SIZE];
- int fd = cursor->resultset_fd;
- char *data;
-
- ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- /* move to column index */
- for (i = 0; i < column_index; i++) {
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- ret = lseek(fd, size, SEEK_CUR);
- if (ret < 0) {
- LOGE("unable to seek in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
-
- ret = read(fd, &type, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_TEXT) {
- LOGE("type mismatch: requested for text type but %d present %d", type,
- cursor->resultset_current_offset);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- ret = read(fd, &size, sizeof(int));
- if (ret == 0) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- if (size > 0 && size < MAX_REQUEST_ARGUMENT_SIZE) {
- data = (char *)malloc((size + 1) * (sizeof(char)));
- if (!data) {
- LOGE("unable to create buffer to read");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- memset(data, 0, size + 1);
- ret = read(fd, data, size);
- if (ret < size) {
- LOGE("unable to read in the resultset file: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
- free(data);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- memcpy(buffer, data, size + 1);
- free(data);
- } else {
- LOGE("Invalid size %d", size);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- return DATACONTROL_ERROR_NONE;
-}
-
-int datacontrol_sql_remove_cursor(resultset_cursor *cursor)
-{
- int ret;
-
- if (cursor == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- close(cursor->resultset_fd);
- if (cursor->resultset_path) {
- ret = remove(cursor->resultset_path);
- if (ret == -1)
- LOGE("unable to remove map query result file: %d", ret);
- free(cursor->resultset_path);
- }
- if (cursor->row_offset_list)
- free(cursor->row_offset_list);
- free(cursor);
-
- return DATACONTROL_ERROR_NONE;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <dlog.h>
-#include <errno.h>
-#include <search.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <glib.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <gio/gio.h>
-
-#include <sys/socket.h>
-
-#include <appsvc/appsvc.h>
-#include <aul/aul.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <pkgmgr-info.h>
-
-#include "data-control-sql.h"
-#include "data-control-internal.h"
-#include "data-control-bulk.h"
-
-#define REQUEST_PATH_MAX 512
-
-typedef struct {
- char *provider_id;
- char *app_id;
- char *data_id;
- char *access_info;
- void *user_data;
- GList *request_info_list;
- datacontrol_sql_response_cb *sql_response_cb;
-} sql_response_cb_s;
-
-static void *datacontrol_sql_tree_root = NULL;
-static GHashTable *__socket_pair_hash = NULL;
-static int __recv_sql_select_process(bundle *kb, int fd,
- resultset_cursor *cursor);
-static int __recv_sql_bulk_insert_process(int fd, data_control_bulk_result_data_h *result_data_h);
-
-static void __sql_call_cb(const char *provider_id, int request_id,
- datacontrol_request_type type, const char *data_id,
- bool provider_result, const char *error, long long insert_rowid,
- resultset_cursor *cursor, data_control_bulk_result_data_h bulk_results, void *data)
-{
- datacontrol_sql_response_cb *callback = NULL;
- sql_response_cb_s *sql_dc;
- datacontrol_h provider;
-
- LOGI("__sql_call_cb, dataID !!!: %s", data_id);
-
- sql_dc = (sql_response_cb_s *)data;
- callback = sql_dc->sql_response_cb;
- if (!callback) {
- LOGE("no listener set");
- return;
- }
-
- datacontrol_sql_create(&provider);
- datacontrol_sql_set_provider_id(provider, provider_id);
- datacontrol_sql_set_data_id(provider, data_id);
-
- switch (type) {
- case DATACONTROL_TYPE_SQL_BULK_INSERT:
- LOGI("BULK INSERT");
- if (callback != NULL && callback->bulk_insert != NULL)
- callback->bulk_insert(request_id, provider, bulk_results, provider_result, error, sql_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_SQL_SELECT:
- LOGI("SELECT");
- if (callback != NULL && callback->select != NULL)
- callback->select(request_id, provider, cursor, provider_result, error, sql_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_SQL_INSERT:
- LOGI("INSERT row_id: %lld", insert_rowid);
- if (callback != NULL && callback->insert != NULL)
- callback->insert(request_id, provider, insert_rowid, provider_result, error, sql_dc->user_data);
- else
- LOGI("No registered callback function");
-
- break;
- case DATACONTROL_TYPE_SQL_UPDATE:
- LOGI("UPDATE");
- if (callback != NULL && callback->update != NULL)
- callback->update(request_id, provider, provider_result, error, sql_dc->user_data);
- else
- LOGI("No registered callback function");
- break;
- case DATACONTROL_TYPE_SQL_DELETE:
- LOGI("DELETE");
- if (callback != NULL && callback->delete != NULL)
- callback->delete(request_id, provider, provider_result, error, sql_dc->user_data);
- else
- LOGI("No registered callback function");
- break;
- default:
- break;
- }
-
- datacontrol_sql_destroy(provider);
-}
-
-static void __sql_instance_free(void *datacontrol_sql_instance)
-{
- sql_response_cb_s *dc = (sql_response_cb_s *)datacontrol_sql_instance;
- if (dc) {
- free(dc->provider_id);
- free(dc->data_id);
- free(dc->app_id);
- free(dc->access_info);
- free(datacontrol_sql_instance);
- }
-
- return;
-}
-
-static int __sql_instance_compare(const void *l_datacontrol_sql_instance, const void *r_datacontrol_sql_instance)
-{
- sql_response_cb_s *dc_left = (sql_response_cb_s *)l_datacontrol_sql_instance;
- sql_response_cb_s *dc_right = (sql_response_cb_s *)r_datacontrol_sql_instance;
- return strcmp(dc_left->provider_id, dc_right->provider_id);
-}
-
-static void __remove_sql_request_info(int request_id, sql_response_cb_s *sql_dc)
-{
-
- datacontrol_consumer_request_info temp_request_info;
- datacontrol_consumer_request_info *temp_data;
-
- temp_request_info.request_id = request_id;
- GList *list = g_list_find_custom(sql_dc->request_info_list, &temp_request_info,
- (GCompareFunc)_consumer_request_compare_cb);
- if (list != NULL) {
- temp_data = (datacontrol_consumer_request_info *)list->data;
- sql_dc->request_info_list = g_list_remove(sql_dc->request_info_list, list->data);
- free(temp_data);
- }
-
-}
-
-static int __sql_handle_cb(bundle *b, void *data, int fd, int request_id)
-{
- resultset_cursor *cursor = NULL;
- int ret = 0;
- const char **result_list = NULL;
- const char *provider_id = NULL;
- const char *data_id = NULL;
- const char *error_message = NULL;
- long long insert_rowid = -1;
- datacontrol_request_type request_type = 0;
- int result_list_len = 0;
- int provider_result = 0;
- const char *p = NULL;
- data_control_bulk_result_data_h bulk_results = NULL;
-
- if (b) {
- /* result list */
- result_list = appsvc_get_data_array(b, OSP_K_ARG, &result_list_len);
- if (!result_list) {
- LOGE("Invalid Bundle: arguement list is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- p = result_list[0]; /* result list[0] = provider_result */
- if (!p) {
- LOGE("Invalid Bundle: provider_result is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Provider result: %s", p);
-
- provider_result = atoi(p);
-
- error_message = result_list[1]; /* result list[1] = error */
- if (!error_message) {
- LOGE("Invalid Bundle: error_message is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Error message: %s", error_message);
-
- p = appsvc_get_data(b, OSP_K_DATACONTROL_REQUEST_TYPE);
- if (!p) {
- LOGE("Invalid Bundle: data-control request type is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- request_type = (datacontrol_request_type)atoi(p);
-
- provider_id = appsvc_get_data(b, OSP_K_DATACONTROL_PROVIDER);
- if (!provider_id) {
- LOGE("Invalid Bundle: provider_id is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- data_id = appsvc_get_data(b, OSP_K_DATACONTROL_DATA);
- if (!data_id) {
- LOGE("Invalid Bundle: data_id is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type);
- switch (request_type) {
- case DATACONTROL_TYPE_SQL_BULK_INSERT:
- LOGI("BULK INSERT RESPONSE");
- if (provider_result) {
- if (__recv_sql_bulk_insert_process(fd, &bulk_results)
- != DATACONTROL_ERROR_NONE) {
- if (bulk_results)
- datacontrol_bulk_result_data_destroy(bulk_results);
-
- return DATACONTROL_ERROR_IO_ERROR;
- }
- }
- break;
- case DATACONTROL_TYPE_SQL_SELECT:
- if (provider_result) {
- cursor = datacontrol_sql_get_cursor();
- if (!cursor) {
- LOGE("failed to get cursor on sql query resultset");
- return DATACONTROL_ERROR_IO_ERROR;
- }
- if (__recv_sql_select_process(b, fd, cursor)
- != DATACONTROL_ERROR_NONE)
- return DATACONTROL_ERROR_IO_ERROR;
- }
- break;
- case DATACONTROL_TYPE_SQL_INSERT:
- LOGI("INSERT RESPONSE");
- if (provider_result) {
- p = result_list[2]; /* result list[2] */
- if (!p) {
- LOGE("Invalid Bundle: insert row_id is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- insert_rowid = atoll(p);
- }
- break;
- case DATACONTROL_TYPE_SQL_UPDATE:
- case DATACONTROL_TYPE_SQL_DELETE:
- LOGI("UPDATE or DELETE RESPONSE");
- break;
- default:
- break;
- }
-
- } else {
- LOGE("the bundle returned from datacontrol-provider-service is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (request_type >= DATACONTROL_TYPE_SQL_SELECT &&
- request_type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
- __sql_call_cb(
- provider_id,
- request_id,
- request_type,
- data_id,
- provider_result,
- error_message,
- insert_rowid,
- cursor,
- bulk_results,
- data);
- if ((request_type == DATACONTROL_TYPE_SQL_SELECT) && (cursor))
- datacontrol_sql_remove_cursor(cursor);
- ret = DATACONTROL_ERROR_NONE;
- } else {
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (bulk_results)
- datacontrol_bulk_result_data_destroy(bulk_results);
-
- return ret;
-}
-
-static int __recv_sql_bulk_insert_process(int fd, data_control_bulk_result_data_h *result_data_h)
-{
- int bulk_results_size;
- guint nb;
- int retval = DATACONTROL_ERROR_NONE;
- int i;
- int bulk_result = 0;
- char *encode_data = NULL;
- int encode_datalen = 0;
- bundle *result_data = NULL;
-
- datacontrol_bulk_result_data_create(result_data_h);
- if (_read_socket(fd, (char *)&bulk_results_size, sizeof(bulk_results_size), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: bulk_results_size");
- goto out;
- }
-
- LOGI("##### bulk result size : %d", bulk_results_size);
- for (i = 0; i < bulk_results_size; i++) {
- if (_read_socket(fd, (char *)&bulk_result, sizeof(bulk_result), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: bulk_result");
- goto out;
- }
- LOGI("##### bulk result : %d", bulk_result);
- if (_read_socket(fd, (char *)&encode_datalen, sizeof(encode_datalen), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: encode_datalen");
- goto out;
- }
- LOGI("##### encode_datalen : %d", encode_datalen);
- if (encode_datalen <= 0 || encode_datalen >= MAX_REQUEST_ARGUMENT_SIZE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("Invalid encode_datalen %d", encode_datalen);
- goto out;
- }
- encode_data = (char *)calloc(encode_datalen, sizeof(char));
- if (encode_data == NULL) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("FAIL to alloc encode data");
- goto out;
- }
- if (_read_socket(fd, encode_data, encode_datalen, &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: encode_data");
- free(encode_data);
- goto out;
- }
- result_data = bundle_decode_raw((bundle_raw *)encode_data, encode_datalen);
- datacontrol_bulk_result_data_add(*result_data_h, result_data, bulk_result);
- if (encode_data) {
- free(encode_data);
- encode_data = NULL;
- }
- bundle_free(result_data);
- }
-
-out:
- return retval;
-}
-
-static int __recv_sql_select_process(bundle *kb, int fd, resultset_cursor *cursor)
-{
- int column_count = 0;
- int column_type = 0;
- int column_name_len = 0;
- char *column_name = NULL;
- int total_len_of_column_names = 0;
- sqlite3_int64 row_count = 0;
- int type;
- int size;
- void *value = NULL;
- sqlite3_int64 i = 0;
- int j = 0;
- char select_map_file[REQUEST_PATH_MAX] = {0,};
- char *req_id = (char *)bundle_get_val(kb, OSP_K_REQUEST_ID);
- int result_fd = 0;
- guint nb;
- int retval = DATACONTROL_ERROR_NONE;
-
- LOGI("req_id : %s", req_id);
- LOGI("SELECT RESPONSE");
-
- size = snprintf(select_map_file, REQUEST_PATH_MAX, "/run/user/%d/%s%s%s", getuid(), DATACONTROL_REQUEST_FILE_PREFIX,
- (char *)bundle_get_val(kb, AUL_K_CALLER_APPID), req_id);
- if (size < 0) {
- LOGE("unable to write formatted output to select_map_file. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- LOGI("select_map_file : %s", select_map_file);
-
- /* TODO - shoud be changed to solve security concerns */
- result_fd = open(select_map_file, O_RDWR | O_CREAT, 0644);
- if (result_fd == -1) {
- LOGE("unable to open insert_map file: %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
-
- }
- cursor->resultset_path = strdup(select_map_file);
- if (cursor->resultset_path == NULL) {
- LOGE("Out of memory. can not dup select map file.");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- cursor->resultset_fd = result_fd;
- if (_read_socket(fd, (char *)&column_count, sizeof(column_count), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: column_count");
- goto out;
- }
-
- /* no data check. */
- if (column_count == DATACONTROL_RESULT_NO_DATA) {
- LOGE("No result");
- close(result_fd);
- return DATACONTROL_ERROR_NONE;
- }
-
- if (column_count < 0 || column_name_len > MAX_COLUMN_COUNT) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("Invalid column_count %d", column_count);
- goto out;
- }
-
- cursor->resultset_col_count = column_count;
- LOGI("column_count : %d", column_count);
-
- if (write(result_fd, &column_count, sizeof(int)) == -1) {
- LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- cursor->resultset_col_type_offset = sizeof(int);
- for (i = 0; i < column_count; i++) {
- if (_read_socket(fd, (char *)&column_type, sizeof(column_type), &nb) != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: column_type");
- goto out;
- }
-
- LOGE("column_type : %d", column_type);
- if (write(result_fd, &column_type, sizeof(int)) == -1) {
- LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
-
- }
- }
-
- cursor->resultset_col_name_offset = cursor->resultset_col_type_offset +
- (cursor->resultset_col_count) * sizeof(int);
- for (i = 0; i < column_count; i++) {
-
- if (_read_socket(fd, (char *)&column_name_len, sizeof(column_name_len), &nb)
- != DATACONTROL_ERROR_NONE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("read socket fail: column_name_len");
- goto out;
- }
-
- if (column_name_len < 0 || column_name_len > MAX_COLUMN_SIZE) {
- retval = DATACONTROL_ERROR_IO_ERROR;
- LOGE("Invalid column_name_len %d", column_name_len);
- goto out;
- }
-
- LOGE("column_name_len : %d", column_name_len);
- if (write(result_fd, &column_name_len, sizeof(int)) == -1) {
- LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- column_name = (char *)calloc(column_name_len, sizeof(char));
- if (column_name == NULL) {
- LOGE("Out of memory.");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- if (_read_socket(fd, (char *)column_name, column_name_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail: column_name");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- LOGE("column_name read : %d", nb);
- LOGE("column_name : %s", column_name);
- if (write(result_fd, column_name, column_name_len) == -1) {
- LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- free(column_name);
- column_name = NULL;
-
- }
-
- if (_read_socket(fd, (char *)&total_len_of_column_names, sizeof(total_len_of_column_names), &nb)
- != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail: total_len_of_column_names");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- LOGE("total_len_of_column_names : %d", total_len_of_column_names);
- if (write(result_fd, &total_len_of_column_names, sizeof(int)) == -1) {
- LOGE("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (_read_socket(fd, (char *)&row_count, sizeof(row_count), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail: row_count");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (row_count < 0 || row_count > MAX_ROW_COUNT) {
- LOGE("invalid row_count %lld", row_count);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- LOGE("row_count : %lld", row_count);
- if (write(result_fd, &row_count, sizeof(row_count)) == -1) {
- LOGE("Writing a row_count to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- cursor->resultset_row_count = row_count;
- cursor->row_offset_list = (off_t *)calloc(row_count, sizeof(off_t));
- if (cursor->row_offset_list == NULL) {
- LOGE("Out of memory. can not alloc row_offset_list.");
- goto out;
- }
-
- cursor->row_offset_list[0] = lseek(result_fd, 0, SEEK_CUR);
- cursor->resultset_content_offset = cursor->row_offset_list[0];
-
- LOGE("resultset_content_offset : %lld",
- (unsigned long long)cursor->resultset_content_offset);
-
- off_t row_offset = 0;
- for (i = 0; i < row_count; i++) {
- row_offset = 0;
- for (j = 0; j < column_count; j++) {
- if (_read_socket(fd, (char *)&type, sizeof(type), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail: type");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- LOGE("type : %d", type);
- if (write(result_fd, &type, sizeof(int)) == -1) {
- LOGE("Writing a type to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (_read_socket(fd, (char *)&size, sizeof(size), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail: size");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- LOGE("size : %d", size);
- if (write(result_fd, &size, sizeof(int)) == -1) {
- LOGE("Writing a size to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (size > 0 && size < MAX_REQUEST_ARGUMENT_SIZE) {
- value = (void *)malloc(sizeof(void) * size);
- if (value == NULL) {
- LOGE("Out of mememory");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (_read_socket(fd, (char *)value, size, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("read socket fail: value");
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- LOGE("value : %s", value);
- if (write(result_fd, value, sizeof(void) * size) == -1) {
- LOGE("Writing a value to a file descriptor is failed. errno = %d", errno);
- retval = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- free(value);
- value = NULL;
-
- }
- row_offset += sizeof(int) * 2 + size;
-
- }
- if (i + 1 < row_count)
- cursor->row_offset_list[i + 1] = cursor->row_offset_list[i] + row_offset;
- }
-
- return retval;
-
-out:
- if (result_fd != -1)
- close(result_fd);
- if (column_name)
- free(column_name);
- if (value)
- free(value);
-
- datacontrol_sql_remove_cursor(cursor);
- return retval;
-}
-
-static gboolean __consumer_recv_sql_message(GIOChannel *channel,
- GIOCondition cond, gpointer data)
-{
- gint fd = g_io_channel_unix_get_fd(channel);
- char *buf = NULL;
- int data_len;
- guint nb;
- const char *p = NULL;
- int request_id;
- bundle *kb = NULL;
- sql_response_cb_s *sql_dc;
- GList *itr;
- datacontrol_consumer_request_info *request_info;
-
- LOGI("__consumer_recv_sql_message: ...from %d:%s%s%s%s\n", fd,
- (cond & G_IO_ERR) ? " ERR" : "",
- (cond & G_IO_HUP) ? " HUP" : "",
- (cond & G_IO_IN) ? " IN" : "",
- (cond & G_IO_PRI) ? " PRI" : "");
-
- if (cond & (G_IO_ERR | G_IO_HUP))
- goto error;
-
- if (cond & G_IO_IN) {
- if (_read_socket(fd, (char *)&data_len, sizeof(data_len), &nb) != DATACONTROL_ERROR_NONE)
- goto error;
- LOGI("data_len : %d", data_len);
-
- if (nb == 0) {
- LOGE("__consumer_recv_sql_message: ...from %d: EOF\n", fd);
- goto error;
- }
- if (data_len > 0 && data_len < MAX_REQUEST_ARGUMENT_SIZE) {
- buf = (char *)calloc(data_len + 1, sizeof(char));
- if (buf == NULL) {
- LOGE("Out of memory.");
- goto error;
- }
-
- if (_read_socket(fd, buf, data_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("Out of memory.");
- goto error;
- }
-
- if (nb == 0) {
- LOGE("__consumer_recv_sql_message: ...from %d: EOF\n", fd);
- goto error;
- }
-
- kb = bundle_decode_raw((bundle_raw *)buf, data_len);
-
- free(buf);
- buf = NULL;
-
- if (kb == NULL) {
- LOGE("bundle_decode_raw fail");
- goto error;
- }
-
- p = appsvc_get_data(kb, OSP_K_REQUEST_ID);
- if (!p) {
- LOGE("Invalid Bundle: request_id is null");
- goto error;
- } else {
- request_id = atoi(p);
- }
- LOGI("Request ID: %d", request_id);
- if (__sql_handle_cb(kb, data, fd, request_id)
- != DATACONTROL_ERROR_NONE)
- goto error;
- __remove_sql_request_info(request_id, data);
- bundle_free(kb);
- }
- }
- return TRUE;
-error:
- if (buf)
- free(buf);
- if (kb)
- bundle_free(kb);
-
- if (((sql_response_cb_s *)data) != NULL) {
- LOGE("g_hash_table_remove");
-
- sql_dc = (sql_response_cb_s *)data;
- g_hash_table_remove(__socket_pair_hash, sql_dc->provider_id);
-
- itr = g_list_first(sql_dc->request_info_list);
- while (itr != NULL) {
- request_info = (datacontrol_consumer_request_info *)itr->data;
- __sql_call_cb(sql_dc->provider_id, request_info->request_id, request_info->type, sql_dc->data_id, false,
- "provider IO Error", -1, NULL, NULL, data);
- itr = g_list_next(itr);
- }
- if (sql_dc->request_info_list) {
- LOGE("free sql request_info_list");
- g_list_free_full(sql_dc->request_info_list, free);
- sql_dc->request_info_list = NULL;
- }
- }
-
- return FALSE;
-}
-
-int __datacontrol_send_sql_async(int sockfd, bundle *kb, void *extra_data, datacontrol_request_type type, void *data)
-{
- bundle_raw *kb_data = NULL;
- bundle_raw *extra_kb_data = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- int datalen = 0;
- int extra_kb_datalen = 0;
- char *buf = NULL;
- int total_len = 0;
- unsigned int nb = 0;
- int i;
- int count;
- bundle *bulk_data;
- data_control_bulk_data_h bulk_data_h = NULL;
- bundle_raw *encode_data = NULL;
- int encode_datalen = 0;
-
- LOGD("send async ~~~");
-
- bundle_encode_raw(kb, &kb_data, &datalen);
- if (kb_data == NULL) {
- LOGE("bundle encode error");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (DATACONTROL_TYPE_SQL_INSERT == type ||
- DATACONTROL_TYPE_SQL_UPDATE == type) {
- bundle_encode_raw((bundle *)extra_data, &extra_kb_data, &extra_kb_datalen);
- if (extra_kb_data == NULL) {
- LOGE("bundle encode error");
- goto out;
- }
- }
-
- total_len = sizeof(datalen) + datalen;
- if (extra_kb_datalen > 0)
- total_len += sizeof(extra_kb_datalen) + extra_kb_datalen;
-
- /* encoded bundle + encoded bundle size */
- buf = (char *)calloc(total_len, sizeof(char));
- if (buf == NULL) {
- bundle_free_encoded_rawdata(&kb_data);
- LOGE("Out of memory.");
- goto out;
- }
-
- memcpy(buf, &datalen, sizeof(datalen));
- memcpy(buf + sizeof(datalen), kb_data, datalen);
- if (extra_kb_datalen > 0) {
- memcpy(buf + sizeof(datalen) + datalen, &extra_kb_datalen, sizeof(extra_kb_datalen));
- memcpy(buf + sizeof(datalen) + datalen + sizeof(extra_kb_datalen), extra_kb_data, extra_kb_datalen);
- }
-
- LOGI("write : %d", total_len);
- if (_write_socket(sockfd, buf, total_len, &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("write data fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
-
- if (DATACONTROL_TYPE_SQL_BULK_INSERT == type) {
- bulk_data_h = (data_control_bulk_data_h)extra_data;
- datacontrol_bulk_data_get_count(bulk_data_h, &count);
-
- if (_write_socket(sockfd, &count, sizeof(count), &nb) != DATACONTROL_ERROR_NONE) {
- LOGI("write bulk count fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- LOGI("write bulk count %d ", count);
- for (i = 0; i < count; i++) {
- datacontrol_bulk_data_get_data(bulk_data_h, i, &bulk_data);
- bundle_encode_raw(bulk_data, &encode_data, &encode_datalen);
- if (_write_socket(sockfd, &encode_datalen, sizeof(encode_datalen), &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("write bulk encode_datalen fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- LOGI("write encode_datalen %d ", encode_datalen);
-
- if (_write_socket(sockfd, encode_data, encode_datalen, &nb) != DATACONTROL_ERROR_NONE) {
- LOGE("write bulk encode_data fail");
- ret = DATACONTROL_ERROR_IO_ERROR;
- goto out;
- }
- encode_datalen = 0;
- bundle_free_encoded_rawdata(&encode_data);
- }
- }
-
-out:
- if (buf)
- free(buf);
- bundle_free_encoded_rawdata(&kb_data);
- bundle_free_encoded_rawdata(&extra_kb_data);
- bundle_free_encoded_rawdata(&encode_data);
-
- return ret;
-}
-
-static int __sql_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *request_data, void *extra_data, int request_id)
-{
- char *app_id = NULL;
- void *response_cb_data = NULL;
- int ret = DATACONTROL_ERROR_NONE;
- sql_response_cb_s *sql_dc_temp;
- void *sql_dc_returned = NULL;
- char caller_app_id[255];
- char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, };
- char req_id[32] = {0, };
- int count = 0;
- const int TRY_COUNT = 2;
- const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 };
- char *socket_info_key;
- bundle *send_data;
-
- LOGI("SQL Data control request, type: %d, request id: %d", type, request_id);
-
- if (__socket_pair_hash == NULL)
- __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, _socket_info_free);
-
- if ((int)type <= (int)DATACONTROL_TYPE_SQL_BULK_INSERT) {
- if ((int)type < (int)DATACONTROL_TYPE_SQL_SELECT) {
- LOGE("invalid request type: %d", (int)type);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- if (!datacontrol_sql_tree_root) {
- LOGE("the listener tree is empty");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- sql_dc_temp = (sql_response_cb_s *)calloc(1, sizeof(sql_response_cb_s));
- if (!sql_dc_temp) {
- LOGE("failed to create sql datacontrol");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- sql_dc_temp->provider_id = strdup(provider->provider_id);
- if (!sql_dc_temp->provider_id) {
- LOGE("failed to assign provider id to sql data control: %d", errno);
- free(sql_dc_temp);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- sql_dc_temp->data_id = strdup(provider->data_id);
- if (!sql_dc_temp->data_id) {
- LOGE("failed to assign data id to sql data control: %d", errno);
- free(sql_dc_temp->provider_id);
- free(sql_dc_temp);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- sql_dc_temp->app_id = NULL;
- sql_dc_temp->access_info = NULL;
- sql_dc_temp->user_data = NULL;
- sql_dc_temp->sql_response_cb = NULL;
-
- sql_dc_returned = tfind(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare);
-
- __sql_instance_free(sql_dc_temp);
-
- if (!sql_dc_returned) {
- LOGE("sql datacontrol returned after tfind is null");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- sql_response_cb_s *sql_dc = *(sql_response_cb_s **)sql_dc_returned;
- app_id = sql_dc->app_id;
-
- datacontrol_consumer_request_info *request_info = (datacontrol_consumer_request_info *)calloc(sizeof(datacontrol_consumer_request_info), 1);
- request_info->request_id = request_id;
- request_info->type = type;
- sql_dc->request_info_list = g_list_append(sql_dc->request_info_list, request_info);
-
- response_cb_data = sql_dc;
-
- LOGI("SQL datacontrol appid: %s", sql_dc->app_id);
- }
-
- pid_t pid = getpid();
- if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
- LOGE("Failed to get appid by pid(%d).", pid);
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- send_data = bundle_dup(request_data);
- if (send_data == NULL) {
- LOGE("fail to alloc result_data");
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(send_data, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
- bundle_add_str(send_data, AUL_K_CALLER_APPID, caller_app_id);
-
- snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type));
- bundle_add_str(send_data, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation);
-
- snprintf(req_id, 32, "%d", request_id);
- bundle_add_str(send_data, OSP_K_REQUEST_ID, req_id);
-
- do {
- datacontrol_socket_info *socket_info = g_hash_table_lookup(__socket_pair_hash, provider->provider_id);
-
- if (socket_info == NULL) {
- ret = _add_watch_on_socket_info(caller_app_id, app_id,
- "consumer", provider->provider_id, "Sql",
- __consumer_recv_sql_message, response_cb_data,
- &socket_info);
- if (ret != DATACONTROL_ERROR_NONE) {
- LOGE("_get_socket_info error !!!");
- bundle_free(send_data);
- return ret;
- }
-
- ret = _request_appsvc_run(caller_app_id, app_id);
- if (ret != DATACONTROL_ERROR_NONE) {
- LOGE("_request_appsvc_run error !!!");
- bundle_free(send_data);
- _socket_info_free(socket_info);
- return ret;
- }
-
- socket_info_key = strdup(provider->provider_id);
- if (socket_info_key == NULL) {
- LOGE("Out of memory. can not dup select map file.");
- bundle_free(send_data);
- return DATACONTROL_ERROR_IO_ERROR;
- }
- g_hash_table_insert(__socket_pair_hash, socket_info_key, socket_info);
- }
-
- LOGE("send data from consumer");
- ret = __datacontrol_send_sql_async(socket_info->socket_fd, send_data, extra_data, type, NULL);
- if (ret != DATACONTROL_ERROR_NONE)
- g_hash_table_remove(__socket_pair_hash, provider->provider_id);
- else
- break;
-
- count++;
- nanosleep(&TRY_SLEEP_TIME, 0);
- } while (ret != DATACONTROL_ERROR_NONE && count < TRY_COUNT);
-
- bundle_free(send_data);
- return ret;
-}
-
-int datacontrol_sql_create(datacontrol_h *provider)
-{
- struct datacontrol_s *request;
-
- if (provider == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- request = malloc(sizeof(struct datacontrol_s));
- if (request == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- request->provider_id = NULL;
- request->data_id = NULL;
-
- *provider = request;
-
- return 0;
-}
-
-int datacontrol_sql_destroy(datacontrol_h provider)
-{
- if (provider == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL)
- free(provider->provider_id);
-
- if (provider->data_id != NULL)
- free(provider->data_id);
-
- free(provider);
- return 0;
-}
-
-int datacontrol_sql_set_provider_id(datacontrol_h provider, const char *provider_id)
-{
- if (provider == NULL || provider_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL)
- free(provider->provider_id);
-
- provider->provider_id = strdup(provider_id);
- if (provider->provider_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- return 0;
-}
-
-int datacontrol_sql_get_provider_id(datacontrol_h provider, char **provider_id)
-{
- if (provider == NULL || provider_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->provider_id != NULL) {
-
- *provider_id = strdup(provider->provider_id);
- if (*provider_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- } else {
- *provider_id = NULL;
- }
-
- return 0;
-}
-
-int datacontrol_sql_set_data_id(datacontrol_h provider, const char *data_id)
-{
- if (provider == NULL || data_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->data_id != NULL)
- free(provider->data_id);
-
- provider->data_id = strdup(data_id);
- if (provider->data_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- return 0;
-}
-
-int datacontrol_sql_get_data_id(datacontrol_h provider, char **data_id)
-{
- if (provider == NULL || data_id == NULL)
- return DATACONTROL_ERROR_INVALID_PARAMETER;
-
- if (provider->data_id != NULL) {
-
- *data_id = strdup(provider->data_id);
- if (*data_id == NULL)
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
-
- } else
- *data_id = NULL;
-
- return 0;
-}
-
-bool datacontrol_sql_cb_is_registered(char *provider_id)
-{
- sql_response_cb_s sql_dc_temp;
- sql_dc_temp.provider_id = provider_id;
-
- if (tfind(&sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare) != NULL)
- return true;
- return false;
-}
-
-int datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_response_cb *callback, void *user_data)
-{
- int ret = 0;
- char *app_id = NULL;
- char *access = NULL;
- void *sql_dc_returned = NULL;
- sql_response_cb_s *sql_dc;
-
- ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id, "Sql", getuid(), &app_id, &access);
- if (ret != PMINFO_R_OK) {
- LOGE("unable to get sql data control information: %d", ret);
- return DATACONTROL_ERROR_IO_ERROR;
- }
-
- LOGI("data control provider appid = %s", app_id);
-
- sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(1, sizeof(sql_response_cb_s));
- if (!sql_dc_temp) {
- LOGE("unable to create a temporary sql data control");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- sql_dc_temp->provider_id = strdup(provider->provider_id);
- if (!sql_dc_temp->provider_id) {
- LOGE("unable to assign provider_id to sql data control: %d", errno);
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- sql_dc_temp->data_id = strdup(provider->data_id);
- if (!sql_dc_temp->data_id) {
- LOGE("unable to assign data_id to sql data control: %d", errno);
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- sql_dc_temp->app_id = app_id;
- sql_dc_temp->access_info = access;
- sql_dc_temp->user_data = user_data;
- sql_dc_temp->sql_response_cb = callback;
-
- sql_dc_returned = tsearch(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare);
-
- sql_dc = *(sql_response_cb_s **)sql_dc_returned;
- if (sql_dc != sql_dc_temp) {
- sql_dc->sql_response_cb = callback;
- sql_dc->user_data = user_data;
- LOGI("the data control is already set");
- __sql_instance_free(sql_dc_temp);
- }
-
- return DATACONTROL_ERROR_NONE;
-
-EXCEPTION:
- if (access)
- free(access);
- if (app_id)
- free(app_id);
-
- if (sql_dc_temp) {
- if (sql_dc_temp->provider_id)
- free(sql_dc_temp->provider_id);
- if (sql_dc_temp->data_id)
- free(sql_dc_temp->data_id);
- free(sql_dc_temp);
- }
-
- return ret;
-}
-
-int datacontrol_sql_unregister_response_cb(datacontrol_h provider)
-{
- int ret = DATACONTROL_ERROR_NONE;
- sql_response_cb_s *sql_dc_returned = NULL;
- char *tmp_provider_id;
-
- LOGE("g_hash_table_remove");
-
- g_hash_table_remove(__socket_pair_hash, provider->provider_id);
-
- sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(1, sizeof(sql_response_cb_s));
-
- if (!sql_dc_temp) {
- LOGE("unable to create a temporary sql data control");
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- sql_dc_temp->provider_id = strdup(provider->provider_id);
- if (!sql_dc_temp->provider_id) {
- LOGE("unable to assign provider_id to sql data control: %d", errno);
- ret = DATACONTROL_ERROR_OUT_OF_MEMORY;
- goto EXCEPTION;
- }
-
- if (datacontrol_sql_tree_root == NULL) {
- LOGE("The listener tree is empty");
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- goto EXCEPTION;
- }
-
- sql_dc_returned = *(sql_response_cb_s **)tfind(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare);
- if (sql_dc_returned == NULL) {
- LOGE("invalid parameter");
- ret = DATACONTROL_ERROR_INVALID_PARAMETER;
- goto EXCEPTION;
- }
-
- if (sql_dc_returned->app_id)
- free(sql_dc_returned->app_id);
- if (sql_dc_returned->data_id)
- free(sql_dc_returned->data_id);
- if (sql_dc_returned->access_info)
- free(sql_dc_returned->access_info);
- if (sql_dc_returned->request_info_list)
- g_list_free_full(sql_dc_returned->request_info_list, free);
-
- tmp_provider_id = sql_dc_returned->provider_id;
- tdelete(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare);
- free(tmp_provider_id);
-
-EXCEPTION:
- if (sql_dc_temp) {
- if (sql_dc_temp->provider_id)
- free(sql_dc_temp->provider_id);
- free(sql_dc_temp);
- }
-
- return ret;
-}
-
-int datacontrol_sql_insert(datacontrol_h provider, const bundle *insert_data, int *request_id)
-{
- int ret = 0;
- long long arg_size = 0;
- const char *arg_list[2];
- bundle *b;
- char insert_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
- int count;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || insert_data == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("SQL data control, insert to provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
-
- /* Check size of arguments */
- bundle_foreach((bundle *)insert_data, _bundle_foreach_check_arg_size_cb, &arg_size);
- arg_size += strlen(provider->data_id) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of the request argument exceeds the limit, 1M.");
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- count = bundle_get_count((bundle *)insert_data);
- ret = snprintf(insert_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", count);
- if (ret < 0) {
- LOGE("unable to convert insert column count to string: %d", errno);
- bundle_free(b);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- arg_list[0] = provider->data_id;
- arg_list[1] = insert_column_count;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
-
- /* Set the request id */
- *request_id = _datacontrol_create_request_id();
- LOGI("request id : %d", *request_id);
-
- ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_INSERT, b, (bundle *)insert_data, *request_id);
- bundle_free(b);
- return ret;
-}
-
-int datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_id)
-{
- const char *arg_list[2];
- int reqId;
- int ret;
- bundle *b;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
-
- if (where)
- arg_list[1] = where;
- else
- arg_list[1] = DATACONTROL_EMPTY;
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
-
- /* Set the request id */
- reqId = _datacontrol_create_request_id();
- *request_id = reqId;
-
- ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_DELETE, b, NULL, reqId);
- bundle_free(b);
- return ret;
-}
-
-int datacontrol_sql_select(datacontrol_h provider, char **column_list, int column_count,
- const char *where, const char *order, int *request_id)
-{
- return datacontrol_sql_select_with_page(provider, column_list, column_count, where, order, 1, 20, request_id);
-}
-
-int datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int column_count,
- const char *where, const char *order, int page_number, int count_per_page, int *request_id)
-{
- int total_arg_count = -1;
- int ret = 0;
- bundle *b;
- char page[32] = {0, };
- char count_per_page_no[32] = {0, };
- const char **arg_list;
- int i;
- char select_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
- int select_col;
- int reqId;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("SQL data control, select to provider_id: %s, data_id: %s, col_count: %d, where: %s, order: %s, page_number: %d, per_page: %d", provider->provider_id, provider->data_id, column_count, where, order, page_number, count_per_page);
-
- if (column_list == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- ret = snprintf(page, 32, "%d", page_number);
- if (ret < 0) {
- LOGE("unable to convert page no to string: %d", errno);
- bundle_free(b);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- ret = snprintf(count_per_page_no, 32, "%d", count_per_page);
- if (ret < 0) {
- LOGE("unable to convert count per page no to string: %d", errno);
- bundle_free(b);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- total_arg_count = column_count + DATACONTROL_SELECT_EXTRA_COUNT;
- arg_list = (const char **)malloc(total_arg_count * (sizeof(char *)));
-
- LOGI("total arg count %d", total_arg_count);
-
- arg_list[0] = provider->data_id; /* arg[0]: data ID */
- i = 1;
- if (column_list) {
- ret = snprintf(select_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", column_count);
- if (ret < 0) {
- LOGE("unable to convert select col count to string: %d", errno);
- free(arg_list);
- bundle_free(b);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
-
- arg_list[i] = select_column_count; /* arg[1]: selected column count */
-
- ++i;
- select_col = 0;
- while (select_col < column_count)
- arg_list[i++] = column_list[select_col++];
- }
-
- if (where) /* arg: where clause */
- arg_list[i++] = where;
- else
- arg_list[i++] = DATACONTROL_EMPTY;
-
- if (order) /* arg: order clause */
- arg_list[i++] = order;
- else
- arg_list[i++] = DATACONTROL_EMPTY;
-
- arg_list[i++] = page; /* arg: page number */
-
- arg_list[i] = count_per_page_no; /* arg: count per page */
-
- bundle_add_str_array(b, OSP_K_ARG, arg_list, total_arg_count);
- free(arg_list);
-
- reqId = _datacontrol_create_request_id();
- *request_id = reqId;
-
- ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_SELECT, b, NULL, reqId);
- bundle_free(b);
- return ret;
-}
-
-int datacontrol_sql_update(datacontrol_h provider, const bundle *update_data, const char *where, int *request_id)
-{
- int ret = 0;
- long long arg_size = 0;
- bundle *b;
- const char *arg_list[4];
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || update_data == NULL || where == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- /* Check size of arguments */
- bundle_foreach((bundle *)update_data, _bundle_foreach_check_arg_size_cb, &arg_size);
- arg_size += strlen(provider->data_id) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of the request argument exceeds the limit, 1M.");
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id; /* list(0): data ID */
- arg_list[1] = where;
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
-
- *request_id = _datacontrol_create_request_id();
- ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_UPDATE, b, (bundle *)update_data, *request_id);
-
- bundle_free(b);
- return ret;
-}
-
-int datacontrol_sql_insert_bulk_data(datacontrol_h provider, data_control_bulk_data_h bulk_data_h, int *request_id)
-{
- int ret = 0;
- long long arg_size = 0;
- const char *arg_list[2];
- bundle *b;
- bundle *data;
- int count;
- int i;
-
- if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) {
- LOGE("Invalid parameter");
- return DATACONTROL_ERROR_INVALID_PARAMETER;
- }
-
- LOGI("SQL data control, insert to provider_id: %s, data_id: %s", provider->provider_id, provider->data_id);
-
- /* Check size of arguments */
- count = datacontrol_bulk_data_get_count(bulk_data_h, &count);
- for (i = 0; i < count; i++) {
- datacontrol_bulk_data_get_data(bulk_data_h, i, &data);
- bundle_foreach(data, _bundle_foreach_check_arg_size_cb, &arg_size);
- }
- arg_size += (strlen(provider->data_id) + strlen(provider->provider_id)) * sizeof(wchar_t);
- if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
- LOGE("The size of the request argument exceeds the limit, 1M.");
- return DATACONTROL_ERROR_MAX_EXCEEDED;
- }
-
- b = bundle_create();
- if (!b) {
- LOGE("unable to create bundle: %d", errno);
- return DATACONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
- bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
-
- arg_list[0] = provider->data_id;
- bundle_add_str_array(b, OSP_K_ARG, arg_list, 1);
-
- /* Set the request id */
- *request_id = _datacontrol_create_request_id();
- LOGI("request id : %d", *request_id);
-
- ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_BULK_INSERT, b, bulk_data_h, *request_id);
- bundle_free(b);
- return ret;
-}
* limitations under the License.
*/
-#include <dlog.h>
#include <errno.h>
#include <glib.h>
#include <stdbool.h>
#include "data_control_log.h"
#include "data_control_bulk.h"
-#include "data-control-bulk.h"
+#include "data_control_internal.h"
-EXPORT_API int data_control_bulk_data_get_data(data_control_bulk_data_h bulk_data_h, int idx, bundle **data)
+typedef struct {
+ bundle *result_data;
+ int result;
+} data_control_bulk_result_data_item_s;
+
+struct data_control_bulk_result_data_s {
+ GList *data_list;
+};
+
+struct data_control_bulk_data_s {
+ GList *data_list;
+};
+
+static void __free_bulk_result_data(gpointer data)
{
- int ret;
+ data_control_bulk_result_data_item_s *result_data_item =
+ (data_control_bulk_result_data_item_s *)data;
+ bundle_free(result_data_item->result_data);
+ free(result_data_item);
+}
- if (bulk_data_h == NULL || data == NULL) {
- LOGE("Invalid bulk data handle");
+static void __free_bulk_data(gpointer data)
+{
+ bundle *bulk_data = (bundle *)data;
+ bundle_free(bulk_data);
+}
+
+EXPORT_API int data_control_bulk_data_get_data(data_control_bulk_data_h bulk_data_h,
+ int idx, bundle **data)
+{
+ bundle *ret_data;
+
+ if (bulk_data_h == NULL || data == NULL ||
+ bulk_data_h->data_list == NULL) {
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
if (idx < 0) {
- LOGE("Invalid index");
+ _LOGE("Invalid index");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret_data = (bundle *)g_list_nth_data(bulk_data_h->data_list, idx);
+ if (ret_data == NULL) {
+ _LOGE("no data at index %d", idx);
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- ret = datacontrol_bulk_data_get_data(bulk_data_h, idx, data);
- return ret;
+
+ *data = ret_data;
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_bulk_data_get_count(data_control_bulk_data_h bulk_data_h, int *count)
+EXPORT_API int data_control_bulk_data_get_count(data_control_bulk_data_h bulk_data_h,
+ int *count)
{
- int ret;
if (bulk_data_h == NULL || count == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- ret = datacontrol_bulk_data_get_count(bulk_data_h, count);
- return ret;
+
+ *count = g_list_length(bulk_data_h->data_list);
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_bulk_data_add(data_control_bulk_data_h bulk_data_h, bundle *data)
+EXPORT_API int data_control_bulk_data_add(data_control_bulk_data_h bulk_data_h,
+ bundle *data)
{
if (bulk_data_h == NULL || data == NULL) {
- LOGE("Invalid data");
+ _LOGE("Invalid data");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_bulk_data_add(bulk_data_h, data);
+
+ bulk_data_h->data_list = g_list_append(bulk_data_h->data_list,
+ bundle_dup(data));
+ _LOGI("append bulk data : %d", g_list_length(bulk_data_h->data_list));
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_bulk_data_create(data_control_bulk_data_h *bulk_data_h)
{
if (bulk_data_h == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_bulk_data_create(bulk_data_h);
+ *bulk_data_h = (struct data_control_bulk_data_s *)calloc(1,
+ sizeof(struct data_control_bulk_data_s));
+ if (*bulk_data_h == NULL) {
+ _LOGE("Fail to create bulk data. Out of memory.");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_bulk_data_destroy(data_control_bulk_data_h bulk_data_h)
{
if (bulk_data_h == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_bulk_data_destroy(bulk_data_h);
+
+ g_list_free_full(bulk_data_h->data_list, __free_bulk_data);
+ free(bulk_data_h);
+ _LOGI("bulk data destroy done");
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_bulk_result_data_get_result_data(data_control_bulk_result_data_h result_data_h, int idx, bundle **result_data, int *result)
+EXPORT_API int data_control_bulk_result_data_get_result_data(data_control_bulk_result_data_h result_data_h,
+ int idx, bundle **result_data, int *result)
{
- int ret;
+ data_control_bulk_result_data_item_s *result_data_item;
- if (result_data_h == NULL || result == NULL) {
- LOGE("Invalid bulk data handle");
+ if (result_data_h == NULL || result == NULL ||
+ result_data_h->data_list == NULL) {
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
if (idx < 0) {
- LOGE("Invalid index");
+ _LOGE("Invalid index");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- ret = datacontrol_bulk_result_data_get_result_data(result_data_h, idx, result_data, result);
- return ret;
+
+ result_data_item =
+ (data_control_bulk_result_data_item_s *)g_list_nth_data(result_data_h->data_list, idx);
+ if (result_data)
+ *result_data = result_data_item->result_data;
+ *result = result_data_item->result;
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_bulk_result_data_get_count(data_control_bulk_result_data_h result_data_h, int *count)
+EXPORT_API int data_control_bulk_result_data_get_count(data_control_bulk_result_data_h result_data_h,
+ int *count)
{
- int ret;
if (result_data_h == NULL || count == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- ret = datacontrol_bulk_result_data_get_count(result_data_h, count);
- return ret;
+
+ *count = g_list_length(result_data_h->data_list);
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_bulk_result_data_add(data_control_bulk_result_data_h result_data_h, bundle *result_data, int result)
+EXPORT_API int data_control_bulk_result_data_add(data_control_bulk_result_data_h result_data_h,
+ bundle *result_data, int result)
{
if (result_data_h == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_bulk_result_data_add(result_data_h, result_data, result);
+
+ data_control_bulk_result_data_item_s *result_data_item =
+ (data_control_bulk_result_data_item_s *)calloc(1, sizeof(data_control_bulk_result_data_item_s));
+ if (result_data_item == NULL) {
+ _LOGE("fail to alloc bulk_result_data");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (result_data != NULL) {
+ result_data_item->result_data = bundle_dup(result_data);
+ if (result_data_item->result_data == NULL) {
+ free(result_data_item);
+ _LOGE("fail to alloc result_data");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ result_data_item->result = result;
+
+ result_data_h->data_list = g_list_append(result_data_h->data_list,
+ result_data_item);
+ _LOGI("append bulk result data : %d", g_list_length(result_data_h->data_list));
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_bulk_result_data_create(data_control_bulk_result_data_h *result_data_h)
{
if (result_data_h == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_bulk_result_data_create(result_data_h);
+ *result_data_h =
+ (struct data_control_bulk_result_data_s *)calloc(1, sizeof(struct data_control_bulk_result_data_s));
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_bulk_result_data_destroy(data_control_bulk_result_data_h result_data_h)
{
if (result_data_h == NULL) {
- LOGE("Invalid bulk data handle");
+ _LOGE("Invalid bulk data handle");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_bulk_result_data_destroy(result_data_h);
+
+ g_list_free_full(result_data_h->data_list, __free_bulk_result_data);
+ free(result_data_h);
+ _LOGI("bulk result data destroy done");
+ return DATA_CONTROL_ERROR_NONE;
}
/*
- * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2013 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define _GNU_SOURCE
-#include <dlog.h>
+#include <sqlite3.h>
+#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <glib.h>
#include <unistd.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <pthread.h>
+#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
-#include <cynara-client.h>
-#include <stdio.h>
+
+#include <appsvc/appsvc.h>
+#include <aul/aul.h>
+
+#include <bundle.h>
+#include <bundle_internal.h>
#include <pkgmgr-info.h>
-#include <aul.h>
+#include <cynara-client.h>
+
+#include "data_control_map.h"
+#include "data_control_sql.h"
+#include "data_control_provider.h"
+#include "data_control_internal.h"
+#include "data_control_types.h"
+#include "data_control_bulk.h"
+#include "data_control_log.h"
+
+#define MAX_STATEMENT_SIZE 1024
+#define RESULT_VALUE_COUNT "RESULT_VALUE_COUNT"
+#define MAX_COUNT_PER_PAGE "MAX_COUNT_PER_PAGE"
+#define RESULT_PAGE_NUMBER "RESULT_PAGE_NUMBER"
+#define MAX_RETRY 10
+
+#define ERR_BUFFER_SIZE 1024
+#define BUFSIZE 512
+#define DATA_CONTROL_DBUS_PATH_PREFIX "/org/tizen/data_control_service_"
+#define DATA_CONTROL_OBJECT_PATH "/org/tizen/data_control_service"
+#define DATA_CONTROL_INTERFACE_NAME "org.tizen.data_control_service"
+#define DATA_CONTROL_DB_NAME_PREFIX "._data_control_list_"
+#define DATA_CONTROL_DB_NAME "DATA_CONTROL_DATA_CHANGE_TABLE"
+
+#define SMACK_LABEL_LEN 255
+#define CHECKED_CACHE_SIZE 10
+#define REQUEST_PATH_MAX 512
+
+struct datacontrol_cert_info {
+ cert_status_type sql;
+ cert_status_type map;
+ time_t time;
+};
+
+typedef struct {
+ char *provider_id;
+ char *app_id;
+ char *data_id;
+ int map_access_info;
+ int sql_access_info;
+ GList *request_info_list;
+ data_control_map_response_cb *map_response_cb;
+ data_control_sql_response_cb *sql_response_cb;
+ data_control_bulk_cb map_bulk_add_cb;
+ data_control_bulk_cb sql_bulk_insert_cb;
+ void *map_user_data;
+ void *map_bulk_user_data;
+ void *sql_user_data;
+ void *sql_bulk_user_data;
+} __response_cb_s;
+
+static GHashTable *__response_table = NULL;
+static GHashTable *__socket_pair_hash = NULL;
+
+
+static GHashTable *__checked_provider_hash;
+static GHashTable *__checked_consumer_hash;
+
+static GDBusConnection *_gdbus_conn = NULL;
+
+int __datacontrol_get_provider_id(void)
+{
+ static int id = 0;
+ g_atomic_int_inc(&id);
+
+ return id;
+}
+
+static char *__get_victim(GHashTable *hash)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+ time_t time = 0;
+ char *victim_key = NULL;
+
+ g_hash_table_iter_init(&iter, hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct datacontrol_cert_info *info = (struct datacontrol_cert_info *)value;
+ if (time == 0 || time > info->time) {
+ time = info->time;
+ victim_key = key;
+ }
+ }
+
+ return victim_key;
+}
+
+static void __insert_hash(GHashTable *hash, const char *key,
+ bool is_map, cert_status_type status)
+{
+ struct datacontrol_cert_info *cert_info;
+ char *victim_key;
+
+ if (g_hash_table_size(hash) > CHECKED_CACHE_SIZE) {
+ victim_key = __get_victim(hash);
+ if (victim_key)
+ g_hash_table_remove(hash, victim_key);
+ }
+
+ cert_info = (struct datacontrol_cert_info *)calloc(1,
+ sizeof(struct datacontrol_cert_info));
+
+ if (is_map)
+ cert_info->map = status;
+ else
+ cert_info->sql = status;
+
+ time(&cert_info->time);
+
+ g_hash_table_insert(hash, strdup(key), cert_info);
+}
+
+static void __free_data(gpointer data)
+{
+ if (data) {
+ g_free(data);
+ data = NULL;
+ }
+}
+
+static void __free_response_cb(gpointer data)
+{
+ __response_cb_s *dc = (__response_cb_s *)data;
+ if (dc) {
+ if (dc->provider_id)
+ free(dc->provider_id);
+ if (dc->data_id)
+ free(dc->data_id);
+ if (dc->app_id)
+ free(dc->app_id);
+ if (dc->map_response_cb)
+ free(dc->map_response_cb);
+ if (dc->sql_response_cb)
+ free(dc->sql_response_cb);
+ if (dc->request_info_list)
+ g_list_free_full(dc->request_info_list, free);
+
+ free(dc);
+ }
+}
+
+static void __initialize(void)
+{
+ __response_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ __free_data, __free_response_cb);
+}
+
+int __consumer_request_compare_cb(gconstpointer a, gconstpointer b)
+{
+ datacontrol_consumer_request_info *key1 =
+ (datacontrol_consumer_request_info *)a;
+ datacontrol_consumer_request_info *key2 =
+ (datacontrol_consumer_request_info *)b;
+ if (key1->request_id == key2->request_id)
+ return 0;
+
+ return 1;
+}
+
+static void __remove_request_info(int request_id, __response_cb_s *dc)
+{
+
+ datacontrol_consumer_request_info temp_request_info;
+ datacontrol_consumer_request_info *data;
+
+ temp_request_info.request_id = request_id;
+ GList *list = g_list_find_custom(dc->request_info_list, &temp_request_info,
+ (GCompareFunc)__consumer_request_compare_cb);
+ if (list != NULL) {
+ data = (datacontrol_consumer_request_info *)list->data;
+ dc->request_info_list =
+ g_list_remove(dc->request_info_list, list->data);
+ free(data);
+ }
+}
+
+static char **__map_get_value_list(int fd, int *value_count)
+{
+ char **value_list = NULL;
+ int i = 0;
+ int count = 0;
+ int nbytes = 0;
+ unsigned int nb = 0;
+ int j;
+
+ if (_read_socket(fd, (char *)&count, sizeof(count), &nb)) {
+ _LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd);
+ return NULL;
+ }
+
+ if (count < 0 || count > MAX_VALUE_COUNT) {
+ _LOGE("invalid count %d", count);
+ return NULL;
+ }
+
+ value_list = (char **)calloc(count, sizeof(char *));
+ if (value_list == NULL) {
+ _LOGE("Failed to create value list");
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) {
+ _LOGE("datacontrol_recv_map_get_value_list : ..from %d: fail to read\n", fd);
+ goto ERROR;
+ }
+ if (nbytes < 0 || nbytes > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("invalid nbytes %d", nbytes);
+ goto ERROR;
+ }
+
+ _LOGI("nbytes : %d %d" , nbytes , nb);
+ value_list[i] = (char *)calloc(nbytes + 1, sizeof(char));
+
+ if (_read_socket(fd, value_list[i], nbytes, &nb)) {
+ _LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd);
+ goto ERROR;
+ }
+ _LOGI("value_list[i] : %s %d" , value_list[i] , nb);
+ }
+ *value_count = count;
+
+ return value_list;
+
+ /* LCOV_EXCL_START */
+ERROR:
+ if (value_list) {
+ for (j = 0; j < i; j++) {
+ if (value_list[j] != NULL)
+ free(value_list[j]);
+ }
+ free(value_list);
+ }
+
+ return NULL;
+ /* LCOV_EXCL_STOP */
+}
+
+void __sql_remove_cursor(resultset_cursor *cursor)
+{
+ int ret;
+
+ close(cursor->resultset_fd);
+ if (cursor->resultset_path) {
+ ret = remove(cursor->resultset_path);
+ if (ret == -1)
+ _LOGE("unable to remove map query result file: %d", ret);
+ free(cursor->resultset_path);
+ }
+ if (cursor->row_offset_list)
+ free(cursor->row_offset_list);
+ free(cursor);
+}
+
+int __recv_bulk_process(int fd, data_control_bulk_result_data_h *result_data_h)
+{
+ int bulk_results_size;
+ guint nb;
+ int retval = DATA_CONTROL_ERROR_NONE;
+ int i;
+ int bulk_result = 0;
+ char *encode_data = NULL;
+ int encode_datalen = 0;
+ bundle *result_data = NULL;
+
+ data_control_bulk_result_data_create(result_data_h);
+ if (_read_socket(fd, (char *)&bulk_results_size,
+ sizeof(bulk_results_size), &nb) != DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: bulk_results_size");
+ goto out;
+ }
+
+ _LOGI("##### bulk result size : %d", bulk_results_size);
+ for (i = 0; i < bulk_results_size; i++) {
+ if (_read_socket(fd, (char *)&bulk_result,
+ sizeof(bulk_result), &nb) != DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: bulk_result");
+ goto out;
+ }
+ _LOGI("##### bulk result : %d", bulk_result);
+ if (_read_socket(fd, (char *)&encode_datalen,
+ sizeof(encode_datalen), &nb) != DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: encode_datalen");
+ goto out;
+ }
+ _LOGI("##### encode_datalen : %d", encode_datalen);
+ if (encode_datalen <= 0 ||
+ encode_datalen >= MAX_REQUEST_ARGUMENT_SIZE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("Invalid encode_datalen %d", encode_datalen);
+ goto out;
+ }
+ encode_data = (char *)calloc(encode_datalen, sizeof(char));
+ if (encode_data == NULL) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("FAIL to alloc encode data");
+ goto out;
+ }
+ if (_read_socket(fd, encode_data, encode_datalen, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: encode_data");
+ free(encode_data);
+ goto out;
+ }
+ result_data =
+ bundle_decode_raw((bundle_raw *)encode_data, encode_datalen);
+ data_control_bulk_result_data_add(*result_data_h, result_data,
+ bulk_result);
+ if (encode_data) {
+ free(encode_data);
+ encode_data = NULL;
+ }
+ bundle_free(result_data);
+ }
+
+out:
+ return retval;
+}
+
+static int __recv_sql_select_process(bundle *kb, int fd,
+ resultset_cursor *cursor)
+{
+ int column_count = 0;
+ int column_type = 0;
+ int column_name_len = 0;
+ char *column_name = NULL;
+ int total_len_of_column_names = 0;
+ sqlite3_int64 row_count = 0;
+ int type;
+ int size;
+ void *value = NULL;
+ sqlite3_int64 i = 0;
+ int j = 0;
+ char select_map_file[REQUEST_PATH_MAX] = {0,};
+ char *req_id = (char *)bundle_get_val(kb, OSP_K_REQUEST_ID);
+ int result_fd = 0;
+ guint nb;
+ int retval = DATA_CONTROL_ERROR_NONE;
+
+ _LOGI("req_id : %s", req_id);
+ _LOGI("SELECT RESPONSE");
+
+ size = snprintf(select_map_file, REQUEST_PATH_MAX, "/run/user/%d/%s%s%s",
+ getuid(), DATACONTROL_REQUEST_FILE_PREFIX,
+ (char *)bundle_get_val(kb, AUL_K_CALLER_APPID), req_id);
+ if (size < 0) {
+ _LOGE("unable to write formatted output to select_map_file. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ _LOGI("select_map_file : %s", select_map_file);
+
+ /* TODO - shoud be changed to solve security concerns */
+ result_fd = open(select_map_file, O_RDWR | O_CREAT, 0644);
+ if (result_fd == -1) {
+ _LOGE("unable to open insert_map file: %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+
+ }
+ cursor->resultset_path = strdup(select_map_file);
+ if (cursor->resultset_path == NULL) {
+ _LOGE("Out of memory. can not dup select map file.");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ cursor->resultset_fd = result_fd;
+ if (_read_socket(fd, (char *)&column_count,
+ sizeof(column_count), &nb) != DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: column_count");
+ goto out;
+ }
+
+ /* no data check. */
+ if (column_count == DATACONTROL_RESULT_NO_DATA) {
+ _LOGE("No result");
+ close(result_fd);
+ return DATA_CONTROL_ERROR_NONE;
+ }
+
+ if (column_count < 0 || column_count > MAX_COLUMN_COUNT) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ LOGE("Invalid column_count %d", column_count);
+ goto out;
+ }
+
+ cursor->resultset_col_count = column_count;
+ _LOGI("column_count : %d", column_count);
+
+ if (write(result_fd, &column_count, sizeof(int)) == -1) {
+ _LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ cursor->resultset_col_type_offset = sizeof(int);
+ for (i = 0; i < column_count; i++) {
+ if (_read_socket(fd, (char *)&column_type,
+ sizeof(column_type), &nb) != DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: column_type");
+ goto out;
+ }
+
+ _LOGE("column_type : %d", column_type);
+ if (write(result_fd, &column_type, sizeof(int)) == -1) {
+ _LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+
+ }
+ }
+
+ cursor->resultset_col_name_offset = cursor->resultset_col_type_offset +
+ (cursor->resultset_col_count) * sizeof(int);
+ for (i = 0; i < column_count; i++) {
+
+ if (_read_socket(fd, (char *)&column_name_len,
+ sizeof(column_name_len), &nb) != DATA_CONTROL_ERROR_NONE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("read socket fail: column_name_len");
+ goto out;
+ }
+
+ if (column_name_len < 0 || column_name_len > MAX_COLUMN_SIZE) {
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGE("Invalid column_name_len %d", column_name_len);
+ goto out;
+ }
+
+ _LOGE("column_name_len : %d", column_name_len);
+ if (write(result_fd, &column_name_len, sizeof(int)) == -1) {
+ _LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ column_name = (char *)calloc(column_name_len, sizeof(char));
+ if (column_name == NULL) {
+ _LOGE("Out of memory.");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ if (_read_socket(fd, (char *)column_name, column_name_len, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail: column_name");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ _LOGE("column_name read : %d", nb);
+ _LOGE("column_name : %s", column_name);
+ if (write(result_fd, column_name, column_name_len) == -1) {
+ _LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ free(column_name);
+ column_name = NULL;
+
+ }
+
+ if (_read_socket(fd, (char *)&total_len_of_column_names,
+ sizeof(total_len_of_column_names), &nb)
+ != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail: total_len_of_column_names");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ _LOGE("total_len_of_column_names : %d", total_len_of_column_names);
+ if (write(result_fd, &total_len_of_column_names, sizeof(int)) == -1) {
+ _LOGE("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (_read_socket(fd, (char *)&row_count,
+ sizeof(row_count), &nb) != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail: row_count");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (row_count < 0 || row_count > MAX_ROW_COUNT) {
+ _LOGE("invalid row_count %lld", row_count);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ _LOGE("row_count : %lld", row_count);
+ if (write(result_fd, &row_count, sizeof(row_count)) == -1) {
+ _LOGE("Writing a row_count to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ cursor->resultset_row_count = row_count;
+ cursor->row_offset_list = (off_t *)calloc(row_count, sizeof(off_t));
+ if (cursor->row_offset_list == NULL) {
+ _LOGE("Out of memory. can not alloc row_offset_list.");
+ goto out;
+ }
+
+ cursor->row_offset_list[0] = lseek(result_fd, 0, SEEK_CUR);
+ cursor->resultset_content_offset = cursor->row_offset_list[0];
+
+ _LOGE("resultset_content_offset : %lld",
+ (unsigned long long)cursor->resultset_content_offset);
+
+ off_t row_offset = 0;
+ for (i = 0; i < row_count; i++) {
+ row_offset = 0;
+ for (j = 0; j < column_count; j++) {
+ if (_read_socket(fd, (char *)&type, sizeof(type), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail: type");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ _LOGE("type : %d", type);
+ if (write(result_fd, &type, sizeof(int)) == -1) {
+ _LOGE("Writing a type to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (_read_socket(fd, (char *)&size, sizeof(size), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail: size");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ _LOGE("size : %d", size);
+ if (write(result_fd, &size, sizeof(int)) == -1) {
+ _LOGE("Writing a size to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (size > 0 && size < MAX_REQUEST_ARGUMENT_SIZE) {
+ value = (void *)malloc(sizeof(void) * size);
+ if (value == NULL) {
+ _LOGE("Out of mememory");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (_read_socket(fd, (char *)value, size, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail: value");
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ _LOGE("value : %s", value);
+ if (write(result_fd, value, sizeof(void) * size) == -1) {
+ _LOGE("Writing a value to a file descriptor is failed. errno = %d", errno);
+ retval = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ free(value);
+ value = NULL;
+
+ }
+ row_offset += sizeof(int) * 2 + size;
+
+ }
+ if (i + 1 < row_count)
+ cursor->row_offset_list[i + 1] =
+ cursor->row_offset_list[i] + row_offset;
+ }
+
+ return retval;
+
+out:
+ if (result_fd != -1)
+ close(result_fd);
+ if (column_name)
+ free(column_name);
+ if (value)
+ free(value);
+
+ __sql_remove_cursor(cursor);
+ return retval;
+}
+
+static void __sql_call_cb(const char *provider_id, int request_id,
+ datacontrol_request_type type, const char *data_id,
+ bool provider_result, const char *error, long long insert_rowid,
+ resultset_cursor *cursor, data_control_bulk_result_data_h bulk_results,
+ void *data)
+{
+ _LOGI("__sql_call_cb, dataID !!!: %s", data_id);
+
+ __response_cb_s *_dc = NULL;
+ data_control_sql_response_cb *sql_callback = NULL;
+ data_control_bulk_cb bulk_callback = NULL;
+
+ _dc = (__response_cb_s *)data;
+ sql_callback = (data_control_sql_response_cb *)_dc->sql_response_cb;
+ bulk_callback = (data_control_bulk_cb)_dc->sql_bulk_insert_cb;
+
+ data_control_h provider = NULL;
+ _create_data_control_h(&provider);
+
+ _set_provider_id(provider, provider_id);
+ _set_data_id(provider, data_id);
+
+ switch (type) {
+ case DATACONTROL_TYPE_SQL_BULK_INSERT:
+ _LOGI("BULK INSERT");
+ if (bulk_callback != NULL)
+ bulk_callback(request_id, provider, bulk_results, provider_result,
+ error, _dc->sql_bulk_user_data);
+ else
+ _LOGI("No registered sql_callback function");
+
+ break;
+ case DATACONTROL_TYPE_SQL_SELECT:
+ _LOGI("SELECT");
+ if (sql_callback != NULL && sql_callback->select_cb != NULL)
+ sql_callback->select_cb(request_id, provider,
+ (result_set_cursor) cursor, provider_result,
+ error, _dc->sql_user_data);
+ else
+ _LOGI("No registered sql_callback function");
+
+ break;
+ case DATACONTROL_TYPE_SQL_INSERT:
+ _LOGI("INSERT row_id: %lld", insert_rowid);
+ if (sql_callback != NULL && sql_callback->insert_cb != NULL)
+ sql_callback->insert_cb(request_id, provider, insert_rowid,
+ provider_result, error, _dc->sql_user_data);
+ else
+ _LOGI("No registered sql_callback function");
+
+ break;
+ case DATACONTROL_TYPE_SQL_UPDATE:
+ _LOGI("UPDATE");
+ if (sql_callback != NULL && sql_callback->update_cb != NULL)
+ sql_callback->update_cb(request_id, provider, provider_result,
+ error, _dc->sql_user_data);
+ else
+ _LOGI("No registered sql_callback function");
+ break;
+ case DATACONTROL_TYPE_SQL_DELETE:
+ _LOGI("DELETE");
+ if (sql_callback != NULL && sql_callback->delete_cb != NULL)
+ sql_callback->delete_cb(request_id, provider, provider_result,
+ error, _dc->sql_user_data);
+ else
+ _LOGI("No registered sql_callback function");
+ break;
+ default:
+ break;
+ }
+
+ _destroy_data_control_h(provider);
+}
+
+static void __map_call_cb(const char *provider_id, int request_id,
+ datacontrol_request_type type, const char *data_id, bool provider_result,
+ const char *error, char **result_value_list, int result_value_count,
+ data_control_bulk_result_data_h bulk_results,
+ void *data)
+{
+ _LOGI("__map_call_cb, dataID: %s", data_id);
+
+ __response_cb_s *_dc = NULL;
+ data_control_map_response_cb *map_callback = NULL;
+ data_control_bulk_cb bulk_callback = NULL;
+
+ _dc = (__response_cb_s *)data;
+ map_callback = (data_control_map_response_cb *)_dc->map_response_cb;
+ bulk_callback = (data_control_bulk_cb)_dc->map_bulk_add_cb;
+
+ data_control_h provider = NULL;
+ _create_data_control_h(&provider);
+
+ _set_provider_id(provider, provider_id);
+ _set_data_id(provider, data_id);
+
+ switch (type) {
+ case DATACONTROL_TYPE_MAP_BULK_ADD:
+ _LOGI("ADD VALUE");
+ if (bulk_callback != NULL)
+ bulk_callback(request_id, provider, bulk_results, provider_result,
+ error, _dc->map_bulk_user_data);
+ else
+ _LOGI("No registered map_callback function");
+
+ break;
+ case DATACONTROL_TYPE_MAP_GET:
+ _LOGI("GET VALUE");
+ if (map_callback != NULL && map_callback->get_cb != NULL)
+ map_callback->get_cb(request_id, provider, result_value_list,
+ result_value_count, provider_result, error,
+ _dc->map_user_data);
+ else
+ _LOGI("No registered map_callback function");
+
+ break;
+ case DATACONTROL_TYPE_MAP_SET:
+ _LOGI("SET VALUE");
+ if (map_callback != NULL && map_callback->set_cb != NULL)
+ map_callback->set_cb(request_id, provider, provider_result,
+ error, _dc->map_user_data);
+ else
+ _LOGI("No registered map_callback function");
+
+ break;
+ case DATACONTROL_TYPE_MAP_ADD:
+ _LOGI("ADD VALUE");
+ if (map_callback != NULL && map_callback->add_cb != NULL)
+ map_callback->add_cb(request_id, provider, provider_result, error,
+ _dc->map_user_data);
+ else
+ _LOGI("No registered map_callback function");
+
+ break;
+ case DATACONTROL_TYPE_MAP_REMOVE:
+ _LOGI("REMOVE VALUE");
+ if (map_callback != NULL && map_callback->remove_cb != NULL)
+ map_callback->remove_cb(request_id, provider, provider_result,
+ error, _dc->map_user_data);
+ else
+ _LOGI("No registered map_callback function");
+
+ break;
+ default:
+ break;
+ }
+
+ _destroy_data_control_h(provider);
+}
+
+static int __handle_cb(int fd, bundle *b, __response_cb_s *data)
+{
+ int ret = 0;
+ int i = 0;
+ const char **result_list = NULL;
+ const char *provider_id = NULL;
+ const char *data_id = NULL;
+ const char *error_message = NULL;
+ int result_list_len = 0;
+ int provider_result = 0;
+ int value_count = 0;
+ char **value_list = NULL;
+ const char *p = NULL;
+ const char *request_code = NULL;
+ int request_type = 0;
+ int request_id = -1;
+ long long insert_rowid = -1;
+ data_control_bulk_result_data_h bulk_results = NULL;
+ resultset_cursor *cursor = NULL;
+
+ _LOGI("__handle_cb, request_type: %d", request_type);
+
+ if (!b) {
+ _LOGE("the bundle returned from datacontrol-provider-service is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ /* result list */
+ result_list = bundle_get_str_array(b, OSP_K_ARG, &result_list_len);
+ if (!result_list) {
+ _LOGE("Invalid Bundle: arguement list is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ p = result_list[0]; /* result list[0] = provider_result */
+ if (!p) {
+ _LOGE("Invalid Bundle: provider_result is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ _LOGI("Provider result: %s", p);
+
+ provider_result = atoi(p);
+
+ error_message = result_list[1]; /* result list[1] = error */
+ if (!error_message) {
+ _LOGE("Invalid Bundle: error_message is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ _LOGI("Error message: %s", error_message);
+
+ p = bundle_get_val(b, OSP_K_REQUEST_ID);
+ if (!p) {
+ _LOGE("Invalid Bundle: request_id is null");
+ } else {
+ request_id = atoi(p);
+ }
+
+ _LOGI("Request ID: %d", request_id);
+
+ provider_id = bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+ if (!provider_id) {
+ _LOGE("Invalid Bundle: provider_id is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ data_id = bundle_get_val(b, OSP_K_DATACONTROL_DATA);
+ if (!data_id) {
+ _LOGE("Invalid Bundle: data_id is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ request_code = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+ if (!request_code) {
+ _LOGE("Invalid Bundle: data-control request type is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ request_type = atoi(request_code);
+ _LOGI("Provider ID: %s, Data ID: %s, Operation type: %d",
+ provider_id, data_id, request_type);
+
+ switch (request_type) {
+ case DATACONTROL_TYPE_MAP_BULK_ADD:
+ _LOGI("BULK ADD RESPONSE");
+ if (provider_result) {
+ if (__recv_bulk_process(fd, &bulk_results)
+ != DATA_CONTROL_ERROR_NONE) {
+ if (bulk_results)
+ data_control_bulk_result_data_destroy(bulk_results);
+
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+ break;
+ case DATACONTROL_TYPE_MAP_GET:
+ _LOGI("GET RESPONSE");
+ if (provider_result) {
+ value_list = __map_get_value_list(fd, &value_count);
+
+ if (value_list == NULL && value_count != 0) {
+ _LOGE("Invalid data: value_list is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ }
+ break;
+ case DATACONTROL_TYPE_SQL_BULK_INSERT:
+ _LOGI("BULK INSERT RESPONSE");
+ if (provider_result) {
+ if (__recv_bulk_process(fd, &bulk_results)
+ != DATA_CONTROL_ERROR_NONE) {
+ if (bulk_results)
+ data_control_bulk_result_data_destroy(bulk_results);
+
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+ break;
+ case DATACONTROL_TYPE_SQL_SELECT:
+ if (provider_result) {
+ cursor = (resultset_cursor *)calloc(1, sizeof(resultset_cursor));
+ if (!cursor) {
+ _LOGE("failed to get cursor on sql query resultset");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ if (__recv_sql_select_process(b, fd, cursor)
+ != DATA_CONTROL_ERROR_NONE)
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ break;
+ case DATACONTROL_TYPE_SQL_INSERT:
+ _LOGI("INSERT RESPONSE");
+ if (provider_result) {
+ p = result_list[2]; /* result list[2] */
+ if (!p) {
+ _LOGE("Invalid Bundle: insert row_id is null");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ insert_rowid = atoll(p);
+ }
+ break;
+ case DATACONTROL_TYPE_SQL_UPDATE:
+ case DATACONTROL_TYPE_SQL_DELETE:
+ case DATACONTROL_TYPE_MAP_SET:
+ case DATACONTROL_TYPE_MAP_ADD:
+ case DATACONTROL_TYPE_MAP_REMOVE:
+ _LOGI("MAP_SET or MAP_ADD or MAP_REMOVE or SQL_UPDATE or SQL_DELETE RESPONSE");
+ break;
+ default:
+ break;
+ }
+
+ if (request_type >= DATACONTROL_TYPE_MAP_GET &&
+ request_type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
+ __map_call_cb(provider_id,
+ request_id,
+ request_type,
+ data_id,
+ provider_result,
+ error_message,
+ value_list,
+ value_count,
+ bulk_results,
+ data);
+ if (value_list) {
+ for (i = 0; i < value_count; i++) {
+ if (value_list[i] != NULL)
+ free(value_list[i]);
+ }
+ free(value_list);
+ }
+ } else if (request_type >= DATACONTROL_TYPE_SQL_SELECT &&
+ request_type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ __sql_call_cb(
+ provider_id,
+ request_id,
+ request_type,
+ data_id,
+ provider_result,
+ error_message,
+ insert_rowid,
+ cursor,
+ bulk_results,
+ data);
+ if ((request_type == DATACONTROL_TYPE_SQL_SELECT) && (cursor))
+ __sql_remove_cursor(cursor);
+ }
+
+ ret = DATA_CONTROL_ERROR_NONE;
+
+ if (bulk_results)
+ data_control_bulk_result_data_destroy(bulk_results);
+
+ return ret;
+}
+
+static gboolean __recv_message(GIOChannel *channel,
+ GIOCondition cond,
+ gpointer data)
+{
+ int request_id = -1;
+ const char *p = NULL;
+ char *buf = NULL;
+ int nbytes;
+ guint nb;
+ bundle *kb = NULL;
+ gint fd = g_io_channel_unix_get_fd(channel);
+ __response_cb_s *_dc;
+ GList *itr;
+ datacontrol_consumer_request_info *request_info;
+
+ _LOGI("__recv_message: ...from %d:%s%s%s%s\n", fd,
+ (cond & G_IO_ERR) ? " ERR" : "",
+ (cond & G_IO_HUP) ? " HUP" : "",
+ (cond & G_IO_IN) ? " IN" : "",
+ (cond & G_IO_PRI) ? " PRI" : "");
+
+ if (cond & (G_IO_ERR | G_IO_HUP))
+ goto error;
+
+ if (cond & G_IO_IN) {
+ if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) {
+ _LOGE("Fail to read nbytes from socket");
+ goto error;
+ }
+ _LOGI("nbytes : %d", nbytes);
+
+ if (nb == 0) {
+ _LOGE("__recv_message: ...from %d: socket closed\n", fd);
+ goto error;
+ }
+
+ _LOGI("__recv_message: ...from %d: %d bytes\n", fd, nbytes);
+ if (nbytes > 0 && nbytes < MAX_REQUEST_ARGUMENT_SIZE) {
+ buf = (char *) calloc(nbytes + 1, sizeof(char));
+ if (buf == NULL) {
+ _LOGE("Malloc failed!!");
+ goto error;
+ }
+ if (_read_socket(fd, buf, nbytes, &nb)) {
+ _LOGE("Fail to read buf from socket");
+ goto error;
+ }
+
+ if (nb == 0) {
+ _LOGE("__recv_message: ...from %d: socket closed\n", fd);
+ goto error;
+ }
+
+ kb = bundle_decode_raw((bundle_raw *)buf, nbytes);
+ if (kb == NULL) {
+ _LOGE("__recv_message: Unable to decode the bundle\n");
+ goto error;
+ }
+
+ p = bundle_get_val(kb, OSP_K_REQUEST_ID);
+ if (!p) {
+ _LOGE("Invalid Bundle: request_id is null");
+ goto error;
+ } else {
+ request_id = atoi(p);
+ }
+
+ _LOGI("Request ID: %d", request_id);
+
+
+ _LOGI("__recv_message: ...from %d: OK\n", fd);
+ _LOGI("__recv_message: ...caller appid %s: OK\n",
+ bundle_get_val(kb, AUL_K_CALLER_APPID));
+
+ if (data) {
+ if (__handle_cb(fd, kb, data) != DATA_CONTROL_ERROR_NONE)
+ goto error;
+ } else {
+ _LOGE("error: listener information is null");
+ goto error;
+ }
+
+ __remove_request_info(request_id, data);
+
+ if (kb)
+ bundle_free(kb);
+ if (buf)
+ free(buf);
+ }
+ }
+ return TRUE;
+error:
+ /* LCOV_EXCL_START */
+ if (kb)
+ bundle_free(kb);
+ if (buf)
+ free(buf);
+
+ if (((__response_cb_s *)data) != NULL) {
+ _dc = (__response_cb_s *)data;
+ g_hash_table_remove(__socket_pair_hash, _dc->provider_id);
+
+ itr = g_list_first(_dc->request_info_list);
+ while (itr != NULL) {
+ request_info = (datacontrol_consumer_request_info *)itr->data;
+
+ if (request_info->type >= DATACONTROL_TYPE_MAP_GET &&
+ request_info->type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
+ __map_call_cb(_dc->provider_id, request_info->request_id,
+ request_info->type, _dc->data_id, false,
+ "provider IO Error", NULL, 0, NULL, data);
+
+ }
+
+ if (request_info->type >= DATACONTROL_TYPE_SQL_SELECT &&
+ request_info->type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ __sql_call_cb(_dc->provider_id, request_info->request_id,
+ request_info->type, _dc->data_id, false,
+ "provider IO Error", -1, NULL, NULL, data);
+ }
+
+ itr = g_list_next(itr);
+ }
+ if (_dc->request_info_list) {
+ _LOGI("free request_info_list");
+ g_list_free_full(_dc->request_info_list, free);
+ _dc->request_info_list = NULL;
+ }
+ }
+ return FALSE;
+ /* LCOV_EXCL_STOP */
+}
+
+static int __datacontrol_send_async(int sockfd, bundle *kb, void *extra_data,
+ datacontrol_request_type type, void *data)
+{
+ bundle_raw *kb_data = NULL;
+ bundle_raw *extra_kb_data = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ int datalen = 0;
+ int extra_kb_datalen = 0;
+ char *buf = NULL;
+ int total_len = 0;
+ unsigned int nb = 0;
+ int i;
+ int count;
+ bundle *bulk_data;
+ data_control_bulk_data_h bulk_data_h = NULL;
+ bundle_raw *encode_data = NULL;
+ int encode_datalen = 0;
+
+ LOGD("send async ~~~");
+
+ bundle_encode_raw(kb, &kb_data, &datalen);
+ if (kb_data == NULL) {
+ _LOGE("bundle encode error");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (DATACONTROL_TYPE_SQL_INSERT == type ||
+ DATACONTROL_TYPE_SQL_UPDATE == type) {
+ bundle_encode_raw((bundle *)extra_data,
+ &extra_kb_data, &extra_kb_datalen);
+ if (extra_kb_data == NULL) {
+ _LOGE("bundle encode error");
+ goto out;
+ }
+ }
+
+ total_len = sizeof(datalen) + datalen;
+ if (extra_kb_datalen > 0)
+ total_len += sizeof(extra_kb_datalen) + extra_kb_datalen;
+
+ /* encoded bundle + encoded bundle size */
+ buf = (char *)calloc(total_len, sizeof(char));
+ if (buf == NULL) {
+ bundle_free_encoded_rawdata(&kb_data);
+ _LOGE("Out of memory.");
+ goto out;
+ }
+
+ memcpy(buf, &datalen, sizeof(datalen));
+ memcpy(buf + sizeof(datalen), kb_data, datalen);
+ if (extra_kb_datalen > 0) {
+ memcpy(buf + sizeof(datalen) + datalen,
+ &extra_kb_datalen, sizeof(extra_kb_datalen));
+ memcpy(buf + sizeof(datalen) + datalen + sizeof(extra_kb_datalen),
+ extra_kb_data, extra_kb_datalen);
+ }
+
+ _LOGI("write : %d", total_len);
+ if (_write_socket(sockfd, buf, total_len, &nb) != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("write data fail");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (DATACONTROL_TYPE_SQL_BULK_INSERT == type ||
+ DATACONTROL_TYPE_MAP_BULK_ADD == type) {
+ bulk_data_h = (data_control_bulk_data_h)extra_data;
+ data_control_bulk_data_get_count(bulk_data_h, &count);
+
+ if (_write_socket(sockfd, &count, sizeof(count), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("write bulk count fail");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ _LOGI("write bulk count %d ", count);
+ for (i = 0; i < count; i++) {
+ data_control_bulk_data_get_data(bulk_data_h, i, &bulk_data);
+ bundle_encode_raw(bulk_data, &encode_data, &encode_datalen);
+ if (_write_socket(sockfd, &encode_datalen, sizeof(encode_datalen),
+ &nb) != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("write bulk encode_datalen fail");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ _LOGI("write encode_datalen %d ", encode_datalen);
+
+ if (_write_socket(sockfd, encode_data, encode_datalen, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("write bulk encode_data fail");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ encode_datalen = 0;
+ bundle_free_encoded_rawdata(&encode_data);
+ }
+ }
+
+out:
+ if (buf)
+ free(buf);
+ bundle_free_encoded_rawdata(&kb_data);
+ bundle_free_encoded_rawdata(&extra_kb_data);
+ bundle_free_encoded_rawdata(&encode_data);
+
+ return ret;
+}
+
+int __request_appsvc_run(const char *caller_id, const char *callee_id)
+{
+ int pid = -1;
+ int count = 0;
+ const int TRY_COUNT = 4;
+ const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 };
+ bundle *arg_list = bundle_create();
+
+ if (!arg_list) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT);
+ appsvc_set_appid(arg_list, callee_id);
+ bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP);
+ bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
+ bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_id);
+ bundle_add_str(arg_list, AUL_K_CALLEE_APPID, callee_id);
+ bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1");
+ _LOGI("caller_id %s, callee_id %s", caller_id, callee_id);
+
+ /* For DataControl CAPI */
+ bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE");
+
+ do {
+ pid = appsvc_run_service(arg_list, 0, NULL, NULL);
+ if (pid >= 0) {
+ _LOGI("Launch the provider app successfully: %d", pid);
+ bundle_free(arg_list);
+ break;
+ } else if (pid == APPSVC_RET_EINVAL) {
+ _LOGE("not able to launch service: %d", pid);
+ bundle_free(arg_list);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ count++;
+
+ nanosleep(&TRY_SLEEP_TIME, 0);
+ } while (count < TRY_COUNT);
+
+ if (count >= TRY_COUNT) {
+ bundle_free(arg_list);
+ _LOGE("unable to launch service: %d", pid);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+void _bundle_foreach_check_arg_size_cb(const char *key, const int type,
+ const bundle_keyval_t *kv, void *arg_size)
+{
+ char *value = NULL;
+ size_t value_len = 0;
+ bundle_keyval_get_basic_val((bundle_keyval_t *)kv, (void **)&value, &value_len);
+
+ arg_size += (strlen(key) + value_len) * sizeof(wchar_t);
+ return;
+}
+
+int _write_socket(int fd, void *buffer, unsigned int nbytes,
+ unsigned int *bytes_write)
+{
+ unsigned int left = nbytes;
+ gsize nb;
+ int retry_cnt = 0;
+
+ *bytes_write = 0;
+ while (left && (retry_cnt < MAX_RETRY)) {
+ nb = write(fd, buffer, left);
+ _LOGI("_write_socket: ...from %d: nb %d left %d\n", fd, nb, left - nb);
+
+ if (nb == -1) {
+ if (errno == EINTR) {
+ _LOGE("_write_socket: EINTR error continue ...");
+ retry_cnt++;
+ continue;
+ }
+ _LOGE("_write_socket: ...error fd %d: errno %d\n", fd, errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ left -= nb;
+ buffer += nb;
+ *bytes_write += nb;
+ retry_cnt = 0;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _read_socket(int fd, char *buffer, unsigned int nbytes,
+ unsigned int *bytes_read)
+{
+ unsigned int left = nbytes;
+ gsize nb;
+ int retry_cnt = 0;
+ const struct timespec TRY_SLEEP_TIME = { 0, 500 * 1000 * 1000 };
+
+ *bytes_read = 0;
+ while (left && (retry_cnt < MAX_RETRY)) {
+ nb = read(fd, buffer, left);
+ _LOGI("_read_socket: ...from %d: nb %d left %d\n", fd, nb, left - nb);
+ if (nb == 0) {
+ _LOGE("_read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ } else if (nb == -1) {
+ /* wrt(nodejs) could change socket to none-blocking socket :-( */
+ if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+ _LOGE("_read_socket: %d errno, sleep and retry ...", errno);
+ retry_cnt++;
+ nanosleep(&TRY_SLEEP_TIME, 0);
+ continue;
+ }
+ _LOGE("_read_socket: ...error fd %d: errno %d\n", fd, errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ left -= nb;
+ buffer += nb;
+ *bytes_read += nb;
+ retry_cnt = 0;
+ }
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+void _socket_info_free(gpointer socket)
+{
+ GError *error = NULL;
+ datacontrol_socket_info *socket_info = (datacontrol_socket_info *)socket;
+
+ if (socket_info != NULL) {
+ if (socket_info->gio_read != NULL) {
+ _LOGE("shutdown socketpair !!!! %d ", socket_info->socket_fd);
+ g_io_channel_shutdown(socket_info->gio_read, TRUE, &error);
+ if (error) {
+ _LOGE("g_io_channel_shutdown error : %s", error->message);
+ g_error_free(error);
+ }
+ g_io_channel_unref(socket_info->gio_read);
+ socket_info->gio_read = NULL;
+ }
+ if (socket_info->g_src_id != 0) {
+ g_source_remove(socket_info->g_src_id);
+ socket_info->g_src_id = 0;
+ }
+ free(socket_info);
+ socket_info = NULL;
+ }
+
+}
+
+int _add_watch_on_socket_info(const char *caller_id,
+ const char *callee_id, const char *type, const char *provider_id,
+ const char *data_type, GIOFunc cb, void *data,
+ datacontrol_socket_info **socket_info)
+{
+ char err_buf[ERR_BUFFER_SIZE];
+ int socketpair = 0;
+ int g_src_id;
+ int ret;
+
+ datacontrol_socket_info *_socket_info = NULL;
+ bundle *sock_bundle = bundle_create();
+ bundle_add_str(sock_bundle, AUL_K_CALLER_APPID, caller_id);
+ bundle_add_str(sock_bundle, AUL_K_CALLEE_APPID, callee_id);
+ bundle_add_str(sock_bundle, "DATA_CONTROL_TYPE", type);
+ _LOGI("type : %s", type);
+ if (provider_id)
+ bundle_add_str(sock_bundle, OSP_K_DATACONTROL_PROVIDER, provider_id);
+ if (data_type)
+ bundle_add_str(sock_bundle, "DATA_CONTROL_DATA_TYPE", data_type);
-#include "data_control_internal.h"
+ ret = aul_request_data_control_socket_pair(sock_bundle, &socketpair);
+ bundle_free(sock_bundle);
+ if (ret != AUL_R_OK) {
+ if (ret != AUL_R_EILLACC) {
+ _LOGE("Permission denied. Consumer need privilege.");
+ return DATA_CONTROL_ERROR_PERMISSION_DENIED;
+ }
-#define SMACK_LABEL_LEN 255
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
+ _LOGI("consumer socket pair : %d", socketpair);
-#define LOG_TAG "CAPI_APPFW_DATA_CONTROL"
+ if (socketpair > 0) {
+ GIOChannel *gio_read = NULL;
+ gio_read = g_io_channel_unix_new(socketpair);
+ if (!gio_read) {
+ _LOGE("Error is %s\n", strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
-#define _LOGE(fmt, arg...) LOGE(fmt, ##arg)
-#define _LOGD(fmt, arg...) LOGD(fmt, ##arg)
+ g_src_id = g_io_add_watch(gio_read, G_IO_IN | G_IO_HUP,
+ cb, data);
+ if (g_src_id == 0) {
+ g_io_channel_unref(gio_read);
+ _LOGE("fail to add watch on socket");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
-#define CHECKED_CACHE_SIZE 10
+ _socket_info =
+ (datacontrol_socket_info *)calloc(1, sizeof(datacontrol_socket_info));
+ if (_socket_info == NULL) {
+ g_io_channel_unref(gio_read);
+ g_source_remove(g_src_id);
+ _LOGE("fail to calloc socket_info");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ _socket_info->socket_fd = socketpair;
+ _socket_info->gio_read = gio_read;
+ _socket_info->g_src_id = g_src_id;
+ _LOGI("Watch on socketpair done.");
+ } else {
+ _LOGE("fail to get socket pair");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
-struct datacontrol_cert_info {
- cert_status_type sql;
- cert_status_type map;
- time_t time;
-};
+ *socket_info = _socket_info;
+ return DATA_CONTROL_ERROR_NONE;
+}
-static GHashTable *__checked_provider_hash;
-static GHashTable *__checked_consumer_hash;
+int _datacontrol_create_request_id(void)
+{
+ static int id = 0;
+ g_atomic_int_inc(&id);
+
+ return id;
+}
+
+int _request_provider(data_control_h provider, datacontrol_request_type type,
+ bundle *request_data, void *extra_data, int request_id)
+{
+ char *app_id = NULL;
+ void *data = NULL;
+ char *data_type = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ char caller_app_id[255];
+ char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, };
+ char req_id[32] = {0,};
+ int count = 0;
+ const int TRY_COUNT = 2;
+ const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 };
+ bundle *send_data;
+
+ _LOGI("Data control request, type: %d, request id: %d", type, request_id);
+
+ if (__socket_pair_hash == NULL)
+ __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, _socket_info_free);
+
+ if (!__response_table) {
+ _LOGE("The listener tree is empty");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (type >= DATACONTROL_TYPE_MAP_GET &&
+ type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
+ data_type = "Map";
+ } else if (type >= DATACONTROL_TYPE_SQL_SELECT &&
+ type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ data_type = "Sql";
+ } else {
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ __response_cb_s *_dc_returned = g_hash_table_lookup(__response_table,
+ provider->provider_id);
+ if (!_dc_returned) {
+ _LOGE("Finding the datacontrol in the listener table is failed.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ app_id = _dc_returned->app_id;
+ datacontrol_consumer_request_info *request_info =
+ (datacontrol_consumer_request_info *)calloc(
+ sizeof(datacontrol_consumer_request_info), 1);
+ request_info->request_id = request_id;
+ request_info->type = type;
+ _dc_returned->request_info_list =
+ g_list_append(_dc_returned->request_info_list, request_info);
+ data = _dc_returned;
+
+ _LOGI("datacontrol appid: %s", _dc_returned->app_id);
+
+ pid_t pid = getpid();
+ if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
+ _LOGE("Failed to get appid by pid(%d).", pid);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ send_data = bundle_dup(request_data);
+ if (send_data == NULL) {
+ _LOGE("fail to alloc result_data");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(send_data, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3);
+ bundle_add_str(send_data, AUL_K_CALLER_APPID, caller_app_id);
+
+ snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type));
+ bundle_add_str(send_data, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation);
+
+ snprintf(req_id, 32, "%d", request_id);
+ bundle_add_str(send_data, OSP_K_REQUEST_ID, req_id);
+
+ _LOGI("caller_id %s, app_id %s", caller_app_id, app_id);
+
+ do {
+ datacontrol_socket_info *socket_info =
+ g_hash_table_lookup(__socket_pair_hash, provider->provider_id);
+ if (socket_info == NULL) {
+ ret = _add_watch_on_socket_info(caller_app_id, app_id,
+ "consumer", provider->provider_id, data_type,
+ __recv_message, data,
+ &socket_info);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ bundle_free(send_data);
+ return ret;
+ }
+
+ ret = __request_appsvc_run(caller_app_id, app_id);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ bundle_free(send_data);
+ return ret;
+ }
+
+ g_hash_table_insert(__socket_pair_hash,
+ strdup(provider->provider_id), socket_info);
+ }
+
+ _LOGI("send data from consumer !!!");
+ ret = __datacontrol_send_async(socket_info->socket_fd, send_data,
+ extra_data, type, NULL);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ g_hash_table_remove(__socket_pair_hash, provider->provider_id);
+ else
+ break;
+ count++;
+ nanosleep(&TRY_SLEEP_TIME, 0);
+ } while (ret != DATA_CONTROL_ERROR_NONE && count < TRY_COUNT);
+
+ bundle_free(send_data);
+ return ret;
+}
+
+int _register_response_cb(data_control_h provider, void *response_cb,
+ datacontrol_request_type type, void *user_data)
+{
+ int ret;
+ char *app_id = NULL;
+ char *access = NULL;
+ int access_info = ACCESS_INFO_NONE;
+ char *data_type;
+ __response_cb_s *_dc_temp;
+
+ if (!response_cb || !provider || !provider->provider_id || !provider->data_id)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ if (__response_table == NULL)
+ __initialize();
+
+ if (type >= DATACONTROL_TYPE_MAP_GET &&
+ type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
+ data_type = "Map";
+ } else if (type >= DATACONTROL_TYPE_SQL_SELECT &&
+ type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ data_type = "Sql";
+ } else {
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id,
+ data_type, getuid(), &app_id, &access);
+ if (ret != PMINFO_R_OK) {
+ _LOGE("unable to get %s data control information: %d", data_type, ret);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (strcasecmp(access, "readonly") == 0)
+ access_info = ACCESS_INFO_READONLY;
+ else if (strcasecmp(access, "writeonly") == 0)
+ access_info = ACCESS_INFO_WRITEONLY;
+ else if (strcasecmp(access, "readwrite") == 0)
+ access_info = ACCESS_INFO_READ_WRITE;
+
+ _LOGI("data control provider appid = %s", app_id);
+
+ _dc_temp = g_hash_table_lookup(__response_table, provider->provider_id);
+
+ if (_dc_temp == NULL) {
+ _dc_temp = (__response_cb_s *)calloc(1, sizeof(__response_cb_s));
+ if (!_dc_temp) {
+ _LOGE("unable to create a temporary data control");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto EXCEPTION;
+ }
+
+ _dc_temp->provider_id = strdup(provider->provider_id);
+ if (!_dc_temp->provider_id) {
+ _LOGE("unable to assign provider_id to data control: %d", errno);
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto EXCEPTION;
+ }
+
+ _dc_temp->data_id = strdup(provider->data_id);
+ if (!_dc_temp->data_id) {
+ _LOGE("unable to assign data_id to data control: %d", errno);
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto EXCEPTION;
+ }
+
+ _dc_temp->app_id = strdup(app_id);
+ if (!_dc_temp->app_id) {
+ _LOGE("unable to assign app_id to data control: %d", errno);
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto EXCEPTION;
+ }
+
+ g_hash_table_insert(__response_table,
+ strdup(provider->provider_id), _dc_temp);
+ }
+
+ if (type >= DATACONTROL_TYPE_MAP_GET &&
+ type < DATACONTROL_TYPE_MAP_BULK_ADD) {
+ if (_dc_temp->map_response_cb == NULL) {
+ _dc_temp->map_response_cb =
+ (data_control_map_response_cb *)calloc(
+ 1, sizeof(data_control_map_response_cb));
+ if (!_dc_temp->map_response_cb) {
+ _LOGE("unable to create a response_cb of temporary");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto EXCEPTION;
+ }
+ }
+
+ memcpy(_dc_temp->map_response_cb, response_cb,
+ sizeof(data_control_map_response_cb));
+ _dc_temp->map_access_info = access_info;
+ _dc_temp->map_user_data = user_data;
+ } else if (type == DATACONTROL_TYPE_MAP_BULK_ADD) {
+ _dc_temp->map_bulk_add_cb = (data_control_bulk_cb)response_cb;
+ _dc_temp->map_access_info = access_info;
+ _dc_temp->map_bulk_user_data = user_data;
+ } else if (type >= DATACONTROL_TYPE_SQL_SELECT &&
+ type < DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ if (_dc_temp->sql_response_cb == NULL) {
+ _dc_temp->sql_response_cb =
+ (data_control_sql_response_cb *)calloc(
+ 1, sizeof(data_control_sql_response_cb));
+ if (!_dc_temp->sql_response_cb) {
+ _LOGE("unable to create a response_cb of temporary");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto EXCEPTION;
+ }
+ }
+
+ memcpy(_dc_temp->sql_response_cb, response_cb,
+ sizeof(data_control_sql_response_cb));
+
+ _dc_temp->sql_access_info = access_info;
+ _dc_temp->sql_user_data = user_data;
+ } else if (type == DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ _dc_temp->sql_bulk_insert_cb = (data_control_bulk_cb)response_cb;
+ _dc_temp->sql_access_info = access_info;
+ _dc_temp->sql_bulk_user_data = user_data;
+ }
+
+ ret = DATA_CONTROL_ERROR_NONE;
+
+ /* LCOV_EXCL_START */
+EXCEPTION:
+ if (access)
+ free(access);
+ if (app_id)
+ free(app_id);
+ if (ret != DATA_CONTROL_ERROR_NONE && _dc_temp) {
+ __free_response_cb((gpointer)_dc_temp);
+ }
+
+ return ret;
+ /* LCOV_EXCL_STOP */
+}
+
+int _unregister_response_cb(data_control_h provider,
+ datacontrol_request_type type)
+{
+ if (provider == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ __response_cb_s *_dc_temp = g_hash_table_lookup(__response_table,
+ provider->provider_id);
+ if (_dc_temp == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ switch (type) {
+ case DATACONTROL_TYPE_MAP_GET:
+ case DATACONTROL_TYPE_MAP_ADD:
+ case DATACONTROL_TYPE_MAP_SET:
+ case DATACONTROL_TYPE_MAP_REMOVE:
+ if (_dc_temp->map_response_cb) {
+ free(_dc_temp->map_response_cb);
+ _dc_temp->map_response_cb = NULL;
+ }
+ break;
+ case DATACONTROL_TYPE_MAP_BULK_ADD:
+ _dc_temp->map_bulk_add_cb = NULL;
+ break;
+ case DATACONTROL_TYPE_SQL_SELECT:
+ case DATACONTROL_TYPE_SQL_INSERT:
+ case DATACONTROL_TYPE_SQL_UPDATE:
+ case DATACONTROL_TYPE_SQL_DELETE:
+ if (_dc_temp->sql_response_cb) {
+ free(_dc_temp->sql_response_cb);
+ _dc_temp->sql_response_cb = NULL;
+ }
+ break;
+ case DATACONTROL_TYPE_SQL_BULK_INSERT:
+ _dc_temp->sql_bulk_insert_cb = NULL;;
+ break;
+ default:
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!_dc_temp->map_response_cb &&
+ !_dc_temp->sql_response_cb &&
+ !_dc_temp->map_bulk_add_cb &&
+ !_dc_temp->sql_bulk_insert_cb) {
+
+ g_hash_table_remove(__response_table, provider->provider_id);
+ g_hash_table_remove(__socket_pair_hash, provider->provider_id);
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+
+char *_get_encoded_db_path()
+{
+ char db_path[PATH_MAX];
+ char *dup_db_path = NULL;
+ char *encoded_appid = NULL;
+ char provider_appid[255];
+ if (aul_app_get_appid_bypid(getpid(), provider_appid, sizeof(provider_appid)) != 0) {
+ _LOGE("Failed to get appid by pid");
+ return NULL;
+ }
+
+ encoded_appid =
+ g_compute_checksum_for_string(G_CHECKSUM_MD5, provider_appid, -1);
+ snprintf(db_path, sizeof(db_path), "/run/user/%d/%s%s.db",
+ getuid(), DATA_CONTROL_DB_NAME_PREFIX, encoded_appid);
+ dup_db_path = strdup(db_path);
+ if (dup_db_path == NULL)
+ _LOGE("fail to dup db path. out of memory.");
+
+ free(encoded_appid);
+ _LOGI("dup db path : %s ", dup_db_path);
+ return dup_db_path;
+}
-int datacontrol_check_privilege(privilege_type check_type)
+char *_get_encoded_path(data_control_h provider, char *consumer_appid)
+{
+ int prefix_len = strlen(DATA_CONTROL_DBUS_PATH_PREFIX);
+ char *encoded_path;
+ char *full_path;
+ int path_len = strlen(provider->provider_id) +
+ strlen(provider->data_id) + strlen(consumer_appid) + 3;
+ int full_path_len = path_len + prefix_len;
+ char *path = (char *)calloc(path_len, sizeof(char));
+ if (path == NULL) {
+ _LOGE("path calloc failed");
+ return 0;
+ }
+
+ snprintf(path, path_len, "%s_%s_%s", provider->provider_id,
+ provider->data_id, consumer_appid);
+ encoded_path = g_compute_checksum_for_string(G_CHECKSUM_MD5, path, -1);
+
+ full_path = (char *)calloc(full_path_len, sizeof(char));
+ snprintf(full_path, full_path_len, "%s%s",
+ DATA_CONTROL_DBUS_PATH_PREFIX, encoded_path);
+
+ free(path);
+ free(encoded_path);
+ _LOGI("full path : %s ", full_path);
+ return full_path;
+}
+
+int _dbus_init()
+{
+ int ret = DATA_CONTROL_ERROR_NONE;
+ GError *error = NULL;
+
+ if (_gdbus_conn == NULL) {
+ _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
+
+ if (_gdbus_conn == NULL) {
+ if (error != NULL) {
+ _LOGE("Failed to get dbus [%s]", error->message);
+ g_error_free(error);
+ }
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ ret = DATA_CONTROL_ERROR_NONE;
+ }
+ return ret;
+}
+
+GDBusConnection *_get_dbus_connection()
+{
+ int result = _dbus_init();
+ if (result != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Can't init dbus %d", result);
+ return NULL;
+ }
+ return _gdbus_conn;
+}
+
+int _dbus_signal_init(int *monitor_id, char *path, GDBusSignalCallback callback)
+{
+ int id;
+ id = g_dbus_connection_signal_subscribe(
+ _get_dbus_connection(),
+ NULL,
+ DATA_CONTROL_INTERFACE_NAME,
+ NULL,
+ path,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ callback,
+ NULL,
+ NULL);
+
+ _LOGI("subscribe id : %d", id);
+ if (id == 0) {
+ _LOGE("Failed to _register_noti_dbus_interface");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ } else {
+ *monitor_id = id;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _check_privilege(privilege_type check_type)
{
cynara *p_cynara = NULL;
ret = cynara_initialize(&p_cynara, NULL);
if (ret != CYNARA_API_SUCCESS) {
- LOGE("cannot init cynara [%d] failed!", ret);
+ _LOGE("cannot init cynara [%d] failed!", ret);
ret = DATA_CONTROL_ERROR_IO_ERROR;
goto out;
}
fd = open("/proc/self/attr/current", O_RDONLY);
if (fd < 0) {
- LOGE("open [%d] failed!", errno);
+ _LOGE("open [%d] failed!", errno);
ret = DATA_CONTROL_ERROR_IO_ERROR;
goto out;
}
ret = read(fd, subject_label, SMACK_LABEL_LEN);
if (ret < 0) {
- LOGE("read [%d] failed!", errno);
+ _LOGE("read [%d] failed!", errno);
close(fd);
ret = DATA_CONTROL_ERROR_IO_ERROR;
goto out;
ret = cynara_check(p_cynara, subject_label, client_session, uid,
"http://tizen.org/privilege/datasharing");
if (ret != CYNARA_API_ACCESS_ALLOWED) {
- LOGE("cynara access check [%d] failed!", ret);
+ _LOGE("cynara access check [%d] failed!", ret);
ret = DATA_CONTROL_ERROR_PERMISSION_DENIED;
goto out;
}
ret = cynara_check(p_cynara, subject_label, client_session, uid,
"http://tizen.org/privilege/appmanager.launch");
if (ret != CYNARA_API_ACCESS_ALLOWED) {
- LOGE("cynara access check [%d] failed!", ret);
+ _LOGE("cynara access check [%d] failed!", ret);
ret = DATA_CONTROL_ERROR_PERMISSION_DENIED;
goto out;
}
return ret;
}
-static char *__get_victim(GHashTable *hash)
-{
- GHashTableIter iter;
- gpointer key;
- gpointer value;
- time_t time = 0;
- char *victim_key = NULL;
-
- g_hash_table_iter_init(&iter, hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- struct datacontrol_cert_info *info = (struct datacontrol_cert_info *)value;
- if (time == 0 || time > info->time) {
- time = info->time;
- victim_key = key;
- }
- }
-
- return victim_key;
-}
-
-static void _insert_hash(GHashTable *hash, const char *key,
- bool is_map, cert_status_type status)
-{
- struct datacontrol_cert_info *cert_info;
- char *victim_key;
-
- if (g_hash_table_size(hash) > CHECKED_CACHE_SIZE) {
- victim_key = __get_victim(hash);
- if (victim_key)
- g_hash_table_remove(hash, victim_key);
- }
-
- cert_info = (struct datacontrol_cert_info *)calloc(1,
- sizeof(struct datacontrol_cert_info));
-
- if (is_map)
- cert_info->map = status;
- else
- cert_info->sql = status;
-
- time(&cert_info->time);
-
- g_hash_table_insert(hash, strdup(key), cert_info);
-}
-
-int datacontrol_check_cert(const char *provider_id, bool is_map,
+int _check_cert(const char *provider_id, bool is_map,
const char *consumer_appid)
{
int ret;
if (consumer_appid == NULL) {
if (__checked_provider_hash == NULL)
- __checked_provider_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+ __checked_provider_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, free, free);
hash_table = __checked_provider_hash;
} else {
if (__checked_consumer_hash == NULL)
- __checked_consumer_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+ __checked_consumer_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, free, free);
hash_table = __checked_consumer_hash;
}
ret = pkgmgrinfo_appinfo_usr_get_datacontrol_trusted_info(provider_id,
is_map ? "Map" : "Sql", getuid(), &provider_appid, &is_trusted);
if (ret != PMINFO_R_OK) {
- LOGE("unable to get data control information: %d", ret);
+ _LOGE("unable to get data control information: %d", ret);
return DATA_CONTROL_ERROR_IO_ERROR;
}
if (is_update)
*status = CERT_MATCH;
else
- _insert_hash(hash_table, provider_id, is_map, CERT_MATCH);
+ __insert_hash(hash_table, provider_id, is_map, CERT_MATCH);
free(provider_appid);
return DATA_CONTROL_ERROR_NONE;
}
if (!consumer_appid) {
ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
if (ret != AUL_R_OK) {
- LOGE("Failed to get appid: %d", ret);
+ _LOGE("Failed to get appid: %d", ret);
free(provider_appid);
return DATA_CONTROL_ERROR_IO_ERROR;
}
ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(provider_appid,
consumer_appid, getuid(), &res);
if (ret < 0) {
- LOGE("certificate check [%d] failed!", ret);
+ _LOGE("certificate check [%d] failed!", ret);
free(provider_appid);
return DATA_CONTROL_ERROR_IO_ERROR;
}
if (res != PMINFO_CERT_COMPARE_MATCH) {
- LOGE("certificate mismatch. provider : %s consumer %s",
+ _LOGE("certificate mismatch. provider : %s consumer %s",
provider_appid, consumer_appid);
if (is_update)
*status = CERT_MISMATCH;
else
- _insert_hash(hash_table, provider_id, is_map, CERT_MISMATCH);
+ __insert_hash(hash_table, provider_id, is_map, CERT_MISMATCH);
free(provider_appid);
return DATA_CONTROL_ERROR_PERMISSION_DENIED;
}
if (is_update)
*status = CERT_MATCH;
else
- _insert_hash(hash_table, provider_id, is_map, CERT_MATCH);
+ __insert_hash(hash_table, provider_id, is_map, CERT_MATCH);
free(provider_appid);
return DATA_CONTROL_ERROR_NONE;
}
-int convert_to_tizen_error(datacontrol_error_e error)
+int _create_data_control_h(data_control_h *provider)
{
- switch (error) {
- case DATACONTROL_ERROR_NONE:
- return DATA_CONTROL_ERROR_NONE;
- case DATACONTROL_ERROR_INVALID_PARAMETER:
+ struct data_control_s *request;
+
+ if (provider == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- case DATACONTROL_ERROR_OUT_OF_MEMORY:
+
+ request = (struct data_control_s *)calloc(1, sizeof(struct data_control_s));
+ if (request == NULL)
return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
- case DATACONTROL_ERROR_IO_ERROR:
- return DATA_CONTROL_ERROR_IO_ERROR;
- case DATACONTROL_ERROR_PERMISSION_DENIED:
- return DATA_CONTROL_ERROR_PERMISSION_DENIED;
- case DATACONTROL_ERROR_MAX_EXCEEDED:
- return DATA_CONTROL_ERROR_MAX_EXCEEDED;
- default:
- return error;
+
+ *provider = request;
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _destroy_data_control_h(data_control_h provider)
+{
+ if (provider == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ if (provider->provider_id != NULL)
+ free(provider->provider_id);
+
+ if (provider->data_id != NULL)
+ free(provider->data_id);
+
+ free(provider);
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _set_provider_id(data_control_h provider, const char *provider_id)
+{
+ if (provider == NULL || provider_id == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ if (provider->provider_id != NULL)
+ free(provider->provider_id);
+
+ provider->provider_id = strdup(provider_id);
+ if (provider->provider_id == NULL)
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _get_provider_id(data_control_h provider, char **provider_id)
+{
+ if (provider == NULL || provider_id == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ if (provider->provider_id != NULL) {
+ *provider_id = strdup(provider->provider_id);
+ if (*provider_id == NULL)
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+
+ } else {
+ *provider_id = NULL;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _set_data_id(data_control_h provider, const char *data_id)
+{
+ if (provider == NULL || data_id == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ if (provider->data_id != NULL)
+ free(provider->data_id);
+
+ provider->data_id = strdup(data_id);
+ if (provider->data_id == NULL)
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _get_data_id(data_control_h provider, char **data_id)
+{
+ if (provider == NULL || data_id == NULL)
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+
+ if (provider->data_id != NULL) {
+ *data_id = strdup(provider->data_id);
+ if (*data_id == NULL)
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+
+ } else {
+ *data_id = NULL;
}
+
+ return DATA_CONTROL_ERROR_NONE;
}
* @file data-control-internal.h
* @brief This is the header file for private keys of the data-control.
*/
+#include <sqlite3.h>
#include <gio/gio.h>
#include <bundle.h>
#include "data_control_types.h"
-#include "data_control_internal.h"
#ifndef _APPFW_DATA_CONTROL_INTERNAL_H_
#define _APPFW_DATA_CONTROL_INTERNAL_H_
+#ifdef __GNUC__
+# ifndef EXPORT_API
+# define EXPORT_API __attribute__((visibility("default")))
+# endif
+#else
+# define EXPORT_API
+#endif
+
#undef LOG_TAG
#ifndef LOG_TAG
#define LOG_TAG "DATA_CONTROL"
/**
* @brief Enumerations of different type of data control requests.
*/
+typedef enum
+{
+ DATACONTROL_TYPE_ERROR = -1,
+ DATACONTROL_TYPE_UNDEFINED,
+ DATACONTROL_TYPE_SQL_SELECT,
+ DATACONTROL_TYPE_SQL_INSERT,
+ DATACONTROL_TYPE_SQL_UPDATE,
+ DATACONTROL_TYPE_SQL_DELETE,
+ DATACONTROL_TYPE_SQL_BULK_INSERT,
+ DATACONTROL_TYPE_MAP_GET,
+ DATACONTROL_TYPE_MAP_SET,
+ DATACONTROL_TYPE_MAP_ADD,
+ DATACONTROL_TYPE_MAP_REMOVE,
+ DATACONTROL_TYPE_MAP_BULK_ADD,
+ DATACONTROL_TYPE_ADD_DATA_CHANGED_CB,
+ DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB,
+ DATACONTROL_TYPE_MAX = 255
+} datacontrol_request_type;
-typedef struct datacontrol_pkt {
- int len;
- unsigned char data[1];
-} datacontrol_pkt_s;
+/**
+ * @brief Enumerations of different type of data control requests.
+ */
+typedef enum {
+ DATACONTROL_DATA_CHANGE_SQL_UPDATE, /**< Update notification */
+ DATACONTROL_DATA_CHANGE_SQL_INSERT, /**< Insert notification */
+ DATACONTROL_DATA_CHANGE_SQL_DELETE, /**< Delete notification */
+ DATACONTROL_DATA_CHANGE_MAP_SET, /**< Set notification */
+ DATACONTROL_DATA_CHANGE_MAP_ADD, /**< Add notification */
+ DATACONTROL_DATA_CHANGE_MAP_REMOVE, /**< Remove notification */
+ DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT,
+ DATACONTROL_DATA_CHANGE_CALLBACK_REMOVE_RESULT
+} datacontrol_data_change_type_e;
-typedef struct datacontrol_socket {
- GIOChannel *gio_read;
- int g_src_id;
- int socket_fd;
-} datacontrol_socket_info;
+/**
+ * @brief The structure type to represent a sql result set. This type can be used to enumerate through the result set of an SQL query.
+ */
+typedef struct {
+ int resultset_fd;
+ sqlite3_int64 resultset_row_count;
+ int resultset_col_count;
+ off_t resultset_col_type_offset;
+ off_t resultset_col_name_offset;
+ off_t resultset_content_offset;
+ off_t resultset_current_offset;
+ sqlite3_int64 resultset_current_row_count;
+ char *resultset_path;
+ off_t *row_offset_list;
+} resultset_cursor;
+
+typedef enum {
+ PRIVILEGE_PROVIDER,
+ PRIVILEGE_CONSUMER
+} privilege_type;
+
+typedef enum {
+ CERT_UNCHECKED,
+ CERT_MATCH,
+ CERT_MISMATCH
+} cert_status_type;
+
+typedef enum {
+ ACCESS_INFO_NONE,
+ ACCESS_INFO_READONLY,
+ ACCESS_INFO_WRITEONLY,
+ ACCESS_INFO_READ_WRITE,
+} access_info_type;
typedef struct datacontrol_consumer_request {
int request_id;
datacontrol_request_type type;
} datacontrol_consumer_request_info;
-typedef struct datacontrol_consumer {
- int monitor_id;
- char *appid;
- char *object_path;
- char *unique_id;
-} datacontrol_consumer_info;
+typedef struct datacontrol_socket {
+ GIOChannel *gio_read;
+ int g_src_id;
+ int socket_fd;
+} datacontrol_socket_info;
-struct datacontrol_s {
+struct data_control_s {
char *provider_id;
char *data_id;
};
void _bundle_foreach_check_arg_size_cb(const char *key, const int type,
const bundle_keyval_t *kv, void *arg_size);
-int _datacontrol_send_async(int sockfd, bundle *kb, void *extra_data, datacontrol_request_type type, void *data);
-int _recv_bulk_process(int fd, data_control_bulk_result_data_h *result_data_h);
-int _consumer_request_compare_cb(gconstpointer a, gconstpointer b);
-int _datacontrol_sql_set_cursor(const char *path);
-int _datacontrol_create_request_id(void);
-int _datacontrol_get_data_changed_callback_id(void);
-int _datacontrol_get_data_changed_filter_callback_id(void);
-int _read_socket(int fd, char *buffer, unsigned int nbytes, unsigned int *bytes_read);
-int _write_socket(int fd, void *buffer, unsigned int nbytes, unsigned int *bytes_write);
+int _read_socket(int fd, char *buffer,
+ unsigned int nbytes, unsigned int *bytes_read);
+int _write_socket(int fd, void *buffer,
+ unsigned int nbytes, unsigned int *bytes_write);
-gboolean _datacontrol_recv_message(GIOChannel *channel, GIOCondition cond, gpointer data);
-int _get_gdbus_shared_connection(GDBusConnection **connection, char *provider_id);
void _socket_info_free(gpointer socket);
int _add_watch_on_socket_info(const char *caller_id,
const char *callee_id, const char *type, const char *provider_id,
const char *data_type, GIOFunc cb, void *data,
datacontrol_socket_info **socket_info);
-int _request_appsvc_run(const char *caller_id, const char *callee_id);
GDBusConnection *_get_dbus_connection();
int _dbus_signal_init(int *monitor_id, char *path, GDBusSignalCallback callback);
-char *_get_encoded_path(datacontrol_h provider, char *consumer_appid);
+char *_get_encoded_path(data_control_h provider, char *consumer_appid);
char *_get_encoded_db_path();
-int _create_datacontrol_h(datacontrol_h *provider);
-int _destroy_datacontrol_h(datacontrol_h provider);
-int _set_provider_id(datacontrol_h provider, const char *provider_id);
-int _set_data_id(datacontrol_h provider, const char *data_id);
-datacontrol_data_change_type_e _get_internal_noti_type(data_control_data_change_type_e type);
-data_control_data_change_type_e _get_public_noti_type(datacontrol_data_change_type_e type);
-bool _check_int(int num);
+int _check_privilege(privilege_type check_type);
+int _check_cert(const char *provider_id, bool is_map,
+ const char *consumer_appid);
+
+int _create_data_control_h(data_control_h *provider);
+int _destroy_data_control_h(data_control_h provider);
+int _set_provider_id(data_control_h provider, const char *provider_id);
+int _get_provider_id(data_control_h provider, char **provider_id);
+int _set_data_id(data_control_h provider, const char *data_id);
+int _get_data_id(data_control_h provider, char **data_id);
+
+int _datacontrol_create_request_id(void);
+int _register_response_cb(data_control_h provider, void *response_cb,
+ datacontrol_request_type type, void *user_data);
+int _unregister_response_cb(data_control_h provider,
+ datacontrol_request_type);
+int _request_provider(data_control_h provider, datacontrol_request_type type,
+ bundle *request_data, void *extra_data, int request_id);
#endif /* _APPFW_DATA_CONTROL_INTERNAL_H_ */
# define EXPORT_API
#endif
+#ifdef LOG_TAG
#undef LOG_TAG
+#endif
#define LOG_TAG "DATA_CONTROL"
#define _LOGE(fmt, arg...) LOGE(fmt, ##arg)
* limitations under the License.
*/
-#include <dlog.h>
-#include <bundle.h>
#include <errno.h>
#include <glib.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <stdio.h>
-#include <data-control-map.h>
+#include <bundle.h>
#include "data_control_internal.h"
+#include "data_control_bulk.h"
#include "data_control_map.h"
#include "data_control_log.h"
-struct data_control_s {
- char *provider_id;
- char *data_id;
-};
-
-struct datacontrol_s {
- char *provider_id;
- char *data_id;
-};
-
-typedef struct bulk_cb_info_s {
- data_control_bulk_cb bulk_cb;
- void *user_data;
-} bulk_cb_info;
-
-static GHashTable *__response_table = NULL;
-static GHashTable *__bulk_response_table = NULL;
-static datacontrol_map_response_cb __datacontrol_map_cb;
-
-static void __map_get_response(int request_id, datacontrol_h provider,
- char **result_value_list, int result_value_count, bool provider_result, const char *error, void *user_data)
+EXPORT_API int data_control_map_create(data_control_h *provider)
{
- _LOGI("map_get_response");
-
- data_control_map_response_cb *callback = (data_control_map_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->get_cb(request_id, (data_control_h)provider, result_value_list, result_value_count, provider_result, error, user_data);
+ return _create_data_control_h(provider);
}
-static void __map_set_response(int request_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+EXPORT_API int data_control_map_destroy(data_control_h provider)
{
- _LOGI("map_set_response");
-
- data_control_map_response_cb *callback = (data_control_map_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->set_cb(request_id, (data_control_h)provider, provider_result, error, user_data);
+ return _destroy_data_control_h(provider);
}
-static void __map_add_response(int request_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+EXPORT_API int data_control_map_set_provider_id(data_control_h provider,
+ const char *provider_id)
{
- _LOGI("map_add_response");
-
- data_control_map_response_cb *callback = (data_control_map_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->add_cb(request_id, (data_control_h)provider, provider_result, error, user_data);
+ return _set_provider_id(provider, provider_id);
}
-static void __map_remove_response(int request_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
+EXPORT_API int data_control_map_get_provider_id(data_control_h provider,
+ char **provider_id)
{
- _LOGI("map_remove_response");
-
- data_control_map_response_cb *callback = (data_control_map_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->remove_cb(request_id, (data_control_h)provider, provider_result, error, user_data);
+ return _get_provider_id(provider, provider_id);
}
-static void __map_bulk_add_response(int request_id, datacontrol_h provider, data_control_bulk_result_data_h bulk_results,
- bool provider_result, const char *error, void *user_data)
+EXPORT_API int data_control_map_set_data_id(data_control_h provider,
+ const char *data_id)
{
- _LOGI("map_bulk_add_response");
-
- bulk_cb_info *info = (bulk_cb_info *)g_hash_table_lookup(__bulk_response_table, provider->provider_id);
- if (info)
- info->bulk_cb(request_id, (data_control_h)provider, bulk_results, provider_result, error, user_data);
+ return _set_data_id(provider, data_id);
}
-static void __free_data(gpointer data)
+EXPORT_API int data_control_map_get_data_id(data_control_h provider,
+ char **data_id)
{
- if (data) {
- g_free(data);
- data = NULL;
- }
+ return _get_data_id(provider, data_id);
}
-static void __initialize(void)
+EXPORT_API int data_control_map_register_response_cb(data_control_h provider,
+ data_control_map_response_cb *callback, void *user_data)
{
- __response_table = g_hash_table_new_full(g_str_hash, g_str_equal, __free_data, __free_data);
- __bulk_response_table = g_hash_table_new_full(g_str_hash, g_str_equal, __free_data, __free_data);
-
- __datacontrol_map_cb.get = __map_get_response;
- __datacontrol_map_cb.set = __map_set_response;
- __datacontrol_map_cb.add = __map_add_response;
- __datacontrol_map_cb.remove = __map_remove_response;
- __datacontrol_map_cb.bulk_add = __map_bulk_add_response;
+ return _register_response_cb(provider, (void *)callback,
+ DATACONTROL_TYPE_MAP_GET, user_data);
}
-EXPORT_API int data_control_map_create(data_control_h *provider)
+EXPORT_API int data_control_map_unregister_response_cb(data_control_h provider)
{
- return convert_to_tizen_error(datacontrol_map_create((datacontrol_h *)provider));
+ return _unregister_response_cb(provider, DATACONTROL_TYPE_MAP_GET);
}
-EXPORT_API int data_control_map_destroy(data_control_h provider)
+EXPORT_API int data_control_map_register_add_bulk_data_response_cb(
+ data_control_h provider,
+ data_control_bulk_cb callback,
+ void *user_data)
{
- return convert_to_tizen_error(datacontrol_map_destroy((datacontrol_h)provider));
+ return _register_response_cb(provider, (void *)callback,
+ DATACONTROL_TYPE_MAP_BULK_ADD, user_data);
}
-EXPORT_API int data_control_map_set_provider_id(data_control_h provider, const char *provider_id)
+EXPORT_API int data_control_map_unregister_add_bulk_data_response_cb(
+ data_control_h provider)
{
- return convert_to_tizen_error(datacontrol_map_set_provider_id((datacontrol_h)provider, provider_id));
+ return _unregister_response_cb(provider, DATACONTROL_TYPE_MAP_BULK_ADD);
}
-EXPORT_API int data_control_map_get_provider_id(data_control_h provider, char **provider_id)
+EXPORT_API int data_control_map_get(data_control_h provider,
+ const char *key, int *request_id)
{
- return convert_to_tizen_error(datacontrol_map_get_provider_id((datacontrol_h)provider, provider_id));
-}
+ int retval;
-EXPORT_API int data_control_map_set_data_id(data_control_h provider, const char *data_id)
-{
- return convert_to_tizen_error(datacontrol_map_set_data_id((datacontrol_h)provider, data_id));
-}
+ if (provider == NULL || provider->provider_id == NULL ||
+ provider->data_id == NULL || key == NULL) {
+ _LOGE("Invalid parameter");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
-EXPORT_API int data_control_map_get_data_id(data_control_h provider, char **data_id)
-{
- return convert_to_tizen_error(datacontrol_map_get_data_id((datacontrol_h)provider, data_id));
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
+ if (retval != DATA_CONTROL_ERROR_NONE)
+ return retval;
+
+ retval = _check_cert(provider->provider_id, true, NULL);
+ if (retval != DATA_CONTROL_ERROR_NONE)
+ return retval;
+
+ return data_control_map_get_with_page(provider, key, request_id, 1, 20);
}
-EXPORT_API int data_control_map_register_response_cb(data_control_h provider, data_control_map_response_cb *callback, void *user_data)
+EXPORT_API int data_control_map_get_with_page(data_control_h provider,
+ const char *key, int *request_id, int page_number, int count_per_page)
{
- data_control_map_response_cb *cb;
- char *id;
+ unsigned int arg_size;
+ int ret = 0;
+ const char *arg_list[4];
+ char page_no_str[32];
+ char count_per_page_str[32];
+ int reqId;
- if (__response_table == NULL)
- __initialize();
-
- if (callback == NULL)
+ if (provider == NULL || provider->provider_id == NULL ||
+ provider->data_id == NULL || key == NULL) {
+ _LOGE("Invalid parameter");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
-
- id = strdup(provider->provider_id);
- if (id == NULL)
- return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
-
- cb = (data_control_map_response_cb *)malloc(sizeof(data_control_map_response_cb));
- if (cb == NULL) {
- free(id);
- return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
}
- memcpy(cb, callback, sizeof(data_control_map_response_cb));
- g_hash_table_insert(__response_table, id, cb);
-
- return convert_to_tizen_error(datacontrol_map_register_response_cb((datacontrol_h)provider, &__datacontrol_map_cb, user_data));
-}
-
-EXPORT_API int data_control_map_unregister_response_cb(data_control_h provider)
-{
- if (provider->provider_id)
- g_hash_table_remove(__response_table, provider->provider_id);
+ ret = _check_privilege(PRIVILEGE_CONSUMER);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
- return convert_to_tizen_error(datacontrol_map_unregister_response_cb((datacontrol_h)provider));
-}
+ ret = _check_cert(provider->provider_id, true, NULL);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
-EXPORT_API int data_control_map_register_add_bulk_data_response_cb(data_control_h provider,
- data_control_bulk_cb callback, void *user_data)
-{
- char *id = NULL;
- bulk_cb_info *info = NULL;
- int ret;
+ _LOGI("Gets the value list from provider_id: %s, data_id: %s",
+ provider->provider_id, provider->data_id);
- if (__bulk_response_table == NULL)
- __initialize();
+ arg_size = (strlen(provider->data_id) + strlen(key)) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of sending argument (%u) exceeds the maximum limit.",
+ arg_size);
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
- if (callback == NULL)
+ bundle *b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
-
- info = (bulk_cb_info *)calloc(1, sizeof(bulk_cb_info));
- if (info == NULL) {
- _LOGE("fail to alloc info");
- ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
- goto out;
}
- info->bulk_cb = callback;
- info->user_data = user_data;
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
- id = strdup(provider->provider_id);
- if (id == NULL) {
- ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
- goto out;
+ arg_list[0] = provider->data_id;
+ arg_list[1] = key;
+
+ ret = snprintf(page_no_str, sizeof(page_no_str), "%d", page_number);
+ if (ret < 0) {
+ _LOGE("unable to convert page no to string: %d", errno);
+ bundle_free(b);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
}
- g_hash_table_insert(__bulk_response_table, id, info);
- if (datacontrol_map_cb_is_registered(id))
- return DATA_CONTROL_ERROR_NONE;
- ret = datacontrol_map_register_response_cb((datacontrol_h)provider, &__datacontrol_map_cb, NULL);
-
-out:
- if (ret != DATA_CONTROL_ERROR_NONE) {
- if (id != NULL)
- free(id);
- if (info != NULL)
- free(info);
+ ret = snprintf(count_per_page_str, sizeof(count_per_page_str),
+ "%d", count_per_page);
+ if (ret < 0) {
+ _LOGE("unable to convert count per page no to string: %d", errno);
+ bundle_free(b);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
}
+ arg_list[2] = page_no_str;
+ arg_list[3] = count_per_page_str;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
+
+ /* Set the request id */
+ reqId = _datacontrol_create_request_id();
+ *request_id = reqId;
+
+ ret = _request_provider(provider, DATACONTROL_TYPE_MAP_GET, b, NULL, reqId);
+ bundle_free(b);
+
return ret;
-}
-EXPORT_API int data_control_map_unregister_add_bulk_data_response_cb(data_control_h provider)
-{
- if (provider != NULL && provider->provider_id && __bulk_response_table) {
- if (g_hash_table_lookup(__bulk_response_table, provider->provider_id) != NULL) {
- g_hash_table_remove(__bulk_response_table, provider->provider_id);
- } else {
- _LOGE("Invalid param");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- }
- } else {
- _LOGE("Invalid param");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- }
- return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_map_get(data_control_h provider, const char *key, int *request_id)
+EXPORT_API int data_control_map_set(data_control_h provider, const char *key,
+ const char *old_value, const char *new_value, int *request_id)
{
int retval;
+ unsigned int arg_size;
+ bundle *b;
+ const char *arg_list[4];
+ int reqId;
if (provider == NULL || provider->provider_id == NULL ||
- provider->data_id == NULL || key == NULL) {
+ provider->data_id == NULL || key == NULL ||
+ old_value == NULL || new_value == NULL) {
_LOGE("Invalid parameter");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
+ retval = _check_cert(provider->provider_id, true, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return convert_to_tizen_error(datacontrol_map_get((datacontrol_h)provider, key, request_id));
-}
+ _LOGI("Sets the old value to new value in provider_id: %s, data_id: %s",
+ provider->provider_id, provider->data_id);
-EXPORT_API int data_control_map_get_with_page(data_control_h provider, const char *key, int *request_id, int page_number, int count_per_page)
-{
- int retval;
+ arg_size = (strlen(provider->data_id) + strlen(key) +
+ strlen(old_value) + strlen(new_value)) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of sending argument (%u) exceeds the maximum limit.",
+ arg_size);
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
- if (provider == NULL || provider->provider_id == NULL ||
- provider->data_id == NULL || key == NULL) {
- _LOGE("Invalid parameter");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ arg_list[0] = provider->data_id;
+ arg_list[1] = key;
+ arg_list[2] = old_value;
+ arg_list[3] = new_value;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 4);
+
+ /* Set the request id */
+ reqId = _datacontrol_create_request_id();
+ *request_id = reqId;
+
+ retval =
+ _request_provider(provider, DATACONTROL_TYPE_MAP_SET, b, NULL, reqId);
+ bundle_free(b);
- return convert_to_tizen_error(datacontrol_map_get_with_page((datacontrol_h)provider, key, request_id, page_number, count_per_page));
+ return retval;
}
-EXPORT_API int data_control_map_set(data_control_h provider, const char *key, const char *old_value, const char *new_value, int *request_id)
+EXPORT_API int data_control_map_add(data_control_h provider,
+ const char *key, const char *value, int *request_id)
{
int retval;
+ unsigned int arg_size;
+ bundle *b;
+ const char *arg_list[3];
+ int reqId;
if (provider == NULL || provider->provider_id == NULL ||
- provider->data_id == NULL || key == NULL ||
- old_value == NULL || new_value == NULL) {
+ provider->data_id == NULL || key == NULL || value == NULL) {
_LOGE("Invalid parameter");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
+ retval = _check_cert(provider->provider_id, true, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return convert_to_tizen_error(datacontrol_map_set((datacontrol_h)provider, key, old_value, new_value, request_id));
-}
+ _LOGI("Adds the value in provider_id: %s, data_id: %s",
+ provider->provider_id, provider->data_id);
-EXPORT_API int data_control_map_add(data_control_h provider, const char *key, const char *value, int *request_id)
-{
- int retval;
+ arg_size = (strlen(provider->data_id) + strlen(key) +
+ strlen(value)) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of sending argument (%u) exceeds the maximum limit.",
+ arg_size);
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
- if (provider == NULL || provider->provider_id == NULL ||
- provider->data_id == NULL || key == NULL || value == NULL) {
- _LOGE("Invalid parameter");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ arg_list[0] = provider->data_id;
+ arg_list[1] = key;
+ arg_list[2] = value;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
+
+ /* Set the request id */
+ reqId = _datacontrol_create_request_id();
+ *request_id = reqId;
+
+ retval =
+ _request_provider(provider, DATACONTROL_TYPE_MAP_ADD, b, NULL, reqId);
+ bundle_free(b);
- return convert_to_tizen_error(datacontrol_map_add((datacontrol_h)provider, key, value, request_id));
+ return retval;
}
-EXPORT_API int data_control_map_remove(data_control_h provider, const char *key, const char *value, int *request_id)
+EXPORT_API int data_control_map_remove(data_control_h provider,
+ const char *key, const char *value, int *request_id)
{
int retval;
+ unsigned int arg_size;
+ bundle *b;
+ const char *arg_list[3];
+ int reqId;
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL || key == NULL || value == NULL) {
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
+ retval = _check_cert(provider->provider_id, true, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return convert_to_tizen_error(datacontrol_map_remove((datacontrol_h)provider, key, value, request_id));
+ _LOGI("Removes the value in provider_id: %s, data_id: %s",
+ provider->provider_id, provider->data_id);
+
+ arg_size = (strlen(provider->data_id) + strlen(key) +
+ strlen(value)) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of sending argument (%u) exceeds the maximum limit.",
+ arg_size);
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
+
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ arg_list[0] = provider->data_id;
+ arg_list[1] = key;
+ arg_list[2] = value;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 3);
+
+ /* Set the request id */
+ reqId = _datacontrol_create_request_id();
+ *request_id = reqId;
+
+ retval =
+ _request_provider(provider, DATACONTROL_TYPE_MAP_REMOVE, b, NULL, reqId);
+ bundle_free(b);
+
+ return retval;
}
-EXPORT_API int data_control_map_add_bulk_data(data_control_h provider, data_control_bulk_data_h bulk_data_h, int *request_id)
+EXPORT_API int data_control_map_add_bulk_data(data_control_h provider,
+ data_control_bulk_data_h bulk_data_h, int *request_id)
{
int retval;
+ unsigned int arg_size = 0;
+ bundle *b;
+ bundle *data;
+ const char *arg_list[3];
+ int count;
+ int i;
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL) {
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
+ retval = _check_cert(provider->provider_id, true, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return convert_to_tizen_error(datacontrol_map_add_bulk_data((datacontrol_h)provider, bulk_data_h, request_id));
+ _LOGI("Adds the value in provider_id: %s, data_id: %s",
+ provider->provider_id, provider->data_id);
+ data_control_bulk_data_get_count(bulk_data_h, &count);
+ for (i = 0; i < count; i++) {
+ data_control_bulk_data_get_data(bulk_data_h, i, &data);
+ bundle_foreach(data, _bundle_foreach_check_arg_size_cb, &arg_size);
+ }
+
+ arg_size +=
+ (strlen(provider->data_id) + strlen(provider->provider_id)) * sizeof(char);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of sending argument (%u) exceeds the maximum limit.",
+ arg_size);
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
+
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ arg_list[0] = provider->data_id;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 1);
+ *request_id = _datacontrol_create_request_id();
+
+ retval = _request_provider(provider, DATACONTROL_TYPE_MAP_BULK_ADD, b,
+ bulk_data_h, *request_id);
+ bundle_free(b);
+
+ return retval;
}
-#include <dlog.h>
#include <errno.h>
#include <glib.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <stdio.h>
+
+#include <aul.h>
+#include <appsvc.h>
+#include <pkgmgr-info.h>
#include "data_control_internal.h"
#include "data_control_log.h"
#include "data_control_noti.h"
-#include "data-control-noti.h"
-struct data_control_s {
+typedef struct {
+ GList *cb_list;
+ char *provider_appid;
char *provider_id;
char *data_id;
-};
+ int monitor_id;
+} provider_info_s;
+
+typedef struct {
+ void *user_data;
+ int callback_id;
+ data_control_data_change_cb changed_cb;
+} changed_cb_info_s;
+
+typedef struct {
+ void *user_data;
+ int callback_id;
+ char *provider_id;
+ char *data_id;
+ int timeout_id;
+ data_control_add_callback_result_cb callback;
+} add_callback_result_cb_info_s;
+
+static GList *__add_callback_result_cb_list = NULL;
+static GList *__changed_provider_list = NULL;
+
+static int __callback_result_info_compare_cb(gconstpointer a, gconstpointer b)
+{
+ add_callback_result_cb_info_s *key1 =
+ (add_callback_result_cb_info_s *)a;
+ add_callback_result_cb_info_s *key2 =
+ (add_callback_result_cb_info_s *)b;
+
+ return !(key1->callback_id == key2->callback_id);
+}
+
+static int __provider_info_compare_cb(gconstpointer a, gconstpointer b)
+{
+ provider_info_s *key1 = (provider_info_s *)a;
+ provider_info_s *key2 = (provider_info_s *)b;
+ return (strcmp(key1->provider_id, key2->provider_id) ||
+ strcmp(key1->data_id, key2->data_id));
+}
+
+static int __changed_cb_info_compare_cb(gconstpointer a, gconstpointer b)
+{
+ changed_cb_info_s *key1 = (changed_cb_info_s *)a;
+ changed_cb_info_s *key2 = (changed_cb_info_s *)b;
+
+ return !(key1->callback_id == key2->callback_id);
+}
+
+static void __free_result_cb_info(
+ add_callback_result_cb_info_s *result_cb_info)
+{
+ if (result_cb_info) {
+ if (result_cb_info->provider_id)
+ free(result_cb_info->provider_id);
+ if (result_cb_info->data_id)
+ free(result_cb_info->data_id);
+ if (result_cb_info->timeout_id > 0)
+ g_source_remove(result_cb_info->timeout_id);
+ free(result_cb_info);
+ result_cb_info = NULL;
+ }
+}
+
+static void __free_provider_info(
+ provider_info_s *provider_info)
+{
+ if (provider_info) {
+ if (provider_info->provider_appid)
+ free(provider_info->provider_appid);
+ if (provider_info->provider_id)
+ free(provider_info->provider_id);
+ if (provider_info->data_id)
+ free(provider_info->data_id);
+ if (provider_info->monitor_id > 0)
+ g_dbus_connection_signal_unsubscribe(_get_dbus_connection(),
+ provider_info->monitor_id);
+ g_list_free_full(provider_info->cb_list, free);
+ free(provider_info);
+ provider_info = NULL;
+ }
+}
+
+static void __noti_process(GVariant *parameters)
+{
+ char *provider_id = NULL;
+ char *data_id = NULL;
+ bundle_raw *raw = NULL;
+ bundle *noti_data = NULL;
+ int len = 0;
+ data_control_h provider = NULL;
+ GList *find_list;
+ changed_cb_info_s *cb_info = NULL;
+ provider_info_s find_info;
+ provider_info_s *provider_info;
+ GList *callback_list = NULL;
+ data_control_data_change_type_e type;
+
+ g_variant_get(parameters, "(i&s&s&si)",
+ &type, &provider_id, &data_id, &raw, &len);
+ _LOGI("__noti_process : %d %s %s %d", type, provider_id, data_id, len);
+
+ if (provider_id == NULL || data_id == NULL)
+ return;
+
+ find_info.provider_id = provider_id;
+ find_info.data_id = data_id;
+
+ find_list = g_list_find_custom(__changed_provider_list, &find_info,
+ (GCompareFunc)__provider_info_compare_cb);
+ if (find_list != NULL) {
+ _create_data_control_h(&provider);
+ _set_provider_id(provider, provider_id);
+ _set_data_id(provider, data_id);
+ noti_data = bundle_decode(raw, len);
+ provider_info = (provider_info_s *)find_list->data;
+ callback_list = g_list_first(provider_info->cb_list);
+ for (; callback_list != NULL; callback_list = callback_list->next) {
+ cb_info = callback_list->data;
+ cb_info->changed_cb((data_control_h)provider,
+ type, noti_data, cb_info->user_data);
+ _LOGI("callback called: %s, %s",
+ provider_info->provider_id, provider_info->data_id);
+ }
+ bundle_free(noti_data);
+ _destroy_data_control_h(provider);
+
+ } else {
+ _LOGE("data_control_data_change_cb is null");
+ }
+ _LOGI("__noti_process done");
+}
+
+static void __call_result_callback(int callback_id, int callback_result)
+{
+ add_callback_result_cb_info_s *result_cb_info;
+ add_callback_result_cb_info_s find_info;
+ data_control_h provider;
+ GList *find_list;
+
+ find_info.callback_id = callback_id;
+ find_list = g_list_find_custom(__add_callback_result_cb_list, &find_info,
+ (GCompareFunc)__callback_result_info_compare_cb);
+
+ if (find_list != NULL) {
+ result_cb_info = (add_callback_result_cb_info_s *)find_list->data;
+ if (result_cb_info->callback) {
+ _create_data_control_h(&provider);
+ _set_provider_id(provider, result_cb_info->provider_id);
+ _set_data_id(provider, result_cb_info->data_id);
+
+ result_cb_info->callback(
+ (data_control_h)provider,
+ callback_result,
+ callback_id,
+ result_cb_info->user_data);
+
+ _destroy_data_control_h(provider);
+ } else {
+ _LOGE("data_control_add_callback_result_cb is null");
+ }
+
+ __add_callback_result_cb_list =
+ g_list_remove(__add_callback_result_cb_list, find_list->data);
+ __free_result_cb_info(result_cb_info);
+ } else {
+ _LOGE("add_callback_result_cb_info_s is null");
+ }
+}
+
+/* LCOV_EXCL_START */
+static gboolean __add_callback_result_timeout_handler(gpointer user_data)
+{
+ _LOGE("add data changed callback time out !!!");
+ add_callback_result_cb_info_s *result_cb_info =
+ (add_callback_result_cb_info_s *)user_data;
+ __call_result_callback(result_cb_info->callback_id,
+ DATA_CONTROL_ERROR_IO_ERROR);
+ return FALSE;
+}
+/* LCOV_EXCL_STOP */
+
+static void __noti_add_remove_data_changed_cb_result_process(
+ GVariant *parameters)
+{
+ int callback_id;
+ data_control_error_e callback_result;
+ datacontrol_data_change_type_e type;
+
+ g_variant_get(parameters, "(iii)", &type, &callback_id, &callback_result);
+ _LOGI("__noti_add_remove_data_changed_cb_result_process: %d %d %d",
+ type, callback_id, callback_result);
+
+ if (type == DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT)
+ __call_result_callback(callback_id, callback_result);
+}
+
+static void __handle_noti(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ _LOGI("signal_name: %s", signal_name);
+
+ if (g_strcmp0(signal_name, "noti_data_changed") == 0)
+ __noti_process(parameters);
+ else if (g_strcmp0(signal_name, "noti_add_remove_result") == 0)
+ __noti_add_remove_data_changed_cb_result_process(parameters);
+}
+
+static int __noti_request_appsvc_run(const char *callee_id,
+ char *provider_id, char *data_id, const char *unique_id,
+ int callback_id, int request_type)
+{
+ int pid = -1;
+ char callback_id_str[32] = {0,};
+ char request_type_str[MAX_LEN_DATACONTROL_REQ_TYPE] = {0,};
+ bundle *arg_list = bundle_create();
+ if (!arg_list) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ snprintf(callback_id_str, 32, "%d", callback_id);
+ snprintf(request_type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(request_type));
+
+ appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT);
+ appsvc_set_appid(arg_list, callee_id);
+
+ bundle_add_str(arg_list, OSP_K_DATACONTROL_REQUEST_TYPE, request_type_str);
+ bundle_add_str(arg_list, OSP_K_DATACONTROL_UNIQUE_NAME, unique_id);
+ bundle_add_str(arg_list, OSP_K_DATACONTROL_PROVIDER, provider_id);
+ bundle_add_str(arg_list, OSP_K_DATACONTROL_DATA, data_id);
+ bundle_add_str(arg_list, OSP_K_DATA_CHANGED_CALLBACK_ID, callback_id_str);
+
+ bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP);
+ bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL);
+ bundle_add_str(arg_list, AUL_K_CALLEE_APPID, callee_id);
+ bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1");
+ _LOGI("callee_id %s", callee_id);
+ _LOGI("provider_id %s, data_id %s", provider_id, data_id);
+
+ /* For DataControl CAPI */
+ bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE");
+
+ pid = appsvc_run_service(arg_list, 0, NULL, NULL);
+ if (pid >= 0) {
+ _LOGI("Launch the provider app successfully: %d", pid);
+ bundle_free(arg_list);
+ } else if (pid == APPSVC_RET_EINVAL) {
+ _LOGE("not able to launch service: %d", pid);
+ bundle_free(arg_list);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ } else {
+ _LOGE("unable to launch service: %d", pid);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int _datacontrol_get_data_changed_callback_id(void)
+{
+ static int id = 0;
+ g_atomic_int_inc(&id);
+
+ return id;
+}
EXPORT_API int data_control_add_data_change_cb(
data_control_h provider,
void *result_cb_user_data,
int *callback_id)
{
- int retval;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ changed_cb_info_s *cb_info = NULL;
+ provider_info_s *provider_info = NULL;
+ provider_info_s find_provider_info;
+ int monitor_id = 0;
+ GList *find_list;
+ char *path = NULL;
+ const char *unique_id = NULL;
+ char caller_app_id[255];
+ pid_t pid;
+ add_callback_result_cb_info_s *result_cb_info = NULL;
+ char *provider_app_id = NULL;
+ char *access = NULL;
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ ret = _check_privilege(PRIVILEGE_CONSUMER);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
if (callback == NULL || provider == NULL || callback_id == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
- if (retval == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
- if (retval == DATA_CONTROL_ERROR_PERMISSION_DENIED)
+ ret = _check_cert(provider->provider_id, true, NULL);
+ if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+ ret = _check_cert(provider->provider_id, false, NULL);
+ if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED)
return DATA_CONTROL_ERROR_PERMISSION_DENIED;
}
- return datacontrol_add_data_change_cb(
- (datacontrol_h)provider,
- callback,
- user_data,
- result_callback,
- result_cb_user_data,
- callback_id);
+ _LOGI("provider_id : %s, data_id : %s",
+ provider->provider_id, provider->data_id);
+ ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id,
+ "Sql", getuid(), &provider_app_id, &access);
+ if (ret != PMINFO_R_OK) {
+ _LOGE("unable to get sql data control information, retry with map: %d", ret);
+ ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id,
+ "Map", getuid(), &provider_app_id, &access);
+ if (ret != PMINFO_R_OK) {
+ _LOGE("unable to get map data control information: %d", ret);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ *callback_id = _datacontrol_get_data_changed_callback_id();
+ unique_id = g_dbus_connection_get_unique_name(_get_dbus_connection());
+ _LOGI("unique_id : %s, callback_id %d", unique_id, *callback_id);
+
+ find_provider_info.provider_id = provider->provider_id;
+ find_provider_info.data_id = provider->data_id;
+ find_list = g_list_find_custom(__changed_provider_list, &find_provider_info,
+ (GCompareFunc)__provider_info_compare_cb);
+ if (find_list == NULL) {
+
+ pid = getpid();
+ if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
+ _LOGE("Failed to get appid by pid(%d).", pid);
+ ret = DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ goto err;
+ }
+ path = _get_encoded_path(provider, caller_app_id);
+ if (path == NULL) {
+ _LOGE("cannot get encoded path. out of memory.");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto err;
+ }
+
+ ret = _dbus_signal_init(&monitor_id, path, __handle_noti);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("fail to init dbus signal.");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto err;
+ }
+
+ provider_info = (provider_info_s *)calloc(1, sizeof(provider_info_s));
+ if (provider_info == NULL) {
+ _LOGE("provider_info_s alloc fail out of memory.");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto err;
+ }
+ provider_info->provider_appid = strdup(provider_app_id);
+ provider_info->provider_id = strdup(provider->provider_id);
+ provider_info->data_id = strdup(provider->data_id);
+ provider_info->monitor_id = monitor_id;
+ if (provider_info->provider_id == NULL ||
+ provider_info->data_id == NULL) {
+ _LOGE("data_id alloc fail out of memory.");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ __free_provider_info(provider_info);
+ goto err;
+ }
+ __changed_provider_list =
+ g_list_append(__changed_provider_list, provider_info);
+ } else {
+ provider_info = (provider_info_s *)find_list->data;
+ }
+
+ ret = __noti_request_appsvc_run(
+ provider_app_id,
+ provider_info->provider_id,
+ provider_info->data_id,
+ unique_id,
+ *callback_id,
+ DATACONTROL_TYPE_ADD_DATA_CHANGED_CB);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("__noti_request_appsvc_run error !!!");
+ goto err;
+ }
+
+ cb_info = (changed_cb_info_s *)calloc(1,
+ sizeof(changed_cb_info_s));
+ if (cb_info == NULL) {
+ _LOGE("changed_cb_info_s alloc fail out of memory.");
+ ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ goto err;
+ }
+
+ cb_info->changed_cb = callback;
+ cb_info->user_data = user_data;
+ cb_info->callback_id = *callback_id;
+ provider_info->cb_list = g_list_append(
+ provider_info->cb_list, cb_info);
+
+ result_cb_info =
+ (add_callback_result_cb_info_s *)calloc(1, sizeof(add_callback_result_cb_info_s));
+ result_cb_info->callback_id = *callback_id;
+ result_cb_info->callback = result_callback;
+ result_cb_info->user_data = result_cb_user_data;
+ result_cb_info->provider_id = strdup(provider_info->provider_id);
+ result_cb_info->data_id = strdup(provider_info->data_id);
+ result_cb_info->timeout_id =
+ g_timeout_add(5000, __add_callback_result_timeout_handler, result_cb_info);
+ __add_callback_result_cb_list =
+ g_list_append(__add_callback_result_cb_list, result_cb_info);
+ _LOGI("datacontrol_add_data_change_cb done");
+
+ /* LCOV_EXCL_START */
+err:
+ if (access)
+ free(access);
+ if (provider_app_id)
+ free(provider_app_id);
+ if (path)
+ free(path);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ if (monitor_id > 0)
+ g_dbus_connection_signal_unsubscribe(_get_dbus_connection(), monitor_id);
+ }
+
+ return ret;
+ /* LCOV_EXCL_STOP */
}
-EXPORT_API int data_control_remove_data_change_cb(data_control_h provider, int callback_id)
+EXPORT_API int data_control_remove_data_change_cb(data_control_h provider,
+ int callback_id)
{
- int retval;
+ changed_cb_info_s *removed_cb_info = NULL;
+ changed_cb_info_s cb_info;
+ provider_info_s info;
+ provider_info_s *target_provider_info;
+ add_callback_result_cb_info_s result_cb_info;
+ add_callback_result_cb_info_s *tmp;
+ GList *provider_list = NULL;
+ GList *callback_list = NULL;
+ GList *result_cb_list = NULL;
+ const char *unique_id = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
if (callback_id < 1 || provider == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ ret = _check_privilege(PRIVILEGE_CONSUMER);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
- retval = datacontrol_check_cert(provider->provider_id, true, NULL);
- if (retval == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
- if (retval == DATA_CONTROL_ERROR_PERMISSION_DENIED)
+ ret = _check_cert(provider->provider_id, true, NULL);
+ if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+ ret = _check_cert(provider->provider_id, false, NULL);
+ if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED)
return DATA_CONTROL_ERROR_PERMISSION_DENIED;
}
- return datacontrol_remove_data_change_cb((datacontrol_h)provider, callback_id);
+ info.provider_id = provider->provider_id;
+ info.data_id = provider->data_id;
+
+ provider_list = g_list_find_custom(__changed_provider_list, &info,
+ (GCompareFunc)__provider_info_compare_cb);
+ if (provider_list == NULL) {
+ _LOGE("Cannot find provider info");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ cb_info.callback_id = callback_id;
+ target_provider_info = (provider_info_s *)provider_list->data;
+ callback_list = g_list_find_custom(
+ target_provider_info->cb_list,
+ &cb_info,
+ (GCompareFunc)__changed_cb_info_compare_cb);
+ if (callback_list == NULL) {
+ _LOGE("Cannot find changed callback info");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ removed_cb_info = (changed_cb_info_s *)callback_list->data;
+ target_provider_info->cb_list
+ = g_list_remove(target_provider_info->cb_list, removed_cb_info);
+ free(removed_cb_info);
+
+ if (g_list_length(target_provider_info->cb_list) == 0) {
+ unique_id = g_dbus_connection_get_unique_name(_get_dbus_connection());
+ _LOGI("unique_id : %s", unique_id);
+ ret = __noti_request_appsvc_run(
+ target_provider_info->provider_appid,
+ target_provider_info->provider_id,
+ target_provider_info->data_id,
+ unique_id,
+ callback_id,
+ DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("__sql_request_provider fail %d", ret);
+ return ret;
+ }
+
+ __changed_provider_list =
+ g_list_remove(__changed_provider_list, target_provider_info);
+ __free_provider_info(target_provider_info);
+ }
+
+ result_cb_info.callback_id = callback_id;
+ result_cb_list =
+ g_list_find_custom(__add_callback_result_cb_list, &result_cb_info,
+ (GCompareFunc)__callback_result_info_compare_cb);
+ if (result_cb_list) {
+ tmp = (add_callback_result_cb_info_s *)result_cb_list->data;
+ __add_callback_result_cb_list =
+ g_list_remove(__add_callback_result_cb_list, result_cb_list->data);
+ __free_result_cb_info(tmp);
+ }
+ return DATA_CONTROL_ERROR_NONE;
}
#include <stdlib.h>
-#include <dlog.h>
+#include <sqlite3.h>
+
+#include <aul/aul.h>
#include <bundle.h>
-#include <data-control-provider.h>
-#include <data-control-types.h>
+#include <bundle_internal.h>
+
+#include "data_control_provider_internal.h"
+#include "data_control_types.h"
+#include "data_control_provider.h"
+#include "data_control_sql.h"
+#include "data_control_log.h"
+#include "data_control_internal.h"
+
+#define INSERT_STMT_CONST_LEN 25
+#define DELETE_STMT_CONST_LEN 12
+#define UPDATE_STMT_CONST_LEN 15
+#define SELECT_STMT_CONST_LEN 13
+#define WHERE_COND_CONST_LEN 7
+#define ORDER_CLS_CONST_LEN 10
+
+#define QUERY_MAXLEN 4096
+#define ROW_ID_SIZE 32
+#define RESULT_PATH_MAX 512
+#define MAX_COLUMN_COUNT 32767 /* Base on sqlite3 maximum column count */
+
+#define RESULT_PAGE_NUMBER "RESULT_PAGE_NUMBER"
+#define MAX_COUNT_PER_PAGE "MAX_COUNT_PER_PAGE"
+#define RESULT_VALUE_COUNT "RESULT_VALUE_COUNT"
+
+#define PACKET_INDEX_REQUEST_RESULT 0
+#define PACKET_INDEX_ERROR_MSG 1
+#define PACKET_INDEX_SELECT_RESULT_FILE 2
+#define PACKET_INDEX_ROW_ID 2
+#define PACKET_INDEX_VALUE_COUNT 2
+#define PACKET_INDEX_GET_RESULT_FILE 3
+
+#define PACKET_INDEX_DATAID 0
+#define PACKET_INDEX_MAP 2
+
+#define PACKET_INDEX_UPDATEWHERE 1
+#define PACKET_INDEX_DELETEWHERE 1
+
+#define PACKET_INDEX_MAP_KEY 1
+#define PACKET_INDEX_MAP_VALUE_1ST 2
+#define PACKET_INDEX_MAP_VALUE_2ND 3
+#define PACKET_INDEX_MAP_PAGE_NO 2
+#define PACKET_INDEX_MAP_COUNT_PER_PAGE 3
+
+#define DATA_CONTROL_BUS_NAME "org.tizen.data_control_service"
+#define DATA_CONTROL_OBJECT_PATH "/org/tizen/data_control_service"
+#define DATA_CONTROL_INTERFACE_NAME "org.tizen.data_control_service"
+#define DATA_CONTROL_DATA_CHANGE_DATA_CHANGED "noti_data_changed"
+#define DATA_CONTROL_DATA_CHANGE_ADD_REMOVE_RESULT "noti_add_remove_result"
+
+typedef struct {
+ int no_of_elements;
+ int length;
+ char **keys;
+ char **vals;
+} key_val_pair;
+
+typedef struct datacontrol_consumer {
+ int monitor_id;
+ char *appid;
+ char *object_path;
+ char *unique_id;
+} datacontrol_consumer_info;
+
+typedef struct {
+ void *user_data;
+ int callback_id;
+ data_control_provider_data_change_consumer_filter_cb callback;
+} changed_noti_consumer_filter_info_s;
+
+static GHashTable *__request_table = NULL;
+static GHashTable *__socket_pair_hash = NULL;
+static sqlite3 *__provider_db = NULL;
+
+static data_control_provider_sql_cb sql_callback;
+static data_control_provider_map_cb map_callback;
+static data_control_provider_bulk_cb sql_bulk_callback;
+static data_control_provider_bulk_cb map_bulk_callback;
+
+static void *sql_user_data;
+static void *map_user_data;
+static void *sql_bulk_callback_user_data = NULL;
+static void *map_bulk_callback_user_data = NULL;
+
+static GList *__noti_consumer_app_list = NULL;
+static GList *__noti_consumer_filter_info_list = NULL;
+
+static int __create_consumer_list_db();
+static int __delete_consumer_list_db_info(char *unique_id);
+
+static int __is_null_sql_callback(data_control_provider_sql_cb callback)
+{
+ if (callback.select_cb == NULL &&
+ callback.insert_cb == NULL &&
+ callback.delete_cb == NULL &&
+ callback.update_cb == NULL)
+ return 1;
+
+ return 0;
+}
+
+static int __is_null_map_callback(data_control_provider_map_cb callback)
+{
+ if (callback.get_cb == NULL &&
+ callback.set_cb == NULL &&
+ callback.add_cb == NULL &&
+ callback.remove_cb == NULL)
+ return 1;
+
+ return 0;
+}
+
+static void __free_bundle_data(gpointer data)
+{
+ if (data) {
+ bundle_free(data);
+ data = NULL;
+ }
+}
+
+static void __free_data(gpointer data)
+{
+ if (data) {
+ free(data);
+ data = NULL;
+ }
+}
+
+static void __initialize_provider(void)
+{
+ int result;
+ __request_table = g_hash_table_new_full(g_int_hash, g_int_equal,
+ __free_data, __free_bundle_data);
+ __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ free, _socket_info_free);
+ result = __create_consumer_list_db();
+ if (result != DATA_CONTROL_ERROR_NONE)
+ _LOGE("fail to create consumer list db");
+}
+
+static int __provider_new_request_id(void)
+{
+ static int id = 0;
+ g_atomic_int_inc(&id);
+ return id;
+}
+
+static int __data_changed_filter_cb_info_compare_cb(gconstpointer a, gconstpointer b)
+{
+ changed_noti_consumer_filter_info_s *key1 =
+ (changed_noti_consumer_filter_info_s *)a;
+ changed_noti_consumer_filter_info_s *key2 =
+ (changed_noti_consumer_filter_info_s *)b;
+
+ return !(key1->callback_id == key2->callback_id);
+}
+
+static int __noti_consumer_app_list_compare_cb(gconstpointer a, gconstpointer b)
+{
+ datacontrol_consumer_info *info_a = (datacontrol_consumer_info *)a;
+ datacontrol_consumer_info *info_b = (datacontrol_consumer_info *)b;
+
+ return strcmp(info_a->unique_id, info_b->unique_id);
+}
+
+static void __free_consumer_info(const gchar *name)
+{
+ datacontrol_consumer_info find_key;
+ datacontrol_consumer_info *info;
+ GList *find_list = NULL;
+ int result;
+
+ find_key.unique_id = (char *)name;
+ find_list = g_list_find_custom(__noti_consumer_app_list, &find_key,
+ (GCompareFunc)__noti_consumer_app_list_compare_cb);
+ if (find_list == NULL) {
+ _LOGI("__free_consumer_info %s not exist", name);
+ return;
+ }
+
+ info = (datacontrol_consumer_info *)find_list->data;
+ result = __delete_consumer_list_db_info(info->unique_id);
+ if (result != DATA_CONTROL_ERROR_NONE)
+ _LOGE("__delete_consumer_list_db_info fail %d", result);
+
+ if (info->appid)
+ free(info->appid);
+ if (info->object_path)
+ free(info->object_path);
+ if (info->unique_id)
+ free(info->unique_id);
+ g_bus_unwatch_name(info->monitor_id);
+
+ __noti_consumer_app_list =
+ g_list_remove(__noti_consumer_app_list, find_list->data);
+
+ free(info);
+ _LOGI("__free_consumer_info done");
+}
+static int __check_consumer_cert(const char *provider_id,
+ const char *consumer_appid,
+ data_control_data_change_type_e type)
+{
+ bool is_map;
+
+ if (consumer_appid == NULL)
+ return DATA_CONTROL_ERROR_IO_ERROR;
+
+ if (type >= DATA_CONTROL_DATA_CHANGE_SQL_UPDATE &&
+ type <= DATA_CONTROL_DATA_CHANGE_SQL_DELETE)
+ is_map = false;
+ else
+ is_map = true;
+
+ return _check_cert(provider_id, is_map, consumer_appid);
+}
+
+int __datacontrol_get_data_changed_filter_callback_id(void)
+{
+ static int id = 0;
+ g_atomic_int_inc(&id);
+
+ return id;
+}
+
+static int __get_int_from_str(const char *str)
+{
+ int result = 0;
+ char *pend;
+ errno = 0;
+ result = strtol(str, &pend, 10);
+ if ((result == LONG_MIN || result == LONG_MAX)
+ && errno != 0) {
+ result = 0;
+ }
+
+ if (*pend != '\0')
+ result = 0;
+
+ return result;
+}
+
+static bundle *__get_bundle_data_from_fd(int fd)
+{
+ bundle *b = NULL;
+ int len = 0;
+ int ret;
+ char *buf;
+
+ ret = read(fd, &len, sizeof(int));
+ if (ret < sizeof(int)) {
+ _LOGE("read error :%d", ret);
+ return NULL;
+ }
+ LOGD("read len : %d", len);
+
+ if (len > 0 && len < MAX_REQUEST_ARGUMENT_SIZE) {
+ buf = (char *)calloc(len, sizeof(char));
+ if (buf == NULL) {
+ _LOGE("calloc fail");
+ return NULL;
+ }
+ ret = read(fd, buf, len);
+ if (ret < len) {
+ _LOGE("read error :%d", ret);
+ if (buf)
+ free(buf);
+ return NULL;
+ }
+ b = bundle_decode_raw((bundle_raw *)buf, len);
+
+ if (buf)
+ free(buf);
+ } else {
+ _LOGE("__get_bundle_data_from_fd read count : %d", len);
+ }
+
+ return b;
+}
+
+static data_control_bulk_data_h __get_bulk_data_from_fd(int fd)
+{
+ data_control_bulk_data_h ret_bulk_data_h = NULL;
+ int size = 0;
+ int ret;
+ int i;
+ bundle *data = NULL;
+
+ data_control_bulk_data_create(&ret_bulk_data_h);
+ ret = read(fd, &size, sizeof(int));
+ if (ret < sizeof(int)) {
+ _LOGE("read error :%d", ret);
+ data_control_bulk_data_destroy(ret_bulk_data_h);
+ return NULL;
+ }
+
+ _LOGI("bulk data size : %d", size);
+ if (size < 0 || size >= MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("Invalid data size");
+ data_control_bulk_data_destroy(ret_bulk_data_h);
+ return NULL;
+ }
+
+ for (i = 0; i < size; i++) {
+ _LOGI("bulk data : %d", i);
+ data = __get_bundle_data_from_fd(fd);
+ if (data == NULL) {
+ _LOGE("get bundle data from fd fail");
+ data_control_bulk_data_destroy(ret_bulk_data_h);
+ return NULL;
+ }
+ data_control_bulk_data_add(ret_bulk_data_h, data);
+ bundle_free(data);
+ }
+ return ret_bulk_data_h;
+}
+
+static void __on_name_appeared(GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ _LOGI("name appeared : %s", name);
+}
+
+static void __on_name_vanished(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ _LOGI("name vanished : %s", name);
+ __free_consumer_info(name);
+}
+
+static int __init_changed_noti_consumer_list()
+{
+ char *app_id = NULL;
+ char *unique_id = NULL;
+ char *object_path = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ sqlite3_stmt *stmt = NULL;
+ char query[QUERY_MAXLEN];
+ datacontrol_consumer_info *consumer_info = NULL;
+
+ sqlite3_snprintf(QUERY_MAXLEN, query,
+ "SELECT app_id, object_path, unique_id " \
+ "FROM data_control_consumer_path_list");
+
+ _LOGI("__init_changed_noti_consumer_list query : %s", query);
+ ret = sqlite3_prepare_v2(__provider_db, query, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("prepare stmt fail");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ while (SQLITE_ROW == sqlite3_step(stmt)) {
+ app_id = (char *)sqlite3_column_text(stmt, 0);
+ if (!app_id) {
+ _LOGE("Failed to get package name\n");
+ continue;
+ }
+
+ object_path = (char *)sqlite3_column_text(stmt, 1);
+ if (!object_path) {
+ _LOGE("Failed to get object_path\n");
+ continue;
+ }
+
+ unique_id = (char *)sqlite3_column_text(stmt, 2);
+ if (!unique_id) {
+ _LOGE("Failed to get unique_id\n");
+ continue;
+ }
+ _LOGI("sql : app_id : %s, object_path : %s, unique_id : %s",
+ app_id, object_path, unique_id);
+
+ consumer_info = (datacontrol_consumer_info *)
+ calloc(1, sizeof(datacontrol_consumer_info));
+ consumer_info->appid = strdup(app_id);
+ consumer_info->object_path = strdup(object_path);
+ consumer_info->unique_id = strdup(unique_id);
+
+ consumer_info->monitor_id = g_bus_watch_name_on_connection(
+ _get_dbus_connection(),
+ consumer_info->unique_id,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ __on_name_appeared,
+ __on_name_vanished,
+ consumer_info,
+ NULL);
+
+ if (consumer_info->monitor_id == 0) {
+ _LOGE("g_bus_watch_name_on_connection fail");
+
+ free(consumer_info->appid);
+ free(consumer_info->object_path);
+ free(consumer_info->unique_id);
+ free(consumer_info);
+ continue;
+ }
+
+ _LOGI("noti consumer_app_list append %s", consumer_info->object_path);
+ __noti_consumer_app_list =
+ g_list_append(__noti_consumer_app_list, consumer_info);
+ }
+ sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
+
+ return ret;
+}
+
+static int __delete_consumer_list_db_info(char *unique_id)
+{
+ int r;
+ char *error = NULL;
+ char query[QUERY_MAXLEN];
+ sqlite3_snprintf(QUERY_MAXLEN, query,
+ "DELETE FROM data_control_consumer_path_list WHERE unique_id = %Q",
+ unique_id);
+ _LOGI("consumer list db DELETE : %s, unique_id : %s", query, unique_id);
+ r = sqlite3_exec(__provider_db, query, NULL, NULL, &error);
+ if (r != SQLITE_OK) {
+ _LOGE("sqlite3_exec error(query = %s, error = %s)", query, error);
+ sqlite3_free(error);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGI("__delete_consumer_list_db_info done");
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+
+static int __create_consumer_list_db()
+{
+ char *db_path = NULL;
+ int ret = SQLITE_OK;
+ int open_flags = (SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
+ char *table_command =
+ "CREATE TABLE IF NOT EXISTS data_control_consumer_path_list" \
+ "(app_id TEXT NOT NULL, provider_id TEXT NOT NULL, "\
+ "data_id TEXT NOT NULL, " \
+ "unique_id TEXT NOT NULL, object_path TEXT NOT NULL, " \
+ "PRIMARY KEY(object_path))";
+
+ if (__provider_db == NULL) {
+ db_path = _get_encoded_db_path();
+ if (db_path == NULL)
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ _LOGI("data-control provider db path : %s", db_path);
+
+ ret = sqlite3_open_v2(db_path, &__provider_db, open_flags, NULL);
+ free(db_path);
+ if (ret != SQLITE_OK) {
+ _LOGE("database creation failed with error: %d", ret);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ ret = sqlite3_exec(__provider_db, table_command, NULL, NULL, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("database table creation failed with error: %d", ret);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ ret = __init_changed_noti_consumer_list();
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("__init_changed_noti_consumer_list fail %d", ret);
+ return ret;
+ }
+ }
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+static int __get_sender_pid(const char *sender_name)
+{
+ GDBusMessage *msg = NULL;
+ GDBusMessage *reply = NULL;
+ GError *err = NULL;
+ GVariant *body;
+ int pid = 0;
+
+ msg = g_dbus_message_new_method_call("org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID");
+ if (!msg) {
+ _LOGE("Can't allocate new method call");
+ goto out;
+ }
+
+ g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
+ reply =
+ g_dbus_connection_send_message_with_reply_sync(_get_dbus_connection(),
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ &err);
+
+ if (!reply) {
+ if (err != NULL) {
+ _LOGE("Failed to get pid [%s]", err->message);
+ g_error_free(err);
+ }
+ goto out;
+ }
+
+ body = g_dbus_message_get_body(reply);
+ g_variant_get(body, "(u)", &pid);
+
+out:
+ if (msg)
+ g_object_unref(msg);
+ if (reply)
+ g_object_unref(reply);
+
+ return pid;
+}
+
+static int __insert_consumer_list_db_info(char *app_id, char *provider_id,
+ char *data_id, char *unique_id, char *object_path)
+{
+ int r;
+ char *error = NULL;
+ char query[QUERY_MAXLEN];
+ sqlite3_snprintf(QUERY_MAXLEN, query,
+ "INSERT OR REPLACE INTO data_control_consumer_path_list(app_id, " \
+ "provider_id, data_id, unique_id, object_path)" \
+ "VALUES (%Q, %Q, %Q, %Q, %Q)",
+ app_id, provider_id, data_id, unique_id, object_path);
+ _LOGI("consumer list db insert sql : %s", query);
+
+ r = sqlite3_exec(__provider_db, query, NULL, NULL, &error);
+ if (r != SQLITE_OK) {
+ _LOGE("sqlite3_exec error(query = %s, error = %s)", query, error);
+ sqlite3_free(error);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+static int __set_consumer_app_list(
+ char *caller,
+ char *object_path,
+ char *unique_id)
+{
+ datacontrol_consumer_info find_key;
+ datacontrol_consumer_info *consumer_info;
+ GList *find_list = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ _LOGI("set consumer_app_list caller : %s, path : %s, unique_id : %s",
+ caller, object_path, unique_id);
+
+ find_key.unique_id = unique_id;
+ find_list = g_list_find_custom(__noti_consumer_app_list,
+ &find_key,
+ (GCompareFunc)__noti_consumer_app_list_compare_cb);
+
+ if (!find_list) {
+ consumer_info = (datacontrol_consumer_info *)
+ calloc(1, sizeof(datacontrol_consumer_info));
+ consumer_info->appid = strdup(caller);
+ consumer_info->object_path = strdup(object_path);
+ consumer_info->unique_id = strdup(unique_id);
+
+ consumer_info->monitor_id = g_bus_watch_name_on_connection(
+ _get_dbus_connection(),
+ consumer_info->unique_id,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ __on_name_appeared,
+ __on_name_vanished,
+ consumer_info,
+ NULL);
+ if (consumer_info->monitor_id == 0) {
+ _LOGE("g_bus_watch_name_on_connection fail");
+
+ free(consumer_info->appid);
+ free(consumer_info->object_path);
+ free(consumer_info->unique_id);
+ free(consumer_info);
+
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ _LOGI("new noti consumer_app_list append %s",
+ consumer_info->object_path);
+ __noti_consumer_app_list =
+ g_list_append(__noti_consumer_app_list, consumer_info);
+ }
+ return ret;
+}
+
+static bundle *__set_result(bundle *b, datacontrol_request_type type, void *data)
+{
+ bundle *res = bundle_create();
+
+ /* Set the type */
+ char type_str[MAX_LEN_DATACONTROL_REQ_TYPE] = {0,};
+ const char *request_type;
+ const char *provider_id;
+ const char *data_id;
+ const char *request_id;
+ const char *caller_appid;
+ const char *list[3];
+ const char *page_num = bundle_get_val(b, RESULT_PAGE_NUMBER);
+ const char *count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE);
+
+ if (type == DATACONTROL_TYPE_UNDEFINED || type == DATACONTROL_TYPE_ERROR) {
+ request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+ if (request_type)
+ strncpy(type_str, request_type, MAX_LEN_DATACONTROL_REQ_TYPE);
+ _LOGI("type is %s", type_str);
+
+ } else {
+ snprintf(type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)type);
+ }
+
+ bundle_add_str(res, OSP_K_DATACONTROL_REQUEST_TYPE, type_str);
+
+ /* Set the provider id */
+ provider_id = bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+ bundle_add_str(res, OSP_K_DATACONTROL_PROVIDER, provider_id);
+
+ /* Set the data id */
+ data_id = bundle_get_val(b, OSP_K_DATACONTROL_DATA);
+ bundle_add_str(res, OSP_K_DATACONTROL_DATA, data_id);
+
+ /* Set the caller request id */
+ request_id = bundle_get_val(b, OSP_K_REQUEST_ID);
+ bundle_add_str(res, OSP_K_REQUEST_ID, request_id);
+
+ caller_appid = bundle_get_val(b, AUL_K_CALLER_APPID);
+ bundle_add_str(res, AUL_K_CALLER_APPID, caller_appid);
+
+ switch (type) {
+ case DATACONTROL_TYPE_SQL_SELECT:
+ {
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+ list[PACKET_INDEX_SELECT_RESULT_FILE] = DATACONTROL_EMPTY;
+
+ page_num = bundle_get_val(b, RESULT_PAGE_NUMBER);
+ count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE);
+
+ _LOGI("page num: %s, count_per_page: %s", page_num, count_per_page);
+
+ bundle_add_str(res, RESULT_PAGE_NUMBER, page_num);
+ bundle_add_str(res, MAX_COUNT_PER_PAGE, count_per_page);
+
+ bundle_add_str_array(res, OSP_K_ARG, list, 3);
+
+ break;
+ }
+ case DATACONTROL_TYPE_SQL_BULK_INSERT:
+ {
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ break;
+ }
+ case DATACONTROL_TYPE_SQL_INSERT:
+ {
+ long long row_id = *(long long *)data;
+
+ const char *list[3];
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+ /* Set the row value */
+ char row_str[ROW_ID_SIZE] = {0,};
+ snprintf(row_str, ROW_ID_SIZE, "%lld", row_id);
+
+ list[PACKET_INDEX_ROW_ID] = row_str;
+ bundle_add_str_array(res, OSP_K_ARG, list, 3);
+ break;
+ }
+ case DATACONTROL_TYPE_SQL_UPDATE:
+ case DATACONTROL_TYPE_SQL_DELETE:
+ {
+ const char *list[2];
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_BULK_ADD:
+ {
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_GET:
+ {
+ const char *list[4];
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ const char *page_num = bundle_get_val(b, RESULT_PAGE_NUMBER);
+ const char *count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE);
+ const char *value_count = bundle_get_val(b, RESULT_VALUE_COUNT);
+
+ bundle_add_str(res, RESULT_PAGE_NUMBER, page_num);
+ bundle_add_str(res, MAX_COUNT_PER_PAGE, count_per_page);
+ bundle_add_str(res, RESULT_VALUE_COUNT, value_count);
+
+ break;
+ }
+ case DATACONTROL_TYPE_ADD_DATA_CHANGED_CB:
+ {
+ const char *list[2];
+ char result_str[2] = {0,};
+ bool result = *(bool *)data;
+ snprintf(result_str, 2, "%d", result);
+
+ list[PACKET_INDEX_REQUEST_RESULT] = result_str; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ break;
+ }
+ case DATACONTROL_TYPE_UNDEFINED: /* DATACONTROL_TYPE_MAP_SET || ADD || REMOVE */
+ {
+ const char *list[2];
+ list[PACKET_INDEX_REQUEST_RESULT] = "1"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
+
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ break;
+ }
+ default: /* Error */
+ {
+ const char *list[2];
+ list[PACKET_INDEX_REQUEST_RESULT] = "0"; /* request result */
+ list[PACKET_INDEX_ERROR_MSG] = (char *)data; /* error string */
+
+ bundle_add_str_array(res, OSP_K_ARG, list, 2);
+ break;
+ }
+ }
+
+ return res;
+}
+
+static int __send_select_result(int fd, bundle *b, void *data)
+{
+ /*
+ In this function, the result set is written in socket as specific form.
+ [sizeof(int)] column count
+ [sizeof(int)] column type x N
+ [ variant ] (column name leng, column name) x N
+ [sieeof(int)] total size of column names
+ [sizeof(int)] row count
+ [ variant ] (type, size, content) x N
+ */
+
+ sqlite3_stmt *state = (sqlite3_stmt *)data;
+ int column_count = DATACONTROL_RESULT_NO_DATA;
+ int i = 0;
+ char *column_name = NULL;
+ int total_len_of_column_names = 0;
+ int count_per_page = 0;
+ int page_number = 1;
+ int offset = 0;
+ sqlite3_int64 offset_idx = 0;
+ sqlite3_int64 row_count = 0;
+ unsigned int nb = 0;
+ int type = 0;
+ int column_name_len;
+ const char *page_number_str;
+ int size = 0;
+ void *value = NULL;
+ int column_type;
+ long long tmp_long = 0;
+ double tmp_double = 0.0;
+ void *buf = NULL;
+ int buf_len = 0;
+ const char *count_per_page_str;
+
+ _LOGI("__send_select_result");
+ if (b == NULL || data == NULL) {
+ _LOGE("The input param is invalid.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (sqlite3_reset(state) != SQLITE_OK) {
+ _LOGE("sqlite3_reset() is failed.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (sqlite3_step(state) != SQLITE_ROW) {
+ _LOGE("The DB does not have another row.");
+ if (_write_socket(fd, &column_count, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a column_count to a file descriptor is failed.");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ return DATA_CONTROL_ERROR_NONE;
+ }
+
+ /* 1. column count */
+ column_count = sqlite3_column_count(state);
+ if (_write_socket(fd, &column_count, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGI("Writing a column_count %d", column_count);
+
+ /*
+ 2. column type x column_count
+ #define SQLITE_INTEGER 1
+ #define SQLITE_FLOAT 2
+ #define SQLITE_TEXT 3
+ #define SQLITE_BLOB 4
+ #define SQLITE_NULL 5
+ */
+ for (i = 0; i < column_count; i++) {
+ type = sqlite3_column_type(state, i);
+ if (_write_socket(fd, &type, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGI("Writing a type to a file descriptor is failed.");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ _LOGI("Writing a column_type %d", type);
+ }
+
+ /* 3. column name x column_count */
+ for (i = 0; i < column_count; i++) {
+ column_name = (char *)sqlite3_column_name(state, i);
+ if (column_name == NULL) {
+ _LOGI("sqlite3_column_name is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ } else {
+ column_name_len = strlen(column_name) + 1;
+ if (_write_socket(fd, &column_name_len, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGI("Writing a column_name_len to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGI("Writing a column_name_len %d", column_name_len);
+
+ if (_write_socket(fd, column_name, column_name_len, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGI("Writing a column_name to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ total_len_of_column_names += strlen(column_name);
+ _LOGI("Writing a column_name %s", column_name);
+ }
+ }
+
+ /* 4. total length of column names */
+ if (_write_socket(fd, &total_len_of_column_names, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGI("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGI("Writing a total_len_of_column_names %d", total_len_of_column_names);
+
+ page_number_str = bundle_get_val(b, RESULT_PAGE_NUMBER);
+ count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE);
+
+ _LOGI("page_number: %s, per_page: %s", page_number_str, count_per_page_str);
+
+ /* 5. type, size and value of each element */
+ if (page_number_str != NULL)
+ page_number = atoi(page_number_str);
+ else
+ page_number = 1;
+
+ if (count_per_page_str != NULL)
+ count_per_page = atoi(count_per_page_str);
+ else
+ count_per_page = 20;
+
+ offset = (page_number - 1) * count_per_page;
+
+ _LOGI("page_number: %d, count_per_page: %d, offset: %d",
+ page_number, count_per_page, offset);
+
+ if (sqlite3_reset(state) != SQLITE_OK) {
+ _LOGE("sqlite3_reset() is failed.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (sqlite3_step(state) != SQLITE_ROW) {
+ _LOGE("The DB does not have another row.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ do {
+ offset_idx++;
+ if (offset_idx > offset)
+ ++row_count;
+ } while (sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page);
+
+ /* 6. row count */
+ if (_write_socket(fd, &row_count, sizeof(row_count), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGI("Writing a row_count to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ _LOGI("Writing a row_count %lld", row_count);
+
+ row_count = 0;
+ offset_idx = 0;
+ if (sqlite3_reset(state) != SQLITE_OK) {
+ _LOGI("sqlite3_reset() is failed.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (sqlite3_step(state) != SQLITE_ROW) {
+ _LOGE("The DB does not have another row.");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ do {
+ offset_idx++;
+ if (offset_idx > offset) {
+ ++row_count;
+ for (i = 0; i < column_count; ++i) {
+ column_type = sqlite3_column_type(state, i);
+
+ switch (column_type) {
+ case SQLITE_INTEGER:
+ type = 1;
+ size = sizeof(long long);
+ tmp_long = sqlite3_column_int64(state, i);
+ value = &tmp_long;
+ break;
+ case SQLITE_FLOAT:
+ type = 2;
+ size = sizeof(double);
+ tmp_double = sqlite3_column_double(state, i);
+ value = &tmp_double;
+ break;
+ case SQLITE_TEXT:
+ type = 3;
+ value = (char *)sqlite3_column_text(state, i);
+ if (value)
+ size = strlen(value) + 1;
+ else
+ size = 0;
+ break;
+ case SQLITE_BLOB:
+ type = 4;
+ size = sqlite3_column_bytes(state, i);
+ value = (char *)sqlite3_column_blob(state, i);
+ break;
+ case SQLITE_NULL:
+ type = 5;
+ size = 0;
+ break;
+ default:
+ _LOGI("The column type is invalid.");
+ break;
+ }
+
+ if (value == NULL && type != 5)
+ return DATA_CONTROL_ERROR_IO_ERROR;
+
+ buf_len = sizeof(int) * 2 + size;
+ buf = calloc(buf_len, sizeof(void));
+ if (buf == NULL) {
+ _LOGE("calloc failed");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+ memcpy(buf, &type, sizeof(int));
+ memcpy(buf + sizeof(int), &size, sizeof(int));
+ if (size > 0)
+ memcpy(buf + sizeof(int) + sizeof(int), value, size);
+
+ if (_write_socket(fd, buf, buf_len, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a size to a file descriptor is failed. errno = %d", errno);
+ free(buf);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ free(buf);
+
+ }
+ _LOGI("row_count ~~~~ %lld", row_count);
+
+ }
+
+ } while (sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page);
+
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+static int __send_get_value_result(int fd, bundle *b, void *data)
+{
+ int i = 0;
+ char **value_list = (char **)data;
+ const char *page_num_str = bundle_get_val(b, RESULT_PAGE_NUMBER);
+ const char *count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE);
+ const char *value_count_str = bundle_get_val(b, RESULT_VALUE_COUNT);
+ int page_number = 0;
+ int count_per_page = 0;
+ int value_count = 0;
+ int current_offset = 0;
+ int remain_count = 0;
+ unsigned int nb;
+ int add_value_count;
+ int length;
+
+ _LOGI("page num: %s, count_per_page: %s, value_count %s",
+ page_num_str, count_per_page_str, value_count_str);
+
+ if (page_num_str)
+ page_number = __get_int_from_str(page_num_str);
+ if (count_per_page_str)
+ count_per_page = __get_int_from_str(count_per_page_str);
+ if (value_count_str)
+ value_count = __get_int_from_str(value_count_str);
+
+ current_offset = (page_number - 1) * count_per_page;
+ remain_count = value_count - current_offset;
+ remain_count = (remain_count > 0) ? remain_count : 0; /* round off to zero if the negative num is found */
+
+ add_value_count =
+ (count_per_page > remain_count) ? remain_count : count_per_page;
+
+ _LOGI("add_value_count: %d, current_offset: %d, remain_count %d",
+ add_value_count, current_offset, remain_count);
+
+ if (_write_socket(fd, &add_value_count, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a length to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ add_value_count += current_offset;
+
+ for (i = current_offset; i < add_value_count; i++) {
+ length = strlen(value_list[i]);
+ _LOGI("length = %d", length);
+ if (_write_socket(fd, &length, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a length to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGI("value_list = %s", value_list[i]);
+ if (_write_socket(fd, value_list[i], length, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a value_list to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+static int __send_bulk_result(int fd, void *data)
+{
+ data_control_bulk_result_data_h bulk_results =
+ (data_control_bulk_result_data_h)data;
+ int count;
+ int i;
+ int result;
+ bundle_raw *encode_data = NULL;
+ int encode_datalen = 0;
+ bundle *result_data;
+ unsigned int nb = 0;
+
+ data_control_bulk_result_data_get_count(bulk_results, &count);
+ if (_write_socket(fd, &count, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a result count to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ LOGD("__send_bulk_result %d", count);
+
+ for (i = 0; i < count; i++) {
+ data_control_bulk_result_data_get_result_data(bulk_results, i,
+ &result_data, &result);
+ if (_write_socket(fd, &result, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a result to a file descriptor is failed. errno = %d", errno);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (result_data != NULL) {
+ bundle_encode_raw(result_data, &encode_data, &encode_datalen);
+ if (encode_data == NULL) {
+ _LOGE("bundle encode error");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ if (_write_socket(fd, &encode_datalen, sizeof(int), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a encode_datalen to a file descriptor is failed. errno = %d", errno);
+ free(encode_data);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (_write_socket(fd, encode_data, encode_datalen, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("Writing a encode_data to a file descriptor is failed. errno = %d", errno);
+ free(encode_data);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGE("result %d, encode_datalen %d", result, encode_datalen);
+ free(encode_data);
+ encode_data = NULL;
+ encode_datalen = 0;
+ }
+ return DATA_CONTROL_ERROR_NONE;
+}
+
+int __datacontrol_send_async(int sockfd, bundle *kb,
+ datacontrol_request_type type, void *data)
+{
+ bundle_raw *kb_data = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ int datalen = 0;
+ char *buf;
+ int total_len = 0;
+ unsigned int nb = 0;
+
+ _LOGI("send async ~~~");
+ bundle_encode_raw(kb, &kb_data, &datalen);
+ if (kb_data == NULL) {
+ _LOGE("bundle encode error");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* encoded bundle + encoded bundle len */
+ buf = (char *)calloc(datalen + 4, sizeof(char));
+ if (buf == NULL) {
+ _LOGE("buf calloc error");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+ memcpy(buf, &datalen, sizeof(datalen));
+ memcpy(buf + sizeof(datalen), kb_data, datalen);
+
+ total_len = sizeof(datalen) + datalen;
+
+ _LOGI("write : %d", datalen);
+ if (_write_socket(sockfd, buf, total_len, &nb) != DATA_CONTROL_ERROR_NONE) {
+ _LOGI("write data fail ");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ if (DATACONTROL_TYPE_SQL_SELECT == type)
+ ret = __send_select_result(sockfd, kb, data);
+ else if (DATACONTROL_TYPE_MAP_GET == type)
+ ret = __send_get_value_result(sockfd, kb, data);
+ else if (DATACONTROL_TYPE_SQL_BULK_INSERT == type ||
+ DATACONTROL_TYPE_MAP_BULK_ADD == type)
+ ret = __send_bulk_result(sockfd, data);
+
+out:
+ free(buf);
+ bundle_free_encoded_rawdata(&kb_data);
+
+ return ret;
+}
+
+static int __send_result(bundle *b, datacontrol_request_type type, void *data)
+{
+ datacontrol_socket_info *socket_info;
+ char *caller_app_id = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
+ int ret = DATA_CONTROL_ERROR_NONE;
+
+ _LOGI("__datacontrol_send_async caller_app_id : %s ", caller_app_id);
+
+ socket_info = g_hash_table_lookup(__socket_pair_hash, caller_app_id);
+ if (socket_info == NULL) {
+ _LOGE("__socket_pair_hash lookup fail");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ ret = __datacontrol_send_async(socket_info->socket_fd, b, type, data);
+ _LOGI("__datacontrol_send_async result : %d ", ret);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ g_hash_table_remove(__socket_pair_hash, caller_app_id);
+
+ return ret;
+}
+
+static int __send_add_callback_result(
+ data_control_data_change_type_e result_type,
+ char *unique_id,
+ char *path,
+ int callback_id,
+ int callback_result)
+{
+ GError *err = NULL;
+ int result = DATA_CONTROL_ERROR_NONE;
+ gboolean signal_result = TRUE;
+ _LOGI("add callback_result type : %d, callback_id : %d, result : %d",
+ result_type, callback_id, callback_result);
+
+ signal_result = g_dbus_connection_emit_signal(
+ _get_dbus_connection(),
+ unique_id,
+ path,
+ DATA_CONTROL_INTERFACE_NAME,
+ DATA_CONTROL_DATA_CHANGE_ADD_REMOVE_RESULT,
+ g_variant_new("(iii)",
+ result_type,
+ callback_id,
+ callback_result), &err);
+ if (signal_result == FALSE) {
+ _LOGE("g_dbus_connection_emit_signal() is failed");
+ if (err != NULL) {
+ _LOGE("g_dbus_connection_emit_signal() err : %s",
+ err->message);
+ g_error_free(err);
+ }
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ _LOGI("Send __send_add_callback_result done %d", result);
+ return result;
+}
+
+static int __provider_noti_process(bundle *b, datacontrol_request_type type)
+{
+ data_control_h provider = NULL;
+ bool noti_allow = true;
+ char *path = NULL;
+ int result = DATA_CONTROL_ERROR_NONE;
+ char *unique_id = NULL;
+ datacontrol_data_change_type_e result_type =
+ DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT;
+ char *callback_id_str = NULL;
+ int callback_id = -1;
+ GList *filter_iter;
+ changed_noti_consumer_filter_info_s *filter_info;
+ char caller_app_id[255];
+ const char *pid_str;
+ int pid;
+ int sender_pid;
+
+ pid_str = bundle_get_val(b, AUL_K_CALLER_PID);
+ if (pid_str == NULL) {
+ _LOGE("fail to get caller pid");
+ result = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ pid = atoi(pid_str);
+ if (pid <= 1) {
+ _LOGE("invalid caller pid %s", pid_str);
+ result = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) {
+ _LOGE("Failed to get appid by pid");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ unique_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_UNIQUE_NAME);
+ _LOGI("unique_id : %s", unique_id);
+ sender_pid = __get_sender_pid(unique_id);
+ if (sender_pid != pid) {
+ _LOGE("invalid unique id. sender does not have unique_id %s", unique_id);
+ return DATA_CONTROL_ERROR_PERMISSION_DENIED;
+ }
+
+ result = __create_consumer_list_db();
+ if (result != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("fail to create consumer list db");
+ return result;
+ }
+
+ provider = malloc(sizeof(struct data_control_s));
+ if (provider == NULL) {
+ _LOGE("Out of memory. fail to alloc provider.");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+ provider->provider_id =
+ (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+ provider->data_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_DATA);
+ if (provider->provider_id == NULL || provider->data_id == NULL) {
+ _LOGE("invalid provider value %s, %s",
+ provider->provider_id, provider->data_id);
+ free(provider);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ _LOGI("Noti Provider ID: %s, data ID: %s, request type: %d",
+ provider->provider_id, provider->data_id, type);
+ path = _get_encoded_path(provider, caller_app_id);
+ if (path == NULL) {
+ _LOGE("can not get encoded path out of memory");
+ free(provider);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ callback_id_str = (char *)bundle_get_val(b, OSP_K_DATA_CHANGED_CALLBACK_ID);
+ if (callback_id_str == NULL) {
+ _LOGE("callback_id is NULL");
+ result = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ callback_id = atoi(callback_id_str);
+
+ switch (type) {
+ case DATACONTROL_TYPE_ADD_DATA_CHANGED_CB:
+ {
+ _LOGI("DATACONTROL_TYPE_ADD_DATA_CHANGED_CB called");
+ result_type = DATACONTROL_DATA_CHANGE_CALLBACK_ADD_RESULT;
+ filter_iter = g_list_first(__noti_consumer_filter_info_list);
+ for (; filter_iter != NULL; filter_iter = filter_iter->next) {
+ filter_info =
+ (changed_noti_consumer_filter_info_s *)filter_iter->data;
+ noti_allow = filter_info->callback(
+ (data_control_h)provider,
+ caller_app_id,
+ filter_info->user_data);
+ if (!noti_allow)
+ break;
+ }
+ _LOGI("provider_sql_consumer_filter_cb result %d", noti_allow);
+
+ if (noti_allow) {
+ result = __insert_consumer_list_db_info(
+ caller_app_id,
+ provider->provider_id,
+ provider->data_id,
+ unique_id,
+ path);
+ if (result != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("fail to set consumer list db info %d", result);
+ result = DATA_CONTROL_ERROR_PERMISSION_DENIED;
+ break;
+ }
+
+ result = __set_consumer_app_list(
+ caller_app_id,
+ path,
+ unique_id);
+ if (result != DATA_CONTROL_ERROR_NONE)
+ _LOGE("fail to __set_consumer_app_list");
+
+ } else {
+ result = DATA_CONTROL_ERROR_PERMISSION_DENIED;
+ break;
+ }
+ break;
+ }
+ case DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB:
+ {
+ _LOGI("DATACONTROL_NOTI_REMOVE_DATA_CHANGED_CB called");
+ result_type = DATACONTROL_DATA_CHANGE_CALLBACK_REMOVE_RESULT;
+ if (__noti_consumer_app_list) {
+ __free_consumer_info(unique_id);
+ _LOGI("unregister %s from __noti_consumer_app_list", unique_id);
+ } else {
+ _LOGI("empty __consumer_app_list");
+ }
+ result = __delete_consumer_list_db_info(unique_id);
+ if (result != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("__delete_consumer_list_db_info fail %d", result);
+ result = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ break;
+ }
+ default:
+ break;
+ }
-#include "data_control_provider.h"
-#include "data_control_sql.h"
-#include "data_control_log.h"
-#include "data_control_internal.h"
-#include "data-control-internal.h"
+out:
+ __send_add_callback_result(
+ result_type, unique_id, path, callback_id, result);
-#define INSERT_STMT_CONST_LEN 25
-#define DELETE_STMT_CONST_LEN 12
-#define UPDATE_STMT_CONST_LEN 15
-#define SELECT_STMT_CONST_LEN 13
-#define WHERE_COND_CONST_LEN 7
-#define ORDER_CLS_CONST_LEN 10
+ if (provider)
+ free(provider);
+ if (path)
+ free(path);
+
+ return result;
+}
-struct data_control_s {
+int __provider_process(bundle *b, int fd, const char *consumer_appid)
+{
+ int ret;
+ int len = 0;
+ const char **arg_list = NULL;
+ const char **column_list = NULL;
+ data_control_h provider = NULL;
+ int provider_req_id = 0;
+ int *key = NULL;
+ bool is_map;
char *provider_id;
- char *data_id;
-};
+ char *caller_appid;
+ bundle *value = NULL;
-typedef struct {
- int no_of_elements;
- int length;
- char **keys;
- char **vals;
-} key_val_pair;
+ const char *request_type =
+ bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+ if (request_type == NULL) {
+ _LOGE("Invalid data control request");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
-static data_control_provider_sql_cb sql_provider_callback;
-static data_control_provider_map_cb map_provider_callback;
-static data_control_provider_bulk_cb sql_provider_bulk_callback;
-static data_control_provider_bulk_cb map_provider_bulk_callback;
-static void *sql_bulk_callback_user_data = NULL;
-static void *map_bulk_callback_user_data = NULL;
+ /* Get the request type */
+ datacontrol_request_type type = atoi(request_type);
+ if (type >= DATACONTROL_TYPE_SQL_SELECT &&
+ type <= DATACONTROL_TYPE_SQL_BULK_INSERT) {
+ is_map = false;
+ } else if (type >= DATACONTROL_TYPE_MAP_GET &&
+ type <= DATACONTROL_TYPE_MAP_BULK_ADD) {
+ is_map = true;
+ } else {
+ _LOGE("Invalid request type");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
-datacontrol_provider_sql_cb sql_internal_callback;
-datacontrol_provider_map_cb map_internal_callback;
+ caller_appid = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
+ if (caller_appid && strncmp(caller_appid,
+ consumer_appid, strlen(consumer_appid)) != 0) {
+ _LOGE("The passed appid(%s) is different from the registered appid(%s).",
+ caller_appid, consumer_appid);
+ return DATA_CONTROL_ERROR_NONE;
+ }
-static void __sql_insert_request_cb(int request_id, datacontrol_h provider, bundle *insert_data, void *user_data)
-{
- _LOGI("sql_insert_request");
+ provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
+ ret = _check_cert(provider_id, is_map, consumer_appid);
+ if (ret != DATA_CONTROL_ERROR_NONE) {
+ if (ret == DATA_CONTROL_ERROR_PERMISSION_DENIED) {
+ _LOGE("The consumer (%s) is not signed with the same certificate",
+ consumer_appid);
+ return DATA_CONTROL_ERROR_NONE;
+ } else {
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
- if (sql_provider_callback.insert_cb)
- sql_provider_callback.insert_cb(request_id, (data_control_h)provider, insert_data, user_data);
-}
+ arg_list = bundle_get_str_array(b, OSP_K_ARG, &len);
-static void __sql_bulk_insert_request_cb(int request_id, datacontrol_h provider, data_control_bulk_data_h bulk_data, void *user_data)
-{
- _LOGI("sql_bulk_insert_request");
+ provider = malloc(sizeof(struct data_control_s));
+ if (provider == NULL) {
+ _LOGE("Out of memory. fail to alloc provider.");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
- if (sql_provider_bulk_callback)
- sql_provider_bulk_callback(request_id, (data_control_h)provider, bulk_data, user_data);
-}
+ /* Set the provider ID */
+ provider->provider_id = provider_id;
+ /* Set the data ID */
+ provider->data_id = (char *)arg_list[PACKET_INDEX_DATAID];
-static void __sql_update_request_cb(int request_id, datacontrol_h provider, bundle *update_data, const char *where, void *user_data)
-{
- _LOGI("sql_update_request");
+ /* Set the request ID */
+ provider_req_id = __provider_new_request_id();
- if (sql_provider_callback.update_cb)
- sql_provider_callback.update_cb(request_id, (data_control_h)provider, update_data, where, user_data);
-}
+ _LOGI("Provider ID: %s, data ID: %s, request type: %s",
+ provider->provider_id, provider->data_id, request_type);
-static void __sql_delete_request_cb(int request_id, datacontrol_h provider, const char *where, void *user_data)
-{
- _LOGI("sql_delete_request");
+ /* Add the data to the table */
+ key = malloc(sizeof(int));
+ if (key == NULL) {
+ _LOGE("Out of memory. fail to malloc key");
+ goto err;
+ }
+ *key = provider_req_id;
- if (sql_provider_callback.delete_cb)
- sql_provider_callback.delete_cb(request_id, (data_control_h)provider, where, user_data);
-}
+ value = bundle_dup(b);
+ if (value == NULL) {
+ _LOGE("Fail to dup value");
+ goto err;
+ }
+ g_hash_table_insert(__request_table, key, value);
+
+ switch (type) {
+ case DATACONTROL_TYPE_SQL_SELECT:
+ {
+ int i = 1;
+ int current = 0;
+ int column_count = __get_int_from_str(arg_list[i++]); /* Column count */
+
+ if (column_count <= 0 || column_count > MAX_COLUMN_COUNT) {
+ _LOGE("Invalid column count %d", column_count);
+ goto err;
+ }
-static void __sql_select_request_cb(int request_id, datacontrol_h provider, const char **column_list, int column_count, const char *where, const char *order, void *user_data)
-{
- _LOGI("sql_select_request");
+ _LOGI("SELECT column count: %d", column_count);
+ column_list = (const char **)malloc(column_count * (sizeof(char *)));
+ if (column_list == NULL) {
+ _LOGE("Out of memory. Fail to malloc column_list.");
+ goto err;
+ }
- if (sql_provider_callback.select_cb)
- sql_provider_callback.select_cb(request_id, (data_control_h)provider, column_list, column_count, where, order, user_data);
-}
+ while (current < column_count) {
+ column_list[current++] = arg_list[i++]; /* Column data */
+ _LOGI("Column %d: %s", current, column_list[current-1]);
+ }
-static void __map_get_request_cb(int request_id, datacontrol_h provider, const char *key, void *user_data)
-{
- _LOGI("map_get_request");
+ const char *where = arg_list[i++]; /* where */
+ const char *order = arg_list[i++]; /* order */
+ _LOGI("where: %s, order: %s", where, order);
+
+ if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+ where = NULL;
+
+ if (strncmp(order, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+ order = NULL;
+
+ const char *page_number = arg_list[i++];
+ const char *per_page = arg_list[i];
+
+ _LOGI("page_number: %s, per_page: %s", page_number, per_page);
+ bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
+ bundle_add_str(value, MAX_COUNT_PER_PAGE, per_page);
+ if (sql_callback.select_cb) {
+ sql_callback.select_cb(
+ provider_req_id,
+ provider,
+ column_list,
+ column_count,
+ where,
+ order,
+ sql_user_data);
+ } else {
+ _LOGE("sql_callback.select_cb is NULL");
+ }
+ free(column_list);
+ break;
+ }
+ case DATACONTROL_TYPE_SQL_INSERT:
+ case DATACONTROL_TYPE_SQL_UPDATE:
+ {
+ _LOGI("INSERT / UPDATE handler");
+ bundle *sql = __get_bundle_data_from_fd(fd);
+ if (sql == NULL) {
+ _LOGE("__get_bundle_data_from_fd fail");
+ goto err;
+ }
+ if (type == DATACONTROL_TYPE_SQL_INSERT) {
+ if (sql_callback.insert_cb) {
+ sql_callback.insert_cb(
+ provider_req_id,
+ provider,
+ sql,
+ sql_user_data);
+ } else {
+ _LOGE("sql_callback.insert_cb is NULL");
+ }
+ } else {
+ const char *where = arg_list[PACKET_INDEX_UPDATEWHERE];
+ _LOGI("UPDATE from where: %s", where);
+ if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+ where = NULL;
+ if (sql_callback.update_cb) {
+ sql_callback.update_cb(
+ provider_req_id,
+ provider,
+ sql,
+ where,
+ sql_user_data);
+ } else {
+ _LOGE("sql_callback.update_cb is NULL");
+ }
+ }
+ bundle_free(sql);
+ break;
+ }
+ case DATACONTROL_TYPE_SQL_BULK_INSERT:
+ {
+ _LOGI("BULK INSERT handler");
+ data_control_bulk_data_h data = __get_bulk_data_from_fd(fd);
+ if (data == NULL) {
+ _LOGE("__get_bulk_data_from_fd fail");
+ goto err;
+ }
- if (map_provider_callback.get_cb)
- map_provider_callback.get_cb(request_id, (data_control_h)provider, key, user_data);
-}
+ if (sql_bulk_callback) {
+ sql_bulk_callback(
+ provider_req_id,
+ provider,
+ data,
+ sql_bulk_callback_user_data);
+ } else {
+ _LOGE("sql_bulk_callback is NULL");
+ }
-static void __map_set_request_cb(int request_id, datacontrol_h provider, const char *key, const char *old_value, const char *new_value, void *user_data)
-{
- _LOGI("map_set_request");
+ data_control_bulk_data_destroy(data);
+ break;
+ }
+ case DATACONTROL_TYPE_SQL_DELETE:
+ {
+ const char *where = arg_list[PACKET_INDEX_DELETEWHERE];
+ _LOGI("DELETE from where: %s", where);
+ if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
+ where = NULL;
+ if (sql_callback.delete_cb) {
+ sql_callback.delete_cb(
+ provider_req_id,
+ provider,
+ where,
+ sql_user_data);
+ } else {
+ _LOGE("sql_callback.delete_cb is NULL");
+ }
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_GET:
+ {
+ const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+ const char *page_number = arg_list[PACKET_INDEX_MAP_PAGE_NO];
+ const char *count_per_page = arg_list[PACKET_INDEX_MAP_COUNT_PER_PAGE];
+ bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
+ bundle_add_str(value, MAX_COUNT_PER_PAGE, count_per_page);
+ _LOGI("Gets the value list related with the key(%s) from Map datacontrol. ", map_key);
+ if (map_callback.get_cb) {
+ map_callback.get_cb(
+ provider_req_id,
+ provider,
+ map_key,
+ map_user_data);
+ } else {
+ _LOGE("map_callback.get_cb is NULL");
+ }
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_SET:
+ {
+ const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+ const char *old_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
+ const char *new_value = arg_list[PACKET_INDEX_MAP_VALUE_2ND];
+ _LOGI("Sets the old value(%s) of the key(%s) to the new value(%s) in Map datacontrol.", old_value, map_key, new_value);
+ if (map_callback.set_cb) {
+ map_callback.set_cb(
+ provider_req_id,
+ provider,
+ map_key,
+ old_value,
+ new_value,
+ map_user_data);
+ } else {
+ _LOGE("map_callback.set_cb is NULL");
+ }
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_ADD:
+ {
+ const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+ const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
+ _LOGI("Adds the %s-%s in Map datacontrol.", map_key, map_value);
+ if (map_callback.add_cb) {
+ map_callback.add_cb(
+ provider_req_id,
+ provider,
+ map_key,
+ map_value,
+ map_user_data);
+ } else {
+ _LOGE("map_callback.add_cb is NULL");
+ }
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_BULK_ADD:
+ {
+ _LOGI("BULK ADD handler");
+ data_control_bulk_data_h data = __get_bulk_data_from_fd(fd);
+ if (data == NULL) {
+ _LOGE("__get_bulk_data_from_fd fail");
+ goto err;
+ }
- if (map_provider_callback.set_cb)
- map_provider_callback.set_cb(request_id, (data_control_h)provider, key, old_value, new_value, user_data);
-}
+ if (map_bulk_callback) {
+ map_bulk_callback(provider_req_id,
+ provider,
+ data,
+ map_bulk_callback_user_data);
+ _LOGI("bulk_add callback call done");
+ } else {
+ _LOGE("map_bulk_callback is NULL");
+ }
-static void __map_add_request_cb(int request_id, datacontrol_h provider, const char *key, const char *value, void *user_data)
-{
- _LOGI("map_add_request");
+ data_control_bulk_data_destroy(data);
+ break;
+ }
+ case DATACONTROL_TYPE_MAP_REMOVE:
+ {
+ const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
+ const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
+ _LOGI("Removes the %s-%s in Map datacontrol.", map_key, map_value);
+ if (map_callback.remove_cb) {
+ map_callback.remove_cb(
+ provider_req_id,
+ provider,
+ map_key,
+ map_value,
+ map_user_data);
+ } else {
+ _LOGE("map_callback.remove_cb is NULL");
+ }
+ break;
+ }
+ default:
+ break;
+ }
- if (map_provider_callback.add_cb)
- map_provider_callback.add_cb(request_id, (data_control_h)provider, key, value, user_data);
+ free(provider);
+
+ return DATA_CONTROL_ERROR_NONE;
+err:
+
+ if (provider)
+ free(provider);
+ if (key)
+ free(key);
+ if (value)
+ bundle_free(value);
+
+ return DATA_CONTROL_ERROR_IO_ERROR;
}
-static void __map_remove_request_cb(int request_id, datacontrol_h provider, const char *key, const char *value, void *user_data)
+gboolean __provider_recv_message(GIOChannel *channel,
+ GIOCondition cond,
+ gpointer data)
{
- _LOGI("map_remove_request");
+ char *buf = NULL;
+ int data_len;
+ char *consumer_appid = (char *)data;
+ guint nb;
+
+ gint fd = g_io_channel_unix_get_fd(channel);
+ gboolean retval = TRUE;
+
+ _LOGI("__provider_recv_message : ...from %d:%s%s%s%s\n", fd,
+ (cond & G_IO_ERR) ? " ERR" : "",
+ (cond & G_IO_HUP) ? " HUP" : "",
+ (cond & G_IO_IN) ? " IN" : "",
+ (cond & G_IO_PRI) ? " PRI" : "");
+
+ if (cond & (G_IO_ERR | G_IO_HUP))
+ goto error;
+
+ if (cond & G_IO_IN) {
+ if (_read_socket(fd, (char *)&data_len, sizeof(data_len), &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGE("read socket fail : data_len");
+ goto error;
+ }
+
+ _LOGI("data_len : %d", data_len);
+
+ if (nb == 0) {
+ _LOGI("__provider_recv_message : ...from %d: EOF\n", fd);
+ goto error;
+ }
- if (map_provider_callback.remove_cb)
- map_provider_callback.remove_cb(request_id, (data_control_h)provider, key, value, user_data);
+ _LOGI("__provider_recv_message: ...from %d: %d bytes\n", fd, data_len);
+ if (data_len > 0 && data_len < MAX_REQUEST_ARGUMENT_SIZE) {
+ bundle *kb = NULL;
+
+ buf = (char *)calloc(data_len + 1, sizeof(char));
+ if (buf == NULL) {
+ _LOGE("calloc failed");
+ goto error;
+ }
+
+ if (_read_socket(fd, buf, data_len, &nb) !=
+ DATA_CONTROL_ERROR_NONE) {
+ _LOGI("read socket fail : data_len\n");
+ goto error;
+ }
+
+ if (nb == 0) {
+ _LOGI("__provider_recv_message: nb 0 : EOF\n");
+ goto error;
+ }
+
+ kb = bundle_decode_raw((bundle_raw *)buf, data_len);
+ if (__provider_process(kb, fd, consumer_appid) !=
+ DATA_CONTROL_ERROR_NONE) {
+ bundle_free(kb);
+ goto error;
+ }
+ bundle_free(kb);
+ }
+ }
+ if (buf)
+ free(buf);
+
+ return retval;
+error:
+ if (consumer_appid != NULL)
+ g_hash_table_remove(__socket_pair_hash, consumer_appid);
+ if (buf)
+ free(buf);
+
+ return FALSE;
}
-static void __map_bulk_add_request_cb(int request_id, datacontrol_h provider, data_control_bulk_data_h bulk_data, void *user_data)
+int __datacontrol_handler_cb(bundle *b, int request_id, void *data)
{
- _LOGI("map_bulk_add_request");
+ datacontrol_socket_info *socket_info;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ const char *caller;
+ const char *callee;
+ char *dup_caller;
+
+ const char *request_type =
+ bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
+ if (request_type == NULL) {
+ caller = bundle_get_val(b, AUL_K_CALLER_APPID);
+ callee = bundle_get_val(b, AUL_K_CALLEE_APPID);
+
+ if (caller == NULL) {
+ _LOGE("Invalid data control request caller is NULL");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ dup_caller = strdup(caller);
+ socket_info = g_hash_table_lookup(__socket_pair_hash, dup_caller);
+
+ if (socket_info != NULL)
+ g_hash_table_remove(__socket_pair_hash, dup_caller);
- if (map_provider_bulk_callback)
- map_provider_bulk_callback(request_id, (data_control_h)provider, bulk_data, user_data);
+ ret = _add_watch_on_socket_info(dup_caller, callee, "provider",
+ NULL, NULL, __provider_recv_message,
+ dup_caller, &socket_info);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
+
+ g_hash_table_insert(__socket_pair_hash, dup_caller, socket_info);
+ } else {
+ /* Get the request type */
+ datacontrol_request_type type = atoi(request_type);
+ if (type == DATACONTROL_TYPE_ADD_DATA_CHANGED_CB ||
+ type == DATACONTROL_TYPE_REMOVE_DATA_CHANGED_CB) {
+ __provider_noti_process(b, type);
+ } else {
+ _LOGE("Invalid data control request");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ return ret;
}
-EXPORT_API int data_control_provider_sql_register_cb(data_control_provider_sql_cb *callback, void *user_data)
+EXPORT_API int data_control_provider_sql_register_cb(
+ data_control_provider_sql_cb *callback, void *user_data)
{
- int retval = datacontrol_check_privilege(PRIVILEGE_PROVIDER);
+ int retval = _check_privilege(PRIVILEGE_PROVIDER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
if (!callback)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- sql_provider_callback = *callback;
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ memcpy(&sql_callback, callback, sizeof(data_control_provider_sql_cb));
+ sql_user_data = user_data;
- sql_internal_callback.insert = __sql_insert_request_cb;
- sql_internal_callback.update = __sql_update_request_cb;
- sql_internal_callback.delete = __sql_delete_request_cb;
- sql_internal_callback.select = __sql_select_request_cb;
- sql_internal_callback.bulk_insert = __sql_bulk_insert_request_cb;
+ /* If the provider_map_cb was registered(not NULL),
+ * __datacontrol_handler_cb is set already. */
+ if (__is_null_map_callback(map_callback))
+ retval = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
- return datacontrol_provider_sql_register_cb(&sql_internal_callback, user_data);
+ return retval;
}
EXPORT_API int data_control_provider_sql_unregister_cb(void)
{
- memset(&sql_provider_callback, 0, sizeof(data_control_provider_sql_cb));
- return datacontrol_provider_sql_unregister_cb();
+ /* When both SQL_cb and Map_cb are unregisted,
+ * unsetting the provider cb is possible. */
+ if (__is_null_map_callback(map_callback))
+ aul_unset_data_control_provider_cb();
+
+ memset(&sql_callback, 0, sizeof(data_control_provider_sql_cb));
+ sql_user_data = NULL;
+
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_provider_sql_register_insert_bulk_data_request_cb(
data_control_provider_bulk_cb callback, void *user_data)
{
- int retval = datacontrol_check_privilege(PRIVILEGE_PROVIDER);
+ int retval = _check_privilege(PRIVILEGE_PROVIDER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
if (callback == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- sql_provider_bulk_callback = callback;
+ sql_bulk_callback = callback;
sql_bulk_callback_user_data = user_data;
- /* sql callback already registered */
- if (datacontrol_provider_sql_is_registered())
- return DATA_CONTROL_ERROR_NONE;
-
- sql_internal_callback.insert = __sql_insert_request_cb;
- sql_internal_callback.update = __sql_update_request_cb;
- sql_internal_callback.delete = __sql_delete_request_cb;
- sql_internal_callback.select = __sql_select_request_cb;
- sql_internal_callback.bulk_insert = __sql_bulk_insert_request_cb;
-
- return datacontrol_provider_sql_register_cb(&sql_internal_callback, NULL);
+ return retval;
}
EXPORT_API int data_control_provider_sql_unregister_insert_bulk_data_request_cb(void)
{
- memset(&sql_provider_bulk_callback, 0, sizeof(data_control_provider_bulk_cb));
+ sql_bulk_callback = NULL;
+ sql_bulk_callback_user_data = NULL;
+
return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_provider_map_register_cb(data_control_provider_map_cb *callback, void *user_data)
+EXPORT_API int data_control_provider_map_register_cb(
+ data_control_provider_map_cb *callback, void *user_data)
{
- int retval = datacontrol_check_privilege(PRIVILEGE_PROVIDER);
+ int retval = _check_privilege(PRIVILEGE_PROVIDER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
if (!callback)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- map_provider_callback = *callback;
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ memcpy(&map_callback, callback, sizeof(data_control_provider_map_cb));
+ map_user_data = user_data;
- map_internal_callback.get = __map_get_request_cb;
- map_internal_callback.set = __map_set_request_cb;
- map_internal_callback.add = __map_add_request_cb;
- map_internal_callback.remove = __map_remove_request_cb;
- map_internal_callback.bulk_add = __map_bulk_add_request_cb;
+ /* If the provider_sql_cb was registered(not NULL),
+ * __datacontrol_handler_cb is set already. */
+ if (__is_null_sql_callback(sql_callback))
+ retval = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
- return datacontrol_provider_map_register_cb(&map_internal_callback, user_data);
+ return retval;
}
EXPORT_API int data_control_provider_map_unregister_cb(void)
{
- memset(&map_provider_callback, 0, sizeof(data_control_provider_map_cb));
+ /* When both SQL_cb and Map_cb are unregisted,
+ * unsetting the provider cb is possible. */
+ if (__is_null_sql_callback(sql_callback))
+ aul_unset_data_control_provider_cb();
- return datacontrol_provider_map_unregister_cb();
+ memset(&map_callback, 0, sizeof(data_control_provider_map_cb));
+ map_user_data = NULL;
+
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_provider_map_register_add_bulk_data_request_cb(
data_control_provider_bulk_cb callback, void *user_data)
{
- int retval = datacontrol_check_privilege(PRIVILEGE_PROVIDER);
+ int retval = _check_privilege(PRIVILEGE_PROVIDER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
if (callback == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- map_provider_bulk_callback = callback;
+ map_bulk_callback = callback;
map_bulk_callback_user_data = user_data;
- /* map callback already registered */
- if (datacontrol_provider_map_is_registered())
- return DATA_CONTROL_ERROR_NONE;
-
- map_internal_callback.get = __map_get_request_cb;
- map_internal_callback.set = __map_set_request_cb;
- map_internal_callback.add = __map_add_request_cb;
- map_internal_callback.remove = __map_remove_request_cb;
- map_internal_callback.bulk_add = __map_bulk_add_request_cb;
-
- return datacontrol_provider_map_register_cb(&map_internal_callback, NULL);
+ return retval;
}
EXPORT_API int data_control_provider_map_unregister_add_bulk_data_request_cb(void)
{
- memset(&map_provider_bulk_callback, 0, sizeof(data_control_provider_bulk_cb));
+ map_bulk_callback = NULL;
+ map_bulk_callback_user_data = NULL;
+
return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_provider_get_client_appid(int request_id, char **appid)
+EXPORT_API int data_control_provider_get_client_appid(
+ int request_id, char **appid)
{
- return datacontrol_provider_get_client_appid(request_id, appid);
+ const char *caller;
+ bundle *b;
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ caller = bundle_get_val(b, AUL_K_CALLER_APPID);
+ if (!caller) {
+ _LOGE("No appid for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ _LOGI("Request ID: %d, caller appid: %s", request_id, caller);
+
+ *appid = strdup(caller);
+
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_provider_send_bulk_insert_result(int request_id, data_control_bulk_result_data_h bulk_results)
+EXPORT_API int data_control_provider_send_bulk_insert_result(
+ int request_id, data_control_bulk_result_data_h bulk_results)
{
int count;
int ret = DATA_CONTROL_ERROR_NONE;
+ bundle *res;
+ bundle *b;
if (bulk_results == NULL) {
_LOGE("Null bulk result data");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_provider_send_bulk_insert_result(request_id, bulk_results);
+ _LOGI("Send an insert result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ res = __set_result(b, DATACONTROL_TYPE_SQL_BULK_INSERT, NULL);
+ ret = __send_result(
+ res, DATACONTROL_TYPE_SQL_BULK_INSERT, (void *)bulk_results);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
-EXPORT_API int data_control_provider_send_select_result(int request_id, void *db_handle)
+EXPORT_API int data_control_provider_send_select_result(
+ int request_id, void *db_handle)
{
- return datacontrol_provider_send_select_result(request_id, db_handle);
+ int ret;
+ bundle *res;
+ bundle *b;
+
+ _LOGI("Send a select result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, db_handle);
+ ret = __send_result(res, DATACONTROL_TYPE_SQL_SELECT, db_handle);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
-EXPORT_API int data_control_provider_send_insert_result(int request_id, long long row_id)
+EXPORT_API int data_control_provider_send_insert_result(
+ int request_id, long long row_id)
{
- return datacontrol_provider_send_insert_result(request_id, row_id);
+int ret;
+ bundle *res;
+ bundle *b;
+
+ _LOGI("Send an insert result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ res = __set_result(b, DATACONTROL_TYPE_SQL_INSERT, (void *)&row_id);
+
+ ret = __send_result(res, DATACONTROL_TYPE_SQL_INSERT, NULL);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
EXPORT_API int data_control_provider_send_update_result(int request_id)
{
- return datacontrol_provider_send_update_result(request_id);
+ int ret;
+ bundle *res;
+ bundle *b;
+
+ _LOGI("Send an update result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ res = __set_result(b, DATACONTROL_TYPE_SQL_UPDATE, NULL);
+
+ ret = __send_result(res, DATACONTROL_TYPE_SQL_UPDATE, NULL);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
EXPORT_API int data_control_provider_send_delete_result(int request_id)
{
- return datacontrol_provider_send_delete_result(request_id);
+ int ret;
+ bundle *res;
+ bundle *b;
+
+ _LOGI("Send a delete result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ res = __set_result(b, DATACONTROL_TYPE_SQL_DELETE, NULL);
+
+ ret = __send_result(res, DATACONTROL_TYPE_SQL_DELETE, NULL);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
-EXPORT_API int data_control_provider_send_error(int request_id, const char *error)
+EXPORT_API int data_control_provider_send_error(
+ int request_id, const char *error)
{
- return datacontrol_provider_send_error(request_id, error);
+ bundle *res;
+ bundle *b;
+ int ret;
+
+ _LOGI("Send an error for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ res = __set_result(b, DATACONTROL_TYPE_ERROR, (void *)error);
+ ret = __send_result(res, DATACONTROL_TYPE_ERROR, NULL);
+ bundle_free(res);
+
+ return ret;
}
-static void bundle_foreach_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+static void bundle_foreach_cb(const char *key, const int type,
+ const bundle_keyval_t *kv, void *user_data)
{
int index;
char *value = NULL;
return;
}
-EXPORT_API char *data_control_provider_create_insert_statement(data_control_h provider, bundle *insert_map)
+EXPORT_API char *data_control_provider_create_insert_statement(
+ data_control_h provider, bundle *insert_map)
{
int index;
char *data_id = NULL;
index = 0;
bundle_foreach(insert_map, bundle_foreach_cb, (void *)(cols));
- data_control_sql_get_data_id(provider, &data_id);
+ _get_data_id(provider, &data_id);
- sql_len = INSERT_STMT_CONST_LEN + strlen(data_id) + (row_count - 1) * 4 + (cols->length) + 1;
+ sql_len = INSERT_STMT_CONST_LEN + strlen(data_id) +
+ (row_count - 1) * 4 + (cols->length) + 1;
_LOGI("SQL statement length: %d", sql_len);
return sql;
}
-EXPORT_API char *data_control_provider_create_delete_statement(data_control_h provider, const char *where)
+EXPORT_API char *data_control_provider_create_delete_statement(
+ data_control_h provider, const char *where)
{
char *data_id = NULL;
int cond_len;
return NULL;
}
- data_control_sql_get_data_id(provider, &data_id);
+ _get_data_id(provider, &data_id);
cond_len = (where != NULL) ? (WHERE_COND_CONST_LEN + strlen(where)) : 0;
sql_len = DELETE_STMT_CONST_LEN + strlen(data_id) + cond_len + 1;
return sql;
}
-EXPORT_API char *data_control_provider_create_update_statement(data_control_h provider, bundle *update_map, const char *where)
+EXPORT_API char *data_control_provider_create_update_statement(
+ data_control_h provider, bundle *update_map, const char *where)
{
int index;
char *data_id = NULL;
index = 0;
bundle_foreach(update_map, bundle_foreach_cb, (void *)(cols));
- data_control_sql_get_data_id(provider, &data_id);
+ _get_data_id(provider, &data_id);
cond_len = (where != NULL) ? (WHERE_COND_CONST_LEN + strlen(where)) : 0;
- sql_len = UPDATE_STMT_CONST_LEN + strlen(data_id) + (cols->length) + (row_count - 1) * 5 + cond_len + 1;
+ sql_len = UPDATE_STMT_CONST_LEN + strlen(data_id) + (cols->length) +
+ (row_count - 1) * 5 + cond_len + 1;
_LOGI("SQL statement length: %d", sql_len);
return sql;
}
-EXPORT_API char *data_control_provider_create_select_statement(data_control_h provider, const char **column_list,
+EXPORT_API char *data_control_provider_create_select_statement(
+ data_control_h provider, const char **column_list,
int column_count, const char *where, const char *order)
{
int index = 0;
col_name_length = 1;
}
- data_control_sql_get_data_id(provider, &data_id);
+ _get_data_id(provider, &data_id);
cond_len = (where != NULL) ? (WHERE_COND_CONST_LEN + strlen(where)) : 0;
order_len = (order != NULL) ? (ORDER_CLS_CONST_LEN + strlen(order)) : 0;
- sql_len = SELECT_STMT_CONST_LEN + col_name_length + strlen(data_id) + cond_len + order_len + 1;
+ sql_len = SELECT_STMT_CONST_LEN + col_name_length + strlen(data_id) +
+ cond_len + order_len + 1;
_LOGI("SQL statement length: %d", sql_len);
return sql;
}
-EXPORT_API bool data_control_provider_match_provider_id(data_control_h provider, const char *provider_id)
+EXPORT_API bool data_control_provider_match_provider_id(
+ data_control_h provider, const char *provider_id)
{
int ret = DATA_CONTROL_ERROR_NONE;
char *prov_id = NULL;
return false;
}
- ret = data_control_sql_get_provider_id(provider, &prov_id);
+ ret = _get_provider_id(provider, &prov_id);
set_last_result(ret);
if (ret != DATA_CONTROL_ERROR_NONE)
return false;
}
}
-EXPORT_API bool data_control_provider_match_data_id(data_control_h provider, const char *data_id)
+EXPORT_API bool data_control_provider_match_data_id(
+ data_control_h provider, const char *data_id)
{
int ret = DATA_CONTROL_ERROR_NONE;
char *data = NULL;
return false;
}
- ret = data_control_sql_get_data_id(provider, &data);
+ ret = _get_data_id(provider, &data);
set_last_result(ret);
if (ret != DATA_CONTROL_ERROR_NONE)
return false;
}
}
-EXPORT_API int data_control_provider_send_map_bulk_add_result(int request_id, data_control_bulk_result_data_h bulk_results)
+EXPORT_API int data_control_provider_send_map_bulk_add_result(
+ int request_id, data_control_bulk_result_data_h bulk_results)
{
int count;
int ret = DATA_CONTROL_ERROR_NONE;
+ bundle *res;
+ bundle *b;
if (bulk_results == NULL) {
_LOGE("Null bulk result data");
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- return datacontrol_provider_send_map_bulk_add_result(request_id, bulk_results);
+ _LOGI("Send bulk add result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ res = __set_result(b, DATACONTROL_TYPE_MAP_BULK_ADD, NULL);
+ ret = __send_result(res, DATACONTROL_TYPE_MAP_BULK_ADD,
+ (void *)bulk_results);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
EXPORT_API int data_control_provider_send_map_result(int request_id)
{
- return datacontrol_provider_send_map_result(request_id);
+int ret;
+ bundle *res;
+ bundle *b;
+
+ _LOGI("Send a set/add/remove result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ res = __set_result(b, DATACONTROL_TYPE_UNDEFINED, NULL);
+
+ ret = __send_result(res, DATACONTROL_TYPE_UNDEFINED, NULL);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
+}
+
+EXPORT_API int data_control_provider_send_map_get_value_result(
+ int request_id, char **value_list, int value_count)
+{
+ int ret;
+ char value_count_str[32];
+ bundle *b;
+ bundle *res;
+
+ _LOGI("Send a get result for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ snprintf(value_count_str, 32, "%d", value_count);
+ bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str);
+
+ res = __set_result(b, DATACONTROL_TYPE_MAP_GET, value_list);
+
+ ret = __send_result(res, DATACONTROL_TYPE_MAP_GET, value_list);
+ bundle_free(res);
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
}
-EXPORT_API int data_control_provider_send_map_get_value_result(int request_id, char **value_list, int value_count)
+static int __send_signal_to_consumer(data_control_h provider,
+ char *unique_id,
+ char *path,
+ data_control_data_change_type_e type,
+ bundle *data)
{
- return datacontrol_provider_send_map_get_value_result(request_id, value_list, value_count);
+ int result = DATA_CONTROL_ERROR_NONE;
+ int len = 0;
+ bundle_raw *raw = NULL;
+ GError *err = NULL;
+ gboolean signal_result = TRUE;
+
+ if (data) {
+ if (bundle_encode(data, &raw, &len) != BUNDLE_ERROR_NONE) {
+ _LOGE("bundle_encode fail");
+ result = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+ }
+
+ _LOGI("emit signal to object path %s", path);
+ signal_result = g_dbus_connection_emit_signal(
+ _get_dbus_connection(),
+ unique_id,
+ path,
+ DATA_CONTROL_INTERFACE_NAME,
+ DATA_CONTROL_DATA_CHANGE_DATA_CHANGED,
+ g_variant_new("(isssi)",
+ type,
+ provider->provider_id,
+ provider->data_id,
+ ((raw) ? (char *)raw : ""),
+ len), &err);
+
+ if (signal_result == FALSE) {
+ _LOGE("g_dbus_connection_emit_signal() is failed");
+ if (err != NULL) {
+ _LOGE("g_dbus_connection_emit_signal() err : %s",
+ err->message);
+ g_error_free(err);
+ }
+ result = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+out:
+ if (raw)
+ free(raw);
+
+ return result;
}
EXPORT_API int data_control_provider_add_data_change_consumer_filter_cb(
if (callback_id == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_provider_add_data_change_consumer_filter_cb(callback, user_data, callback_id);
+ changed_noti_consumer_filter_info_s *filter_info =
+ (changed_noti_consumer_filter_info_s *)calloc(1, sizeof(changed_noti_consumer_filter_info_s));
+
+ *callback_id = __datacontrol_get_data_changed_filter_callback_id();
+
+ filter_info->callback_id = *callback_id;
+ filter_info->callback = callback;
+ filter_info->user_data = user_data;
+ __noti_consumer_filter_info_list =
+ g_list_append(__noti_consumer_filter_info_list, filter_info);
+
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_provider_remove_data_change_consumer_filter_cb(int callback_id)
{
+ GList *find_list;
+ changed_noti_consumer_filter_info_s filter_info;
+ changed_noti_consumer_filter_info_s *temp;
+
if (callback_id < 1)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_provider_remove_data_change_consumer_filter_cb(callback_id);
+ filter_info.callback_id = callback_id;
+ find_list = g_list_find_custom(__noti_consumer_filter_info_list, &filter_info,
+ (GCompareFunc)__data_changed_filter_cb_info_compare_cb);
+ if (find_list != NULL) {
+ temp = (changed_noti_consumer_filter_info_s *)find_list->data;
+ __noti_consumer_filter_info_list =
+ g_list_remove(__noti_consumer_filter_info_list, find_list->data);
+ free(temp);
+ } else {
+ _LOGE("invalid callback_id : %d", callback_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_provider_send_data_change_noti(
data_control_data_change_type_e type,
bundle *data)
{
- int retval = datacontrol_check_privilege(PRIVILEGE_PROVIDER);
+ int retval = _check_privilege(PRIVILEGE_PROVIDER);
+ GList *consumer_iter = NULL;
+ datacontrol_consumer_info *consumer_info = NULL;
+
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
if (!provider)
if (provider->provider_id == NULL || provider->data_id == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- if (type < DATA_CONTROL_DATA_CHANGE_SQL_UPDATE || type > DATA_CONTROL_DATA_CHANGE_MAP_REMOVE)
+ if (type < DATA_CONTROL_DATA_CHANGE_SQL_UPDATE ||
+ type > DATA_CONTROL_DATA_CHANGE_MAP_REMOVE)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_provider_send_data_change_noti(
- (datacontrol_h)provider,
- _get_internal_noti_type(type),
- data);
+ _LOGE("datacontrol_provider_send_data_change_noti %d, %d",
+ g_list_length(__noti_consumer_app_list), type);
+ consumer_iter = g_list_first(__noti_consumer_app_list);
+ for (; consumer_iter != NULL; consumer_iter = consumer_iter->next) {
+ consumer_info = (datacontrol_consumer_info *)consumer_iter->data;
+ if (__check_consumer_cert(provider->provider_id,
+ consumer_info->appid,
+ type) != DATA_CONTROL_ERROR_NONE)
+ continue;
+ retval = __send_signal_to_consumer(
+ provider,
+ consumer_info->unique_id,
+ consumer_info->object_path,
+ type,
+ data);
+ if (retval != DATA_CONTROL_ERROR_NONE) {
+ _LOGE("__send_signal_to_consumer fail : %d", retval);
+ break;
+ }
+ }
+ return retval;
}
EXPORT_API int data_control_provider_foreach_data_change_consumer(
data_control_provider_data_change_consumer_cb list_cb,
void *user_data)
{
+ char *app_id = NULL;
+ char *unique_id = NULL;
+ int ret = DATA_CONTROL_ERROR_NONE;
+ sqlite3_stmt *stmt = NULL;
+ char query[QUERY_MAXLEN];
+ bool callback_result;
+ data_control_provider_data_change_consumer_cb consumer_list_cb;
+ consumer_list_cb = list_cb;
+
if (!provider || !list_cb)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
if (provider->provider_id == NULL || provider->data_id == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_provider_foreach_data_change_consumer(
- (datacontrol_h)provider, list_cb, user_data);
+ sqlite3_snprintf(QUERY_MAXLEN, query,
+ "SELECT app_id, unique_id " \
+ "FROM data_control_consumer_path_list " \
+ "WHERE provider_id = ? AND data_id = ?");
+ _LOGI("get_changed_noti_consumer_list query : %s", query);
+
+ ret = sqlite3_prepare_v2(__provider_db, query, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("prepare stmt fail");
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, provider->provider_id, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ _LOGE("bind provider id fail: %s", sqlite3_errmsg(__provider_db));
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ ret = sqlite3_bind_text(stmt, 2, provider->data_id, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ _LOGE("bind data id fail: %s", sqlite3_errmsg(__provider_db));
+ ret = DATA_CONTROL_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ while (SQLITE_ROW == sqlite3_step(stmt)) {
+
+ app_id = (char *)sqlite3_column_text(stmt, 0);
+ if (!app_id) {
+ _LOGE("Failed to get package name\n");
+ continue;
+ }
+ unique_id = (char *)sqlite3_column_text(stmt, 1);
+ callback_result =
+ consumer_list_cb((data_control_h)provider, app_id, user_data);
+ _LOGI("app_id : %s, unique_id : %s, result : %d ",
+ app_id, unique_id, callback_result);
+ if (!callback_result)
+ break;
+ }
+out:
+ if (stmt) {
+ sqlite3_reset(stmt);
+ sqlite3_clear_bindings(stmt);
+ sqlite3_finalize(stmt);
+ }
+
+ return ret;
+}
+
+int datacontrol_provider_write_socket(
+ int fd, void *buffer, unsigned int nbytes,
+ unsigned int *bytes_write)
+{
+ int ret = _write_socket(fd, buffer, nbytes, bytes_write);
+ return ret;
+}
+
+int datacontrol_provider_send_select_result_without_data(
+ int request_id, int *fd)
+{
+ int ret;
+ bundle *res;
+ bundle *b;
+ datacontrol_socket_info *socket_info;
+ char *caller_app_id;
+
+ _LOGI("Send select result by byte array for request id: %d", request_id);
+
+ if (__request_table == NULL)
+ __initialize_provider();
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, NULL);
+ ret = __send_result(res, DATACONTROL_TYPE_UNDEFINED, NULL);
+ bundle_free(res);
+
+ caller_app_id = (char *)bundle_get_val(b, AUL_K_CALLER_APPID);
+ socket_info = g_hash_table_lookup(__socket_pair_hash, caller_app_id);
+ if (socket_info == NULL) {
+ _LOGE("__socket_pair_hash lookup fail");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ *fd = socket_info->socket_fd;
+ g_hash_table_remove(__request_table, &request_id);
+
+ return ret;
+}
+
+int datacontrol_provider_get_select_page_info(
+ int request_id, int *page_num, int *count_per_page)
+{
+ bundle *b;
+ const char *page_num_str;
+ const char *count_per_page_str;
+
+ if (__request_table == NULL) {
+ _LOGE("__request_table is NULL");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ b = g_hash_table_lookup(__request_table, &request_id);
+ if (!b) {
+ _LOGE("No data for the request id: %d", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ page_num_str = bundle_get_val(b, RESULT_PAGE_NUMBER);
+ count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE);
+ if (page_num_str == NULL || count_per_page_str == NULL) {
+ _LOGE("No page data for the request id: %d, ", request_id);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ *page_num = __get_int_from_str(page_num_str);
+ *count_per_page = __get_int_from_str(count_per_page_str);
+
+ return DATA_CONTROL_ERROR_NONE;
}
*/
-#include <dlog.h>
#include <bundle.h>
#include <errno.h>
#include <glib.h>
#include <stdbool.h>
#include <stdlib.h>
-#include <data-control-sql.h>
#include "data_control_bulk.h"
#include "data_control_internal.h"
#include "data_control_sql.h"
#include "data_control_log.h"
-struct data_control_s {
- char *provider_id;
- char *data_id;
-};
-
-struct datacontrol_s {
- char *provider_id;
- char *data_id;
-};
-
-typedef struct bulk_cb_info_s {
- data_control_bulk_cb bulk_cb;
- void *user_data;
-} bulk_cb_info;
-
-static GHashTable *__response_table = NULL;
-static GHashTable *__bulk_response_table = NULL;
-
-static datacontrol_sql_response_cb __datacontrol_sql_cb;
-
-static void __sql_bulk_insert_response(int req_id, datacontrol_h provider, data_control_bulk_result_data_h bulk_results, bool provider_result, const char *error, void *user_data)
-{
- _LOGI("sql_bulk_insert_response");
-
- bulk_cb_info *info = (bulk_cb_info *)g_hash_table_lookup(__bulk_response_table, provider->provider_id);
- if (info)
- info->bulk_cb(req_id, (data_control_h)provider, bulk_results, provider_result, error, user_data);
-}
-
-static void __sql_insert_response(int req_id, datacontrol_h provider, long long insert_rowid, bool provider_result, const char *error, void *user_data)
-{
- _LOGI("sql_insert_response");
-
- data_control_sql_response_cb *callback = (data_control_sql_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->insert_cb(req_id, (data_control_h)provider, insert_rowid, provider_result, error, user_data);
-}
-
-static void __sql_update_response(int req_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
-{
- _LOGI("sql_update_response");
-
- data_control_sql_response_cb *callback = (data_control_sql_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->update_cb(req_id, (data_control_h)provider, provider_result, error, user_data);
-}
-
-static void __sql_delete_response(int req_id, datacontrol_h provider, bool provider_result, const char *error, void *user_data)
-{
- _LOGI("sql_delete_response");
-
- data_control_sql_response_cb *callback = (data_control_sql_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->delete_cb(req_id, (data_control_h)provider, provider_result, error, user_data);
-}
-
-static void __sql_select_response(int req_id, datacontrol_h provider, resultset_cursor *enumerator, bool provider_result, const char *error, void *user_data)
-{
- _LOGI("sql_select_response");
-
- data_control_sql_response_cb *callback = (data_control_sql_response_cb *)g_hash_table_lookup(__response_table, provider->provider_id);
- if (callback)
- callback->select_cb(req_id, (data_control_h)provider, (result_set_cursor)enumerator, provider_result, error, user_data);
-}
-
-static void __free_data(gpointer data)
-{
- if (data) {
- g_free(data);
- data = NULL;
- }
-}
-
-static void __initialize(void)
-{
- __response_table = g_hash_table_new_full(g_str_hash, g_str_equal, __free_data, __free_data);
- __bulk_response_table = g_hash_table_new_full(g_str_hash, g_str_equal, __free_data, __free_data);
-
- __datacontrol_sql_cb.bulk_insert = __sql_bulk_insert_response;
- __datacontrol_sql_cb.insert = __sql_insert_response;
- __datacontrol_sql_cb.delete = __sql_delete_response;
- __datacontrol_sql_cb.select = __sql_select_response;
- __datacontrol_sql_cb.update = __sql_update_response;
-}
-
EXPORT_API int data_control_sql_create(data_control_h *provider)
{
- return datacontrol_sql_create((datacontrol_h *)provider);
+ return _create_data_control_h(provider);
}
EXPORT_API int data_control_sql_destroy(data_control_h provider)
{
- return datacontrol_sql_destroy((datacontrol_h)provider);
+ return _destroy_data_control_h(provider);
}
-EXPORT_API int data_control_sql_set_provider_id(data_control_h provider, const char *provider_id)
+EXPORT_API int data_control_sql_set_provider_id(data_control_h provider,
+ const char *provider_id)
{
- return datacontrol_sql_set_provider_id((datacontrol_h)provider, provider_id);
+ return _set_provider_id(provider, provider_id);
}
-EXPORT_API int data_control_sql_get_provider_id(data_control_h provider, char **provider_id)
+EXPORT_API int data_control_sql_get_provider_id(data_control_h provider,
+ char **provider_id)
{
- return datacontrol_sql_get_provider_id((datacontrol_h)provider, provider_id);
+ return _get_provider_id(provider, provider_id);
}
-EXPORT_API int data_control_sql_set_data_id(data_control_h provider, const char *data_id)
+EXPORT_API int data_control_sql_set_data_id(data_control_h provider,
+ const char *data_id)
{
- return datacontrol_sql_set_data_id((datacontrol_h)provider, data_id);
+ return _set_data_id(provider, data_id);
}
-EXPORT_API int data_control_sql_get_data_id(data_control_h provider, char **data_id)
+EXPORT_API int data_control_sql_get_data_id(data_control_h provider,
+ char **data_id)
{
- return datacontrol_sql_get_data_id((datacontrol_h)provider, data_id);
+ return _get_data_id(provider, data_id);
}
-EXPORT_API int data_control_sql_register_response_cb(data_control_h provider, data_control_sql_response_cb *callback, void *user_data)
+EXPORT_API int data_control_sql_register_response_cb(data_control_h provider,
+ data_control_sql_response_cb *callback, void *user_data)
{
- char *id;
- data_control_sql_response_cb *cb;
-
- if (__response_table == NULL)
- __initialize();
-
- if (callback == NULL)
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
-
- id = strdup(provider->provider_id);
- if (id == NULL)
- return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
-
- cb = (data_control_sql_response_cb *)malloc(sizeof(data_control_sql_response_cb));
- if (cb == NULL) {
- free(id);
- return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
- }
-
- memcpy(cb, callback, sizeof(data_control_sql_response_cb));
- g_hash_table_insert(__response_table, id, cb);
-
- return datacontrol_sql_register_response_cb((datacontrol_h)provider, &__datacontrol_sql_cb, user_data);
+ return _register_response_cb(provider, (void *)callback,
+ DATACONTROL_TYPE_SQL_SELECT, user_data);
}
EXPORT_API int data_control_sql_unregister_response_cb(data_control_h provider)
{
- if (provider->provider_id)
- g_hash_table_remove(__response_table, provider->provider_id);
-
- return datacontrol_sql_unregister_response_cb((datacontrol_h)provider);
+ return _unregister_response_cb(provider, DATACONTROL_TYPE_SQL_SELECT);
}
-EXPORT_API int data_control_sql_register_insert_bulk_data_response_cb(data_control_h provider,
+EXPORT_API int data_control_sql_register_insert_bulk_data_response_cb(
+ data_control_h provider,
data_control_bulk_cb callback, void *user_data)
{
- char *id = NULL;
- bulk_cb_info *info = NULL;
- int ret;
-
- if (__bulk_response_table == NULL)
- __initialize();
-
- if (callback == NULL)
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
-
- info = (bulk_cb_info *)calloc(1, sizeof(bulk_cb_info));
- if (info == NULL) {
- _LOGE("fail to alloc info");
- ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
- goto out;
- }
- info->bulk_cb = callback;
- info->user_data = user_data;
-
- id = strdup(provider->provider_id);
- if (id == NULL) {
- ret = DATA_CONTROL_ERROR_OUT_OF_MEMORY;
- goto out;
- }
-
- g_hash_table_insert(__bulk_response_table, id, info);
- if (datacontrol_sql_cb_is_registered(id))
- return DATA_CONTROL_ERROR_NONE;
- ret = datacontrol_sql_register_response_cb((datacontrol_h)provider, &__datacontrol_sql_cb, NULL);
-
-out:
- if (ret != DATA_CONTROL_ERROR_NONE) {
- if (id != NULL)
- free(id);
- if (info != NULL)
- free(info);
- }
-
- return ret;
+ return _register_response_cb(provider, (void *)callback,
+ DATACONTROL_TYPE_SQL_BULK_INSERT, user_data);
}
EXPORT_API int data_control_sql_unregister_insert_bulk_data_response_cb(data_control_h provider)
{
- if (provider != NULL && provider->provider_id && __bulk_response_table) {
- if (g_hash_table_lookup(__bulk_response_table, provider->provider_id) != NULL) {
- g_hash_table_remove(__bulk_response_table, provider->provider_id);
- } else {
- _LOGE("Invalid param");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- }
- } else {
- _LOGE("Invalid param");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- }
- return DATA_CONTROL_ERROR_NONE;
+ return _unregister_response_cb(provider, DATACONTROL_TYPE_SQL_BULK_INSERT);
}
-EXPORT_API int data_control_sql_insert_bulk_data(data_control_h provider, data_control_bulk_data_h bulk_data_h, int *request_id)
+EXPORT_API int data_control_sql_insert_bulk_data(data_control_h provider,
+ data_control_bulk_data_h bulk_data_h, int *request_id)
{
int retval;
+ long long arg_size = 0;
+ const char *arg_list[2];
+ bundle *b;
+ bundle *data;
+ int count;
+ int i;
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL) {
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
+ if (retval != DATA_CONTROL_ERROR_NONE)
+ return retval;
+
+ retval = _check_cert(provider->provider_id, false, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+ _LOGI("SQL data control, insert to provider_id: %s, data_id: %s",
+ provider->provider_id, provider->data_id);
+
+ /* Check size of arguments */
+ retval = data_control_bulk_data_get_count(bulk_data_h, &count);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return datacontrol_sql_insert_bulk_data((datacontrol_h)provider, bulk_data_h, request_id);
+ for (i = 0; i < count; i++) {
+ data_control_bulk_data_get_data(bulk_data_h, i, &data);
+ bundle_foreach(data, _bundle_foreach_check_arg_size_cb, &arg_size);
+ }
+ arg_size += (strlen(provider->data_id) + strlen(provider->provider_id)) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of the request argument exceeds the limit, 1M.");
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
+
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ arg_list[0] = provider->data_id;
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 1);
+
+ /* Set the request id */
+ *request_id = _datacontrol_create_request_id();
+ _LOGI("request id : %d", *request_id);
+
+ retval = _request_provider(provider, DATACONTROL_TYPE_SQL_BULK_INSERT,
+ b, bulk_data_h, *request_id);
+ bundle_free(b);
+ return retval;
}
-EXPORT_API int data_control_sql_insert(data_control_h provider, const bundle *insert_data, int *request_id)
+EXPORT_API int data_control_sql_insert(data_control_h provider,
+ const bundle *insert_data, int *request_id)
{
int retval;
+ long long arg_size = 0;
+ const char *arg_list[2];
+ bundle *b;
+ char insert_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
+ int count;
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL || insert_data == NULL) {
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+ retval = _check_cert(provider->provider_id, false, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return datacontrol_sql_insert((datacontrol_h)provider, insert_data, request_id);
+ /* Check size of arguments */
+ bundle_foreach((bundle *)insert_data, _bundle_foreach_check_arg_size_cb, &arg_size);
+ arg_size += strlen(provider->data_id) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of the request argument exceeds the limit, 1M.");
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
+
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ count = bundle_get_count((bundle *)insert_data);
+ retval = snprintf(insert_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", count);
+ if (retval < 0) {
+ _LOGE("unable to convert insert column count to string: %d", errno);
+ bundle_free(b);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ arg_list[0] = provider->data_id;
+ arg_list[1] = insert_column_count;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
+
+ /* Set the request id */
+ *request_id = _datacontrol_create_request_id();
+ _LOGI("request id : %d", *request_id);
+
+ retval = _request_provider(provider, DATACONTROL_TYPE_SQL_INSERT,
+ b, (bundle *)insert_data, *request_id);
+ bundle_free(b);
+
+ return retval;
}
-EXPORT_API int data_control_sql_delete(data_control_h provider, const char *where, int *request_id)
+EXPORT_API int data_control_sql_delete(data_control_h provider,
+ const char *where, int *request_id)
{
int retval;
+ const char *arg_list[2];
+ int reqId;
+ bundle *b;
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL) {
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+ retval = _check_cert(provider->provider_id, false, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return datacontrol_sql_delete((datacontrol_h)provider, where, request_id);
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ arg_list[0] = provider->data_id;
+
+ if (where)
+ arg_list[1] = where;
+ else
+ arg_list[1] = DATACONTROL_EMPTY;
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
+
+ /* Set the request id */
+ reqId = _datacontrol_create_request_id();
+ *request_id = reqId;
+
+ retval = _request_provider(provider, DATACONTROL_TYPE_SQL_DELETE, b, NULL, reqId);
+ bundle_free(b);
+ return retval;
+
}
-EXPORT_API int data_control_sql_select(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id)
+EXPORT_API int data_control_sql_select(data_control_h provider,
+ char **column_list, int column_count, const char *where,
+ const char *order, int *request_id)
{
+ return data_control_sql_select_with_page(provider, column_list,
+ column_count, where, order, 1, 20, request_id);
+}
+
+EXPORT_API int data_control_sql_select_with_page(data_control_h provider,
+ char **column_list, int column_count, const char *where,
+ const char *order, int page_number, int count_per_page,
+ int *request_id)
+{
+ int total_arg_count = -1;
int retval;
+ bundle *b;
+ char page[32] = {0, };
+ char count_per_page_no[32] = {0, };
+ const char **arg_list;
+ int i;
+ char select_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, };
+ int select_col;
+ int reqId;
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL || column_list == NULL) {
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+ retval = _check_cert(provider->provider_id, false, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return datacontrol_sql_select((datacontrol_h)provider, column_list, column_count, where, order, request_id);
-}
+ _LOGI("SQL data control, select to provider_id: %s, data_id: %s, \
+ col_count: %d, where: %s, order: %s, page_number: %d, \
+ per_page: %d",
+ provider->provider_id, provider->data_id,
+ column_count, where, order, page_number,
+ count_per_page);
-EXPORT_API int data_control_sql_select_with_page(data_control_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id)
-{
- int retval;
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
- if (provider == NULL || provider->provider_id == NULL ||
- provider->data_id == NULL || column_list == NULL) {
- _LOGE("Invalid parameter");
- return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ retval = snprintf(page, 32, "%d", page_number);
+ if (retval < 0) {
+ _LOGE("unable to convert page no to string: %d", errno);
+ bundle_free(b);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ retval = snprintf(count_per_page_no, 32, "%d", count_per_page);
+ if (retval < 0) {
+ _LOGE("unable to convert count per page no to string: %d", errno);
+ bundle_free(b);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
- if (retval != DATA_CONTROL_ERROR_NONE)
- return retval;
+ total_arg_count = column_count + DATACONTROL_SELECT_EXTRA_COUNT;
+ arg_list = (const char **)malloc(total_arg_count * (sizeof(char *)));
+
+ _LOGI("total arg count %d", total_arg_count);
+
+ arg_list[0] = provider->data_id; /* arg[0]: data ID */
+ i = 1;
+ if (column_list) {
+ retval = snprintf(select_column_count,
+ MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", column_count);
+ if (retval < 0) {
+ _LOGE("unable to convert select col count to string: %d", errno);
+ free(arg_list);
+ bundle_free(b);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+
+ arg_list[i] = select_column_count; /* arg[1]: selected column count */
+
+ ++i;
+ select_col = 0;
+ while (select_col < column_count)
+ arg_list[i++] = column_list[select_col++];
+ }
- return datacontrol_sql_select_with_page((datacontrol_h)provider, column_list, column_count, where, order, page_number, count_per_page, request_id);
+ if (where) /* arg: where clause */
+ arg_list[i++] = where;
+ else
+ arg_list[i++] = DATACONTROL_EMPTY;
+
+ if (order) /* arg: order clause */
+ arg_list[i++] = order;
+ else
+ arg_list[i++] = DATACONTROL_EMPTY;
+
+ arg_list[i++] = page; /* arg: page number */
+
+ arg_list[i] = count_per_page_no; /* arg: count per page */
+
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, total_arg_count);
+ free(arg_list);
+
+ reqId = _datacontrol_create_request_id();
+ *request_id = reqId;
+
+ retval = _request_provider(provider, DATACONTROL_TYPE_SQL_SELECT,
+ b, NULL, reqId);
+ bundle_free(b);
+ return retval;
}
-EXPORT_API int data_control_sql_update(data_control_h provider, const bundle *update_data, const char *where, int *request_id)
+EXPORT_API int data_control_sql_update(data_control_h provider,
+ const bundle *update_data, const char *where, int *request_id)
{
int retval;
+ long long arg_size = 0;
+ bundle *b;
+ const char *arg_list[4];
if (provider == NULL || provider->provider_id == NULL ||
provider->data_id == NULL ||
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
}
- retval = datacontrol_check_privilege(PRIVILEGE_CONSUMER);
+ retval = _check_privilege(PRIVILEGE_CONSUMER);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- retval = datacontrol_check_cert(provider->provider_id, false, NULL);
+ retval = _check_cert(provider->provider_id, false, NULL);
if (retval != DATA_CONTROL_ERROR_NONE)
return retval;
- return datacontrol_sql_update((datacontrol_h)provider, update_data, where, request_id);
-}
+ /* Check size of arguments */
+ bundle_foreach((bundle *)update_data, _bundle_foreach_check_arg_size_cb, &arg_size);
+ arg_size += strlen(provider->data_id) * sizeof(wchar_t);
+ if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) {
+ _LOGE("The size of the request argument exceeds the limit, 1M.");
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED;
+ }
+ b = bundle_create();
+ if (!b) {
+ _LOGE("unable to create bundle: %d", errno);
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id);
+ bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id);
+
+ arg_list[0] = provider->data_id; /* list(0): data ID */
+ arg_list[1] = where;
+ bundle_add_str_array(b, OSP_K_ARG, arg_list, 2);
+
+ *request_id = _datacontrol_create_request_id();
+ retval = _request_provider(provider, DATACONTROL_TYPE_SQL_UPDATE,
+ b, (bundle *)update_data, *request_id);
+
+ bundle_free(b);
+ return retval;
+
+}
* limitations under the License.
*/
-#include <dlog.h>
-#include <data-control-sql-cursor.h>
+#include <stdlib.h>
+#include <string.h>
#include "data_control_sql_cursor.h"
+#include "data_control_types.h"
+#include "data_control_log.h"
+#include "data_control_internal.h"
+
+#define ERR_BUFFER_SIZE 1024
struct result_set_s {
int result_set_fd;
EXPORT_API int data_control_sql_step_next(result_set_cursor cursor)
{
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_step_next((resultset_cursor *)cursor);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ if (__cursor->resultset_row_count == 0) {
+ _LOGE("Reached to the end of the result set");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (__cursor->resultset_current_offset == 0) {
+ __cursor->resultset_current_offset = __cursor->resultset_content_offset;
+ } else {
+ if (!(__cursor->resultset_current_row_count < (__cursor->resultset_row_count - 1))) {
+ _LOGE("Reached to the end of the result set");
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ __cursor->resultset_current_offset =
+ __cursor->row_offset_list[__cursor->resultset_current_row_count + 1];
+ __cursor->resultset_current_row_count++;
+ }
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_sql_step_last(result_set_cursor cursor)
{
+ int ret = 0;
+ int i = 0;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_step_last((resultset_cursor *)cursor);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ if (__cursor->resultset_current_row_count ==
+ (__cursor->resultset_row_count - 1))
+ return DATA_CONTROL_ERROR_NONE; /* Already @ last row */
+
+ if (!__cursor->row_offset_list) {
+ /* make a first move */
+ ret = data_control_sql_step_next((result_set_cursor)__cursor);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
+ }
+
+ /* check if the rowOffsetList contains last row offset */
+ if (__cursor->row_offset_list &&
+ __cursor->row_offset_list[__cursor->resultset_row_count - 1] != 0) {
+ __cursor->resultset_current_offset =
+ __cursor->row_offset_list[__cursor->resultset_row_count - 1];
+ __cursor->resultset_current_row_count =
+ __cursor->resultset_row_count - 1;
+ } else {
+ /* Move till last row offset. */
+ for (i = (__cursor->resultset_current_row_count + 1);
+ i < __cursor->resultset_row_count;
+ i++) {
+ /* move till last row data offset */
+ ret = data_control_sql_step_next((result_set_cursor)__cursor);
+ if (ret != DATA_CONTROL_ERROR_NONE)
+ return ret;
+ }
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_sql_step_first(result_set_cursor cursor)
{
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_step_first((resultset_cursor *)cursor);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ if (__cursor->resultset_current_offset > 0) {
+ __cursor->resultset_current_offset = __cursor->resultset_content_offset;
+ __cursor->resultset_current_row_count = 0;
+ return DATA_CONTROL_ERROR_NONE;
+ }
+
+ /* MoveFirst is called for the first time before MoveNext() or MoveLast() */
+ __cursor->resultset_current_offset = 0;
+ return data_control_sql_step_next((result_set_cursor)__cursor);
}
EXPORT_API int data_control_sql_step_previous(result_set_cursor cursor)
{
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_step_previous((resultset_cursor *)cursor);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ if ((__cursor->resultset_current_row_count - 1) < 0) {
+ _LOGE("invalid request");
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+ __cursor->resultset_current_offset =
+ __cursor->row_offset_list[__cursor->resultset_current_row_count - 1];
+ __cursor->resultset_current_row_count--;
+
+ return DATA_CONTROL_ERROR_NONE;
}
EXPORT_API int data_control_sql_get_column_count(result_set_cursor cursor)
{
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_column_count((resultset_cursor *)cursor);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ return __cursor->resultset_col_count;
}
-EXPORT_API int data_control_sql_get_column_name(result_set_cursor cursor, int column_index, char *name)
+EXPORT_API int data_control_sql_get_column_name(result_set_cursor cursor,
+ int column_index, char *name)
{
+ char *col_name = NULL;
+ int i = 0;
+ int ret = 0;
+ int column_len = 0;
+ int fd;
+ char err_buf[ERR_BUFFER_SIZE];
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_column_name((resultset_cursor *)cursor, column_index, name);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+ ret = lseek(fd, __cursor->resultset_col_name_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %d %s",
+ __cursor->resultset_current_offset,
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ for (i = 0; i < column_index + 1; i++) {
+ ret = read(fd, &column_len, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read column_len: %d", column_len);
+ goto error;
+ }
+
+ if (column_len < 0 || column_len > MAX_COLUMN_SIZE) {
+ _LOGE("Invalid column_len: %d", column_len);
+ goto error;
+ }
+
+ if (i == column_index) {
+ col_name = (char *)calloc(column_len, sizeof(char));
+ ret = read(fd, col_name, column_len);
+ if (ret == 0) {
+ _LOGE("unable to read col_name : %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ goto error;
+ }
+ } else {
+ ret = lseek(fd, column_len, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ goto error;
+ }
+ }
+ }
+ memset(name, 0, column_len);
+ memcpy(name, col_name, column_len);
+ free(col_name);
+ _LOGI("The column name is %s", name);
+
+ return DATA_CONTROL_ERROR_NONE;
+
+error:
+ if (col_name)
+ free(col_name);
+ return DATA_CONTROL_ERROR_IO_ERROR;
}
-EXPORT_API int data_control_sql_get_column_item_size(result_set_cursor cursor, int column_index)
+EXPORT_API int data_control_sql_get_column_item_size(result_set_cursor cursor,
+ int column_index)
{
+ int type = -1;
+ int size = 0;
+ int i = 0;
+ int ret = 0;
+ char err_buf[ERR_BUFFER_SIZE];
+ int fd = 0;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_column_item_size((resultset_cursor *)cursor, column_index);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+ ret = lseek(fd, __cursor->resultset_current_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %d %s",
+ __cursor->resultset_current_offset,
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ /* move to column index */
+ for (i = 0; i < column_index; i++) {
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = lseek(fd, size, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ return size;
+
}
-EXPORT_API int data_control_sql_get_column_item_type(result_set_cursor cursor, int column_index, data_control_sql_column_type_e *col_type)
+EXPORT_API int data_control_sql_get_column_item_type(result_set_cursor cursor,
+ int column_index, data_control_sql_column_type_e *col_type)
{
+ int type = -1;
+ int i = 0;
+ int size = 0;
+ int ret = 0;
+ char err_buf[ERR_BUFFER_SIZE];
+ int fd = 0;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_column_item_type((resultset_cursor *)cursor, column_index, (datacontrol_sql_column_type *)col_type);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+
+ ret = lseek(fd, __cursor->resultset_current_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ /* move to column index */
+ for (i = 0; i < column_index; i++) {
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = lseek(fd, size, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ switch (type) {
+ case DATA_CONTROL_SQL_COLUMN_TYPE_INT64:
+ *col_type = DATA_CONTROL_SQL_COLUMN_TYPE_INT64;
+ break;
+ case DATA_CONTROL_SQL_COLUMN_TYPE_DOUBLE:
+ *col_type = DATA_CONTROL_SQL_COLUMN_TYPE_DOUBLE;
+ break;
+ case DATA_CONTROL_SQL_COLUMN_TYPE_TEXT:
+ *col_type = DATA_CONTROL_SQL_COLUMN_TYPE_TEXT;
+ break;
+ case DATA_CONTROL_SQL_COLUMN_TYPE_BLOB:
+ *col_type = DATA_CONTROL_SQL_COLUMN_TYPE_BLOB;
+ break;
+ case DATA_CONTROL_SQL_COLUMN_TYPE_NULL:
+ *col_type = DATA_CONTROL_SQL_COLUMN_TYPE_NULL;
+ break;
+ default:
+ *col_type = DATA_CONTROL_SQL_COLUMN_TYPE_UNDEFINED;
+ break;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+
}
-EXPORT_API int data_control_sql_get_blob_data(result_set_cursor cursor, int column_index, void *buffer, int data_size)
+EXPORT_API int data_control_sql_get_blob_data(result_set_cursor cursor,
+ int column_index, void *buffer, int data_size)
{
+ int type = -1;
+ int size = 0;
+ int i = 0;
+ int ret = 0;
+ char err_buf[ERR_BUFFER_SIZE];
+ int fd = 0;
+ char *data;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_blob_data((resultset_cursor *)cursor, column_index, buffer, data_size);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+
+
+ ret = lseek(fd, __cursor->resultset_current_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ /* move to column index */
+ for (i = 0; i < column_index; i++) {
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = lseek(fd, size, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (type != (int)DATA_CONTROL_SQL_COLUMN_TYPE_BLOB) {
+ _LOGE("type mismatch: requested for BLOB type but %d present:", type);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read size in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (size > data_size) {
+ _LOGE("size is more than the size requested");
+ return DATA_CONTROL_ERROR_MAX_EXCEEDED; /* overflow */
+ }
+
+ if (size > 0 && size < MAX_REQUEST_ARGUMENT_SIZE) {
+ data = (char *)malloc((size + 1) * (sizeof(char)));
+ memset(data, 0, size + 1);
+
+ ret = read(fd, data, size);
+ if (ret < size) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ free(data);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ memcpy(buffer, data, size + 1);
+ free(data);
+ } else {
+ _LOGE("Invalid size %d", size);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ return DATA_CONTROL_ERROR_NONE;
}
-EXPORT_API int data_control_sql_get_int_data(result_set_cursor cursor, int column_index, int *data)
+EXPORT_API int data_control_sql_get_int_data(result_set_cursor cursor,
+ int column_index, int *data)
{
+ long long long_value = 0;
+ int ret = -1;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_int_data((resultset_cursor *)cursor, column_index, data);
+
+ ret = data_control_sql_get_int64_data(cursor, column_index, &long_value);
+ if (ret == 0)
+ *data = (int) long_value;
+
+ return ret;
}
-EXPORT_API int data_control_sql_get_int64_data(result_set_cursor cursor, int column_index, long long *data)
+EXPORT_API int data_control_sql_get_int64_data(result_set_cursor cursor,
+ int column_index, long long *data)
{
+ int type = -1;
+ int size = 0;
+ int i = 0;
+ int ret = 0;
+ char err_buf[ERR_BUFFER_SIZE];
+ int fd = 0;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_int64_data((resultset_cursor *)cursor, column_index, data);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+ ret = lseek(fd, __cursor->resultset_current_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ /* move to column index */
+ for (i = 0; i < column_index; i++) {
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = lseek(fd, size, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (type != (int)DATA_CONTROL_SQL_COLUMN_TYPE_INT64) {
+ _LOGE("type mismatch: requested for int type but %d present:", type);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, data, size);
+ if (ret < size) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+
}
-EXPORT_API int data_control_sql_get_double_data(result_set_cursor cursor, int column_index, double *data)
+EXPORT_API int data_control_sql_get_double_data(result_set_cursor cursor,
+ int column_index, double *data)
{
+ int type = -1;
+ int size = 0;
+ int i = 0;
+ int ret = 0;
+ char err_buf[ERR_BUFFER_SIZE];
+ int fd = 0;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_double_data((resultset_cursor *)cursor, column_index, data);
+
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+ ret = lseek(fd, __cursor->resultset_current_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ /* move to column index */
+ for (i = 0; i < column_index; i++) {
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = lseek(fd, size, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (type != (int)DATA_CONTROL_SQL_COLUMN_TYPE_DOUBLE) {
+ _LOGE("type mismatch: requested for double type but %d present:", type);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, data, size);
+ if (ret < size) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+
}
-EXPORT_API int data_control_sql_get_text_data(result_set_cursor cursor, int column_index, char *buffer)
+EXPORT_API int data_control_sql_get_text_data(result_set_cursor cursor,
+ int column_index, char *buffer)
{
+ int type = -1;
+ int size = 0;
+ int i = 0;
+ int ret = 0;
+ char err_buf[ERR_BUFFER_SIZE];
+ char *data;
+ int fd = 0;
+ resultset_cursor *__cursor = NULL;
+
if (cursor == NULL)
return DATA_CONTROL_ERROR_INVALID_PARAMETER;
- return datacontrol_sql_get_text_data((resultset_cursor *)cursor, column_index, buffer);
-}
+ __cursor = (resultset_cursor *)cursor;
+
+ fd = __cursor->resultset_fd;
+ ret = lseek(fd, __cursor->resultset_current_offset, SEEK_SET);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ /* move to column index */
+ for (i = 0; i < column_index; i++) {
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ ret = lseek(fd, size, SEEK_CUR);
+ if (ret < 0) {
+ _LOGE("unable to seek in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+ }
+
+ ret = read(fd, &type, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (type != (int)DATA_CONTROL_SQL_COLUMN_TYPE_TEXT) {
+ _LOGE("type mismatch: requested for text type but %d present %d", type,
+ __cursor->resultset_current_offset);
+ return DATA_CONTROL_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = read(fd, &size, sizeof(int));
+ if (ret == 0) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ if (size > 0 && size < MAX_REQUEST_ARGUMENT_SIZE) {
+ data = (char *)malloc((size + 1) * (sizeof(char)));
+ if (!data) {
+ _LOGE("unable to create buffer to read");
+ return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
+ }
+
+ memset(data, 0, size + 1);
+ ret = read(fd, data, size);
+ if (ret < size) {
+ _LOGE("unable to read in the resultset file: %s",
+ strerror_r(errno, err_buf, sizeof(err_buf)));
+ free(data);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ memcpy(buffer, data, size + 1);
+ free(data);
+ } else {
+ _LOGE("Invalid size %d", size);
+ return DATA_CONTROL_ERROR_IO_ERROR;
+ }
+
+ return DATA_CONTROL_ERROR_NONE;
+}