From: Gowtham Anandha Babu Date: Thu, 11 May 2017 13:43:39 +0000 (+0530) Subject: [Bluetooth][OTP] Add object browsing support X-Git-Tag: submit/tizen/20170523.010304^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git;a=commitdiff_plain;h=1e23796887007d56d3736cd8303bd324a38a267d [Bluetooth][OTP] Add object browsing support Client side changes: 1) Exposed characterstics_write_value BT-API 2) Send "GattValueChanged" indication to otp-application Server side changes: 1) Change implementation to support both single and multiple object(s). Change-Id: I9fd250505b739b858f26ee7618737e058bc95a8d Signed-off-by: Gowtham Anandha Babu --- diff --git a/bt-api/bt-common.c b/bt-api/bt-common.c index 1ad2171..363f5a2 100644 --- a/bt-api/bt-common.c +++ b/bt-api/bt-common.c @@ -604,6 +604,7 @@ const char *_bt_convert_service_function_to_string(int function) {BT_TDS_ACTIVATE_CONTROL_POINT, "BT_TDS_ACTIVATE_CONTROL_POINT"}, {BT_OTP_READ_VALUE, "BT_OTP_READ_VALUE"}, {BT_OTP_ENABLE_NOTIFICATION, "BT_OTP_ENABLE_NOTIFICATION"}, + {BT_OTP_WRITE_VALUE, "BT_OTP_WRITE_VALUE"}, {-1, ""}, }; diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index 991094b..67ead44 100644 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -3104,6 +3104,47 @@ static void __bt_otp_event_filter(GDBusConnection *connection, _bt_common_event_cb(BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED, result, handle, event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_OTP_WRITE_CHAR_VAL) == 0) { + BT_DBG("OTP Control point Activation result"); + char *handle = NULL; + + /* Extract data from DBUS params */ + g_variant_get(parameters, "(i&s)", &result, &handle); + BT_DBG("Handle [%s]", handle); + BT_DBG("Result [%d]", result); + + _bt_common_event_cb(BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL, + result, handle, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_OTP_INDICATION) == 0) { + BT_DBG("OTP Control point Indication Response"); + bluetooth_otp_resp_info_t *ind_res = NULL; + char *buffer = NULL; + GVariant *byte_var = NULL; + char *handle = NULL; + + g_variant_get(parameters, "(i&s@ay)", &result, &handle, &byte_var); + + ind_res = g_malloc0(sizeof(bluetooth_otp_resp_info_t)); + ind_res->data_length = g_variant_get_size(byte_var); + buffer = (char *)g_variant_get_data(byte_var); + ind_res->data = g_memdup(buffer, ind_res->data_length); + ind_res->handle = g_strdup(handle); + + _bt_common_event_cb(BLUETOOTH_EVENT_OTP_INDICATION, + result, ind_res, + event_info->cb, event_info->user_data); + + if (ind_res->handle) { + g_free(ind_res->handle); + } + + if (ind_res->data) { + g_free(ind_res->data); + g_free(ind_res); + } + if (byte_var) + g_variant_unref(byte_var); } BT_DBG("-"); diff --git a/bt-api/bt-otp.c b/bt-api/bt-otp.c index 23eb5eb..1d0a86c 100644 --- a/bt-api/bt-otp.c +++ b/bt-api/bt-otp.c @@ -152,4 +152,52 @@ BT_EXPORT_API int bluetooth_otp_enable_notification(const char *handle) BT_DBG("-"); return result; -} \ No newline at end of file +} + +BT_EXPORT_API int bluetooth_otp_write_characteristics_value(const char *handle, + unsigned char *buf, int length) +{ + char *path; + int path_len = 0; + bt_user_info_t *user_info; + int result = BLUETOOTH_ERROR_INTERNAL; + bluetooth_otp_charc_data_t data; + BT_DBG("+"); + + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_PARAMETER(buf, return); + BT_CHECK_ENABLED_LE(return); + + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + memset(&data, 0x00, sizeof(bluetooth_otp_charc_data_t)); + + data.length = length; + if (length > 0) + memcpy(data.data, buf, length); + + path = g_strdup(handle); + path_len = _bluetooth_handle_get_len(path); + + /*Fill parameters*/ + g_array_append_vals(in_param1, path, path_len); + + g_array_append_vals(in_param2, &data, sizeof(bluetooth_otp_charc_data_t)); + + int i; + for (i = 0; i < length; i++) + BT_INFO("Value[%d] = %u", i, buf[i]); + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_WRITE_VALUE, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_free(path); + BT_DBG("-"); + return result; +} diff --git a/bt-otp/bt-otpserver.c b/bt-otp/bt-otpserver.c index 3eff442..0b7870c 100644 --- a/bt-otp/bt-otpserver.c +++ b/bt-otp/bt-otpserver.c @@ -95,6 +95,7 @@ static guint obj_curr_index; static int adv_handle = 0; static gboolean OLCP_indicate = FALSE; char *directory = NULL; +gboolean mutiple_obj_support = false; static const gchar otp_introspection_xml[] = "" @@ -111,6 +112,7 @@ static const gchar otp_introspection_xml[] = void _bt_otp_deinit_event_receiver(void); void _bt_otp_unregister_interface(void); +void update_obj_metadata_charc_value(struct object_metadata *object); static void delete_all_objects(void) { @@ -347,14 +349,17 @@ int _bt_otp_prepare_ots(void) if (ret != BLUETOOTH_ERROR_NONE) goto fail; - /* Characteristic Object ID */ - props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ; - perms = BLUETOOTH_GATT_PERMISSION_READ; - char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_ID_UUID); - ret = add_new_characteristic(char_uuid, perms, props, - &otp_object_id_obj_path); - if (ret != BLUETOOTH_ERROR_NONE) - goto fail; + /* Object ID is mandatory for mutiple object server */ + if (mutiple_obj_support) { + /* Characteristic Object ID */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ; + perms = BLUETOOTH_GATT_PERMISSION_READ; + char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_ID_UUID); + ret = add_new_characteristic(char_uuid, perms, props, + &otp_object_id_obj_path); + if (ret != BLUETOOTH_ERROR_NONE) + goto fail; + } /* Characteristic Object Properties */ props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ; @@ -386,25 +391,30 @@ int _bt_otp_prepare_ots(void) goto fail; } - /* Characteristic OLCP */ - props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE | - BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE; - perms = BLUETOOTH_GATT_PERMISSION_WRITE; - char_uuid = _otp_convert_uuid_to_uuid128(OTP_OLCP_UUID); - ret = add_new_characteristic(char_uuid, perms, props, - &otp_olcp_obj_path); - if (ret != BLUETOOTH_ERROR_NONE) - goto fail; + /* OLCP Characteristics is not required + * for single object server + */ + if (mutiple_obj_support) { + /* Characteristic OLCP */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE; + perms = BLUETOOTH_GATT_PERMISSION_WRITE; + char_uuid = _otp_convert_uuid_to_uuid128(OTP_OLCP_UUID); + ret = add_new_characteristic(char_uuid, perms, props, + &otp_olcp_obj_path); + if (ret != BLUETOOTH_ERROR_NONE) + goto fail; - /* CCCD for OLCP */ - desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID); - perms = BLUETOOTH_GATT_PERMISSION_READ | - BLUETOOTH_GATT_PERMISSION_WRITE; - ret = bluetooth_gatt_add_descriptor(otp_olcp_obj_path, desc_uuid, - perms, &otp_olcp_desc_obj_path); - if (ret != BLUETOOTH_ERROR_NONE) { - BT_ERR("Failed to add new char descriptor %d", ret); - goto fail; + /* CCCD for OLCP */ + desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID); + perms = BLUETOOTH_GATT_PERMISSION_READ | + BLUETOOTH_GATT_PERMISSION_WRITE; + ret = bluetooth_gatt_add_descriptor(otp_olcp_obj_path, desc_uuid, + perms, &otp_olcp_desc_obj_path); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char descriptor %d", ret); + goto fail; + } } /* Register service */ @@ -494,12 +504,17 @@ static void _bt_otp_method(GDBusConnection *connection, list = g_slist_append(list, (gpointer) filename); } + g_dir_close(dir); + if (!list) { BT_DBG("No object found in given directory"); status = BLUETOOTH_ERROR_NO_OBJECTS_FOUND; goto fail; } + if (g_slist_length(list) > 1) + mutiple_obj_support = true; + for (l = list; l != NULL; l = l->next) { if (!l->data) continue; snprintf(absolute_path, sizeof(absolute_path), "%s%s", directory, @@ -530,8 +545,6 @@ static void _bt_otp_method(GDBusConnection *connection, object_id++; } - g_dir_close(dir); - BT_DBG("preparing"); if (_bt_otp_prepare_ots() != BLUETOOTH_ERROR_NONE) { BT_ERR("Fail to prepare OTP Proxy"); @@ -539,6 +552,15 @@ static void _bt_otp_method(GDBusConnection *connection, goto fail; } + /* If single object is supported, make that as + * selected object and update the metadata for the same. + */ + if (!mutiple_obj_support) { + BT_INFO("Server supports single object"); + selected_object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0); + update_obj_metadata_charc_value(selected_object); + } + BT_DBG("advertsing"); if (_bt_otp_set_advertising_data() != BLUETOOTH_ERROR_NONE) { BT_ERR("Fail to set advertising data"); @@ -711,8 +733,11 @@ void update_obj_metadata_charc_value(struct object_metadata *object) _bt_otp_set_char_value(otp_object_first_created_obj_path, value, 7); _bt_otp_set_char_value(otp_object_last_modified_obj_path, value, 7); - convert_to_hex(object, "id", value); - _bt_otp_set_char_value(otp_object_id_obj_path, value, 6); + /* Object ID is optonal for single object server */ + if (mutiple_obj_support) { + convert_to_hex(object, "id", value); + _bt_otp_set_char_value(otp_object_id_obj_path, value, 6); + } convert_to_hex(object, "props", value); _bt_otp_set_char_value(otp_object_prop_obj_path, value, 4); diff --git a/bt-service/bt-request-handler.c b/bt-service/bt-request-handler.c index 162e94a..cf35d49 100644 --- a/bt-service/bt-request-handler.c +++ b/bt-service/bt-request-handler.c @@ -2407,6 +2407,38 @@ int __bt_bluez_request(int function_name, g_free(handle); break; } + case BT_OTP_WRITE_VALUE: { + char *handle; + char *data = NULL; + guint data_len = 0; + char *sender = NULL; + bluetooth_otp_charc_data_t otp_charc_data; + sender = (char *)g_dbus_method_invocation_get_sender(context); + + data_len = g_variant_get_size(in_param1); + data = (char *)g_variant_get_data(in_param1); + + handle = g_strndup(data, data_len); + BT_DBG("OTP Write Characteristic value [%s]", handle); + + __bt_service_get_parameters(in_param2, + &otp_charc_data, sizeof(bluetooth_otp_charc_data_t)); + + int i; + for (i = 0; i < otp_charc_data.length; i++) + BT_DBG("Value[%d] = %u", i, otp_charc_data.data[i]); + + result = _bt_otp_write_characteristic_value(request_id, sender, handle, + otp_charc_data.data, otp_charc_data.length); + + if (result != BLUETOOTH_ERROR_NONE) { + BT_ERR("OTP Write Characteristic failed result [%d]", result); + g_array_append_vals(*out_param1, handle, data_len); + } + if (handle) + g_free(handle); + break; + } default: result = BLUETOOTH_ERROR_INTERNAL; break; @@ -3255,6 +3287,7 @@ gboolean __bt_service_check_privilege(int function_name, case BT_OTP_SERVER_DEINIT: case BT_OTP_READ_VALUE: case BT_OTP_ENABLE_NOTIFICATION: + case BT_OTP_WRITE_VALUE: case BT_MAP_CREATE_SESSION: case BT_MAP_DESTROY_SESSION: diff --git a/bt-service/bt-service-event-receiver.c b/bt-service/bt-service-event-receiver.c index c1b7037..153c6ad 100644 --- a/bt-service/bt-service-event-receiver.c +++ b/bt-service/bt-service-event-receiver.c @@ -44,6 +44,7 @@ #include "bt-service-opp-client.h" #include "bt-service-map-client.h" #include "bt-service-tds.h" +#include "bt-service-otp.h" #ifdef TIZEN_FEATURE_BT_DPM #include "bt-service-dpm.h" @@ -1709,6 +1710,9 @@ void _bt_handle_gatt_event(GVariant *msg, const char *member, const char *path) if (strcasecmp(member, "GattValueChanged") == 0) { /* Check TDS seekers waiting for Indication */ _bt_tds_check_indication(path, msg); +#ifdef TIZEN_FEATURE_BT_OTP + _bt_otp_check_indication(path, msg); +#endif } else { BT_INFO("Unhandled event"); } diff --git a/bt-service/bt-service-event-sender.c b/bt-service/bt-service-event-sender.c index 8ba8847..a5ccbe2 100644 --- a/bt-service/bt-service-event-sender.c +++ b/bt-service/bt-service-event-sender.c @@ -559,6 +559,12 @@ int _bt_send_event_to_dest(const char* dest, int event_type, case BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED: signal = BT_OTP_NOTIFICATION_ENABLED; break; + case BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL: + signal = BT_OTP_WRITE_CHAR_VAL; + break; + case BLUETOOTH_EVENT_OTP_INDICATION: + signal = BT_OTP_INDICATION; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; diff --git a/bt-service/bt-service-otp.c b/bt-service/bt-service-otp.c index 3e49707..e62e809 100644 --- a/bt-service/bt-service-otp.c +++ b/bt-service/bt-service-otp.c @@ -41,11 +41,13 @@ #define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1" #define GATT_DEFAULT_TIMEOUT (6 * 1000) /* Dependent on supervision timeout 6 sec */ +#define BT_INDICATION_TIMEOUT_MAX 15000 /* Timeout for Indication from OTP Server in msec */ /* OTP Notification Request structure */ typedef struct { char *handle; char *sender; + unsigned int notification_timeout_id; int req_id; } bt_otp_notification_info; @@ -394,8 +396,8 @@ int _bt_otp_read_characteristic_value(int request_id, char *sender, char *handle { GDBusConnection *conn; bt_otp_read_req_info *info = NULL; - GVariantBuilder *builder = NULL; char *charc_handle = g_strdup(handle); + GVariantBuilder *builder = NULL; guint16 offset = 0; BT_CHECK_PARAMETER(handle, return); @@ -471,6 +473,10 @@ static void __bt_otp_remove_notification_info(bt_otp_notification_info *info) g_free(info->handle); if (info->sender) g_free(info->sender); + if (info->notification_timeout_id > 0) { + g_source_remove(info->notification_timeout_id); + info->notification_timeout_id = 0; + } g_free(info); } @@ -516,9 +522,15 @@ static void __bt_otp_notification_enable_request_cb(GObject *source_object, if (info) req_info = _bt_get_request_info(info->req_id); - /* CCCD Enable request failed */ + /* If CCCD Enable request failed for any reason, reset timer */ if (result != BLUETOOTH_ERROR_NONE && info != NULL) { BT_ERR("Activation Request failed"); + /* Reset Timer */ + if (info->notification_timeout_id > 0) { + g_source_remove(info->notification_timeout_id); + info->notification_timeout_id = 0; + } + /* Remove Indication Info */ __bt_otp_remove_notification_info(info); } else { @@ -600,3 +612,218 @@ int _bt_otp_enable_notification(int request_id, char *sender, char *handle) BT_DBG("-"); return BLUETOOTH_ERROR_NONE; } + +static void __bt_otp_write_request_cb(GObject *source_object, + GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + GDBusConnection *system_gconn = NULL; + GVariant *value = NULL; + GVariant *param = NULL; + GVariant *out_param1 = NULL; + int result = BLUETOOTH_ERROR_NONE; + char *handle = NULL; + bt_otp_notification_info *info = NULL; + request_info_t *req_info = NULL; + BT_DBG("+"); + + system_gconn = _bt_gdbus_get_system_gconn(); + value = g_dbus_connection_call_finish(system_gconn, res, &error); + + if (error) { + BT_ERR("Error : %s \n", error->message); + /* Process error->message to narrow down the att_ecode */ + result = BLUETOOTH_ERROR_INTERNAL; + } + + handle = (char *)user_data; + info = __bt_otp_get_notification_info(handle); + if (info) + req_info = _bt_get_request_info(info->req_id); + + /* Is Activation request failed for any reason, reset timer */ + if (result != BLUETOOTH_ERROR_NONE && info != NULL) { + BT_ERR("Activation Request failed"); + /* Remove Indication Info */ + __bt_otp_remove_notification_info(info); + } else { + /* Activation Request successful */ + if (info) { + param = g_variant_new("(is)", result, handle); + _bt_send_event_to_dest(info->sender, BT_OTP_EVENT, + BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL, + param); + } + } + + if (req_info == NULL) { + BT_ERR("OTP Write Request is not found!!"); + goto done; + } + + if (req_info->context == NULL) + goto done; + + out_param1 = g_variant_new_from_data((const GVariantType*)"ay", + handle, __get_handle_length(handle), TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(iv)", result, out_param1)); + + _bt_delete_request_list(req_info->req_id); + +done: + if (value) + g_variant_unref(value); + if (error) + g_clear_error(&error); + if (handle) + g_free(handle); + + BT_DBG("-"); + return; +} + +static void __bt_otp_send_indication_event(bt_otp_notification_info *info, + unsigned char *buffer, int len, int result) +{ + GVariant *otp_data; + GVariant *param; + + otp_data = g_variant_new_from_data((const GVariantType*)"ay", + buffer, len, TRUE, NULL, NULL); + + BT_DBG("Send Indication event to sender"); + param = g_variant_new("(is@ay)", result, info->handle, otp_data); + _bt_send_event_to_dest(info->sender, BT_OTP_EVENT, + BLUETOOTH_EVENT_OTP_INDICATION, + param); + + /* Remove info from list */ + __bt_otp_remove_notification_info(info); +} + +static bool __bt_otp_indication_timeout_cb(gpointer user_data) +{ + char *handle = NULL; + handle = (char *) user_data; + bt_otp_notification_info *info = NULL; + /* Indication:Fail*/ + info = __bt_otp_get_notification_info(handle); + BT_DBG("Activation timer Expired [Server] [%s]", info->handle); + if (info) + __bt_otp_send_indication_event(info, NULL, 0, BLUETOOTH_ERROR_INTERNAL); + + return FALSE; +} + +int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handle, + unsigned char *param, int length) +{ + GVariantBuilder *builder1; + GVariant *val; + GVariant *options; + GVariantBuilder *builder2; + guint16 offset = 0; + bt_otp_notification_info *info = NULL; + GDBusConnection *conn; + char *charc_handle = g_strdup(handle); + int i; + + BT_DBG("+"); + + BT_CHECK_PARAMETER(handle, return); + BT_CHECK_PARAMETER(sender, return); + BT_CHECK_PARAMETER(param, return); + + conn = _bt_gdbus_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + BT_DBG("OTP Write Characteristic value handle [%s] data length [%d]", handle, length); + /* Check if activation is ongoing for the same Remote Server */ + + info = __bt_otp_get_notification_info(handle); + if (info && info->notification_timeout_id > 0) { + BT_ERR("Write Request is already ongoing in remote server"); + g_free(charc_handle); + return BLUETOOTH_ERROR_IN_PROGRESS; + } + + builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay")); + + for (i = 0; i < length; i++) { + g_variant_builder_add(builder1, "y", param[i]); + } + + val = g_variant_new("(ay)", builder1); + builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + /*offset*/ + g_variant_builder_add(builder2, "{sv}", "offset", + g_variant_new_uint16(offset)); + + options = g_variant_new("a{sv}", builder2); + + /* Activate Control Point */ + g_dbus_connection_call(conn, + BT_BLUEZ_NAME, + handle, + GATT_CHAR_INTERFACE, + "WriteValue", + g_variant_new("(@ay@a{sv})", + val, options), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + (GAsyncReadyCallback)__bt_otp_write_request_cb, + (gpointer)charc_handle); + + g_variant_builder_unref(builder1); + g_variant_builder_unref(builder2); + + if (info == NULL) { + info = g_malloc0(sizeof(bt_otp_notification_info)); + info->handle = g_strdup(handle); + info->sender = g_strdup(sender); + otp_notification_info_list = g_slist_append(otp_notification_info_list, info); + } + info->req_id = request_id; + info->notification_timeout_id = g_timeout_add(BT_INDICATION_TIMEOUT_MAX, + (GSourceFunc)__bt_otp_indication_timeout_cb, (gpointer)info->handle); + + BT_DBG("-"); + return BLUETOOTH_ERROR_NONE; +} + +void _bt_otp_check_indication(const char *path, GVariant *msg) +{ + bt_otp_notification_info *info = NULL; + unsigned char *buffer = NULL; + int len = 0; + int i; + GVariant *value = NULL; + BT_DBG("+"); + + info = __bt_otp_get_notification_info((char *)path); + + if (info) { + g_variant_get(msg, "(is@ay)", NULL, NULL, &value); + len = g_variant_get_size(value); + BT_DBG("Indication data from Server len[%d]", len); + if (len > 0) { + buffer = (unsigned char *)g_variant_get_data(value); + /* DEBUG */ + for (i = 0; i < len; i++) + BT_DBG("%.2x", buffer[i]); + } + + /* Reset Timer */ + if (info->notification_timeout_id > 0) + g_source_remove(info->notification_timeout_id); + + /* Send Indication & info removed internally */ + __bt_otp_send_indication_event(info, buffer, len, BLUETOOTH_ERROR_NONE); + + if (value) + g_variant_unref(value); + } + BT_DBG("-"); +} diff --git a/bt-service/include/bt-service-otp.h b/bt-service/include/bt-service-otp.h index b525e18..64d4026 100644 --- a/bt-service/include/bt-service-otp.h +++ b/bt-service/include/bt-service-otp.h @@ -34,6 +34,11 @@ int _bt_otp_read_characteristic_value(int request_id, char *sender, char *handle int _bt_otp_enable_notification(int request_id, char *sender, char *handle); +int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handle, + unsigned char *param, int length); + +void _bt_otp_check_indication(const char *path, GVariant *msg); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 3eab8cb..153f324 100644 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -86,6 +86,8 @@ extern "C" { */ #define BLUETOOTH_MAX_OTP_SERVER_DIR_NAME 100 +#define BLUETOOTH_OTP_CHARC_VAL_MAX_LENGTH 500 /**< OTP Characteristics Value Max length */ + /** * This is Bluetooth error code */ @@ -506,6 +508,14 @@ typedef struct { } bluetooth_tds_transport_data_info_t; /** +* OTP Characteristics Value +*/ +typedef struct { + int length; /**< Characteristics value length */ + guint8 data[BLUETOOTH_OTP_CHARC_VAL_MAX_LENGTH]; /**< Characteristics data */ +} bluetooth_otp_charc_data_t; + +/** * Structure to hold the OTP response data from remote OTP server */ typedef struct { @@ -833,6 +843,8 @@ typedef enum { BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED, /* OTP Server Status **/ BLUETOOTH_EVENT_OTP_READ_CHAR_VAL, /* OTP Read Value Response */ BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED, /* OTP Notification Enabled Response */ + BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL, /* OTP Write Value Response */ + BLUETOOTH_EVENT_OTP_INDICATION, /* OTP Indication */ } bluetooth_event_type_t; /** @@ -7580,8 +7592,57 @@ int bluetooth_otp_server_init(const char *directory); */ int bluetooth_otp_server_deinit(); +/** + * @fn int bluetooth_otp_enable_notification(const char *handle); + * + * @brief Enable notification for remote OACP & OLCP characteristics. + * + * This function is a synchronous call. + * + * @return + * + * @exception None + * @param[in] None + * @param[out] None + * + * @remark None + */ int bluetooth_otp_enable_notification(const char *handle); +/** + * @fn int bluetooth_otp_write_characteristics_value( const char *handle, + * unsigned char *buf, int length); + * + * @brief Write value on remote characteristics. + * + * This function is a synchronous call. + * + * @return + * + * @exception None + * @param[in] None + * @param[out] None + * + * @remark None + */ +int bluetooth_otp_write_characteristics_value( const char *handle, + unsigned char *buf, int length); + +/** + * @fn int bluetooth_otp_read_characteristic_value(const char *handle); + * + * @brief Read value for remote characteristics. + * + * This function is a synchronous call. + * + * @return + * + * @exception None + * @param[in] None + * @param[out] None + * + * @remark None + */ int bluetooth_otp_read_characteristic_value(const char *handle); /** diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index c5469cd..23d8917 100644 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -385,6 +385,7 @@ typedef enum { BT_OTP_SERVER_DEINIT, BT_OTP_READ_VALUE, BT_OTP_ENABLE_NOTIFICATION, + BT_OTP_WRITE_VALUE, } bt_function_t; typedef struct { @@ -565,6 +566,8 @@ typedef struct { #define BT_OTP_SERVER_STATE_CHANGED "OtpServerStateChanged" #define BT_OTP_READ_CHAR_VAL "OtpReadCharVal" #define BT_OTP_NOTIFICATION_ENABLED "OtpNotificationEnabled" +#define BT_OTP_WRITE_CHAR_VAL "OtpWriteCharVal" +#define BT_OTP_INDICATION "OtpIndication" typedef enum { _PROFILE_UNKNOWN = 0,