* limitations under the License.
*/
-#include <glib.h>
-#include <dlog.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <arpa/inet.h>
-#include <bluetooth-api.h>
-
-#include "bluetooth.h"
-#include "bluetooth_internal.h"
-#include "bluetooth_private.h"
-
-#ifdef TIZEN_FEATURE_OTP_SUPPORT
-#define BT_CHECK_OTP_SUPPORT()
-#else
-#define BT_CHECK_OTP_SUPPORT() \
- { \
- LOGE("[%s] NOT_SUPPORTED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_SUPPORTED); \
- return BT_ERROR_NOT_SUPPORTED; \
- }
-#endif
-
-#define BT_CHECK_LE_SUPPORT() \
-{ \
- BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON); \
- BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_LE); \
-}
-
-#define BT_CHECK_OTP_SERVER_INIT_STATUS() \
- if (__bt_check_otp_server_init_status() == BT_ERROR_NOT_INITIALIZED) { \
- LOGE("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, \
- BT_ERROR_NOT_INITIALIZED); \
- return BT_ERROR_NOT_INITIALIZED; \
- }
-
-#define BT_OTP_SERVICE_UUID "00001825-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_FEATURE_UUID "00002abd-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OACP_CONTROL_POINT_UUID "00002ac5-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OLCP_CONTROL_POINT_UUID "00002ac6-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_NAME_UUID "00002abe-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_TYPE_UUID "00002abf-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_SIZE_UUID "00002ac0-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_FIRST_CREATED_UUID "00002ac1-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_LAST_MODIFIED_UUID "00002ac2-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_ID_UUID "00002ac3-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_PROP_UUID "00002ac4-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_LIST_FILTER_UUID "00002ac7-0000-1000-8000-00805f9b34fb"
-#define BT_OTP_OBJECT_CHANGED_UUID "00002ac8-0000-1000-8000-00805f9b34fb"
-
-/* OLCP opcodes */
-#define OLCP_FIRST 0x01
-#define OLCP_LAST 0x02
-#define OLCP_PREVIOUS 0x03
-#define OLCP_NEXT 0x04
-#define OLCP_GOTO 0x05
-#define OLCP_ORDER 0x06
-#define OLCP_REQ_NO_OBJ 0x07
-#define OLCP_CLEAR_MARKING 0x08
-#define OLCP_RESPONSE 0x70
-
-/* OLCP error opcodes */
-#define OLCP_SUCCESS 0x01
-#define OLCP_OPCODE_NOT_SUPPORTED 0x02
-#define OLCP_INVALID_PARAM 0x03
-#define OLCP_OPERATION_FAILED 0x04
-#define OLCP_OUT_OF_BOUNDS 0x05
-#define OLCP_TOO_MANY_OBJ 0x06
-#define OLCP_NO_OBJ 0x07
-#define OLCP_OJECT_ID_NOT_FOUND 0x08
-
-/* OACP opcodes */
-#define OACP_CREATE 0x01
-#define OACP_DELETE 0x02
-#define OACP_CALC_CHECKSUM 0x03
-#define OACP_EXECUTE 0x04
-#define OACP_READ 0x05
-#define OACP_WRITE 0x06
-#define OACP_ABORT 0x07
-#define OACP_RESPONSE 0x60
-
-/* OACP error codes */
-#define OACP_SUCCESS 0x01
-#define OACP_OPCODE_NOT_SUPPORTED 0x02
-#define OACP_INVALID_PARAM 0x03
-#define OACP_INSUFFICIENT_RESOURCES 0x04
-#define OACP_INVALID_OBJ 0x05
-#define OACP_CHANNEL_UNAVAILABLE 0x06
-#define OACP_UNSUPPORTED_TYPE 0x07
-#define OACP_PROCEDURE_NOT_SUPPORTED 0x08
-#define OACP_OBJECT_LOCKED 0x09
-#define OACP_OPERATION_FAILED 0x0A
-
-/* Object Properties */
-#define OBJECT_DELETE 0x00000001
-#define OBJECT_EXECUTE 0x00000002
-#define OBJECT_READ 0x00000004
-#define OBJECT_WRITE 0x00000008
-#define OBJECT_APPEND 0x00000010
-#define OBJECT_TRUNCATE 0x00000020
-#define OBJECT_PATCH 0x00000040
-#define OBJECT_MARK 0x00000080
-
-#define BT_OTP_CLIENT_BASE_DIR "/home/owner/media/otp-client/"
-#define BT_FILE_PATH_MAX_LEN 262
-#define BT_OTP_FEATURE_LENGTH 8
-#define BT_ADDR_LENGTH 18
-
-#define BT_OTC_CONNECTION_MAX_TIMEOUT 10000 /* Timeout for OTC Connection in msec */
-
-#define BT_L2CAP_BUFFER_LEN 672
-
-#define BT_OTP_IS_OACP_SUPPORTED(feature) feature & 0xffffffff00000000
-#define BT_OTP_IS_OLCP_SUPPORTED(feature) feature & 0x00000000ffffffff
-#define BT_OTP_IS_OACP_READ_SUPPORTED(feature) feature & 0x1000000000000000
-#define BT_OTP_IS_OACP_CREATE_SUPPORTED(feature) feature & 0x0100000000000000
-#define BT_OTP_IS_OACP_WRITE_SUPPORTED(feature) feature & 0x2000000000000000
-#define BT_OTP_IS_OACP_EXECUTE_SUPPORTED(feature) feature & 0x0800000000000000
-#define BT_OTP_IS_OACP_DELETE_SUPPORTED(feature) feature & 0x0200000000000000
-#define BT_OTP_IS_OLCP_GOTO_SUPPORTED(feature) feature & 0x0000000001000000
-
-#define BT_OTP_IS_READ_PERMITTED(props) props & OBJECT_READ
-#define BT_OTP_IS_WRITE_PERMITTED(props) props & OBJECT_WRITE
-#define BT_OTP_IS_EXECUTE_PERMITTED(props) props & OBJECT_EXECUTE
-#define BT_OTP_IS_DELETE_PERMITTED(props) props & OBJECT_DELETE
-
-#define BT_OTP_OBJ_CHANGED_SRC(flag) (flag & 0x01)
-#define BT_OTP_OBJ_CHANGED_CONTENT(flag) ((flag & 0x02) >> 1)
-#define BT_OTP_OBJ_CHANGED_META(flag) ((flag & 0x04) >> 2)
-#define BT_OTP_OBJ_CHANGED_CREATE(flag) ((flag & 0x08) >> 3)
-#define BT_OTP_OBJ_CHANGED_DELETE(flag) ((flag & 0x10) >> 4)
-
-/* OTP Object Type Custom UUIDs */
-/* In SIG Assigned numbers not available */
-#define UNSUPPORTED_OBJECT_TYPE_UUID "7fb0"
-#define FIRMWARE_UUID "7fb1"
-#define ROUTE_GPX_UUID "7fb2"
-#define TRACK_GPX_UUID "7fb3"
-
-typedef enum {
- BT_OTP_NO_OPERATION = 0,
- BT_OTP_OBJECT_DISCOVERY,
- BT_OTP_OBJECT_READ,
- BT_OTP_OBJECT_SELECT,
- BT_OTP_OBJECT_CREATE,
- BT_OTP_OBJECT_WRITE,
- BT_OTP_OBJECT_EXECUTE,
- BT_OTP_OBJECT_DELETE,
-} bt_otp_api_info_e;
-
-typedef struct {
- char *name;
- char *type;
- uint32_t curr_size;
- uint32_t alloc_size;
- time_t first_created;
- time_t last_modified;
- uint64_t id;
- uint32_t props;
-} object_metadata;
-
-typedef struct {
- char *remote_address;
- bool connected;
-
- const void *connection_callback;
- void *conn_cb_user_data;
-
- char *otp_service_handle; /* OTP Service Handle */
- char *otp_feature_obj_path; /* OTP feature characteristic handle */
- uint64_t otp_feature; /* OTP feature value */
- char *otp_oacp_control_point; /* OTP OACP Control Point characteristic handle */
- char *otp_oacp_cccd; /* OTP OACP Control Point CCCD handle */
- char *otp_olcp_control_point; /* OTP OLCP Control Point characteristic handle */
- char *otp_olcp_cccd; /* OTP OLCP Control Point CCCD handle */
-
- /* Object Metadata paths */
- char *otp_name_obj_path; /* OTP Object Name characteristic handle */
- char *otp_type_obj_path; /* OTP Object Type characteristic handle */
- char *otp_size_obj_path; /* OTP Object Size characteristic handle */
- char *otp_first_created_obj_path; /* OTP Object Frist Created characteristic handle */
- char *otp_last_modified_obj_path; /* OTP Object Last Modified characteristic handle */
- char *otp_id_obj_path; /* OTP Object ID characteristic handle */
- char *otp_props_obj_path; /* OTP Object Properties characteristic handle */
-
- char *otp_list_filter_obj_path; /* OTP Object List Filter handle */
- char *otp_obj_changed_obj_path; /* OTP Object Changed handle */
- char *otp_obj_changed_cccd; /* OTP Object Changed CCCD handle */
-
- bool oacp_cccd_enabled; /* OTP OACP Control Point CCCD is enabled or not */
- bool olcp_cccd_enabled; /* OTP OLCP Control Point CCCD is enabled or not */
- bool obj_changed_cccd_enabed; /* OTP Object Changed CCCD is enabled or not */
- bool multiple_obj_supp; /* Indicates whether remote server supports
- * multiple-objects or not
- */
- GSList *object_list; /* List of server objects */
- uint64_t object_id; /* ID of current object */
-
- /* Ongoing API Information */
- bt_otp_api_info_e curr_op;
- const void *callback;
- void *user_data;
-} bt_otp_client_s;
-
-typedef struct {
- uint32_t offset;
- uint32_t length;
- uint32_t size;
- char *file_path;
- FILE *fp;
-} bt_otp_client_read_op;
-
-typedef struct {
- char *filename;
- char *type_uuid;
- time_t first_created;
- uint32_t size;
-} bt_otp_client_create_op;
-
-typedef struct {
- char *file_path;
- time_t last_modified;
- uint32_t size;
- uint32_t offset;
- uint32_t length;
- uint8_t mode;
- FILE *fp;
-} bt_otp_client_write_op;
-
-static bool is_otp_server_initialized = false;
-bt_otp_client_create_op *oacp_create_op = NULL;
-bt_otp_client_read_op *oacp_read_op = NULL;
-bt_otp_client_write_op *oacp_write_op = NULL;
-bool otc_connection_status = FALSE;
-bt_otp_object_list_s *obj_list;
-uint64_t select_obj_id = 0;
-object_metadata *metadata;
-GSList *otp_client_list;
-unsigned int timeout_id;
-guint id;
-
-object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id);
-static void _bt_otp_client_notify_read_object_status(int result,
- char *file_path, bt_otp_client_s *otp_client_s);
-void __bt_otp_reset_api_info(bt_otp_client_s *otp_client_s);
-static void _bt_otp_client_send_select_object_callback(int result,
- bt_otp_client_s *otp_client_s);
-static void _bt_otp_client_send_create_object_callback(int result,
- uint64_t id, bt_otp_client_s *otp_client_s);
-static void _bt_otp_client_send_write_object_callback(int result,
- unsigned int length, bt_otp_client_s *otp_client_s);
-static void _bt_otp_client_send_execute_object_callback(int result,
- bt_otp_client_s *otp_client_s);
-static void _bt_otp_client_send_delete_object_callback(int result,
- bt_otp_client_s *otp_client_s);
-static void _bt_otp_send_callback(int result, char *file_path, uint64_t id,
- unsigned int length, bt_otp_client_s *otp_client_s);
-
-/* LCOV_EXCL_START */
-int __bt_check_otp_server_init_status(void)
-{
- if (is_otp_server_initialized != true) {
- BT_ERR("NOT_INITIALIZED(0x%08x)", BT_ERROR_NOT_INITIALIZED);
- return BT_ERROR_NOT_INITIALIZED;
- }
-
- return BT_ERROR_NONE;
-}
-
-int bt_otp_server_initialize(const char *directory)
-{
- int error_code = BT_ERROR_NONE;
-
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_INIT_STATUS();
-
- error_code = _bt_get_error_code(bluetooth_otp_server_init(directory));
-
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
- error_code);
- return error_code;
- }
-
- is_otp_server_initialized = true;
- return BT_ERROR_NONE;
-}
-
-int bt_otp_server_deinitialize()
-{
- int error_code = BT_ERROR_NONE;
-
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_OTP_SERVER_INIT_STATUS();
-
- error_code = _bt_get_error_code(bluetooth_otp_server_deinit());
-
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
- error_code);
- return error_code;
- }
-
- is_otp_server_initialized = false;
- return BT_ERROR_NONE;
-}
-
-int bt_otp_set_server_state_changed_cb(bt_otp_server_state_changed_cb callback, void *user_data)
-{
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(callback);
- _bt_set_cb(BT_EVENT_OTP_SERVER_STATE_CHANGED, callback, user_data);
- return BT_ERROR_NONE;
-
-}
-int bt_otp_unset_server_state_changed_cb(void)
-{
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- if (_bt_check_cb(BT_EVENT_OTP_SERVER_STATE_CHANGED) == true)
- _bt_unset_cb(BT_EVENT_OTP_SERVER_STATE_CHANGED);
- return BT_ERROR_NONE;
-}
-
-static bt_otp_client_s *_bt_otp_client_find(const char *remote_address)
-{
- GSList *l;
- bt_otp_client_s *info;
-
- for (l = otp_client_list; l; l = g_slist_next(l)) {
- info = l->data;
- if ((info == NULL) || (info->remote_address == NULL)) {
- BT_ERR("_bt_otp_client_find Error Parameter are NULL..\n");
- continue;
- } else if (info && !g_ascii_strcasecmp(info->remote_address, remote_address)) {
- return info;
- }
- }
- return NULL;
-}
-
-static char *free_object_path(char *path)
-{
- g_free(path);
- return NULL;
-}
-
-static void _bt_otp_client_free_object_list(bt_otp_client_s *otp_client_s)
-{
- GSList *tmp = NULL;
- for (tmp = otp_client_s->object_list; tmp != NULL; tmp = tmp->next) {
- if (tmp->data) {
- object_metadata *metadata_info = tmp->data;
- g_free(metadata_info->name);
- g_free(metadata_info->type);
- otp_client_s->object_list = g_slist_delete_link(otp_client_s->object_list, tmp->data);
- }
- }
- g_slist_free(otp_client_s->object_list);
- otp_client_s->object_list = NULL;
-}
-
-static void _bt_otp_client_init(bt_otp_client_s *otp_client_s)
-{
- /* Reset CCCD */
- otp_client_s->oacp_cccd_enabled = FALSE;
- otp_client_s->olcp_cccd_enabled = FALSE;
- otp_client_s->obj_changed_cccd_enabed = FALSE;
-
- otp_client_s->curr_op = BT_OTP_NO_OPERATION;
- otp_client_s->multiple_obj_supp = FALSE;
-}
-
-static void __bt_otp_client_reset_server_data(bt_otp_client_s *otp_client_s)
-{
- int k;
-
- otp_client_s->otp_service_handle =
- free_object_path(otp_client_s->otp_service_handle);
- otp_client_s->otp_feature_obj_path =
- free_object_path(otp_client_s->otp_feature_obj_path);
- otp_client_s->otp_oacp_control_point =
- free_object_path(otp_client_s->otp_oacp_control_point);
- otp_client_s->otp_oacp_cccd =
- free_object_path(otp_client_s->otp_oacp_cccd);
- otp_client_s->otp_olcp_control_point =
- free_object_path(otp_client_s->otp_olcp_control_point);
- otp_client_s->otp_olcp_cccd =
- free_object_path(otp_client_s->otp_olcp_cccd);
- otp_client_s->otp_name_obj_path =
- free_object_path(otp_client_s->otp_name_obj_path);
- otp_client_s->otp_type_obj_path =
- free_object_path(otp_client_s->otp_type_obj_path);
- otp_client_s->otp_size_obj_path =
- free_object_path(otp_client_s->otp_size_obj_path);
- otp_client_s->otp_first_created_obj_path =
- free_object_path(otp_client_s->otp_first_created_obj_path);
- otp_client_s->otp_last_modified_obj_path =
- free_object_path(otp_client_s->otp_last_modified_obj_path);
- otp_client_s->otp_id_obj_path =
- free_object_path(otp_client_s->otp_id_obj_path);
- otp_client_s->otp_props_obj_path =
- free_object_path(otp_client_s->otp_props_obj_path);
- otp_client_s->otp_list_filter_obj_path =
- free_object_path(otp_client_s->otp_list_filter_obj_path);
- otp_client_s->otp_obj_changed_obj_path =
- free_object_path(otp_client_s->otp_obj_changed_obj_path);
- otp_client_s->otp_obj_changed_cccd =
- free_object_path(otp_client_s->otp_obj_changed_cccd);
-
- /* Free GSList */
- if (obj_list) {
- for (k = 0; k < obj_list->num_objects; k++) {
- otp_object_metadata_s *data = obj_list->data[k];
- g_free(data->name);
- g_free(data);
- }
- g_free(obj_list);
- obj_list = NULL;
- }
-
- /* Free Object List */
- _bt_otp_client_free_object_list(otp_client_s);
-
- if (oacp_read_op) {
- fclose(oacp_read_op->fp);
- g_free(oacp_read_op->file_path);
- g_free(oacp_read_op);
- oacp_read_op = NULL;
- }
-
- if (oacp_create_op) {
- g_free(oacp_create_op->filename);
- g_free(oacp_create_op->type_uuid);
- g_free(oacp_create_op);
- oacp_create_op = NULL;
- }
-
- _bt_otp_client_init(otp_client_s);
-}
-
-int bt_otp_client_set_connection_state_changed_cb(bt_otp_client_h otp_client,
- bt_otp_client_state_changed_cb callback, void *user_data)
-{
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
- BT_CHECK_INPUT_PARAMETER(callback);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- BT_DBG("Set OTP Client Connection State changed callback");
- /* register the callback */
- otp_client_s->connection_callback = callback;
- otp_client_s->conn_cb_user_data = user_data;
-
- return BT_ERROR_NONE;
-}
-
-int bt_otp_client_unset_connection_state_changed_cb(bt_otp_client_h otp_client)
-{
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- BT_DBG("UnSet OTP Client Connection State changed callback");
- /* unregister the callback */
- otp_client_s->connection_callback = NULL;
- otp_client_s->conn_cb_user_data = NULL;
-
- return BT_ERROR_NONE;
-}
-
-static int __bt_opt_update_feature(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- int ret = BLUETOOTH_ERROR_NONE;
-
- BT_DBG("OTP feature characteristic discovered");
-
- if (otp_client_s->otp_feature_obj_path)
- g_free(otp_client_s->otp_feature_obj_path);
-
- otp_client_s->otp_feature_obj_path = g_strdup(characteristic->handle);
-
- ret = _bt_get_error_code(bluetooth_otp_read_characteristic_value(otp_client_s->otp_feature_obj_path));
- if (ret != BT_ERROR_NONE)
- BT_ERR("Failed to read OTP Feature : %s(0x%08x)", _bt_convert_error_to_string(ret), ret);
-
- BT_DBG("OTP feature handle [%s]", otp_client_s->otp_feature_obj_path);
-
- return ret;
-}
-
-static int __bt_opt_update_oacp_control_point(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- int ret = BLUETOOTH_ERROR_NONE;
-
- BT_DBG("OTP OACP Control Point discovered");
- bt_gatt_char_descriptor_property_t desc_property;
- memset(&desc_property, 0x00, sizeof(desc_property));
-
- /* Get CCCD for Control Point */
- ret = bluetooth_gatt_get_char_descriptor_property(
- characteristic->char_desc_handle.handle[0], &desc_property);
-
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Failed to discover CCCD for OACP Control point");
- bluetooth_gatt_free_desc_property(&desc_property);
- return ret;
- }
- if (otp_client_s->otp_oacp_control_point)
- g_free(otp_client_s->otp_oacp_control_point);
- otp_client_s->otp_oacp_control_point = g_strdup(characteristic->handle);
-
- if (otp_client_s->otp_oacp_cccd)
- g_free(otp_client_s->otp_oacp_cccd);
- otp_client_s->otp_oacp_cccd = g_strdup(desc_property.handle);
-
- BT_DBG("OACP Control point handle [%s]", otp_client_s->otp_oacp_control_point);
- BT_DBG("OACP Control point CCCD handle [%s]", otp_client_s->otp_oacp_cccd);
-
- return ret;
-}
-
-static int __bt_opt_update_olcp_control_point(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- int ret = BLUETOOTH_ERROR_NONE;
-
- BT_DBG("OTP OLCP Control Point discovered");
- bt_gatt_char_descriptor_property_t desc_property;
- memset(&desc_property, 0x00, sizeof(desc_property));
-
- /* Get CCCD for Control Point */
- ret = bluetooth_gatt_get_char_descriptor_property(
- characteristic->char_desc_handle.handle[0], &desc_property);
-
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Failed to discover CCCD for OLCP Control point");
- bluetooth_gatt_free_desc_property(&desc_property);
- return ret;
- }
- if (otp_client_s->otp_olcp_control_point)
- g_free(otp_client_s->otp_olcp_control_point);
- otp_client_s->otp_olcp_control_point = g_strdup(characteristic->handle);
-
- if (otp_client_s->otp_olcp_cccd)
- g_free(otp_client_s->otp_olcp_cccd);
- otp_client_s->otp_olcp_cccd = g_strdup(desc_property.handle);
-
- BT_DBG("OLCP Control point handle [%s]", otp_client_s->otp_olcp_control_point);
- BT_DBG("OLCP Control point CCCD handle [%s]", otp_client_s->otp_olcp_cccd);
-
- return ret;
-}
-
-static int __bt_opt_update_object_name(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object Name characteristic discovered");
-
- if (otp_client_s->otp_name_obj_path)
- g_free(otp_client_s->otp_name_obj_path);
-
- otp_client_s->otp_name_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object Name handle [%s]", otp_client_s->otp_name_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_type(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object Type characteristic discovered");
-
- if (otp_client_s->otp_type_obj_path)
- g_free(otp_client_s->otp_type_obj_path);
-
- otp_client_s->otp_type_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object Type handle [%s]", otp_client_s->otp_type_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_size(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object Size characteristic discovered");
-
- if (otp_client_s->otp_size_obj_path)
- g_free(otp_client_s->otp_size_obj_path);
-
- otp_client_s->otp_size_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object Size handle [%s]", otp_client_s->otp_size_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_first_created(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object First Created characteristic discovered");
-
- if (otp_client_s->otp_first_created_obj_path)
- g_free(otp_client_s->otp_first_created_obj_path);
-
- otp_client_s->otp_first_created_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object First Created handle [%s]", otp_client_s->otp_first_created_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_last_modified(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object Last Modified characteristic discovered");
-
- if (otp_client_s->otp_last_modified_obj_path)
- g_free(otp_client_s->otp_last_modified_obj_path);
-
- otp_client_s->otp_last_modified_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object Last Modified handle [%s]", otp_client_s->otp_last_modified_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_id(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object ID characteristic discovered");
-
- if (otp_client_s->otp_id_obj_path)
- g_free(otp_client_s->otp_id_obj_path);
-
- otp_client_s->otp_id_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object ID handle [%s]", otp_client_s->otp_id_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_properties(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object Properties characteristic discovered");
-
- if (otp_client_s->otp_props_obj_path)
- g_free(otp_client_s->otp_props_obj_path);
-
- otp_client_s->otp_props_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object Properties handle [%s]", otp_client_s->otp_props_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_list_filter(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- BT_DBG("OTP Object List Filter characteristic discovered");
-
- if (otp_client_s->otp_list_filter_obj_path)
- g_free(otp_client_s->otp_list_filter_obj_path);
-
- otp_client_s->otp_list_filter_obj_path = g_strdup(characteristic->handle);
-
- BT_DBG("OTP Object List Filter handle [%s]", otp_client_s->otp_list_filter_obj_path);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_opt_update_object_changed(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- int ret = BLUETOOTH_ERROR_NONE;
-
- BT_DBG("OTP Object Changed characteristic discovered");
- bt_gatt_char_descriptor_property_t desc_property;
- memset(&desc_property, 0x00, sizeof(desc_property));
-
- /* Get CCCD for Object Changed Charc */
- ret = bluetooth_gatt_get_char_descriptor_property(
- characteristic->char_desc_handle.handle[0], &desc_property);
-
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Failed to discover CCCD for Object Changed Charc");
- bluetooth_gatt_free_desc_property(&desc_property);
- return ret;
- }
-
- if (otp_client_s->otp_obj_changed_obj_path)
- g_free(otp_client_s->otp_obj_changed_obj_path);
-
- otp_client_s->otp_obj_changed_obj_path = g_strdup(characteristic->handle);
-
- if (otp_client_s->otp_obj_changed_cccd)
- g_free(otp_client_s->otp_obj_changed_cccd);
-
- otp_client_s->otp_obj_changed_cccd = g_strdup(desc_property.handle);
-
- BT_DBG("OTP Object Changed handle [%s]", otp_client_s->otp_obj_changed_obj_path);
- BT_DBG("OTP Object Changed CCCD handle [%s]", otp_client_s->otp_obj_changed_cccd);
-
- return ret;
-}
-
-static int __bt_otp_update_data(bt_otp_client_s *otp_client_s, bt_gatt_char_property_t *characteristic)
-{
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_FEATURE_UUID))
- return __bt_opt_update_feature(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OACP_CONTROL_POINT_UUID))
- return __bt_opt_update_oacp_control_point(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OLCP_CONTROL_POINT_UUID))
- return __bt_opt_update_olcp_control_point(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_NAME_UUID))
- return __bt_opt_update_object_name(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_TYPE_UUID))
- return __bt_opt_update_object_type(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_SIZE_UUID))
- return __bt_opt_update_object_size(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_FIRST_CREATED_UUID))
- return __bt_opt_update_object_first_created(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_LAST_MODIFIED_UUID))
- return __bt_opt_update_object_last_modified(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_ID_UUID))
- return __bt_opt_update_object_id(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_PROP_UUID))
- return __bt_opt_update_object_properties(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_LIST_FILTER_UUID))
- return __bt_opt_update_object_list_filter(otp_client_s, characteristic);
-
- if (g_strstr_len(characteristic->uuid, -1, BT_OTP_OBJECT_CHANGED_UUID))
- return __bt_opt_update_object_changed(otp_client_s, characteristic);
-
- BT_DBG("Other OTP Characteristic handle [%s]", characteristic->handle);
- BT_DBG("UUID [%s]", characteristic->uuid);
-
- return BLUETOOTH_ERROR_NONE;
-}
-
-static int __bt_update_otp_server_data(bluetooth_device_address_t *address, bt_otp_client_s *otp_client_s)
-{
- int ret = BLUETOOTH_ERROR_INTERNAL;
- bt_gatt_service_property_t service;
- int count;
-
- ret = bluetooth_gatt_get_service_from_uuid(address, BT_OTP_SERVICE_UUID, &service);
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Failed to find OTP service on the remote device [%s]", address->addr);
- return ret;
- }
-
- /* Discover all charc & desc of OTP service */
- for (count = 0; count < service.char_handle.count; count++) {
- bt_gatt_char_property_t characteristic;
- memset(&characteristic, 0x00, sizeof(characteristic));
-
- BT_DBG("Get properties for Char [%s]", service.char_handle.handle[count]);
-
- ret = bluetooth_gatt_get_characteristics_property(service.char_handle.handle[count],
- &characteristic);
-
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Get characteristic property failed(0x%08x)", ret);
- bluetooth_gatt_free_service_property(&service);
- bluetooth_gatt_free_char_property(&characteristic);
- goto fail;
- }
-
- ret = __bt_otp_update_data(otp_client_s, &characteristic);
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Update data failed(0x%08x)", ret);
- bluetooth_gatt_free_service_property(&service);
- bluetooth_gatt_free_char_property(&characteristic);
- goto fail;
- }
-
- bluetooth_gatt_free_char_property(&characteristic);
- } /* Next Charatceristic */
-
- if (otp_client_s->otp_service_handle)
- g_free(otp_client_s->otp_service_handle);
-
- otp_client_s->otp_service_handle = g_strdup(service.handle);
- bluetooth_gatt_free_service_property(&service);
- return ret;
-fail:
- __bt_otp_client_reset_server_data(otp_client_s);
- return ret;
-}
-
-void _bt_otp_check_service_changed(char *address, bt_gatt_service_change_t *service_change)
-{
- bt_otp_client_s *otp_client_s = NULL;
- int error_code = BLUETOOTH_ERROR_NONE;
- bluetooth_device_address_t addr_hex = { {0,} };
- if (!address) {
- BT_ERR("Abnormal Result!!");
- return;
- }
- otp_client_s = _bt_otp_client_find(address);
- BT_DBG("GATT Service state changed [%d]", service_change->change_type);
- BT_DBG("GATT Service [%s]", service_change->svc_path);
- if (otp_client_s) {
- if (service_change->change_type == BLUETOOTH_GATT_SERVICE_CHANGE_TYPE_REMOVE) {
- if (otp_client_s->otp_service_handle &&
- g_strcmp0(otp_client_s->otp_service_handle, service_change->svc_path) == 0) {
- BT_ERR("OTS Primary Service removed abnormally from Remote Server [%s]", address);
- __bt_otp_client_reset_server_data(otp_client_s);
- }
- } else {
- _bt_convert_address_to_hex(&addr_hex, address);
-
- /* Attempt to update OTS Service data if service added is OTS service */
- if (__bt_update_otp_server_data(&addr_hex, otp_client_s) == BLUETOOTH_ERROR_NONE) {
- BT_INFO("OTS Primary Service added in Remote Server [%s]", address);
- /* Set Service changed Watcher */
- error_code = bluetooth_gatt_set_service_change_watcher(&addr_hex, true);
- if (error_code != BLUETOOTH_ERROR_NONE)
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- }
- }
- }
- BT_DBG("-");
-}
-
-void _bt_otp_client_connection_state_changed(int result,
- const char *remote_address,
- bool connected)
-{
- bt_otp_client_s *otp_client_s = NULL;
- BT_DBG("OTP Client Connection state changed result [%d] connected [%d]", result, connected ? TRUE : FALSE);
-
- otp_client_s = _bt_otp_client_find(remote_address);
- if (otp_client_s) {
- BT_DBG("OTP Client found against address [%s]", remote_address);
-
- bluetooth_device_address_t addr_hex = { {0,} };
- _bt_convert_address_to_hex(&addr_hex, remote_address);
-
- if (result != BT_ERROR_NONE) {
- BT_ERR("GATT Connect Request failed Address [%s]", remote_address);
- __bt_otp_client_reset_server_data(otp_client_s);
- bluetooth_gatt_set_service_change_watcher(&addr_hex, false);
-
- if (otp_client_s->connection_callback)
- ((bt_otp_client_state_changed_cb)otp_client_s->connection_callback)
- (result, remote_address, otp_client_s, connected, otp_client_s->conn_cb_user_data);
- return;
- }
- /* Update OTP Service values */
- if (connected) {
- int error_code = BLUETOOTH_ERROR_NONE;
- BT_DBG("Remote device connected successfully");
- /* Attempt to update OTP Service data */
- error_code = __bt_update_otp_server_data(&addr_hex, otp_client_s);
- if (error_code != BLUETOOTH_ERROR_NONE)
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
-
- /* Set Service changed Watcher */
- error_code = bluetooth_gatt_set_service_change_watcher(&addr_hex, true);
- if (error_code != BLUETOOTH_ERROR_NONE)
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- } else {
- BT_DBG("Remote device disconnected successfully");
- /* Disconnected */
- __bt_otp_client_reset_server_data(otp_client_s);
- bluetooth_gatt_set_service_change_watcher(&addr_hex, false);
- }
- otp_client_s->connected = connected;
-
- if (otp_client_s->connection_callback)
- ((bt_otp_client_state_changed_cb)otp_client_s->connection_callback)
- (result, remote_address, otp_client_s, connected, otp_client_s->conn_cb_user_data);
- } else {
- BT_DBG("OTP client not found!");
- }
-}
-
-int bt_otp_client_create(const char *remote_address, bt_otp_client_h *otp_client)
-{
- int error_code = BT_ERROR_NONE;
- bt_otp_client_s *otp_client_s = NULL;
- bool connected = false;
- bluetooth_device_address_t addr_hex = { {0,} };
- bt_otp_client_s *info;
- GSList *l;
- BT_INFO("+");
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(remote_address);
- BT_CHECK_INPUT_PARAMETER(otp_client);
-
- for (l = otp_client_list; l; l = g_slist_next(l)) {
- info = l->data;
-
- if ((info == NULL) || (info->remote_address == NULL)) {
- BT_ERR("bt_otp_client_create Error Parameter are NULL..\n");
- continue;
- } else if (info && !g_ascii_strcasecmp(info->remote_address, remote_address)) {
- BT_ERR("OTP Client for Remote device [%s] is already created",
- remote_address);
- *otp_client = (bt_otp_client_h)info;
- return BT_ERROR_ALREADY_DONE;
- }
- }
-
- otp_client_s = g_malloc0(sizeof(*otp_client_s));
- if (otp_client_s == NULL) {
- error_code = BT_ERROR_OUT_OF_MEMORY;
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- return error_code;
- }
-
- if (bt_device_is_profile_connected(remote_address, BT_PROFILE_GATT,
- &connected) != BT_ERROR_NONE)
- BT_ERR("bt_device_is_profile_connected is failed");
- otp_client_s->connected = connected;
-
- _bt_convert_address_to_hex(&addr_hex, remote_address);
-
- if (otp_client_s->connected == true) {
- /* Update all serv & charc */
- error_code = __bt_update_otp_server_data(&addr_hex, otp_client_s);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- __bt_otp_client_reset_server_data(otp_client_s);
- g_free(otp_client_s);
- return BT_ERROR_OPERATION_FAILED;
- }
- error_code = bluetooth_gatt_set_service_change_watcher(&addr_hex, true);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- __bt_otp_client_reset_server_data(otp_client_s);
- g_free(otp_client_s);
- return BT_ERROR_OPERATION_FAILED;
- }
- }
-
- otp_client_s->remote_address = g_strdup(remote_address);
- if (otp_client_s->remote_address == NULL) {
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code),
- error_code);
- __bt_otp_client_reset_server_data(otp_client_s);
- g_free(otp_client_s);
- return BT_ERROR_OUT_OF_MEMORY;
- }
-
- _bt_otp_client_init(otp_client_s);
-
- otp_client_list = g_slist_append(otp_client_list, otp_client_s);
- *otp_client = (bt_otp_client_h)otp_client_s;
-
- BT_DBG("OTP Client Created");
- return BT_ERROR_NONE;
-}
-
-int bt_otp_client_destroy(bt_otp_client_h otp_client)
-{
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- BT_DBG("OTP client Remote device [%s]", otp_client_s->remote_address);
- __bt_otp_client_reset_server_data(otp_client_s);
-
- otp_client_list = g_slist_remove(otp_client_list, otp_client_s);
- g_free(otp_client_s);
- otp_client_s = NULL;
-
- return BT_ERROR_NONE;
-}
-
-int bt_otp_client_connect(bt_otp_client_h otp_client)
-{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected)
- return BT_ERROR_NONE;
-
- BT_DBG("OTP client connect Remote device [%s]", otp_client_s->remote_address);
- error_code = bt_gatt_connect(otp_client_s->remote_address, FALSE);
-
- if (error_code != BT_ERROR_NONE)
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
-
- return error_code;
-}
-
-int bt_otp_client_disconnect(bt_otp_client_h otp_client)
-{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client Disconnect Remote device [%s]", otp_client_s->remote_address);
- error_code = bt_gatt_disconnect(otp_client_s->remote_address);
-
- if (error_code != BT_ERROR_NONE)
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
-
- return error_code;
-}
-
-void _bt_otp_get_remote_address(char *handle, char *remote_address)
-{
- char *dev_path;
- dev_path = strstr(handle, "dev_");
- dev_path += 4;
- /* 18 -> Length of BT ADDR in path */
- g_strlcpy(remote_address, dev_path, BT_ADDR_LENGTH);
- g_strdelimit(remote_address, "_", ':');
- BT_INFO("[%s] --> [%s]", handle, remote_address);
-}
-
-void _bt_otp_send_discovery_callback(int result, bt_otp_client_s *otp_client_s)
-{
- object_metadata *metadata;
- GSList *l;
- int k;
- if (result != BLUETOOTH_ERROR_NONE) {
- ((bt_otp_client_object_discovery_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address, NULL, otp_client_s->user_data);
- return;
- }
-
- BT_INFO("All Object/Objects Discovered");
- if (obj_list) {
- for (k = 0; k < obj_list->num_objects; k++) {
- otp_object_metadata_s *data = obj_list->data[k];
- g_free(data->name);
- g_free(data);
- }
- g_free(obj_list);
- obj_list = NULL;
- }
- obj_list = g_malloc0(sizeof(bt_otp_object_list_s));
- obj_list->num_objects = g_slist_length(otp_client_s->object_list);
- obj_list->data = (otp_object_metadata_s **)g_malloc0(sizeof(otp_object_metadata_s *)*obj_list->num_objects);
- k = 0;
- for (l = otp_client_s->object_list; l; l = g_slist_next(l)) {
- metadata = l->data;
- if (metadata == NULL)
- continue;
- otp_object_metadata_s *m_data = g_malloc0(sizeof(otp_object_metadata_s));
- m_data->id = metadata->id;
- m_data->name = g_strdup(metadata->name);
- obj_list->data[k] = (otp_object_metadata_s *)g_malloc0(sizeof(otp_object_metadata_s));
- obj_list->data[k] = m_data;
- k++;
- }
- ((bt_otp_client_object_discovery_cb)otp_client_s->callback)(
- BLUETOOTH_ERROR_NONE, otp_client_s->remote_address, obj_list, otp_client_s->user_data);
-}
-
-static void __bt_otp_client_feature_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
-
- uint64_t feature = (uint64_t)(value[0] & 0xFF) << 56 |
- (uint64_t)(value[1] & 0xFF) << 48 |
- (uint64_t)(value[2] & 0xFF) << 40 |
- (uint64_t)(value[3] & 0xFF) << 32 |
- (uint64_t)(value[4] & 0xFF) << 24 |
- (uint64_t)(value[5] & 0xFF) << 16 |
- (uint64_t)(value[6] & 0xFF) << 8 |
- (uint64_t)(value[7] & 0xFF);
- otp_client_s->otp_feature = feature;
- BT_INFO("OTP Feature [%llu]", (long long unsigned int)feature);
-
- if (BT_OTP_IS_OACP_SUPPORTED(otp_client_s->otp_feature)
- && !otp_client_s->oacp_cccd_enabled
- && otp_client_s->otp_oacp_control_point) {
-
- error_code = bluetooth_otp_enable_notification(otp_client_s->otp_oacp_control_point);
- if (error_code != BT_ERROR_NONE)
- BT_ERR("OACP Notification enable failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- }
-
- if (BT_OTP_IS_OLCP_SUPPORTED(otp_client_s->otp_feature)
- && !otp_client_s->olcp_cccd_enabled
- && otp_client_s->otp_olcp_control_point) {
- error_code = bluetooth_otp_enable_notification(otp_client_s->otp_olcp_control_point);
- if (error_code != BT_ERROR_NONE)
- BT_ERR("OLCP Notification enable failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- }
-
- if (!otp_client_s->obj_changed_cccd_enabed
- && otp_client_s->otp_obj_changed_obj_path) {
- error_code = bluetooth_otp_enable_notification(otp_client_s->otp_obj_changed_obj_path);
- if (error_code != BT_ERROR_NONE)
- BT_ERR("Object Changed Notification enable failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- }
-}
-
-static void __bt_otp_client_name_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- char *name = NULL;
- name = g_strndup(value, len);
- BT_INFO("Object Name [%s]", name);
-
- if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY) {
- metadata->name = g_strdup(name);
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_type_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- g_free(name);
- return;
- }
- }
- g_free(name);
-}
-
-static void __bt_otp_client_type_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- char *type = NULL;
- type = g_strndup(value, len);
- BT_INFO("Object Type [%s]", type);
-
- if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY) {
- metadata->type = g_strdup(type);
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_size_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- g_free(type);
- return;
- }
- }
- g_free(type);
-}
-
-static void __bt_otp_client_size_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- uint32_t csize, asize;
- csize = (uint32_t)(value[3] & 0xFF) << 24 |
- (uint32_t)(value[2] & 0xFF) << 16 |
- (uint32_t)(value[1] & 0xFF) << 8 |
- (uint32_t)(value[0] & 0xFF);
-
- asize = (uint32_t)(value[7] & 0xFF) << 24 |
- (uint32_t)(value[6] & 0xFF) << 16 |
- (uint32_t)(value[5] & 0xFF) << 8 |
- (uint32_t)(value[4] & 0xFF);
-
- BT_INFO("Object Size curr[%u] alloc[%u]", csize, asize);
-
- if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY) {
- metadata->curr_size = csize;
- metadata->alloc_size = asize;
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_props_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- }
- }
-}
-
-static void __bt_otp_client_props_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- uint32_t props;
- props = (uint32_t)(value[3] & 0xFF) << 24 |
- (uint32_t)(value[2] & 0xFF) << 16 |
- (uint32_t)(value[1] & 0xFF) << 8 |
- (uint32_t)(value[0] & 0xFF);
- BT_INFO("Object Properties [%u]", props);
-
- /* First-created & Last-modified are optional charcacteristics */
- if (otp_client_s->curr_op != BT_OTP_OBJECT_DISCOVERY)
- return;
-
- metadata->props = props;
- if (otp_client_s->otp_first_created_obj_path) {
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_first_created_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto done;
- }
- return;
- }
-
- if (otp_client_s->otp_last_modified_obj_path) {
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_last_modified_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto done;
- }
- return;
- }
-
- /* Reading Object ID characteristics makes sense if server
- * supports multiple objects.
- */
- if (otp_client_s->multiple_obj_supp) {
- metadata->id = 0x256;
- otp_client_s->object_id = metadata->id;
- otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
- goto done;
- }
-
- if (otp_client_s->otp_id_obj_path) {
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto done;
- }
- }
- return;
-done:
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
-}
-
-static void __bt_otp_client_first_created_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- struct tm tm = {0};
- uint16_t year = (uint16_t)(value[1] & 0xFF) << 8 |
- (uint16_t)(value[0] & 0xFF);
- tm.tm_year = year-1900;
- tm.tm_mon = value[2] & 0xFF;
- tm.tm_mon = tm.tm_mon-1;
- tm.tm_mday = value[3] & 0xFF;
- tm.tm_hour = value[4] & 0xFF;
- tm.tm_min = value[5] & 0xFF;
- tm.tm_sec = value[6] & 0xFF;
- BT_INFO("Object First Created [%d]-[%d]-[%d]\t[%d][%d][%d]", tm.tm_mday,
- tm.tm_mon, tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec);
-
- if (otp_client_s->curr_op != BT_OTP_OBJECT_DISCOVERY)
- return;
-
- metadata->first_created = mktime(&tm);
- if (otp_client_s->otp_last_modified_obj_path) {
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_last_modified_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto done;
- }
- return;
- }
-
- if (otp_client_s->multiple_obj_supp) {
- metadata->id = 0x256;
- otp_client_s->object_id = metadata->id;
- otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
- goto done;
- }
-
- if (otp_client_s->otp_id_obj_path) {
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto done;
- }
- }
- return;
-done:
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
-}
-
-static void __bt_otp_client_last_modified_response(bt_otp_client_s *otp_client_s, char *value, int len)
-{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- struct tm tm = {0};
- uint16_t year = (uint16_t)(value[1] & 0xFF) << 8 |
- (uint16_t)(value[0] & 0xFF);
- tm.tm_year = year-1900;
- tm.tm_mon = value[2] & 0xFF;
- tm.tm_mon = tm.tm_mon-1;
- tm.tm_mday = value[3] & 0xFF;
- tm.tm_hour = value[4] & 0xFF;
- tm.tm_min = value[5] & 0xFF;
- tm.tm_sec = value[6] & 0xFF;
- BT_INFO("Object Last Modified [%d]-[%d]-[%d]\t[%d][%d][%d]", tm.tm_mday,
- tm.tm_mon, tm.tm_year, tm.tm_hour, tm.tm_min, tm.tm_sec);
-
- if (otp_client_s->curr_op != BT_OTP_OBJECT_DISCOVERY)
- return;
-
- metadata->last_modified = mktime(&tm);
- if (otp_client_s->multiple_obj_supp) {
- /* None of the optional characteristics supported, so finish object discovery */
- metadata->id = 0x256;
- otp_client_s->object_id = metadata->id;
- otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- return;
- }
-
- if (otp_client_s->otp_id_obj_path) {
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- }
- }
-}
+#include "bluetooth.h"
+#include "bluetooth_internal.h"
+#include "bluetooth_private.h"
-static void __bt_otp_client_id_response(bt_otp_client_s *otp_client_s, char *value, int len)
+int bt_otp_server_initialize(const char *directory)
{
- int error_code = BLUETOOTH_ERROR_NONE;
- int result = BLUETOOTH_ERROR_NONE;
- uint64_t id;
- id = (uint64_t)(value[5] & 0xFF) << 48 |
- (uint64_t)(value[4] & 0xFF) << 32 |
- (uint64_t)(value[3] & 0xFF) << 24 |
- (uint64_t)(value[2] & 0xFF) << 16 |
- (uint64_t)(value[1] & 0xFF) << 8 |
- (uint64_t)(value[0] & 0xFF);
- BT_INFO("Object ID [%llu]", (long long unsigned int)id);
-
- /* TODO: Remove the previous stored object list */
- if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY) {
- uint8_t write_value[7] = {0x00};
-
- metadata->id = id;
-
- otp_client_s->object_id = metadata->id;
- otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
- write_value[0] = OLCP_NEXT;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_olcp_control_point, write_value, 1);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- }
- return;
- }
-
- if (otp_client_s->curr_op == BT_OTP_OBJECT_CREATE) {
- metadata = g_malloc0(sizeof(object_metadata));
- metadata->name = g_strdup(oacp_create_op->filename);
- metadata->type = g_strdup(oacp_create_op->type_uuid);
- metadata->curr_size = oacp_create_op->size;
- metadata->alloc_size = oacp_create_op->size;
- /* Dont hard code */
- metadata->props = OBJECT_READ | OBJECT_WRITE;
- metadata->first_created = oacp_create_op->first_created;
- metadata->last_modified = oacp_create_op->first_created;
- metadata->id = id;
- otp_client_s->object_id = metadata->id;
- otp_client_s->object_list = g_slist_append(otp_client_s->object_list, metadata);
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
-void _bt_otp_client_read_value_response(int result, char *char_path,
- char *value, int len)
+int bt_otp_server_deinitialize()
{
- bt_otp_client_s *otp_client_s = NULL;
- char remote_address[BT_ADDR_LENGTH];
-
- _bt_otp_get_remote_address(char_path, remote_address);
-
- BT_DBG("OTP client Read Value Response [%d] [%s] [%s] [%d]", result,
- char_path, value, len);
-
- otp_client_s = _bt_otp_client_find(remote_address);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- return;
- }
-
- if (result != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read failed for [%s]", char_path);
- if (otp_client_s->curr_op == BT_OTP_OBJECT_DISCOVERY ||
- otp_client_s->curr_op == BT_OTP_OBJECT_CREATE)
- _bt_otp_send_callback(result, NULL, otp_client_s->object_id, 0, otp_client_s);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_feature_obj_path, char_path)) {
- __bt_otp_client_feature_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_name_obj_path, char_path)) {
- __bt_otp_client_name_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_type_obj_path, char_path)) {
- __bt_otp_client_type_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_size_obj_path, char_path)) {
- __bt_otp_client_size_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_props_obj_path, char_path)) {
- __bt_otp_client_props_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_first_created_obj_path, char_path)) {
- __bt_otp_client_first_created_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_last_modified_obj_path, char_path)) {
- __bt_otp_client_last_modified_response(otp_client_s, value, len);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_id_obj_path, char_path)) {
- __bt_otp_client_id_response(otp_client_s, value, len);
- return;
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
-static void _bt_otp_send_callback(int result, char *file_path, uint64_t id,
- unsigned int length, bt_otp_client_s *otp_client_s)
+int bt_otp_set_server_state_changed_cb(bt_otp_server_state_changed_cb callback, void *user_data)
{
- switch (otp_client_s->curr_op) {
- case BT_OTP_OBJECT_DISCOVERY:
- _bt_otp_send_discovery_callback(result, otp_client_s);
- break;
- case BT_OTP_OBJECT_READ:
- _bt_otp_client_notify_read_object_status(result,
- file_path, otp_client_s);
- break;
- case BT_OTP_OBJECT_SELECT:
- _bt_otp_client_send_select_object_callback(result, otp_client_s);
- break;
- case BT_OTP_OBJECT_CREATE:
- _bt_otp_client_send_create_object_callback(result, id, otp_client_s);
- break;
- case BT_OTP_OBJECT_WRITE:
- _bt_otp_client_send_write_object_callback(result, length, otp_client_s);
- break;
- case BT_OTP_OBJECT_EXECUTE:
- _bt_otp_client_send_execute_object_callback(result, otp_client_s);
- break;
- case BT_OTP_OBJECT_DELETE:
- _bt_otp_client_send_delete_object_callback(result, otp_client_s);
- break;
- case BT_OTP_NO_OPERATION:
- break;
- default:
- break;
- }
+ return BT_ERROR_NOT_SUPPORTED;
- __bt_otp_reset_api_info(otp_client_s);
}
-
-void _bt_otp_client_write_value_response(int result, char *handle)
+int bt_otp_unset_server_state_changed_cb(void)
{
- bt_otp_client_s *otp_client_s = NULL;
- char remote_address[BT_ADDR_LENGTH];
- BT_DBG("OTP client Write Value Response [%d] [%s]", result, handle);
-
- _bt_otp_get_remote_address(handle, remote_address);
- otp_client_s = _bt_otp_client_find(remote_address);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- return;
- }
-
- if (result != BLUETOOTH_ERROR_NONE) {
- BT_DBG("OTP Write Failed");
- goto fail;
- }
-
- if (otp_client_s->curr_op == BT_OTP_OBJECT_CREATE) {
- if ((!g_strcmp0(otp_client_s->otp_name_obj_path, handle) ||
- !g_strcmp0(otp_client_s->otp_first_created_obj_path, handle)) &&
- oacp_create_op) {
- struct tm fc_tm;
- uint8_t value[8];
- int error_code;
- memset(value, 0, 8);
- localtime_r(&(oacp_create_op->first_created), &fc_tm);
-
- value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF;
- value[0] = (fc_tm.tm_year+1900) & 0xFF;
- value[2] = (fc_tm.tm_mon+1) & 0xFF;
- value[3] = fc_tm.tm_mday & 0xFF;
- value[4] = fc_tm.tm_hour & 0xFF;
- value[5] = fc_tm.tm_min & 0xFF;
- value[6] = fc_tm.tm_sec & 0xFF;
-
- if (!g_strcmp0(otp_client_s->otp_name_obj_path, handle)) {
- /* Write First-Created */
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_first_created_obj_path,
- value, sizeof(value));
- } else {
- /* Write Last-Modified */
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_last_modified_obj_path,
- value, sizeof(value));
- }
-
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write first_created / last_modified : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto fail;
- }
- } else if (!g_strcmp0(otp_client_s->otp_last_modified_obj_path, handle)) {
- /* Read Object ID */
- int error_code;
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_id_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read object ID Failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto fail;
- }
- }
- }
- return;
-fail:
- _bt_otp_send_callback(result, NULL, 0, 0, otp_client_s);
+ return BT_ERROR_NOT_SUPPORTED;
}
-void _bt_otp_client_notification_enabled(int result, char *handle)
+int bt_otp_client_set_connection_state_changed_cb(bt_otp_client_h otp_client,
+ bt_otp_client_state_changed_cb callback, void *user_data)
{
- bt_otp_client_s *otp_client_s = NULL;
- char remote_address[BT_ADDR_LENGTH];
- BT_DBG("OTP notificaton [%d] [%s]", result, handle);
- _bt_otp_get_remote_address(handle, remote_address);
-
- otp_client_s = _bt_otp_client_find(remote_address);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_oacp_control_point, handle)) {
- if (result != BLUETOOTH_ERROR_NONE) {
- otp_client_s->oacp_cccd_enabled = FALSE;
- BT_ERR("Failed to enable OACP notification : %s(0x%08x)",
- _bt_convert_error_to_string(result), result);
- } else {
- otp_client_s->oacp_cccd_enabled = TRUE;
- }
- } else if (!g_strcmp0(otp_client_s->otp_olcp_control_point, handle)) {
- if (result != BLUETOOTH_ERROR_NONE) {
- otp_client_s->olcp_cccd_enabled = FALSE;
- BT_ERR("Failed to enable OLCP notification : %s(0x%08x)",
- _bt_convert_error_to_string(result), result);
- } else {
- otp_client_s->olcp_cccd_enabled = TRUE;
- }
- } else if (!g_strcmp0(otp_client_s->otp_obj_changed_obj_path, handle)) {
- if (result != BLUETOOTH_ERROR_NONE) {
- otp_client_s->obj_changed_cccd_enabed = FALSE;
- BT_ERR("Failed to enable Object changed notification : %s(0x%08x)",
- _bt_convert_error_to_string(result), result);
- } else {
- otp_client_s->obj_changed_cccd_enabed = TRUE;
- }
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
-static void __bt_otp_oacp_control_indication(int result, bt_otp_client_s *otp_client_s, bluetooth_otp_resp_info_t *info)
+int bt_otp_client_unset_connection_state_changed_cb(bt_otp_client_h otp_client)
{
- uint8_t resp_code = info->data[0];
- uint8_t req_opcode = info->data[1];
- uint8_t result_code = info->data[2];
- int error_code;
-
- /* Indication failed/timeout occured */
- if (result != BLUETOOTH_ERROR_NONE)
- goto oacp_done;
-
- BT_INFO("Resp_code [0x%x], Req_opcode [0x%x], result_code [0x%x]",
- resp_code, req_opcode, result_code);
-
- if (resp_code != OACP_RESPONSE) {
- BT_INFO("Indication Response Failed : Wrong Response Code");
- result = BLUETOOTH_ERROR_INTERNAL;
- goto oacp_done;
- }
-
- if (result_code != OACP_SUCCESS) {
- BT_INFO("Indication Response Fail [0x%x]", result_code);
- result = BLUETOOTH_ERROR_INTERNAL;
- goto oacp_done;
- }
-
- switch (req_opcode) {
- case OACP_CREATE:
- BT_INFO("OACP_CREATE Indication received");
- if ((otp_client_s->curr_op == BT_OTP_OBJECT_CREATE) && oacp_create_op) {
- int len;
- uint8_t value[BT_FILE_PATH_MAX_LEN];
-
- len = strlen(oacp_create_op->filename) + 1;
- memcpy(value, oacp_create_op->filename, len);
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_name_obj_path,
- value, len);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write object name : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto oacp_done;
- }
- }
- break;
- case OACP_DELETE:
- BT_INFO("OACP_DELETE Indication received");
- goto oacp_done;
- break;
- case OACP_CALC_CHECKSUM:
- break;
- case OACP_EXECUTE:
- BT_INFO("OACP_EXECUTE Indication received");
- goto oacp_done;
- break;
- case OACP_READ:
- case OACP_WRITE:
- {
- BT_INFO("OACP Read/Write Indication received");
- bluetooth_device_address_t addr_hex = { {0,} };
- _bt_convert_address_to_hex(&addr_hex, otp_client_s->remote_address);
-
- if (otc_connection_status) {
- BT_INFO("OTC Connected already");
- break;
- }
-
- error_code = bluetooth_otp_connect_otc(&addr_hex);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("OTC Connection Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto oacp_done;
- }
- break;
- }
- case OACP_ABORT:
- break;
- default:
- BT_INFO("Indication Failed : Wrong Req Opcode [0x%x], Reason [0x%x]",
- req_opcode, result_code);
- result = BLUETOOTH_ERROR_INTERNAL;
- goto oacp_done;
- break;
- }
- return;
-
-oacp_done:
- switch (otp_client_s->curr_op) {
- case BT_OTP_OBJECT_READ:
- case BT_OTP_OBJECT_CREATE:
- case BT_OTP_OBJECT_WRITE:
- case BT_OTP_OBJECT_EXECUTE:
- case BT_OTP_OBJECT_DELETE:
- _bt_otp_send_callback(result, NULL, 0, 0, otp_client_s);
- break;
- default:
- break;
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
-static void __bt_otp_olcp_control_indication(int result, bt_otp_client_s *otp_client_s, bluetooth_otp_resp_info_t *info)
+int bt_otp_client_create(const char *remote_address, bt_otp_client_h *otp_client)
{
- uint8_t resp_code = info->data[0];
- uint8_t req_opcode = info->data[1];
- uint8_t result_code = info->data[2];
- int error_code;
-
- /* Indication failed/timeout occured */
- if (result != BLUETOOTH_ERROR_NONE)
- goto olcp_done;
-
- BT_INFO("Resp_code [0x%x], Req_opcode [0x%x], result_code [0x%x]",
- resp_code, req_opcode, result_code);
-
- if (resp_code != OLCP_RESPONSE) {
- BT_INFO("Indication Response Failed : Wrong Response Code");
- result = BLUETOOTH_ERROR_INTERNAL;
- goto olcp_done;
- }
-
- if (result_code != OLCP_SUCCESS) {
- switch (result_code) {
- case OLCP_NO_OBJ:
- BT_INFO("No Object Found on server");
- result = BLUETOOTH_ERROR_INTERNAL;
- break;
- case OLCP_OUT_OF_BOUNDS:
- /* All object discovered succesfully, notify application via callback */
- result = BLUETOOTH_ERROR_NONE;
- break;
- case OLCP_OJECT_ID_NOT_FOUND:
- BT_INFO("Object ID not found");
- result = BLUETOOTH_ERROR_INTERNAL;
- break;
- default:
- BT_INFO("Indication Response Fail [0x%x]", result_code);
- result = BLUETOOTH_ERROR_INTERNAL;
- break;
- }
- goto olcp_done;
- }
-
- switch (req_opcode) {
- case OLCP_ORDER:
- case OLCP_REQ_NO_OBJ:
- case OLCP_CLEAR_MARKING:
- break;
- case OLCP_FIRST:
- case OLCP_LAST:
- case OLCP_NEXT:
- case OLCP_PREVIOUS: {
- /* Once we get success indication response for OLCP,
- * attempt to read object metadata */
- metadata = g_malloc0(sizeof(object_metadata));
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_name_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- result = error_code;
- goto olcp_done;
- }
- } break;
- case OLCP_GOTO:
- /* Update the object id & notify client app*/
- otp_client_s->object_id = select_obj_id;
- select_obj_id = 0;
- goto olcp_done;
- break;
- default:
- BT_INFO("Indication Response Failed : Wrong Req Opcode [0x%x], Reason [0x%x]",
- req_opcode, result_code);
- result = BLUETOOTH_ERROR_INTERNAL;
- goto olcp_done;
- break;
- }
- return;
-
-olcp_done:
- switch (otp_client_s->curr_op) {
- case BT_OTP_OBJECT_DISCOVERY:
- case BT_OTP_OBJECT_SELECT:
- _bt_otp_send_callback(result, NULL, 0, 0, otp_client_s);
- break;
- default:
- break;
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
-void _bt_otp_client_indication(int result, bluetooth_otp_resp_info_t *info)
+int bt_otp_client_destroy(bt_otp_client_h otp_client)
{
- bt_otp_client_s *otp_client_s = NULL;
- char remote_address[BT_ADDR_LENGTH];
-
- BT_DBG("OTP indication response [%s]", info->handle);
- _bt_otp_get_remote_address(info->handle, remote_address);
-
- otp_client_s = _bt_otp_client_find(remote_address);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_oacp_control_point, info->handle)) {
- __bt_otp_oacp_control_indication(result, otp_client_s, info);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_olcp_control_point, info->handle)) {
- __bt_otp_olcp_control_indication(result, otp_client_s, info);
- return;
- }
-
- if (!g_strcmp0(otp_client_s->otp_obj_changed_obj_path, info->handle)) {
- BT_INFO("Indication Received for Object Changed Characteristic");
- uint8_t flag = info->data[0];
- uint64_t id = 0;
- BT_INFO("Source of change : %s", BT_OTP_OBJ_CHANGED_SRC(flag) ? "Client" : "Server");
- BT_INFO("Change occurred to obj contents : %s", BT_OTP_OBJ_CHANGED_CONTENT(flag) ? "True" : "False");
- BT_INFO("Change occurred to obj metadata : %s", BT_OTP_OBJ_CHANGED_META(flag) ? "True" : "False");
- BT_INFO("Object creation : %s", BT_OTP_OBJ_CHANGED_CREATE(flag) ? "True" : "False");
- BT_INFO("Object Deletion : %s", BT_OTP_OBJ_CHANGED_DELETE(flag) ? "True" : "False");
-
- id = (uint64_t)(info->data[6] & 0xFF) << 40 |
- (uint64_t)(info->data[5] & 0xFF) << 32 |
- (uint64_t)(info->data[4] & 0xFF) << 24 |
- (uint64_t)(info->data[3] & 0xFF) << 16 |
- (uint64_t)(info->data[2] & 0xFF) << 8 |
- (uint64_t)(info->data[1] & 0xFF);
- BT_INFO("Changed occurred to object id %llu", (long long unsigned int)id);
- return;
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
-void __bt_otp_reset_api_info(bt_otp_client_s *otp_client_s)
+int bt_otp_client_discover_all_objects(bt_otp_client_h otp_client,
+ bt_otp_client_object_discovery_cb callback,
+ void *user_data)
{
- otp_client_s->curr_op = BT_OTP_NO_OPERATION;
- otp_client_s->callback = NULL;
- otp_client_s->user_data = NULL;
+ return BT_ERROR_NOT_SUPPORTED;
}
-int bt_otp_client_discover_all_objects(bt_otp_client_h otp_client,
- bt_otp_client_object_discovery_cb callback,
- void *user_data)
+int bt_otp_client_connect(bt_otp_client_h otp_client)
{
- int error_code = BLUETOOTH_ERROR_NONE;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client Discover objects from Remote device [%s]", otp_client_s->remote_address);
- otp_client_s->curr_op = BT_OTP_OBJECT_DISCOVERY;
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
-
- _bt_otp_client_free_object_list(otp_client_s);
-
- if (!otp_client_s->otp_olcp_control_point) {
- /* Remote server supports only single object */
- otp_client_s->multiple_obj_supp = TRUE;
- metadata = g_malloc0(sizeof(object_metadata));
- error_code = bluetooth_otp_read_characteristic_value(otp_client_s->otp_name_obj_path);
- if (error_code != BLUETOOTH_ERROR_NONE) {
- BT_INFO("Read Charc Value Failed %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- error_code = BT_ERROR_OPERATION_FAILED;
- __bt_otp_reset_api_info(otp_client_s);
- }
- } else {
- /* Remote server supports multiple objects.
- * Perform OLCP to discover all objects.
- */
- uint8_t value[7] = {0x00};
- value[0] = OLCP_FIRST;
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_olcp_control_point, value, 1);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)", _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
- }
-
- return error_code;
+ return BT_ERROR_NOT_SUPPORTED;
}
-static void _bt_otp_client_send_select_object_callback(int result,
- bt_otp_client_s *otp_client_s)
+int bt_otp_client_disconnect(bt_otp_client_h otp_client)
{
- ((bt_otp_client_object_select_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address,
- otp_client_s->object_id, otp_client_s->user_data);
+ return BT_ERROR_NOT_SUPPORTED;
}
int bt_otp_client_select_object(bt_otp_client_h otp_client, unsigned long long id,
bt_otp_client_object_select_cb callback, void *user_data)
{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->object_id == id) {
- BT_INFO("Object already selected");
- _bt_otp_client_send_select_object_callback(BLUETOOTH_ERROR_NONE, otp_client_s);
- return BLUETOOTH_ERROR_NONE;
- }
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_OLCP_GOTO_SUPPORTED(otp_client_s->otp_feature)) {
- BT_INFO("OLCP GOTO not supported");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client select object [%llu] from Remote device [%s]", (long long unsigned int)id, otp_client_s->remote_address);
- otp_client_s->curr_op = BT_OTP_OBJECT_SELECT;
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
-
- select_obj_id = id;
-
- uint8_t value[7] = {0x00};
- value[0] = OLCP_GOTO;
- value[1] = select_obj_id & 0xFF;
- value[2] = (select_obj_id >> 8) & 0xFF;
- value[3] = (select_obj_id >> 16) & 0xFF;
- value[4] = (select_obj_id >> 24) & 0xFF;
- value[5] = (select_obj_id >> 32) & 0xFF;
- value[6] = (select_obj_id >> 40) & 0xFF;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_olcp_control_point,
- value, 7);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
-
- return error_code;
-}
-
-static bool __bt_otc_connection_timeout_cb(gpointer user_data)
-{
- bluetooth_otc_info_t *otc_info = (bluetooth_otc_info_t *)user_data;
- char *address = otc_info->address;
- bluetooth_device_address_t addr_hex = { {0,} };
-
- /* TODO: Write OACP Abort opcode, then disconnect */
-
- BT_DBG("OTC Connection timer Expired [%s]", address);
- _bt_convert_address_to_hex(&addr_hex, address);
- bluetooth_otp_disconnect_otc(&addr_hex);
-
- return TRUE;
-}
-
-static gboolean __client_data_received_cb(GIOChannel *chan, GIOCondition cond,
- gpointer data)
-{
- bluetooth_otc_info_t *otc_info = (bluetooth_otc_info_t *)data;
- char *remote_addr = otc_info->address;
- GIOStatus status = G_IO_STATUS_NORMAL;
- GError *err = NULL;
- char *buffer = NULL;
- gsize len = 0;
- int written;
- int fd;
-
- BT_DBG("");
-
- fd = g_io_channel_unix_get_fd(chan);
- if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
- otc_connection_status = FALSE;
- BT_ERR("OTC Client disconnected: %d", fd);
- close(fd);
- g_source_remove(id);
- return FALSE;
- }
-
- buffer = g_malloc0(BT_L2CAP_BUFFER_LEN + 1);
-
- status = g_io_channel_read_chars(chan, buffer,
- BT_L2CAP_BUFFER_LEN,
- &len, &err);
- if (status != G_IO_STATUS_NORMAL) {
- BT_ERR("IO Channel read is failed with %d", status);
-
- g_free(buffer);
- if (err) {
- otc_connection_status = FALSE;
- BT_ERR("IO Channel read error [%s]", err->message);
- if (status == G_IO_STATUS_ERROR) {
- BT_ERR("cond : %d", cond);
- g_error_free(err);
- close(fd);
- g_source_remove(id);
- return FALSE;
- }
- g_error_free(err);
- }
- return TRUE;
- }
-
- BT_DBG("Received data length %zd, remote_addr = %s", len, remote_addr);
-
- if (!oacp_read_op) {
- char file_path[BT_FILE_PATH_MAX_LEN] = {0, };
- bt_otp_client_s *otp_client_s = NULL;
- object_metadata *object_info = NULL;
- uint64_t obj_id;
- FILE *fp = NULL;
- char err_msg[256] = {0, };
-
- otp_client_s = _bt_otp_client_find(remote_addr);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- goto fail;
- }
-
- obj_id = otp_client_s->object_id;
-
- object_info = _bt_otp_client_find_object(otp_client_s->object_list, obj_id);
- if (!object_info) {
- BT_INFO("Object Not Found [%llu]", (long long unsigned int)obj_id);
- goto fail;
- }
-
- snprintf(file_path, sizeof(file_path), "%s%s",
- BT_OTP_CLIENT_BASE_DIR, object_info->name);
- BT_DBG("file_path = [%s]", file_path);
-
- fp = fopen(file_path, "w");
- if (!fp) {
- strerror_r(errno, err_msg, sizeof(err_msg));
- BT_ERR("fopen() failed : %s", err_msg);
- goto fail;
- }
-
- oacp_read_op = g_malloc0(sizeof(bt_otp_client_read_op));
- oacp_read_op->offset = 0;
- oacp_read_op->length = 0;
- oacp_read_op->fp = fp;
- oacp_read_op->size = object_info->curr_size;
- oacp_read_op->file_path = g_strdup(file_path);
- }
-
- if (oacp_read_op->length <= oacp_read_op->size) {
- written = fwrite(buffer, 1, len, oacp_read_op->fp);
- oacp_read_op->length += written;
- BT_DBG("written [%d], length_sofar [%u], received_buff_len [%zd], size [%u]",
- written, oacp_read_op->length, len, oacp_read_op->size);
- }
-
- if (timeout_id > 0) {
- g_source_remove(timeout_id);
- timeout_id = g_timeout_add(BT_OTC_CONNECTION_MAX_TIMEOUT,
- (GSourceFunc)__bt_otc_connection_timeout_cb, (gpointer)otc_info);
- }
-fail:
- g_free(buffer);
- return TRUE;
-}
-
-static void _bt_otp_client_notify_read_object_status(int result,
- char *file_path, bt_otp_client_s *otp_client_s)
-{
-
- ((bt_otp_client_read_object_complete_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address,
- file_path, otp_client_s->user_data);
-}
-
-static void _bt_otp_client_write_on_fd(bluetooth_otc_info_t *otc_info)
-{
- char buf[BT_L2CAP_BUFFER_LEN];
- int written, read, len;
- FILE *fp = NULL;
- int length;
- unsigned int byteswritten = 0;
- int fd = otc_info->fd;
- char *address = otc_info->address;
- int result = BLUETOOTH_ERROR_NONE;
- bt_otp_client_s *otp_client_s = NULL;
- bluetooth_device_address_t addr_hex = { {0,} };
- struct tm fc_tm;
- uint8_t value[7];
- char err_msg[256] = {0, };
-
- if (!oacp_write_op) {
- result = BLUETOOTH_ERROR_INTERNAL;
- goto fail;
- }
-
- BT_DBG("file_path = [%s]", oacp_write_op->file_path);
-
- fp = fopen(oacp_write_op->file_path, "r");
- if (!fp) {
- strerror_r(errno, err_msg, sizeof(err_msg));
- BT_ERR("fopen() failed : %s", err_msg);
- result = BLUETOOTH_ERROR_INTERNAL;
- goto fail;
- }
-
- if (oacp_write_op->offset > 0)
- fseek(fp, oacp_write_op->offset, SEEK_SET);
-
- BT_DBG("length [%d]", oacp_write_op->length);
- length = oacp_write_op->length;
-
- while (length > 0) {
- if (length < BT_L2CAP_BUFFER_LEN)
- len = length;
- else
- len = BT_L2CAP_BUFFER_LEN;
-
- read = fread(buf, 1, len, fp);
- written = write(fd, buf, len);
-
- if (written < 0) {
- result = BLUETOOTH_ERROR_INTERNAL;
- goto fail;
- }
-
- length -= written;
- byteswritten += written;
-
- BT_DBG("read [%d], written [%d], rem_len [%d]",
- read, written, length);
- }
-
-fail:
- if (fp)
- fclose(fp);
-
- /* Disconnect and notify application */
- _bt_convert_address_to_hex(&addr_hex, address);
- bluetooth_otp_disconnect_otc(&addr_hex);
-
- otp_client_s = _bt_otp_client_find(address);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- return;
- }
-
- if (result == BLUETOOTH_ERROR_NONE) {
- /* Write Last-modified */
- memset(value, 0, 7);
- localtime_r(&(oacp_write_op->last_modified), &fc_tm);
-
- value[1] = ((fc_tm.tm_year+1900) >> 8) & 0xFF;
- value[0] = (fc_tm.tm_year+1900) & 0xFF;
- value[2] = (fc_tm.tm_mon+1) & 0xFF;
- value[3] = fc_tm.tm_mday & 0xFF;
- value[4] = fc_tm.tm_hour & 0xFF;
- value[5] = fc_tm.tm_min & 0xFF;
- value[6] = fc_tm.tm_sec & 0xFF;
- result = bluetooth_otp_write_characteristics_value(otp_client_s->otp_last_modified_obj_path,
- value, 7);
- }
-
- _bt_otp_client_send_write_object_callback(result,
- byteswritten, otp_client_s);
- __bt_otp_reset_api_info(otp_client_s);
-}
-
-void _bt_otc_connection_state_changed(int result, bluetooth_otc_info_t *otc_info)
-{
- GIOChannel *data_io;
- char file_path[BT_FILE_PATH_MAX_LEN];
- bt_otp_client_s *otp_client_s = NULL;
-
- BT_DBG("OTC Channel status [%d], fd [%d]", otc_info->connected, otc_info->fd);
-
- otp_client_s = _bt_otp_client_find(otc_info->address);
- if (otp_client_s == NULL) {
- BT_INFO("Client Not Found");
- return;
- }
-
- if (oacp_read_op) {
- if (!otc_info->connected)
- memcpy(file_path, oacp_read_op->file_path,
- strlen(oacp_read_op->file_path) + 1);
- /*
- * Remove request in both connected/disconnected case.
- * So that new request can proceed.
- */
- fclose(oacp_read_op->fp);
- g_free(oacp_read_op->file_path);
- g_free(oacp_read_op);
- oacp_read_op = NULL;
- }
-
- if (otc_info->connected) {
- BT_DBG("OTC Connected");
- otc_connection_status = TRUE;
-
- data_io = g_io_channel_unix_new(otc_info->fd);
-
- g_io_channel_set_encoding(data_io, NULL, NULL);
- g_io_channel_set_flags(data_io, G_IO_FLAG_NONBLOCK, NULL);
-
- if (otp_client_s->curr_op == BT_OTP_OBJECT_WRITE) {
- _bt_otp_client_write_on_fd(otc_info);
- } else if (otp_client_s->curr_op == BT_OTP_OBJECT_READ) {
- bluetooth_otc_info_t *new_otc_info = g_malloc0(sizeof(bluetooth_otc_info_t));
-
- new_otc_info->fd = otc_info->fd;
- new_otc_info->connected = otc_info->connected;
- new_otc_info->address = g_strdup(otc_info->address);
-
- id = g_io_add_watch(data_io,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- __client_data_received_cb, (gpointer)new_otc_info);
-
- timeout_id = g_timeout_add(BT_OTC_CONNECTION_MAX_TIMEOUT,
- (GSourceFunc)__bt_otc_connection_timeout_cb, (gpointer)new_otc_info);
- }
- } else {
- BT_DBG("OTC Disconnected");
- otc_connection_status = FALSE;
- if (timeout_id > 0) {
- g_source_remove(timeout_id);
- timeout_id = 0;
- }
-
- if (otp_client_s && (otp_client_s->curr_op == BT_OTP_OBJECT_READ)) {
- _bt_otp_client_notify_read_object_status(BLUETOOTH_ERROR_NONE,
- file_path, otp_client_s);
- __bt_otp_reset_api_info(otp_client_s);
- }
- }
-}
-
-object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id)
-{
- GSList *l;
- object_metadata *info;
-
- for (l = list; l; l = g_slist_next(l)) {
- info = l->data;
-
- if (info && (info->id == id))
- return info;
- }
- return NULL;
+ return BT_ERROR_NOT_SUPPORTED;
}
int bt_otp_client_read_object_contents(bt_otp_client_h otp_client,
bt_otp_client_read_object_complete_cb callback,
void *user_data)
{
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
- object_metadata *object_info = NULL;
- uint64_t obj_id;
- int error_code;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_OTP_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- obj_id = otp_client_s->object_id;
-
- BT_DBG("OTP client Read objects Contents from Remote device [%s] for Object [%llu]",
- otp_client_s->remote_address, (long long unsigned int)obj_id);
-
- object_info = _bt_otp_client_find_object(otp_client_s->object_list, obj_id);
- if (!object_info) {
- BT_INFO("Object Not Found [%llu]", (long long unsigned int)obj_id);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_OACP_READ_SUPPORTED(otp_client_s->otp_feature)) {
- BT_INFO("OACP Read not supported");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_READ_PERMITTED(object_info->props)) {
- BT_INFO("Read not permitted");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP Client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
- otp_client_s->curr_op = BT_OTP_OBJECT_READ;
-
- uint32_t offset = 0;
- uint32_t length = object_info->curr_size;
-
- BT_INFO("Object ID [%llu],Offset [%u], Length [%u], curr_size [%u]",
- (long long unsigned int)obj_id, offset, length, object_info->curr_size);
- uint8_t value[9] = {0x00};
-
- value[0] = OACP_READ;
- value[1] = (offset) & 0xFF;
- value[2] = (offset >> 8) & 0xFF;
- value[3] = (offset >> 16) & 0xFF;
- value[4] = (offset >> 24) & 0xFF;
- value[5] = (length) & 0xFF;
- value[6] = (length >> 8) & 0xFF;
- value[7] = (length >> 16) & 0xFF;
- value[8] = (length >> 24) & 0xFF;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_oacp_control_point,
- value, 9);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
-
- return error_code;
-}
-
-static void _bt_otp_client_send_create_object_callback(int result,
- uint64_t id, bt_otp_client_s *otp_client_s)
-{
-
- ((bt_otp_client_object_create_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address,
- id, otp_client_s->user_data);
-
- if (oacp_create_op) {
- g_free(oacp_create_op->filename);
- g_free(oacp_create_op->type_uuid);
- g_free(oacp_create_op);
- oacp_create_op = NULL;
- }
-}
-
-int _bt_otp_uuid_convert_string_to_hex(char *uuid, char *value)
-{
- int len, uuid_len;
- uint32_t data0, data4;
- uint16_t data1, data2, data3, data5;
-
- if (!uuid) {
- BT_ERR("Object Type UUID NULL");
- return 0;
- }
-
- len = strlen(uuid);
-
- switch (len) {
- case 4:
- /* UUID 16bits */
- sscanf(uuid, "%04hx", &data1);
- data1 = htons(data1);
- memcpy(value, &data1, 2);
- uuid_len = 2;
- break;
-
- case 8:
- /* UUID 32bits */
- sscanf(uuid, "%08x", &data0);
- data0 = htonl(data0);
- memcpy(value, &data0, 4);
- uuid_len = 4;
- break;
-
- case 36:
- /* UUID 128bits */
- sscanf(uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
- &data0, &data1, &data2,
- &data3, &data4, &data5);
-
- data0 = htonl(data0);
- data1 = htons(data1);
- data2 = htons(data2);
- data3 = htons(data3);
- data4 = htonl(data4);
- data5 = htons(data5);
-
- memcpy(value, &data0, 4);
- memcpy(value+4, &data1, 2);
- memcpy(value+6, &data2, 2);
- memcpy(value+8, &data3, 2);
- memcpy(value+10, &data4, 4);
- memcpy(value+14, &data5, 2);
- uuid_len = 16;
- break;
-
- default:
- uuid_len = 0;
- }
-
- return uuid_len;
+ return BT_ERROR_NOT_SUPPORTED;
}
int bt_otp_client_create_object(bt_otp_client_h otp_client,
bt_otp_client_object_create_cb callback,
void *user_data)
{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
- struct stat st;
- uint32_t size;
- char *file_name, *last_token;
- time_t curr_time;
- char *type_uuid;
- char err_msg[256] = {0, };
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP Client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_OACP_CREATE_SUPPORTED(otp_client_s->otp_feature)) {
- BT_INFO("OACP Create not supported");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client create object [%s] in Remote device [%s]",
- file_path, otp_client_s->remote_address);
-
- /* Get file_name & size from file_path */
- if (stat(file_path, &st) == -1) {
- strerror_r(errno, err_msg, sizeof(err_msg));
- BT_INFO("stat failed: %s (%d)\n", err_msg, errno);
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
- otp_client_s->curr_op = BT_OTP_OBJECT_CREATE;
-
- size = (uint32_t)st.st_size;
- last_token = strrchr(file_path, '/');
- file_name = last_token + 1;
-
- BT_INFO("Filepath [%s], Filename [%s], Size[%u]\n",
- file_path, file_name, size);
-
- oacp_create_op = g_malloc0(sizeof(bt_otp_client_create_op));
- oacp_create_op->size = size;
- oacp_create_op->filename = g_strdup(file_name);
-
- time(&curr_time);
- oacp_create_op->first_created = curr_time;
-
- /* There isn't clear description for Object Type in spec */
- type_uuid = g_strdup(UNSUPPORTED_OBJECT_TYPE_UUID);
- oacp_create_op->type_uuid = g_strdup(type_uuid);
-
- /* UUIDs can be 128/64/16 bits */
- uint8_t value[40] = {0x00};
- int len;
-
- value[0] = OACP_CREATE;
- len = 1;
- len += _bt_otp_uuid_convert_string_to_hex(type_uuid, (char *)value + 1);
- value[++len] = size & 0xFF;
- value[++len] = (size >> 8) & 0xFF;
- value[++len] = (size >> 16) & 0xFF;
- value[++len] = (size >> 24) & 0xFF;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_oacp_control_point,
- value, len);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
- g_free(type_uuid);
- return error_code;
-}
-
-static void _bt_otp_client_send_write_object_callback(int result,
- unsigned int length, bt_otp_client_s *otp_client_s)
-{
- ((bt_otp_client_object_write_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address,
- length, otp_client_s->user_data);
-
- if (oacp_write_op) {
- g_free(oacp_write_op->file_path);
- g_free(oacp_write_op);
- oacp_write_op = NULL;
- }
+ return BT_ERROR_NOT_SUPPORTED;
}
int bt_otp_client_write_object(bt_otp_client_h otp_client,
bt_otp_client_object_write_cb callback,
void *user_data)
{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
- object_metadata *object_info = NULL;
- struct stat st;
- uint32_t size;
- time_t curr_time;
- char err_msg[256] = {0, };
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
- BT_CHECK_INPUT_PARAMETER(file_path);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP Client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_OACP_WRITE_SUPPORTED(otp_client_s->otp_feature)) {
- BT_INFO("OACP Write not supported");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- object_info = _bt_otp_client_find_object(otp_client_s->object_list,
- otp_client_s->object_id);
- if (!object_info) {
- BT_INFO("Object Not Found [%llu]", (long long unsigned int)otp_client_s->object_id);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_WRITE_PERMITTED(object_info->props)) {
- BT_INFO("Write not permitted");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client wirte object [%s] in Remote device [%s]",
- file_path, otp_client_s->remote_address);
-
- /* Get file_name & size from file_path */
- if (stat(file_path, &st) == -1) {
- strerror_r(errno, err_msg, sizeof(err_msg));
- BT_INFO("stat failed: %s (%d)\n", err_msg, errno);
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- size = (uint32_t)st.st_size;
-
- BT_INFO("Filepath [%s], Size[%u]", file_path, size);
- BT_INFO("offset[%u], length[%u], mode[%u]", offset, length, mode);
-
- oacp_write_op = g_malloc0(sizeof(bt_otp_client_write_op));
- oacp_write_op->size = size;
- oacp_write_op->file_path = g_strdup(file_path);
- oacp_write_op->offset = offset;
- oacp_write_op->length = length;
- oacp_write_op->mode = mode;
-
- time(&curr_time);
- oacp_write_op->last_modified = curr_time;
-
- if (offset < 0 && (offset > size || (length - offset) > size)) {
- /* Invalid param */
- return BLUETOOTH_ERROR_INTERNAL;
- }
-
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
- otp_client_s->curr_op = BT_OTP_OBJECT_WRITE;
-
- uint8_t value[10] = {0x00};
- value[0] = OACP_WRITE;
- value[1] = offset & 0xFF;
- value[2] = (offset >> 8) & 0xFF;
- value[3] = (offset >> 16) & 0xFF;
- value[4] = (offset >> 24) & 0xFF;
- value[5] = length & 0xFF;
- value[6] = (length >> 8) & 0xFF;
- value[7] = (length >> 16) & 0xFF;
- value[8] = (length >> 24) & 0xFF;
- value[9] = mode & 0xFF;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_oacp_control_point,
- value, 10);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
-
- return error_code;
-}
-
-static void _bt_otp_client_send_execute_object_callback(int result,
- bt_otp_client_s *otp_client_s)
-{
- ((bt_otp_client_object_execute_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address,
- otp_client_s->object_id, otp_client_s->user_data);
+ return BT_ERROR_NOT_SUPPORTED;
}
int bt_otp_client_execute_object(bt_otp_client_h otp_client,
bt_otp_client_object_execute_cb callback,
void *user_data)
{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
- object_metadata *object_info = NULL;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP Client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_OACP_EXECUTE_SUPPORTED(otp_client_s->otp_feature)) {
- BT_INFO("OACP Execute not supported");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- object_info = _bt_otp_client_find_object(otp_client_s->object_list,
- otp_client_s->object_id);
- if (!object_info) {
- BT_INFO("Object Not Found [%llu]", (long long unsigned int)otp_client_s->object_id);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_EXECUTE_PERMITTED(object_info->props)) {
- BT_INFO("Execute not permitted");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client execute object [%llu] in Remote device [%s]",
- (long long unsigned int)otp_client_s->object_id, otp_client_s->remote_address);
-
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
- otp_client_s->curr_op = BT_OTP_OBJECT_EXECUTE;
-
- uint8_t value[1];
- value[0] = OACP_EXECUTE;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_oacp_control_point,
- value, 1);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
-
- return error_code;
-}
-
-static void _bt_otp_client_send_delete_object_callback(int result,
- bt_otp_client_s *otp_client_s)
-{
- ((bt_otp_client_object_delete_cb)otp_client_s->callback)(
- result, otp_client_s->remote_address,
- otp_client_s->object_id, otp_client_s->user_data);
-
- if (result == BLUETOOTH_ERROR_NONE)
- otp_client_s->object_id = 0;
+ return BT_ERROR_NOT_SUPPORTED;
}
int bt_otp_client_delete_object(bt_otp_client_h otp_client,
bt_otp_client_object_delete_cb callback,
void *user_data)
{
- int error_code;
- bt_otp_client_s *otp_client_s = (bt_otp_client_s *)otp_client;
- object_metadata *object_info = NULL;
-
- BT_CHECK_LE_SUPPORT();
- BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(otp_client_s);
-
- if (_bt_otp_client_find(otp_client_s->remote_address) == NULL)
- return BT_ERROR_NOT_INITIALIZED;
-
- if (otp_client_s->connected == false) {
- BT_ERR("Remote device [%s] is not conencted", otp_client_s->remote_address);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (otp_client_s->curr_op != BT_OTP_NO_OPERATION) {
- BT_DBG("OTP Client is busy");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_OACP_DELETE_SUPPORTED(otp_client_s->otp_feature)) {
- BT_INFO("OACP Delete not supported");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- object_info = _bt_otp_client_find_object(otp_client_s->object_list,
- otp_client_s->object_id);
- if (!object_info) {
- BT_INFO("Object Not Found [%llu]", (long long unsigned int)otp_client_s->object_id);
- return BT_ERROR_OPERATION_FAILED;
- }
-
- if (~BT_OTP_IS_DELETE_PERMITTED(object_info->props)) {
- BT_INFO("Delete not permitted");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- BT_DBG("OTP client delete object [%llu] in Remote device [%s]",
- (long long unsigned int)otp_client_s->object_id, otp_client_s->remote_address);
-
- otp_client_s->callback = callback;
- otp_client_s->user_data = user_data;
- otp_client_s->curr_op = BT_OTP_OBJECT_DELETE;
-
- uint8_t value[1];
- value[0] = OACP_DELETE;
-
- error_code = bluetooth_otp_write_characteristics_value(otp_client_s->otp_oacp_control_point,
- value, 1);
- if (error_code != BT_ERROR_NONE) {
- BT_ERR("Failed to write control point : %s(0x%08x)",
- _bt_convert_error_to_string(error_code), error_code);
- __bt_otp_reset_api_info(otp_client_s);
- }
-
- return error_code;
+ return BT_ERROR_NOT_SUPPORTED;
}
-/* LCOV_EXCL_STOP */