[OTP] Handle Object Select request
[platform/core/connectivity/bluetooth-frwk.git] / bt-otp / bt-otpserver.c
index e59b134..c8e372b 100644 (file)
@@ -1063,12 +1063,29 @@ void update_obj_metadata_charc_value(struct object_metadata *object)
        _bt_otp_set_char_value(otp_object_prop_obj_path, value, 4);
 }
 
+struct object_metadata *_bt_otp_client_find_object(GSList *list, uint64_t id, guint *index)
+{
+       GSList *l;
+       struct object_metadata *info;
+
+       for (l = list; l; l = g_slist_next(l)) {
+               (*index)++;
+               info = l->data;
+
+               if (info && (info->id == id))
+                       return info;
+       }
+       return NULL;
+}
+
 int _bt_otp_olcp_write_cb(char *value, int len, int offset,
                                        struct indicate_info *info)
 {
        int ret = OLCP_SUCCESS;
        int opcode = value[0];
        struct object_metadata *object;
+       uint64_t object_id;
+       guint index = 0;
 
        BT_INFO("OLCP Opcode 0x%d", opcode);
 
@@ -1078,7 +1095,7 @@ int _bt_otp_olcp_write_cb(char *value, int len, int offset,
        }
 
        switch (opcode) {
-       case OLCP_FIRST: {
+       case OLCP_FIRST:
                object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
                if (!object) {
                        ret = OLCP_OUT_OF_BOUNDS;
@@ -1087,8 +1104,8 @@ int _bt_otp_olcp_write_cb(char *value, int len, int offset,
                update_obj_metadata_charc_value(object);
                selected_object = object;
                obj_curr_index = 0;
-       } break;
-       case OLCP_LAST: {
+               break;
+       case OLCP_LAST:
                len = g_slist_length(otp_object_list);
                object = (struct object_metadata *) g_slist_nth_data(otp_object_list, len-1);
                if (!object) {
@@ -1098,8 +1115,8 @@ int _bt_otp_olcp_write_cb(char *value, int len, int offset,
                update_obj_metadata_charc_value(object);
                selected_object = object;
                obj_curr_index = len-1;
-       } break;
-       case OLCP_PREVIOUS: {
+               break;
+       case OLCP_PREVIOUS:
                if (obj_curr_index == 0) {
                        ret = OLCP_OUT_OF_BOUNDS;
                        goto fail;
@@ -1112,8 +1129,8 @@ int _bt_otp_olcp_write_cb(char *value, int len, int offset,
                update_obj_metadata_charc_value(object);
                selected_object = object;
                obj_curr_index -= 1;
-       } break;
-       case OLCP_NEXT: {
+               break;
+       case OLCP_NEXT:
                object = (struct object_metadata *) g_slist_nth_data(otp_object_list, obj_curr_index+1);
                if (!object) {
                        ret = OLCP_OUT_OF_BOUNDS;
@@ -1122,8 +1139,27 @@ int _bt_otp_olcp_write_cb(char *value, int len, int offset,
                update_obj_metadata_charc_value(object);
                selected_object = object;
                obj_curr_index += 1;
-       } break;
+               break;
        case OLCP_GOTO:
+               object_id = (uint64_t)(value[6] & 0xFF) << 40 |
+                               (uint64_t)(value[5] & 0xFF) << 32 |
+                               (uint64_t)(value[4] & 0xFF) << 24 |
+                               (uint64_t)(value[3] & 0xFF) << 16 |
+                               (uint64_t)(value[2] & 0xFF) << 8  |
+                               (uint64_t)(value[1] & 0xFF);
+               BT_INFO("Object ID [%llu]", object_id);
+               if (selected_object && selected_object->id == object_id)
+                       goto fail;
+
+               object = _bt_otp_client_find_object(otp_object_list, object_id, &index);
+               if (!object) {
+                       ret = OLCP_OJECT_ID_NOT_FOUND;
+                       goto fail;
+               }
+               update_obj_metadata_charc_value(object);
+               selected_object = object;
+               obj_curr_index = index - 1;
+               break;
        case OLCP_ORDER:
        case OLCP_REQ_NO_OBJ:
        case OLCP_CLEAR_MARKING: