/* * Copyright (c) 2019 - 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MEDIA_PROXY_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MEDIA_PROXY_H_ /** @brief Media proxy module * * @defgroup bt_media_proxy Media Proxy * * @ingroup bluetooth * @{ * * The media proxy module is the connection point between media players * and media controllers. * * A media player has (access to) media content and knows how to * navigate and play this content. A media controller reads or gets * information from a player and controls the player by setting player * parameters and giving the player commands. * * The media proxy module allows media player implementations to make * themselves available to media controllers. And it allows * controllers to access, and get updates from, any player. * * The media proxy module allows both local and remote control of * local player instances: A media controller may be a local * application, or it may be a Media Control Service relaying requests * from a remote Media Control Client. There may be either local or * remote control, or both, or even multiple instances of each. * * [Experimental] Users should note that the APIs can change * as a part of ongoing development. */ #include #include #include /* TODO: Remove dependency on mcs.h */ #include "mcs.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Media player command */ struct mpl_cmd { uint8_t opcode; bool use_param; int32_t param; }; /** * @brief Media command notification */ struct mpl_cmd_ntf { uint8_t requested_opcode; uint8_t result_code; }; /** * @brief Search control item */ struct mpl_sci { uint8_t len; /**< Length of type and parameter */ uint8_t type; /**< MEDIA_PROXY_SEARCH_TYPE_<...> */ char param[SEARCH_PARAM_MAX]; /**< Search parameter */ }; /** * @brief Search */ struct mpl_search { uint8_t len; char search[SEARCH_LEN_MAX]; /* Concatenated search control items */ }; /* - (type, length, param) */ /** * @brief Playback speed parameters * * All values from -128 to 127 allowed, only some defined */ #define MEDIA_PROXY_PLAYBACK_SPEED_MIN -128 #define MEDIA_PROXY_PLAYBACK_SPEED_QUARTER -128 #define MEDIA_PROXY_PLAYBACK_SPEED_HALF -64 #define MEDIA_PROXY_PLAYBACK_SPEED_UNITY 0 #define MEDIA_PROXY_PLAYBACK_SPEED_DOUBLE 64 #define MEDIA_PROXY_PLAYBACK_SPEED_MAX 127 /** * @brief Seeking speed factors * * The allowed values for seeking speed are the range -64 to -4 * (endpoints included), the value 0, and the range 4 to 64 * (endpoints included). */ #define MEDIA_PROXY_SEEKING_SPEED_FACTOR_MAX 64 #define MEDIA_PROXY_SEEKING_SPEED_FACTOR_MIN 4 #define MEDIA_PROXY_SEEKING_SPEED_FACTOR_ZERO 0 /** * @brief Playing orders */ #define MEDIA_PROXY_PLAYING_ORDER_SINGLE_ONCE 0x01 #define MEDIA_PROXY_PLAYING_ORDER_SINGLE_REPEAT 0x02 #define MEDIA_PROXY_PLAYING_ORDER_INORDER_ONCE 0x03 #define MEDIA_PROXY_PLAYING_ORDER_INORDER_REPEAT 0x04 #define MEDIA_PROXY_PLAYING_ORDER_OLDEST_ONCE 0x05 #define MEDIA_PROXY_PLAYING_ORDER_OLDEST_REPEAT 0x06 #define MEDIA_PROXY_PLAYING_ORDER_NEWEST_ONCE 0x07 #define MEDIA_PROXY_PLAYING_ORDER_NEWEST_REPEAT 0x08 #define MEDIA_PROXY_PLAYING_ORDER_SHUFFLE_ONCE 0x09 #define MEDIA_PROXY_PLAYING_ORDER_SHUFFLE_REPEAT 0x0a /** * @brief Playing orders supported * * A bitmap, in the same order as the playing orders above. * Note that playing order 1 corresponds to bit 0, and so on. */ #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SINGLE_ONCE BIT(0) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SINGLE_REPEAT BIT(1) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_INORDER_ONCE BIT(2) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_INORDER_REPEAT BIT(3) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_OLDEST_ONCE BIT(4) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_OLDEST_REPEAT BIT(5) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_NEWEST_ONCE BIT(6) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_NEWEST_REPEAT BIT(7) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SHUFFLE_ONCE BIT(8) #define MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_SHUFFLE_REPEAT BIT(9) /** * @brief Media player states */ #define MEDIA_PROXY_STATE_INACTIVE 0x00 #define MEDIA_PROXY_STATE_PLAYING 0x01 #define MEDIA_PROXY_STATE_PAUSED 0x02 #define MEDIA_PROXY_STATE_SEEKING 0x03 #define MEDIA_PROXY_STATE_LAST 0x04 /** * @brief Media player command opcodes */ #define MEDIA_PROXY_OP_PLAY 0x01 #define MEDIA_PROXY_OP_PAUSE 0x02 #define MEDIA_PROXY_OP_FAST_REWIND 0x03 #define MEDIA_PROXY_OP_FAST_FORWARD 0x04 #define MEDIA_PROXY_OP_STOP 0x05 #define MEDIA_PROXY_OP_MOVE_RELATIVE 0x10 #define MEDIA_PROXY_OP_PREV_SEGMENT 0x20 #define MEDIA_PROXY_OP_NEXT_SEGMENT 0x21 #define MEDIA_PROXY_OP_FIRST_SEGMENT 0x22 #define MEDIA_PROXY_OP_LAST_SEGMENT 0x23 #define MEDIA_PROXY_OP_GOTO_SEGMENT 0x24 #define MEDIA_PROXY_OP_PREV_TRACK 0x30 #define MEDIA_PROXY_OP_NEXT_TRACK 0x31 #define MEDIA_PROXY_OP_FIRST_TRACK 0x32 #define MEDIA_PROXY_OP_LAST_TRACK 0x33 #define MEDIA_PROXY_OP_GOTO_TRACK 0x34 #define MEDIA_PROXY_OP_PREV_GROUP 0x40 #define MEDIA_PROXY_OP_NEXT_GROUP 0x41 #define MEDIA_PROXY_OP_FIRST_GROUP 0x42 #define MEDIA_PROXY_OP_LAST_GROUP 0x43 #define MEDIA_PROXY_OP_GOTO_GROUP 0x44 /** * @brief Media player supported opcodes length */ #define MEDIA_PROXY_OPCODES_SUPPORTED_LEN 4 /** * @brief Media player supported command opcodes */ #define MEDIA_PROXY_OP_SUP_PLAY BIT(0) #define MEDIA_PROXY_OP_SUP_PAUSE BIT(1) #define MEDIA_PROXY_OP_SUP_FAST_REWIND BIT(2) #define MEDIA_PROXY_OP_SUP_FAST_FORWARD BIT(3) #define MEDIA_PROXY_OP_SUP_STOP BIT(4) #define MEDIA_PROXY_OP_SUP_MOVE_RELATIVE BIT(5) #define MEDIA_PROXY_OP_SUP_PREV_SEGMENT BIT(6) #define MEDIA_PROXY_OP_SUP_NEXT_SEGMENT BIT(7) #define MEDIA_PROXY_OP_SUP_FIRST_SEGMENT BIT(8) #define MEDIA_PROXY_OP_SUP_LAST_SEGMENT BIT(9) #define MEDIA_PROXY_OP_SUP_GOTO_SEGMENT BIT(10) #define MEDIA_PROXY_OP_SUP_PREV_TRACK BIT(11) #define MEDIA_PROXY_OP_SUP_NEXT_TRACK BIT(12) #define MEDIA_PROXY_OP_SUP_FIRST_TRACK BIT(13) #define MEDIA_PROXY_OP_SUP_LAST_TRACK BIT(14) #define MEDIA_PROXY_OP_SUP_GOTO_TRACK BIT(15) #define MEDIA_PROXY_OP_SUP_PREV_GROUP BIT(16) #define MEDIA_PROXY_OP_SUP_NEXT_GROUP BIT(17) #define MEDIA_PROXY_OP_SUP_FIRST_GROUP BIT(18) #define MEDIA_PROXY_OP_SUP_LAST_GROUP BIT(19) #define MEDIA_PROXY_OP_SUP_GOTO_GROUP BIT(20) /** * @brief Media player command result codes */ #define MEDIA_PROXY_CMD_SUCCESS 0x01 #define MEDIA_PROXY_CMD_NOT_SUPPORTED 0x02 #define MEDIA_PROXY_CMD_PLAYER_INACTIVE 0x03 #define MEDIA_PROXY_CMD_CANNOT_BE_COMPLETED 0x04 /** * @brief Search operation type values */ #define MEDIA_PROXY_SEARCH_TYPE_TRACK_NAME 0x01 #define MEDIA_PROXY_SEARCH_TYPE_ARTIST_NAME 0x02 #define MEDIA_PROXY_SEARCH_TYPE_ALBUM_NAME 0x03 #define MEDIA_PROXY_SEARCH_TYPE_GROUP_NAME 0x04 #define MEDIA_PROXY_SEARCH_TYPE_EARLIEST_YEAR 0x05 #define MEDIA_PROXY_SEARCH_TYPE_LATEST_YEAR 0x06 #define MEDIA_PROXY_SEARCH_TYPE_GENRE 0x07 #define MEDIA_PROXY_SEARCH_TYPE_ONLY_TRACKS 0x08 #define MEDIA_PROXY_SEARCH_TYPE_ONLY_GROUPS 0x09 /** * @brief Search operation result codes */ #define MEDIA_PROXY_SEARCH_SUCCESS 0x01 #define MEDIA_PROXY_SEARCH_FAILURE 0x02 /* Group object object types */ #define MEDIA_PROXY_GROUP_OBJECT_TRACK_TYPE 0x00 #define MEDIA_PROXY_GROUP_OBJECT_GROUP_TYPE 0x01 /** * @brief Opaque media player instance */ struct media_player; /* PUBLIC API FOR CONTROLLERS */ /** @brief Callbacks to a controller, from the media proxy * * Given by a controller when registering */ struct media_proxy_ctrl_cbs { /** * @brief Media Player Instance callback * * Called when the local Media Player instance is registered or read (TODO). * Also called if the local player instance is already registered when * the controller is registered. * Provides the controller with the pointer to the local player instance. * * @param player Media player instance pointer * @param err Error value. 0 on success, or errno on negative value. */ void (*local_player_instance)(struct media_player *player, int err); #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL /** * @brief Discover Player Instance callback * * Called when a remote player instance has been discovered. * The instance has been discovered, and will be accessed, using Bluetooth, * via media control client and a remote media control service. * * @param player Instance pointer to the remote player * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. */ void (*discover_player)(struct media_player *player, int err); #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */ /** * @brief Media Player Name receive callback * * Called when the Media Player Name is read or changed * See also media_proxy_ctrl_name_get() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param name The name of the media player */ void (*player_name_recv)(struct media_player *player, int err, const char *name); /** * @brief Media Player Icon Object ID receive callback * * Called when the Media Player Icon Object ID is read * See also media_proxy_ctrl_get_icon_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the Icon object in the Object Transfer Service (48 bits) */ void (*icon_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Media Player Icon URL receive callback * * Called when the Media Player Icon URL is read * See also media_proxy_ctrl_get_icon_url() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param url The URL of the icon */ void (*icon_url_recv)(struct media_player *player, int err, const char *url); /** * @brief Track changed receive callback * * Called when the Current Track is changed * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. */ void (*track_changed_recv)(struct media_player *player, int err); /** * @brief Track Title receive callback * * Called when the Track Title is read or changed * See also media_proxy_ctrl_get_track_title() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param title The title of the current track */ void (*track_title_recv)(struct media_player *player, int err, const char *title); /** * @brief Track Duration receive callback * * Called when the Track Duration is read or changed * See also media_proxy_ctrl_get_track_duration() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param duration The duration of the current track */ void (*track_duration_recv)(struct media_player *player, int err, int32_t duration); /** * @brief Track Position receive callback * * Called when the Track Position is read or changed * See also media_proxy_ctrl_get_track_position() and * media_proxy_ctrl_set_track_position() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param position The player's position in the track */ void (*track_position_recv)(struct media_player *player, int err, int32_t position); /** * @brief Track Position write callback * * Called when the Track Position is written * See also media_proxy_ctrl_set_track_position(). * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param position The position given attempted to write */ void (*track_position_write)(struct media_player *player, int err, int32_t position); /** * @brief Playback Speed receive callback * * Called when the Playback Speed is read or changed * See also media_proxy_ctrl_get_playback_speed() and * media_proxy_ctrl_set_playback_speed() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param speed The playback speed parameter */ void (*playback_speed_recv)(struct media_player *player, int err, int8_t speed); /** * @brief Playback Speed write callback * * Called when the Playback Speed is written * See also media_proxy_ctrl_set_playback_speed() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param speed The playback speed parameter attempted to write */ void (*playback_speed_write)(struct media_player *player, int err, int8_t speed); /** * @brief Seeking Speed receive callback * * Called when the Seeking Speed is read or changed * See also media_proxy_ctrl_get_seeking_speed() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param speed The seeking speed factor */ void (*seeking_speed_recv)(struct media_player *player, int err, int8_t speed); /** * @brief Track Segments Object ID receive callback * * Called when the Track Segments Object ID is read * See also media_proxy_ctrl_get_track_segments_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the track segments object in Object Transfer Service (48 bits) */ void (*track_segments_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Current Track Object ID receive callback * * Called when the Current Track Object ID is read or changed * See also media_proxy_ctrl_get_current_track_id() and * media_proxy_ctrl_set_current_track_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the current track object in Object Transfer Service (48 bits) */ void (*current_track_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Current Track Object ID write callback * * Called when the Current Track Object ID is written * See also media_proxy_ctrl_set_current_track_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID (48 bits) attempted to write */ void (*current_track_id_write)(struct media_player *player, int err, uint64_t id); /** * @brief Next Track Object ID receive callback * * Called when the Next Track Object ID is read or changed * See also media_proxy_ctrl_get_next_track_id() and * media_proxy_ctrl_set_next_track_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the next track object in Object Transfer Service (48 bits) */ void (*next_track_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Next Track Object ID write callback * * Called when the Next Track Object ID is written * See also media_proxy_ctrl_set_next_track_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID (48 bits) attempted to write */ void (*next_track_id_write)(struct media_player *player, int err, uint64_t id); /** * @brief Parent Group Object ID receive callback * * Called when the Parent Group Object ID is read or changed * See also media_proxy_ctrl_get_parent_group_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the parent group object in Object Transfer Service (48 bits) */ void (*parent_group_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Current Group Object ID receive callback * * Called when the Current Group Object ID is read or changed * See also media_proxy_ctrl_get_current_group_id() and * media_proxy_ctrl_set_current_group_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the current group object in Object Transfer Service (48 bits) */ void (*current_group_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Current Group Object ID write callback * * Called when the Current Group Object ID is written * See also media_proxy_ctrl_set_current_group_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID (48 bits) attempted to write */ void (*current_group_id_write)(struct media_player *player, int err, uint64_t id); /** * @brief Playing Order receive callback * * Called when the Playing Order is read or changed * See also media_proxy_ctrl_get_playing_order() and * media_proxy_ctrl_set_playing_order() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param order The playing order */ void (*playing_order_recv)(struct media_player *player, int err, uint8_t order); /** * @brief Playing Order write callback * * Called when the Playing Order is written * See also media_proxy_ctrl_set_playing_order() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param order The playing order attempted to write */ void (*playing_order_write)(struct media_player *player, int err, uint8_t order); /** * @brief Playing Orders Supported receive callback * * Called when the Playing Orders Supported is read * See also media_proxy_ctrl_get_playing_orders_supported() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param orders The playing orders supported */ void (*playing_orders_supported_recv)(struct media_player *player, int err, uint16_t orders); /** * @brief Media State receive callback * * Called when the Media State is read or changed * See also media_proxy_ctrl_get_media_state() and * media_proxy_ctrl_send_command() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param state The media player state */ void (*media_state_recv)(struct media_player *player, int err, uint8_t state); /** * @brief Command send callback * * Called when a command has been sent * See also media_proxy_ctrl_send_command() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param cmd The command sent */ void (*command_send)(struct media_player *player, int err, const struct mpl_cmd *cmd); /** * @brief Command result receive callback * * Called when a command result has been received * See also media_proxy_ctrl_send_command() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param result The result received */ void (*command_recv)(struct media_player *player, int err, const struct mpl_cmd_ntf *result); /** * @brief Commands supported receive callback * * Called when the Commands Supported is read or changed * See also media_proxy_ctrl_get_commands_supported() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param opcodes The supported command opcodes (bitmap) */ void (*commands_supported_recv)(struct media_player *player, int err, uint32_t opcodes); /** * @brief Search send callback * * Called when a search has been sent * See also media_proxy_ctrl_send_search() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param search The search sent */ void (*search_send)(struct media_player *player, int err, const struct mpl_search *search); /** * @brief Search result code receive callback * * Called when a search result code has been received * See also media_proxy_ctrl_send_search() * * The search result code tells whether the search was successful or not. * For a successful search, the actual results of the search (i.e. what was found * as a result of the search)can be accessed using the Search Results Object ID. * The Search Results Object ID has a separate callback - search_results_id_recv(). * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param result_code Search result code */ void (*search_recv)(struct media_player *player, int err, uint8_t result_code); /** * @brief Search Results Object ID receive callback * See also media_proxy_ctrl_get_search_results_id() * * Called when the Search Results Object ID is read or changed * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param id The ID of the search results object in Object Transfer Service (48 bits) */ void (*search_results_id_recv)(struct media_player *player, int err, uint64_t id); /** * @brief Content Control ID receive callback * * Called when the Content Control ID is read * See also media_proxy_ctrl_get_content_ctrl_id() * * @param player Media player instance pointer * @param err Error value. 0 on success, GATT error on positive value * or errno on negative value. * @param ccid The content control ID */ void (*content_ctrl_id_recv)(struct media_player *player, int err, uint8_t ccid); }; /** * @brief Register a controller with the media_proxy * * @param ctrl_cbs Callbacks to the controller * * @return 0 if success, errno on failure */ int media_proxy_ctrl_register(struct media_proxy_ctrl_cbs *ctrl_cbs); /** * @brief Discover a remote media player * * Discover a remote media player instance. * The remote player instance will be discovered, and accessed, using Bluetooth, * via the media control client and a remote media control service. * This call will start a GATT discovery of the Media Control Service on the peer, * and setup handles and subscriptions. * * This shall be called once before any other actions can be executed for the * remote player. The remote player instance will be returned in the * discover_player() callback. * * @param conn The connection to do discovery for * * @return 0 if success, errno on failure */ int media_proxy_ctrl_discover_player(struct bt_conn *conn); /** * @brief Read Media Player Name * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_player_name(struct media_player *player); /** * @brief Read Icon Object ID * * Get an ID (48 bit) that can be used to retrieve the Icon * Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.2 and * 4.1 for a description of the Icon Object. * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_icon_id(struct media_player *player); /** * @brief Read Icon URL * * Get a URL to the media player's icon. * * @param player Media player instance pointer */ int media_proxy_ctrl_get_icon_url(struct media_player *player); /** * @brief Read Track Title * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_track_title(struct media_player *player); /** * @brief Read Track Duration * * The duration of a track is measured in hundredths of a * second. * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_track_duration(struct media_player *player); /** * @brief Read Track Position * * The position of the player (the playing position) is * measured in hundredths of a second from the beginning of * the track * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_track_position(struct media_player *player); /** * @brief Set Track Position * * Set the playing position of the media player in the current * track. The position is given in in hundredths of a second, * from the beginning of the track of the track for positive * values, and (backwards) from the end of the track for * negative values. * * @param player Media player instance pointer * @param position The track position to set * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_set_track_position(struct media_player *player, int32_t position); /** * @brief Get Playback Speed * * The playback speed parameter is related to the actual * playback speed as follows: * actual playback speed = 2^(speed_parameter/64) * * A speed parameter of 0 corresponds to unity speed playback * (i.e. playback at "normal" speed). A speed parameter of * -128 corresponds to playback at one fourth of normal speed, * 127 corresponds to playback at almost four times the normal * speed. * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_playback_speed(struct media_player *player); /** * @brief Set Playback Speed * * See the get_playback_speed() function for an explanation of * the playback speed parameter. * * Note that the media player may not support all possible * values of the playback speed parameter. If the value given * is not supported, and is higher than the current value, the * player should set the playback speed to the next higher * supported value. (And correspondingly to the next lower * supported value for given values lower than the current * value.) * * @param player Media player instance pointer * @param speed The playback speed parameter to set * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_set_playback_speed(struct media_player *player, int8_t speed); /** * @brief Get Seeking Speed * * The seeking speed gives the speed with which the player is * seeking. It is a factor, relative to real-time playback * speed - a factor four means seeking happens at four times * the real-time playback speed. Positive values are for * forward seeking, negative values for backwards seeking. * * The seeking speed is not settable - a non-zero seeking speed * is the result of "fast rewind" of "fast forward" commands. * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_seeking_speed(struct media_player *player); /** * @brief Read Current Track Segments Object ID * * Get an ID (48 bit) that can be used to retrieve the Current * Track Segments Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.10 and * 4.2 for a description of the Track Segments Object. * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_track_segments_id(struct media_player *player); /** * @brief Read Current Track Object ID * * Get an ID (48 bit) that can be used to retrieve the Current * Track Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.11 and * 4.3 for a description of the Current Track Object. * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_current_track_id(struct media_player *player); /** * @brief Set Current Track Object ID * * Change the player's current track to the track given by the ID. * (Behaves similarly to the goto track command.) * * Requires Object Transfer Service * * @param player Media player instance pointer * @param id The ID of a track object * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_set_current_track_id(struct media_player *player, uint64_t id); /** * @brief Read Next Track Object ID * * Get an ID (48 bit) that can be used to retrieve the Next * Track Object from an Object Transfer Service * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_next_track_id(struct media_player *player); /** * @brief Set Next Track Object ID * * Change the player's next track to the track given by the ID. * * Requires Object Transfer Service * * @param player Media player instance pointer * @param id The ID of a track object * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_set_next_track_id(struct media_player *player, uint64_t id); /** * @brief Read Parent Group Object ID * * Get an ID (48 bit) that can be used to retrieve the Parent * Track Object from an Object Transfer Service * * The parent group is the parent of the current group. * * See the Media Control Service spec v1.0 sections 3.14 and * 4.4 for a description of the Current Track Object. * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_parent_group_id(struct media_player *player); /** * @brief Read Current Group Object ID * * Get an ID (48 bit) that can be used to retrieve the Current * Track Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.14 and * 4.4 for a description of the Current Group Object. * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_current_group_id(struct media_player *player); /** * @brief Set Current Group Object ID * * Change the player's current group to the group given by the * ID, and the current track to the first track in that group. * * Requires Object Transfer Service * * @param player Media player instance pointer * @param id The ID of a group object * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_set_current_group_id(struct media_player *player, uint64_t id); /** * @brief Read Playing Order * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_playing_order(struct media_player *player); /** * @brief Set Playing Order * * Set the media player's playing order * * @param player Media player instance pointer * @param order The playing order to set * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_set_playing_order(struct media_player *player, uint8_t order); /** * @brief Read Playing Orders Supported * * Read a bitmap containing the media player's supported * playing orders. * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_playing_orders_supported(struct media_player *player); /** * @brief Read Media State * * Read the media player's state * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_media_state(struct media_player *player); /** * @brief Send Command * * Send a command to the media player. * Commands may cause the media player to change its state * May result in two callbacks - one for the actual sending of the command to the * player, one for the result of the command from the player. * * @param player Media player instance pointer * @param command The command to send * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_send_command(struct media_player *player, const struct mpl_cmd *command); /** * @brief Read Commands Supported * * Read a bitmap containing the media player's supported * command opcodes. * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_commands_supported(struct media_player *player); /** * @brief Set Search * * Write a search to the media player. * If the search is successful, the search results will be available as a group object * in the Object Transfer Service (OTS). * * May result in up to three callbacks * - one for the actual sending of the search to the player * - one for the result code for the search from the player * - if the search is successful, one for the the search results object ID in the OTs * * Requires Object Transfer Service * * @param player Media player instance pointer * @param search The search to write * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_send_search(struct media_player *player, const struct mpl_search *search); /** * @brief Read Search Results Object ID * * Get an ID (48 bit) that can be used to retrieve the Search * Results Object from an Object Transfer Service * * The search results object is a group object. * The search results object only exists if a successful * search operation has been done. * * Requires Object Transfer Service * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ int media_proxy_ctrl_get_search_results_id(struct media_player *player); /** * @brief Read Content Control ID * * The content control ID identifies a content control service * on a device, and links it to the corresponding audio * stream. * * @param player Media player instance pointer * * @return 0 if success, errno on failure. */ uint8_t media_proxy_ctrl_get_content_ctrl_id(struct media_player *player); /* PUBLIC API FOR PLAYERS */ /** @brief Available calls in a player, that the media proxy can call * * Given by a player when registering. */ struct media_proxy_pl_calls { /** * @brief Read Media Player Name * * @return The name of the media player */ const char *(*get_player_name)(void); /** * @brief Read Icon Object ID * * Get an ID (48 bit) that can be used to retrieve the Icon * Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.2 and * 4.1 for a description of the Icon Object. * * @return The Icon Object ID */ uint64_t (*get_icon_id)(void); /** * @brief Read Icon URL * * Get a URL to the media player's icon. * * @return The URL of the Icon */ const char *(*get_icon_url)(void); /** * @brief Read Track Title * * @return The title of the current track */ const char *(*get_track_title)(void); /** * @brief Read Track Duration * * The duration of a track is measured in hundredths of a * second. * * @return The duration of the current track */ int32_t (*get_track_duration)(void); /** * @brief Read Track Position * * The position of the player (the playing position) is * measured in hundredths of a second from the beginning of * the track * * @return The position of the player in the current track */ int32_t (*get_track_position)(void); /** * @brief Set Track Position * * Set the playing position of the media player in the current * track. The position is given in in hundredths of a second, * from the beginning of the track of the track for positive * values, and (backwards) from the end of the track for * negative values. * * @param position The player position to set */ void (*set_track_position)(int32_t position); /** * @brief Get Playback Speed * * The playback speed parameter is related to the actual * playback speed as follows: * actual playback speed = 2^(speed_parameter/64) * * A speed parameter of 0 corresponds to unity speed playback * (i.e. playback at "normal" speed). A speed parameter of * -128 corresponds to playback at one fourth of normal speed, * 127 corresponds to playback at almost four times the normal * speed. * * @return The playback speed parameter */ int8_t (*get_playback_speed)(void); /** * @brief Set Playback Speed * * See the get_playback_speed() function for an explanation of * the playback speed parameter. * * Note that the media player may not support all possible * values of the playback speed parameter. If the value given * is not supported, and is higher than the current value, the * player should set the playback speed to the next higher * supported value. (And correspondingly to the next lower * supported value for given values lower than the current * value.) * * @param speed The playback speed parameter to set */ void (*set_playback_speed)(int8_t speed); /** * @brief Get Seeking Speed * * The seeking speed gives the speed with which the player is * seeking. It is a factor, relative to real-time playback * speed - a factor four means seeking happens at four times * the real-time playback speed. Positive values are for * forward seeking, negative values for backwards seeking. * * The seeking speed is not settable - a non-zero seeking speed * is the result of "fast rewind" of "fast forward" commands. * * @return The seeking speed factor */ int8_t (*get_seeking_speed)(void); /** * @brief Read Current Track Segments Object ID * * Get an ID (48 bit) that can be used to retrieve the Current * Track Segments Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.10 and * 4.2 for a description of the Track Segments Object. * * @return Current The Track Segments Object ID */ uint64_t (*get_track_segments_id)(void); /** * @brief Read Current Track Object ID * * Get an ID (48 bit) that can be used to retrieve the Current * Track Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.11 and * 4.3 for a description of the Current Track Object. * * @return The Current Track Object ID */ uint64_t (*get_current_track_id)(void); /** * @brief Set Current Track Object ID * * Change the player's current track to the track given by the ID. * (Behaves similarly to the goto track command.) * * @param id The ID of a track object */ void (*set_current_track_id)(uint64_t id); /** * @brief Read Next Track Object ID * * Get an ID (48 bit) that can be used to retrieve the Next * Track Object from an Object Transfer Service * * @return The Next Track Object ID */ uint64_t (*get_next_track_id)(void); /** * @brief Set Next Track Object ID * * Change the player's next track to the track given by the ID. * * @param id The ID of a track object */ void (*set_next_track_id)(uint64_t id); /** * @brief Read Parent Group Object ID * * Get an ID (48 bit) that can be used to retrieve the Parent * Track Object from an Object Transfer Service * * The parent group is the parent of the current group. * * See the Media Control Service spec v1.0 sections 3.14 and * 4.4 for a description of the Current Track Object. * * @return The Current Group Object ID */ uint64_t (*get_parent_group_id)(void); /** * @brief Read Current Group Object ID * * Get an ID (48 bit) that can be used to retrieve the Current * Track Object from an Object Transfer Service * * See the Media Control Service spec v1.0 sections 3.14 and * 4.4 for a description of the Current Group Object. * * @return The Current Group Object ID */ uint64_t (*get_current_group_id)(void); /** * @brief Set Current Group Object ID * * Change the player's current group to the group given by the * ID, and the current track to the first track in that group. * * @param id The ID of a group object */ void (*set_current_group_id)(uint64_t id); /** * @brief Read Playing Order * * return The media player's current playing order */ uint8_t (*get_playing_order)(void); /** * @brief Set Playing Order * * Set the media player's playing order. * See the MEDIA_PROXY_PLAYING_ORDER_* defines. * * @param order The playing order to set */ void (*set_playing_order)(uint8_t order); /** * @brief Read Playing Orders Supported * * Read a bitmap containing the media player's supported * playing orders. * See the MEDIA_PROXY_PLAYING_ORDERS_SUPPORTED_* defines. * * @return The media player's supported playing orders */ uint16_t (*get_playing_orders_supported)(void); /** * @brief Read Media State * * Read the media player's state * See the MEDIA_PROXY_MEDIA_STATE_* defines. * * @return The media player's state */ uint8_t (*get_media_state)(void); /** * @brief Send Command * * Send a command to the media player. * For command opcodes (play, pause, ...) - see the MEDIA_PROXY_OP_* * defines. * * @param command The command to send */ void (*send_command)(const struct mpl_cmd *command); /** * @brief Read Commands Supported * * Read a bitmap containing the media player's supported * command opcodes. * See the MEDIA_PROXY_OP_SUP_* defines. * * @return The media player's supported command opcodes */ uint32_t (*get_commands_supported)(void); /** * @brief Set Search * * Write a search to the media player. * (For the formatting of a search, see the Media Control * Service spec and the mcs.h file.) * * @param search The search to write */ void (*send_search)(const struct mpl_search *search); /** * @brief Read Search Results Object ID * * Get an ID (48 bit) that can be used to retrieve the Search * Results Object from an Object Transfer Service * * The search results object is a group object. * The search results object only exists if a successful * search operation has been done. * * @return The Search Results Object ID */ uint64_t (*get_search_results_id)(void); /** * @brief Read Content Control ID * * The content control ID identifies a content control service * on a device, and links it to the corresponding audio * stream. * * @return The content control ID for the media player */ uint8_t (*get_content_ctrl_id)(void); }; /** * @brief Register a player with the media proxy * * Register a player with the media proxy module, for use by media * controllers. * * The media proxy may call any non-NULL function pointers in the * supplied media_proxy_pl_calls structure. * * @param pl_calls Function pointers to the media player's calls * * @return 0 if success, errno on failure */ int media_proxy_pl_register(struct media_proxy_pl_calls *pl_calls); /* Initialize player - TODO: Move to player header file */ int media_proxy_pl_init(void); /* TODO: Find best location for this call, and move this one also */ struct bt_ots *bt_mcs_get_ots(void); /* Callbacks from the player to the media proxy */ /** * @brief Player name changed callback * * To be called when the player's name is changed. * * @param name The name of the player */ void media_proxy_pl_name_cb(const char *name); /** * @brief Player icon URL changed callback * * To be called when the player's icon URL is changed. * * @param url The URL of the player's icon */ void media_proxy_pl_icon_url_cb(const char *url); /** * @brief Track changed callback * * To be called when the player's current track is changed */ void media_proxy_pl_track_changed_cb(void); /** * @brief Track title callback * * To be called when the player's current track is changed * * @param title The title of the track */ void media_proxy_pl_track_title_cb(char *title); /** * @brief Track duration callback * * To be called when the current track's duration is changed (e.g. due * to a track change) * * The track duration is given in hundredths of a second. * * @param duration The track duration */ void media_proxy_pl_track_duration_cb(int32_t duration); /** * @brief Track position callback * * To be called when the media player's position in the track is * changed, or when the player is paused or similar. * * Exception: This callback should not be called when the position * changes during regular playback, i.e. while the player is playing * and playback happens at a constant speed. * * The track position is given in hundredths of a second from the * start of the track. * * @param position The media player's position in the track */ void media_proxy_pl_track_position_cb(int32_t position); /** * @brief Playback speed callback * * To be called when the playback speed is changed. * * @param speed The playback speed parameter */ void media_proxy_pl_playback_speed_cb(int8_t speed); /** * @brief Seeking speed callback * * To be called when the seeking speed is changed. * * @param speed The seeking speed factor */ void media_proxy_pl_seeking_speed_cb(int8_t speed); /** * @brief Current track object ID callback * * To be called when the ID of the current track is changed (e.g. due * to a track change). * * @param id The ID of the current track object in the OTS */ void media_proxy_pl_current_track_id_cb(uint64_t id); /** * @brief Next track object ID callback * * To be called when the ID of the current track is changes * * @param id The ID of the next track object in the OTS */ void media_proxy_pl_next_track_id_cb(uint64_t id); /** * @brief Parent group object ID callback * * To be called when the ID of the parent group is changed * * @param id The ID of the parent group object in the OTS */ void media_proxy_pl_parent_group_id_cb(uint64_t id); /** * @brief Current group object ID callback * * To be called when the ID of the current group is changed * * @param id The ID of the current group object in the OTS */ void media_proxy_pl_current_group_id_cb(uint64_t id); /** * @brief Playing order callback * * To be called when the playing order is changed * * @param order The playing order */ void media_proxy_pl_playing_order_cb(uint8_t order); /** * @brief Media state callback * * To be called when the media state is changed * * @param state The media player's state */ void media_proxy_pl_media_state_cb(uint8_t state); /** * @brief Command callback * * To be called when a command has been sent, to notify whether the * command was successfully performed or not. * See the MEDIA_PROXY_CMD_* result code defines. * * @param cmd_ntf The result of the command */ void media_proxy_pl_command_cb(const struct mpl_cmd_ntf *cmd_ntf); /** * @brief Commands supported callback * * To be called when the set of commands supported is changed * * @param opcodes The supported commands opcodes */ void media_proxy_pl_commands_supported_cb(uint32_t opcodes); /** * @brief Search callback * * To be called when a search has been set to notify whether the * search was successfully performed or not. * See the MEDIA_PROXY_SEARCH_* result code defines. * * The actual results of the search, if successful, can be found in * the search results object. * * @param result_code The result (success or failure) of the search */ void media_proxy_pl_search_cb(uint8_t result_code); /** * @brief Search Results object ID callback * * To be called when the ID of the search results is changed * (typically as the result of a new successful search). * * @param id The ID of the search results object in the OTS */ void media_proxy_pl_search_results_id_cb(uint64_t id); #ifdef __cplusplus } #endif /** @} */ /* End of group bt_media_proxy */ #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_MEDIA_PROXY_H_ */