[Bluetooth][OTP-Client] Handle GATT operations for OTP 65/127965/5
authorGowtham Anandha Babu <gowtham.ab@samsung.com>
Tue, 2 May 2017 15:52:55 +0000 (21:22 +0530)
committerGowtham Anandha Babu <gowtham.ab@samsung.com>
Thu, 11 May 2017 07:23:16 +0000 (12:53 +0530)
Expose GATT Read & StartNotify methods to CAPI for
OTP client operations.

Change-Id: I0dee5572ee155f4440aa260730783811e5785348
Signed-off-by: Gowtham Anandha Babu <gowtham.ab@samsung.com>
bt-api/bt-common.c
bt-api/bt-event-handler.c
bt-api/bt-otp.c
bt-otp/bt-otpserver.c
bt-service/bt-request-handler.c
bt-service/bt-service-event-sender.c
bt-service/bt-service-otp.c
bt-service/include/bt-service-otp.h
include/bluetooth-api.h
include/bt-internal-types.h

index 3839810..1ad2171 100644 (file)
@@ -602,6 +602,8 @@ const char *_bt_convert_service_function_to_string(int function)
                {BT_TDS_READ_TRANSPORT_DATA, "BT_TDS_READ_TRANSPORT_DATA"},
                {BT_TDS_ENABLE_CONTROL_POINT, "BT_TDS_ENABLE_CONTROL_POINT"},
                {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"},
                {-1, ""},
        };
 
index f53ee98..991094b 100644 (file)
@@ -2936,7 +2936,7 @@ static void __bt_tds_event_filter(GDBusConnection *connection,
 
                if (data_len == 0) {
                        BT_ERR("No data");
-            g_variant_unref(var);
+                       g_variant_unref(var);
                        return;
                }
 
@@ -3051,6 +3051,59 @@ static void __bt_otp_event_filter(GDBusConnection *connection,
 
                _bt_common_event_cb(BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED,
                                result, &status, event_info->cb, event_info->user_data);
+       } else if (strcasecmp(signal_name, BT_OTP_READ_CHAR_VAL) == 0) {
+               BT_DBG("OTP Read Data received");
+               const char *handle = NULL;
+               char *data;
+               int data_len = 0;
+               GVariant *var = NULL;
+               bluetooth_otp_resp_info_t *info = NULL;
+
+               /* Extract data from DBUS params */
+               g_variant_get(parameters, "(i&sn@ay)", &result, &handle, &data_len, &var);
+               data = (char *)g_variant_get_data(var);
+
+               BT_DBG("Handle [%s]", handle);
+               BT_DBG("Data len [%d]", data_len);
+
+               if (data_len == 0) {
+                       BT_ERR("No data");
+                       if (var)
+                               g_variant_unref(var);
+                       return;
+               }
+
+               info = g_malloc0(sizeof(bluetooth_otp_resp_info_t));
+               info->data_length = data_len;
+               info->data = g_memdup(data, data_len);
+               info->handle = g_strdup(handle);
+
+               _bt_common_event_cb(BLUETOOTH_EVENT_OTP_READ_CHAR_VAL,
+                               result, info,
+                               event_info->cb, event_info->user_data);
+
+               if (info->handle) {
+                       g_free(info->handle);
+               }
+
+               if (info->data) {
+                       g_free(info->data);
+                       g_free(info);
+               }
+               if (var)
+                       g_variant_unref(var);
+       } else if (strcasecmp(signal_name, BT_OTP_NOTIFICATION_ENABLED) == 0) {
+               BT_DBG("OTP Notification Enabled event");
+               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_NOTIFICATION_ENABLED,
+                               result, handle,
+                               event_info->cb, event_info->user_data);
        }
 
        BT_DBG("-");
index 85cf974..23eb5eb 100644 (file)
 #include "bt-request-sender.h"
 #include "bt-event-handler.h"
 
+static int _bluetooth_handle_get_len(const char *str)
+{
+       int i;
+       for (i = 0; str && str[i] != '\0'; i++);
+       return i;
+}
+
 BT_EXPORT_API int bluetooth_otp_server_init(const char *directory)
 {
        int result = BLUETOOTH_ERROR_INTERNAL;
@@ -78,4 +85,71 @@ BT_EXPORT_API int bluetooth_otp_server_deinit()
 
        BT_DBG("-");
        return result;
+}
+
+BT_EXPORT_API int bluetooth_otp_read_characteristic_value(const char *handle)
+{
+       char *path;
+       int path_len = 0;
+       bt_user_info_t *user_info;
+       int result = BLUETOOTH_ERROR_INTERNAL;
+       BT_DBG("+");
+
+       BT_CHECK_PARAMETER(handle, 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);
+
+       path = g_strdup(handle);
+       path_len = _bluetooth_handle_get_len(path);
+       g_array_append_vals(in_param1, path, path_len);
+       g_free(path);
+
+       result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_READ_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);
+
+       BT_DBG("-");
+       return result;
+}
+
+BT_EXPORT_API int bluetooth_otp_enable_notification(const char *handle)
+{
+       char *path;
+       int path_len = 0;
+       bt_user_info_t *user_info;
+       int result = BLUETOOTH_ERROR_INTERNAL;
+       BT_DBG("+");
+
+       BT_CHECK_PARAMETER(handle, 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);
+
+       path = g_strdup(handle);
+       path_len = _bluetooth_handle_get_len(path);
+       g_array_append_vals(in_param1, path, path_len);
+       g_free(path);
+
+       result = _bt_send_request_async(
+                                       BT_BLUEZ_SERVICE,
+                                       BT_OTP_ENABLE_NOTIFICATION,
+                                       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);
+
+       BT_DBG("-");
+       return result;
 }
\ No newline at end of file
index 1d2bb31..3eff442 100644 (file)
@@ -263,8 +263,8 @@ int _bt_otp_prepare_ots(void)
        char *desc_uuid;
        bt_gatt_characteristic_property_t props;
        bt_gatt_permission_t perms;
-       char supp_feat[OTP_FEATURE_LENGTH] = { 0x0C, 0x00, 0x00, 0x00,
-                                               0x00, 0x00, 0x00, 0x00 };
+       char supp_feat[OTP_FEATURE_LENGTH] = { 0x08, 0x00, 0x00, 0x00,
+                                               0x80, 0x00, 0x00, 0x00 };
 
        ret = bluetooth_gatt_init();
        if (ret != BLUETOOTH_ERROR_NONE) {
index c017876..162e94a 100644 (file)
@@ -2359,6 +2359,54 @@ int __bt_bluez_request(int function_name,
                result = bt_otp_server_deinit(request_id);
                break;
        }
+       case BT_OTP_READ_VALUE: {
+               char *handle;
+               char *data = NULL;
+               guint data_len = 0;
+
+               char *sender = NULL;
+               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("Read OTP Characteristic Value [%s]", handle);
+
+               result = _bt_otp_read_characteristic_value(request_id, sender, handle);
+
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Reading OTP Characteristic Value failed result [%d]", result);
+                       g_array_append_vals(*out_param1, handle, data_len);
+               }
+               if (handle)
+                       g_free(handle);
+               break;
+       }
+       case BT_OTP_ENABLE_NOTIFICATION: {
+               char *handle;
+               char *data = NULL;
+               guint data_len = 0;
+
+               char *sender = NULL;
+               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 Control point CCCD handle [%s]", handle);
+
+               result = _bt_otp_enable_notification(request_id, sender, handle);
+
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Enabling OTP CCCD 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;
@@ -3205,6 +3253,8 @@ gboolean __bt_service_check_privilege(int function_name,
        /* OTP Server */
        case BT_OTP_SERVER_INIT:
        case BT_OTP_SERVER_DEINIT:
+       case BT_OTP_READ_VALUE:
+       case BT_OTP_ENABLE_NOTIFICATION:
 
        case BT_MAP_CREATE_SESSION:
        case BT_MAP_DESTROY_SESSION:
index 158e910..8ba8847 100644 (file)
@@ -508,6 +508,9 @@ int _bt_send_event_to_dest(const char* dest, int event_type,
        case BT_TDS_EVENT:
                path = BT_TDS_PATH;
                break;
+       case BT_OTP_EVENT:
+               path = BT_OTP_PATH;
+               break;
        default:
                BT_ERR("Unknown event");
                return BLUETOOTH_ERROR_INTERNAL;
@@ -550,6 +553,12 @@ int _bt_send_event_to_dest(const char* dest, int event_type,
        case BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT:
                signal = BT_TDS_ACTIVATION_RESULT;
                break;
+       case BLUETOOTH_EVENT_OTP_READ_CHAR_VAL:
+               signal = BT_OTP_READ_CHAR_VAL;
+               break;
+       case BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED:
+               signal = BT_OTP_NOTIFICATION_ENABLED;
+               break;
        default:
                BT_ERR("Unknown event");
                return BLUETOOTH_ERROR_INTERNAL;
index c46edfa..3e49707 100644 (file)
 
 #define BT_OTP_BASE_DIR_PATH "/home/owner/media/otp/"
 
+#define GATT_CHAR_INTERFACE             "org.bluez.GattCharacteristic1"
+
+#define GATT_DEFAULT_TIMEOUT  (6 * 1000) /* Dependent on supervision timeout 6 sec */
+
+/* OTP Notification Request structure */
+typedef struct {
+       char *handle;
+       char *sender;
+       int req_id;
+} bt_otp_notification_info;
+
+/* OTP transport specific data read Request info structure */
+typedef struct {
+       char *handle;
+       char *sender;
+       int req_id;
+} bt_otp_read_req_info;
+
+static GSList *otp_read_req_info_list = NULL;
+
+static GSList *otp_notification_info_list = NULL;
+
 static GDBusProxy *otp_gproxy;
 
 static GDBusProxy *_bt_core_gdbus_init_otp_proxy(void)
@@ -116,7 +138,7 @@ void server_init_cb(GObject *object, GAsyncResult *res,
                BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED,
                param);
 
-       out_param = g_variant_new_from_data((const GVariantType *)"i",
+       out_param = g_variant_new_from_data((const GVariantType*)"i",
                                result, sizeof(int), TRUE, NULL, NULL);
 
        if (req_info) {
@@ -125,6 +147,7 @@ void server_init_cb(GObject *object, GAsyncResult *res,
 
                _bt_delete_request_list(req_info->req_id);
        }
+
        g_variant_unref(result);
 }
 
@@ -194,7 +217,7 @@ void server_deinit_cb(GObject *object, GAsyncResult *res,
                        param);
 
        if (req_info) {
-               out_param = g_variant_new_from_data((const GVariantType *)"i",
+               out_param = g_variant_new_from_data((const GVariantType*)"i",
                                result, sizeof(int), TRUE, NULL, NULL);
 
                g_dbus_method_invocation_return_value(req_info->context,
@@ -231,3 +254,349 @@ int bt_otp_server_deinit(int request_id)
        BT_DBG("-");
        return BLUETOOTH_ERROR_NONE;
 }
+
+int __get_handle_length(char *handle)
+{
+       int i = 0;
+       while (handle && (handle[i] != '\0')) {
+               i++;
+       }
+       return i;
+}
+
+static bt_otp_read_req_info *__bt_otp_get_read_info(char *handle)
+{
+       GSList *l;
+       bt_otp_read_req_info *info = NULL;
+       BT_INFO("Found waiting for OTP Read from charc handle[%s]", handle);
+       for (l = otp_read_req_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (bt_otp_read_req_info *)l->data;
+               if (info == NULL)
+                       continue;
+
+               if (!g_strcmp0(info->handle, handle)) {
+                       BT_INFO("Found waiting for OTP Read from remote addr[%s]",
+                                       info->handle);
+                       return info;
+               }
+       }
+       return NULL;
+}
+
+static void __bt_otp_remove_read_info(bt_otp_read_req_info *info)
+{
+       BT_DBG("Removing Read Req Info [%s]", info->handle);
+
+       otp_read_req_info_list = g_slist_remove(otp_read_req_info_list, info);
+       if (info->handle)
+               g_free(info->handle);
+       if (info->sender)
+               g_free(info->sender);
+       g_free(info);
+}
+
+static void __bt_otp_read_char_cb(GObject *source_object,
+                       GAsyncResult *res, gpointer user_data)
+{
+       bt_gatt_char_descriptor_property_t att_value =  { 0, };
+       GDBusConnection *system_gconn = NULL;
+       GVariant *var_data, *param = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_otp_read_req_info *info = NULL;
+       GByteArray *gp_byte_array = NULL;
+       request_info_t *req_info = NULL;
+       GVariantIter *iter = NULL;
+       GVariant *value = NULL;
+       char *otp_data = NULL;
+       GVariant *out_param1;
+       GError *error = NULL;
+       guint8 g_byte;
+       char *handle;
+
+       BT_DBG("+");
+       system_gconn = _bt_gdbus_get_system_gconn();
+
+       handle = (char *)user_data;
+       info = __bt_otp_get_read_info(handle);
+
+       value = g_dbus_connection_call_finish(system_gconn, res, &error);
+
+       if (error) {
+               BT_ERR("Error : %s \n", error->message);
+               g_free(handle);
+               if (info) {
+                       req_info = _bt_get_request_info(info->req_id);
+                       __bt_otp_remove_read_info(info);
+               }
+               result = BLUETOOTH_ERROR_INTERNAL;
+               goto dbus_return;
+       }
+
+       gp_byte_array = g_byte_array_new();
+       g_variant_get(value, "(ay)", &iter);
+
+       while (g_variant_iter_loop(iter, "y",  &g_byte))
+               g_byte_array_append(gp_byte_array, &g_byte, 1);
+
+       if (gp_byte_array->len != 0) {
+               att_value.val_len = (unsigned int)gp_byte_array->len;
+               att_value.val = (unsigned char *)gp_byte_array->data;
+       }
+
+       otp_data = (char *)g_memdup(att_value.val, att_value.val_len);
+
+       var_data = g_variant_new_from_data((const GVariantType*)"ay",
+                       otp_data, att_value.val_len, TRUE, NULL, NULL);
+
+       if (info) {
+               param = g_variant_new("(isn@ay)", result, handle, att_value.val_len, var_data);
+               _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
+                               BLUETOOTH_EVENT_OTP_READ_CHAR_VAL,
+                               param);
+               req_info = _bt_get_request_info(info->req_id);
+               __bt_otp_remove_read_info(info);
+       }
+
+dbus_return:
+       if (req_info == NULL) {
+               BT_ERR("OTP data read Request 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:
+       /* Data free */
+       if (error)
+               g_clear_error(&error);
+       if (gp_byte_array)
+               g_byte_array_free(gp_byte_array, TRUE);
+       if (handle)
+               g_free(handle);
+       if (value)
+               g_variant_unref(value);
+       if (iter)
+               g_variant_iter_free(iter);
+       if (otp_data)
+               g_free(otp_data);
+       BT_DBG("-");
+}
+
+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);
+       guint16 offset = 0;
+
+       BT_CHECK_PARAMETER(handle, return);
+       BT_CHECK_PARAMETER(sender, return);
+
+       conn = _bt_gdbus_get_system_gconn();
+       retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_DBG("Read OTP Characteristic from server handle [%s]", handle);
+
+       /* If OTP data read already pending on same Server, then return In progress */
+       if (__bt_otp_get_read_info(handle) != NULL) {
+               BT_ERR("Read Req is ongoing in remote server [%s]", charc_handle);
+               g_free(charc_handle);
+               return BLUETOOTH_ERROR_IN_PROGRESS;
+       }
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       /*offset*/
+       g_variant_builder_add(builder, "{sv}", "offset",
+               g_variant_new("q", offset));
+
+       g_dbus_connection_call(conn,
+                       BT_BLUEZ_NAME,
+                       handle,
+                       GATT_CHAR_INTERFACE,
+                       "ReadValue",
+                       g_variant_new("(a{sv})", builder),
+                       G_VARIANT_TYPE("(ay)"),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       (GAsyncReadyCallback)__bt_otp_read_char_cb,
+                       (gpointer)charc_handle);
+
+       /* Save Info in pending list */
+       info = g_malloc0(sizeof(bt_otp_read_req_info));
+       info->handle = g_strdup(handle);
+       BT_INFO("Found waiting for OTP Read from charc handle[%s] [%s]", info->handle, handle);
+       info->sender = g_strdup(sender);
+       info->req_id = request_id;
+       otp_read_req_info_list = g_slist_append(otp_read_req_info_list, info);
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static bt_otp_notification_info *__bt_otp_get_notification_info(char *handle)
+{
+       GSList *l;
+       bt_otp_notification_info *info = NULL;
+
+       for (l = otp_notification_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (bt_otp_notification_info *)l->data;
+               if (info == NULL)
+                       continue;
+
+               if (!g_strcmp0(info->handle, handle)) {
+                       BT_INFO("Found waiting for Ind from Server addr[%s]",
+                                       info->handle);
+                               return info;
+               }
+       }
+       return NULL;
+}
+
+static void __bt_otp_remove_notification_info(bt_otp_notification_info *info)
+{
+       BT_DBG("Removing Notification Info [%s]", info->handle);
+
+       otp_notification_info_list = g_slist_remove(otp_notification_info_list, info);
+       if (info->handle)
+               g_free(info->handle);
+       if (info->sender)
+               g_free(info->sender);
+       g_free(info);
+}
+
+static void __bt_otp_notification_enable_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);
+               if (g_strrstr(error->message, "Already notifying"))
+                       result = BLUETOOTH_ERROR_NONE;
+               else if (g_strrstr(error->message, "In Progress"))
+                       result = BLUETOOTH_ERROR_IN_PROGRESS;
+               else if (g_strrstr(error->message, "Operation is not supported"))
+                       result = BLUETOOTH_ERROR_NOT_SUPPORT;
+               else if (g_strrstr(error->message, "Write not permitted") ||
+                               g_strrstr(error->message, "Operation Not Authorized"))
+                       result = BLUETOOTH_ERROR_PERMISSION_DEINED;
+               else if (g_strrstr(error->message, "Not paired"))
+                       result = BLUETOOTH_ERROR_NOT_PAIRED;
+               else
+                       result = BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               BT_DBG("OTP CCCD enable request successful, send event to BT App");
+       }
+
+       handle = (char *)user_data;
+       info = __bt_otp_get_notification_info(handle);
+
+       if (info)
+               req_info = _bt_get_request_info(info->req_id);
+
+       /* CCCD Enable request failed */
+       if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
+               BT_ERR("Activation Request failed");
+               /* Remove Indication Info */
+               __bt_otp_remove_notification_info(info);
+       } else {
+               /* CCCD Enable Request successful */
+               if (info) {
+                       param = g_variant_new("(is)", result, handle);
+                       _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
+                                       BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED,
+                                       param);
+               }
+       }
+
+       if (req_info == NULL) {
+               BT_ERR("OTP Control Point CCCD Enable 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;
+}
+
+int _bt_otp_enable_notification(int request_id, char *sender, char *handle)
+{
+       bt_otp_notification_info *info = NULL;
+       char *charc_handle = g_strdup(handle);
+       GDBusConnection *conn;
+
+       BT_CHECK_PARAMETER(handle, return);
+       BT_CHECK_PARAMETER(sender, return);
+
+       conn = _bt_gdbus_get_system_gconn();
+       retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_DBG("OTP Control point CCCD Handle [%s]", handle);
+
+       if (__bt_otp_get_notification_info(handle) != NULL) {
+               BT_ERR("Activation is already ongoing for same remote server");
+               g_free(charc_handle);
+               return BLUETOOTH_ERROR_IN_PROGRESS;
+       }
+
+       BT_INFO("Start Notify to Bluez");
+       g_dbus_connection_call(conn,
+                       BT_BLUEZ_NAME,
+                       handle,
+                       GATT_CHAR_INTERFACE,
+                       "StartNotify",
+                       NULL,
+                       NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       GATT_DEFAULT_TIMEOUT, NULL,
+                       (GAsyncReadyCallback)__bt_otp_notification_enable_request_cb,
+                       (gpointer)charc_handle);
+
+       info = g_malloc0(sizeof(bt_otp_notification_info));
+       info->handle = g_strdup(handle);
+       info->sender = g_strdup(sender);
+       info->req_id = request_id;
+       otp_notification_info_list = g_slist_append(otp_notification_info_list, info);
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
index b952ec1..b525e18 100644 (file)
@@ -30,6 +30,10 @@ int bt_otp_server_init(int request_id, const char *directory);
 
 int bt_otp_server_deinit(int request_id);
 
+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);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index c35f4dd..3eab8cb 100644 (file)
@@ -506,6 +506,15 @@ typedef struct {
 } bluetooth_tds_transport_data_info_t;
 
 /**
+* Structure to hold the OTP response data from remote OTP server
+*/
+typedef struct {
+       char *handle;      /**< Handle */
+       int data_length;                        /**< Data length */
+       char *data;                             /**< Read data */
+} bluetooth_otp_resp_info_t;
+
+/**
 * Advertising parameters
 */
 typedef struct {
@@ -822,6 +831,8 @@ typedef enum {
        BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION,    /** TDS Activation Indication from Provider */
 
        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_type_t;
 
  /**
@@ -7569,6 +7580,10 @@ int bluetooth_otp_server_init(const char *directory);
  */
 int bluetooth_otp_server_deinit();
 
+int bluetooth_otp_enable_notification(const char *handle);
+
+int bluetooth_otp_read_characteristic_value(const char *handle);
+
 /**
  * @}
  */
index 3992147..c5469cd 100644 (file)
@@ -383,6 +383,8 @@ typedef enum {
        BT_TDS_ACTIVATE_CONTROL_POINT,
        BT_OTP_SERVER_INIT = BT_FUNC_OTP_BASE,
        BT_OTP_SERVER_DEINIT,
+       BT_OTP_READ_VALUE,
+       BT_OTP_ENABLE_NOTIFICATION,
 } bt_function_t;
 
 typedef struct {
@@ -561,6 +563,8 @@ typedef struct {
 
 /* OTP */
 #define BT_OTP_SERVER_STATE_CHANGED "OtpServerStateChanged"
+#define BT_OTP_READ_CHAR_VAL "OtpReadCharVal"
+#define BT_OTP_NOTIFICATION_ENABLED "OtpNotificationEnabled"
 
 typedef enum {
        _PROFILE_UNKNOWN = 0,