[OTP] Handle Object Delete request
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-avrcp.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <gio/gio.h>
19 #include <glib.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <syspopup_caller.h>
23
24 #include "bluetooth-api.h"
25 #include "bt-internal-types.h"
26 #include "bt-service-common.h"
27 #include "bt-service-avrcp.h"
28 #include "bt-service-event.h"
29 #include "bt-service-util.h"
30 #include "bt-service-audio.h"
31
32 static bt_player_settinngs_t loopstatus_settings[] = {
33         { REPEAT_INVALID, "" },
34         { REPEAT_MODE_OFF, "None" },
35         { REPEAT_SINGLE_TRACK, "Track" },
36         { REPEAT_ALL_TRACK, "Playlist" },
37         { REPEAT_INVALID, "" }
38 };
39
40 static bt_player_settinngs_t shuffle_settings[] = {
41         { SHUFFLE_INVALID, "" },
42         { SHUFFLE_MODE_OFF, "off" },
43         { SHUFFLE_ALL_TRACK, "alltracks" },
44         { SHUFFLE_GROUP, "group" },
45         { SHUFFLE_INVALID, "" }
46 };
47
48 static bt_player_settinngs_t player_status[] = {
49         { STATUS_STOPPED, "stopped" },
50         { STATUS_PLAYING, "playing" },
51         { STATUS_PAUSED, "paused" },
52         { STATUS_FORWARD_SEEK, "forward-seek" },
53         { STATUS_REVERSE_SEEK, "reverse-seek" },
54         { STATUS_ERROR, "error" },
55         { STATUS_INVALID, "" }
56 };
57
58 static guint avrcp_reg_id = 0;
59
60 /* Introspection data exposed from bt-service */
61 static const gchar bt_avrcp_bluez_introspection_xml[] =
62 "<node name='/'>"
63 " <interface name='org.freedesktop.DBus.Properties'>"
64 "     <method name='Set'>"
65 "          <arg type='s' name='interface' direction='in'/>"
66 "          <arg type='s' name='property' direction='in'/>"
67 "          <arg type='v' name='value' direction='in'/>"
68 "     </method>"
69 " </interface>"
70 "</node>";
71
72 static gboolean __bt_media_emit_property_changed(GDBusConnection *connection,
73                 const char *path, const char *interface, const char *name,
74                 const GVariant *variant)
75 {
76         GVariantBuilder *builder = NULL;
77         GError *error = NULL;
78
79         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
80         g_variant_builder_add(builder, "{sv}", name, variant);
81
82         g_dbus_connection_emit_signal(connection, NULL, path,
83                                 BT_PROPERTIES_INTERFACE,
84                                 "PropertiesChanged",
85                                 g_variant_new("(sa{sv})",
86                                 interface, builder),
87                                 &error);
88
89         g_variant_builder_unref(builder);
90         if (error) {
91                 BT_ERR("Could not Emit PropertiesChanged Signal: errCode[%x], message[%s]",
92                         error->code, error->message);
93                 g_clear_error(&error);
94                 return FALSE;
95         }
96
97         return TRUE;
98 }
99
100 static GQuark __bt_avrcp_error_quark(void)
101 {
102         static GQuark quark = 0;
103
104         if (!quark)
105                 quark = g_quark_from_static_string("bt-avrcp");
106
107         return quark;
108 }
109
110 static GError *__bt_avrcp_set_error(bt_avrcp_error_t error)
111 {
112         BT_ERR("error[%d]\n", error);
113
114         switch (error) {
115         case BT_AVRCP_ERROR_INVALID_PARAM:
116                 return g_error_new(BT_AVRCP_ERROR, error,
117                                 BT_ERROR_INVALID_PARAM);
118         case BT_AVRCP_ERROR_INVALID_INTERFACE:
119                 return g_error_new(BT_AVRCP_ERROR, error,
120                                 BT_ERROR_INVALID_INTERFACE);
121         case BT_AVRCP_ERROR_INTERNAL:
122         default:
123                 return g_error_new(BT_AVRCP_ERROR, error,
124                                 BT_ERROR_INTERNAL);
125         }
126 }
127
128 static void __bt_avrcp_agent_method(GDBusConnection *connection,
129                 const gchar *sender,
130                 const gchar *object_path,
131                 const gchar *interface_name,
132                 const gchar *method_name,
133                 GVariant *parameters,
134                 GDBusMethodInvocation *invocation,
135                 gpointer user_data)
136 {
137         BT_DBG("+");
138         BT_INFO("method %s", method_name);
139         BT_INFO("object_path %s", object_path);
140         int ret = BT_AVRCP_ERROR_NONE;
141         GError *err = NULL;
142         gboolean shuffle_status;
143         guint32 status;
144         gchar *interface = NULL;
145         gchar *property = NULL;
146         gchar *loop_status = NULL;
147         GVariant *value = NULL;
148
149         if (g_strcmp0(method_name, "Set") == 0) {
150                 g_variant_get(parameters, "(&s&sv)", &interface, &property,
151                                 &value);
152
153                 if (g_strcmp0(interface, BT_MEDIA_PLAYER_INTERFACE) != 0) {
154                         ret = BT_AVRCP_ERROR_INVALID_INTERFACE;
155                         goto fail;
156                 }
157         }
158
159         if (value == NULL) {
160                 BT_ERR("value is NULL");
161                 goto fail;
162         }
163
164         BT_DBG("Property: %s\n", property);
165         if (g_strcmp0(property, "Shuffle") == 0) {
166
167                 if (!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
168                         BT_ERR("Error");
169                         ret = BT_AVRCP_ERROR_INVALID_PARAM;
170                         goto fail;
171                 }
172
173                 shuffle_status = g_variant_get_boolean(value);
174                 BT_DBG("Value: %s\n", shuffle_status ? "TRUE" : "FALSE");
175                 if (shuffle_status == TRUE)
176                         status = SHUFFLE_ALL_TRACK;
177                 else
178                         status = SHUFFLE_MODE_OFF;
179
180                 _bt_send_event(BT_AVRCP_EVENT,
181                                 BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
182                                 g_variant_new("(u)", status));
183         } else if (g_strcmp0(property, "LoopStatus") == 0) {
184
185                 if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
186                         BT_ERR("Error");
187                         ret = BT_AVRCP_ERROR_INVALID_PARAM;
188                         goto fail;
189                 }
190
191                 loop_status = (gchar *)g_variant_get_string(value, NULL);
192                 BT_DBG("Value: %s\n", loop_status);
193
194                 if (g_strcmp0(loop_status, "Track") == 0)
195                         status = REPEAT_SINGLE_TRACK;
196                 else if (g_strcmp0(loop_status, "Playlist") == 0)
197                         status = REPEAT_ALL_TRACK;
198                 else if (g_strcmp0(loop_status, "None") == 0)
199                         status = REPEAT_MODE_OFF;
200                 else
201                         status = REPEAT_INVALID;
202
203                 _bt_send_event(BT_AVRCP_EVENT,
204                                 BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
205                                 g_variant_new("(u)", status));
206         }
207
208         BT_DBG("-");
209         return;
210
211 fail:
212         if (value)
213                 g_variant_unref(value);
214         err = __bt_avrcp_set_error(ret);
215         g_dbus_method_invocation_return_gerror(invocation, err);
216         g_clear_error(&err);
217         BT_INFO("-");
218 }
219
220 static const GDBusInterfaceVTable method_table = {
221         __bt_avrcp_agent_method,
222         NULL,
223         NULL,
224 };
225
226 static GDBusNodeInfo *__bt_avrcp_create_method_node_info
227                                 (const gchar *introspection_data)
228 {
229         GError *err = NULL;
230         GDBusNodeInfo *node_info = NULL;
231
232         if (introspection_data == NULL)
233                 return NULL;
234
235         node_info = g_dbus_node_info_new_for_xml(introspection_data, &err);
236
237         if (err) {
238                 BT_ERR("Unable to create node: %s", err->message);
239                 g_clear_error(&err);
240         }
241
242         return node_info;
243 }
244
245 int _bt_register_media_player(void)
246 {
247         BT_DBG("+");
248         GDBusConnection *g_conn;
249         gchar *adapter_path;
250         gboolean shuffle_status;
251         gchar *path;
252         GDBusNodeInfo *node_info;
253         GDBusProxy *proxy;
254         GVariantBuilder *builder;
255         GVariant *ret;
256         GError *error = NULL;
257
258         media_player_settings_t player_settings = {0,};
259
260         player_settings.repeat  = REPEAT_MODE_OFF;
261         player_settings.status = STATUS_STOPPED;
262         player_settings.position = 0;
263         shuffle_status = FALSE;
264
265         g_conn = _bt_gdbus_get_system_gconn();
266         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
267
268         node_info = __bt_avrcp_create_method_node_info(
269                                 bt_avrcp_bluez_introspection_xml);
270         if (node_info == NULL)
271                 return BLUETOOTH_ERROR_INTERNAL;
272
273         avrcp_reg_id = g_dbus_connection_register_object(g_conn,
274                                         BT_MEDIA_OBJECT_PATH,
275                                         node_info->interfaces[0],
276                                         &method_table,
277                                         NULL, NULL, &error);
278         g_dbus_node_info_unref(node_info);
279
280         if (avrcp_reg_id == 0) {
281                 BT_ERR("Failed to register: %s", error->message);
282                 g_clear_error(&error);
283                 return BLUETOOTH_ERROR_INTERNAL;
284         }
285
286         adapter_path = _bt_get_adapter_path();
287         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
288
289         proxy =  g_dbus_proxy_new_sync(g_conn,
290                         G_DBUS_PROXY_FLAGS_NONE, NULL,
291                         BT_BLUEZ_NAME, adapter_path,
292                         BT_MEDIA_INTERFACE, NULL, &error);
293         g_free(adapter_path);
294
295         if (proxy == NULL) {
296                 BT_ERR("Unable to create proxy");
297                 if (error) {
298                         BT_ERR("Error: %s", error->message);
299                         g_clear_error(&error);
300                 }
301                 return BLUETOOTH_ERROR_INTERNAL;
302         }
303
304         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
305
306         g_variant_builder_add(builder, "{sv}", "LoopStatus",
307                         g_variant_new("s",
308                         loopstatus_settings[player_settings.repeat].property));
309         BT_ERR("LoopStatus: %s", loopstatus_settings[player_settings.repeat].property);
310
311         g_variant_builder_add(builder, "{sv}", "Shuffle",
312                         g_variant_new("b", shuffle_status));
313
314         g_variant_builder_add(builder, "{sv}", "PlaybackStatus",
315                         g_variant_new("s",
316                         player_status[player_settings.status].property));
317         BT_ERR("PlaybackStatus: %s", player_status[player_settings.status].property);
318
319         g_variant_builder_add(builder, "{sv}", "Position",
320                         g_variant_new("u", player_settings.position));
321
322         path = g_strdup(BT_MEDIA_OBJECT_PATH);
323         ret = g_dbus_proxy_call_sync(proxy, "RegisterPlayer",
324                         g_variant_new("(oa{sv})", path, builder),
325                         G_DBUS_CALL_FLAGS_NONE, -1,
326                         NULL, &error);
327
328         g_object_unref(proxy);
329         g_free(path);
330         g_variant_builder_unref(builder);
331
332         if (ret == NULL) {
333                 BT_ERR("Call RegisterPlayer Failed");
334                 if (error) {
335                         BT_ERR("errCode[%x], message[%s]",
336                                         error->code, error->message);
337                         g_clear_error(&error);
338                 }
339                 return BLUETOOTH_ERROR_INTERNAL;
340         }
341
342         g_variant_unref(ret);
343         return BLUETOOTH_ERROR_NONE;
344 }
345
346 static void __bt_avrcp_unregister_object_path(void)
347 {
348         GDBusConnection *g_conn;
349
350         g_conn = _bt_gdbus_get_system_gconn();
351         ret_if(g_conn == NULL);
352
353         if (avrcp_reg_id > 0) {
354                 g_dbus_connection_unregister_object(g_conn,
355                                                         avrcp_reg_id);
356                 avrcp_reg_id = 0;
357         }
358 }
359
360 int _bt_unregister_media_player(void)
361 {
362         BT_DBG("+");
363         GDBusConnection *g_conn;
364         GDBusProxy *proxy;
365         gchar *adapter_path;
366         GVariant *ret;
367         GError *error = NULL;
368         gchar *path;
369         int result = BLUETOOTH_ERROR_NONE;
370
371         adapter_path = _bt_get_adapter_path();
372         if (adapter_path == NULL) {
373                 result = BLUETOOTH_ERROR_INTERNAL;
374                 goto FAIL;
375         }
376
377         g_conn = _bt_gdbus_get_system_gconn();
378         if (g_conn == NULL) {
379                 BT_ERR("g_conn is NULL");
380                 g_free(adapter_path);
381                 result = BLUETOOTH_ERROR_INTERNAL;
382                 goto FAIL;
383         }
384
385         proxy =  g_dbus_proxy_new_sync(g_conn,
386                         G_DBUS_PROXY_FLAGS_NONE, NULL,
387                         BT_BLUEZ_NAME, adapter_path,
388                         BT_MEDIA_INTERFACE, NULL, &error);
389         g_free(adapter_path);
390
391         if (proxy == NULL) {
392                 BT_ERR("Unable to create proxy");
393                 if (error) {
394                         BT_ERR("Error: %s", error->message);
395                         g_clear_error(&error);
396                 }
397                 result = BLUETOOTH_ERROR_INTERNAL;
398                 goto FAIL;
399         }
400
401         path = g_strdup(BT_MEDIA_OBJECT_PATH);
402         BT_DBG("path is [%s]", path);
403
404         ret = g_dbus_proxy_call_sync(proxy, "UnregisterPlayer",
405                         g_variant_new("(o)", path),
406                         G_DBUS_CALL_FLAGS_NONE, -1,
407                         NULL, &error);
408         g_free(path);
409         g_object_unref(proxy);
410
411         if (ret == NULL) {
412                 BT_ERR("UnregisterPlayer failed");
413                 if (error) {
414                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
415                                         error->code, error->message);
416                         g_clear_error(&error);
417                 }
418                 result = BLUETOOTH_ERROR_INTERNAL;
419         }
420         g_variant_unref(ret);
421
422 FAIL:
423         __bt_avrcp_unregister_object_path();
424
425         BT_DBG("-");
426         return result;
427 }
428
429 int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
430 {
431         BT_DBG("+");
432         char *interface = BT_MEDIA_PLAYER_INTERFACE;
433         GDBusConnection *g_conn;
434         GError *error = NULL;
435         GVariantBuilder *builder = NULL;
436         GVariantBuilder *inner_builder = NULL;
437         GVariant *children[1];
438         gboolean ret;
439
440         retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
441
442         g_conn = _bt_gdbus_get_system_gconn();;
443         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
444
445         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
446         inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
447
448         g_variant_builder_add(inner_builder, "{sv}",
449                 "xesam:title", g_variant_new_string(meta_data->title));
450
451         children[0] = g_variant_new_string(meta_data->artist);
452         g_variant_builder_add(inner_builder, "{sv}",
453                 "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
454                 children, 1));
455
456         g_variant_builder_add(inner_builder, "{sv}",
457                 "xesam:album", g_variant_new_string(meta_data->album));
458
459         children[0] = g_variant_new_string(meta_data->genre);
460         g_variant_builder_add(inner_builder, "{sv}",
461                 "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
462                 children, 1));
463
464         g_variant_builder_add(inner_builder, "{sv}",
465                 "xesam:totalTracks", g_variant_new_int32(meta_data->total_tracks));
466
467         g_variant_builder_add(inner_builder, "{sv}",
468                 "xesam:trackNumber", g_variant_new_int32(meta_data->number));
469
470         g_variant_builder_add(inner_builder, "{sv}",
471                 "mpris:length", g_variant_new_int64(meta_data->duration));
472
473         g_variant_builder_add(builder, "{sv}",
474                 "Metadata", g_variant_new("a{sv}", inner_builder));
475
476         ret = g_dbus_connection_emit_signal(g_conn, NULL, BT_MEDIA_OBJECT_PATH,
477                                 BT_PROPERTIES_INTERFACE,
478                                 "PropertiesChanged",
479                                 g_variant_new("(sa{sv})",
480                                 interface, builder),
481                                 &error);
482
483         g_variant_builder_unref(inner_builder);
484         g_variant_builder_unref(builder);
485
486         if (!ret) {
487                 if (error != NULL) {
488                         BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
489                                 error->code, error->message);
490                         g_clear_error(&error);
491                 }
492         }
493
494         BT_DBG("-");
495         return BLUETOOTH_ERROR_NONE;
496 }
497
498 int _bt_avrcp_set_interal_property(int type, media_player_settings_t *properties)
499 {
500         BT_DBG("+");
501         GDBusConnection *g_conn;
502         int value;
503         media_metadata_attributes_t meta_data;
504         gboolean shuffle;
505         GVariantBuilder *builder = NULL;
506         GVariant *children[1];
507
508         g_conn = _bt_gdbus_get_system_gconn();;
509         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
510
511         switch (type) {
512         case REPEAT:
513                 value = properties->repeat;
514                 if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
515                                 BT_MEDIA_PLAYER_INTERFACE, "LoopStatus",
516                                 g_variant_new_string(loopstatus_settings[value].property))) {
517                         BT_ERR("Error sending the PropertyChanged signal \n");
518                         return BLUETOOTH_ERROR_INTERNAL;
519                 }
520                 break;
521         case SHUFFLE:
522                 value = properties->shuffle;
523                 if (g_strcmp0(shuffle_settings[value].property, "off") == 0)
524                         shuffle = FALSE;
525                 else
526                         shuffle = TRUE;
527
528                 if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
529                                 BT_MEDIA_PLAYER_INTERFACE, "Shuffle",
530                                 g_variant_new_boolean(shuffle))) {
531                         BT_ERR("Error sending the PropertyChanged signal \n");
532                         return BLUETOOTH_ERROR_INTERNAL;
533                 }
534                 break;
535         case STATUS:
536                 value = properties->status;
537                 if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
538                                 BT_MEDIA_PLAYER_INTERFACE, "PlaybackStatus",
539                                 g_variant_new_string(player_status[value].property))) {
540                         BT_ERR("Error sending the PropertyChanged signal \n");
541                         return BLUETOOTH_ERROR_INTERNAL;
542                 }
543                 break;
544         case POSITION:
545                 value = properties->position;
546                 if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
547                                 BT_MEDIA_PLAYER_INTERFACE, "Position",
548                                 g_variant_new_uint32(value))) {
549                         BT_ERR("Error sending the PropertyChanged signal \n");
550                         return BLUETOOTH_ERROR_INTERNAL;
551                 }
552                 break;
553         case METADATA:
554                 meta_data = properties->metadata;
555
556                 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
557                 g_variant_builder_add(builder, "{sv}",
558                                 "xesam:title", g_variant_new_string(meta_data.title));
559
560                 children[0] = g_variant_new_string(meta_data.artist);
561                 g_variant_builder_add(builder, "{sv}",
562                                 "xesam:artist", g_variant_new_array(G_VARIANT_TYPE_STRING,
563                                                 children, 1));
564
565                 g_variant_builder_add(builder, "{sv}",
566                                 "xesam:album", g_variant_new_string(meta_data.album));
567
568                 children[0] = g_variant_new_string(meta_data.genre);
569                 g_variant_builder_add(builder, "{sv}",
570                                 "xesam:genre", g_variant_new_array(G_VARIANT_TYPE_STRING,
571                                                 children, 1));
572
573                 g_variant_builder_add(builder, "{sv}",
574                                 "xesam:totalTracks", g_variant_new_int32(meta_data.total_tracks));
575
576                 g_variant_builder_add(builder, "{sv}",
577                                 "xesam:trackNumber", g_variant_new_int32(meta_data.number));
578
579                 g_variant_builder_add(builder, "{sv}",
580                                 "mpris:length", g_variant_new_int64(meta_data.duration));
581
582                 if (!__bt_media_emit_property_changed(g_conn, BT_MEDIA_OBJECT_PATH,
583                                 BT_MEDIA_PLAYER_INTERFACE, "Metadata",
584                                 g_variant_new("a{sv}", builder))) {
585                         BT_ERR("Error sending the PropertyChanged signal \n");
586                         g_variant_builder_unref(builder);
587                         return BLUETOOTH_ERROR_INTERNAL;
588                 }
589                 g_variant_builder_unref(builder);
590                 break;
591         default:
592                 BT_ERR("Invalid Type\n");
593                 return BLUETOOTH_ERROR_INTERNAL;
594         }
595         BT_DBG("-");
596         return BLUETOOTH_ERROR_NONE;
597 }
598
599 int _bt_avrcp_set_properties(media_player_settings_t *properties)
600 {
601         BT_DBG("+");
602
603         if (_bt_avrcp_set_interal_property(REPEAT,
604                                 properties) != BLUETOOTH_ERROR_NONE) {
605                         return BLUETOOTH_ERROR_INTERNAL;
606         }
607         if (_bt_avrcp_set_interal_property(SHUFFLE,
608                         properties) != BLUETOOTH_ERROR_NONE) {
609                 return BLUETOOTH_ERROR_INTERNAL;
610         }
611
612         if (_bt_avrcp_set_interal_property(STATUS,
613                         properties) != BLUETOOTH_ERROR_NONE) {
614                 return BLUETOOTH_ERROR_INTERNAL;
615         }
616
617         if (_bt_avrcp_set_interal_property(POSITION,
618                         properties) != BLUETOOTH_ERROR_NONE) {
619                 return BLUETOOTH_ERROR_INTERNAL;
620         }
621
622         if (_bt_avrcp_set_interal_property(METADATA,
623                         properties) != BLUETOOTH_ERROR_NONE) {
624                 return BLUETOOTH_ERROR_INTERNAL;
625         }
626         BT_DBG("-");
627         return BLUETOOTH_ERROR_NONE;
628 }
629
630 int _bt_avrcp_set_property(int type, unsigned int value)
631 {
632         BT_DBG("+");
633         media_player_settings_t properties;
634
635         switch (type) {
636         case REPEAT:
637                 properties.repeat = value;
638                 break;
639         case SHUFFLE:
640                 properties.shuffle = value;
641                 break;
642         case STATUS:
643                 properties.status = value;
644                 break;
645         case POSITION:
646                 properties.position = value;
647                 break;
648         default:
649                 BT_DBG("Invalid Type\n");
650                 return BLUETOOTH_ERROR_INTERNAL;
651         }
652
653         if (_bt_avrcp_set_interal_property(type,
654                         &properties) != BLUETOOTH_ERROR_NONE)
655                 return BLUETOOTH_ERROR_INTERNAL;
656
657         BT_DBG("-");
658
659         return BLUETOOTH_ERROR_NONE;
660 }