Merge "[Bluetooth][OTP] Add object browsing support" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-otp / bt-otpserver.c
index 1d2bb31..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)
 {
@@ -263,8 +265,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) {
@@ -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");
@@ -669,13 +691,15 @@ void convert_to_hex(struct object_metadata *object, char *type, char *value)
 
                localtime_r(&(object->first_created), tm);
 
-               value[1] = ((tm->tm_year+1900) >> 8) & 0xFF;
-               value[0] = (tm->tm_year+1900) & 0xFF;
-               value[2] = (tm->tm_mon+1) & 0xFF;
-               value[3] = tm->tm_mday & 0xFF;
-               value[4] = tm->tm_hour & 0xFF;
-               value[5] = tm->tm_min & 0xFF;
-               value[6] = tm->tm_sec & 0xFF;
+               if (tm) {
+                       value[1] = ((tm->tm_year+1900) >> 8) & 0xFF;
+                       value[0] = (tm->tm_year+1900) & 0xFF;
+                       value[2] = (tm->tm_mon+1) & 0xFF;
+                       value[3] = tm->tm_mday & 0xFF;
+                       value[4] = tm->tm_hour & 0xFF;
+                       value[5] = tm->tm_min & 0xFF;
+                       value[6] = tm->tm_sec & 0xFF;
+               }
 
        } else if (!g_strcmp0(type, "id")) {
 
@@ -711,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);