1Bluetooth: Media Control Profile Shell
2######################################
3
4This document describes how to run the media control functionality,
5using the shell, both as a client and as a server.
6
7The media control server consists of to parts. There is a media
8player (mpl) that contains the logic to handle media, and there is a
9media control service (mcs) that serves as a GATT-based interface to
10the player. The media control client consists of one part, the GATT
11based client (mcc).
12
13The media control server may include an object transfer service (ots)
14and the media control client may include an object transfer client
15(otc). When these are included, a richer set of functionality is
16available.
17
18The media control server and client both implement the Generic Media
19Control Service (only), and do not use any underlying Media Control
20Services.
21
22Note that in the examples below, in many cases the debug output has
23been removed and long outputs may have been shortened to make the
24examples shorter and clearer.
25
26Also note that this documentation does not list all shell commands, it
27just shows examples of some of them. The set of commands is
28explorable from the mcc shell and the mpl shell, by typing :code:`mcc`
29or :code:`mpl` and pressing TAB.  A help text for each command can be
30found by doing :samp:`mcc {<command>} help` or :samp:`mpl {<command>} help`.
31
32Overview
33********
34
35A media player has a *name* and an *icon* that allows identification
36of the player for the user.
37
38The content of the media player is structured into tracks and groups.
39A media player has a number of groups. A group contains tracks and
40other groups. (In this implementation, a group only contains tracks,
41not other groups.) Tracks can be divided into segments.
42
43An active player will have a *current track*. This is the track that
44is playing now (if the player is playing). The current track has a
45*title*, a *duration* (given in hundredths of a second) and a
46*position* - the current position of the player within the track.
47
48There is also a *current group* (the group of the current track), a
49*parent group* (the parent group of the current group) and a *next
50track*.
51
52The media player is in a *state*, which will be one of playing,
53paused, seeking or inactive. When playing, playback happens at a
54given *playback speed*, and the tracks are played according to the
55*playing order*, which is one of the *playing orders supported*.
56Track changes are signalled as notifications of the *track changed*
57characteristic. When seeking (fast forward or fast rewind), the track
58position is moved according to the *seeking speed*.
59
60The *opcodes supported* tells which operations are supported by the
61player by writing to the *media control point*. There is also a
62*search control point* that allows to search for groups and tracks
63according to various criteria, with the result returned in the *search
64results*.
65
66Finally, the *content control ID* is used to associate the media
67player with an audio stream.
68
69
70Media Control Client (MCP)
71**************************
72
73The media control client is used to control, and to get information
74from, a media control server. Control is done by writing to one of
75the two control points, or by writing to other writable
76characteristics. Getting information is done by reading
77characteristics, or by configuring the server to send notifications.
78
79Using the media control client
80==============================
81
82Before use, the media control client must be initialized by the
83command :code:`mcc init`.
84
85To achieve a connection to the peer, the :code:`bt` commands must be
86used - :code:`bt init` followed by :code:`bt advertise on` (or
87:code:`bt connect` if the server is advertising).
88
89When the media control client is connected to a media control server,
90the client can discover the server's Generic Media Control Service, by
91giving the command :code:`mcc discover_mcs`. This will store the
92handles of the service, and (optionally, but default) subscribe to all
93notifications.
94
95After discovery, the media control client can read and write
96characteristics, including the media control point and the search
97control point.
98
99
100Example usage
101=============
102
103Setup
104-----
105
106.. code-block:: console
107
108   uart:~$ bt init
109   Bluetooth initialized
110
111   uart:~$ mcc init
112   MCC init complete
113
114   uart:~$ bt advertise on
115   Advertising started
116   Connected: F6:58:DC:27:F3:57 (random)
117
118
119When connected
120--------------
121
122Service discovery (GMCS and included OTS):
123
124.. code-block:: console
125
126   uart:~$ mcc discover_mcs
127   <dbg> bt_mcc.bt_mcc_discover_mcs: start discovery of MCS primary service
128   <dbg> bt_mcc.discover_primary_func: [ATTRIBUTE] handle 0x00ae
129   <dbg> bt_mcc.discover_primary_func: Primary discovery complete
130   <dbg> bt_mcc.discover_primary_func: UUID: 2800
131   <dbg> bt_mcc.discover_primary_func: UUID: 8fd7
132   <dbg> bt_mcc.discover_primary_func: Start discovery of MCS characteristics
133   <dbg> bt_mcc.discover_mcs_char_func: [ATTRIBUTE] handle 0x00b0
134   <dbg> bt_mcc.discover_mcs_char_func: Player name, UUID: 8fa0
135   <dbg> bt_mcc.discover_mcs_char_func: [ATTRIBUTE] handle 0x00b2
136   <dbg> bt_mcc.discover_mcs_char_func: Icon Object, UUID: 8fa1
137   <dbg> bt_mcc.discover_mcs_char_func: [ATTRIBUTE] handle 0x00b4
138   <dbg> bt_mcc.discover_mcs_char_func: Icon URI, UUID: 8fa2
139   <dbg> bt_mcc.discover_mcs_char_func: [ATTRIBUTE] handle 0x00b6
140   <dbg> bt_mcc.discover_mcs_char_func: Track Changed, UUID: 8fa3
141   <dbg> bt_mcc.discover_mcs_char_func: Subscribing - handle: 0x00b6
142   [...]
143   <dbg> bt_mcc.discover_mcs_char_func: [ATTRIBUTE] handle 0x00ea
144   <dbg> bt_mcc.discover_mcs_char_func: Content Control ID, UUID: 8fb5
145   <dbg> bt_mcc.discover_mcs_char_func: Setup complete for MCS
146   <dbg> bt_mcc.discover_mcs_char_func: Start discovery of included services
147   <dbg> bt_mcc.discover_include_func: [ATTRIBUTE] handle 0x00af
148   <dbg> bt_mcc.discover_include_func: Include UUID 1825
149   <dbg> bt_mcc.discover_include_func: Discover include complete for MCS: OTS
150   <dbg> bt_mcc.discover_include_func: Start discovery of OTS characteristics
151   <dbg> bt_mcc.discover_otc_char_func: [ATTRIBUTE] handle 0x009c
152   <dbg> bt_mcc.discover_otc_char_func: OTS Features
153   [...]
154   <dbg> bt_mcc.discover_otc_char_func: [ATTRIBUTE] handle 0x00ac
155   <dbg> bt_mcc.discover_otc_char_func: Object Size
156   Discovery complete
157   <dbg> bt_otc.bt_otc_register: 0
158   <dbg> bt_otc.bt_otc_register: L2CAP psm 0x  25 sec_level 1 registered
159   <dbg> bt_mcc.discover_otc_char_func: Setup complete for OTS 1 / 1
160   uart:~$
161
162
163Reading characteristics - the player name and the track duration as
164examples:
165
166.. code-block:: console
167
168   uart:~$ mcc read_player_name
169   Player name: My media player
170   4d 79 20 6d 65 64 69 61  20 70 6c 61 79 65 72    |My media  player
171
172   uart:~$ mcc read_track_duration
173   Track duration: 6300
174
175Note that the value of some characteristics may be truncated due to
176being too long to fit in the ATT packet. Increasing the ATT MTU may
177help:
178
179.. code-block:: console
180
181   uart:~$ mcc read_track_title
182   Track title: Interlude #1 (Song for
183
184   uart:~$ gatt exchange-mtu
185   Exchange pending
186   Exchange successful
187
188   uart:~$ mcc read_track_title
189   Track title: Interlude #1 (Song for Alison)
190
191Writing characteristics - track position as an example:
192
193The track position is where the player "is" in the current track.
194Read the track position, change it by writing to it, confirm by
195reading it again.
196
197.. code-block:: console
198
199   uart:~$ mcc read_track_position
200   Track Position: 0
201
202   uart:~$ mcc set_track_position 500
203   Track Position: 500
204
205   uart:~$ mcc read_track_position
206   Track Position: 500
207
208
209Controlling the player via the control point:
210
211Writing to the control point allows the client to request the server
212to do operations like play, pause, fast forward, change track, change
213group and so on. Some operations (e.g. goto track) take an argument.
214Currently, raw opcode values are used as input to the control point
215shell command. These opcode values can be found in the mpl.h header
216file.
217
218Send the play command (opcode "1"), the command to go to track (opcode
219"52") number three, and the pause command (opcode "2"):
220
221.. code-block:: console
222
223   uart:~$ mcc set_cp 1
224   Media State: 1
225   Operation: 1, result: 1
226   Operation: 1, param: 0
227
228   uart:~$ mcc set_cp 52 3
229   Track changed
230   Track title: Interlude #3 (Levanto Seventy)
231   Track duration: 7800
232   Track Position: 0
233   Current Track Object ID: 0x000000000104
234   Next Track Object ID: 0x000000000105
235   Operation: 52, result: 1
236   Operation: 52, param: 3
237
238   uart:~$ mcc set_cp 2
239   Media State: 2
240   Operation: 2, result: 1
241   Operation: 2, param: 0
242
243
244
245Using the included object transfer client
246-----------------------------------------
247
248When object transfer is supported by both the client and the server, a
249larger set of characteristics is available. These include object IDs
250for the various track and group objects. These IDs can be used to
251select and download the corresponding objects from the server's object
252transfer service.
253
254
255Read the object ID of the current group object:
256
257.. code-block:: console
258
259   uart:~$ mcc read_current_group_obj_id
260   Current Group Object ID: 0x000000000107
261
262
263Select the object with that ID:
264
265.. code-block:: console
266
267   uart:~$ mcc ots_select 0x107
268   Selecting object succeeded
269
270
271Read the object's metadata:
272
273.. code-block:: console
274
275   uart:~$ mcc ots_read_metadata
276   Reading object metadata succeeded
277   <inf> bt_mcc: Object's meta data:
278   <inf> bt_mcc:        Current size    :35
279   <inf> bt_otc: --- Displaying 1 metadata records ---
280   <inf> bt_otc: Object ID: 0x000000000107
281   <inf> bt_otc: Object name: Joe Pass - Guitar Inte
282   <inf> bt_otc: Object Current Size: 35
283   <inf> bt_otc: Object Allocate Size: 35
284   <inf> bt_otc: Type: Group Obj Type
285   <inf> bt_otc: Properties:0x4
286   <inf> bt_otc:  - read permitted
287
288
289Read the object itself:
290
291The object received is a group object. It consists of a series of
292records consisting of a type (track or group) and an object ID.
293
294.. code-block:: console
295
296   uart:~$ mcc ots_read_current_group_object
297   <dbg> bt_mcc.on_group_content: Object type: 0, object  ID: 0x000000000102
298   <dbg> bt_mcc.on_group_content: Object type: 0, object  ID: 0x000000000103
299   <dbg> bt_mcc.on_group_content: Object type: 0, object  ID: 0x000000000104
300   <dbg> bt_mcc.on_group_content: Object type: 0, object  ID: 0x000000000105
301   <dbg> bt_mcc.on_group_content: Object type: 0, object  ID: 0x000000000106
302
303
304Search
305------
306
307The search control point takes as its input a sequence of search
308control items, each consisting of length, type (e.g. track name or
309artist name) and parameter (the track name or artist name to search
310for). If the result is successful, the search results are stored in
311an object in the object transfer service. The ID of the search
312results ID object can be read from the search results object ID
313characteristic. The search result object can then be downloaded as
314for the current group object above. (Note that the search results
315object ID is empty until a search has been done.)
316
317This implementation has a working implementation of the search
318functionality interface and the server-side search control point
319parameter parsing. But the **actual searching is faked**, the same
320results are returned no matter what is searched for.
321
322There are two commands for search, one (:code:`mcc set_scp_raw`)
323allows to input the search control point parameter (the sequence of
324search control items) as a string. The other (:code:`mcc
325set_scp_ioptest`) does preset IOP test searches and takes the round
326number of the IOP search control point test as a parameter.
327
328Before the search, the search results object ID is empty
329
330.. code-block:: console
331
332   uart:~$ mcc read_search_results_obj_id
333   Search Results Object ID: 0x000000000000
334   <dbg> bt_mcc.mcc_read_search_results_obj_id_cb: Zero-length Search Results Object ID
335
336Run the search corresponding to the fourth round of the IOP test:
337
338The search control point parameter generated by this command and
339parameter has one search control item. The length field (first octet)
340is 16 (0x10). (The length of the length field itself is not
341included.) The type field (second octet) is 0x04 (search for a group
342name). The parameter (the group name to search for) is
343"TSPX_Group_Name".
344
345.. code-block:: console
346
347   uart:~$ mcc set_scp_ioptest 4
348   Search string:
349   00000000: 10 04 54 53 50 58 5f 47  72 6f 75 70 5f 4e 61 6d |..TSPX_G roup_Nam|
350   00000010: 65                                               |e                |
351   Search control point notification result code: 1
352   Search Results Object ID: 0x000000000107
353   Search Control Point set
354
355After the successful search, the search results object ID has a value:
356
357.. code-block:: console
358
359   uart:~$ mcc read_search_results_obj_id
360   Search Results Object ID: 0x000000000107
361
362
363Media Control Service (MCS)
364***************************
365
366The media control service (mcs) and the associated media player (mpl)
367typically reside on devices that can provide access to, and serve,
368media content, like PCs and smartphones.
369
370As mentioned above, the media player (mpl) has the player logic, while
371the media control service (mcs) has the GATT-based interface. This
372separation is done so that the media player can also be used without
373the GATT-based interface.
374
375
376Using the media control service and the media player
377====================================================
378
379The media control service and the media player are in general
380controlled remotely, from the media control client.
381
382Before use, the media control client must be initialized by the
383command :code:`mpl init`.
384
385As for the client, the :code:`bt` commands are used for connecting -
386:code:`bt init` followed by :code:`bt connect <address> <address
387type>` (or :code:`bt advertise on` if the server is advertising).
388
389
390Example Usage
391=============
392
393Setup
394-----
395
396.. code-block:: console
397
398   uart:~$ bt init
399   Bluetooth initialized
400
401   uart:~$ mpl init
402   [Large amounts of debug output]
403
404   uart:~$ bt connect F9:33:3B:67:D2:A7 (random)
405   Connection pending
406   Connected: F9:33:3B:67:D2:A7 (random)
407
408
409When connected
410--------------
411
412Control is done from the client.
413
414The server will give debug output related to the various operations
415performed by the client.
416
417Example: Debug output by the server when the client gives the "next
418track" command:
419
420.. code-block:: console
421
422   [00:13:29.932,373] <dbg> bt_mcs.control_point_write: Opcode: 49
423   [00:13:29.932,403] <dbg> bt_mpl.mpl_operation_set: opcode: 49, param: 536880068
424   [00:13:29.932,403] <dbg> bt_mpl.paused_state_operation_handler: Operation opcode: 49
425   [00:13:29.932,495] <dbg> bt_mpl.do_next_track: Track ID before: 0x000000000104
426   [00:13:29.932,586] <dbg> bt_mpl.do_next_track: Track ID after: 0x000000000105
427   [00:13:29.932,617] <dbg> bt_mcs.mpl_track_changed_cb: Notifying track change
428   [00:13:29.932,708] <dbg> bt_mcs.mpl_track_title_cb: Notifying track title: Interlude #4 (Vesper Dreams)
429   [00:13:29.932,800] <dbg> bt_mcs.mpl_track_duration_cb: Notifying track duration: 13500
430   [00:13:29.932,861] <dbg> bt_mcs.mpl_track_position_cb: Notifying track position: 0
431   [00:13:29.933,044] <dbg> bt_mcs.mpl_current_track_id_cb: Notifying current track ID: 0x000000000105
432   [00:13:29.933,258] <dbg> bt_mcs.mpl_next_track_id_cb: Notifying next track ID: 0x000000000106
433   [00:13:29.933,380] <dbg> bt_mcs.mpl_operation_cb: Notifying control point - opcode: 49, result: 1
434
435
436Some server commands are available. These commands force
437notifications of the various characteristics, for testing that the
438client receives notifications. The values sent in the notifications
439caused by these testing commands are independent of the media player,
440so they do not correspond the actual values of the characteristics nor
441to the actual state of the media player.
442
443Example: Force (fake value) notification of the track duration:
444
445.. code-block:: console
446
447   uart:~$ mpl duration_changed_cb
448   [00:15:17.491,058] <dbg> bt_mcs.mpl_track_duration_cb: Notifying track duration: 12000
449