Merge "[Bluetooth][OTP] Add object browsing support" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-otp / bt-otpserver.c
index cc514cb..9501f3e 100644 (file)
@@ -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[] =
 "<node name='/'>"
@@ -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");
@@ -713,8 +735,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);