diff -Nru bluez-5.70/btio/btio.c bluez-5.71/btio/btio.c --- bluez-5.70/btio/btio.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/btio/btio.c 2023-12-14 05:40:27.000000000 +0800 @@ -774,16 +774,21 @@ return 0; } -static int iso_bind(int sock, const bdaddr_t *src, uint8_t src_type, - const bdaddr_t *dst, uint8_t dst_type, - uint8_t bc_sid, uint8_t num_bis, - uint8_t *bis, GError **err) +static int iso_bind(int sock, bool server, const bdaddr_t *src, + uint8_t src_type, const bdaddr_t *dst, + uint8_t dst_type, uint8_t bc_sid, + uint8_t num_bis, uint8_t *bis, + GError **err) { struct sockaddr_iso *addr = NULL; size_t addr_len; int ret = 0; - if (num_bis) + /* If this is an ISO listener and the destination address + * is not BDADDR_ANY, the listener should be bound to the + * broadcaster address + */ + if (server && bacmp(dst, BDADDR_ANY)) addr_len = sizeof(*addr) + sizeof(*addr->iso_bc); else addr_len = sizeof(*addr); @@ -798,7 +803,7 @@ bacpy(&addr->iso_bdaddr, src); addr->iso_bdaddr_type = src_type; - if (num_bis) { + if (addr_len > sizeof(*addr)) { bacpy(&addr->iso_bc->bc_bdaddr, dst); addr->iso_bc->bc_bdaddr_type = dst_type; addr->iso_bc->bc_sid = bc_sid; @@ -1791,14 +1796,67 @@ gboolean bt_io_bcast_accept(GIOChannel *io, BtIOConnect connect, gpointer user_data, GDestroyNotify destroy, - GError * *err) + GError * *err, BtIOOption opt1, ...) { int sock; char c; struct pollfd pfd; + va_list args; + struct sockaddr_iso *addr = NULL; + uint8_t bc_num_bis = 0; + uint8_t bc_bis[ISO_MAX_NUM_BIS] = {0}; + BtIOOption opt = opt1; + + va_start(args, opt1); + + while (opt != BT_IO_OPT_INVALID) { + if (opt == BT_IO_OPT_ISO_BC_NUM_BIS) { + bc_num_bis = va_arg(args, int); + } else if (opt == BT_IO_OPT_ISO_BC_BIS) { + memcpy(bc_bis, va_arg(args, uint8_t *), + bc_num_bis); + } else { + g_set_error(err, BT_IO_ERROR, EINVAL, + "Invalid option %d", opt); + break; + } + + opt = va_arg(args, int); + } + + va_end(args); + + if (*err) + return FALSE; sock = g_io_channel_unix_get_fd(io); + if (bc_num_bis) { + addr = malloc(sizeof(*addr) + sizeof(*addr->iso_bc)); + + if (!addr) { + ERROR_FAILED(err, "poll", ENOMEM); + return FALSE; + } + + memset(addr, 0, sizeof(*addr) + sizeof(*addr->iso_bc)); + addr->iso_family = AF_BLUETOOTH; + + addr->iso_bc->bc_num_bis = bc_num_bis; + memcpy(addr->iso_bc->bc_bis, bc_bis, + addr->iso_bc->bc_num_bis); + + if (bind(sock, (struct sockaddr *)addr, + sizeof(*addr) + sizeof(*addr->iso_bc)) < 0) { + ERROR_FAILED(err, "bind", errno); + } + + free(addr); + + if (*err) + return FALSE; + } + memset(&pfd, 0, sizeof(pfd)); pfd.fd = sock; pfd.events = POLLOUT; @@ -1930,10 +1988,9 @@ return NULL; } - if (iso_bind(sock, &opts->src, opts->src_type, - &opts->dst, opts->dst_type, - opts->bc_sid, opts->bc_num_bis, - opts->bc_bis, err) < 0) + if (iso_bind(sock, server, &opts->src, opts->src_type, + &opts->dst, opts->dst_type, opts->bc_sid, + opts->bc_num_bis, opts->bc_bis, err) < 0) goto failed; if (!iso_set_qos(sock, &opts->qos, err)) goto failed; diff -Nru bluez-5.70/btio/btio.h bluez-5.71/btio/btio.h --- bluez-5.70/btio/btio.h 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/btio/btio.h 2023-12-14 05:40:27.000000000 +0800 @@ -77,7 +77,7 @@ gboolean bt_io_bcast_accept(GIOChannel *io, BtIOConnect connect, gpointer user_data, GDestroyNotify destroy, - GError **err); + GError **err, BtIOOption opt1, ...); gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...); diff -Nru bluez-5.70/ChangeLog bluez-5.71/ChangeLog --- bluez-5.70/ChangeLog 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/ChangeLog 2023-12-14 05:40:27.000000000 +0800 @@ -1,3 +1,8 @@ +ver 5.71: + Fix issue with not registering CSIS service. + Fix issue with registering pairing callbacks. + Fix issue with corruption during discovery filter parsing. + ver 5.70: Fix issue with not sending GATT confirmations. Fix issue with not handling initiator properly. diff -Nru bluez-5.70/client/bluetoothctl-admin.1 bluez-5.71/client/bluetoothctl-admin.1 --- bluez-5.70/client/bluetoothctl-admin.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-admin.1 2023-12-14 05:58:09.000000000 +0800 @@ -0,0 +1,61 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-ADMIN" 1 "November 2022" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-admin \- Admin Policy Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [admin.commands] +.SH ADMIN POLICY COMMANDS +.SS allow +.sp +Allow service UUIDs and block rest of them. +.INDENT 0.0 +.TP +.B Usage +\fB# allow [clear/uuid1 uuid2 ...]\fP +.TP +.B Example +\fB# allow 0x1101 0x1102 0x1103\fP +.TP +.B Example +\fB# allow clear\fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-admin.rst bluez-5.71/client/bluetoothctl-admin.rst --- bluez-5.70/client/bluetoothctl-admin.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-admin.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,41 @@ +================== +bluetoothctl-admin +================== + +-------------------- +Admin Policy Submenu +-------------------- + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: November 2022 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [admin.commands] + +Admin Policy Commands +===================== + +allow +----- + +Allow service UUIDs and block rest of them. + +:Usage: **# allow [clear/uuid1 uuid2 ...]** +:Example: **# allow 0x1101 0x1102 0x1103** +:Example: **# allow clear** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/bluetoothctl-advertise.1 bluez-5.71/client/bluetoothctl-advertise.1 --- bluez-5.70/client/bluetoothctl-advertise.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-advertise.1 2023-12-14 05:58:10.000000000 +0800 @@ -0,0 +1,278 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-ADVERTISE" 1 "November 2022" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-advertise \- Advertise Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [advertise.commands] +.SH ADVERTISE OPTIONS COMMANDS +.SS uuids +.sp +Set/Get advertise uuids. +.INDENT 0.0 +.TP +.B Usage +\fB# uuids [all/uuid1 uuid2 ...]\fP +.TP +.B Example +\fB# uuids 0x1234\fP +.TP +.B Example +\fB# uuids 0x12345678\fP +.TP +.B Example +\fB# uuids 90f95193\-35de\-4306\-a6e9\-699328f15059\fP +.UNINDENT +.SS service +.sp +Set/Get advertise service data. +.INDENT 0.0 +.TP +.B Usage +\fB# service [uuid] [data=xx xx ...]\fP +.UNINDENT +.SS manufacturer +.sp +Set/Get advertise manufacturer data. +.sp +Updating is in real time while advertising. This is currently limited to 25 +bytes and will return an error message of \(dqToo much data\(dq if that maximum has +been exceeded. However, this does not check if the advertising payload length +maximum has been exceeded so you may receive an error from bluetoothd that it +\(dqFailed to register advertisement\(dq which means you need to reduce your +manufacturer data length. +.INDENT 0.0 +.TP +.B Usage +\fB# manufacturer [id] [data=xx xx ...]\fP +.UNINDENT +.SS data +.sp +Set/Get advertise data. +.sp +This allows you to advertise data with a given type. You cannot use a registered +data type value {1} with this command. For LE the advertising shows up in the +primary advertisements. +.sp +If you set only the type of the data without any data (data 0x0c) this will +cause a parse error when turning advertise on. +.sp +You can modify the advertising data while it is advertising. +.sp +To get the currently set data use the command data without any arguments. +.INDENT 0.0 +.TP +.B Usage +\fB# data [type] [data=xx xx ...]\fP +.TP +.B Example +\fB# data 0x0C 01 0x0F 13\fP +.UNINDENT +.SS discoverable +.sp +Set/Get advertise discoverable. +.sp +For LE discoverable on will set the LE General Discoverable Mode flag to true in +the primary advertisement if on. +.sp +This feature can be changed during advertising, but will only trigger LE General +Discoverable Mode even if you had previously selected discoverable\-timeout this +will be ignored. +.sp +Entering the command by itself will show the status of the setting +.INDENT 0.0 +.TP +.B Usage +\fB# discoverable [on/off]\fP +.UNINDENT +.SS discoverable\-timeout +.sp +Set/Get advertise discoverable timeout. +.sp +Using this feature in LE will cause the LE Limited Discoverable Mode flag to be +set in the primary advertisement and The LE General Discoverable Mode flag +will not be set. +.sp +The LE Limited Discoverable Mode flag will automatically turn off after [seconds] +discoverable [on] must be set to use this feature. +.sp +Entering the command by itself will show the current value set. +.INDENT 0.0 +.TP +.B Usage +\fB# discoverable\-timeout [seconds]\fP +.UNINDENT +.SS tx\-power +.sp +Show/Enable/Disable TX power to be advertised. +.sp +This sets the TX Power Level field in the advertising packet. +.sp +The value is in dBm and can be between \-127 and 127. +.sp +When this feature is turned on the LE device will advertise its transmit power +in the primary advertisement. +.sp +This feature can be modified while advertising. +.sp +Entering the command by itself will show the current value set. +.INDENT 0.0 +.TP +.B Usage +\fB# tx\-power [on/off] [power]\fP +.UNINDENT +.SS name +.sp +Configure local name to be advertised. +.sp +Local name to be used in the advertising report. +.sp +If the string is too big to fit into the packet it will be truncated. +.sp +It will either advertise as a complete local name or if it has to be truncated +then a shortened local name. +.INDENT 0.0 +.TP +.B Usage +\fB# name [on/off/name]\fP +.TP +.B Example +\fB# name \(dq0123456789abcdef0123456789abcdef\(dq\fP +.UNINDENT +.SS appearance +.sp +Configure custom appearance to be advertised. +.INDENT 0.0 +.TP +.B Usage +\fB# appearance [on/off/value]\fP +.UNINDENT +.SS duration +.sp +Set/Get advertise duration. +.sp +The Duration parameter configures the length of an Instance. +.sp +The value is in seconds. +.sp +A value of 0 indicates a default value is chosen for the Duration. +.sp +The default is 2 seconds. +.sp +If only one advertising Instance has been added, then the Duration value will be +ignored. +.sp +If multiple advertising Instances have been added, then the Duration value will +be used to determine the length of time each Instance is advertised for. +.sp +The Duration value is used to calculate the number of advertising events that +will be used to advertise each Instance. +.sp +The number of advertising events is calculated by dividing the Duration value by +the advertising interval. +.sp +The advertising interval is determined by the advertising parameters that are +set for each Instance. The advertising interval is the maximum of the +advertising intervals set for each Instance. +.INDENT 0.0 +.TP +.B Usage +\fB# duration [seconds]\fP +.UNINDENT +.SS timeout +.sp +Set/Get advertise timeout. +.INDENT 0.0 +.TP +.B Usage +\fB# timeout [seconds]\fP +.UNINDENT +.SS secondary +.sp +Set/Get advertise secondary channel. +.INDENT 0.0 +.TP +.B Usage +\fB# secondary [1M/2M/Coded]\fP +.UNINDENT +.SS interval +.sp +Set/Get advertise interval. +.sp +The Interval parameter configures the advertising interval of an Instance. +.sp +The value is in milliseconds. +.sp +A value of 0 indicates a default value is chosen for the Interval. +.sp +The default is 100 milliseconds. +.sp +The Interval value is used to calculate the number of advertising events that +will be used to advertise each Instance. +.sp +The number of advertising events is calculated by dividing the Duration value by +the advertising interval. +.sp +The advertising interval is determined by the advertising parameters that are +set for each Instance. +.sp +The advertising interval is the maximum of the advertising intervals set for +each Instance. +.INDENT 0.0 +.TP +.B Usage +\fB# interval [milliseconds]\fP +.UNINDENT +.SS clear +.sp +Clear advertise config. +.sp +This will stop advertising if it is currently advertising. +.sp +If you want to change the advertise configuration while advertising you must +first clear the advertise configuration and then set the new advertise +configuration. +.INDENT 0.0 +.TP +.B Usage +\fB# clear [uuids/service/manufacturer/config\-name...]\fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-advertise.rst bluez-5.71/client/bluetoothctl-advertise.rst --- bluez-5.70/client/bluetoothctl-advertise.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-advertise.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,239 @@ +====================== +bluetoothctl-advertise +====================== + +----------------- +Advertise Submenu +----------------- + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: November 2022 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [advertise.commands] + +Advertise Options Commands +========================== + +uuids +----- + +Set/Get advertise uuids. + +:Usage: **# uuids [all/uuid1 uuid2 ...]** +:Example: **# uuids 0x1234** +:Example: **# uuids 0x12345678** +:Example: **# uuids 90f95193-35de-4306-a6e9-699328f15059** + +service +------- + +Set/Get advertise service data. + +:Usage: **# service [uuid] [data=xx xx ...]** + +manufacturer +------------ + +Set/Get advertise manufacturer data. + +Updating is in real time while advertising. This is currently limited to 25 +bytes and will return an error message of "Too much data" if that maximum has +been exceeded. However, this does not check if the advertising payload length +maximum has been exceeded so you may receive an error from bluetoothd that it +"Failed to register advertisement" which means you need to reduce your +manufacturer data length. + +:Usage: **# manufacturer [id] [data=xx xx ...]** + +data +---- + +Set/Get advertise data. + +This allows you to advertise data with a given type. You cannot use a registered +data type value {1} with this command. For LE the advertising shows up in the +primary advertisements. + +If you set only the type of the data without any data (data 0x0c) this will +cause a parse error when turning advertise on. + +You can modify the advertising data while it is advertising. + +To get the currently set data use the command data without any arguments. + +:Usage: **# data [type] [data=xx xx ...]** +:Example: **# data 0x0C 01 0x0F 13** + +discoverable +------------ + +Set/Get advertise discoverable. + +For LE discoverable on will set the LE General Discoverable Mode flag to true in +the primary advertisement if on. + +This feature can be changed during advertising, but will only trigger LE General +Discoverable Mode even if you had previously selected discoverable-timeout this +will be ignored. + +Entering the command by itself will show the status of the setting + +:Usage: **# discoverable [on/off]** + +discoverable-timeout +-------------------- + +Set/Get advertise discoverable timeout. + +Using this feature in LE will cause the LE Limited Discoverable Mode flag to be +set in the primary advertisement and The LE General Discoverable Mode flag +will not be set. + +The LE Limited Discoverable Mode flag will automatically turn off after [seconds] +discoverable [on] must be set to use this feature. + +Entering the command by itself will show the current value set. + +:Usage: **# discoverable-timeout [seconds]** + +tx-power +-------- + +Show/Enable/Disable TX power to be advertised. + +This sets the TX Power Level field in the advertising packet. + +The value is in dBm and can be between -127 and 127. + +When this feature is turned on the LE device will advertise its transmit power +in the primary advertisement. + +This feature can be modified while advertising. + +Entering the command by itself will show the current value set. + +:Usage: **# tx-power [on/off] [power]** + +name +---- + +Configure local name to be advertised. + +Local name to be used in the advertising report. + +If the string is too big to fit into the packet it will be truncated. + +It will either advertise as a complete local name or if it has to be truncated +then a shortened local name. + +:Usage: **# name [on/off/name]** +:Example: **# name "0123456789abcdef0123456789abcdef"** + +appearance +---------- + +Configure custom appearance to be advertised. + +:Usage: **# appearance [on/off/value]** + +duration +-------- + +Set/Get advertise duration. + +The Duration parameter configures the length of an Instance. + +The value is in seconds. + +A value of 0 indicates a default value is chosen for the Duration. + +The default is 2 seconds. + +If only one advertising Instance has been added, then the Duration value will be +ignored. + +If multiple advertising Instances have been added, then the Duration value will +be used to determine the length of time each Instance is advertised for. + +The Duration value is used to calculate the number of advertising events that +will be used to advertise each Instance. + +The number of advertising events is calculated by dividing the Duration value by +the advertising interval. + +The advertising interval is determined by the advertising parameters that are +set for each Instance. The advertising interval is the maximum of the +advertising intervals set for each Instance. + +:Usage: **# duration [seconds]** + +timeout +------- + +Set/Get advertise timeout. + +:Usage: **# timeout [seconds]** + +secondary +--------- + +Set/Get advertise secondary channel. + +:Usage: **# secondary [1M/2M/Coded]** + +interval +-------- + +Set/Get advertise interval. + +The Interval parameter configures the advertising interval of an Instance. + +The value is in milliseconds. + +A value of 0 indicates a default value is chosen for the Interval. + +The default is 100 milliseconds. + +The Interval value is used to calculate the number of advertising events that +will be used to advertise each Instance. + +The number of advertising events is calculated by dividing the Duration value by +the advertising interval. + +The advertising interval is determined by the advertising parameters that are +set for each Instance. + +The advertising interval is the maximum of the advertising intervals set for +each Instance. + +:Usage: **# interval [milliseconds]** + +clear +----- + +Clear advertise config. + +This will stop advertising if it is currently advertising. + +If you want to change the advertise configuration while advertising you must +first clear the advertise configuration and then set the new advertise +configuration. + +:Usage: **# clear [uuids/service/manufacturer/config-name...]** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/bluetoothctl-endpoint.1 bluez-5.71/client/bluetoothctl-endpoint.1 --- bluez-5.70/client/bluetoothctl-endpoint.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-endpoint.1 2023-12-14 05:58:11.000000000 +0800 @@ -0,0 +1,95 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-ENDPOINT" 1 "November 2022" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-endpoint \- Endpoint Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [endpoint.commands] +.SH ENDPOINT COMMANDS +.SS list +.sp +List available endpoints. +.INDENT 0.0 +.TP +.B Usage +\fB# list [local]\fP +.UNINDENT +.SS show +.sp +Endpoint information. +.INDENT 0.0 +.TP +.B Usage +\fB# show \fP +.UNINDENT +.SS register +.sp +Register Endpoint. +.INDENT 0.0 +.TP +.B Usage +\fB# register [capabilities...]\fP +.UNINDENT +.SS unregister +.sp +Unregister Endpoint. +.INDENT 0.0 +.TP +.B Usage +\fB# unregister \fP +.UNINDENT +.SS config +.sp +Configure Endpoint. +.INDENT 0.0 +.TP +.B Usage +\fB# config [preset]\fP +.UNINDENT +.SS presets +.sp +List available presets. +.INDENT 0.0 +.TP +.B Usage +\fB# presets [default]\fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-endpoint.rst bluez-5.71/client/bluetoothctl-endpoint.rst --- bluez-5.70/client/bluetoothctl-endpoint.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-endpoint.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,74 @@ +===================== +bluetoothctl-endpoint +===================== + +---------------- +Endpoint Submenu +---------------- + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: November 2022 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [endpoint.commands] + +Endpoint Commands +================= + +list +---- + +List available endpoints. + +:Usage: **# list [local]** + +show +---- + +Endpoint information. + +:Usage: **# show ** + +register +-------- + +Register Endpoint. + +:Usage: **# register [capabilities...]** + +unregister +---------- + +Unregister Endpoint. + +:Usage: **# unregister ** + +config +------ + +Configure Endpoint. + +:Usage: **# config [preset]** + +presets +------- + +List available presets. + +:Usage: **# presets [default]** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/bluetoothctl-gatt.1 bluez-5.71/client/bluetoothctl-gatt.1 --- bluez-5.70/client/bluetoothctl-gatt.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-gatt.1 2023-12-14 05:58:12.000000000 +0800 @@ -0,0 +1,215 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-GATT" 1 "November 2022" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-gatt \- Generic Attribute Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [gatt.commands] +.SH GENERIC ATTRIBUTE COMMANDS +.SS list\-attributes +.sp +List attributes. +.INDENT 0.0 +.TP +.B Usage +\fB# list\-attributes \fP +.UNINDENT +.SS select\-attribute +.sp +Select attribute. +.INDENT 0.0 +.TP +.B Usage +\fB# select\-attribute \fP +.UNINDENT +.SS attribute\-info +.sp +Select attribute. +.INDENT 0.0 +.TP +.B Usage +\fB# attribute\-info [attribute/UUID]\fP +.UNINDENT +.SS read +.sp +Read attribute value. +.INDENT 0.0 +.TP +.B Usage +\fB# read [offset]\fP +.UNINDENT +.SS write +.sp +Write attribute value. +.INDENT 0.0 +.TP +.B Usage +\fB# write [offset] [type]\fP +.UNINDENT +.SS acquire\-write +.sp +Acquire Write file descriptor. +.INDENT 0.0 +.TP +.B Usage +\fB# acquire\-write\fP +.UNINDENT +.SS release\-write +.sp +Release Write file descriptor. +.INDENT 0.0 +.TP +.B Usage +\fB# release\-write\fP +.UNINDENT +.SS acquire\-notify +.sp +Acquire Notify file descriptor. +.INDENT 0.0 +.TP +.B Usage +\fB# acquire\-notify\fP +.UNINDENT +.SS release\-notify +.sp +Release Notify file descriptor. +.INDENT 0.0 +.TP +.B Usage +\fB# release\-notify\fP +.UNINDENT +.SS notify +.sp +Notify attribute value. +.INDENT 0.0 +.TP +.B Usage +\fB# notify \fP +.UNINDENT +.SS clone +.sp +Clone a device or attribute. +.INDENT 0.0 +.TP +.B Usage +\fB# clone [dev/attribute/UUID]\fP +.UNINDENT +.SS register\-application +.sp +Register application. +.INDENT 0.0 +.TP +.B Usage +\fB# register\-application [UUID ...]\fP +.UNINDENT +.SS unregister\-application +.sp +Unregister application +.INDENT 0.0 +.TP +.B Usage +\fB# unregister\-application\fP +.UNINDENT +.SS register\-service +.sp +Register application service. +.INDENT 0.0 +.TP +.B Usage +\fB# register\-service [handle]\fP +.UNINDENT +.SS unregister\-service +.sp +Unregister application service +.INDENT 0.0 +.TP +.B Usage +\fB# unregister\-service \fP +.UNINDENT +.SS register\-includes +.sp +Register as Included service. +.INDENT 0.0 +.TP +.B Usage +\fB#r egister\-includes [handle]\fP +.UNINDENT +.SS unregister\-includes +.sp +Unregister Included service. +.INDENT 0.0 +.TP +.B Usage +\fB# unregister\-includes \fP +.UNINDENT +.SS register\-characteristic +.sp +Register service characteristic. +.INDENT 0.0 +.TP +.B Usage +\fB# register\-characteristic [handle]\fP +.UNINDENT +.SS unregister\-characteristic +.sp +Unregister service characteristic. +.INDENT 0.0 +.TP +.B Usage +\fB# unregister\-characteristic \fP +.UNINDENT +.SS register\-descriptor +.sp +Register characteristic descriptor. +.INDENT 0.0 +.TP +.B Usage +\fB# register\-descriptor [handle]\fP +.UNINDENT +.SS unregister\-descriptor +.sp +Unregister characteristic descriptor. +.INDENT 0.0 +.TP +.B Usage +\fB# unregister\-descriptor \fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-gatt.rst bluez-5.71/client/bluetoothctl-gatt.rst --- bluez-5.70/client/bluetoothctl-gatt.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-gatt.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,180 @@ +================= +bluetoothctl-gatt +================= + +------------------------- +Generic Attribute Submenu +------------------------- + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: November 2022 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [gatt.commands] + + +Generic Attribute Commands +========================== + +list-attributes +--------------- + +List attributes. + +:Usage: **# list-attributes ** + +select-attribute +---------------- + +Select attribute. + +:Usage: **# select-attribute ** + +attribute-info +-------------- + +Select attribute. + +:Usage: **# attribute-info [attribute/UUID]** + +read +---- + +Read attribute value. + +:Usage: **# read [offset]** + +write +----- + +Write attribute value. + +:Usage: **# write [offset] [type]** + +acquire-write +------------- + +Acquire Write file descriptor. + +:Usage: **# acquire-write** + +release-write +------------- + +Release Write file descriptor. + +:Usage: **# release-write** + +acquire-notify +-------------- + +Acquire Notify file descriptor. + +:Usage: **# acquire-notify** + +release-notify +-------------- + +Release Notify file descriptor. + +:Usage: **# release-notify** + +notify +------ + +Notify attribute value. + +:Usage: **# notify ** + +clone +----- + +Clone a device or attribute. + +:Usage: **# clone [dev/attribute/UUID]** + +register-application +-------------------- + +Register application. + +:Usage: **# register-application [UUID ...]** + +unregister-application +---------------------- + +Unregister application + +:Usage: **# unregister-application** + +register-service +---------------- + +Register application service. + +:Usage: **# register-service [handle]** + +unregister-service +------------------ + +Unregister application service + +:Usage: **# unregister-service ** + +register-includes +----------------- + +Register as Included service. + +:Usage: **#r egister-includes [handle]** + +unregister-includes +------------------- + +Unregister Included service. + +:Usage: **# unregister-includes ** + +register-characteristic +----------------------- + +Register service characteristic. + +:Usage: **# register-characteristic [handle]** + +unregister-characteristic +------------------------- + +Unregister service characteristic. + +:Usage: **# unregister-characteristic ** + +register-descriptor +------------------- + +Register characteristic descriptor. + +:Usage: **# register-descriptor [handle]** + +unregister-descriptor +--------------------- + +Unregister characteristic descriptor. + +:Usage: **# unregister-descriptor ** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/bluetoothctl-player.1 bluez-5.71/client/bluetoothctl-player.1 --- bluez-5.70/client/bluetoothctl-player.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-player.1 2023-12-14 05:58:12.000000000 +0800 @@ -0,0 +1,199 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-PLAYER" 1 "November 2022" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-player \- Media Player Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [player.commands] +.SH MEDIA PLAYER COMMANDS +.SS list +.sp +List available players. +.INDENT 0.0 +.TP +.B Usage +\fB# list\fP +.UNINDENT +.SS show +.sp +Show player information. +.INDENT 0.0 +.TP +.B Usage +\fB# show [player]\fP +.UNINDENT +.SS select +.sp +Select default player. +.INDENT 0.0 +.TP +.B Usage +\fB# select \fP +.UNINDENT +.SS play +.sp +Start playback. +.INDENT 0.0 +.TP +.B Usage +\fB# play [item]\fP +.UNINDENT +.SS pause +.sp +Pause playback. +.INDENT 0.0 +.TP +.B Usage +\fB# pause\fP +.UNINDENT +.SS stop +.sp +Stop playback. +.INDENT 0.0 +.TP +.B Usage +\fB# stop\fP +.UNINDENT +.SS next +.sp +Jump to next item. +.INDENT 0.0 +.TP +.B Usage +\fB# next\fP +.UNINDENT +.SS previous +.sp +Jump to previous item. +.INDENT 0.0 +.TP +.B Usage +\fB# previous\fP +.UNINDENT +.SS fast\-forward +.sp +Fast forward playback. +.INDENT 0.0 +.TP +.B Usage +\fB# fast\-forward\fP +.UNINDENT +.SS rewind +.sp +Rewind playback. +.INDENT 0.0 +.TP +.B Usage +\fB# rewind\fP +.UNINDENT +.SS equalizer +.sp +Enable/Disable equalizer. +.INDENT 0.0 +.TP +.B Usage +\fB# equalizer \fP +.UNINDENT +.SS repeat +.sp +Set repeat mode. +.INDENT 0.0 +.TP +.B Usage +\fB# repeat \fP +.UNINDENT +.SS shuffle +.sp +Set shuffle mode. +.INDENT 0.0 +.TP +.B Usage +\fB# shuffle \fP +.UNINDENT +.SS scan +.sp +Set scan mode. +.INDENT 0.0 +.TP +.B Usage +\fB# scan \fP +.UNINDENT +.SS change\-folder +.sp +Change current folder. +.INDENT 0.0 +.TP +.B Usage +\fB# change\-folder \fP +.UNINDENT +.SS list\-items +.sp +List items of current folder. +.INDENT 0.0 +.TP +.B Usage +\fB# list\-items [start] [end]\fP +.UNINDENT +.SS search +.sp +Search items containing string. +.INDENT 0.0 +.TP +.B Usage +\fB# search \fP +.UNINDENT +.SS queue +.sp +Add item to playlist queue. +.INDENT 0.0 +.TP +.B Usage +\fB# queue \fP +.UNINDENT +.SS show\-item +.sp +Show item information. +.INDENT 0.0 +.TP +.B Usage +\fB# show\-item \fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-player.rst bluez-5.71/client/bluetoothctl-player.rst --- bluez-5.70/client/bluetoothctl-player.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-player.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,165 @@ +=================== +bluetoothctl-player +=================== + +-------------------- +Media Player Submenu +-------------------- + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: November 2022 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [player.commands] + +Media Player Commands +===================== + +list +---- + +List available players. + +:Usage: **# list** + +show +---- + +Show player information. + +:Usage: **# show [player]** + +select +------ + +Select default player. + +:Usage: **# select ** + +play +---- + +Start playback. + +:Usage: **# play [item]** + +pause +----- + +Pause playback. + +:Usage: **# pause** + +stop +---- + +Stop playback. + +:Usage: **# stop** + +next +---- + +Jump to next item. + +:Usage: **# next** + +previous +-------- + +Jump to previous item. + +:Usage: **# previous** + +fast-forward +------------ + +Fast forward playback. + +:Usage: **# fast-forward** + +rewind +------ + +Rewind playback. + +:Usage: **# rewind** + +equalizer +--------- + +Enable/Disable equalizer. + +:Usage: **# equalizer ** + +repeat +------ + +Set repeat mode. + +:Usage: **# repeat ** + +shuffle +------- + +Set shuffle mode. + +:Usage: **# shuffle ** + +scan +---- + +Set scan mode. + +:Usage: **# scan ** + +change-folder +------------- + +Change current folder. + +:Usage: **# change-folder ** + +list-items +---------- + +List items of current folder. + +:Usage: **# list-items [start] [end]** + +search +------ + +Search items containing string. + +:Usage: **# search ** + +queue +----- + +Add item to playlist queue. + +:Usage: **# queue ** + +show-item +--------- + +Show item information. + +:Usage: **# show-item ** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/bluetoothctl-scan.1 bluez-5.71/client/bluetoothctl-scan.1 --- bluez-5.70/client/bluetoothctl-scan.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-scan.1 2023-12-14 05:58:13.000000000 +0800 @@ -0,0 +1,172 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-SCAN" 1 "July 2023" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-scan \- Scan Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [scan.commands] +.SH SCAN COMMANDS +.SS uuids +.sp +Set/Get UUIDs filter. +.INDENT 0.0 +.TP +.B Usage +\fB# uuids [all/uuid1 uuid2 ...]\fP +.UNINDENT +.SS rssi +.sp +Set/Get RSSI filter, and clears pathloss. +.sp +This sets the minimum rssi value for reporting device advertisements. +.sp +The value is in dBm. +.sp +If one or more discovery filters have been set, the RSSI delta\-threshold imposed +by starting discovery by default will not be applied. +.INDENT 0.0 +.TP +.B Usage +\fB# rssi [rssi]\fP +.TP +.B Example +\fB# rssi \-60\fP +.UNINDENT +.SS pathloss +.sp +Set/Get Pathloss filter, and clears RSSI. +.sp +This sets the maximum pathloss value for reporting device advertisements. +.sp +The value is in dB. +.sp +If one or more discovery filters have been set, the RSSI delta\-threshold +imposed by starting discovery by default will not be applied. +.INDENT 0.0 +.TP +.B Usage +\fB# pathloss [pathloss]\fP +.TP +.B Example +\fB# pathloss 4\fP +.UNINDENT +.SS transport +.sp +Set/Get transport filter. +.sp +Transport parameter determines the type of scan. +.sp +The default is auto. +.sp +Possible values: +.INDENT 0.0 +.IP \(bu 2 +\(dqauto\(dq: interleaved scan +.IP \(bu 2 +\(dqbredr\(dq: BR/EDR inquiry +.IP \(bu 2 +\(dqle\(dq: LE scan only +.UNINDENT +.sp +If \(dqle\(dq or \(dqbredr\(dq Transport is requested and the controller doesn\(aqt support it, +an org.bluez.Error.Failed error will be returned. +.sp +If \(dqauto\(dq transport is requested, the scan will use LE, BREDR, or both, +depending on what\(aqs currently enabled on the controller. +.INDENT 0.0 +.TP +.B Usage +\fB# transport [auto/bredr/le]\fP +.UNINDENT +.SS duplicate\-data +.sp +Set/Get duplicate data filter. +.sp +Disables duplicate detection of advertisement data. +.sp +When enabled, PropertiesChanged signals will be generated for ManufacturerData +and ServiceData every time they are discovered. +.INDENT 0.0 +.TP +.B Usage +\fB# duplicate\-data [on/off]\fP +.UNINDENT +.SS discoverable +.sp +Set/Get discoverable filter. +.sp +Makes the adapter discoverable while discovering. +.sp +If the adapter is already discoverable, setting this filter won\(aqt have any +effect. +.INDENT 0.0 +.TP +.B Usage +\fB# discoverable [on/off]\fP +.UNINDENT +.SS pattern +.sp +Set/Get pattern filter. +.sp +Discover devices where the pattern matches either the prefix of the address or +the device name, which is a convenient way to limit the number of device objects +created during a discovery. +.sp +When set, it disregards device discoverable flags. +.INDENT 0.0 +.TP +.B Note +The pattern matching is ignored if there are other clients that don\(aqt +set any pattern, as it works as a logical OR. Also, setting an empty +string \(dq\(dq pattern will match any device found. +.TP +.B Usage +\fB# pattern [value]\fP +.UNINDENT +.SS clear +.sp +Clears discovery filter. +.INDENT 0.0 +.TP +.B Usage +\fB# clear [uuids/rssi/pathloss/transport/duplicate\-data/discoverable/pattern]\fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-scan.rst bluez-5.71/client/bluetoothctl-scan.rst --- bluez-5.70/client/bluetoothctl-scan.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-scan.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,140 @@ +================= +bluetoothctl-scan +================= + +------------ +Scan Submenu +------------ + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: July 2023 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [scan.commands] + +Scan Commands +============= + +uuids +----- + +Set/Get UUIDs filter. + +:Usage: **# uuids [all/uuid1 uuid2 ...]** + +rssi +---- + +Set/Get RSSI filter, and clears pathloss. + +This sets the minimum rssi value for reporting device advertisements. + +The value is in dBm. + +If one or more discovery filters have been set, the RSSI delta-threshold imposed +by starting discovery by default will not be applied. + +:Usage: **# rssi [rssi]** +:Example: **# rssi -60** + +pathloss +-------- +Set/Get Pathloss filter, and clears RSSI. + +This sets the maximum pathloss value for reporting device advertisements. + +The value is in dB. + +If one or more discovery filters have been set, the RSSI delta-threshold +imposed by starting discovery by default will not be applied. + +:Usage: **# pathloss [pathloss]** +:Example: **# pathloss 4** + +transport +--------- + +Set/Get transport filter. + +Transport parameter determines the type of scan. + +The default is auto. + +Possible values: + +- "auto": interleaved scan +- "bredr": BR/EDR inquiry +- "le": LE scan only + +If "le" or "bredr" Transport is requested and the controller doesn't support it, +an org.bluez.Error.Failed error will be returned. + +If "auto" transport is requested, the scan will use LE, BREDR, or both, +depending on what's currently enabled on the controller. + +:Usage: **# transport [auto/bredr/le]** + +duplicate-data +-------------- + +Set/Get duplicate data filter. + +Disables duplicate detection of advertisement data. + +When enabled, PropertiesChanged signals will be generated for ManufacturerData +and ServiceData every time they are discovered. + +:Usage: **# duplicate-data [on/off]** + +discoverable +------------ + +Set/Get discoverable filter. + +Makes the adapter discoverable while discovering. + +If the adapter is already discoverable, setting this filter won't have any +effect. + +:Usage: **# discoverable [on/off]** + +pattern +------- + +Set/Get pattern filter. + +Discover devices where the pattern matches either the prefix of the address or +the device name, which is a convenient way to limit the number of device objects +created during a discovery. + +When set, it disregards device discoverable flags. + +:Note: The pattern matching is ignored if there are other clients that don't + set any pattern, as it works as a logical OR. Also, setting an empty + string "" pattern will match any device found. + +:Usage: **# pattern [value]** + + +clear +----- + +Clears discovery filter. + +:Usage: **# clear [uuids/rssi/pathloss/transport/duplicate-data/discoverable/pattern]** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/bluetoothctl-transport.1 bluez-5.71/client/bluetoothctl-transport.1 --- bluez-5.70/client/bluetoothctl-transport.1 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-transport.1 2023-12-14 05:58:14.000000000 +0800 @@ -0,0 +1,103 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "BLUETOOTHCTL-TRANSPORT" 1 "November 2022" "BlueZ" "Linux System Administration" +.SH NAME +bluetoothctl-transport \- Media Transport Submenu +.SH SYNOPSIS +.sp +\fBbluetoothctl\fP [\-\-options] [transport.commands] +.SH MEDIA TRANSPORT COMMANDS +.SS list +.sp +List available transports. +.INDENT 0.0 +.TP +.B Usage +\fB# list\fP +.UNINDENT +.SS show +.sp +Show transport information. +.INDENT 0.0 +.TP +.B Usage +\fB# show \fP +.UNINDENT +.SS acquire +.sp +Acquire transport. +.INDENT 0.0 +.TP +.B Usage +\fB# acquire [transport1...]\fP +.UNINDENT +.SS release +.sp +Release transport. +.INDENT 0.0 +.TP +.B Usage +\fB# release [transport1...]\fP +.UNINDENT +.SS send +.sp +Send contents of a file. +.INDENT 0.0 +.TP +.B Usage +\fB# send \fP +.UNINDENT +.SS receive +.sp +Get/Set file to receive. +.INDENT 0.0 +.TP +.B Usage +\fB# receive [filename]\fP +.UNINDENT +.SS volume +.sp +Get/Set transport volume. +.INDENT 0.0 +.TP +.B Usage +\fB# volume [value]\fP +.UNINDENT +.SH RESOURCES +.sp +\fI\%http://www.bluez.org\fP +.SH REPORTING BUGS +.sp +\fI\%linux\-bluetooth@vger.kernel.org\fP +.SH COPYRIGHT +Free use of this software is granted under ther terms of the GNU +Lesser General Public Licenses (LGPL). +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/client/bluetoothctl-transport.rst bluez-5.71/client/bluetoothctl-transport.rst --- bluez-5.70/client/bluetoothctl-transport.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/client/bluetoothctl-transport.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,81 @@ +====================== +bluetoothctl-transport +====================== + +----------------------- +Media Transport Submenu +----------------------- + +:Version: BlueZ +:Copyright: Free use of this software is granted under ther terms of the GNU + Lesser General Public Licenses (LGPL). +:Date: November 2022 +:Manual section: 1 +:Manual group: Linux System Administration + +SYNOPSIS +======== + +**bluetoothctl** [--options] [transport.commands] + +Media Transport Commands +========================= + +list +---- + +List available transports. + +:Usage: **# list** + +show +---- + +Show transport information. + +:Usage: **# show ** + +acquire +------- + +Acquire transport. + +:Usage: **# acquire [transport1...]** + +release +------- + +Release transport. + +:Usage: **# release [transport1...]** + +send +---- + +Send contents of a file. + +:Usage: **# send ** + +receive +------- + +Get/Set file to receive. + +:Usage: **# receive [filename]** + +volume +------ + +Get/Set transport volume. + +:Usage: **# volume [value]** + +RESOURCES +========= + +http://www.bluez.org + +REPORTING BUGS +============== + +linux-bluetooth@vger.kernel.org diff -Nru bluez-5.70/client/main.c bluez-5.71/client/main.c --- bluez-5.70/client/main.c 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/client/main.c 2023-12-14 05:40:27.000000000 +0800 @@ -908,6 +908,8 @@ bt_shell_printf("Controller %s\n", address); } + print_property(adapter->proxy, "Manufacturer"); + print_property(adapter->proxy, "Version"); print_property(adapter->proxy, "Name"); print_property(adapter->proxy, "Alias"); print_property(adapter->proxy, "Class"); @@ -1323,9 +1325,14 @@ return bt_shell_noninteractive_quit(EXIT_FAILURE); if (enable == TRUE) { - if (strcmp(mode, "")) { + if (!g_strcmp0(mode, "")) { + g_free(filter.transport); + filter.transport = NULL; + filter.set = false; + } else { g_free(filter.transport); filter.transport = g_strdup(mode); + filter.set = false; } set_discovery_filter(false); diff -Nru bluez-5.70/client/mgmt.c bluez-5.71/client/mgmt.c --- bluez-5.70/client/mgmt.c 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/client/mgmt.c 2023-12-14 05:40:27.000000000 +0800 @@ -3056,6 +3056,18 @@ bt_shell_noninteractive_quit(EXIT_SUCCESS); } +static void register_pair_callbacks(struct mgmt *mgmt, uint16_t index) +{ + mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index, request_pin, + mgmt, NULL); + mgmt_register(mgmt, MGMT_EV_USER_CONFIRM_REQUEST, index, user_confirm, + mgmt, NULL); + mgmt_register(mgmt, MGMT_EV_USER_PASSKEY_REQUEST, index, + request_passkey, mgmt, NULL); + mgmt_register(mgmt, MGMT_EV_PASSKEY_NOTIFY, index, + passkey_notify, mgmt, NULL); +} + static struct option pair_options[] = { { "help", 0, 0, 'h' }, { "capability", 1, 0, 'c' }, @@ -3105,6 +3117,8 @@ if (index == MGMT_INDEX_NONE) index = 0; + register_pair_callbacks(mgmt, index); + memset(&cp, 0, sizeof(cp)); str2ba(argv[0], &cp.addr.bdaddr); cp.addr.type = type; @@ -5780,14 +5794,6 @@ local_name_changed, NULL, NULL); mgmt_register(mgmt, MGMT_EV_DEVICE_FOUND, index, device_found, mgmt, NULL); - mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index, request_pin, - mgmt, NULL); - mgmt_register(mgmt, MGMT_EV_USER_CONFIRM_REQUEST, index, user_confirm, - mgmt, NULL); - mgmt_register(mgmt, MGMT_EV_USER_PASSKEY_REQUEST, index, - request_passkey, mgmt, NULL); - mgmt_register(mgmt, MGMT_EV_PASSKEY_NOTIFY, index, - passkey_notify, mgmt, NULL); mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_ADDED, index, unconf_index_added, NULL, NULL); mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_REMOVED, index, diff -Nru bluez-5.70/client/player.c bluez-5.71/client/player.c --- bluez-5.70/client/player.c 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/client/player.c 2023-12-14 05:40:27.000000000 +0800 @@ -42,6 +42,7 @@ #include "src/shared/shell.h" #include "src/shared/io.h" #include "src/shared/queue.h" +#include "src/shared/bap-debug.h" #include "print.h" #include "player.h" @@ -63,6 +64,14 @@ #define SEC_USEC(_t) (_t * 1000000L) #define TS_USEC(_ts) (SEC_USEC((_ts)->tv_sec) + NSEC_USEC((_ts)->tv_nsec)) +#define EP_SRC_LOCATIONS 0x00000001 +#define EP_SNK_LOCATIONS 0x00000003 + +#define EP_SRC_CTXT 0x000f +#define EP_SUPPORTED_SRC_CTXT EP_SRC_CTXT +#define EP_SNK_CTXT 0x0fff +#define EP_SUPPORTED_SNK_CTXT EP_SNK_CTXT + struct endpoint { char *path; char *uuid; @@ -71,6 +80,9 @@ uint16_t vid; struct iovec *caps; struct iovec *meta; + uint32_t locations; + uint16_t supported_context; + uint16_t context; bool auto_accept; uint8_t max_transports; uint8_t iso_group; @@ -1199,7 +1211,7 @@ struct codec_qos { uint32_t interval; uint8_t framing; - char *phy; + uint8_t phy; uint16_t sdu; uint8_t rtn; uint16_t latency; @@ -1274,22 +1286,22 @@ QOS_CONFIG(_interval, 0x01, _phy, _sdu, _rtn, _latency, _delay) #define QOS_UNFRAMED_1M(_interval, _sdu, _rtn, _latency, _delay) \ - QOS_UNFRAMED(_interval, "1M", _sdu, _rtn, _latency, _delay) \ + QOS_UNFRAMED(_interval, 0x01, _sdu, _rtn, _latency, _delay) \ #define QOS_FRAMED_1M(_interval, _sdu, _rtn, _latency, _delay) \ - QOS_FRAMED(_interval, "1M", _sdu, _rtn, _latency, _delay) \ + QOS_FRAMED(_interval, 0x01, _sdu, _rtn, _latency, _delay) \ #define QOS_UNFRAMED_2M(_interval, _sdu, _rtn, _latency, _delay) \ - QOS_UNFRAMED(_interval, "2M", _sdu, _rtn, _latency, _delay) \ + QOS_UNFRAMED(_interval, 0x02, _sdu, _rtn, _latency, _delay) \ #define QOS_FRAMED_2M(_interval, _sdu, _rtn, _latency, _delay) \ - QOS_FRAMED(_interval, "2M", _sdu, _rtn, _latency, _delay) \ + QOS_FRAMED(_interval, 0x02, _sdu, _rtn, _latency, _delay) \ #define LC3_7_5_UNFRAMED(_sdu, _rtn, _latency, _delay) \ - QOS_UNFRAMED(7500u, "2M", _sdu, _rtn, _latency, _delay) + QOS_UNFRAMED(7500u, 0x02, _sdu, _rtn, _latency, _delay) #define LC3_7_5_FRAMED(_sdu, _rtn, _latency, _delay) \ - QOS_FRAMED(7500u, "2M", _sdu, _rtn, _latency, _delay) + QOS_FRAMED(7500u, 0x02, _sdu, _rtn, _latency, _delay) #define LC3_10_UNFRAMED(_sdu, _rtn, _latency, _delay) \ QOS_UNFRAMED_2M(10000u, _sdu, _rtn, _latency, _delay) @@ -1302,6 +1314,13 @@ 0x02, LC3_CONFIG_DURATION, _duration, \ 0x03, LC3_CONFIG_FRAME_LEN, _len, _len >> 8) +#define LC3_PRESET_DATA_ALL(_freq, _duration, _alloc, _len) \ + CODEC_DATA(0x02, LC3_CONFIG_FREQ, _freq, \ + 0x02, LC3_CONFIG_DURATION, _duration, \ + 0x05, LC3_CONFIG_CHAN_ALLOC, _alloc, _alloc >> 8, \ + _alloc >> 16, _alloc >> 24, \ + 0x03, LC3_CONFIG_FRAME_LEN, _len, _len >> 8) + #define LC3_PRESET_8KHZ(_duration, _len) \ LC3_PRESET_DATA(LC3_CONFIG_FREQ_8KHZ, _duration, _len) @@ -1320,18 +1339,24 @@ #define LC3_PRESET_32KHZ(_duration, _len) \ LC3_PRESET_DATA(LC3_CONFIG_FREQ_32KHZ, _duration, _len) +#define LC3_PRESET_32KHZ_ALL(_duration, _len, _alloc) \ + LC3_PRESET_DATA_ALL(LC3_CONFIG_FREQ_48KHZ, _duration, _alloc, _len) + #define LC3_PRESET_44KHZ(_duration, _len) \ LC3_PRESET_DATA(LC3_CONFIG_FREQ_44KHZ, _duration, _len) #define LC3_PRESET_48KHZ(_duration, _len) \ LC3_PRESET_DATA(LC3_CONFIG_FREQ_48KHZ, _duration, _len) +#define LC3_PRESET_48KHZ_ALL(_duration, _len, _alloc) \ + LC3_PRESET_DATA_ALL(LC3_CONFIG_FREQ_48KHZ, _duration, _alloc, _len) + #define LC3_PRESET_LL(_name, _data, _qos) \ { \ .name = _name, \ .data = _data, \ .qos = _qos, \ - .latency = 0x01, \ + .target_latency = 0x01, \ } #define LC3_PRESET(_name, _data, _qos) \ @@ -1449,8 +1474,97 @@ LC3_PRESET_HR("48_6_2", LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_10, 155u), LC3_10_UNFRAMED(155u, 13u, 100u, 40000u)), + /* QoS configuration support setting requirements for the UGG and UGT */ + LC3_PRESET_LL("16_1_gs", + LC3_PRESET_16KHZ(LC3_CONFIG_DURATION_7_5, 30u), + LC3_7_5_UNFRAMED(30u, 1u, 15u, 60000u)), + LC3_PRESET_LL("16_2_gs", + LC3_PRESET_16KHZ(LC3_CONFIG_DURATION_10, 40u), + LC3_10_UNFRAMED(40u, 1u, 20u, 60000u)), + LC3_PRESET_LL("32_1_gs", + LC3_PRESET_32KHZ(LC3_CONFIG_DURATION_7_5, 60u), + LC3_7_5_UNFRAMED(60u, 1u, 15u, 60000u)), + LC3_PRESET_LL("32_2_gs", + LC3_PRESET_32KHZ(LC3_CONFIG_DURATION_10, 80u), + LC3_10_UNFRAMED(80u, 1u, 20u, 60000u)), + LC3_PRESET_LL("48_1_gs", + LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_7_5, 75u), + LC3_7_5_UNFRAMED(75u, 1u, 15u, 60000u)), + LC3_PRESET_LL("48_2_gs", + LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_10, 100u), + LC3_10_UNFRAMED(100u, 1u, 20u, 60000u)), + LC3_PRESET_LL("32_1_gr", + LC3_PRESET_32KHZ(LC3_CONFIG_DURATION_7_5, 60u), + LC3_7_5_UNFRAMED(60u, 1u, 15u, 10000u)), + LC3_PRESET_LL("32_2_gr", + LC3_PRESET_32KHZ(LC3_CONFIG_DURATION_10, 80u), + LC3_10_UNFRAMED(80u, 1u, 20u, 10000u)), + LC3_PRESET_LL("48_1_gr", + LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_7_5, 75u), + LC3_7_5_UNFRAMED(75u, 1u, 15u, 10000u)), + LC3_PRESET_LL("48_2_gr", + LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_10, 100u), + LC3_10_UNFRAMED(100u, 1u, 20u, 10000u)), + LC3_PRESET_LL("48_3_gr", + LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_7_5, 90u), + LC3_7_5_UNFRAMED(90u, 1u, 15u, 10000u)), + LC3_PRESET_LL("48_4_gr", + LC3_PRESET_48KHZ(LC3_CONFIG_DURATION_10, 120u), + LC3_10_UNFRAMED(120u, 1u, 20u, 10000u)), + LC3_PRESET_LL("32_1_gr_l+r", + LC3_PRESET_32KHZ_ALL(LC3_CONFIG_DURATION_7_5, 60u, + 0x00000003), + LC3_7_5_UNFRAMED(2 * 60u, 1u, 15u, 10000u)), + LC3_PRESET_LL("32_2_gr_l+r", + LC3_PRESET_32KHZ_ALL(LC3_CONFIG_DURATION_10, 80u, + 0x00000003), + LC3_10_UNFRAMED(2 * 80u, 1u, 20u, 10000u)), + LC3_PRESET_LL("48_1_gr_l+r", + LC3_PRESET_48KHZ_ALL(LC3_CONFIG_DURATION_7_5, 75u, + 0x00000003), + LC3_7_5_UNFRAMED(2 * 75u, 1u, 15u, 10000u)), + LC3_PRESET_LL("48_2_gr_l+r", + LC3_PRESET_48KHZ_ALL(LC3_CONFIG_DURATION_10, 100u, + 0x00000003), + LC3_10_UNFRAMED(2 * 100u, 1u, 20u, 10000u)), + LC3_PRESET_LL("48_3_gr_l+r", + LC3_PRESET_48KHZ_ALL(LC3_CONFIG_DURATION_7_5, 90u, + 0x00000003), + LC3_7_5_UNFRAMED(2 * 90u, 1u, 15u, 10000u)), + LC3_PRESET_LL("48_4_gr_l+r", + LC3_PRESET_48KHZ_ALL(LC3_CONFIG_DURATION_10, 120u, + 0x00000003), + LC3_10_UNFRAMED(2 * 120u, 1u, 20u, 10000u)), }; +static void print_ltv(const char *str, void *user_data) +{ + const char *label = user_data; + + bt_shell_printf("\t%s.%s\n", label, str); +} + +static void print_lc3_caps(uint8_t *data, int len) +{ + const char *label = "Capabilities"; + + bt_bap_debug_caps(data, len, print_ltv, (void *)label); +} + +static void print_lc3_cfg(void *data, int len) +{ + const char *label = "Configuration"; + + bt_bap_debug_config(data, len, print_ltv, (void *)label); +} + +static void print_lc3_meta(void *data, int len) +{ + const char *label = "Metadata"; + + bt_bap_debug_metadata(data, len, print_ltv, (void *)label); +} + #define PRESET(_uuid, _codec, _presets, _default_index) \ { \ .uuid = _uuid, \ @@ -1756,7 +1870,7 @@ .bcast = { .big = BT_ISO_QOS_BIG_UNSET, .bis = BT_ISO_QOS_BIS_UNSET, - .sync_interval = 24, + .sync_factor = 24, .packing = 0x00, .framing = 0x00, .encryption = 0x00, @@ -1770,159 +1884,206 @@ } }; -static void append_properties(DBusMessageIter *iter, - struct endpoint_config *cfg) +static void append_io_qos(DBusMessageIter *iter, struct endpoint_config *cfg) { - DBusMessageIter dict; struct codec_qos *qos = (void *)cfg->qos; - const char *key = "Capabilities"; - const char *meta = "Metadata"; - const char *keyBCode = "BroadcastCode"; - dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &dict); + bt_shell_printf("Interval %u\n", qos->interval); - bt_shell_printf("Capabilities: "); - bt_shell_hexdump(cfg->caps->iov_base, cfg->caps->iov_len); + g_dbus_dict_append_entry(iter, "Interval", DBUS_TYPE_UINT32, + &qos->interval); - g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &key, - DBUS_TYPE_BYTE, &cfg->caps->iov_base, - cfg->caps->iov_len); + bt_shell_printf("PHY 0x%02x\n", qos->phy); - if (cfg->meta && cfg->meta->iov_len) { - g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &meta, - DBUS_TYPE_BYTE, &cfg->meta->iov_base, - cfg->meta->iov_len); + g_dbus_dict_append_entry(iter, "PHY", DBUS_TYPE_BYTE, &qos->phy); - bt_shell_printf("Metadata:\n"); - bt_shell_hexdump(cfg->meta->iov_base, cfg->meta->iov_len); - } + bt_shell_printf("SDU %u\n", cfg->qos->sdu); - if (!qos) - goto done; + g_dbus_dict_append_entry(iter, "SDU", DBUS_TYPE_UINT16, &qos->sdu); - if (cfg->target_latency) { - bt_shell_printf("TargetLatency 0x%02x\n", qos->interval); - g_dbus_dict_append_entry(&dict, "TargetLatency", - DBUS_TYPE_BYTE, &cfg->target_latency); - } + bt_shell_printf("Retransmissions %u\n", qos->rtn); - if ((!cfg->ep->broadcast) && - (cfg->ep->iso_group != BT_ISO_QOS_GROUP_UNSET)) { + g_dbus_dict_append_entry(iter, "Retransmissions", + DBUS_TYPE_BYTE, &qos->rtn); + + bt_shell_printf("Latency %u\n", qos->latency); + + g_dbus_dict_append_entry(iter, "Latency", + DBUS_TYPE_UINT16, &qos->latency); +} + +static void append_ucast_qos(DBusMessageIter *iter, struct endpoint_config *cfg) +{ + struct codec_qos *qos = (void *)cfg->qos; + + if (cfg->ep->iso_group != BT_ISO_QOS_GROUP_UNSET) { bt_shell_printf("CIG 0x%2.2x\n", cfg->ep->iso_group); - g_dbus_dict_append_entry(&dict, "CIG", DBUS_TYPE_BYTE, + g_dbus_dict_append_entry(iter, "CIG", DBUS_TYPE_BYTE, &cfg->ep->iso_group); - } else { - bt_shell_printf("BIG 0x%2.2x\n", bcast_qos.bcast.big); - g_dbus_dict_append_entry(&dict, "BIG", DBUS_TYPE_BYTE, - &bcast_qos.bcast.big); } - if ((!cfg->ep->broadcast) && - (cfg->ep->iso_stream != BT_ISO_QOS_STREAM_UNSET)) { + if (cfg->ep->iso_stream != BT_ISO_QOS_STREAM_UNSET) { bt_shell_printf("CIS 0x%2.2x\n", cfg->ep->iso_stream); - g_dbus_dict_append_entry(&dict, "CIS", DBUS_TYPE_BYTE, + g_dbus_dict_append_entry(iter, "CIS", DBUS_TYPE_BYTE, &cfg->ep->iso_stream); - - } else { - bt_shell_printf("BIS 0x%2.2x\n", bcast_qos.bcast.bis); - g_dbus_dict_append_entry(&dict, "BIS", DBUS_TYPE_BYTE, - &bcast_qos.bcast.bis); } - bt_shell_printf("Interval %u\n", qos->interval); - - g_dbus_dict_append_entry(&dict, "Interval", DBUS_TYPE_UINT32, - &qos->interval); - - if (!cfg->ep->broadcast) { - bt_shell_printf("Framing %s\n", - qos->framing ? "true" : "false"); + bt_shell_printf("Framing 0x%02x\n", qos->framing); - g_dbus_dict_append_entry(&dict, "Framing", DBUS_TYPE_BOOLEAN, + g_dbus_dict_append_entry(iter, "Framing", DBUS_TYPE_BYTE, &qos->framing); - } else { - bt_shell_printf("Framing %s\n", - bcast_qos.bcast.framing ? "true" : "false"); - - g_dbus_dict_append_entry(&dict, "Framing", DBUS_TYPE_BOOLEAN, - &bcast_qos.bcast.framing); - } - - bt_shell_printf("PHY %s\n", qos->phy); - - g_dbus_dict_append_entry(&dict, "PHY", DBUS_TYPE_STRING, &qos->phy); - - bt_shell_printf("SDU %u\n", cfg->qos->sdu); - - g_dbus_dict_append_entry(&dict, "SDU", DBUS_TYPE_UINT16, &qos->sdu); - - bt_shell_printf("Retransmissions %u\n", qos->rtn); - g_dbus_dict_append_entry(&dict, "Retransmissions", DBUS_TYPE_BYTE, - &qos->rtn); + bt_shell_printf("PresentationDelay %u\n", qos->delay); - bt_shell_printf("Latency %u\n", qos->latency); + g_dbus_dict_append_entry(iter, "PresentationDelay", + DBUS_TYPE_UINT32, &qos->delay); - g_dbus_dict_append_entry(&dict, "Latency", DBUS_TYPE_UINT16, - &qos->latency); + if (cfg->target_latency) { + bt_shell_printf("TargetLatency 0x%02x\n", cfg->target_latency); + g_dbus_dict_append_entry(iter, "TargetLatency", + DBUS_TYPE_BYTE, &cfg->target_latency); + } - bt_shell_printf("Delay %u\n", qos->delay); + append_io_qos(iter, cfg); +} - g_dbus_dict_append_entry(&dict, "Delay", DBUS_TYPE_UINT32, - &qos->delay); +static void append_bcast_qos(DBusMessageIter *iter, struct endpoint_config *cfg) +{ + if (bcast_qos.bcast.big != BT_ISO_QOS_BIG_UNSET) { + bt_shell_printf("BIG 0x%2.2x\n", bcast_qos.bcast.big); + g_dbus_dict_append_entry(iter, "BIG", DBUS_TYPE_BYTE, + &bcast_qos.bcast.big); + } - if (!cfg->ep->broadcast) - goto done; + if (bcast_qos.bcast.bis != BT_ISO_QOS_BIS_UNSET) { + bt_shell_printf("BIS 0x%2.2x\n", bcast_qos.bcast.bis); + g_dbus_dict_append_entry(iter, "BIS", DBUS_TYPE_BYTE, + &bcast_qos.bcast.bis); + } - bt_shell_printf("SyncInterval %u\n", bcast_qos.bcast.sync_interval); + bt_shell_printf("Framing 0x%02x\n", bcast_qos.bcast.framing); - g_dbus_dict_append_entry(&dict, "SyncInterval", DBUS_TYPE_BYTE, - &bcast_qos.bcast.sync_interval); + g_dbus_dict_append_entry(iter, "Framing", DBUS_TYPE_BYTE, + &bcast_qos.bcast.framing); - bt_shell_printf("Encryption %u\n", bcast_qos.bcast.encryption); + bt_shell_printf("SyncFactor %u\n", bcast_qos.bcast.sync_factor); - g_dbus_dict_append_entry(&dict, "Encryption", DBUS_TYPE_BYTE, - &bcast_qos.bcast.encryption); + g_dbus_dict_append_entry(iter, "SyncFactor", DBUS_TYPE_BYTE, + &bcast_qos.bcast.sync_factor); bt_shell_printf("Options %u\n", bcast_qos.bcast.options); - g_dbus_dict_append_entry(&dict, "Options", DBUS_TYPE_BYTE, + g_dbus_dict_append_entry(iter, "Options", DBUS_TYPE_BYTE, &bcast_qos.bcast.options); bt_shell_printf("Skip %u\n", bcast_qos.bcast.skip); - g_dbus_dict_append_entry(&dict, "Skip", DBUS_TYPE_UINT16, + g_dbus_dict_append_entry(iter, "Skip", DBUS_TYPE_UINT16, &bcast_qos.bcast.skip); bt_shell_printf("SyncTimeout %u\n", bcast_qos.bcast.sync_timeout); - g_dbus_dict_append_entry(&dict, "SyncTimeout", DBUS_TYPE_UINT16, + g_dbus_dict_append_entry(iter, "SyncTimeout", DBUS_TYPE_UINT16, &bcast_qos.bcast.sync_timeout); bt_shell_printf("SyncCteType %u\n", bcast_qos.bcast.sync_cte_type); - g_dbus_dict_append_entry(&dict, "SyncCteType", DBUS_TYPE_BYTE, + g_dbus_dict_append_entry(iter, "SyncType", DBUS_TYPE_BYTE, &bcast_qos.bcast.sync_cte_type); bt_shell_printf("MSE %u\n", bcast_qos.bcast.mse); - g_dbus_dict_append_entry(&dict, "MSE", DBUS_TYPE_BYTE, + g_dbus_dict_append_entry(iter, "MSE", DBUS_TYPE_BYTE, &bcast_qos.bcast.mse); bt_shell_printf("Timeout %u\n", bcast_qos.bcast.timeout); - g_dbus_dict_append_entry(&dict, "Timeout", DBUS_TYPE_UINT16, + g_dbus_dict_append_entry(iter, "Timeout", DBUS_TYPE_UINT16, &bcast_qos.bcast.timeout); - bt_shell_printf("BroadcastCode:\n"); - bt_shell_hexdump(cfg->ep->bcode->iov_base, cfg->ep->bcode->iov_len); + if (cfg->ep->bcode) { + const char *key = "BCode"; - g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &keyBCode, - DBUS_TYPE_BYTE, + bt_shell_printf("BCode:\n"); + bt_shell_hexdump(cfg->ep->bcode->iov_base, + cfg->ep->bcode->iov_len); + + g_dbus_dict_append_basic_array(iter, DBUS_TYPE_STRING, + &key, DBUS_TYPE_BYTE, &cfg->ep->bcode->iov_base, cfg->ep->bcode->iov_len); + } + + append_io_qos(iter, cfg); +} + +static void append_qos(DBusMessageIter *iter, struct endpoint_config *cfg) +{ + DBusMessageIter entry, var, dict; + struct codec_qos *qos = (void *)cfg->qos; + const char *key = "QoS"; + + if (!qos) + return; + + dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + + dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, + "a{sv}", &var); + + dbus_message_iter_open_container(&var, DBUS_TYPE_ARRAY, "{sv}", + &dict); + + if (cfg->ep->broadcast) + append_bcast_qos(&dict, cfg); + else + append_ucast_qos(&dict, cfg); + + dbus_message_iter_close_container(&var, &dict); + dbus_message_iter_close_container(&entry, &var); + dbus_message_iter_close_container(iter, &entry); +} + +static void append_properties(DBusMessageIter *iter, + struct endpoint_config *cfg) +{ + DBusMessageIter dict; + const char *key = "Capabilities"; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &dict); + + if (cfg->ep->codec == LC3_ID) { + print_lc3_cfg(cfg->caps->iov_base, cfg->caps->iov_len); + } else { + bt_shell_printf("Capabilities: "); + bt_shell_hexdump(cfg->caps->iov_base, cfg->caps->iov_len); + } + + g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &key, + DBUS_TYPE_BYTE, &cfg->caps->iov_base, + cfg->caps->iov_len); + + if (cfg->meta && cfg->meta->iov_len) { + const char *meta = "Metadata"; + + g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &meta, + DBUS_TYPE_BYTE, &cfg->meta->iov_base, + cfg->meta->iov_len); + + if (cfg->ep->codec == LC3_ID) { + print_lc3_meta(cfg->meta->iov_base, cfg->meta->iov_len); + } else { + bt_shell_printf("Metadata:\n"); + bt_shell_hexdump(cfg->meta->iov_base, + cfg->meta->iov_len); + } + } + + append_qos(&dict, cfg); -done: dbus_message_iter_close_container(iter, &dict); } @@ -2086,6 +2247,42 @@ return NULL; } +static void print_capabilities(GDBusProxy *proxy) +{ + DBusMessageIter iter, subiter; + uint8_t codec; + uint8_t *data; + int len; + + if (!g_dbus_proxy_get_property(proxy, "Codec", &iter)) + return; + + dbus_message_iter_get_basic(&iter, &codec); + + if (codec != LC3_ID) { + print_property(proxy, "Capabilities"); + return; + } + + if (!g_dbus_proxy_get_property(proxy, "Capabilities", &iter)) + return; + + dbus_message_iter_recurse(&iter, &subiter); + + dbus_message_iter_get_fixed_array(&subiter, &data, &len); + + print_lc3_caps(data, len); + + if (!g_dbus_proxy_get_property(proxy, "Metadata", &iter)) + return; + + dbus_message_iter_recurse(&iter, &subiter); + + dbus_message_iter_get_fixed_array(&subiter, &data, &len); + + print_lc3_meta(data, len); +} + static void cmd_show_endpoint(int argc, char *argv[]) { GDBusProxy *proxy; @@ -2101,9 +2298,13 @@ print_property(proxy, "UUID"); print_property(proxy, "Codec"); - print_property(proxy, "Capabilities"); + print_capabilities(proxy); print_property(proxy, "Device"); print_property(proxy, "DelayReporting"); + print_property(proxy, "Locations"); + print_property(proxy, "SupportedContext"); + print_property(proxy, "Context"); + print_property(proxy, "QoS"); return bt_shell_noninteractive_quit(EXIT_SUCCESS); } @@ -2247,6 +2448,63 @@ return ep->meta ? TRUE : FALSE; } +static gboolean endpoint_get_locations(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct endpoint *ep = data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &ep->locations); + + return TRUE; +} + +static gboolean endpoint_locations_exists(const GDBusPropertyTable *property, + void *data) +{ + struct endpoint *ep = data; + + return ep->supported_context ? TRUE : FALSE; +} + +static gboolean +endpoint_get_supported_context(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct endpoint *ep = data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, + &ep->supported_context); + + return TRUE; +} + +static gboolean +endpoint_supported_context_exists(const GDBusPropertyTable *property, + void *data) +{ + struct endpoint *ep = data; + + return ep->supported_context ? TRUE : FALSE; +} + +static gboolean endpoint_get_context(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct endpoint *ep = data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &ep->context); + + return TRUE; +} + +static gboolean endpoint_context_exists(const GDBusPropertyTable *property, + void *data) +{ + struct endpoint *ep = data; + + return ep->context ? TRUE : FALSE; +} + static const GDBusPropertyTable endpoint_properties[] = { { "UUID", "s", endpoint_get_uuid, NULL, NULL }, { "Codec", "y", endpoint_get_codec, NULL, NULL }, @@ -2254,6 +2512,11 @@ { "Metadata", "ay", endpoint_get_metadata, NULL, endpoint_metadata_exists }, { "Vendor", "u", endpoint_get_vendor, NULL, endpoint_vendor_exists }, + { "Locations", "u", endpoint_get_locations, NULL, + endpoint_locations_exists }, + { "SupportedContext", "q", endpoint_get_supported_context, NULL, + endpoint_supported_context_exists }, + { "Context", "q", endpoint_get_context, NULL, endpoint_context_exists }, { } }; @@ -2297,6 +2560,19 @@ bt_shell_hexdump(ep->meta->iov_base, ep->meta->iov_len); } + if (ep->locations) + g_dbus_dict_append_entry(&dict, "Locations", DBUS_TYPE_UINT32, + &ep->locations); + + if (ep->supported_context) + g_dbus_dict_append_entry(&dict, "SupportedContext", + DBUS_TYPE_UINT16, + &ep->supported_context); + + if (ep->context) + g_dbus_dict_append_entry(&dict, "Context", DBUS_TYPE_UINT16, + &ep->context); + dbus_message_iter_close_container(iter, &dict); } @@ -2436,6 +2712,67 @@ endpoint_iso_stream, ep); } +static void endpoint_context(const char *input, void *user_data) +{ + struct endpoint *ep = user_data; + char *endptr = NULL; + int value; + + value = strtol(input, &endptr, 0); + + if (!endptr || *endptr != '\0' || value > UINT16_MAX) { + bt_shell_printf("Invalid argument: %s\n", input); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + + ep->context = value; + + if (ep->broadcast) + bt_shell_prompt_input(ep->path, "BIG (auto/value):", + endpoint_iso_group, ep); + else + bt_shell_prompt_input(ep->path, "CIG (auto/value):", + endpoint_iso_group, ep); +} + +static void endpoint_supported_context(const char *input, void *user_data) +{ + struct endpoint *ep = user_data; + char *endptr = NULL; + int value; + + value = strtol(input, &endptr, 0); + + if (!endptr || *endptr != '\0' || value > UINT16_MAX) { + bt_shell_printf("Invalid argument: %s\n", input); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + + ep->supported_context = value; + + bt_shell_prompt_input(ep->path, "Context (value):", endpoint_context, + ep); +} + +static void endpoint_locations(const char *input, void *user_data) +{ + struct endpoint *ep = user_data; + char *endptr = NULL; + int value; + + value = strtol(input, &endptr, 0); + + if (!endptr || *endptr != '\0') { + bt_shell_printf("Invalid argument: %s\n", input); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + + ep->locations = value; + + bt_shell_prompt_input(ep->path, "Supported Context (value):", + endpoint_supported_context, ep); +} + static void endpoint_max_transports(const char *input, void *user_data) { struct endpoint *ep = user_data; @@ -2455,12 +2792,7 @@ ep->max_transports = value; } - if (ep->broadcast) - bt_shell_prompt_input(ep->path, "BIG (auto/value):", - endpoint_iso_group, ep); - else - bt_shell_prompt_input(ep->path, "CIG (auto/value):", - endpoint_iso_group, ep); + bt_shell_prompt_input(ep->path, "Locations:", endpoint_locations, ep); } static void endpoint_auto_accept(const char *input, void *user_data) @@ -2481,17 +2813,13 @@ return; } else if (!strcasecmp(input, "n") || !strcasecmp(input, "no")) { ep->auto_accept = false; + bt_shell_prompt_input(ep->path, "Max Transports (auto/value):", + endpoint_max_transports, ep); + return; } else { bt_shell_printf("Invalid input for Auto Accept\n"); return bt_shell_noninteractive_quit(EXIT_FAILURE); } - - if (ep->broadcast) - bt_shell_prompt_input(ep->path, "BIG (auto/value):", - endpoint_iso_group, ep); - else - bt_shell_prompt_input(ep->path, "CIG (auto/value):", - endpoint_iso_group, ep); } static void endpoint_set_metadata(const char *input, void *user_data) @@ -2892,9 +3220,9 @@ struct codec_qos *qos = (void *)&p->qos; if (!strcmp(input, "1M")) - qos->phy = "1M"; + qos->phy = 0x01; else if (!strcmp(input, "2M")) - qos->phy = "2M"; + qos->phy = 0x02; else { char *endptr = NULL; uint8_t phy = strtol(input, &endptr, 0); @@ -2906,10 +3234,8 @@ switch (phy) { case 0x01: - qos->phy = "1M"; - break; case 0x02: - qos->phy = "2M"; + qos->phy = phy; break; default: bt_shell_printf("Invalid argument: %s\n", input); @@ -3224,14 +3550,41 @@ {} }, }; +static void endpoint_init_defaults(struct endpoint *ep) +{ + ep->preset = find_presets(ep->uuid, ep->codec, ep->vid, ep->cid); + ep->max_transports = UINT8_MAX; + ep->auto_accept = true; + + if (!strcmp(ep->uuid, A2DP_SOURCE_UUID) || + !strcmp(ep->uuid, A2DP_SOURCE_UUID)) + return; + + ep->iso_group = BT_ISO_QOS_GROUP_UNSET; + ep->iso_stream = BT_ISO_QOS_STREAM_UNSET; + + ep->broadcast = (strcmp(ep->uuid, BCAA_SERVICE_UUID) && + strcmp(ep->uuid, BAA_SERVICE_UUID)) ? false : true; + if (ep->broadcast) + return; + + if (!strcmp(ep->uuid, PAC_SINK_UUID)) { + ep->locations = EP_SNK_LOCATIONS; + ep->supported_context = EP_SUPPORTED_SNK_CTXT; + ep->context = EP_SNK_CTXT; + } else if (!strcmp(ep->uuid, PAC_SOURCE_UUID)) { + ep->locations = EP_SRC_LOCATIONS; + ep->supported_context = EP_SUPPORTED_SRC_CTXT; + ep->context = EP_SRC_CTXT; + } +} + static struct endpoint *endpoint_new(const struct capabilities *cap) { struct endpoint *ep; ep = new0(struct endpoint, 1); ep->uuid = g_strdup(cap->uuid); - ep->broadcast = (strcmp(cap->uuid, BCAA_SERVICE_UUID) && - strcmp(cap->uuid, BAA_SERVICE_UUID)) ? false : true; ep->codec = cap->codec_id; ep->path = g_strdup_printf("%s/ep%u", BLUEZ_MEDIA_ENDPOINT_PATH, g_list_length(local_endpoints)); @@ -3254,12 +3607,7 @@ continue; ep = endpoint_new(cap); - ep->preset = find_presets(ep->uuid, ep->codec, ep->vid, - ep->cid); - ep->max_transports = UINT8_MAX; - ep->auto_accept = true; - ep->iso_group = BT_ISO_QOS_GROUP_UNSET; - ep->iso_stream = BT_ISO_QOS_STREAM_UNSET; + endpoint_init_defaults(ep); endpoint_register(ep); } } @@ -3777,6 +4125,42 @@ return bt_shell_noninteractive_quit(EXIT_SUCCESS); } +static void print_configuration(GDBusProxy *proxy) +{ + DBusMessageIter iter, subiter; + uint8_t codec; + uint8_t *data; + int len; + + if (!g_dbus_proxy_get_property(proxy, "Codec", &iter)) + return; + + dbus_message_iter_get_basic(&iter, &codec); + + if (codec != LC3_ID) { + print_property(proxy, "Configuration"); + return; + } + + if (!g_dbus_proxy_get_property(proxy, "Configuration", &iter)) + return; + + dbus_message_iter_recurse(&iter, &subiter); + + dbus_message_iter_get_fixed_array(&subiter, &data, &len); + + print_lc3_cfg(data, len); + + if (!g_dbus_proxy_get_property(proxy, "Metadata", &iter)) + return; + + dbus_message_iter_recurse(&iter, &subiter); + + dbus_message_iter_get_fixed_array(&subiter, &data, &len); + + print_lc3_meta(data, len); +} + static void cmd_show_transport(int argc, char *argv[]) { GDBusProxy *proxy; @@ -3792,20 +4176,14 @@ print_property(proxy, "UUID"); print_property(proxy, "Codec"); - print_property(proxy, "Configuration"); + print_configuration(proxy); print_property(proxy, "Device"); print_property(proxy, "State"); print_property(proxy, "Delay"); print_property(proxy, "Volume"); print_property(proxy, "Endpoint"); - - print_property(proxy, "Interval"); - print_property(proxy, "Framing"); - print_property(proxy, "SDU"); - print_property(proxy, "Retransmissions"); - print_property(proxy, "Latency"); + print_property(proxy, "QoS"); print_property(proxy, "Location"); - print_property(proxy, "Metadata"); print_property(proxy, "Links"); return bt_shell_noninteractive_quit(EXIT_SUCCESS); diff -Nru bluez-5.70/client/print.c bluez-5.71/client/print.c --- bluez-5.70/client/print.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/client/print.c 2023-12-14 05:40:27.000000000 +0800 @@ -165,11 +165,19 @@ break; case DBUS_TYPE_DICT_ENTRY: dbus_message_iter_recurse(iter, &subiter); - entry = g_strconcat(name, " Key", NULL); - print_iter(label, entry, &subiter); - g_free(entry); - entry = g_strconcat(name, " Value", NULL); + if (dbus_message_iter_get_arg_type(&subiter) == + DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&subiter, &valstr); + entry = g_strconcat(name, ".", valstr, NULL); + } else { + entry = g_strconcat(name, ".Key", NULL); + print_iter(label, entry, &subiter); + g_free(entry); + + entry = g_strconcat(name, ".Value", NULL); + } + dbus_message_iter_next(&subiter); print_iter(label, entry, &subiter); g_free(entry); diff -Nru bluez-5.70/configure bluez-5.71/configure --- bluez-5.70/configure 2023-09-29 03:54:35.000000000 +0800 +++ bluez-5.71/configure 2023-12-14 05:41:59.000000000 +0800 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for bluez 5.70. +# Generated by GNU Autoconf 2.71 for bluez 5.71. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, @@ -618,8 +618,8 @@ # Identity of this package. PACKAGE_NAME='bluez' PACKAGE_TARNAME='bluez' -PACKAGE_VERSION='5.70' -PACKAGE_STRING='bluez 5.70' +PACKAGE_VERSION='5.71' +PACKAGE_STRING='bluez 5.71' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1569,7 +1569,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures bluez 5.70 to adapt to many kinds of systems. +\`configure' configures bluez 5.71 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1640,7 +1640,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bluez 5.70:";; + short | recursive ) echo "Configuration of bluez 5.71:";; esac cat <<\_ACEOF @@ -1849,7 +1849,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bluez configure 5.70 +bluez configure 5.71 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2067,7 +2067,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bluez $as_me 5.70, which was +It was created by bluez $as_me 5.71, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3337,7 +3337,7 @@ # Define the identity of the package. PACKAGE='bluez' - VERSION='5.70' + VERSION='5.71' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -17374,7 +17374,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bluez $as_me 5.70, which was +This file was extended by bluez $as_me 5.71, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17442,7 +17442,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -bluez config.status 5.70 +bluez config.status 5.71 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff -Nru bluez-5.70/configure.ac bluez-5.71/configure.ac --- bluez-5.70/configure.ac 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/configure.ac 2023-12-14 05:40:27.000000000 +0800 @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 AC_PREREQ(2.60) -AC_INIT(bluez, 5.70) +AC_INIT(bluez, 5.71) AM_INIT_AUTOMAKE([foreign subdir-objects color-tests silent-rules tar-pax no-dist-gzip dist-xz]) diff -Nru bluez-5.70/debian/changelog bluez-5.71/debian/changelog --- bluez-5.70/debian/changelog 2023-11-29 17:01:59.000000000 +0800 +++ bluez-5.71/debian/changelog 2024-01-03 17:32:31.000000000 +0800 @@ -1,3 +1,15 @@ +bluez (5.71-0ubuntu1) noble; urgency=medium + + * New upstream release 5.71 (LP: #2047780): + - Fix issue with not registering CSIS service. + - Fix issue with registering pairing callbacks. + - Fix issue with corruption during discovery filter parsing. + * Drop upstreamed patches: + - 303925b28110469ad002ac19ce0eb9c84d6aceb2.patch + - CVE-2023-45866.patch + + -- Daniel van Vugt Wed, 03 Jan 2024 17:32:31 +0800 + bluez (5.70-0ubuntu3) noble; urgency=medium * SECURITY UPDATE: make conf compliant to HID specification diff -Nru bluez-5.70/debian/patches/303925b28110469ad002ac19ce0eb9c84d6aceb2.patch bluez-5.71/debian/patches/303925b28110469ad002ac19ce0eb9c84d6aceb2.patch --- bluez-5.70/debian/patches/303925b28110469ad002ac19ce0eb9c84d6aceb2.patch 2023-11-21 19:05:28.000000000 +0800 +++ bluez-5.71/debian/patches/303925b28110469ad002ac19ce0eb9c84d6aceb2.patch 1970-01-01 08:00:00.000000000 +0800 @@ -1,54 +0,0 @@ -From 303925b28110469ad002ac19ce0eb9c84d6aceb2 Mon Sep 17 00:00:00 2001 -From: Juerg Haefliger -Date: Mon, 30 Oct 2023 07:53:41 +0100 -Subject: [PATCH] shared/shell: Fix --init-script commandline option - -The newly added option -i/--init-script introduced a short option -namespace collision with btmgmt's --index, both of which use '-i'. - -As a result, a provided --index is treated as a file name: - -$ sudo btmgmt --index 0 info -Unable to open 0: No such file or directory (2) - -Fix this by using '-s' for --init-script. - -Fixes: https://github.com/bluez/bluez/issues/639 ---- - src/shared/shell.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/shared/shell.c b/src/shared/shell.c -index db79c882ca..fbccff5b54 100644 ---- a/src/shared/shell.c -+++ b/src/shared/shell.c -@@ -1128,7 +1128,7 @@ static void rl_init(void) - static const struct option main_options[] = { - { "version", no_argument, 0, 'v' }, - { "help", no_argument, 0, 'h' }, -- { "init-script", required_argument, 0, 'i' }, -+ { "init-script", required_argument, 0, 's' }, - { "timeout", required_argument, 0, 't' }, - { "monitor", no_argument, 0, 'm' }, - { "zsh-complete", no_argument, 0, 'z' }, -@@ -1169,9 +1169,9 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt) - if (opt) { - memcpy(options + offset, opt->options, - sizeof(struct option) * opt->optno); -- snprintf(optstr, sizeof(optstr), "+mhvi:t:%s", opt->optstr); -+ snprintf(optstr, sizeof(optstr), "+mhvs:t:%s", opt->optstr); - } else -- snprintf(optstr, sizeof(optstr), "+mhvi:t:"); -+ snprintf(optstr, sizeof(optstr), "+mhvs:t:"); - - data.name = strrchr(argv[0], '/'); - if (!data.name) -@@ -1193,7 +1193,7 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt) - data.argv = &cmplt; - data.mode = 1; - goto done; -- case 'i': -+ case 's': - if (optarg) - data.init_fd = open(optarg, O_RDONLY); - if (data.init_fd < 0) diff -Nru bluez-5.70/debian/patches/CVE-2023-45866.patch bluez-5.71/debian/patches/CVE-2023-45866.patch --- bluez-5.70/debian/patches/CVE-2023-45866.patch 2023-11-29 16:56:28.000000000 +0800 +++ bluez-5.71/debian/patches/CVE-2023-45866.patch 1970-01-01 08:00:00.000000000 +0800 @@ -1,45 +0,0 @@ -From 25a471a83e02e1effb15d5a488b3f0085eaeb675 Mon Sep 17 00:00:00 2001 -From: Luiz Augusto von Dentz -Date: Tue, 10 Oct 2023 13:03:12 -0700 -Subject: input.conf: Change default of ClassicBondedOnly - -This changes the default of ClassicBondedOnly since defaulting to false -is not inline with HID specification which mandates the of Security Mode -4: - -BLUETOOTH SPECIFICATION Page 84 of 123 -Human Interface Device (HID) Profile: - - 5.4.3.4.2 Security Modes - Bluetooth HID Hosts shall use Security Mode 4 when interoperating with - Bluetooth HID devices that are compliant to the Bluetooth Core - Specification v2.1+EDR[6]. ---- - profiles/input/device.c | 2 +- - profiles/input/input.conf | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -(limited to 'profiles/input') - ---- bluez-5.70.orig/profiles/input/device.c -+++ bluez-5.70/profiles/input/device.c -@@ -81,7 +81,7 @@ struct input_device { - - static int idle_timeout = 0; - static bool uhid_enabled = false; --static bool classic_bonded_only = false; -+static bool classic_bonded_only = true; - - void input_set_idle_timeout(int timeout) - { ---- bluez-5.70.orig/profiles/input/input.conf -+++ bluez-5.70/profiles/input/input.conf -@@ -17,7 +17,7 @@ - # platforms may want to make sure that input connections only come from bonded - # device connections. Several older mice have been known for not supporting - # pairing/encryption. --# Defaults to false to maximize device compatibility. -+# Defaults to true for security. - #ClassicBondedOnly=true - - # LE upgrade security diff -Nru bluez-5.70/debian/patches/series bluez-5.71/debian/patches/series --- bluez-5.70/debian/patches/series 2023-11-29 16:56:20.000000000 +0800 +++ bluez-5.71/debian/patches/series 2024-01-03 17:32:31.000000000 +0800 @@ -1,4 +1,3 @@ -303925b28110469ad002ac19ce0eb9c84d6aceb2.patch use-lib-firmware.patch work-around-Logitech-diNovo-Edge-keyboard-firmware-i.patch bluetooth.conf.patch @@ -14,4 +13,3 @@ raspi-bcm43xx-load-firmware.patch raspi-bcm43xx-3wire.patch raspi-cypress-305-bdaddr.patch -CVE-2023-45866.patch diff -Nru bluez-5.70/doc/adapter-api.txt bluez-5.71/doc/adapter-api.txt --- bluez-5.70/doc/adapter-api.txt 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/doc/adapter-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,362 +0,0 @@ -BlueZ D-Bus Adapter API description -*********************************** - - -Adapter hierarchy -================= - -Service org.bluez -Interface org.bluez.Adapter1 -Object path [variable prefix]/{hci0,hci1,...} - -Methods void StartDiscovery() - - This method starts the device discovery session. This - includes an inquiry procedure and remote device name - resolving. Use StopDiscovery to release the sessions - acquired. - - This process will start creating Device objects as - new devices are discovered. - - During discovery RSSI delta-threshold is imposed. - - Each client can request a single device discovery session - per adapter. - - Possible errors: org.bluez.Error.NotReady - org.bluez.Error.Failed - org.bluez.Error.InProgress - - void StopDiscovery() - - This method will cancel any previous StartDiscovery - transaction. - - Note that a discovery procedure is shared between all - discovery sessions thus calling StopDiscovery will only - release a single session and discovery will stop when - all sessions from all clients have finished. - - Possible errors: org.bluez.Error.NotReady - org.bluez.Error.Failed - org.bluez.Error.NotAuthorized - - void RemoveDevice(object device) - - This removes the remote device object at the given - path. It will remove also the pairing information. - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.Failed - - void SetDiscoveryFilter(dict filter) - - This method sets the device discovery filter for the - caller. When this method is called with no filter - parameter, filter is removed. - - Parameters that may be set in the filter dictionary - include the following: - - array{string} UUIDs - - Filter by service UUIDs, empty means match - _any_ UUID. - - When a remote device is found that advertises - any UUID from UUIDs, it will be reported if: - - Pathloss and RSSI are both empty. - - only Pathloss param is set, device advertise - TX pwer, and computed pathloss is less than - Pathloss param. - - only RSSI param is set, and received RSSI is - higher than RSSI param. - - int16 RSSI - - RSSI threshold value. - - PropertiesChanged signals will be emitted - for already existing Device objects, with - updated RSSI value. If one or more discovery - filters have been set, the RSSI delta-threshold, - that is imposed by StartDiscovery by default, - will not be applied. - - uint16 Pathloss - - Pathloss threshold value. - - PropertiesChanged signals will be emitted - for already existing Device objects, with - updated Pathloss value. - - string Transport (Default "auto") - - Transport parameter determines the type of - scan. - - Possible values: - "auto" - interleaved scan - "bredr" - BR/EDR inquiry - "le" - LE scan only - - If "le" or "bredr" Transport is requested, - and the controller doesn't support it, - org.bluez.Error.Failed error will be returned. - If "auto" transport is requested, scan will use - LE, BREDR, or both, depending on what's - currently enabled on the controller. - - bool DuplicateData (Default: true) - - Disables duplicate detection of advertisement - data. - - When enabled PropertiesChanged signals will be - generated for either ManufacturerData and - ServiceData everytime they are discovered. - - bool Discoverable (Default: false) - - Make adapter discoverable while discovering, - if the adapter is already discoverable setting - this filter won't do anything. - - string Pattern (Default: none) - - Discover devices where the pattern matches - either the prefix of the address or - device name which is convenient way to limited - the number of device objects created during a - discovery. - - When set disregards device discoverable flags. - - Note: The pattern matching is ignored if there - are other client that don't set any pattern as - it work as a logical OR, also setting empty - string "" pattern will match any device found. - - When discovery filter is set, Device objects will be - created as new devices with matching criteria are - discovered regardless of they are connectable or - discoverable which enables listening to - non-connectable and non-discoverable devices. - - When multiple clients call SetDiscoveryFilter, their - filters are internally merged, and notifications about - new devices are sent to all clients. Therefore, each - client must check that device updates actually match - its filter. - - When SetDiscoveryFilter is called multiple times by the - same client, last filter passed will be active for - given client. - - SetDiscoveryFilter can be called before StartDiscovery. - It is useful when client will create first discovery - session, to ensure that proper scan will be started - right after call to StartDiscovery. - - Possible errors: org.bluez.Error.NotReady - org.bluez.Error.NotSupported - org.bluez.Error.Failed - - array{string} GetDiscoveryFilters() - - Return available filters that can be given to - SetDiscoveryFilter. - - Possible errors: None - - object ConnectDevice(dict properties) [experimental] - - This method connects to device without need of - performing General Discovery. Connection mechanism is - similar to Connect method from Device1 interface with - exception that this method returns success when physical - connection is established and you can specify bearer to - connect with parameter. After this method returns, - services discovery will continue and any supported - profile will be connected. There is no need for calling - Connect on Device1 after this call. If connection was - successful this method returns object path to created - device object or device that already exist. - - Parameters that may be set in the filter dictionary - include the following: - - string Address - - The Bluetooth device address of the remote - device. This parameter is mandatory. - - string AddressType - - The Bluetooth device Address Type. This is - address type that should be used for initial - connection. If this parameter is not present - BR/EDR device is created. - - Possible values: - "public" - Public address - "random" - Random address - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.AlreadyExists - org.bluez.Error.NotSupported - org.bluez.Error.NotReady - org.bluez.Error.Failed - -Properties string Address [readonly] - - The Bluetooth device address. - - string AddressType [readonly] - - The Bluetooth Address Type. For dual-mode and BR/EDR - only adapter this defaults to "public". Single mode LE - adapters may have either value. With privacy enabled - this contains type of Identity Address and not type of - address used for connection. - - Possible values: - "public" - Public address - "random" - Random address - - string Name [readonly] - - The Bluetooth system name (pretty hostname). - - This property is either a static system default - or controlled by an external daemon providing - access to the pretty hostname configuration. - - string Alias [readwrite] - - The Bluetooth friendly name. This value can be - changed. - - In case no alias is set, it will return the system - provided name. Setting an empty string as alias will - convert it back to the system provided name. - - When resetting the alias with an empty string, the - property will default back to system name. - - On a well configured system, this property never - needs to be changed since it defaults to the system - name and provides the pretty hostname. Only if the - local name needs to be different from the pretty - hostname, this property should be used as last - resort. - - uint32 Class [readonly] - - The Bluetooth class of device. - - This property represents the value that is either - automatically configured by DMI/ACPI information - or provided as static configuration. - - boolean Powered [readwrite] - - Switch an adapter on or off. This will also set the - appropriate connectable state of the controller. - - The value of this property is not persistent. After - restart or unplugging of the adapter it will reset - back to false. - - string PowerState [readonly, experimental] - - The power state of an adapter. - - The power state will show whether the adapter is - turning off, or turning on, as well as being on - or off. - - Possible values: - "on" - powered on - "off" - powered off - "off-enabling" - transitioning from "off" to "on" - "on-disabling" - transitioning from "on" to "off" - "off-blocked" - blocked by rfkill - - boolean Discoverable [readwrite] - - Switch an adapter to discoverable or non-discoverable - to either make it visible or hide it. This is a global - setting and should only be used by the settings - application. - - If the DiscoverableTimeout is set to a non-zero - value then the system will set this value back to - false after the timer expired. - - In case the adapter is switched off, setting this - value will fail. - - When changing the Powered property the new state of - this property will be updated via a PropertiesChanged - signal. - - For any new adapter this settings defaults to false. - - boolean Pairable [readwrite] - - Switch an adapter to pairable or non-pairable. This is - a global setting and should only be used by the - settings application. - - Note that this property only affects incoming pairing - requests. - - For any new adapter this settings defaults to true. - - uint32 PairableTimeout [readwrite] - - The pairable timeout in seconds. A value of zero - means that the timeout is disabled and it will stay in - pairable mode forever. - - The default value for pairable timeout should be - disabled (value 0). - - uint32 DiscoverableTimeout [readwrite] - - The discoverable timeout in seconds. A value of zero - means that the timeout is disabled and it will stay in - discoverable/limited mode forever. - - The default value for the discoverable timeout should - be 180 seconds (3 minutes). - - boolean Discovering [readonly] - - Indicates that a device discovery procedure is active. - - array{string} UUIDs [readonly] - - List of 128-bit UUIDs that represents the available - local services. - - string Modalias [readonly, optional] - - Local Device ID information in modalias format - used by the kernel and udev. - - array{string} Roles [readonly] - - List of supported roles. Possible values: - "central": Supports the central role. - "peripheral": Supports the peripheral role. - "central-peripheral": Supports both roles - concurrently. - - array{string} ExperimentalFeatures [readonly, optional] - - List of 128-bit UUIDs that represents the experimental - features currently enabled. diff -Nru bluez-5.70/doc/advertising-api.txt bluez-5.71/doc/advertising-api.txt --- bluez-5.70/doc/advertising-api.txt 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/doc/advertising-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,278 +0,0 @@ -BlueZ D-Bus LE Advertising API Description -****************************************** - -Advertising packets are structured data which is broadcast on the LE Advertising -channels and available for all devices in range. Because of the limited space -available in LE Advertising packets (31 bytes), each packet's contents must be -carefully controlled. - -BlueZ acts as a store for the Advertisement Data which is meant to be sent. -It constructs the correct Advertisement Data from the structured -data and configured the kernel to send the correct advertisement. - -Advertisement Data objects are registered freely and then referenced by BlueZ -when constructing the data sent to the kernel. - -LE Advertisement Data hierarchy -=============================== - -Specifies the Advertisement Data to be broadcast and some advertising -parameters. Properties which are not present will not be included in the -data. Required advertisement data types will always be included. -All UUIDs are 128-bit versions in the API, and 16 or 32-bit -versions of the same UUID will be used in the advertising data as appropriate. - -Service org.bluez -Interface org.bluez.LEAdvertisement1 -Object path freely definable - -Methods void Release() [noreply] - - This method gets called when the service daemon - removes the Advertisement. A client can use it to do - cleanup tasks. There is no need to call - UnregisterAdvertisement because when this method gets - called it has already been unregistered. - -Properties string Type - - Determines the type of advertising packet requested. - - Possible values: "broadcast" or "peripheral" - - array{string} ServiceUUIDs - - List of UUIDs to include in the "Service UUID" field of - the Advertising Data. - - dict ManufacturerData - - Manufactuer Data fields to include in - the Advertising Data. Keys are the Manufacturer ID - to associate with the data. - - array{string} SolicitUUIDs - - Array of UUIDs to include in "Service Solicitation" - Advertisement Data. - - dict ServiceData - - Service Data elements to include. The keys are the - UUID to associate with the data. - - dict Data [Experimental] - - Advertising Type to include in the Advertising - Data. Key is the advertising type and value is the - data as byte array. - - Note: Types already handled by other properties shall - not be used. - - Possible values: - - ... - - Example: - - 0x26 0x01 0x01... - - bool Discoverable [Experimental] - - Advertise as general discoverable. When present this - will override adapter Discoverable property. - - Note: This property shall not be set when Type is set - to broadcast. - - uint16 DiscoverableTimeout [Experimental] - - The discoverable timeout in seconds. A value of zero - means that the timeout is disabled and it will stay in - discoverable/limited mode forever. - - Note: This property shall not be set when Type is set - to broadcast. - - array{string} Includes - - List of features to be included in the advertising - packet. - - Possible values: as found on - LEAdvertisingManager.SupportedIncludes - - string LocalName - - Local name to be used in the advertising report. If the - string is too big to fit into the packet it will be - truncated. - - If this property is available 'local-name' cannot be - present in the Includes. - - uint16 Appearance - - Appearance to be used in the advertising report. - - Possible values: as found on GAP Service. - - uint16_t Duration - - Rotation duration of the advertisement in seconds. If - there are other applications advertising no duration is - set the default is 2 seconds. - - uint16_t Timeout - - Timeout of the advertisement in seconds. This defines - the lifetime of the advertisement. - - string SecondaryChannel [Experimental] - - Secondary channel to be used. Primary channel is - always set to "1M" except when "Coded" is set. - - Possible value: "1M" (default) - "2M" - "Coded" - - uint32 MinInterval [Experimental] - - Minimum advertising interval to be used by the - advertising set, in milliseconds. Acceptable values - are in the range [20ms, 10,485s]. If the provided - MinInterval is larger than the provided MaxInterval, - the registration will return failure. - - uint32 MaxInterval [Experimental] - - Maximum advertising interval to be used by the - advertising set, in milliseconds. Acceptable values - are in the range [20ms, 10,485s]. If the provided - MinInterval is larger than the provided MaxInterval, - the registration will return failure. - - int16 TxPower [Experimental] - - Requested transmission power of this advertising set. - The provided value is used only if the "CanSetTxPower" - feature is enabled on the Advertising Manager. The - provided value must be in range [-127 to +20], where - units are in dBm. - - -LE Advertising Manager hierarchy -================================ - -The Advertising Manager allows external applications to register Advertisement -Data which should be broadcast to devices. Advertisement Data elements must -follow the API for LE Advertisement Data described above. - -Service org.bluez -Interface org.bluez.LEAdvertisingManager1 -Object path /org/bluez/{hci0,hci1,...} - -Methods RegisterAdvertisement(object advertisement, dict options) - - Registers an advertisement object to be sent over the LE - Advertising channel. The service must be exported - under interface LEAdvertisement1. - - InvalidArguments error indicates that the object has - invalid or conflicting properties. - - InvalidLength error indicates that the data - provided generates a data packet which is too long. - - The properties of this object are parsed when it is - registered, and any changes are ignored. - - If the same object is registered twice it will result in - an AlreadyExists error. - - If the maximum number of advertisement instances is - reached it will result in NotPermitted error. - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.AlreadyExists - org.bluez.Error.InvalidLength - org.bluez.Error.NotPermitted - - UnregisterAdvertisement(object advertisement) - - This unregisters an advertisement that has been - previously registered. The object path parameter must - match the same value that has been used on registration. - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.DoesNotExist - -Properties byte ActiveInstances - - Number of active advertising instances. - - byte SupportedInstances - - Number of available advertising instances. - - array{string} SupportedIncludes - - List of supported system includes. - - Possible values: "tx-power" - "appearance" - "local-name" - "rsi" - - array{string} SupportedSecondaryChannels [Experimental] - - List of supported Secondary channels. Secondary - channels can be used to advertise with the - corresponding PHY. - - Possible values: "1M" - "2M" - "Coded" - - dict SupportedCapabilities [Experimental] - - Enumerates Advertising-related controller capabilities - useful to the client. - - Possible Values: - - byte MaxAdvLen - - Max advertising data length - - byte MaxScnRspLen - - Max advertising scan response length - - int16 MinTxPower - - Min advertising tx power (dBm) - - int16 MaxTxPower - - Max advertising tx power (dBm) - - array{string} SupportedFeatures [readonly,optional,Experimental] - - List of supported platform features. If no features - are available on the platform, the SupportedFeatures - array will be empty. - - Possible values: "CanSetTxPower" - - Indicates whether platform can - specify tx power on each - advertising instance. - - "HardwareOffload" - - Indicates whether multiple - advertising will be offloaded - to the controller. diff -Nru bluez-5.70/doc/agent-api.txt bluez-5.71/doc/agent-api.txt --- bluez-5.70/doc/agent-api.txt 2017-12-27 07:03:48.000000000 +0800 +++ bluez-5.71/doc/agent-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,185 +0,0 @@ -BlueZ D-Bus Agent API description -********************************** - - -Agent Manager hierarchy -======================= - -Service org.bluez -Interface org.bluez.AgentManager1 -Object path /org/bluez - - void RegisterAgent(object agent, string capability) - - This registers an agent handler. - - The object path defines the path of the agent - that will be called when user input is needed. - - Every application can register its own agent and - for all actions triggered by that application its - agent is used. - - It is not required by an application to register - an agent. If an application does chooses to not - register an agent, the default agent is used. This - is on most cases a good idea. Only application - like a pairing wizard should register their own - agent. - - An application can only register one agent. Multiple - agents per application is not supported. - - The capability parameter can have the values - "DisplayOnly", "DisplayYesNo", "KeyboardOnly", - "NoInputNoOutput" and "KeyboardDisplay" which - reflects the input and output capabilities of the - agent. - - If an empty string is used it will fallback to - "KeyboardDisplay". - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.AlreadyExists - - void UnregisterAgent(object agent) - - This unregisters the agent that has been previously - registered. The object path parameter must match the - same value that has been used on registration. - - Possible errors: org.bluez.Error.DoesNotExist - - void RequestDefaultAgent(object agent) - - This requests is to make the application agent - the default agent. The application is required - to register an agent. - - Special permission might be required to become - the default agent. - - Possible errors: org.bluez.Error.DoesNotExist - - -Agent hierarchy -=============== - -Service unique name -Interface org.bluez.Agent1 -Object path freely definable - -Methods void Release() - - This method gets called when the service daemon - unregisters the agent. An agent can use it to do - cleanup tasks. There is no need to unregister the - agent, because when this method gets called it has - already been unregistered. - - string RequestPinCode(object device) - - This method gets called when the service daemon - needs to get the passkey for an authentication. - - The return value should be a string of 1-16 characters - length. The string can be alphanumeric. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - void DisplayPinCode(object device, string pincode) - - This method gets called when the service daemon - needs to display a pincode for an authentication. - - An empty reply should be returned. When the pincode - needs no longer to be displayed, the Cancel method - of the agent will be called. - - This is used during the pairing process of keyboards - that don't support Bluetooth 2.1 Secure Simple Pairing, - in contrast to DisplayPasskey which is used for those - that do. - - This method will only ever be called once since - older keyboards do not support typing notification. - - Note that the PIN will always be a 6-digit number, - zero-padded to 6 digits. This is for harmony with - the later specification. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - uint32 RequestPasskey(object device) - - This method gets called when the service daemon - needs to get the passkey for an authentication. - - The return value should be a numeric value - between 0-999999. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - void DisplayPasskey(object device, uint32 passkey, - uint16 entered) - - This method gets called when the service daemon - needs to display a passkey for an authentication. - - The entered parameter indicates the number of already - typed keys on the remote side. - - An empty reply should be returned. When the passkey - needs no longer to be displayed, the Cancel method - of the agent will be called. - - During the pairing process this method might be - called multiple times to update the entered value. - - Note that the passkey will always be a 6-digit number, - so the display should be zero-padded at the start if - the value contains less than 6 digits. - - void RequestConfirmation(object device, uint32 passkey) - - This method gets called when the service daemon - needs to confirm a passkey for an authentication. - - To confirm the value it should return an empty reply - or an error in case the passkey is invalid. - - Note that the passkey will always be a 6-digit number, - so the display should be zero-padded at the start if - the value contains less than 6 digits. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - void RequestAuthorization(object device) - - This method gets called to request the user to - authorize an incoming pairing attempt which - would in other circumstances trigger the just-works - model, or when the user plugged in a device that - implements cable pairing. In the latter case, the - device would not be connected to the adapter via - Bluetooth yet. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - void AuthorizeService(object device, string uuid) - - This method gets called when the service daemon - needs to authorize a connection/service request. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - void Cancel() - - This method gets called to indicate that the agent - request failed before a reply was returned. diff -Nru bluez-5.70/doc/device-api.txt bluez-5.71/doc/device-api.txt --- bluez-5.70/doc/device-api.txt 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/doc/device-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,293 +0,0 @@ -BlueZ D-Bus Device API description -********************************** - - -Device hierarchy -================ - -Service org.bluez -Interface org.bluez.Device1 -Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX - -Methods void Connect() - - This is a generic method to connect any profiles - the remote device supports that can be connected - to and have been flagged as auto-connectable on - our side. If only subset of profiles is already - connected it will try to connect currently disconnected - ones. - - If at least one profile was connected successfully this - method will indicate success. - - For dual-mode devices only one bearer is connected at - time, the conditions are in the following order: - - 1. Connect the disconnected bearer if already - connected. - - 2. Connect first the bonded bearer. If no - bearers are bonded or both are skip and check - latest seen bearer. - - 3. Connect last seen bearer, in case the - timestamps are the same BR/EDR takes - precedence. - - Possible errors: org.bluez.Error.NotReady - org.bluez.Error.Failed - org.bluez.Error.InProgress - org.bluez.Error.AlreadyConnected - - void Disconnect() - - This method gracefully disconnects all connected - profiles and then terminates low-level ACL connection. - - ACL connection will be terminated even if some profiles - were not disconnected properly e.g. due to misbehaving - device. - - This method can be also used to cancel a preceding - Connect call before a reply to it has been received. - - For non-trusted devices connected over LE bearer calling - this method will disable incoming connections until - Connect method is called again. - - Possible errors: org.bluez.Error.NotConnected - - void ConnectProfile(string uuid) - - This method connects a specific profile of this - device. The UUID provided is the remote service - UUID for the profile. - - Possible errors: org.bluez.Error.Failed - org.bluez.Error.InProgress - org.bluez.Error.InvalidArguments - org.bluez.Error.NotAvailable - org.bluez.Error.NotReady - - void DisconnectProfile(string uuid) - - This method disconnects a specific profile of - this device. The profile needs to be registered - client profile. - - There is no connection tracking for a profile, so - as long as the profile is registered this will always - succeed. - - Possible errors: org.bluez.Error.Failed - org.bluez.Error.InProgress - org.bluez.Error.InvalidArguments - org.bluez.Error.NotSupported - - void Pair() - - This method will connect to the remote device, - initiate pairing and then retrieve all SDP records - (or GATT primary services). - - If the application has registered its own agent, - then that specific agent will be used. Otherwise - it will use the default agent. - - Only for applications like a pairing wizard it - would make sense to have its own agent. In almost - all other cases the default agent will handle - this just fine. - - In case there is no application agent and also - no default agent present, this method will fail. - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.Failed - org.bluez.Error.AlreadyExists - org.bluez.Error.AuthenticationCanceled - org.bluez.Error.AuthenticationFailed - org.bluez.Error.AuthenticationRejected - org.bluez.Error.AuthenticationTimeout - org.bluez.Error.ConnectionAttemptFailed - - void CancelPairing() - - This method can be used to cancel a pairing - operation initiated by the Pair method. - - Possible errors: org.bluez.Error.DoesNotExist - org.bluez.Error.Failed - -Properties string Address [readonly] - - The Bluetooth device address of the remote device. - - string AddressType [readonly] - - The Bluetooth device Address Type. For dual-mode and - BR/EDR only devices this defaults to "public". Single - mode LE devices may have either value. If remote device - uses privacy than before pairing this represents address - type used for connection and Identity Address after - pairing. - - Possible values: - "public" - Public address - "random" - Random address - - string Name [readonly, optional] - - The Bluetooth remote name. This value can not be - changed. Use the Alias property instead. - - This value is only present for completeness. It is - better to always use the Alias property when - displaying the devices name. - - If the Alias property is unset, it will reflect - this value which makes it more convenient. - - string Icon [readonly, optional] - - Proposed icon name according to the freedesktop.org - icon naming specification. - - uint32 Class [readonly, optional] - - The Bluetooth class of device of the remote device. - - uint16 Appearance [readonly, optional] - - External appearance of device, as found on GAP service. - - array{string} UUIDs [readonly, optional] - - List of 128-bit UUIDs that represents the available - remote services. - - boolean Paired [readonly] - - Indicates if the remote device is paired. Paired means - the pairing process where devices exchange the - information to establish an encrypted connection has - been completed. - - boolean Bonded [readonly] - - Indicates if the remote device is bonded. Bonded means - the information exchanged on pairing process has been - stored and will be persisted. - - boolean Connected [readonly] - - Indicates if the remote device is currently connected. - A PropertiesChanged signal indicate changes to this - status. - - boolean Trusted [readwrite] - - Indicates if the remote is seen as trusted. This - setting can be changed by the application. - - boolean Blocked [readwrite] - - If set to true any incoming connections from the - device will be immediately rejected. Any device - drivers will also be removed and no new ones will - be probed as long as the device is blocked. - - boolean WakeAllowed [readwrite] - - If set to true this device will be allowed to wake the - host from system suspend. - - string Alias [readwrite] - - The name alias for the remote device. The alias can - be used to have a different friendly name for the - remote device. - - In case no alias is set, it will return the remote - device name. Setting an empty string as alias will - convert it back to the remote device name. - - When resetting the alias with an empty string, the - property will default back to the remote name. - - object Adapter [readonly] - - The object path of the adapter the device belongs to. - - boolean LegacyPairing [readonly] - - Set to true if the device only supports the pre-2.1 - pairing mechanism. This property is useful during - device discovery to anticipate whether legacy or - simple pairing will occur if pairing is initiated. - - Note that this property can exhibit false-positives - in the case of Bluetooth 2.1 (or newer) devices that - have disabled Extended Inquiry Response support. - - string Modalias [readonly, optional] - - Remote Device ID information in modalias format - used by the kernel and udev. - - int16 RSSI [readonly, optional] - - Received Signal Strength Indicator of the remote - device (inquiry or advertising). - - int16 TxPower [readonly, optional] - - Advertised transmitted power level (inquiry or - advertising). - - dict ManufacturerData [readonly, optional] - - Manufacturer specific advertisement data. Keys are - 16 bits Manufacturer ID followed by its byte array - value. - - dict ServiceData [readonly, optional] - - Service advertisement data. Keys are the UUIDs in - string format followed by its byte array value. - - bool ServicesResolved [readonly] - - Indicate whether or not service discovery has been - resolved. - - array{byte} AdvertisingFlags [readonly, experimental] - - The Advertising Data Flags of the remote device. - - dict AdvertisingData [readonly, experimental] - - The Advertising Data of the remote device. Keys are - are 8 bits AD Type followed by data as byte array. - - Note: Only types considered safe to be handled by - application are exposed. - - Possible values: - - ... - - Example: - - 0x26 0x01 0x01... - - array{object, dict} Sets [readonly, experimental] - - The object paths of the sets the device belongs to - followed by a dictionary which can contain the - following: - - byte Rank: - - Rank of the device in the Set. diff -Nru bluez-5.70/doc/gatt-api.txt bluez-5.71/doc/gatt-api.txt --- bluez-5.70/doc/gatt-api.txt 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/doc/gatt-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,512 +0,0 @@ -BlueZ D-Bus GATT API description -******************************** - -GATT local and remote services share the same high-level D-Bus API. Local -refers to GATT based service exported by a BlueZ plugin or an external -application. Remote refers to GATT services exported by the peer. - -BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and -Properties (or the opposite). Support for D-Bus Object Manager is mandatory for -external services to allow seamless GATT declarations (Service, Characteristic -and Descriptors) discovery. Each GATT service tree is required to export a D-Bus -Object Manager at its root that is solely responsible for the objects that -belong to that service. - -Releasing a registered GATT service is not defined yet. Any API extension -should avoid breaking the defined API, and if possible keep an unified GATT -remote and local services representation. - -Service hierarchy -================= - -GATT remote and local service representation. Object path for local services -is freely definable. - -External applications implementing local services must register the services -using GattManager1 registration method and must implement the methods and -properties defined in GattService1 interface. - -Service org.bluez -Interface org.bluez.GattService1 -Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX - -Properties string UUID [read-only] - - 128-bit service UUID. - - boolean Primary [read-only] - - Indicates whether or not this GATT service is a - primary service. If false, the service is secondary. - - object Device [read-only, optional] - - Object path of the Bluetooth device the service - belongs to. Only present on services from remote - devices. - - array{object} Includes [read-only, optional] - - Array of object paths representing the included - services of this service. - - uint16 Handle [read-write, optional] (Server Only) - [read-only] (Client Only) - - Service handle. When available in the server it - would attempt to use to allocate into the database - which may fail, to auto allocate the value 0x0000 - shall be used which will cause the allocated handle to - be set once registered. - - -Characteristic hierarchy -======================== - -For local GATT defined services, the object paths need to follow the service -path hierarchy and are freely definable. - -Service org.bluez -Interface org.bluez.GattCharacteristic1 -Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY - -Methods array{byte} ReadValue(dict options) - - Issues a request to read the value of the - characteristic and returns the value if the - operation was successful. - - Possible options: "offset": uint16 offset - "mtu": Exchanged MTU (Server only) - "device": Object Device (Server only) - - Possible Errors: org.bluez.Error.Failed(string ecode) - org.bluez.Error.InProgress - org.bluez.Error.NotPermitted - org.bluez.Error.NotAuthorized - org.bluez.Error.InvalidOffset - org.bluez.Error.NotSupported - - Possible Error Code: string 0x80 - 0x9f - - void WriteValue(array{byte} value, dict options) - - Issues a request to write the value of the - characteristic. - - Possible options: "offset": Start offset - "type": string - Possible values: - "command": Write without - response - "request": Write with response - "reliable": Reliable Write - "mtu": Exchanged MTU (Server only) - "device": Device path (Server only) - "link": Link type (Server only) - "prepare-authorize": True if prepare - authorization - request - - Possible Errors: org.bluez.Error.Failed(string ecode) - org.bluez.Error.InProgress - org.bluez.Error.NotPermitted - org.bluez.Error.InvalidValueLength - org.bluez.Error.NotAuthorized - org.bluez.Error.NotSupported - - Possible Error Code: string 0x80 - 0x9f - - fd, uint16 AcquireWrite(dict options) [optional] - - Acquire file descriptor and MTU for writing. Only - sockets are supported. Usage of WriteValue will be - locked causing it to return NotPermitted error. - - For server the MTU returned shall be equal or smaller - than the negotiated MTU. - - For client it only works with characteristic that has - WriteAcquired property which relies on - write-without-response Flag. - - To release the lock the client shall close the file - descriptor, a HUP is generated in case the device - is disconnected. - - Note: the MTU can only be negotiated once and is - symmetric therefore this method may be delayed in - order to have the exchange MTU completed, because of - that the file descriptor is closed during - reconnections as the MTU has to be renegotiated. - - Possible options: "device": Object Device (Server only) - "mtu": Exchanged MTU (Server only) - "link": Link type (Server only) - - Possible Errors: org.bluez.Error.Failed - org.bluez.Error.NotSupported - - fd, uint16 AcquireNotify(dict options) [optional] - - Acquire file descriptor and MTU for notify. Only - sockets are support. Usage of StartNotify will be locked - causing it to return NotPermitted error. - - For server the MTU returned shall be equal or smaller - than the negotiated MTU. - - Only works with characteristic that has NotifyAcquired - which relies on notify Flag and no other client have - called StartNotify. - - Notification are enabled during this procedure so - StartNotify shall not be called, any notification - will be dispatched via file descriptor therefore the - Value property is not affected during the time where - notify has been acquired. - - To release the lock the client shall close the file - descriptor, a HUP is generated in case the device - is disconnected. - - Note: the MTU can only be negotiated once and is - symmetric therefore this method may be delayed in - order to have the exchange MTU completed, because of - that the file descriptor is closed during - reconnections as the MTU has to be renegotiated. - - Possible options: "device": Object Device (Server only) - "mtu": Exchanged MTU (Server only) - "link": Link type (Server only) - - Possible Errors: org.bluez.Error.Failed - org.bluez.Error.NotSupported - - void StartNotify() - - Starts a notification session from this characteristic - if it supports value notifications or indications. - - Possible Errors: org.bluez.Error.Failed - org.bluez.Error.NotPermitted - org.bluez.Error.InProgress - org.bluez.Error.NotConnected - org.bluez.Error.NotSupported - - void StopNotify() - - This method will cancel any previous StartNotify - transaction. Note that notifications from a - characteristic are shared between sessions thus - calling StopNotify will release a single session. - - Possible Errors: org.bluez.Error.Failed - - void Confirm() [optional] (Server only) - - This method doesn't expect a reply so it is just a - confirmation that value was received. - - Possible Errors: org.bluez.Error.Failed - -Properties string UUID [read-only] - - 128-bit characteristic UUID. - - object Service [read-only] - - Object path of the GATT service the characteristic - belongs to. - - array{byte} Value [read-only, optional] - - The cached value of the characteristic. This property - gets updated only after a successful read request and - when a notification or indication is received, upon - which a PropertiesChanged signal will be emitted. - - boolean WriteAcquired [read-only, optional] - - True, if this characteristic has been acquired by any - client using AcquireWrite. - - For client properties is ommited in case - 'write-without-response' flag is not set. - - For server the presence of this property indicates - that AcquireWrite is supported. - - boolean NotifyAcquired [read-only, optional] - - True, if this characteristic has been acquired by any - client using AcquireNotify. - - For client this properties is ommited in case 'notify' - flag is not set. - - For server the presence of this property indicates - that AcquireNotify is supported. - - boolean Notifying [read-only, optional] - - True, if notifications or indications on this - characteristic are currently enabled. - - array{string} Flags [read-only] - - Defines how the characteristic value can be used. See - Core spec "Table 3.5: Characteristic Properties bit - field", and "Table 3.8: Characteristic Extended - Properties bit field". - - The "x-notify" and "x-indicate" flags restrict access - to notifications and indications by imposing write - restrictions on a characteristic's client - characteristic configuration descriptor. - - Allowed values: - - "broadcast" - "read" - "write-without-response" - "write" - "notify" - "indicate" - "authenticated-signed-writes" - "extended-properties" - "reliable-write" - "writable-auxiliaries" - "encrypt-read" - "encrypt-write" - "encrypt-notify" (Server only) - "encrypt-indicate" (Server only) - "encrypt-authenticated-read" - "encrypt-authenticated-write" - "encrypt-authenticated-notify" (Server only) - "encrypt-authenticated-indicate" (Server only) - "secure-read" (Server only) - "secure-write" (Server only) - "secure-notify" (Server only) - "secure-indicate" (Server only) - "authorize" - - uint16 Handle [read-write, optional] (Server Only) - [read-only] (Client Only) - - Characteristic handle. When available in the server it - would attempt to use to allocate into the database - which may fail, to auto allocate the value 0x0000 - shall be used which will cause the allocated handle to - be set once registered. - - uint16 MTU [read-only] - - Characteristic MTU, this is valid both for ReadValue - and WriteValue but either method can use long - procedures when supported. - -Characteristic Descriptors hierarchy -==================================== - -Local or remote GATT characteristic descriptors hierarchy. - -Service org.bluez -Interface org.bluez.GattDescriptor1 -Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ - -Methods array{byte} ReadValue(dict flags) - - Issues a request to read the value of the - characteristic and returns the value if the - operation was successful. - - Possible options: "offset": Start offset - "device": Device path (Server only) - "link": Link type (Server only) - - Possible Errors: org.bluez.Error.Failed - org.bluez.Error.InProgress - org.bluez.Error.NotPermitted - org.bluez.Error.NotAuthorized - org.bluez.Error.NotSupported - - void WriteValue(array{byte} value, dict flags) - - Issues a request to write the value of the - characteristic. - - Possible options: "offset": Start offset - "device": Device path (Server only) - "link": Link type (Server only) - "prepare-authorize": boolean Is prepare - authorization - request - - Possible Errors: org.bluez.Error.Failed - org.bluez.Error.InProgress - org.bluez.Error.NotPermitted - org.bluez.Error.InvalidValueLength - org.bluez.Error.NotAuthorized - org.bluez.Error.NotSupported - -Properties string UUID [read-only] - - 128-bit descriptor UUID. - - object Characteristic [read-only] - - Object path of the GATT characteristic the descriptor - belongs to. - - array{byte} Value [read-only, optional] - - The cached value of the descriptor. This property - gets updated only after a successful read request, upon - which a PropertiesChanged signal will be emitted. - - array{string} Flags [read-only] - - Defines how the descriptor value can be used. - - Possible values: - - "read" - "write" - "encrypt-read" - "encrypt-write" - "encrypt-authenticated-read" - "encrypt-authenticated-write" - "secure-read" (Server Only) - "secure-write" (Server Only) - "authorize" - - uint16 Handle [read-write, optional] (Server Only) - [read-only] (Client Only) - - Characteristic handle. When available in the server it - would attempt to use to allocate into the database - which may fail, to auto allocate the value 0x0000 - shall be used which will cause the allocated handle to - be set once registered. - -GATT Profile hierarchy -===================== - -Local profile (GATT client) instance. By registering this type of object -an application effectively indicates support for a specific GATT profile -and requests automatic connections to be established to devices -supporting it. - -Service -Interface org.bluez.GattProfile1 -Object path - -Methods void Release() - - This method gets called when the service daemon - unregisters the profile. The profile can use it to - do cleanup tasks. There is no need to unregister the - profile, because when this method gets called it has - already been unregistered. - -Properties array{string} UUIDs [read-only] - - 128-bit GATT service UUIDs to auto connect. - - -GATT Manager hierarchy -====================== - -GATT Manager allows external applications to register GATT services and -profiles. - -Registering a profile allows applications to subscribe to *remote* services. -These must implement the GattProfile1 interface defined above. - -Registering a service allows applications to publish a *local* GATT service, -which then becomes available to remote devices. A GATT service is represented by -a D-Bus object hierarchy where the root node corresponds to a service and the -child nodes represent characteristics and descriptors that belong to that -service. Each node must implement one of GattService1, GattCharacteristic1, -or GattDescriptor1 interfaces described above, based on the attribute it -represents. Each node must also implement the standard D-Bus Properties -interface to expose their properties. These objects collectively represent a -GATT service definition. - -To make service registration simple, BlueZ requires that all objects that belong -to a GATT service be grouped under a D-Bus Object Manager that solely manages -the objects of that service. Hence, the standard DBus.ObjectManager interface -must be available on the root service path. An example application hierarchy -containing two separate GATT services may look like this: - --> /com/example - | - org.freedesktop.DBus.ObjectManager - | - -> /com/example/service0 - | | - org.freedesktop.DBus.Properties - | | - org.bluez.GattService1 - | | - | -> /com/example/service0/char0 - | | - org.freedesktop.DBus.Properties - | | - org.bluez.GattCharacteristic1 - | | - | -> /com/example/service0/char1 - | | - org.freedesktop.DBus.Properties - | | - org.bluez.GattCharacteristic1 - | | - | -> /com/example/service0/char1/desc0 - | - org.freedesktop.DBus.Properties - | - org.bluez.GattDescriptor1 - | - -> /com/example/service1 - | - org.freedesktop.DBus.Properties - | - org.bluez.GattService1 - | - -> /com/example/service1/char0 - - org.freedesktop.DBus.Properties - - org.bluez.GattCharacteristic1 - -When a service is registered, BlueZ will automatically obtain information about -all objects using the service's Object Manager. Once a service has been -registered, the objects of a service should not be removed. If BlueZ receives an -InterfacesRemoved signal from a service's Object Manager, it will immediately -unregister the service. Similarly, if the application disconnects from the bus, -all of its registered services will be automatically unregistered. -InterfacesAdded signals will be ignored. - -Examples: - - Client - test/example-gatt-client - client/bluetoothctl - - Server - test/example-gatt-server - tools/gatt-service - - -Service org.bluez -Interface org.bluez.GattManager1 -Object path [variable prefix]/{hci0,hci1,...} - -Methods void RegisterApplication(object application, dict options) - - Registers a local GATT services hierarchy as described - above (GATT Server) and/or GATT profiles (GATT Client). - - The application object path together with the D-Bus - system bus connection ID define the identification of - the application registering a GATT based - service or profile. - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.AlreadyExists - - void UnregisterApplication(object application) - - This unregisters the services that has been - previously registered. The object path parameter - must match the same value that has been used - on registration. - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.DoesNotExist diff -Nru bluez-5.70/doc/input-api.txt bluez-5.71/doc/input-api.txt --- bluez-5.70/doc/input-api.txt 2013-05-14 09:04:08.000000000 +0800 +++ bluez-5.71/doc/input-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,32 +0,0 @@ -BlueZ D-Bus Input API description -********************************* - -Input hierarchy -=============== - -Service org.bluez -Interface org.bluez.Input1 -Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX - -Properties string ReconnectMode [readonly] - - Determines the Connectability mode of the HID device as - defined by the HID Profile specification, Section 5.4.2. - - This mode is based in the two properties - HIDReconnectInitiate (see Section 5.3.4.6) and - HIDNormallyConnectable (see Section 5.3.4.14) which - define the following four possible values: - - "none" Device and host are not required to - automatically restore the connection. - - "host" Bluetooth HID host restores connection. - - "device" Bluetooth HID device restores - connection. - - "any" Bluetooth HID device shall attempt to - restore the lost connection, but - Bluetooth HID Host may also restore the - connection. diff -Nru bluez-5.70/doc/media-api.rst bluez-5.71/doc/media-api.rst --- bluez-5.70/doc/media-api.rst 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/doc/media-api.rst 1970-01-01 08:00:00.000000000 +0800 @@ -1,1047 +0,0 @@ -=================================== -BlueZ D-Bus Media API documentation -=================================== - - -Media interface -=============== - -:Service: org.bluez -:Interface: org.bluez.Media1 -:Object path: [variable prefix]/{hci0,hci1,...} - -Methods -------- - -void RegisterEndpoint(object endpoint, dict properties) -``````````````````````````````````````````````````````` - - Register a local end point to sender, the sender can register as many - end points as it likes. - - Note: If the sender disconnects the end points are automatically - unregistered. - - possible properties: - - :string UUID: - - UUID of the profile which the endpoint is for. - - UUID must be in the list of SupportedUUIDS. - - :byte Codec: - - Assigned number of codec that the endpoint implements. The - values should match the profile specification which is - indicated by the UUID. - - :uint32_t Vendor [Optional]: - - Vendor-specific Company ID, Codec ID tuple that the endpoint - implements. - - It shall be set to appropriate value when Vendor Specific Codec - (0xff) is used. - - :array{byte} Capabilities: - - Capabilities blob, it is used as it is so the size and byte - order must match. - - :array{byte} Metadata [Optional]: - - Metadata blob, it is used as it is so the size and byte order - must match. - - Possible Errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.NotSupported: - - emitted when interface for the end-point is disabled - -void UnregisterEndpoint(object endpoint) -```````````````````````````````````````` - Unregister sender end point. - -void RegisterPlayer(object player, dict properties) -``````````````````````````````````````````````````` - - Register a media player object to sender, the sender can register as - many objects as it likes. - - Object must implement at least org.mpris.MediaPlayer2.Player as defined - in MPRIS 2.2 spec: - - http://specifications.freedesktop.org/mpris-spec/latest/ - - Note: If the sender disconnects its objects are automatically - unregistered. - - Possible Errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.NotSupported: - -void UnregisterPlayer(object player) -```````````````````````````````````` - - Unregister sender media player. - -void RegisterApplication(object root, dict options) -``````````````````````````````````````````````````` - - Register endpoints an player objects within root object which must - implement ObjectManager. - - The application object path together with the D-Bus system bus - connection ID define the identification of the application. - - Possible errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.AlreadyExists: - -void UnregisterApplication(object application) -`````````````````````````````````````````````` - - This unregisters the services that has been previously registered. The - object path parameter must match the same value that has been used on - registration. - - Possible errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.DoesNotExist: - -Properties ----------- - -array{string} SupportedUUIDs [readonly] -``````````````````````````````````````` - - List of 128-bit UUIDs that represents the supported Endpoint - registration. - -MediaControl interface -====================== - -:Service: org.bluez -:Interface: org.bluez.MediaControl1 -:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX - -Methods -------- - -void Play() [Deprecated] -```````````````````````` - - Resume playback. - -void Pause() [Deprecated] -````````````````````````` - - Pause playback. - -void Stop() [Deprecated] -```````````````````````` - - Stop playback. - -void Next() [Deprecated] -```````````````````````` - - Next item. - -void Previous() [Deprecated] -```````````````````````````` - - Previous item. - -void VolumeUp() [Deprecated] -```````````````````````````` - - Adjust remote volume one step up - -void VolumeDown() [Deprecated] -`````````````````````````````` - - Adjust remote volume one step down - -void FastForward() [Deprecated] -``````````````````````````````` - - Fast forward playback, this action is only stopped when another method - in this interface is called. - -void Rewind() [Deprecated] -`````````````````````````` - - Rewind playback, this action is only stopped when another method in - this interface is called. - -Properties ----------- - -boolean Connected [readonly] -```````````````````````````` - -object Player [readonly, optional] -`````````````````````````````````` - - Addressed Player object path. - -MediaPlayer interface -===================== - -:Service: org.bluez (Controller role) -:Interface: org.bluez.MediaPlayer1 -:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX - -Methods -------- - -void Play() -``````````` - - Resume playback. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Pause() -```````````` - - Pause playback. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Stop() -``````````` - - Stop playback. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Next() -``````````` - - Next item. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Previous() -``````````````` - - Previous item. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void FastForward() -`````````````````` - - Fast forward playback, this action is only stopped when another method - in this interface is called. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Rewind() -````````````` - - Rewind playback, this action is only stopped when another method in - this interface is called. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Press(byte avc_key) -```````````````````````` - - Press a specific key to send as passthrough command. The key will be - released automatically. Use Hold() instead if the intention is to hold - down the key. - - Possible Errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Hold(byte avc_key) -``````````````````````` - - Press and hold a specific key to send as passthrough command. It is - your responsibility to make sure that Release() is called after calling - this method. The held key will also be released when any other method - in this interface is called. - - Possible Errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void Release() -`````````````` - - Release the previously held key invoked using Hold(). - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -Properties ----------- - -string Equalizer [readwrite] -```````````````````````````` - - Possible values: "off" or "on" - -string Repeat [readwrite] -````````````````````````` - - Possible values: "off", "singletrack", "alltracks" or "group" - -string Shuffle [readwrite] -`````````````````````````` - - Possible values: "off", "alltracks" or "group" - -string Scan [readwrite] -``````````````````````` - - Possible values: "off", "alltracks" or "group" - -string Status [readonly] -```````````````````````` - - Possible status: "playing", "stopped", "paused", "forward-seek", - "reverse-seek" or "error" - -uint32 Position [readonly] -`````````````````````````` - - Playback position in milliseconds. Changing the position may generate - additional events that will be sent to the remote device. When position - is 0 it means the track is starting and when it's greater than or equal - to track's duration the track has ended. - - Note that even if duration is not available in metadata it's possible - to signal its end by setting position to the maximum uint32 value. - -dict Track [readonly] -````````````````````` - - Track metadata. - - Possible values: - - :string Title: - - Track title name - - :string Artist: - - Track artist name - - :string Album: - - Track album name - - :string Genre: - - Track genre name - - :uint32 NumberOfTracks: - - Number of tracks in total - - :uint32 TrackNumber: - - Track number - - :uint32 Duration: - - Track duration in milliseconds - -object Device [readonly] -```````````````````````` - - Device object path. - -string Name [readonly] -`````````````````````` - - Player name - -string Type [readonly] -`````````````````````` - - Player type - - Possible values: - - "Audio" - "Video" - "Audio Broadcasting" - "Video Broadcasting" - -string Subtype [readonly] -````````````````````````` - - Player subtype - - Possible values: - - "Audio Book" - "Podcast" - -boolean Browsable [readonly] -```````````````````````````` - - If present indicates the player can be browsed using MediaFolder - interface. - - Possible values: - - :True: - - Supported and active - - :False: - - Supported but inactive - - Note: If supported but inactive clients can enable it by using - MediaFolder interface but it might interfere in the playback of other - players. - -boolean Searchable [readonly] -````````````````````````````` - - If present indicates the player can be searched using MediaFolder - interface. - - Possible values: - - :True: - - Supported and active - - :False: - - Supported but inactive - - Note: If supported but inactive clients can enable it by using - MediaFolder interface but it might interfere in the playback of other - players. - -object Playlist -``````````````` - - Playlist object path. - -MediaFolder interface -===================== - -:Service: unique name (Target role) - org.bluez (Controller role) -:Interface: org.bluez.MediaFolder1 -:Object path: freely definable (Target role) - [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX - (Controller role) - -Methods -------- - -object Search(string value, dict filter) -```````````````````````````````````````` - - Return a folder object containing the search result. - - To list the items found use the folder object returned and pass to - ChangeFolder. - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -array{objects, properties} ListItems(dict filter) -````````````````````````````````````````````````` - - Return a list of items found - - Possible Errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void ChangeFolder(object folder) -```````````````````````````````` - - Change current folder. - - Note: By changing folder the items of previous folder might be destroyed - and have to be listed again, the exception is NowPlaying folder which - should be always present while the player is active. - - Possible Errors: - - :org.bluez.Error.InvalidArguments: - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -Properties ----------- - -uint32 NumberOfItems [readonly] -``````````````````````````````` - - Number of items in the folder - -string Name [readonly] -`````````````````````` - - Folder name: - - Possible values: - - :"/Filesystem/...": - - Filesystem scope - - :"/NowPlaying/...": - - NowPlaying scope - - Note: /NowPlaying folder might not be listed if player is stopped, - folders created by Search are virtual so once another Search is perform - or the folder is changed using ChangeFolder it will no longer be listed. - -Filters -------- - -:uint32 Start: - - Offset of the first item. - - Default value: 0 - -:uint32 End: - - Offset of the last item. - - Default value: NumbeOfItems - -:array{string} Attributes: - - Item properties that should be included in the list. - - Possible Values: - - "title", "artist", "album", "genre", "number-of-tracks", - "number", "duration" - - Default Value: All - -MediaItem interface -=================== - -:Service: unique name (Target role) - org.bluez (Controller role) -:Interface: org.bluez.MediaItem1 -:Object path: freely definable (Target role) - [variable - prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX - (Controller role) - -Methods -------- - -void Play() -``````````` - - Play item - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -void AddtoNowPlaying() -`````````````````````` - - Add item to now playing list - - Possible Errors: - - :org.bluez.Error.NotSupported: - :org.bluez.Error.Failed: - -Properties ----------- - -object Player [readonly] -```````````````````````` - - Player object path the item belongs to - -string Name [readonly] -`````````````````````` - - Item displayable name - -string Type [readonly] -`````````````````````` - - Item type - - Possible values: "video", "audio", "folder" - -string FolderType [readonly, optional] -`````````````````````````````````````` - - Folder type. - - Possible values: "mixed", "titles", "albums", "artists" - - Available if property Type is "Folder" - -boolean Playable [readonly, optional] -````````````````````````````````````` - - Indicates if the item can be played - - Available if property Type is "folder" - -dict Metadata [readonly] -```````````````````````` - - Item metadata. - - Possible values: - - :string Title: - - Item title name - - Available if property Type is "audio" or "video" - - :string Artist: - - Item artist name - - Available if property Type is "audio" or "video" - - :string Album: - - Item album name - - Available if property Type is "audio" or "video" - - :string Genre: - - Item genre name - - Available if property Type is "audio" or "video" - - :uint32 NumberOfTracks: - - Item album number of tracks in total - - Available if property Type is "audio" or "video" - - :uint32 Number: - - Item album number - - Available if property Type is "audio" or "video" - - :uint32 Duration: - - Item duration in milliseconds - - Available if property Type is "audio" or "video" - -MediaEndpoint interface -======================= - -:Service: unique name (Server role) - org.bluez (Client role) -:Interface: org.bluez.MediaEndpoint1 -:Object path: freely definable (Server role) - [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX - (Client role) - -Methods -------- - -void SetConfiguration(object transport, dict properties) -```````````````````````````````````````````````````````` - - Set configuration for the transport. - - For client role transport must be set with a server endpoint oject which - will be configured and the properties must contain the following - properties: - - :array{byte} Capabilities [Mandatory]: - :array{byte} Metadata [ISO only]: - :byte CIG [ISO only]: - :byte CIS [ISO only]: - :uint32 Interval [ISO only]: - :bool Framing [ISO only]: - :string PHY [ISO only]: - :uint16 SDU [ISO only]: - :byte Retransmissions [ISO only]: - :uint16 Latency [ISO only]: - :uint32 Delay [ISO only]: - :uint8 TargetLatency [ISO Latency]: - :byte BIG [ISO broadcast only]: - :byte BIS [ISO broadcast only]: - :byte SyncInterval [ISO broadcast only]: - :byte Encryption [ISO broadcast only]: - :byte Options [ISO broadcast only]: - :uint16 Skip [ISO broadcast only]: - :uint16 SyncTimeout [ISO broadcast only]: - :byte SyncCteType [ISO broadcast only]: - :byte MSE [ISO broadcast only]: - :uint16 Timeout [ISO broadcast only]: - :array{byte} BroadcastCode [ISO broadcast only]: - -array{byte} SelectConfiguration(array{byte} capabilities) -````````````````````````````````````````````````````````` - - Select preferable configuration from the supported capabilities. - - Returns a configuration which can be used to setup a transport. - - Note: There is no need to cache the selected configuration since on - success the configuration is send back as parameter of SetConfiguration. - -dict SelectProperties(dict properties) -`````````````````````````````````````` - - Select preferable properties from the supported properties: - - :object Endpoint [ISO only]: - :Refer to SetConfiguration for the list of other possible properties.: - - Returns propeties which can be used to setup a transport. - - Note: There is no need to cache the selected properties since on - success the configuration is send back as parameter of SetConfiguration. - -void ClearConfiguration(object transport) -````````````````````````````````````````` - - Clear transport configuration. - -void Release() -`````````````` - - This method gets called when the service daemon unregisters the - endpoint. An endpoint can use it to do cleanup tasks. There is no need - to unregister the endpoint, because when this method gets called it has - already been unregistered. - -Properties ----------- - -string UUID [readonly, optional] -```````````````````````````````` - - UUID of the profile which the endpoint is for. - -byte Codec [readonly, optional] -``````````````````````````````` - - Assigned number of codec that the endpoint implements. - The values should match the profile specification which is indicated by - the UUID. - -uint32_t Vendor [readonly, Optional] -```````````````````````````````````` - - Vendor-specific Company ID, Codec ID tuple that the endpoint implements. - - It shall be set to appropriate value when Vendor Specific Codec (0xff) - is used. - -array{byte} Capabilities [readonly, optional] -````````````````````````````````````````````` - - Capabilities blob, it is used as it is so the size and byte order must - match. - -array{byte} Metadata [readonly, Optional] -````````````````````````````````````````` - - Metadata blob, it is used as it is so the size and byte order must - match. - -object Device [readonly, optional] -`````````````````````````````````` - - Device object which the endpoint is belongs to. - -bool DelayReporting [readonly, optional] -```````````````````````````````````````` - - Indicates if endpoint supports Delay Reporting. - -byte Framing [ISO only] -``````````````````````` - - Indicates endpoint support framing. - -byte PHY [ISO only] -``````````````````` - - Indicates endpoint supported PHY. - -uint16_t MaximumLatency [ISO only] -`````````````````````````````````` - - Indicates endpoint maximum latency. - -uint32_t MinimumDelay [ISO only] -```````````````````````````````` - - Indicates endpoint minimum presentation delay. - -uint32_t MaximumDelay [ISO only] -```````````````````````````````` - - Indicates endpoint maximum presentation delay. - -uint32_t PreferredMinimumDelay [ISO only] -````````````````````````````````````````` - - Indicates endpoint preferred minimum presentation delay. - -uint32_t PreferredMinimumDelay [ISO only] -````````````````````````````````````````` - - Indicates endpoint preferred minimum presentation delay. - -uint32 Location [ISO only] -`````````````````````````` - - Indicates endpoint supported locations. - -uint16 SupportedContext [ISO only] -`````````````````````````````````` - - Indicates endpoint supported audio context. - -uint16 Context [ISO only] -````````````````````````` - - Indicates endpoint available audio context. - -MediaTransport interface -======================== - -:Service: org.bluez -:Interface: org.bluez.MediaTransport1 -:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX - -Methods -------- - -fd, uint16, uint16 Acquire() -```````````````````````````` - - Acquire transport file descriptor and the MTU for read and write - respectively. - - Possible Errors: - - :org.bluez.Error.NotAuthorized: - :org.bluez.Error.Failed: - -fd, uint16, uint16 TryAcquire() -``````````````````````````````` - - Acquire transport file descriptor only if the transport is in "pending" - state at the time the message is received by BlueZ. Otherwise no request - will be sent to the remote device and the function will just fail with - org.bluez.Error.NotAvailable. - - Possible Errors: - - :org.bluez.Error.NotAuthorized: - :org.bluez.Error.Failed: - :org.bluez.Error.NotAvailable: - -void Release() -`````````````` - - Releases file descriptor. - -Properties ----------- - -object Device [readonly] -```````````````````````` - - Device object which the transport is connected to. - -string UUID [readonly] -`````````````````````` - - UUID of the profile which the transport is for. - -byte Codec [readonly] -````````````````````` - - Assigned number of codec that the transport support. - The values should match the profile specification which is indicated by - the UUID. - -array{byte} Configuration [readonly] -```````````````````````````````````` - - Configuration blob, it is used as it is so the size and byte order must - match. - -string State [readonly] -``````````````````````` - - Indicates the state of the transport. Possible values are: - - :"idle": not streaming - :"pending": streaming but not acquired - :"active": streaming and acquired - -uint16 Delay [readwrite, optional] -`````````````````````````````````` - - Transport delay in 1/10 of millisecond, this property is only writeable - when the transport was acquired by the sender. - -uint16 Volume [readwrite, optional] -``````````````````````````````````` - - Indicates volume level of the transport, this property is only writeable - when the transport was acquired by the sender. - - Possible Values: 0-127 - -object Endpoint [readonly, optional, experimental] -`````````````````````````````````````````````````` - - Endpoint object which the transport is associated with. - -uint32 Location [readonly, ISO only, experimental] -`````````````````````````````````````````````````` - - Indicates transport Audio Location. - -array{byte} Metadata [readwrite, ISO Only, experimental] -```````````````````````````````````````````````````````` - - Indicates transport Metadata. - -array{object} Links [readonly, optional, ISO only, experimental] -```````````````````````````````````````````````````````````````` - - Linked transport objects which the transport is associated with. - -dict QoS [readonly, optional, ISO only, experimental] -````````````````````````````````````````````````````` - - Only present when QoS is configured. - - Possible values for Unicast: - - :byte CIG: - - Indicates configured CIG. - - :byte CIS: - - Indicates configured CIS. - - :uint32 Interval: - - Indicates configured ISO interval. - - :boolean Framing: - - Indicates configured framing. - - :byte PHY: - - Indicates configured PHY. - - :uint16 SDU: - - Indicates configured SDU. - - :byte Retransmissions: - - Indicates configured retransmissions. - - :uint16 Latency: - - Indicates configured transport latency. - - Possible values for Broadcast: - - :byte BIG: - - Indicates configured QoS BIG. - - :byte BIS: - - Indicates configured BIS. - - :uint32 SyncFactor: - - Indicates configured sync factor. - - :uint32 Interval: - - Indicates configured ISO interval. - - :byte PHY: - - Indicates configured PHY. - - :uint16 SDU: - - Indicates configured maximum SDU. - - :byte SyncTimeout: - - Indicates configured broadcast sync timeout. - - :uint16 Latency: - - Indicates configured transport latency. diff -Nru bluez-5.70/doc/network-api.txt bluez-5.71/doc/network-api.txt --- bluez-5.70/doc/network-api.txt 2012-12-25 01:46:54.000000000 +0800 +++ bluez-5.71/doc/network-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,76 +0,0 @@ -BlueZ D-Bus Network API description -*********************************** - - -Network hierarchy -================= - -Service org.bluez -Interface org.bluez.Network1 -Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX - -Methods string Connect(string uuid) - - Connect to the network device and return the network - interface name. Examples of the interface name are - bnep0, bnep1 etc. - - uuid can be either one of "gn", "panu" or "nap" (case - insensitive) or a traditional string representation of - UUID or a hexadecimal number. - - The connection will be closed and network device - released either upon calling Disconnect() or when - the client disappears from the message bus. - - Possible errors: org.bluez.Error.AlreadyConnected - org.bluez.Error.ConnectionAttemptFailed - - void Disconnect() - - Disconnect from the network device. - - To abort a connection attempt in case of errors or - timeouts in the client it is fine to call this method. - - Possible errors: org.bluez.Error.Failed - -Properties boolean Connected [readonly] - - Indicates if the device is connected. - - string Interface [readonly] - - Indicates the network interface name when available. - - string UUID [readonly] - - Indicates the connection role when available. - - -Network server hierarchy -======================== - -Service org.bluez -Interface org.bluez.NetworkServer1 -Object path /org/bluez/{hci0,hci1,...} - -Methods void Register(string uuid, string bridge) - - Register server for the provided UUID. Every new - connection to this server will be added the bridge - interface. - - Valid UUIDs are "gn", "panu" or "nap". - - Initially no network server SDP is provided. Only - after this method a SDP record will be available - and the BNEP server will be ready for incoming - connections. - - void Unregister(string uuid) - - Unregister the server for provided UUID. - - All servers will be automatically unregistered when - the calling application terminates. diff -Nru bluez-5.70/doc/obex-agent-api.txt bluez-5.71/doc/obex-agent-api.txt --- bluez-5.70/doc/obex-agent-api.txt 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/doc/obex-agent-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,62 +0,0 @@ -OBEX D-Bus Agent API description -******************************** - - -Agent Manager hierarchy -======================= - -Service org.bluez.obex -Interface org.bluez.obex.AgentManager1 -Object path /org/bluez/obex - -Methods void RegisterAgent(object agent) - - Register an agent to request authorization of - the user to accept/reject objects. Object push - service needs to authorize each received object. - - Possible errors: org.bluez.obex.Error.AlreadyExists - - void UnregisterAgent(object agent) - - This unregisters the agent that has been previously - registered. The object path parameter must match the - same value that has been used on registration. - - Possible errors: org.bluez.obex.Error.DoesNotExist - - -Agent hierarchy -=============== - -Service unique name -Interface org.bluez.obex.Agent1 -Object path freely definable - -Methods void Release() - - This method gets called when the service daemon - unregisters the agent. An agent can use it to do - cleanup tasks. There is no need to unregister the - agent, because when this method gets called it has - already been unregistered. - - string AuthorizePush(object transfer) - - This method gets called when the service daemon - needs to accept/reject a Bluetooth object push request. - - Returns the full path (including the filename) or the - folder name suffixed with '/' where the object shall - be stored. The transfer object will contain a Filename - property that contains the default location and name - that can be returned. - - Possible errors: org.bluez.obex.Error.Rejected - org.bluez.obex.Error.Canceled - - void Cancel() - - This method gets called to indicate that the agent - request failed before a reply was returned. It cancels - the previous request. diff -Nru bluez-5.70/doc/obex-api.txt bluez-5.71/doc/obex-api.txt --- bluez-5.70/doc/obex-api.txt 2014-12-12 21:38:33.000000000 +0800 +++ bluez-5.71/doc/obex-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,894 +0,0 @@ -OBEX D-Bus API description -************************** - - -Client hierarchy -================ - -Service org.bluez.obex -Interface org.bluez.obex.Client1 -Object path /org/bluez/obex - -Methods object CreateSession(string destination, dict args) - - Create a new OBEX session for the given remote address. - - The last parameter is a dictionary to hold optional or - type-specific parameters. Typical parameters that can - be set in this dictionary include the following: - - string "Target" : type of session to be created - string "Source" : local address to be used - byte "Channel" - - The currently supported targets are the following: - - "ftp" - "map" - "opp" - "pbap" - "sync" - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - void RemoveSession(object session) - - Unregister session and abort pending transfers. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.NotAuthorized - -Session hierarchy -================= - -Service org.bluez.obex -Interface org.bluez.obex.Session1 -Object path /org/bluez/obex/server/session{0, 1, 2, ...} or - /org/bluez/obex/client/session{0, 1, 2, ...} - -Methods string GetCapabilities() - - Get remote device capabilities. - - Possible errors: org.bluez.obex.Error.NotSupported - org.bluez.obex.Error.Failed - -Properties string Source [readonly] - - Bluetooth adapter address - - string Destination [readonly] - - Bluetooth device address - - byte Channel [readonly] - - Bluetooth channel - - string Target [readonly] - - Target UUID - - string Root [readonly] - - Root path - - -Transfer hierarchy -================== - -Service org.bluez.obex -Interface org.bluez.obex.Transfer1 -Object path [Session object path]/transfer{0, 1, 2, ...} - -Methods void Cancel() - - Stops the current transference. - - Possible errors: org.bluez.obex.Error.NotAuthorized - org.bluez.obex.Error.InProgress - org.bluez.obex.Error.Failed - - void Suspend() - - Suspend transference. - - Possible errors: org.bluez.obex.Error.NotAuthorized - org.bluez.obex.Error.NotInProgress - - Note that it is not possible to suspend transfers - which are queued which is why NotInProgress is listed - as possible error. - - void Resume() - - Resume transference. - - Possible errors: org.bluez.obex.Error.NotAuthorized - org.bluez.obex.Error.NotInProgress - - Note that it is not possible to resume transfers - which are queued which is why NotInProgress is listed - as possible error. - -Properties string Status [readonly] - - Inform the current status of the transfer. - - Possible values: "queued", "active", "suspended", - "complete" or "error" - - object Session [readonly] - - The object path of the session the transfer belongs - to. - - string Name [readonly] - - Name of the transferred object. Either Name or Type - or both will be present. - - string Type [readonly] - - Type of the transferred object. Either Name or Type - or both will be present. - - uint64 Time [readonly, optional] - - Time of the transferred object if this is - provided by the remote party. - - uint64 Size [readonly, optional] - - Size of the transferred object. If the size is - unknown, then this property will not be present. - - uint64 Transferred [readonly, optional] - - Number of bytes transferred. For queued transfers, this - value will not be present. - - string Filename [readonly, optional] - - Complete name of the file being received or sent. - - For incoming object push transaction, this will be - the proposed default location and name. It can be - overwritten by the AuthorizePush agent callback - and will be then updated accordingly. - - -Object Push hierarchy -===================== - -Service org.bluez.obex -Interface org.bluez.obex.ObjectPush1 -Object path [Session object path] - -Methods object, dict SendFile(string sourcefile) - - Send one local file to the remote device. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - object, dict PullBusinessCard(string targetfile) - - Request the business card from a remote device and - store it in the local file. - - If an empty target file is given, a name will be - automatically calculated for the temporary file. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - object, dict ExchangeBusinessCards(string clientfile, - string targetfile) - - Push the client's business card to the remote device - and then retrieve the remote business card and store - it in a local file. - - If an empty target file is given, a name will be - automatically calculated for the temporary file. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - -File Transfer hierarchy -======================= - -Service org.bluez.obex -Interface org.bluez.obex.FileTransfer -Object path [Session object path] - -Methods void ChangeFolder(string folder) - - Change the current folder of the remote device. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - void CreateFolder(string folder) - - Create a new folder in the remote device. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - array{dict} ListFolder() - - Returns a dictionary containing information about - the current folder content. - - The following keys are defined: - - string Name : Object name in UTF-8 format - string Type : Either "folder" or "file" - uint64 Size : Object size or number of items in - folder - string Permission : Group, owner and other - permission - uint64 Modified : Last change - uint64 Accessed : Last access - uint64 Created : Creation date - - Possible errors: org.bluez.obex.Error.Failed - - object, dict GetFile(string targetfile, string sourcefile) - - Copy the source file (from remote device) to the - target file (on local filesystem). - - If an empty target file is given, a name will be - automatically calculated for the temporary file. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - object, dict PutFile(string sourcefile, string targetfile) - - Copy the source file (from local filesystem) to the - target file (on remote device). - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - void CopyFile(string sourcefile, string targetfile) - - Copy a file within the remote device from source file - to target file. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - void MoveFile(string sourcefile, string targetfile) - - Move a file within the remote device from source file - to the target file. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - void Delete(string file) - - Deletes the specified file/folder. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - -Phonebook Access hierarchy -========================== - -Service org.bluez.obex -Interface org.bluez.obex.PhonebookAccess1 -Object path [Session object path] - -Methods void Select(string location, string phonebook) - - Select the phonebook object for other operations. Should - be call before all the other operations. - - location : Where the phonebook is stored, possible - inputs : - "int" ( "internal" which is default ) - "sim" ( "sim1" ) - "sim2" - ... - - phonebook : Possible inputs : - "pb" : phonebook for the saved contacts - "ich": incoming call history - "och": outgoing call history - "mch": missing call history - "cch": combination of ich och mch - "spd": speed dials entry ( only for "internal" ) - "fav": favorites entry ( only for "internal" ) - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - object, dict PullAll(string targetfile, dict filters) - - Return the entire phonebook object from the PSE server - in plain string with vcard format, and store it in - a local file. - - If an empty target file is given, a name will be - automatically calculated for the temporary file. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible filters: Format, Order, Offset, MaxCount and - Fields - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Forbidden - - array{string vcard, string name} List(dict filters) - - Return an array of vcard-listing data where every entry - consists of a pair of strings containing the vcard - handle and the contact name. For example: - "1.vcf" : "John" - - Possible filters: Order, Offset and MaxCount - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Forbidden - - object, dict - Pull(string vcard, string targetfile, dict filters) - - Given a vcard handle, retrieve the vcard in the current - phonebook object and store it in a local file. - - If an empty target file is given, a name will be - automatically calculated for the temporary file. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possbile filters: Format and Fields - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Forbidden - org.bluez.obex.Error.Failed - - array{string vcard, string name} - Search(string field, string value, dict filters) - - Search for entries matching the given condition and - return an array of vcard-listing data where every entry - consists of a pair of strings containing the vcard - handle and the contact name. - - vcard : name paired string match the search condition. - - field : the field in the vcard to search with - { "name" (default) | "number" | "sound" } - value : the string value to search for - - - Possible filters: Order, Offset and MaxCount - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Forbidden - org.bluez.obex.Error.Failed - - uint16 GetSize() - - Return the number of entries in the selected phonebook - object that are actually used (i.e. indexes that - correspond to non-NULL entries). - - Possible errors: org.bluez.obex.Error.Forbidden - org.bluez.obex.Error.Failed - - void UpdateVersion() - - Attempt to update PrimaryCounter and SecondaryCounter. - - Possible errors: org.bluez.obex.Error.NotSupported - org.bluez.obex.Error.Forbidden - org.bluez.obex.Error.Failed - - array{string} ListFilterFields() - - Return All Available fields that can be used in Fields - filter. - - Possible errors: None - -Filter: string Format: - - Items vcard format - - Possible values: "vcard21" (default) or "vcard30" - - string Order: - - Items order - - Possible values: "indexed" (default), "alphanumeric" or - "phonetic" - - uint16 Offset: - - Offset of the first item, default is 0 - - uint16 MaxCount: - - Maximum number of items, default is unlimited (65535) - - array{string} Fields: - - Item vcard fields, default is all values. - - Possible values can be query with ListFilterFields. - - array{string} FilterAll: - - Filter items by fields using AND logic, cannot be used - together with FilterAny. - - Possible values can be query with ListFilterFields. - - array{string} FilterAny: - - Filter items by fields using OR logic, cannot be used - together with FilterAll. - - Possible values can be query with ListFilterFields. - - bool ResetNewMissedCalls - - Reset new the missed calls items, shall only be used - for folders mch and cch. - -Properties string Folder [readonly] - - Current folder. - - string DatabaseIdentifier [readonly, optional] - - 128 bits persistent database identifier. - - Possible values: 32-character hexadecimal such - as A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 - - string PrimaryCounter [readonly, optional] - - 128 bits primary version counter. - - Possible values: 32-character hexadecimal such - as A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 - - string SecondaryCounter [readonly, optional] - - 128 bits secondary version counter. - - Possible values: 32-character hexadecimal such - as A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 - - bool FixedImageSize [readonly, optional] - - Indicate support for fixed image size. - - Possible values: True if image is JPEG 300x300 pixels - otherwise False. - -Synchronization hierarchy -========================= - -Service org.bluez.obex -Interface org.bluez.obex.Synchronization1 -Object path [Session object path] - -Methods void SetLocation(string location) - - Set the phonebook object store location for other - operations. Should be called before all the other - operations. - - location: Where the phonebook is stored, possible - values: - "int" ( "internal" which is default ) - "sim1" - "sim2" - ...... - - Possible errors: org.bluez.obex.Error.InvalidArguments - - object, dict GetPhonebook(string targetfile) - - Retrieve an entire Phonebook Object store from remote - device, and stores it in a local file. - - If an empty target file is given, a name will be - automatically calculated for the temporary file. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - object, dict PutPhonebook(string sourcefile) - - Send an entire Phonebook Object store to remote device. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - -Message Access hierarchy -========================= - -Service org.bluez.obex -Interface org.bluez.obex.MessageAccess1 -Object path [Session object path] - -Methods void SetFolder(string name) - - Set working directory for current session, *name* may - be the directory name or '..[/dir]'. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - array{dict} ListFolders(dict filter) - - Returns a dictionary containing information about - the current folder content. - - The following keys are defined: - - string Name : Folder name - - Possible filters: Offset and MaxCount - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - array{string} ListFilterFields() - - Return all available fields that can be used in Fields - filter. - - Possible errors: None - - array{object, dict} ListMessages(string folder, dict filter) - - Returns an array containing the messages found in the - given subfolder of the current folder, or in the - current folder if folder is empty. - - Possible Filters: Offset, MaxCount, SubjectLength, Fields, - Type, PeriodStart, PeriodEnd, Status, Recipient, Sender, - Priority - - Each message is represented by an object path followed - by a dictionary of the properties. - - Properties: - - string Subject: - - Message subject - - string Timestamp: - - Message timestamp - - string Sender: - - Message sender name - - string SenderAddress: - - Message sender address - - string ReplyTo: - - Message Reply-To address - - string Recipient: - - Message recipient name - - string RecipientAddress: - - Message recipient address - - string Type: - - Message type - - Possible values: "email", "sms-gsm", - "sms-cdma" and "mms" - - uint64 Size: - - Message size in bytes - - boolean Text: - - Message text flag - - Specifies whether message has textual - content or is binary only - - string Status: - - Message status - - Possible values for received messages: - "complete", "fractioned", "notification" - - Possible values for sent messages: - "delivery-success", "sending-success", - "delivery-failure", "sending-failure" - - uint64 AttachmentSize: - - Message overall attachment size in bytes - - boolean Priority: - - Message priority flag - - boolean Read: - - Message read flag - - boolean Sent: - - Message sent flag - - boolean Protected: - - Message protected flag - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - void UpdateInbox(void) - - Request remote to update its inbox. - - Possible errors: org.bluez.obex.Error.Failed - - object, dict - PushMessage(string sourcefile, string folder, dict args) - - Transfer a message (in bMessage format) to the - remote device. - - The message is transferred either to the given - subfolder of the current folder, or to the current - folder if folder is empty. - - Possible args: Transparent, Retry, Charset - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetAll. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - - -Filter: uint16 Offset: - - Offset of the first item, default is 0 - - uint16 MaxCount: - - Maximum number of items, default is 1024 - - byte SubjectLength: - - Maximum length of the Subject property in the - message, default is 256 - - array{string} Fields: - - Message fields, default is all values. - - Possible values can be query with ListFilterFields. - - array{string} Types: - - Filter messages by type. - - Possible values: "sms", "email", "mms". - - string PeriodBegin: - - Filter messages by starting period. - - Possible values: Date in "YYYYMMDDTHHMMSS" format. - - string PeriodEnd: - - Filter messages by ending period. - - Possible values: Date in "YYYYMMDDTHHMMSS" format. - - boolean Read: - - Filter messages by read flag. - - Possible values: True for read or False for unread - - string Recipient: - - Filter messages by recipient address. - - string Sender: - - Filter messages by sender address. - - boolean Priority: - - Filter messages by priority flag. - - Possible values: True for high priority or False for - non-high priority - -Message hierarchy -================= - -Service org.bluez.obex -Interface org.bluez.obex.Message1 -Object path [Session object path]/{message0,...} - -Methods object, dict Get(string targetfile, boolean attachment) - - Download message and store it in the target file. - - If an empty target file is given, a temporary file - will be automatically generated. - - The returned path represents the newly created transfer, - which should be used to find out if the content has been - successfully transferred or if the operation fails. - - The properties of this transfer are also returned along - with the object path, to avoid a call to GetProperties. - - Possible errors: org.bluez.obex.Error.InvalidArguments - org.bluez.obex.Error.Failed - -Properties string Folder [readonly] - - Folder which the message belongs to - - string Subject [readonly] - - Message subject - - string Timestamp [readonly] - - Message timestamp - - string Sender [readonly] - - Message sender name - - string SenderAddress [readonly] - - Message sender address - - string ReplyTo [readonly] - - Message Reply-To address - - string Recipient [readonly] - - Message recipient name - - string RecipientAddress [readonly] - - Message recipient address - - string Type [readonly] - - Message type - - Possible values: "email", "sms-gsm", - "sms-cdma" and "mms" - - uint64 Size [readonly] - - Message size in bytes - - string Status [readonly] - - Message reception status - - Possible values: "complete", - "fractioned" and "notification" - - boolean Priority [readonly] - - Message priority flag - - boolean Read [read/write] - - Message read flag - - boolean Deleted [writeonly] - - Message deleted flag - - boolean Sent [readonly] - - Message sent flag - - boolean Protected [readonly] - - Message protected flag diff -Nru bluez-5.70/doc/org.bluez.Adapter.5 bluez-5.71/doc/org.bluez.Adapter.5 --- bluez-5.70/doc/org.bluez.Adapter.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Adapter.5 2023-12-14 05:57:33.000000000 +0800 @@ -0,0 +1,472 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.ADAPTER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Adapter \- BlueZ D-Bus Adapter API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.Adapter1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void StartDiscovery() +.INDENT 0.0 +.INDENT 3.5 +Starts device discovery session which may include starting an inquiry +and/or scanning procedures and remote device name resolving. +.sp +Use \fBStopDiscovery\fP to release the sessions acquired. +.sp +This process will start creating Device objects as new devices are +discovered. +.sp +During discovery RSSI delta\-threshold is imposed. +.sp +Each client can request a single device discovery session per adapter. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotReady +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.UNINDENT +.UNINDENT +.UNINDENT +.SS void StopDiscovery() +.INDENT 0.0 +.INDENT 3.5 +Stops device discovery session started by \fBStartDiscovery\fP\&. +.sp +Note that a discovery procedure is shared between all discovery sessions +thus calling StopDiscovery will only release a single session and +discovery will stop when all sessions from all clients have finished. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotReady +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.NotAuthorized +.UNINDENT +.UNINDENT +.UNINDENT +.SS void RemoveDevice(object device) +.INDENT 0.0 +.INDENT 3.5 +Removes the remote device object at the given path including cahed +information such as bonding information. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void SetDiscoveryFilter(dict filter) +.INDENT 0.0 +.INDENT 3.5 +Sets the device discovery filter for the caller. When this method is +called with no filter parameter, filter is removed. +.sp +Possible filter values: +.INDENT 0.0 +.TP +.B array{string} UUIDs +Filter by service UUIDs, empty means match \fIany\fP UUID. +.sp +When a remote device is found that advertises any UUID from +UUIDs, it will be reported if: +.INDENT 7.0 +.IP \(bu 2 +\fBPathloss\fP and \fBRSSI\fP are both empty. +.IP \(bu 2 +only \fBPathloss\fP param is set, device advertise TX power, and +computed pathloss is less than Pathloss param. +.IP \(bu 2 +only \fBRSSI\fP param is set, and received RSSI is higher +than RSSI param. +.UNINDENT +.TP +.B int16 RSSI +RSSI threshold value. +.sp +PropertiesChanged signals will be emitted for already existing +Device objects, with updated RSSI value. If one or more +discovery filters have been set, the RSSI delta\-threshold, that +is imposed by StartDiscovery by default, will not be applied. +.TP +.B uint16 Pathloss +Pathloss threshold value. +.sp +PropertiesChanged signals will be emitted for already existing +Device objects, with updated Pathloss value. +.TP +.B string Transport (Default \(dqauto\(dq) +Transport parameter determines the type of scan. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqauto\(dq +Interleaved scan, use LE, BREDR, or both, depending on +what\(aqs currently enabled. +.TP +.B \(dqbredr\(dq +BR/EDR inquiry only. +.TP +.B \(dqle\(dq +LE scan only. +.UNINDENT +.TP +.B bool DuplicateData (Default true) +Disables duplicate detection of advertisement data. +.sp +When enabled PropertiesChanged signals will be generated for +either ManufacturerData and ServiceData everytime they are +discovered. +.TP +.B bool Discoverable (Default false) +Make adapter discoverable while discovering, if the adapter is +already discoverable setting this filter won\(aqt do anything. +.TP +.B string Pattern (Default none) +Discover devices where the pattern matches either the prefix of +the address or device name which is convenient way to limited +the number of device objects created during a discovery. +.sp +When set disregards device discoverable flags. +.sp +Note: The pattern matching is ignored if there are other client +that don\(aqt set any pattern as it work as a logical OR, also +setting empty string \(dq\(dq pattern will match any device found. +.sp +When discovery filter is set, Device objects will be created as +new devices with matching criteria are discovered regardless of +they are connectable or discoverable which enables listening to +non\-connectable and non\-discoverable devices. +.sp +When multiple clients call SetDiscoveryFilter, their filters are +internally merged, and notifications about new devices are sent +to all clients. Therefore, each client must check that device +updates actually match its filter. +.sp +When SetDiscoveryFilter is called multiple times by the same +client, last filter passed will be active for given client. +.sp +SetDiscoveryFilter can be called before StartDiscovery. +It is useful when client will create first discovery session, +to ensure that proper scan will be started right after call to +StartDiscovery. +.sp +Possible errors: +.INDENT 7.0 +.TP +.B org.bluez.Error.NotReady +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} GetDiscoveryFilters() +.INDENT 0.0 +.INDENT 3.5 +Returns available filters that can be given to \fBSetDiscoveryFilter\fP\&. +.sp +Possible errors: None +.UNINDENT +.UNINDENT +.SS object ConnectDevice(dict properties) [experimental] +.INDENT 0.0 +.INDENT 3.5 +connects to device without need of performing General Discovery. +Connection mechanism is similar to Connect method on +\fBorg.bluez.Device1(5)\fP interface with exception that this method +returns success when physical connection is established and you can +specify bearer to connect with parameter. After this method returns, +services discovery will continue and any supported profile will be +connected. There is no need for calling Connect on Device1 after this +call. If connection was successful this method returns object path to +created device object or device that already exist. +.sp +Possible properties values: +.INDENT 0.0 +.TP +.B string Address (Mandatory) +The Bluetooth device address of the remote device. +.TP +.B string AddressType (Default \(dqBR/EDR\(dq) +The Bluetooth device Address Type. This is address type that +should be used for initial connection. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqpublic\(dq +Public address +.TP +.B \(dqrandom\(dq +Random address +.UNINDENT +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.NotReady +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string Address [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth device address. +.UNINDENT +.UNINDENT +.SS string AddressType [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth Address Type. For dual\-mode and BR/EDR only adapter this +defaults to \(dqpublic\(dq. Single mode LE adapters may have either value. +With privacy enabled this contains type of Identity Address and not +type of address used for connection. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqpublic\(dq +Public address. +.TP +.B \(dqrandom +Random address. +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Name [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth system name (pretty hostname). +.sp +This property is either a static system default or controlled by an +external daemon providing access to the pretty hostname configuration. +.UNINDENT +.UNINDENT +.SS string Alias [readwrite] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth friendly name. This value can be changed. +.sp +In case no alias is set, it will return the system provided name. +Setting an empty string as alias will convert it back to the system +provided name. +.sp +When resetting the alias with an empty string, the property will default +back to system name. +.sp +On a well configured system, this property never needs to be changed +since it defaults to the system name and provides the pretty hostname. +Only if the local name needs to be different from the pretty hostname, +this property should be used as last resort. +.UNINDENT +.UNINDENT +.SS uint32 Class [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth class of device. +.sp +This property represents the value that is either automatically +configured by DMI/ACPI information or provided as static configuration. +.UNINDENT +.UNINDENT +.SS boolean Powered [readwrite] +.INDENT 0.0 +.INDENT 3.5 +Switch an adapter on or off. This will also set the appropriate +connectable state of the controller. +.sp +The value of this property is not persistent. After restart or +unplugging of the adapter it will reset back to false. +.UNINDENT +.UNINDENT +.SS string PowerState [readonly, experimental] +.INDENT 0.0 +.INDENT 3.5 +The power state of an adapter. +.sp +The power state will show whether the adapter is turning off, or turning +on, as well as being on or off. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqon\(dq +Powered on. +.TP +.B \(dqoff\(dq +Powered off +.TP +.B \(dqoff\-enabling\(dq +Transitioning from \(dqoff\(dq to \(dqon\(dq. +.TP +.B \(dqon\-disabling\(dq +Transitioning from \(dqon\(dq to \(dqoff\(dq. +.TP +.B \(dqoff\-blocked\(dq +Blocked by rfkill. +.UNINDENT +.UNINDENT +.UNINDENT +.SS boolean Discoverable [readwrite] (Default: false) +.INDENT 0.0 +.INDENT 3.5 +Switch an adapter to discoverable or non\-discoverable to either make it +visible or hide it. This is a global setting and should only be used by +the settings application. +.sp +If the DiscoverableTimeout is set to a non\-zero value then the system +will set this value back to false after the timer expired. +.sp +In case the adapter is switched off, setting this value will fail. +.sp +When changing the Powered property the new state of this property will +be updated via a PropertiesChanged signal. +.UNINDENT +.UNINDENT +.SS boolean Pairable [readwrite] (Default: true) +.INDENT 0.0 +.INDENT 3.5 +Switch an adapter to pairable or non\-pairable. This is a global setting +and should only be used by the settings application. +.sp +Note that this property only affects incoming pairing requests. +.UNINDENT +.UNINDENT +.SS uint32 PairableTimeout [readwrite] (Default: 0) +.INDENT 0.0 +.INDENT 3.5 +The pairable timeout in seconds. A value of zero means that the timeout +is disabled and it will stay in pairable mode forever. +.UNINDENT +.UNINDENT +.SS uint32 DiscoverableTimeout [readwrite] (Default: 180) +.INDENT 0.0 +.INDENT 3.5 +The discoverable timeout in seconds. A value of zero means that the +timeout is disabled and it will stay in discoverable/limited mode +forever. +.UNINDENT +.UNINDENT +.SS boolean Discovering [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates that a device discovery procedure is active. +.UNINDENT +.UNINDENT +.SS array{string} UUIDs [readonly] +.INDENT 0.0 +.INDENT 3.5 +List of 128\-bit UUIDs that represents the available local services. +.UNINDENT +.UNINDENT +.SS string Modalias [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Local Device ID information in modalias format used by the kernel and +udev. +.UNINDENT +.UNINDENT +.SS array{string} Roles [readonly] +.INDENT 0.0 +.INDENT 3.5 +List of supported roles. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqcentral\(dq +Supports the central role. +.TP +.B \(dqperipheral\(dq +Supports the peripheral role. +.TP +.B \(dqcentral\-peripheral\(dq +Supports both roles concurrently. +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} ExperimentalFeatures [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +List of 128\-bit UUIDs that represents the experimental features +currently enabled. +.UNINDENT +.UNINDENT +.SS uint16 Manufacturer [readonly] +.INDENT 0.0 +.INDENT 3.5 +The manufacturer of the device, as a uint16 company identifier defined +by the Core Bluetooth Specification. +.UNINDENT +.UNINDENT +.SS byte Version [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth version supported by the device, as a core version code +defined by the Core Bluetooth Specification. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.Adapter.rst bluez-5.71/doc/org.bluez.Adapter.rst --- bluez-5.70/doc/org.bluez.Adapter.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Adapter.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,412 @@ +================= +org.bluez.Adapter +================= + +------------------------------------- +BlueZ D-Bus Adapter API documentation +------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.Adapter1 +:Object path: [variable prefix]/{hci0,hci1,...} + +Methods +------- + +void StartDiscovery() +````````````````````` + + Starts device discovery session which may include starting an inquiry + and/or scanning procedures and remote device name resolving. + + Use **StopDiscovery** to release the sessions acquired. + + This process will start creating Device objects as new devices are + discovered. + + During discovery RSSI delta-threshold is imposed. + + Each client can request a single device discovery session per adapter. + + Possible errors: + + :org.bluez.Error.NotReady: + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + +void StopDiscovery() +```````````````````` + + Stops device discovery session started by **StartDiscovery**. + + Note that a discovery procedure is shared between all discovery sessions + thus calling StopDiscovery will only release a single session and + discovery will stop when all sessions from all clients have finished. + + Possible errors: + + :org.bluez.Error.NotReady: + :org.bluez.Error.Failed: + :org.bluez.Error.NotAuthorized: + +void RemoveDevice(object device) +```````````````````````````````` + + Removes the remote device object at the given path including cahed + information such as bonding information. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.Failed: + +void SetDiscoveryFilter(dict filter) +```````````````````````````````````` + + Sets the device discovery filter for the caller. When this method is + called with no filter parameter, filter is removed. + + Possible filter values: + + :array{string} UUIDs: + + Filter by service UUIDs, empty means match *any* UUID. + + When a remote device is found that advertises any UUID from + UUIDs, it will be reported if: + + - **Pathloss** and **RSSI** are both empty. + - only **Pathloss** param is set, device advertise TX power, and + computed pathloss is less than Pathloss param. + - only **RSSI** param is set, and received RSSI is higher + than RSSI param. + + :int16 RSSI: + + RSSI threshold value. + + PropertiesChanged signals will be emitted for already existing + Device objects, with updated RSSI value. If one or more + discovery filters have been set, the RSSI delta-threshold, that + is imposed by StartDiscovery by default, will not be applied. + + :uint16 Pathloss: + + Pathloss threshold value. + + PropertiesChanged signals will be emitted for already existing + Device objects, with updated Pathloss value. + + :string Transport (Default "auto"): + + Transport parameter determines the type of scan. + + Possible values: + + :"auto": + + Interleaved scan, use LE, BREDR, or both, depending on + what's currently enabled. + + :"bredr": + + BR/EDR inquiry only. + + :"le": + + LE scan only. + + + :bool DuplicateData (Default true): + + Disables duplicate detection of advertisement data. + + When enabled PropertiesChanged signals will be generated for + either ManufacturerData and ServiceData everytime they are + discovered. + + :bool Discoverable (Default false): + + Make adapter discoverable while discovering, if the adapter is + already discoverable setting this filter won't do anything. + + :string Pattern (Default none): + + Discover devices where the pattern matches either the prefix of + the address or device name which is convenient way to limited + the number of device objects created during a discovery. + + When set disregards device discoverable flags. + + Note: The pattern matching is ignored if there are other client + that don't set any pattern as it work as a logical OR, also + setting empty string "" pattern will match any device found. + + When discovery filter is set, Device objects will be created as + new devices with matching criteria are discovered regardless of + they are connectable or discoverable which enables listening to + non-connectable and non-discoverable devices. + + When multiple clients call SetDiscoveryFilter, their filters are + internally merged, and notifications about new devices are sent + to all clients. Therefore, each client must check that device + updates actually match its filter. + + When SetDiscoveryFilter is called multiple times by the same + client, last filter passed will be active for given client. + + SetDiscoveryFilter can be called before StartDiscovery. + It is useful when client will create first discovery session, + to ensure that proper scan will be started right after call to + StartDiscovery. + + Possible errors: + + :org.bluez.Error.NotReady: + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +array{string} GetDiscoveryFilters() +``````````````````````````````````` + + Returns available filters that can be given to **SetDiscoveryFilter**. + + Possible errors: None + +object ConnectDevice(dict properties) [experimental] +```````````````````````````````````````````````````` + + connects to device without need of performing General Discovery. + Connection mechanism is similar to Connect method on + **org.bluez.Device1(5)** interface with exception that this method + returns success when physical connection is established and you can + specify bearer to connect with parameter. After this method returns, + services discovery will continue and any supported profile will be + connected. There is no need for calling Connect on Device1 after this + call. If connection was successful this method returns object path to + created device object or device that already exist. + + Possible properties values: + + :string Address (Mandatory): + + The Bluetooth device address of the remote device. + + :string AddressType (Default "BR/EDR"): + + The Bluetooth device Address Type. This is address type that + should be used for initial connection. + + Possible values: + + :"public": + + Public address + + :"random": + + Random address + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + :org.bluez.Error.NotSupported: + :org.bluez.Error.NotReady: + :org.bluez.Error.Failed: + +Properties +---------- + +string Address [readonly] +````````````````````````` + + The Bluetooth device address. + +string AddressType [readonly] +````````````````````````````` + + The Bluetooth Address Type. For dual-mode and BR/EDR only adapter this + defaults to "public". Single mode LE adapters may have either value. + With privacy enabled this contains type of Identity Address and not + type of address used for connection. + + Possible values: + + :"public": + + Public address. + + + :"random: + + Random address. + +string Name [readonly] +`````````````````````` + + The Bluetooth system name (pretty hostname). + + This property is either a static system default or controlled by an + external daemon providing access to the pretty hostname configuration. + +string Alias [readwrite] +```````````````````````` + + The Bluetooth friendly name. This value can be changed. + + In case no alias is set, it will return the system provided name. + Setting an empty string as alias will convert it back to the system + provided name. + + When resetting the alias with an empty string, the property will default + back to system name. + + On a well configured system, this property never needs to be changed + since it defaults to the system name and provides the pretty hostname. + Only if the local name needs to be different from the pretty hostname, + this property should be used as last resort. + +uint32 Class [readonly] +``````````````````````` + + The Bluetooth class of device. + + This property represents the value that is either automatically + configured by DMI/ACPI information or provided as static configuration. + +boolean Powered [readwrite] +``````````````````````````` + + Switch an adapter on or off. This will also set the appropriate + connectable state of the controller. + + The value of this property is not persistent. After restart or + unplugging of the adapter it will reset back to false. + +string PowerState [readonly, experimental] +`````````````````````````````````````````` + + The power state of an adapter. + + The power state will show whether the adapter is turning off, or turning + on, as well as being on or off. + + Possible values: + + :"on": + + Powered on. + + :"off": + + Powered off + + :"off-enabling": + + Transitioning from "off" to "on". + + :"on-disabling": + + Transitioning from "on" to "off". + + :"off-blocked": + + Blocked by rfkill. + +boolean Discoverable [readwrite] (Default: false) +````````````````````````````````````````````````` + + Switch an adapter to discoverable or non-discoverable to either make it + visible or hide it. This is a global setting and should only be used by + the settings application. + + If the DiscoverableTimeout is set to a non-zero value then the system + will set this value back to false after the timer expired. + + In case the adapter is switched off, setting this value will fail. + + When changing the Powered property the new state of this property will + be updated via a PropertiesChanged signal. + +boolean Pairable [readwrite] (Default: true) +```````````````````````````````````````````` + + Switch an adapter to pairable or non-pairable. This is a global setting + and should only be used by the settings application. + + Note that this property only affects incoming pairing requests. + +uint32 PairableTimeout [readwrite] (Default: 0) +``````````````````````````````````````````````` + + The pairable timeout in seconds. A value of zero means that the timeout + is disabled and it will stay in pairable mode forever. + +uint32 DiscoverableTimeout [readwrite] (Default: 180) +````````````````````````````````````````````````````` + + The discoverable timeout in seconds. A value of zero means that the + timeout is disabled and it will stay in discoverable/limited mode + forever. + +boolean Discovering [readonly] +`````````````````````````````` + + Indicates that a device discovery procedure is active. + +array{string} UUIDs [readonly] +`````````````````````````````` + + List of 128-bit UUIDs that represents the available local services. + +string Modalias [readonly, optional] +```````````````````````````````````` + + Local Device ID information in modalias format used by the kernel and + udev. + +array{string} Roles [readonly] +`````````````````````````````` + + List of supported roles. + + Possible values: + + :"central": + + Supports the central role. + + :"peripheral": + + Supports the peripheral role. + + :"central-peripheral": + + Supports both roles concurrently. + +array{string} ExperimentalFeatures [readonly, optional] +``````````````````````````````````````````````````````` + + List of 128-bit UUIDs that represents the experimental features + currently enabled. + +uint16 Manufacturer [readonly] +`````````````````````````````` + + The manufacturer of the device, as a uint16 company identifier defined + by the Core Bluetooth Specification. + +byte Version [readonly] +``````````````````````` + + The Bluetooth version supported by the device, as a core version code + defined by the Core Bluetooth Specification. diff -Nru bluez-5.70/doc/org.bluez.AdminPolicySet.5 bluez-5.71/doc/org.bluez.AdminPolicySet.5 --- bluez-5.70/doc/org.bluez.AdminPolicySet.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdminPolicySet.5 2023-12-14 05:57:42.000000000 +0800 @@ -0,0 +1,79 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.ADMINPOLICYSET" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.AdminPolicySet \- BlueZ D-Bus AdminPolicySet API documentation +.SH DESCRIPTION +.sp +This API provides methods to control the behavior of \fBbluetoothd(8)\fP as an +administrator. +.sp +Interface AdminPolicySet1 provides methods to set policies. Once the policy is +set successfully, it will affect all clients and stay persistently even after +restarting \fBbluetoothd(8)\fP\&. The only way to clear it is to overwrite the +policy with the same method. +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.AdminPolicySet1 [experimental] +.TP +.B Object path +[variable prefix]/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void SetServiceAllowList(array{string} UUIDs) +.INDENT 0.0 +.INDENT 3.5 +Sets the service allowlist by specifying service UUIDs. +.sp +When called, \fBbluetoothd(8)\fP will block incoming and outgoing +connections to the service not in UUIDs for all of the clients. +.sp +Any subsequent calls to this method will supersede any previously set +allowlist values. Calling this method with an empty array will allow +any service UUIDs to be used. +.sp +The default value is an empty array. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.AdminPolicySet.rst bluez-5.71/doc/org.bluez.AdminPolicySet.rst --- bluez-5.70/doc/org.bluez.AdminPolicySet.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdminPolicySet.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,52 @@ +======================== +org.bluez.AdminPolicySet +======================== + +-------------------------------------------- +BlueZ D-Bus AdminPolicySet API documentation +-------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +============ + +This API provides methods to control the behavior of **bluetoothd(8)** as an +administrator. + +Interface AdminPolicySet1 provides methods to set policies. Once the policy is +set successfully, it will affect all clients and stay persistently even after +restarting **bluetoothd(8)**. The only way to clear it is to overwrite the +policy with the same method. + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.AdminPolicySet1 [experimental] +:Object path: [variable prefix]/{hci0,hci1,...} + +Methods +------- + +void SetServiceAllowList(array{string} UUIDs) +````````````````````````````````````````````` + + Sets the service allowlist by specifying service UUIDs. + + When called, **bluetoothd(8)** will block incoming and outgoing + connections to the service not in UUIDs for all of the clients. + + Any subsequent calls to this method will supersede any previously set + allowlist values. Calling this method with an empty array will allow + any service UUIDs to be used. + + The default value is an empty array. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.Failed: diff -Nru bluez-5.70/doc/org.bluez.AdminPolicyStatus.5 bluez-5.71/doc/org.bluez.AdminPolicyStatus.5 --- bluez-5.70/doc/org.bluez.AdminPolicyStatus.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdminPolicyStatus.5 2023-12-14 05:57:42.000000000 +0800 @@ -0,0 +1,77 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.ADMINPOLICYSTATUS" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.AdminPolicyStatus \- BlueZ D-Bus AdminPolicyStatus API documentation +.SH DESCRIPTION +.sp +Interface AdminPolicyStatus1 provides readonly properties to indicate the +current values of admin policy affecting the Adapter and Device objects. +.SH INTERFACE +.SS Adapter +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.AdminPolicyStatus1 [experimental] +.TP +.B Object path +[variable prefix]/{hci0,hci1,...} +.UNINDENT +.SS Device +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.AdminPolicyStatus1 [experimental] +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX +.UNINDENT +.SS Properties +.SS array{string} ServiceAllowList [readonly, adapter\-only] +.INDENT 0.0 +.INDENT 3.5 +Current value of service allow list. +.UNINDENT +.UNINDENT +.SS bool IsAffectedByPolicy [readonly, device\-only] +.INDENT 0.0 +.INDENT 3.5 +Indicate if there is any auto\-connect profile in this device is not +allowed by admin policy. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.AdminPolicyStatus.rst bluez-5.71/doc/org.bluez.AdminPolicyStatus.rst --- bluez-5.70/doc/org.bluez.AdminPolicyStatus.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdminPolicyStatus.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,49 @@ +=========================== +org.bluez.AdminPolicyStatus +=========================== + +----------------------------------------------- +BlueZ D-Bus AdminPolicyStatus API documentation +----------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +Interface AdminPolicyStatus1 provides readonly properties to indicate the +current values of admin policy affecting the Adapter and Device objects. + +Interface +========= + +Adapter +------- + +:Service: org.bluez +:Interface: org.bluez.AdminPolicyStatus1 [experimental] +:Object path: [variable prefix]/{hci0,hci1,...} + +Device +------ + +:Service: org.bluez +:Interface: org.bluez.AdminPolicyStatus1 [experimental] +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Properties +---------- + +array{string} ServiceAllowList [readonly, adapter-only] +``````````````````````````````````````````````````````` + + Current value of service allow list. + +bool IsAffectedByPolicy [readonly, device-only] +``````````````````````````````````````````````` + + Indicate if there is any auto-connect profile in this device is not + allowed by admin policy. diff -Nru bluez-5.70/doc/org.bluez.AdvertisementMonitor.5 bluez-5.71/doc/org.bluez.AdvertisementMonitor.5 --- bluez-5.70/doc/org.bluez.AdvertisementMonitor.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdvertisementMonitor.5 2023-12-14 05:57:54.000000000 +0800 @@ -0,0 +1,189 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.ADVERTISEMENTMONITOR" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.AdvertisementMonitor \- BlueZ D-Bus AdvertisementMonitor API documentation +.SH DESCRIPTION +.sp +This API allows an client to specify a job of monitoring advertisements by +registering the root of hierarchy and then exposing advertisement monitors +under the root with filtering conditions, thresholds of RSSI and timers +of RSSI thresholds. +.sp +Once a monitoring job is activated by \fBbluetoothd(8)\fP, the client can expect +to get notified on the targeted advertisements no matter if there is an ongoing +discovery session (see \fBStartDiscovery()\fP in \fBorg.bluez.Adapter(5)\fP). +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.AdvertisementMonitor1 [experimental] +.TP +.B Object path +freely definable +.UNINDENT +.SS Methods +.SS void Release() [noreply] +.INDENT 0.0 +.INDENT 3.5 +This gets called as a signal for a client to perform clean\-up when: +.INDENT 0.0 +.IP \(bu 2 +Monitor cannot be activated after it was exposed +.IP \(bu 2 +Monitor has been deactivated. +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Activate() [noreply] +.INDENT 0.0 +.INDENT 3.5 +After a monitor was exposed, this gets called as a signal for client to +get acknowledged when a monitor has been activated, so the client can +expect to receive calls on \fBDeviceFound()\fP or \fBDeviceLost()\fP\&. +.UNINDENT +.UNINDENT +.SS void DeviceFound(object device) [noreply] +.INDENT 0.0 +.INDENT 3.5 +This gets called to notify the client of finding the targeted device. +Once receiving the call, the client should start to monitor the +corresponding device to retrieve the changes on RSSI and advertisement +content. +.UNINDENT +.UNINDENT +.SS void DeviceLost(object device) [noreply] +.INDENT 0.0 +.INDENT 3.5 +This gets called to notify the client of losing the targeted device. +Once receiving this call, the client should stop monitoring the +corresponding device. +.UNINDENT +.UNINDENT +.SS Properties +.SS string Type [read\-only] +.INDENT 0.0 +.INDENT 3.5 +The type of the monitor. See \fBSupportedMonitorTypes\fP in +\fBorg.bluez.AdvertisementMonitorManager(5)\fP for the available options. +.UNINDENT +.UNINDENT +.SS int16 RSSILowThreshold [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +Used in conjunction with \fBRSSILowTimeout\fP to determine whether a +device becomes out\-of\-range. Valid range is \-127 to 20 (dBm), while 127 +indicates unset. +.UNINDENT +.UNINDENT +.SS int16 RSSIHighThreshold [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +Used in conjunction with RSSIHighTimeout to determine whether a device +becomes in\-range. Valid range is \-127 to 20 (dBm), while 127 indicates +unset. +.UNINDENT +.UNINDENT +.SS uint16 RSSILowTimeout [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +The time it takes to consider a device as out\-of\-range. If this many +seconds elapses without receiving any signal at least as strong as +\fBRSSILowThreshold\fP, a currently in\-range device will be considered as +out\-of\-range (lost). Valid range is 1 to 300 (seconds), while 0 +indicates unset. +.UNINDENT +.UNINDENT +.SS uint16 RSSIHighTimeout [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +The time it takes to consider a device as in\-range. If this many +seconds elapses while we continuouslyreceive signals at least as strong +as \fBRSSIHighThreshold\fP, a currently out\-of\-range device will be +considered as in\-range (found). Valid range is 1 to 300 (seconds), +while 0 indicates unset. +.UNINDENT +.UNINDENT +.SS uint16 RSSISamplingPeriod [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +Grouping rules on how to propagate the received advertisement packets +to the client. +.sp +Possible values: +.INDENT 0.0 +.TP +.B 0 +All advertisement packets from in\-range devices would be +propagated. +.TP +.B 255 +Only the first advertisement packet of in\-range devices would +be propagated. If the device becomes lost, then the first +packet when it is found again will also be propagated. +.TP +.B 1 to 254 +Advertisement packets would be grouped into 100ms * N time +period. Packets in the same group will only be reported once, +with the RSSI value being averaged out. +.UNINDENT +.sp +Currently this is unimplemented in user space, so the value is only +used to be forwarded to the kernel. +.UNINDENT +.UNINDENT +.SS array{(uint8, uint8, array{byte})} Patterns [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +If the \fBType\fP property is set to \fB\(dqor_patterns\(dq\fP, then this +property must exist and have at least one entry in the array. +.sp +The structure of a pattern contains the following: +.INDENT 0.0 +.TP +.B uint8 start_position +The index in an AD data field where the search hould start. The +beginning of an AD data field is index 0. +.TP +.B uint8 AD_data_type +See \fI\%https://www.bluetooth.com/specifications/assigned\-numbers/\fP +generic\-access\-profile/ for the possible allowed value. +.TP +.B array{byte} content_of_pattern +This is the value of the pattern. The maximum length of the +bytes is 31. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.AdvertisementMonitorManager.5 bluez-5.71/doc/org.bluez.AdvertisementMonitorManager.5 --- bluez-5.70/doc/org.bluez.AdvertisementMonitorManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdvertisementMonitorManager.5 2023-12-14 05:57:53.000000000 +0800 @@ -0,0 +1,119 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.ADVERTISEMENTMONITORMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.AdvertisementMonitorManager \- BlueZ D-Bus AdvertisementMonitorManager API documentation +.SH INTERFACE +.sp +Service org.bluez +Interface org.bluez.AdvertisementMonitorManager1 [experimental] +Object path /org/bluez/{hci0,hci1,...} +.SS Methods +.SS void RegisterMonitor(object application) +.INDENT 0.0 +.INDENT 3.5 +Registers the root path of a hierarchy of advertisement monitors +implementing \fBorg.bluez.AdvertisementMonitor(5)\fP\&. +.sp +The application object path together with the D\-Bus ystem bus +connection ID define the identification of the application registering +advertisement monitors. +.sp +Once a root path is registered by a client via this method, the client +can freely expose/unexpose advertisement monitors without re\-registering +the root path again. After use, the client should call +\fBUnregisterMonitor()\fP method to invalidate the advertisement monitors. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterMonitor(object application) +.INDENT 0.0 +.INDENT 3.5 +Unregisters a hierarchy of advertisement monitors that has been +previously registered with \fBRegisterMonitor()\fP\&. The object path +parameter must match the same value that has been used on registration. +.sp +Upon unregistration, the advertisement monitor(s) should expect to +receive \fBRelease()\fP method as the signal that the advertisement +monitor(s) has been deactivated. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS array{string} SupportedMonitorTypes [read\-only] +.INDENT 0.0 +.INDENT 3.5 +This lists the supported types of advertisement monitors. An application +should check this before instantiate and expose an object of +\fBorg.bluez.AdvertisementMonitor(5)\fP\&. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqor_patterns\(dq +Patterns with logic OR applied. With this type, property +\fBPatterns\fP must exist and has at least one pattern. +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} SupportedFeatures [read\-only] +.INDENT 0.0 +.INDENT 3.5 +This lists the features of advertisement monitoring supported by +\fBbluetoothd(8)\fP\&. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqcontroller\-patterns\(dq +If the controller is capable of performing advertisement +monitoring by patterns, \fBbluetoothd(8)\fP would offload the +patterns to the controller to reduce power consumption. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.AdvertisementMonitorManager.rst bluez-5.71/doc/org.bluez.AdvertisementMonitorManager.rst --- bluez-5.70/doc/org.bluez.AdvertisementMonitorManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdvertisementMonitorManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,90 @@ +===================================== +org.bluez.AdvertisementMonitorManager +===================================== + +--------------------------------------------------------- +BlueZ D-Bus AdvertisementMonitorManager API documentation +--------------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +Service org.bluez +Interface org.bluez.AdvertisementMonitorManager1 [experimental] +Object path /org/bluez/{hci0,hci1,...} + +Methods +------- + +void RegisterMonitor(object application) +```````````````````````````````````````` + + Registers the root path of a hierarchy of advertisement monitors + implementing **org.bluez.AdvertisementMonitor(5)**. + + The application object path together with the D-Bus ystem bus + connection ID define the identification of the application registering + advertisement monitors. + + Once a root path is registered by a client via this method, the client + can freely expose/unexpose advertisement monitors without re-registering + the root path again. After use, the client should call + **UnregisterMonitor()** method to invalidate the advertisement monitors. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + :org.bluez.Error.Failed: + +void UnregisterMonitor(object application) +`````````````````````````````````````````` + + Unregisters a hierarchy of advertisement monitors that has been + previously registered with **RegisterMonitor()**. The object path + parameter must match the same value that has been used on registration. + + Upon unregistration, the advertisement monitor(s) should expect to + receive **Release()** method as the signal that the advertisement + monitor(s) has been deactivated. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.DoesNotExist: + +Properties +---------- + +array{string} SupportedMonitorTypes [read-only] +``````````````````````````````````````````````` + + This lists the supported types of advertisement monitors. An application + should check this before instantiate and expose an object of + **org.bluez.AdvertisementMonitor(5)**. + + Possible values: + + :"or_patterns": + + Patterns with logic OR applied. With this type, property + **Patterns** must exist and has at least one pattern. + +array{string} SupportedFeatures [read-only] +``````````````````````````````````````````` + + This lists the features of advertisement monitoring supported by + **bluetoothd(8)**. + + Possible values: + + :"controller-patterns": + + If the controller is capable of performing advertisement + monitoring by patterns, **bluetoothd(8)** would offload the + patterns to the controller to reduce power consumption. diff -Nru bluez-5.70/doc/org.bluez.AdvertisementMonitor.rst bluez-5.71/doc/org.bluez.AdvertisementMonitor.rst --- bluez-5.70/doc/org.bluez.AdvertisementMonitor.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AdvertisementMonitor.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,153 @@ +============================== +org.bluez.AdvertisementMonitor +============================== + +-------------------------------------------------- +BlueZ D-Bus AdvertisementMonitor API documentation +-------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +This API allows an client to specify a job of monitoring advertisements by +registering the root of hierarchy and then exposing advertisement monitors +under the root with filtering conditions, thresholds of RSSI and timers +of RSSI thresholds. + +Once a monitoring job is activated by **bluetoothd(8)**, the client can expect +to get notified on the targeted advertisements no matter if there is an ongoing +discovery session (see **StartDiscovery()** in **org.bluez.Adapter(5)**). + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.AdvertisementMonitor1 [experimental] +:Object path: freely definable + +Methods +------- + +void Release() [noreply] +```````````````````````` + + This gets called as a signal for a client to perform clean-up when: + + - Monitor cannot be activated after it was exposed + - Monitor has been deactivated. + +void Activate() [noreply] +````````````````````````` + + After a monitor was exposed, this gets called as a signal for client to + get acknowledged when a monitor has been activated, so the client can + expect to receive calls on **DeviceFound()** or **DeviceLost()**. + +void DeviceFound(object device) [noreply] +````````````````````````````````````````` + + This gets called to notify the client of finding the targeted device. + Once receiving the call, the client should start to monitor the + corresponding device to retrieve the changes on RSSI and advertisement + content. + +void DeviceLost(object device) [noreply] +```````````````````````````````````````` + + This gets called to notify the client of losing the targeted device. + Once receiving this call, the client should stop monitoring the + corresponding device. + +Properties +---------- + +string Type [read-only] +``````````````````````` + + The type of the monitor. See **SupportedMonitorTypes** in + **org.bluez.AdvertisementMonitorManager(5)** for the available options. + +int16 RSSILowThreshold [read-only, optional] +```````````````````````````````````````````` + + Used in conjunction with **RSSILowTimeout** to determine whether a + device becomes out-of-range. Valid range is -127 to 20 (dBm), while 127 + indicates unset. + +int16 RSSIHighThreshold [read-only, optional] +````````````````````````````````````````````` + + Used in conjunction with RSSIHighTimeout to determine whether a device + becomes in-range. Valid range is -127 to 20 (dBm), while 127 indicates + unset. + +uint16 RSSILowTimeout [read-only, optional] +``````````````````````````````````````````` + + The time it takes to consider a device as out-of-range. If this many + seconds elapses without receiving any signal at least as strong as + **RSSILowThreshold**, a currently in-range device will be considered as + out-of-range (lost). Valid range is 1 to 300 (seconds), while 0 + indicates unset. + +uint16 RSSIHighTimeout [read-only, optional] +```````````````````````````````````````````` + + The time it takes to consider a device as in-range. If this many + seconds elapses while we continuouslyreceive signals at least as strong + as **RSSIHighThreshold**, a currently out-of-range device will be + considered as in-range (found). Valid range is 1 to 300 (seconds), + while 0 indicates unset. + +uint16 RSSISamplingPeriod [read-only, optional] +``````````````````````````````````````````````` + + Grouping rules on how to propagate the received advertisement packets + to the client. + + Possible values: + + :0: + All advertisement packets from in-range devices would be + propagated. + + :255: + Only the first advertisement packet of in-range devices would + be propagated. If the device becomes lost, then the first + packet when it is found again will also be propagated. + + :1 to 254: + Advertisement packets would be grouped into 100ms * N time + period. Packets in the same group will only be reported once, + with the RSSI value being averaged out. + + Currently this is unimplemented in user space, so the value is only + used to be forwarded to the kernel. + +array{(uint8, uint8, array{byte})} Patterns [read-only, optional] +````````````````````````````````````````````````````````````````` + + If the **Type** property is set to **"or_patterns"**, then this + property must exist and have at least one entry in the array. + + The structure of a pattern contains the following: + + :uint8 start_position: + + The index in an AD data field where the search hould start. The + beginning of an AD data field is index 0. + + :uint8 AD_data_type: + + See https://www.bluetooth.com/specifications/assigned-numbers/ + generic-access-profile/ for the possible allowed value. + + :array{byte} content_of_pattern: + + This is the value of the pattern. The maximum length of the + bytes is 31. diff -Nru bluez-5.70/doc/org.bluez.Agent.5 bluez-5.71/doc/org.bluez.Agent.5 --- bluez-5.70/doc/org.bluez.Agent.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Agent.5 2023-12-14 05:57:36.000000000 +0800 @@ -0,0 +1,201 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.AGENT" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Agent \- BlueZ D-Bus Agent API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +unique name +.TP +.B Interface +org.bluez.Agent1 +.TP +.B Object path +freely definable +.UNINDENT +.SS Methods +.SS void Release() +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon unregisters the agent. +An agent can use it to do cleanup tasks. There is no need to unregister +the agent, because when this method gets called it has already been +unregistered. +.UNINDENT +.UNINDENT +.SS string RequestPinCode(object device) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon needs to get the passkey +for an authentication. +.sp +The return value should be a string of 1\-16 characters length. The +string can be alphanumeric. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void DisplayPinCode(object device, string pincode) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon needs to display a +pincode for an authentication. +.sp +An empty reply should be returned. When the pincode needs no longer to +be displayed, the Cancel method of the agent will be called. +.sp +This is used during the pairing process of keyboards that don\(aqt support +Bluetooth 2.1 Secure Simple Pairing, in contrast to DisplayPasskey which +is used for those that do. +.sp +This method will only ever be called once since older keyboards do not +support typing notification. +.sp +Note that the PIN will always be a 6\-digit number, zero\-padded to 6 +digits. This is for harmony with the later specification. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint32 RequestPasskey(object device) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon needs to get the passkey +for an authentication. +.sp +The return value should be a numeric value between 0\-999999. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void DisplayPasskey(object device, uint32 passkey, uint16 entered) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon needs to display a +passkey for an authentication. +.sp +The entered parameter indicates the number of already typed keys on the +remote side. +.sp +An empty reply should be returned. When the passkey needs no longer to +be displayed, the Cancel method of the agent will be called. +.sp +During the pairing process this method might be called multiple times to +update the entered value. +.sp +Note that the passkey will always be a 6\-digit number, so the display +should be zero\-padded at the start if the value contains less than 6 +digits. +.UNINDENT +.UNINDENT +.SS void RequestConfirmation(object device, uint32 passkey) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon needs to confirm a +passkey for an authentication. +.sp +To confirm the value it should return an empty reply or an error in case +the passkey is invalid. +.sp +Note that the passkey will always be a 6\-digit number, so the display +should be zero\-padded at the start if the value contains less than 6 +digits. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void RequestAuthorization(object device) +.INDENT 0.0 +.INDENT 3.5 +This method gets called to request the user to authorize an incoming +pairing attempt which would in other circumstances trigger the +just\-works model, or when the user plugged in a device that implements +cable pairing. In the latter case, the device would not be connected to +the adapter via Bluetooth yet. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void AuthorizeService(object device, string uuid) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon needs to authorize a +connection/service request. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Cancel() +.INDENT 0.0 +.INDENT 3.5 +This method gets called to indicate that the agent request failed before +a reply was returned. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.AgentManager.5 bluez-5.71/doc/org.bluez.AgentManager.5 --- bluez-5.70/doc/org.bluez.AgentManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AgentManager.5 2023-12-14 05:57:35.000000000 +0800 @@ -0,0 +1,122 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.AGENTMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.AgentManager \- BlueZ D-Bus AgentManager API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.AgentManager1 +.TP +.B Object path +/org/bluez +.UNINDENT +.SS Methods +.SS void RegisterAgent(object agent, string capability) +.INDENT 0.0 +.INDENT 3.5 +Registers pairing agent. +.sp +The object path defines the path of the agent that will be called when +user input is needed and must implement \fBorg.bluez.Agent(5)\fP +interface. +.sp +Every application can register its own agent and for all actions +triggered by that application its agent is used. +.sp +It is not required by an application to register an agent. If an +application does chooses to not register an agent, the default agent is +used. This is on most cases a good idea. Only application like a pairing +wizard should register their own agent. +.sp +An application can only register one agent. Multiple agents per +application is not supported. +.sp +Possible capability values: +.INDENT 0.0 +.TP +.B \(dq\(dq +Fallback to \(dqKeyboardDisplay\(dq. +.TP +.B \(dqDisplayOnly\(dq +.TP +.B \(dqDisplayYesNo\(dq +.TP +.B \(dqKeyboardOnly\(dq +.TP +.B \(dqNoInputNoOutput\(dq +.TP +.B \(dqKeyboardDisplay\(dq +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterAgent(object agent) +.INDENT 0.0 +.INDENT 3.5 +Unregisters an agent that has been previously registered using +\fBRegisterAgent\fP\&. The object path parameter must match the same value +that has been used on registration. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.SS void RequestDefaultAgent(object agent) +.INDENT 0.0 +.INDENT 3.5 +Requests to make the application agent the default agent. The +application is required to register an agent. +.sp +Special permission might be required to become the default agent. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.AgentManager.rst bluez-5.71/doc/org.bluez.AgentManager.rst --- bluez-5.70/doc/org.bluez.AgentManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.AgentManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,83 @@ +====================== +org.bluez.AgentManager +====================== + +------------------------------------------ +BlueZ D-Bus AgentManager API documentation +------------------------------------------ + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.AgentManager1 +:Object path: /org/bluez + +Methods +------- + +void RegisterAgent(object agent, string capability) +``````````````````````````````````````````````````` + + Registers pairing agent. + + The object path defines the path of the agent that will be called when + user input is needed and must implement **org.bluez.Agent(5)** + interface. + + Every application can register its own agent and for all actions + triggered by that application its agent is used. + + It is not required by an application to register an agent. If an + application does chooses to not register an agent, the default agent is + used. This is on most cases a good idea. Only application like a pairing + wizard should register their own agent. + + An application can only register one agent. Multiple agents per + application is not supported. + + Possible capability values: + + :"": + + Fallback to "KeyboardDisplay". + + :"DisplayOnly": + :"DisplayYesNo": + :"KeyboardOnly": + :"NoInputNoOutput": + :"KeyboardDisplay": + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + +void UnregisterAgent(object agent) +`````````````````````````````````` + + Unregisters an agent that has been previously registered using + **RegisterAgent**. The object path parameter must match the same value + that has been used on registration. + + Possible errors: + + :org.bluez.Error.DoesNotExist: + +void RequestDefaultAgent(object agent) +`````````````````````````````````````` + + Requests to make the application agent the default agent. The + application is required to register an agent. + + Special permission might be required to become the default agent. + + Possible errors: + + :org.bluez.Error.DoesNotExist: + diff -Nru bluez-5.70/doc/org.bluez.Agent.rst bluez-5.71/doc/org.bluez.Agent.rst --- bluez-5.70/doc/org.bluez.Agent.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Agent.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,149 @@ +=============== +org.bluez.Agent +=============== + +----------------------------------- +BlueZ D-Bus Agent API documentation +----------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: unique name +:Interface: org.bluez.Agent1 +:Object path: freely definable + +Methods +------- + +void Release() +`````````````` + + This method gets called when the service daemon unregisters the agent. + An agent can use it to do cleanup tasks. There is no need to unregister + the agent, because when this method gets called it has already been + unregistered. + +string RequestPinCode(object device) +```````````````````````````````````` + + This method gets called when the service daemon needs to get the passkey + for an authentication. + + The return value should be a string of 1-16 characters length. The + string can be alphanumeric. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: + +void DisplayPinCode(object device, string pincode) +`````````````````````````````````````````````````` + + This method gets called when the service daemon needs to display a + pincode for an authentication. + + An empty reply should be returned. When the pincode needs no longer to + be displayed, the Cancel method of the agent will be called. + + This is used during the pairing process of keyboards that don't support + Bluetooth 2.1 Secure Simple Pairing, in contrast to DisplayPasskey which + is used for those that do. + + This method will only ever be called once since older keyboards do not + support typing notification. + + Note that the PIN will always be a 6-digit number, zero-padded to 6 + digits. This is for harmony with the later specification. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: + +uint32 RequestPasskey(object device) +```````````````````````````````````` + + This method gets called when the service daemon needs to get the passkey + for an authentication. + + The return value should be a numeric value between 0-999999. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: + +void DisplayPasskey(object device, uint32 passkey, uint16 entered) +`````````````````````````````````````````````````````````````````` + + This method gets called when the service daemon needs to display a + passkey for an authentication. + + The entered parameter indicates the number of already typed keys on the + remote side. + + An empty reply should be returned. When the passkey needs no longer to + be displayed, the Cancel method of the agent will be called. + + During the pairing process this method might be called multiple times to + update the entered value. + + Note that the passkey will always be a 6-digit number, so the display + should be zero-padded at the start if the value contains less than 6 + digits. + +void RequestConfirmation(object device, uint32 passkey) +``````````````````````````````````````````````````````` + + This method gets called when the service daemon needs to confirm a + passkey for an authentication. + + To confirm the value it should return an empty reply or an error in case + the passkey is invalid. + + Note that the passkey will always be a 6-digit number, so the display + should be zero-padded at the start if the value contains less than 6 + digits. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: + +void RequestAuthorization(object device) +```````````````````````````````````````` + + This method gets called to request the user to authorize an incoming + pairing attempt which would in other circumstances trigger the + just-works model, or when the user plugged in a device that implements + cable pairing. In the latter case, the device would not be connected to + the adapter via Bluetooth yet. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: + +void AuthorizeService(object device, string uuid) +````````````````````````````````````````````````` + + This method gets called when the service daemon needs to authorize a + connection/service request. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: + +void Cancel() +````````````` + + This method gets called to indicate that the agent request failed before + a reply was returned. diff -Nru bluez-5.70/doc/org.bluez.Battery.5 bluez-5.71/doc/org.bluez.Battery.5 --- bluez-5.70/doc/org.bluez.Battery.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Battery.5 2023-12-14 05:57:41.000000000 +0800 @@ -0,0 +1,66 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.BATTERY" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Battery \- BlueZ D-Bus Battery API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.Battery1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX +.UNINDENT +.SS Properties +.SS byte Percentage [readonly] +.INDENT 0.0 +.INDENT 3.5 +The percentage of battery left as an unsigned 8\-bit integer. +.UNINDENT +.UNINDENT +.SS string Source [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Describes where the battery information comes from. +.sp +This property is informational only and may be useful for debugging +purposes. +.sp +Providers from \fBorg.bluez.BatteryProvider(5)\fP may make use +of this property to indicate where the battery report comes from +(e.g. \(dqHFP 1.7\(dq, \(dqHID\(dq, or the profile UUID). +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.BatteryProvider.5 bluez-5.71/doc/org.bluez.BatteryProvider.5 --- bluez-5.70/doc/org.bluez.BatteryProvider.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.BatteryProvider.5 2023-12-14 05:57:40.000000000 +0800 @@ -0,0 +1,58 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.BATTERYPROVIDER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.BatteryProvider \- BlueZ D-Bus BatteryProvider API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service + +.TP +.B Interface +org.bluez.BatteryProvider1 +.TP +.B Object path +{provider_root}/{unique battery object path} +.UNINDENT +.SS Properties +.sp +Objects provided on this interface contain the same properties as +\fBorg.bluez.Battery(5)\fP interface. Additionally, this interface needs to have +the Device property indicating the object path of the device this battery +provides. +.SS object Device [readonly] +.INDENT 0.0 +.INDENT 3.5 +The object path of the device that has this battery. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.BatteryProviderManager.5 bluez-5.71/doc/org.bluez.BatteryProviderManager.5 --- bluez-5.70/doc/org.bluez.BatteryProviderManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.BatteryProviderManager.5 2023-12-14 05:57:40.000000000 +0800 @@ -0,0 +1,75 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.BATTERYPROVIDERMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.BatteryProviderManager \- BlueZ D-Bus BatteryProviderManager API documentation +.SH DESCRIPTION +.sp +A battery provider starts by registering itself as a battery provider with the +\fBRegisterBatteryProvider()\fP method passing an object path as the provider ID. +Then, it can start exposing \fBorg.bluez.BatteryProvider(5)\fP objects having the +path starting with the given provider ID. It can also remove objects at any +time. +The objects and their properties exposed by battery providers will be reflected +on \fBorg.bluez.Battery(5)\fP interface. +.sp +\fBbluetoothd(8)\fP will stop monitoring these exposed and removed objects after +UnregisterBatteryProvider is called for that provider ID. +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.BatteryProviderManager1 +.TP +.B Object path +/org/bluez/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void RegisterBatteryProvider(object provider) +.INDENT 0.0 +.INDENT 3.5 +Registers a battery provider. A registered battery provider can then +expose objects with \fBorg.bluez.BatteryProvider(5)\fP interface. +.UNINDENT +.UNINDENT +.SS void UnregisterBatteryProvider(object provider) +.INDENT 0.0 +.INDENT 3.5 +Unregisters a battery provider previously registered with +\fBRegisterBatteryProvider()\fP\&. After unregistration, the +\fBorg.bluez.BatteryProvider(5)\fP objects provided by this client are +ignored by \fBbluetoothd(8)\fP\&. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.BatteryProviderManager.rst bluez-5.71/doc/org.bluez.BatteryProviderManager.rst --- bluez-5.70/doc/org.bluez.BatteryProviderManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.BatteryProviderManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,50 @@ +================================ +org.bluez.BatteryProviderManager +================================ + +---------------------------------------------------- +BlueZ D-Bus BatteryProviderManager API documentation +---------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +============ + +A battery provider starts by registering itself as a battery provider with the +**RegisterBatteryProvider()** method passing an object path as the provider ID. +Then, it can start exposing **org.bluez.BatteryProvider(5)** objects having the +path starting with the given provider ID. It can also remove objects at any +time. +The objects and their properties exposed by battery providers will be reflected +on **org.bluez.Battery(5)** interface. + +**bluetoothd(8)** will stop monitoring these exposed and removed objects after +UnregisterBatteryProvider is called for that provider ID. + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.BatteryProviderManager1 +:Object path: /org/bluez/{hci0,hci1,...} + +Methods +------- + +void RegisterBatteryProvider(object provider) +````````````````````````````````````````````` + + Registers a battery provider. A registered battery provider can then + expose objects with **org.bluez.BatteryProvider(5)** interface. + +void UnregisterBatteryProvider(object provider) +``````````````````````````````````````````````` + + Unregisters a battery provider previously registered with + **RegisterBatteryProvider()**. After unregistration, the + **org.bluez.BatteryProvider(5)** objects provided by this client are + ignored by **bluetoothd(8)**. diff -Nru bluez-5.70/doc/org.bluez.BatteryProvider.rst bluez-5.71/doc/org.bluez.BatteryProvider.rst --- bluez-5.70/doc/org.bluez.BatteryProvider.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.BatteryProvider.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,32 @@ +========================= +org.bluez.BatteryProvider +========================= + +--------------------------------------------- +BlueZ D-Bus BatteryProvider API documentation +--------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: +:Interface: org.bluez.BatteryProvider1 +:Object path: {provider_root}/{unique battery object path} + +Properties +---------- + +Objects provided on this interface contain the same properties as +**org.bluez.Battery(5)** interface. Additionally, this interface needs to have +the Device property indicating the object path of the device this battery +provides. + +object Device [readonly] +```````````````````````` + + The object path of the device that has this battery. diff -Nru bluez-5.70/doc/org.bluez.Battery.rst bluez-5.71/doc/org.bluez.Battery.rst --- bluez-5.70/doc/org.bluez.Battery.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Battery.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,39 @@ +================= +org.bluez.Battery +================= + +------------------------------------- +BlueZ D-Bus Battery API documentation +------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.Battery1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Properties +---------- + +byte Percentage [readonly] +`````````````````````````` + + The percentage of battery left as an unsigned 8-bit integer. + +string Source [readonly, optional] +`````````````````````````````````` + + Describes where the battery information comes from. + + This property is informational only and may be useful for debugging + purposes. + + Providers from **org.bluez.BatteryProvider(5)** may make use + of this property to indicate where the battery report comes from + (e.g. "HFP 1.7", "HID", or the profile UUID). diff -Nru bluez-5.70/doc/org.bluez.Device.5 bluez-5.71/doc/org.bluez.Device.5 --- bluez-5.70/doc/org.bluez.Device.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Device.5 2023-12-14 05:57:34.000000000 +0800 @@ -0,0 +1,420 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.DEVICE" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Device \- BlueZ D-Bus Device API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.Device1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX +.UNINDENT +.SS Methods +.SS void Connect() +.INDENT 0.0 +.INDENT 3.5 +Connects all profiles the remote device supports that can be connected +to and have been flagged as auto\-connectable. If only subset of profiles +is already connected it will try to connect currently disconnected ones. +.sp +If at least one profile was connected successfully this method will +indicate success. +.sp +For dual\-mode devices only one bearer is connected at time, the +conditions are in the following order: +.INDENT 0.0 +.IP 1. 3 +Connect the disconnected bearer if already connected. +.UNINDENT +.sp +2. Connect first the bonded bearer. If no bearers are bonded or both +are skip and check latest seen bearer. +.sp +3. Connect last seen bearer, in case the timestamps are the same BR/EDR +takes precedence. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotReady +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.AlreadyConnected +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Disconnect() +.INDENT 0.0 +.INDENT 3.5 +Disconnects all connected profiles and then terminates low\-level ACL +connection. +.sp +ACL connection will be terminated even if some profiles were not +disconnected properly e.g. due to misbehaving device. +.sp +This method can be also used to cancel a preceding Connect call before +a reply to it has been received. +.sp +For non\-trusted devices connected over LE bearer calling this method +will disable incoming connections until Connect method is called again. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotConnected +.UNINDENT +.UNINDENT +.UNINDENT +.SS void ConnectProfile(string uuid) +.INDENT 0.0 +.INDENT 3.5 +Connects a specific profile of this device. The UUID provided is the +remote service UUID for the profile. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotAvailable +.TP +.B org.bluez.Error.NotReady +.UNINDENT +.UNINDENT +.UNINDENT +.SS void DisconnectProfile(string uuid) +.INDENT 0.0 +.INDENT 3.5 +Disconnects a specific profile of this device. The profile needs to be +registered client profile. +.sp +There is no connection tracking for a profile, so as long as the +profile is registered this will always succeed. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Pair() +.INDENT 0.0 +.INDENT 3.5 +Connects to the remote device and initiate pairing procedure then +proceed with service discovery. +.sp +If the application has registered its own agent, then that specific +agent will be used. Otherwise it will use the default agent. +.sp +Only for applications like a pairing wizard it would make sense to have +its own agent. In almost all other cases the default agent will handle +this just fine. +.sp +In case there is no application agent and also no default agent present, +this method will fail. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.AlreadyExists +.TP +.B org.bluez.Error.AuthenticationCanceled +.TP +.B org.bluez.Error.AuthenticationFailed +.TP +.B org.bluez.Error.AuthenticationRejected +.TP +.B org.bluez.Error.AuthenticationTimeout +.TP +.B org.bluez.Error.ConnectionAttemptFailed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void CancelPairing() +.INDENT 0.0 +.INDENT 3.5 +Cancels a pairing operation initiated by the \fBPair\fP method. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.DoesNotExist +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string Address [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth device address of the remote device. +.UNINDENT +.UNINDENT +.SS string AddressType [readonly] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth device Address Type. For dual\-mode and BR/EDR only devices +this defaults to \(dqpublic\(dq. Single mode LE devices may have either value. +If remote device uses privacy than before pairing this represents +address type used for connection and Identity Address after pairing. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqpublic\(dq +Public address +.TP +.B \(dqrandom\(dq +Random address +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Name [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth remote name. +.sp +This value is only present for completeness. It is better to always use +the \fBAlias\fP property when displaying the devices name. +.sp +If the \fBAlias\fP property is unset, it will reflect this value which +makes it more convenient. +.UNINDENT +.UNINDENT +.SS string Icon [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Proposed icon name according to the freedesktop.org icon naming +specification. +.UNINDENT +.UNINDENT +.SS uint32 Class [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +The Bluetooth class of device of the remote device. +.UNINDENT +.UNINDENT +.SS uint16 Appearance [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +External appearance of device, as found on GAP service. +.UNINDENT +.UNINDENT +.SS array{string} UUIDs [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +List of 128\-bit UUIDs that represents the available remote services. +.UNINDENT +.UNINDENT +.SS boolean Paired [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the remote device is paired. Paired means the pairing +process where devices exchange the information to establish an +encrypted connection has been completed. +.UNINDENT +.UNINDENT +.SS boolean Bonded [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the remote device is bonded. Bonded means the information +exchanged on pairing process has been stored and will be persisted. +.UNINDENT +.UNINDENT +.SS boolean Connected [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the remote device is currently connected. +A PropertiesChanged signal indicate changes to this status. +.UNINDENT +.UNINDENT +.SS boolean Trusted [readwrite] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the remote is seen as trusted. This setting can be changed +by the application. +.UNINDENT +.UNINDENT +.SS boolean Blocked [readwrite] +.INDENT 0.0 +.INDENT 3.5 +If set to true any incoming connections from the device will be +immediately rejected. Any device drivers will also be removed and +no new ones will be probed as long as the device is blocked. +.UNINDENT +.UNINDENT +.SS boolean WakeAllowed [readwrite] +.INDENT 0.0 +.INDENT 3.5 +If set to true this device will be allowed to wake the host from +system suspend. +.UNINDENT +.UNINDENT +.SS string Alias [readwrite] +.INDENT 0.0 +.INDENT 3.5 +The name alias for the remote device. The alias can be used to have a +different friendly name for the remote device. +.sp +In case no alias is set, it will return the remote device name. Setting +an empty string as alias will convert it back to the remote device name. +.sp +When resetting the alias with an empty string, the property will default +back to the remote name. +.UNINDENT +.UNINDENT +.SS object Adapter [readonly] +.INDENT 0.0 +.INDENT 3.5 +The object path of the adapter the device belongs to. +.UNINDENT +.UNINDENT +.SS boolean LegacyPairing [readonly] +.INDENT 0.0 +.INDENT 3.5 +Set to true if the device only supports the pre\-2.1 pairing mechanism. +This property is useful during device discovery to anticipate whether +legacy or simple pairing will occur if pairing is initiated. +.sp +Note that this property can exhibit false\-positives in the case of +Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry +Response support. +.UNINDENT +.UNINDENT +.SS string Modalias [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Remote Device ID information in modalias format used by the kernel and +udev. +.UNINDENT +.UNINDENT +.SS int16 RSSI [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Received Signal Strength Indicator of the remote device (inquiry or +advertising). +.UNINDENT +.UNINDENT +.SS int16 TxPower [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Advertised transmitted power level (inquiry or advertising). +.UNINDENT +.UNINDENT +.SS dict ManufacturerData [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Manufacturer specific advertisement data. Keys are 16 bits Manufacturer +ID followed by its byte array value. +.UNINDENT +.UNINDENT +.SS dict ServiceData [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Service advertisement data. Keys are the UUIDs in string format followed +by its byte array value. +.UNINDENT +.UNINDENT +.SS bool ServicesResolved [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicate whether or not service discovery has been resolved. +.UNINDENT +.UNINDENT +.SS array{byte} AdvertisingFlags [readonly, experimental] +.INDENT 0.0 +.INDENT 3.5 +The Advertising Data Flags of the remote device. +.UNINDENT +.UNINDENT +.SS dict AdvertisingData [readonly, experimental] +.INDENT 0.0 +.INDENT 3.5 +The Advertising Data of the remote device. Keys are 1 byte AD Type +followed by data as byte array. +.sp +Note: Only types considered safe to be handled by application are +exposed. +.sp +Possible values: +.INDENT 0.0 +.TP +.B + +.UNINDENT +.sp +Example: +.INDENT 0.0 +.INDENT 3.5 + +0x26 0x01 0x01... +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{object, dict} Sets [readonly, experimental] +.INDENT 0.0 +.INDENT 3.5 +The object paths of the sets the device belongs to followed by a +dictionary which can contain the following: +.INDENT 0.0 +.TP +.B byte Rank +Rank of the device in the Set. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.Device.rst bluez-5.71/doc/org.bluez.Device.rst --- bluez-5.70/doc/org.bluez.Device.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Device.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,329 @@ +================ +org.bluez.Device +================ + +------------------------------------ +BlueZ D-Bus Device API documentation +------------------------------------ + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.Device1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Methods +------- + +void Connect() +`````````````` + + Connects all profiles the remote device supports that can be connected + to and have been flagged as auto-connectable. If only subset of profiles + is already connected it will try to connect currently disconnected ones. + + If at least one profile was connected successfully this method will + indicate success. + + For dual-mode devices only one bearer is connected at time, the + conditions are in the following order: + + 1. Connect the disconnected bearer if already connected. + + 2. Connect first the bonded bearer. If no bearers are bonded or both + are skip and check latest seen bearer. + + 3. Connect last seen bearer, in case the timestamps are the same BR/EDR + takes precedence. + + Possible errors: + + :org.bluez.Error.NotReady: + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + :org.bluez.Error.AlreadyConnected: + +void Disconnect() +````````````````` + + Disconnects all connected profiles and then terminates low-level ACL + connection. + + ACL connection will be terminated even if some profiles were not + disconnected properly e.g. due to misbehaving device. + + This method can be also used to cancel a preceding Connect call before + a reply to it has been received. + + For non-trusted devices connected over LE bearer calling this method + will disable incoming connections until Connect method is called again. + + Possible errors: + + :org.bluez.Error.NotConnected: + +void ConnectProfile(string uuid) +```````````````````````````````` + + Connects a specific profile of this device. The UUID provided is the + remote service UUID for the profile. + + Possible errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotAvailable: + :org.bluez.Error.NotReady: + +void DisconnectProfile(string uuid) +``````````````````````````````````` + + Disconnects a specific profile of this device. The profile needs to be + registered client profile. + + There is no connection tracking for a profile, so as long as the + profile is registered this will always succeed. + + Possible errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + +void Pair() +``````````` + + Connects to the remote device and initiate pairing procedure then + proceed with service discovery. + + If the application has registered its own agent, then that specific + agent will be used. Otherwise it will use the default agent. + + Only for applications like a pairing wizard it would make sense to have + its own agent. In almost all other cases the default agent will handle + this just fine. + + In case there is no application agent and also no default agent present, + this method will fail. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.Failed: + :org.bluez.Error.AlreadyExists: + :org.bluez.Error.AuthenticationCanceled: + :org.bluez.Error.AuthenticationFailed: + :org.bluez.Error.AuthenticationRejected: + :org.bluez.Error.AuthenticationTimeout: + :org.bluez.Error.ConnectionAttemptFailed: + +void CancelPairing() +```````````````````` + + Cancels a pairing operation initiated by the **Pair** method. + + Possible errors: + + :org.bluez.Error.DoesNotExist: + :org.bluez.Error.Failed: + +Properties +---------- + +string Address [readonly] +````````````````````````` + + The Bluetooth device address of the remote device. + +string AddressType [readonly] +````````````````````````````` + + The Bluetooth device Address Type. For dual-mode and BR/EDR only devices + this defaults to "public". Single mode LE devices may have either value. + If remote device uses privacy than before pairing this represents + address type used for connection and Identity Address after pairing. + + Possible values: + + :"public": + + Public address + + :"random": + + Random address + +string Name [readonly, optional] +```````````````````````````````` + + The Bluetooth remote name. + + This value is only present for completeness. It is better to always use + the **Alias** property when displaying the devices name. + + If the **Alias** property is unset, it will reflect this value which + makes it more convenient. + +string Icon [readonly, optional] +```````````````````````````````` + + Proposed icon name according to the freedesktop.org icon naming + specification. + +uint32 Class [readonly, optional] +````````````````````````````````` + + The Bluetooth class of device of the remote device. + +uint16 Appearance [readonly, optional] +`````````````````````````````````````` + + External appearance of device, as found on GAP service. + +array{string} UUIDs [readonly, optional] +```````````````````````````````````````` + + List of 128-bit UUIDs that represents the available remote services. + +boolean Paired [readonly] +````````````````````````` + + Indicates if the remote device is paired. Paired means the pairing + process where devices exchange the information to establish an + encrypted connection has been completed. + +boolean Bonded [readonly] +````````````````````````` + + Indicates if the remote device is bonded. Bonded means the information + exchanged on pairing process has been stored and will be persisted. + +boolean Connected [readonly] +```````````````````````````` + + Indicates if the remote device is currently connected. + A PropertiesChanged signal indicate changes to this status. + +boolean Trusted [readwrite] +``````````````````````````` + + Indicates if the remote is seen as trusted. This setting can be changed + by the application. + +boolean Blocked [readwrite] +``````````````````````````` + + If set to true any incoming connections from the device will be + immediately rejected. Any device drivers will also be removed and + no new ones will be probed as long as the device is blocked. + +boolean WakeAllowed [readwrite] +``````````````````````````````` + + If set to true this device will be allowed to wake the host from + system suspend. + +string Alias [readwrite] +```````````````````````` + + The name alias for the remote device. The alias can be used to have a + different friendly name for the remote device. + + In case no alias is set, it will return the remote device name. Setting + an empty string as alias will convert it back to the remote device name. + + When resetting the alias with an empty string, the property will default + back to the remote name. + +object Adapter [readonly] +````````````````````````` + + The object path of the adapter the device belongs to. + +boolean LegacyPairing [readonly] +```````````````````````````````` + + Set to true if the device only supports the pre-2.1 pairing mechanism. + This property is useful during device discovery to anticipate whether + legacy or simple pairing will occur if pairing is initiated. + + Note that this property can exhibit false-positives in the case of + Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry + Response support. + +string Modalias [readonly, optional] +```````````````````````````````````` + + Remote Device ID information in modalias format used by the kernel and + udev. + +int16 RSSI [readonly, optional] +``````````````````````````````` + + Received Signal Strength Indicator of the remote device (inquiry or + advertising). + +int16 TxPower [readonly, optional] +`````````````````````````````````` + + Advertised transmitted power level (inquiry or advertising). + +dict ManufacturerData [readonly, optional] +`````````````````````````````````````````` + + Manufacturer specific advertisement data. Keys are 16 bits Manufacturer + ID followed by its byte array value. + +dict ServiceData [readonly, optional] +````````````````````````````````````` + + Service advertisement data. Keys are the UUIDs in string format followed + by its byte array value. + +bool ServicesResolved [readonly] +```````````````````````````````` + + Indicate whether or not service discovery has been resolved. + +array{byte} AdvertisingFlags [readonly, experimental] +````````````````````````````````````````````````````` + + The Advertising Data Flags of the remote device. + +dict AdvertisingData [readonly, experimental] +````````````````````````````````````````````` + + The Advertising Data of the remote device. Keys are 1 byte AD Type + followed by data as byte array. + + Note: Only types considered safe to be handled by application are + exposed. + + Possible values: + + :: + + + + Example: + + + 0x26 0x01 0x01... + +array{object, dict} Sets [readonly, experimental] +````````````````````````````````````````````````` + + The object paths of the sets the device belongs to followed by a + dictionary which can contain the following: + + :byte Rank: + + Rank of the device in the Set. diff -Nru bluez-5.70/doc/org.bluez.DeviceSet.5 bluez-5.71/doc/org.bluez.DeviceSet.5 --- bluez-5.70/doc/org.bluez.DeviceSet.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.DeviceSet.5 2023-12-14 05:57:34.000000000 +0800 @@ -0,0 +1,107 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.DEVICESET" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.DeviceSet \- BlueZ D-Bus DeviceSet API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.DeviceSet1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/set_{sirk} +.UNINDENT +.SS Methods +.SS void Connect() [experimental] +.INDENT 0.0 +.INDENT 3.5 +Connects all \fBdevices\fP members of the set, each member is +connected in sequence as they were added/loaded following the +same proceedure as described in \fBDevice1.Connect\fP\&. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotReady +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.AlreadyConnected +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Disconnect() [experimental] +.INDENT 0.0 +.INDENT 3.5 +Disconnects all \fBdevices\fP members of the set, each member is +disconnected in sequence as they were connected following the +same proceedure as described in \fBDevice1.Disconnect\fP\&. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotConnected +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS object Adapter [readonly, experimental] +.INDENT 0.0 +.INDENT 3.5 +The object path of the adapter the set belongs to. +.UNINDENT +.UNINDENT +.SS bool AutoConnect [read\-write, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the \fBdevices\fP members of the set shall be automatically +connected once any of its members is connected. +.UNINDENT +.UNINDENT +.SS array(object) Devices [ready\-only, experimental] +.INDENT 0.0 +.INDENT 3.5 +List of devices objects that are members of the set. +.UNINDENT +.UNINDENT +.SS byte Size [read\-only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Set members size. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.DeviceSet.rst bluez-5.71/doc/org.bluez.DeviceSet.rst --- bluez-5.70/doc/org.bluez.DeviceSet.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.DeviceSet.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,71 @@ +=================== +org.bluez.DeviceSet +=================== + +--------------------------------------- +BlueZ D-Bus DeviceSet API documentation +--------------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.DeviceSet1 +:Object path: [variable prefix]/{hci0,hci1,...}/set_{sirk} + +Methods +------- + +void Connect() [experimental] +````````````````````````````` + + Connects all **devices** members of the set, each member is + connected in sequence as they were added/loaded following the + same proceedure as described in **Device1.Connect**. + + Possible errors: + + :org.bluez.Error.NotReady: + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + :org.bluez.Error.AlreadyConnected: + +void Disconnect() [experimental] +```````````````````````````````` + + Disconnects all **devices** members of the set, each member is + disconnected in sequence as they were connected following the + same proceedure as described in **Device1.Disconnect**. + + Possible errors: + + :org.bluez.Error.NotConnected: + +Properties +---------- + +object Adapter [readonly, experimental] +``````````````````````````````````````` + + The object path of the adapter the set belongs to. + +bool AutoConnect [read-write, experimental] +``````````````````````````````````````````` + + Indicates if the **devices** members of the set shall be automatically + connected once any of its members is connected. + +array(object) Devices [ready-only, experimental] +```````````````````````````````````````````````` + + List of devices objects that are members of the set. + +byte Size [read-only, experimental] +``````````````````````````````````` + + Set members size. diff -Nru bluez-5.70/doc/org.bluez.GattCharacteristic.5 bluez-5.71/doc/org.bluez.GattCharacteristic.5 --- bluez-5.70/doc/org.bluez.GattCharacteristic.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattCharacteristic.5 2023-12-14 05:57:50.000000000 +0800 @@ -0,0 +1,465 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.GATTCHARACTERISTIC" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.GattCharacteristic \- BlueZ D-Bus GattCharacteristic API documentation +.SH DESCRIPTION +.sp +GATT local/server and remote/client characteristic attribute representation +share the same high\-level D\-Bus API. +.sp +Local/Server refers to GATT based characteristics exported by a plugin or an +external application. +.sp +Remote/Client refers to GATT characteristics exported by the peer. +.SH INTERFACE +.SS Client +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.GattCharacteristic1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY +.UNINDENT +.SS Server +.INDENT 0.0 +.TP +.B Service +unique name +.TP +.B Interface +org.bluez.GattCharacteristic1 +.TP +.B Object path +freely definable +.UNINDENT +.SS Methods +.SS array{byte} ReadValue(dict options) +.INDENT 0.0 +.INDENT 3.5 +Issues a request to read the value of the characteristic and returns the +value if the operation was successful. +.sp +Possible options: +.INDENT 0.0 +.TP +.B uint16_t offset +Read start offset in bytes. +.TP +.B uint16_t mtu (server only) +Exchange MTU in bytes. +.TP +.B object device (server only) +Device object. +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +Possible values: string 0x80 \- 0x9f +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.NotPermitted +.TP +.B org.bluez.Error.NotAuthorized +.TP +.B org.bluez.Error.InvalidOffset +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS void WriteValue(array{byte} value, dict options) +.INDENT 0.0 +.INDENT 3.5 +Issues a request to write the value of the characteristic. +.sp +Possible options: +.INDENT 0.0 +.TP +.B uint16 offset +Write start offset in bytes. +.TP +.B string type +Possible values: +.INDENT 7.0 +.TP +.B \(dqcommand\(dq +Use Write without response procedure. +.TP +.B \(dqrequest\(dq +Use Write with response procedure. +.TP +.B \(dqreliable\(dq +Use Reliable Write procedure. +.UNINDENT +.TP +.B uint16 mtu +Exchanged MTU (Server only). +.TP +.B object device +Device path (Server only). +.TP +.B string link +Link type (Server only). +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqBR/EDR\(dq +.TP +.B \(dqLE\(dq +.UNINDENT +.TP +.B boolean prepare\-authorize +True if prepare authorization request. +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +Possible values: string 0x80 \- 0x9f +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.NotPermitted +.TP +.B org.bluez.Error.InvalidValueLength +.TP +.B org.bluez.Error.NotAuthorized +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS fd, uint16 AcquireWrite(dict options) [optional] +.INDENT 0.0 +.INDENT 3.5 +Acquire file descriptor and MTU for writing. Only sockets are supported. +Usage of WriteValue will be locked causing it to return NotPermitted +error. +.sp +For server the MTU returned shall be equal or smaller than the +negotiated MTU. +.sp +For client it only works with characteristic that has \fBWriteAcquired\fP +property which relies on write\-without\-response \fBFlag\fP\&. +.sp +To release the lock the client shall close the file descriptor, a HUP +is generated in case the device is disconnected. +.sp +Note: the MTU can only be negotiated once and is symmetric therefore +this method may be delayed in order to have the exchange MTU completed, +because of that the file descriptor is closed during reconnections as +the MTU has to be renegotiated. +.sp +Possible options: +.INDENT 0.0 +.TP +.B object device +Object Device (Server only). +.TP +.B uint16 mtu +Exchanged MTU (Server only). +.TP +.B string link +Link type (Server only). +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqBR/EDR\(dq +.TP +.B \(dqLE\(dq +.UNINDENT +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS fd, uint16 AcquireNotify(dict options) [optional] +.INDENT 0.0 +.INDENT 3.5 +Acquire file descriptor and MTU for notify. Only sockets are support. +.sp +Usage of StartNotify will be locked causing it to return +\fBorg.bluez.Error.NotPermitted\fP\&. +.sp +For server the MTU returned shall be equal or smaller than the +negotiated MTU. +.sp +Only works with characteristic that has \fBNotifyAcquired\fP property +which relies on \fB\(dqnotify\(dq\fP \fBFlag\fP and no other client have called +\fBStartNotify()\fP\&. +.sp +Notification are enabled during this procedure so \fBStartNotify()\fP +shall not be called, any notification will be dispatched via file +descriptor therefore the Value property is not affected during the time +where notify has been acquired. +.sp +To release the lock the client shall close the file descriptor, a HUP is +generated in case the device is disconnected. +.sp +Note: the MTU can only be negotiated once and is symmetric therefore +this method may be delayed in order to have the exchange MTU completed, +because of that the file descriptor is closed during reconnections as +the MTU has to be renegotiated. +.sp +Possible options: +.INDENT 0.0 +.TP +.B object device +Object Device (Server only). +.TP +.B uint16 mtu +Exchanged MTU (Server only). +.TP +.B string link +Link type (Server only). +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqBR/EDR\(dq +.TP +.B \(dqLE\(dq +.UNINDENT +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.NotPermitted +.UNINDENT +.UNINDENT +.UNINDENT +.SS void StartNotify() +.INDENT 0.0 +.INDENT 3.5 +Starts a notification session from this characteristic if it supports +value notifications or indications. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.NotPermitted +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.NotConnected +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS void StopNotify() +.INDENT 0.0 +.INDENT 3.5 +Stops or cancel session previously created by \fBStartNotify()\fP\&. +.sp +Note that notifications from a characteristic are shared between +sessions thus calling StopNotify will release a single session. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Confirm() [noreply, optional] (Server only) +.INDENT 0.0 +.INDENT 3.5 +Confirms value was received. +.sp +Possible Errors: +.sp +org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.SS Properties +.SS string UUID [read\-only] +.INDENT 0.0 +.INDENT 3.5 +128\-bit characteristic UUID. +.UNINDENT +.UNINDENT +.SS object Service [read\-only] +.INDENT 0.0 +.INDENT 3.5 +Object path of the GATT service the characteristic belongs to. +.UNINDENT +.UNINDENT +.SS array{byte} Value [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +The cached value of the characteristic. This property gets updated only +after a successful read request and when a notification or indication +is received, upon which a PropertiesChanged signal will be emitted. +.UNINDENT +.UNINDENT +.SS boolean WriteAcquired [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +True, if this characteristic has been acquired by any client using +AcquireWrite. +.sp +For client properties is ommited in case \(aqwrite\-without\-response\(aq flag +is not set. +.sp +For server the presence of this property indicates that AcquireWrite is +supported. +.UNINDENT +.UNINDENT +.SS boolean NotifyAcquired [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +True, if this characteristic has been acquired by any client using +AcquireNotify. +.sp +For client this properties is ommited in case \(aqnotify\(aq flag is not set. +.sp +For server the presence of this property indicates that AcquireNotify +is supported. +.UNINDENT +.UNINDENT +.SS boolean Notifying [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +True, if notifications or indications on this characteristic are +currently enabled. +.UNINDENT +.UNINDENT +.SS array{string} Flags [read\-only] +.INDENT 0.0 +.INDENT 3.5 +Defines how the characteristic value can be used. See Core spec +\(dqTable 3.5: Characteristic Properties bit field\(dq, and +\(dqTable 3.8: Characteristic Extended Properties bit field\(dq. +.sp +The \(dqx\-notify\(dq and \(dqx\-indicate\(dq flags restrict access to notifications +and indications by imposing write restrictions on a characteristic\(aqs +client characteristic configuration descriptor. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqbroadcast\(dq +.TP +.B \(dqread\(dq +.TP +.B \(dqwrite\-without\-response\(dq +.TP +.B \(dqwrite\(dq +.TP +.B \(dqnotify\(dq +.TP +.B \(dqindicate\(dq +.TP +.B \(dqauthenticated\-signed\-writes\(dq +.TP +.B \(dqextended\-properties\(dq +.TP +.B \(dqreliable\-write\(dq +.TP +.B \(dqwritable\-auxiliaries\(dq +.TP +.B \(dqencrypt\-read\(dq +.TP +.B \(dqencrypt\-write\(dq +.TP +.B \(dqencrypt\-notify\(dq (Server only) +.TP +.B \(dqencrypt\-indicate\(dq (Server only) +.TP +.B \(dqencrypt\-authenticated\-read\(dq +.TP +.B \(dqencrypt\-authenticated\-write\(dq +.TP +.B \(dqencrypt\-authenticated\-notify\(dq (Server only) +.TP +.B \(dqencrypt\-authenticated\-indicate\(dq (Server only) +.TP +.B \(dqsecure\-read\(dq (Server only) +.TP +.B \(dqsecure\-write\(dq (Server only) +.TP +.B \(dqsecure\-notify\(dq (Server only) +.TP +.B \(dqsecure\-indicate\(dq (Server only) +.TP +.B \(dqauthorize\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint16 Handle [read\-only] (Client Only) +.INDENT 0.0 +.INDENT 3.5 +Characteristic handle. +.UNINDENT +.UNINDENT +.SS uint16 Handle [read\-write, optional] (Server Only) +.INDENT 0.0 +.INDENT 3.5 +Characteristic handle. When available in the server it would attempt to +use to allocate into the database which may fail, to auto allocate the +value 0x0000 shall be used which will cause the allocated handle to be +set once registered. +.UNINDENT +.UNINDENT +.SS uint16 MTU [read\-only] +.INDENT 0.0 +.INDENT 3.5 +Characteristic MTU, this is valid both for \fBReadValue()\fP and +\fBWriteValue()\fP but either method can use long procedures when +supported. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.GattCharacteristic.rst bluez-5.71/doc/org.bluez.GattCharacteristic.rst --- bluez-5.70/doc/org.bluez.GattCharacteristic.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattCharacteristic.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,375 @@ +============================ +org.bluez.GattCharacteristic +============================ + +------------------------------------------------ +BlueZ D-Bus GattCharacteristic API documentation +------------------------------------------------ + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +GATT local/server and remote/client characteristic attribute representation +share the same high-level D-Bus API. + +Local/Server refers to GATT based characteristics exported by a plugin or an +external application. + +Remote/Client refers to GATT characteristics exported by the peer. + +Interface +========= + +Client +------ + +:Service: org.bluez +:Interface: org.bluez.GattCharacteristic1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY + +Server +------ + +:Service: unique name +:Interface: org.bluez.GattCharacteristic1 +:Object path: freely definable + +Methods +------- + +array{byte} ReadValue(dict options) +``````````````````````````````````` + + Issues a request to read the value of the characteristic and returns the + value if the operation was successful. + + Possible options: + + :uint16_t offset: + + Read start offset in bytes. + + :uint16_t mtu (server only): + + Exchange MTU in bytes. + + :object device (server only): + + Device object. + + Possible Errors: + + :org.bluez.Error.Failed: + + Possible values: string 0x80 - 0x9f + + :org.bluez.Error.InProgress: + :org.bluez.Error.NotPermitted: + :org.bluez.Error.NotAuthorized: + :org.bluez.Error.InvalidOffset: + :org.bluez.Error.NotSupported: + +void WriteValue(array{byte} value, dict options) +```````````````````````````````````````````````` + + Issues a request to write the value of the characteristic. + + Possible options: + + :uint16 offset: + + Write start offset in bytes. + + :string type: + + Possible values: + + :"command": + + Use Write without response procedure. + + :"request": + + Use Write with response procedure. + + :"reliable": + + Use Reliable Write procedure. + + :uint16 mtu: + + Exchanged MTU (Server only). + + :object device: + + Device path (Server only). + + :string link: + + Link type (Server only). + + Possible values: + + :"BR/EDR": + :"LE": + + :boolean prepare-authorize: + + True if prepare authorization request. + + Possible Errors: + + :org.bluez.Error.Failed: + + Possible values: string 0x80 - 0x9f + + :org.bluez.Error.InProgress: + :org.bluez.Error.NotPermitted: + :org.bluez.Error.InvalidValueLength: + :org.bluez.Error.NotAuthorized: + :org.bluez.Error.NotSupported: + +fd, uint16 AcquireWrite(dict options) [optional] +```````````````````````````````````````````````` + + Acquire file descriptor and MTU for writing. Only sockets are supported. + Usage of WriteValue will be locked causing it to return NotPermitted + error. + + For server the MTU returned shall be equal or smaller than the + negotiated MTU. + + For client it only works with characteristic that has **WriteAcquired** + property which relies on write-without-response **Flag**. + + To release the lock the client shall close the file descriptor, a HUP + is generated in case the device is disconnected. + + Note: the MTU can only be negotiated once and is symmetric therefore + this method may be delayed in order to have the exchange MTU completed, + because of that the file descriptor is closed during reconnections as + the MTU has to be renegotiated. + + Possible options: + + :object device: + + Object Device (Server only). + + :uint16 mtu: + + Exchanged MTU (Server only). + + :string link: + + Link type (Server only). + + Possible values: + + :"BR/EDR": + :"LE": + + Possible Errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.NotSupported: + +fd, uint16 AcquireNotify(dict options) [optional] +````````````````````````````````````````````````` + + Acquire file descriptor and MTU for notify. Only sockets are support. + + Usage of StartNotify will be locked causing it to return + **org.bluez.Error.NotPermitted**. + + For server the MTU returned shall be equal or smaller than the + negotiated MTU. + + Only works with characteristic that has **NotifyAcquired** property + which relies on **"notify"** **Flag** and no other client have called + **StartNotify()**. + + Notification are enabled during this procedure so **StartNotify()** + shall not be called, any notification will be dispatched via file + descriptor therefore the Value property is not affected during the time + where notify has been acquired. + + To release the lock the client shall close the file descriptor, a HUP is + generated in case the device is disconnected. + + Note: the MTU can only be negotiated once and is symmetric therefore + this method may be delayed in order to have the exchange MTU completed, + because of that the file descriptor is closed during reconnections as + the MTU has to be renegotiated. + + Possible options: + + :object device: + + Object Device (Server only). + + :uint16 mtu: + + Exchanged MTU (Server only). + + :string link: + + Link type (Server only). + + Possible values: + + :"BR/EDR": + :"LE": + + Possible Errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.NotSupported: + :org.bluez.Error.NotPermitted: + +void StartNotify() +`````````````````` + + Starts a notification session from this characteristic if it supports + value notifications or indications. + + Possible Errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.NotPermitted: + :org.bluez.Error.InProgress: + :org.bluez.Error.NotConnected: + :org.bluez.Error.NotSupported: + +void StopNotify() +````````````````` + + Stops or cancel session previously created by **StartNotify()**. + + Note that notifications from a characteristic are shared between + sessions thus calling StopNotify will release a single session. + + Possible Errors: + + :org.bluez.Error.Failed: + +void Confirm() [noreply, optional] (Server only) +```````````````````````````````````````````````` + + + Confirms value was received. + + Possible Errors: + + org.bluez.Error.Failed + +Properties +---------- + +string UUID [read-only] +``````````````````````` + + 128-bit characteristic UUID. + +object Service [read-only] +`````````````````````````` + + Object path of the GATT service the characteristic belongs to. + +array{byte} Value [read-only, optional] +``````````````````````````````````````` + + The cached value of the characteristic. This property gets updated only + after a successful read request and when a notification or indication + is received, upon which a PropertiesChanged signal will be emitted. + +boolean WriteAcquired [read-only, optional] +``````````````````````````````````````````` + + True, if this characteristic has been acquired by any client using + AcquireWrite. + + For client properties is ommited in case 'write-without-response' flag + is not set. + + For server the presence of this property indicates that AcquireWrite is + supported. + +boolean NotifyAcquired [read-only, optional] +```````````````````````````````````````````` + + True, if this characteristic has been acquired by any client using + AcquireNotify. + + For client this properties is ommited in case 'notify' flag is not set. + + For server the presence of this property indicates that AcquireNotify + is supported. + +boolean Notifying [read-only, optional] +``````````````````````````````````````` + + True, if notifications or indications on this characteristic are + currently enabled. + +array{string} Flags [read-only] +``````````````````````````````` + + Defines how the characteristic value can be used. See Core spec + "Table 3.5: Characteristic Properties bit field", and + "Table 3.8: Characteristic Extended Properties bit field". + + The "x-notify" and "x-indicate" flags restrict access to notifications + and indications by imposing write restrictions on a characteristic's + client characteristic configuration descriptor. + + Possible values: + + :"broadcast": + :"read": + :"write-without-response": + :"write": + :"notify": + :"indicate": + :"authenticated-signed-writes": + :"extended-properties": + :"reliable-write": + :"writable-auxiliaries": + :"encrypt-read": + :"encrypt-write": + :"encrypt-notify" (Server only): + :"encrypt-indicate" (Server only): + :"encrypt-authenticated-read": + :"encrypt-authenticated-write": + :"encrypt-authenticated-notify" (Server only): + :"encrypt-authenticated-indicate" (Server only): + :"secure-read" (Server only): + :"secure-write" (Server only): + :"secure-notify" (Server only): + :"secure-indicate" (Server only): + :"authorize": + +uint16 Handle [read-only] (Client Only) +``````````````````````````````````````` + + Characteristic handle. + +uint16 Handle [read-write, optional] (Server Only) +`````````````````````````````````````````````````` + + Characteristic handle. When available in the server it would attempt to + use to allocate into the database which may fail, to auto allocate the + value 0x0000 shall be used which will cause the allocated handle to be + set once registered. + +uint16 MTU [read-only] +`````````````````````` + + Characteristic MTU, this is valid both for **ReadValue()** and + **WriteValue()** but either method can use long procedures when + supported. diff -Nru bluez-5.70/doc/org.bluez.GattDescriptor.5 bluez-5.71/doc/org.bluez.GattDescriptor.5 --- bluez-5.70/doc/org.bluez.GattDescriptor.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattDescriptor.5 2023-12-14 05:57:51.000000000 +0800 @@ -0,0 +1,224 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.GATTDESCRIPTOR" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.GattDescriptor \- BlueZ D-Bus GattDescriptor API documentation +.SH DESCRIPTION +.sp +GATT local/server and remote/client descriptor attribute representation +share the same high\-level D\-Bus API. +.sp +Local/Server refers to GATT based descriptors exported by a plugin or an +external application. +.sp +Remote/Client refers to GATT descriptors exported by the peer. +.SH INTERFACE +.SS Client +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.GattDescriptor1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ +.UNINDENT +.SS Server +.INDENT 0.0 +.TP +.B Service +unique name +.TP +.B Interface +org.bluez.GattDescriptor1 +.TP +.B Object path +freely definable +.UNINDENT +.SS Methods +.SS array{byte} ReadValue(dict flags) +.INDENT 0.0 +.INDENT 3.5 +Issues a request to read the value of the descriptor and returns the +value if the operation was successful. +.sp +Possible options: +.INDENT 0.0 +.TP +.B uint16_t offset +Read start offset in bytes. +.TP +.B object device (server only) +Device object. +.TP +.B string link +Link type (Server only). +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqBR/EDR\(dq +.TP +.B \(dqLE\(dq +.UNINDENT +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.NotPermitted +.TP +.B org.bluez.Error.NotAuthorized +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS void WriteValue(array{byte} value, dict flags) +.INDENT 0.0 +.INDENT 3.5 +Issues a request to write the value of the descriptor. +.sp +Possible flags: +.INDENT 0.0 +.TP +.B uint16 offset +Write start offset in bytes. +.TP +.B uint16 mtu +Exchanged MTU (Server only). +.TP +.B object device +Device path (Server only). +.TP +.B string link +Link type (Server only). +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqBR/EDR\(dq +.TP +.B \(dqLE\(dq +.UNINDENT +.TP +.B boolean prepare\-authorize +True if prepare authorization request. +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.NotPermitted +.TP +.B org.bluez.Error.InvalidValueLength +.TP +.B org.bluez.Error.NotAuthorized +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string UUID [read\-only] +.INDENT 0.0 +.INDENT 3.5 +128\-bit descriptor UUID. +.UNINDENT +.UNINDENT +.SS object Characteristic [read\-only] +.INDENT 0.0 +.INDENT 3.5 +Object path of the GATT characteristic the descriptor belongs to. +.UNINDENT +.UNINDENT +.SS array{byte} Value [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +The cached value of the descriptor. This property gets updated only +after a successful read request, upon which a PropertiesChanged signal +will be emitted. +.UNINDENT +.UNINDENT +.SS array{string} Flags [read\-only] +.INDENT 0.0 +.INDENT 3.5 +Defines how the descriptor value can be used. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqread\(dq +.TP +.B \(dqwrite\(dq +.TP +.B \(dqencrypt\-read\(dq +.TP +.B \(dqencrypt\-write\(dq +.TP +.B \(dqencrypt\-authenticated\-read\(dq +.TP +.B \(dqencrypt\-authenticated\-write\(dq +.TP +.B \(dqsecure\-read\(dq (Server Only) +.TP +.B \(dqsecure\-write\(dq (Server Only) +.TP +.B \(dqauthorize\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint16 Handle [read\-only] (Client Only) +.INDENT 0.0 +.INDENT 3.5 +Descriptor handle. +.UNINDENT +.UNINDENT +.SS uint16 Handle [read\-write, optional] (Server Only) +.INDENT 0.0 +.INDENT 3.5 +Descriptor handle. When available in the server it would attempt to +use to allocate into the database which may fail, to auto allocate the +value 0x0000 shall be used which will cause the allocated handle to be +set once registered. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.GattDescriptor.rst bluez-5.71/doc/org.bluez.GattDescriptor.rst --- bluez-5.70/doc/org.bluez.GattDescriptor.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattDescriptor.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,167 @@ +======================== +org.bluez.GattDescriptor +======================== + +-------------------------------------------- +BlueZ D-Bus GattDescriptor API documentation +-------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +GATT local/server and remote/client descriptor attribute representation +share the same high-level D-Bus API. + +Local/Server refers to GATT based descriptors exported by a plugin or an +external application. + +Remote/Client refers to GATT descriptors exported by the peer. + +Interface +========= + +Client +------ + +:Service: org.bluez +:Interface: org.bluez.GattDescriptor1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ + +Server +------ + +:Service: unique name +:Interface: org.bluez.GattDescriptor1 +:Object path: freely definable + +Methods +------- + +array{byte} ReadValue(dict flags) +````````````````````````````````` + + Issues a request to read the value of the descriptor and returns the + value if the operation was successful. + + Possible options: + + :uint16_t offset: + + Read start offset in bytes. + + :object device (server only): + + Device object. + + :string link: + + Link type (Server only). + + Possible values: + + :"BR/EDR": + :"LE": + + Possible Errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + :org.bluez.Error.NotPermitted: + :org.bluez.Error.NotAuthorized: + :org.bluez.Error.NotSupported: + +void WriteValue(array{byte} value, dict flags) +`````````````````````````````````````````````` + + Issues a request to write the value of the descriptor. + + Possible flags: + + :uint16 offset: + + Write start offset in bytes. + + :uint16 mtu: + + Exchanged MTU (Server only). + + :object device: + + Device path (Server only). + + :string link: + + Link type (Server only). + + Possible values: + + :"BR/EDR": + :"LE": + + :boolean prepare-authorize: + + True if prepare authorization request. + + Possible Errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.InProgress: + :org.bluez.Error.NotPermitted: + :org.bluez.Error.InvalidValueLength: + :org.bluez.Error.NotAuthorized: + :org.bluez.Error.NotSupported: + +Properties +---------- + +string UUID [read-only] +``````````````````````` + + 128-bit descriptor UUID. + +object Characteristic [read-only] +````````````````````````````````` + + Object path of the GATT characteristic the descriptor belongs to. + +array{byte} Value [read-only, optional] +``````````````````````````````````````` + + The cached value of the descriptor. This property gets updated only + after a successful read request, upon which a PropertiesChanged signal + will be emitted. + +array{string} Flags [read-only] +``````````````````````````````` + + Defines how the descriptor value can be used. + + Possible values: + + :"read": + :"write": + :"encrypt-read": + :"encrypt-write": + :"encrypt-authenticated-read": + :"encrypt-authenticated-write": + :"secure-read" (Server Only): + :"secure-write" (Server Only): + :"authorize": + +uint16 Handle [read-only] (Client Only) +``````````````````````````````````````` + + Descriptor handle. + +uint16 Handle [read-write, optional] (Server Only) +`````````````````````````````````````````````````` + + Descriptor handle. When available in the server it would attempt to + use to allocate into the database which may fail, to auto allocate the + value 0x0000 shall be used which will cause the allocated handle to be + set once registered. diff -Nru bluez-5.70/doc/org.bluez.GattManager.5 bluez-5.71/doc/org.bluez.GattManager.5 --- bluez-5.70/doc/org.bluez.GattManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattManager.5 2023-12-14 05:57:48.000000000 +0800 @@ -0,0 +1,149 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.GATTMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.GattManager \- BlueZ D-Bus GattManager API documentation +.SH DESCRIPTION +.sp +GATT Manager allows external applications to register GATT services and +profiles. +.sp +Registering a profile allows applications to subscribe to \fIremote/client\fP +services. +.sp +Registering a service allows applications to publish a \fIlocal/server\fP GATT +service, which then becomes available to remote devices. A GATT service is +represented by a D\-Bus object hierarchy where the root node corresponds to a +service and the child nodes represent characteristics and descriptors that +belong to that service. Each node must implement one of +\fBorg.bluez.GattService(5)\fP, \fBorg.bluez.GattCharacteristic(5)\fP or +\fBorg.bluez.GattDescriptor(5)\fP interfaces, based on the attribute it +represents. Each node must also implement the standard D\-Bus Properties +interface to expose their properties. These objects collectively represent a +GATT service definition. +.sp +To make service registration simple, \fBbluetoothd(8)\fP requires that all objects +that belong to a GATT service be grouped under a D\-Bus Object Manager that +solely manages the objects of that service. Hence, the standard +DBus.ObjectManager interface must be available on the root service path. An +example application hierarchy containing two separate GATT services may look +like this: +.INDENT 0.0 +.INDENT 3.5 +.sp +.EX +\-> /com/example + | \- org.freedesktop.DBus.ObjectManager + | + \-> /com/example/service0 + | | \- org.freedesktop.DBus.Properties + | | \- org.bluez.GattService1 + | | + | \-> /com/example/service0/char0 + | | \- org.freedesktop.DBus.Properties + | | \- org.bluez.GattCharacteristic1 + | | + | \-> /com/example/service0/char1 + | | \- org.freedesktop.DBus.Properties + | | \- org.bluez.GattCharacteristic1 + | | + | \-> /com/example/service0/char1/desc0 + | \- org.freedesktop.DBus.Properties + | \- org.bluez.GattDescriptor1 + | + \-> /com/example/service1 + | \- org.freedesktop.DBus.Properties + | \- org.bluez.GattService1 + | + \-> /com/example/service1/char0 + \- org.freedesktop.DBus.Properties + \- org.bluez.GattCharacteristic1 +.EE +.UNINDENT +.UNINDENT +.sp +When a service is registered, \fBbluetoothd(8)\fP will automatically obtain +information about all objects using the service\(aqs Object Manager. Once a service +has been registered, the objects of a service should not be removed. If +\fBbluetoothd(8)\fP receives an InterfacesRemoved signal from a service\(aqs Object +Manager, it will immediately unregister the service. Similarly, if the +application disconnects from the bus, all of its registered services will be +automatically unregistered. InterfacesAdded signals will be ignored. +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.GattManager1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void RegisterApplication(object application, dict options) +.INDENT 0.0 +.INDENT 3.5 +Registers a local GATT services hierarchy as described above +(GATT Server) and/or GATT profiles (GATT Client). +.sp +The application object path together with the D\-Bus system bus +connection ID define the identification of the application registering +a GATT based service (\fBorg.bluez.GattService(5)\fP) and/or profile +(\fBorg.bluez.GattProfile(5)\fP). +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterApplication(object application) +.INDENT 0.0 +.INDENT 3.5 +This unregisters the services and/or profiles that has been previously +registered using \fBRegisterApplication()\fP\&. The object path parameter +must match the same value that has been used on registration. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.GattManager.rst bluez-5.71/doc/org.bluez.GattManager.rst --- bluez-5.70/doc/org.bluez.GattManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,114 @@ +===================== +org.bluez.GattManager +===================== + +----------------------------------------- +BlueZ D-Bus GattManager API documentation +----------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +GATT Manager allows external applications to register GATT services and +profiles. + +Registering a profile allows applications to subscribe to *remote/client* +services. + +Registering a service allows applications to publish a *local/server* GATT +service, which then becomes available to remote devices. A GATT service is +represented by a D-Bus object hierarchy where the root node corresponds to a +service and the child nodes represent characteristics and descriptors that +belong to that service. Each node must implement one of +**org.bluez.GattService(5)**, **org.bluez.GattCharacteristic(5)** or +**org.bluez.GattDescriptor(5)** interfaces, based on the attribute it +represents. Each node must also implement the standard D-Bus Properties +interface to expose their properties. These objects collectively represent a +GATT service definition. + +To make service registration simple, **bluetoothd(8)** requires that all objects +that belong to a GATT service be grouped under a D-Bus Object Manager that +solely manages the objects of that service. Hence, the standard +DBus.ObjectManager interface must be available on the root service path. An +example application hierarchy containing two separate GATT services may look +like this: + +.. code-block:: + + -> /com/example + | - org.freedesktop.DBus.ObjectManager + | + -> /com/example/service0 + | | - org.freedesktop.DBus.Properties + | | - org.bluez.GattService1 + | | + | -> /com/example/service0/char0 + | | - org.freedesktop.DBus.Properties + | | - org.bluez.GattCharacteristic1 + | | + | -> /com/example/service0/char1 + | | - org.freedesktop.DBus.Properties + | | - org.bluez.GattCharacteristic1 + | | + | -> /com/example/service0/char1/desc0 + | - org.freedesktop.DBus.Properties + | - org.bluez.GattDescriptor1 + | + -> /com/example/service1 + | - org.freedesktop.DBus.Properties + | - org.bluez.GattService1 + | + -> /com/example/service1/char0 + - org.freedesktop.DBus.Properties + - org.bluez.GattCharacteristic1 + +When a service is registered, **bluetoothd(8)** will automatically obtain +information about all objects using the service's Object Manager. Once a service +has been registered, the objects of a service should not be removed. If +**bluetoothd(8)** receives an InterfacesRemoved signal from a service's Object +Manager, it will immediately unregister the service. Similarly, if the +application disconnects from the bus, all of its registered services will be +automatically unregistered. InterfacesAdded signals will be ignored. + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.GattManager1 +:Object path: [variable prefix]/{hci0,hci1,...} + +Methods +------- + +void RegisterApplication(object application, dict options) +`````````````````````````````````````````````````````````` + + Registers a local GATT services hierarchy as described above + (GATT Server) and/or GATT profiles (GATT Client). + + The application object path together with the D-Bus system bus + connection ID define the identification of the application registering + a GATT based service (**org.bluez.GattService(5)**) and/or profile + (**org.bluez.GattProfile(5)**). + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + +void UnregisterApplication(object application) +`````````````````````````````````````````````` + + This unregisters the services and/or profiles that has been previously + registered using **RegisterApplication()**. The object path parameter + must match the same value that has been used on registration. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.DoesNotExist: diff -Nru bluez-5.70/doc/org.bluez.GattProfile.5 bluez-5.71/doc/org.bluez.GattProfile.5 --- bluez-5.70/doc/org.bluez.GattProfile.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattProfile.5 2023-12-14 05:57:49.000000000 +0800 @@ -0,0 +1,69 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.GATTPROFILE" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.GattProfile \- BlueZ D-Bus GattProfile API documentation +.SH DESCRIPTION +.sp +Local profile (GATT client) instance. By registering this type of object +an application effectively indicates support for a specific GATT profile +and requests automatic connections to be established to devices +supporting it. +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service + +.TP +.B Interface +org.bluez.GattProfile1 +.TP +.B Object path + +.UNINDENT +.SS Methods +.SS void Release() +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon +unregisters the profile. The profile can use it to do cleanup tasks. +There is no need to unregister the profile, because when this method +gets called it has already been unregistered. +.UNINDENT +.UNINDENT +.SS Properties +.SS array{string} UUIDs [read\-only] +.INDENT 0.0 +.INDENT 3.5 +128\-bit GATT service UUIDs to auto connect. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.GattProfile.rst bluez-5.71/doc/org.bluez.GattProfile.rst --- bluez-5.70/doc/org.bluez.GattProfile.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattProfile.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,46 @@ +===================== +org.bluez.GattProfile +===================== + +----------------------------------------- +BlueZ D-Bus GattProfile API documentation +----------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +Local profile (GATT client) instance. By registering this type of object +an application effectively indicates support for a specific GATT profile +and requests automatic connections to be established to devices +supporting it. + +Interface +========= + +:Service: +:Interface: org.bluez.GattProfile1 +:Object path: + +Methods +------- + +void Release() +`````````````` + + This method gets called when the service daemon + unregisters the profile. The profile can use it to do cleanup tasks. + There is no need to unregister the profile, because when this method + gets called it has already been unregistered. + +Properties +---------- + +array{string} UUIDs [read-only] +``````````````````````````````` + + 128-bit GATT service UUIDs to auto connect. diff -Nru bluez-5.70/doc/org.bluez.GattService.5 bluez-5.71/doc/org.bluez.GattService.5 --- bluez-5.70/doc/org.bluez.GattService.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattService.5 2023-12-14 05:57:49.000000000 +0800 @@ -0,0 +1,111 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.GATTSERVICE" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.GattService \- BlueZ D-Bus GattService API documentation +.SH DESCRIPTION +.sp +GATT local/server and remote/client services share the same high\-level D\-Bus +API. +.sp +Local/Server refers to GATT based service exported by a plugin or an external +application. +.sp +Remote/Client refers to GATT services exported by the peer. +.SH INTERFACE +.SS Client +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.GattService1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX +.UNINDENT +.SS Server +.INDENT 0.0 +.TP +.B Service +unique name +.TP +.B Interface +org.bluez.GattService1 +.TP +.B Object path +freely definable +.UNINDENT +.SS Properties +.SS string UUID [read\-only] +.INDENT 0.0 +.INDENT 3.5 +128\-bit service UUID. +.UNINDENT +.UNINDENT +.SS boolean Primary [read\-only] +.INDENT 0.0 +.INDENT 3.5 +Indicates whether or not this GATT service is a primary service. If +false, the service is secondary. +.UNINDENT +.UNINDENT +.SS object Device [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +Object path of the Bluetooth device the service belongs to. Only +present on services from remote devices. +.UNINDENT +.UNINDENT +.SS array{object} Includes [read\-only, optional] +.INDENT 0.0 +.INDENT 3.5 +Array of object paths representing the included services of this +service. +.UNINDENT +.UNINDENT +.SS uint16 Handle [read\-only] (client only) +.INDENT 0.0 +.INDENT 3.5 +Service handle. +.UNINDENT +.UNINDENT +.SS uint16 Handle [read\-write, optional] (Server Only) +.INDENT 0.0 +.INDENT 3.5 +Service handle. When available in the server it would attempt to use to +allocate into the database which may fail, to auto allocate the value +0x0000 shall be used which will cause the allocated handle to be set +once registered. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.GattService.rst bluez-5.71/doc/org.bluez.GattService.rst --- bluez-5.70/doc/org.bluez.GattService.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.GattService.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,79 @@ +===================== +org.bluez.GattService +===================== + +------------------------------------------------- +BlueZ D-Bus GattService API documentation +------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +GATT local/server and remote/client services share the same high-level D-Bus +API. + +Local/Server refers to GATT based service exported by a plugin or an external +application. + +Remote/Client refers to GATT services exported by the peer. + +Interface +========= + +Client +------ + +:Service: org.bluez +:Interface: org.bluez.GattService1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX + +Server +------ + +:Service: unique name +:Interface: org.bluez.GattService1 +:Object path: freely definable + +Properties +---------- + +string UUID [read-only] +``````````````````````` + + 128-bit service UUID. + +boolean Primary [read-only] +``````````````````````````` + + Indicates whether or not this GATT service is a primary service. If + false, the service is secondary. + +object Device [read-only, optional] +``````````````````````````````````` + + Object path of the Bluetooth device the service belongs to. Only + present on services from remote devices. + +array{object} Includes [read-only, optional] +```````````````````````````````````````````` + + Array of object paths representing the included services of this + service. + +uint16 Handle [read-only] (client only) +``````````````````````````````````````` + + Service handle. + +uint16 Handle [read-write, optional] (Server Only) +`````````````````````````````````````````````````` + + Service handle. When available in the server it would attempt to use to + allocate into the database which may fail, to auto allocate the value + 0x0000 shall be used which will cause the allocated handle to be set + once registered. diff -Nru bluez-5.70/doc/org.bluez.Input.5 bluez-5.71/doc/org.bluez.Input.5 --- bluez-5.70/doc/org.bluez.Input.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Input.5 2023-12-14 05:57:39.000000000 +0800 @@ -0,0 +1,75 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.INPUT" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Input \- BlueZ D-Bus Input API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.Input1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX +.UNINDENT +.SS Properties +.SS string ReconnectMode [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates the Connectability mode of the HID device as defined by the +HID Profile specification, Section 5.4.2. +.sp +This mode is based in the two properties HIDReconnectInitiate (see +Section 5.3.4.6) and HIDNormallyConnectable (see Section 5.3.4.14) which +define the following four possible values: +.INDENT 0.0 +.TP +.B \(dqnone\(dq +Device and host are not required to automatically restore the +connection. +.TP +.B \(dqhost\(dq +Bluetooth HID host restores connection. +.TP +.B \(dqdevice\(dq +Bluetooth HID device restores connection. +.TP +.B \(dqany\(dq +Bluetooth HID device shall attempt to restore the lost +connection, but Bluetooth HID Host may also restore the +connection. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.Input.rst bluez-5.71/doc/org.bluez.Input.rst --- bluez-5.70/doc/org.bluez.Input.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Input.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,51 @@ +=============== +org.bluez.Input +=============== + +----------------------------------- +BlueZ D-Bus Input API documentation +----------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.Input1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Properties +---------- + +string ReconnectMode [readonly] +``````````````````````````````` + + Indicates the Connectability mode of the HID device as defined by the + HID Profile specification, Section 5.4.2. + + This mode is based in the two properties HIDReconnectInitiate (see + Section 5.3.4.6) and HIDNormallyConnectable (see Section 5.3.4.14) which + define the following four possible values: + + :"none": + + Device and host are not required to automatically restore the + connection. + + :"host": + + Bluetooth HID host restores connection. + + :"device": + + Bluetooth HID device restores connection. + + :"any": + + Bluetooth HID device shall attempt to restore the lost + connection, but Bluetooth HID Host may also restore the + connection. diff -Nru bluez-5.70/doc/org.bluez.LEAdvertisement.5 bluez-5.71/doc/org.bluez.LEAdvertisement.5 --- bluez-5.70/doc/org.bluez.LEAdvertisement.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.LEAdvertisement.5 2023-12-14 05:57:52.000000000 +0800 @@ -0,0 +1,244 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.LEADVERTISEMENT" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.LEAdvertisement \- BlueZ D-Bus LEAdvertisement API documentation +.SH DESCRIPTION +.sp +Advertising packets are structured data which is broadcast on the LE Advertising +channels and available for all devices in range. Because of the limited space +available in LE Advertising packets, each packet\(aqs contents must be carefully +controlled. +.sp +The service daemon acts as a store for the Advertisement Data which is meant to +be sent. It constructs the correct Advertisement Data from the structured +data and configured the kernel to send the correct advertisement. +.SH INTERFACE +.sp +Specifies the Advertisement Data to be broadcast and some advertising +parameters. Properties which are not present will not be included in the +data. Required advertisement data types will always be included. +All UUIDs are 128\-bit versions in the API, and 16 or 32\-bit +versions of the same UUID will be used in the advertising data as appropriate. +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.LEAdvertisement1 +.TP +.B Object path +freely definable +.UNINDENT +.SS Methods +.SS void Release() [noreply] +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon removes the +Advertisement. A client can use it to do cleanup tasks. There is no +need to call \fBUnregisterAdvertisement()\fP because when this method +gets called it has already been unregistered. +.UNINDENT +.UNINDENT +.SS Properties +.SS string Type [readonly] +.INDENT 0.0 +.INDENT 3.5 +Determines the type of advertising packet requested. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqbroadcast\(dq +.TP +.B \(dqperipheral\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} ServiceUUIDs +.INDENT 0.0 +.INDENT 3.5 +List of UUIDs to include in the \(dqService UUID\(dq field of the Advertising +Data. +.UNINDENT +.UNINDENT +.SS dict ManufacturerData +.INDENT 0.0 +.INDENT 3.5 +Manufacturer Data fields to include in the Advertising Data. Keys are +the Manufacturer ID to associate with the data. +.UNINDENT +.UNINDENT +.SS array{string} SolicitUUIDs +.INDENT 0.0 +.INDENT 3.5 +Array of UUIDs to include in \(dqService Solicitation\(dq Advertisement Data. +.UNINDENT +.UNINDENT +.SS dict ServiceData +.INDENT 0.0 +.INDENT 3.5 +Service Data elements to include. The keys are the UUID to associate +with the data. +.UNINDENT +.UNINDENT +.SS dict Data [Experimental] +.INDENT 0.0 +.INDENT 3.5 +Advertising Data to include. Key is the advertising type and value is +the data as byte array. +.sp +Note: Types already handled by other properties shall not be used. +.sp +Possible values: +.INDENT 0.0 +.TP +.B + +.UNINDENT +.INDENT 0.0 +.TP +.B Example: + +0x26 0x01 0x01... +.UNINDENT +.UNINDENT +.UNINDENT +.SS bool Discoverable [Experimental] +.INDENT 0.0 +.INDENT 3.5 +Advertise as general discoverable. When present this will override +adapter Discoverable property. +.sp +Note: This property shall not be set when \fBType\fP is set to +\(dqbroadcast\(dq. +.UNINDENT +.UNINDENT +.SS uint16 DiscoverableTimeout [Experimental] +.INDENT 0.0 +.INDENT 3.5 +The discoverable timeout in seconds. A value of zero means that the +timeout is disabled and it will stay in discoverable/limited mode +forever. +.sp +Note: This property shall not be set when \fBType\fP is set to +\(dqbroadcast\(dq. +.UNINDENT +.UNINDENT +.SS array{string} Includes +.INDENT 0.0 +.INDENT 3.5 +List of features to be included in the advertising packet. +.sp +Possible values: +.sp +See \fBorg.bluez.LEAdvertisingManager(5)\fP \fBSupportedIncludes\fP +property. +.UNINDENT +.UNINDENT +.SS string LocalName +.INDENT 0.0 +.INDENT 3.5 +Local name to be used in the advertising report. If the string is too +big to fit into the packet it will be truncated. +.sp +If this property is available \(aqlocal\-name\(aq cannot be present in the +\fBIncludes\fP\&. +.UNINDENT +.UNINDENT +.SS uint16 Appearance +.INDENT 0.0 +.INDENT 3.5 +Appearance to be used in the advertising report. +.sp +Possible values: as found on GAP Service. +.UNINDENT +.UNINDENT +.SS uint16_t Duration +.INDENT 0.0 +.INDENT 3.5 +Rotation duration of the advertisement in seconds. If there are other +applications advertising no duration is set the default is 2 seconds. +.UNINDENT +.UNINDENT +.SS uint16_t Timeout +.INDENT 0.0 +.INDENT 3.5 +Timeout of the advertisement in seconds. This defines the lifetime of +the advertisement. +.UNINDENT +.UNINDENT +.SS string SecondaryChannel [Experimental] +.INDENT 0.0 +.INDENT 3.5 +Secondary channel to be used. Primary channel is always set to \(dq1M\(dq +except when \(dqCoded\(dq is set. +.sp +Possible value: +.INDENT 0.0 +.TP +.B \(dq1M\(dq (default) +.TP +.B \(dq2M\(dq +.TP +.B \(dqCoded\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint32 MinInterval [Experimental] +.INDENT 0.0 +.INDENT 3.5 +Minimum advertising interval to be used by the advertising set, in +milliseconds. Acceptable values are in the range [20ms, 10,485s]. +If the provided MinInterval is larger than the provided MaxInterval, +the registration will return failure. +.UNINDENT +.UNINDENT +.SS uint32 MaxInterval [Experimental] +.INDENT 0.0 +.INDENT 3.5 +Maximum advertising interval to be used by the advertising set, in +milliseconds. Acceptable values are in the range [20ms, 10,485s]. If the +provided MinInterval is larger than the provided MaxInterval, the +registration will return failure. +.UNINDENT +.UNINDENT +.SS int16 TxPower [Experimental] +.INDENT 0.0 +.INDENT 3.5 +Requested transmission power of this advertising set. The provided value +is used only if the \(dqCanSetTxPower\(dq feature is enabled on the +\fBorg.bluez.LEAdvertisingManager(5)\fP\&. The provided value must be in +range [\-127 to +20], where units are in dBm. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.LEAdvertisement.rst bluez-5.71/doc/org.bluez.LEAdvertisement.rst --- bluez-5.70/doc/org.bluez.LEAdvertisement.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.LEAdvertisement.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,195 @@ +========================= +org.bluez.LEAdvertisement +========================= + +--------------------------------------------- +BlueZ D-Bus LEAdvertisement API documentation +--------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Description +=========== + +Advertising packets are structured data which is broadcast on the LE Advertising +channels and available for all devices in range. Because of the limited space +available in LE Advertising packets, each packet's contents must be carefully +controlled. + +The service daemon acts as a store for the Advertisement Data which is meant to +be sent. It constructs the correct Advertisement Data from the structured +data and configured the kernel to send the correct advertisement. + +Interface +========= + +Specifies the Advertisement Data to be broadcast and some advertising +parameters. Properties which are not present will not be included in the +data. Required advertisement data types will always be included. +All UUIDs are 128-bit versions in the API, and 16 or 32-bit +versions of the same UUID will be used in the advertising data as appropriate. + +:Service: org.bluez +:Interface: org.bluez.LEAdvertisement1 +:Object path: freely definable + +Methods +------- + +void Release() [noreply] +```````````````````````` + + This method gets called when the service daemon removes the + Advertisement. A client can use it to do cleanup tasks. There is no + need to call **UnregisterAdvertisement()** because when this method + gets called it has already been unregistered. + +Properties +---------- + +string Type [readonly] +`````````````````````` + + Determines the type of advertising packet requested. + + Possible values: + + :"broadcast": + :"peripheral": + +array{string} ServiceUUIDs +`````````````````````````` + + List of UUIDs to include in the "Service UUID" field of the Advertising + Data. + +dict ManufacturerData +````````````````````` + + Manufacturer Data fields to include in the Advertising Data. Keys are + the Manufacturer ID to associate with the data. + +array{string} SolicitUUIDs +`````````````````````````` + + Array of UUIDs to include in "Service Solicitation" Advertisement Data. + +dict ServiceData +```````````````` + + Service Data elements to include. The keys are the UUID to associate + with the data. + +dict Data [Experimental] +```````````````````````` + + Advertising Data to include. Key is the advertising type and value is + the data as byte array. + + Note: Types already handled by other properties shall not be used. + + Possible values: + + :: + + + + Example: + + 0x26 0x01 0x01... + +bool Discoverable [Experimental] +```````````````````````````````` + + Advertise as general discoverable. When present this will override + adapter Discoverable property. + + Note: This property shall not be set when **Type** is set to + "broadcast". + +uint16 DiscoverableTimeout [Experimental] +````````````````````````````````````````` + + The discoverable timeout in seconds. A value of zero means that the + timeout is disabled and it will stay in discoverable/limited mode + forever. + + Note: This property shall not be set when **Type** is set to + "broadcast". + +array{string} Includes +`````````````````````` + + List of features to be included in the advertising packet. + + Possible values: + + See **org.bluez.LEAdvertisingManager(5)** **SupportedIncludes** + property. + +string LocalName +```````````````` + + Local name to be used in the advertising report. If the string is too + big to fit into the packet it will be truncated. + + If this property is available 'local-name' cannot be present in the + **Includes**. + +uint16 Appearance +````````````````` + + Appearance to be used in the advertising report. + + Possible values: as found on GAP Service. + +uint16_t Duration +````````````````` + + Rotation duration of the advertisement in seconds. If there are other + applications advertising no duration is set the default is 2 seconds. + +uint16_t Timeout +```````````````` + + Timeout of the advertisement in seconds. This defines the lifetime of + the advertisement. + +string SecondaryChannel [Experimental] +`````````````````````````````````````` + + Secondary channel to be used. Primary channel is always set to "1M" + except when "Coded" is set. + + Possible value: + + :"1M" (default): + :"2M": + :"Coded": + +uint32 MinInterval [Experimental] +````````````````````````````````` + + Minimum advertising interval to be used by the advertising set, in + milliseconds. Acceptable values are in the range [20ms, 10,485s]. + If the provided MinInterval is larger than the provided MaxInterval, + the registration will return failure. + +uint32 MaxInterval [Experimental] +````````````````````````````````` + + Maximum advertising interval to be used by the advertising set, in + milliseconds. Acceptable values are in the range [20ms, 10,485s]. If the + provided MinInterval is larger than the provided MaxInterval, the + registration will return failure. + +int16 TxPower [Experimental] +```````````````````````````` + + Requested transmission power of this advertising set. The provided value + is used only if the "CanSetTxPower" feature is enabled on the + **org.bluez.LEAdvertisingManager(5)**. The provided value must be in + range [-127 to +20], where units are in dBm. diff -Nru bluez-5.70/doc/org.bluez.LEAdvertisingManager.5 bluez-5.71/doc/org.bluez.LEAdvertisingManager.5 --- bluez-5.70/doc/org.bluez.LEAdvertisingManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.LEAdvertisingManager.5 2023-12-14 05:57:52.000000000 +0800 @@ -0,0 +1,189 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.LEADVERTISINGMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.LEAdvertisingManager \- BlueZ D-Bus LEAvertisingManager API documentation +.SH INTERFACE +.sp +The Advertising Manager allows external applications to register Advertisement +Data which should be broadcast to devices. Advertisement Data elements must +follow the API for LE Advertisement Data described above. +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.LEAdvertisingManager1 +.TP +.B Object path +/org/bluez/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void RegisterAdvertisement(object advertisement, dict options) +.INDENT 0.0 +.INDENT 3.5 +Registers an advertisement object to be sent over the LE Advertising +channel. The service must implement \fBorg.bluez.LEAdvertisement(5)\fP +interface. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +Indicates that the object has invalid or conflicting properties. +.TP +.B org.bluez.Error.AlreadyExists +Indicates the object is already registered. +.TP +.B org.bluez.Error.InvalidLength +Indicates that the data provided generates a data packet which +is too long +.TP +.B org.bluez.Error.NotPermitted +Indicates the maximum number of advertisement instances has +been reached. +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterAdvertisement(object advertisement) +.INDENT 0.0 +.INDENT 3.5 +Unregisters an advertisement that has been previously registered using +\fBRegisterAdvertisement()\fP\&. The object path parameter must match the +same value that has been used on registration. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS byte ActiveInstances [readonly] +.INDENT 0.0 +.INDENT 3.5 +Number of active advertising instances. +.UNINDENT +.UNINDENT +.SS byte SupportedInstances [readonly] +.INDENT 0.0 +.INDENT 3.5 +Number of available advertising instances. +.UNINDENT +.UNINDENT +.SS array{string} SupportedIncludes [readonly] +.INDENT 0.0 +.INDENT 3.5 +List of supported system includes. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqtx\-power\(dq +.TP +.B \(dqappearance\(dq +.TP +.B \(dqlocal\-name\(dq +.TP +.B \(dqrsi\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} SupportedSecondaryChannels [readonly, Experimental] +.INDENT 0.0 +.INDENT 3.5 +List of supported Secondary channels. Secondary channels can be used to +advertise with the corresponding PHY. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dq1M\(dq +.TP +.B \(dq2M\(dq +.TP +.B \(dqCoded\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS dict SupportedCapabilities [readonly, Experimental] +.INDENT 0.0 +.INDENT 3.5 +Enumerates Advertising\-related controller capabilities useful to the +client. +.sp +Possible Values: +.INDENT 0.0 +.TP +.B byte MaxAdvLen +Max advertising data length +.TP +.B byte MaxScnRspLen +Max advertising scan response length +.UNINDENT +.sp +;int16 MinTxPower: +.INDENT 0.0 +.INDENT 3.5 +Min advertising tx power (dBm) +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B int16 MaxTxPower +Max advertising tx power (dBm) +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} SupportedFeatures [readonly,optional,Experimental] +.INDENT 0.0 +.INDENT 3.5 +List of supported platform features. If no features are available on +the platform, the SupportedFeatures array will be empty. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqCanSetTxPower\(dq +Indicates whether platform can specify tx power on each +advertising instance. +.TP +.B \(dqHardwareOffload\(dq +Indicates whether multiple advertising will be offloaded to the +controller. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.LEAdvertisingManager.rst bluez-5.71/doc/org.bluez.LEAdvertisingManager.rst --- bluez-5.70/doc/org.bluez.LEAdvertisingManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.LEAdvertisingManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,144 @@ +============================== +org.bluez.LEAdvertisingManager +============================== + +------------------------------------------------- +BlueZ D-Bus LEAvertisingManager API documentation +------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +The Advertising Manager allows external applications to register Advertisement +Data which should be broadcast to devices. Advertisement Data elements must +follow the API for LE Advertisement Data described above. + +:Service: org.bluez +:Interface: org.bluez.LEAdvertisingManager1 +:Object path: /org/bluez/{hci0,hci1,...} + +Methods +------- + +void RegisterAdvertisement(object advertisement, dict options) +`````````````````````````````````````````````````````````````` + + Registers an advertisement object to be sent over the LE Advertising + channel. The service must implement **org.bluez.LEAdvertisement(5)** + interface. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + + Indicates that the object has invalid or conflicting properties. + + :org.bluez.Error.AlreadyExists: + + Indicates the object is already registered. + + :org.bluez.Error.InvalidLength: + + Indicates that the data provided generates a data packet which + is too long + + :org.bluez.Error.NotPermitted: + + Indicates the maximum number of advertisement instances has + been reached. + +void UnregisterAdvertisement(object advertisement) +`````````````````````````````````````````````````` + + Unregisters an advertisement that has been previously registered using + **RegisterAdvertisement()**. The object path parameter must match the + same value that has been used on registration. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.DoesNotExist: + +Properties +---------- + +byte ActiveInstances [readonly] +``````````````````````````````` + + Number of active advertising instances. + +byte SupportedInstances [readonly] +`````````````````````````````````` + + Number of available advertising instances. + +array{string} SupportedIncludes [readonly] +`````````````````````````````````````````` + + List of supported system includes. + + Possible values: + + :"tx-power": + :"appearance": + :"local-name": + :"rsi": + +array{string} SupportedSecondaryChannels [readonly, Experimental] +````````````````````````````````````````````````````````````````` + + List of supported Secondary channels. Secondary channels can be used to + advertise with the corresponding PHY. + + Possible values: + + :"1M": + :"2M": + :"Coded": + +dict SupportedCapabilities [readonly, Experimental] +``````````````````````````````````````````````````` + + Enumerates Advertising-related controller capabilities useful to the + client. + + Possible Values: + + :byte MaxAdvLen: + + Max advertising data length + + :byte MaxScnRspLen: + + Max advertising scan response length + + ;int16 MinTxPower: + + Min advertising tx power (dBm) + + :int16 MaxTxPower: + + Max advertising tx power (dBm) + +array{string} SupportedFeatures [readonly,optional,Experimental] +```````````````````````````````````````````````````````````````` + + List of supported platform features. If no features are available on + the platform, the SupportedFeatures array will be empty. + + Possible values: + + :"CanSetTxPower": + + Indicates whether platform can specify tx power on each + advertising instance. + + :"HardwareOffload": + + Indicates whether multiple advertising will be offloaded to the + controller. diff -Nru bluez-5.70/doc/org.bluez.Media.5 bluez-5.71/doc/org.bluez.Media.5 --- bluez-5.70/doc/org.bluez.Media.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Media.5 2023-12-14 05:57:43.000000000 +0800 @@ -0,0 +1,175 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIA" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Media \- BlueZ D-Bus Media API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.Media1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void RegisterEndpoint(object endpoint, dict properties) +.INDENT 0.0 +.INDENT 3.5 +Register a local end point to sender, the sender can register as many +end points as it likes. +.sp +Note: If the sender disconnects the end points are automatically +unregistered. +.sp +possible properties: +.INDENT 0.0 +.TP +.B string UUID +UUID of the profile which the endpoint is for. +.sp +UUID must be in the list of SupportedUUIDS. +.TP +.B byte Codec +Assigned number of codec that the endpoint implements. The +values should match the profile specification which is +indicated by the UUID. +.TP +.B uint32_t Vendor [Optional] +Vendor\-specific Company ID, Codec ID tuple that the endpoint +implements. +.sp +It shall be set to appropriate value when Vendor Specific Codec +(0xff) is used. +.TP +.B array{byte} Capabilities +Capabilities blob, it is used as it is so the size and byte +order must match. +.TP +.B array{byte} Metadata [Optional] +Metadata blob, it is used as it is so the size and byte order +must match. +.UNINDENT +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +emitted when interface for the end\-point is disabled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterEndpoint(object endpoint) +.INDENT 0.0 +.INDENT 3.5 +Unregister sender end point. +.UNINDENT +.UNINDENT +.SS void RegisterPlayer(object player, dict properties) +.INDENT 0.0 +.INDENT 3.5 +Register a media player object to sender, the sender can register as +many objects as it likes. +.sp +Object must implement at least org.mpris.MediaPlayer2.Player as defined +in MPRIS 2.2 spec: +.INDENT 0.0 +.INDENT 3.5 +\fI\%http://specifications.freedesktop.org/mpris\-spec/latest/\fP +.UNINDENT +.UNINDENT +.sp +Note: If the sender disconnects its objects are automatically +unregistered. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterPlayer(object player) +.INDENT 0.0 +.INDENT 3.5 +Unregister sender media player. +.UNINDENT +.UNINDENT +.SS void RegisterApplication(object root, dict options) +.INDENT 0.0 +.INDENT 3.5 +Register endpoints an player objects within root object which must +implement ObjectManager. +.sp +The application object path together with the D\-Bus system bus +connection ID define the identification of the application. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterApplication(object application) +.INDENT 0.0 +.INDENT 3.5 +This unregisters the services that has been previously registered. The +object path parameter must match the same value that has been used on +registration. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS array{string} SupportedUUIDs [readonly] +.INDENT 0.0 +.INDENT 3.5 +List of 128\-bit UUIDs that represents the supported Endpoint +registration. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaControl.5 bluez-5.71/doc/org.bluez.MediaControl.5 --- bluez-5.70/doc/org.bluez.MediaControl.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaControl.5 2023-12-14 05:57:44.000000000 +0800 @@ -0,0 +1,111 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIACONTROL" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.MediaControl \- BlueZ D-Bus MediaControl API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.MediaControl1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX +.UNINDENT +.SS Methods +.SS void Play() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Resume playback. +.UNINDENT +.UNINDENT +.SS void Pause() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Pause playback. +.UNINDENT +.UNINDENT +.SS void Stop() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Stop playback. +.UNINDENT +.UNINDENT +.SS void Next() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Next item. +.UNINDENT +.UNINDENT +.SS void Previous() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Previous item. +.UNINDENT +.UNINDENT +.SS void VolumeUp() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Adjust remote volume one step up +.UNINDENT +.UNINDENT +.SS void VolumeDown() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Adjust remote volume one step down +.UNINDENT +.UNINDENT +.SS void FastForward() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Fast forward playback, this action is only stopped when another method +in this interface is called. +.UNINDENT +.UNINDENT +.SS void Rewind() [Deprecated] +.INDENT 0.0 +.INDENT 3.5 +Rewind playback, this action is only stopped when another method in +this interface is called. +.UNINDENT +.UNINDENT +.SS Properties +.SS boolean Connected [readonly] +.SS object Player [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Addressed Player object path. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaControl.rst bluez-5.71/doc/org.bluez.MediaControl.rst --- bluez-5.70/doc/org.bluez.MediaControl.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaControl.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,80 @@ +====================== +org.bluez.MediaControl +====================== + +------------------------------------------ +BlueZ D-Bus MediaControl API documentation +------------------------------------------ + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.MediaControl1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Methods +------- + +void Play() [Deprecated] +```````````````````````` + + Resume playback. + +void Pause() [Deprecated] +````````````````````````` + + Pause playback. + +void Stop() [Deprecated] +```````````````````````` + + Stop playback. + +void Next() [Deprecated] +```````````````````````` + + Next item. + +void Previous() [Deprecated] +```````````````````````````` + + Previous item. + +void VolumeUp() [Deprecated] +```````````````````````````` + + Adjust remote volume one step up + +void VolumeDown() [Deprecated] +`````````````````````````````` + + Adjust remote volume one step down + +void FastForward() [Deprecated] +``````````````````````````````` + + Fast forward playback, this action is only stopped when another method + in this interface is called. + +void Rewind() [Deprecated] +`````````````````````````` + + Rewind playback, this action is only stopped when another method in + this interface is called. + +Properties +---------- + +boolean Connected [readonly] +```````````````````````````` + +object Player [readonly, optional] +`````````````````````````````````` + + Addressed Player object path. diff -Nru bluez-5.70/doc/org.bluez.MediaEndpoint.5 bluez-5.71/doc/org.bluez.MediaEndpoint.5 --- bluez-5.70/doc/org.bluez.MediaEndpoint.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaEndpoint.5 2023-12-14 05:57:47.000000000 +0800 @@ -0,0 +1,280 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIAENDPOINT" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.MediaEndpoint \- BlueZ D-Bus MediaEndpoint API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +unique name (Server role) +org.bluez (Client role) +.TP +.B Interface +org.bluez.MediaEndpoint1 +.TP +.B Object path +freely definable (Server role) +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX +(Client role) +.UNINDENT +.SS Methods +.SS void SetConfiguration(object transport, dict properties) +.INDENT 0.0 +.INDENT 3.5 +Set configuration for the transport. +.INDENT 0.0 +.TP +.B object transport +Configured transport object. +.TP +.B dict properties +Configured \fBorg.bluez.MediaTransport(5)\fP properties. +.UNINDENT +.sp +For client role transport must be set with a server endpoint +object which will be configured and the properties must +contain the following properties: +.INDENT 0.0 +.TP +.B array{byte} Capabilities [Mandatory] +See Capabilities property. +.TP +.B array{byte} Metadata [ISO only] +See Metadata property. +.TP +.B dict QoS [ISO only] +See \fBorg.bluez.MediaTransport(5)\fP QoS property. +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{byte} SelectConfiguration(array{byte} capabilities) +.INDENT 0.0 +.INDENT 3.5 +Select preferable configuration from the supported capabilities. +.sp +Returns a configuration which can be used to setup a transport, see +\fBorg.bluez.MediaTransport(5)\fP for possible values. +.sp +Note: There is no need to cache the selected configuration since on +success the configuration is send back as parameter of SetConfiguration. +.UNINDENT +.UNINDENT +.SS dict SelectProperties(dict capabilities) +.INDENT 0.0 +.INDENT 3.5 +Select BAP unicast configuration from the supported capabilities: +.INDENT 0.0 +.TP +.B object Endpoint +.TP +.B array{byte} Capabilities +.TP +.B array{byte} Metadata +.TP +.B uint32 Locations +.TP +.B dict QoS +.INDENT 7.0 +.TP +.B byte Framing +.TP +.B byte PHY +.TP +.B uint16 MaximumLatency +.TP +.B uint32 MinimumDelay +.TP +.B uint32 MaximumDelay +.TP +.B uint32 PreferredMinimumDelay +.TP +.B uint32 PreferredMaximumDelay +.UNINDENT +.UNINDENT +.sp +See \fI\%MediaEndpoint Properties\fP for their possible values. +.sp +Returns a configuration which can be used to setup a transport: +.INDENT 0.0 +.TP +.B array{byte} Capabilities +.TP +.B array{byte} Metadata [optional] +.TP +.B dict QoS +.UNINDENT +.sp +See \fI\%SetConfiguration\fP for their possible values. +.sp +Note: There is no need to cache the selected properties since on +success the configuration is send back as parameter of SetConfiguration. +.UNINDENT +.UNINDENT +.SS void ClearConfiguration(object transport) +.INDENT 0.0 +.INDENT 3.5 +Clear transport configuration. +.UNINDENT +.UNINDENT +.SS void Release() +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon unregisters the +endpoint. An endpoint can use it to do cleanup tasks. There is no need +to unregister the endpoint, because when this method gets called it has +already been unregistered. +.UNINDENT +.UNINDENT +.SS MediaEndpoint Properties +.SS string UUID [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +UUID of the profile which the endpoint is for. +.UNINDENT +.UNINDENT +.SS byte Codec [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Assigned number of codec that the endpoint implements. +The values should match the profile specification which is indicated by +the UUID. +.UNINDENT +.UNINDENT +.SS uint32_t Vendor [readonly, Optional] +.INDENT 0.0 +.INDENT 3.5 +Vendor\-specific Company ID, Codec ID tuple that the endpoint implements. +.sp +It shall be set to appropriate value when Vendor Specific Codec (0xff) +is used. +.UNINDENT +.UNINDENT +.SS array{byte} Capabilities [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Capabilities blob, it is used as it is so the size and byte order must +match. +.UNINDENT +.UNINDENT +.SS array{byte} Metadata [readonly, Optional] +.INDENT 0.0 +.INDENT 3.5 +Metadata blob, it is used as it is so the size and byte order must +match. +.UNINDENT +.UNINDENT +.SS object Device [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Device object which the endpoint is belongs to. +.UNINDENT +.UNINDENT +.SS bool DelayReporting [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Indicates if endpoint supports Delay Reporting. +.UNINDENT +.UNINDENT +.SS uint32 Locations [readonly, optional, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates endpoint supported locations. +.UNINDENT +.UNINDENT +.SS uint16 SupportedContext [readonly, optional, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates endpoint supported audio context. +.UNINDENT +.UNINDENT +.SS uint16 Context [readonly, optional, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates endpoint available audio context. +.UNINDENT +.UNINDENT +.SS dict QoS [readonly, optional, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates QoS capabilities. +.INDENT 0.0 +.TP +.B byte Framing +Indicates endpoint support framing. +.sp +Possible Values: +.INDENT 7.0 +.TP +.B 0x00 +Unframed PDUs supported. +.TP +.B 0x01 +Unframed PDUs not supported. +.UNINDENT +.TP +.B byte PHY +Indicates endpoint preferred PHY. +.sp +Possible values: +.INDENT 7.0 +.TP +.B bit 0 +LE 1M preferred. +.TP +.B bit 1 +LE 2M preferred. +.TP +.B bit 2 +LE Coded preferred. +.UNINDENT +.TP +.B byte Retransmissions +Indicates endpoint preferred number of retransmissions. +.TP +.B uint16 MaximumLatency +Indicates endpoint maximum latency. +.TP +.B uint32 MinimumDelay +Indicates endpoint minimum presentation delay. +.TP +.B uint32 MaximumDelay +Indicates endpoint maximum presentation delay. +.TP +.B uint32 PreferredMinimumDelay +Indicates endpoint preferred minimum presentation delay. +.TP +.B uint32 PreferredMaximumDelay +Indicates endpoint preferred maximum presentation delay. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaEndpoint.rst bluez-5.71/doc/org.bluez.MediaEndpoint.rst --- bluez-5.70/doc/org.bluez.MediaEndpoint.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaEndpoint.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,238 @@ +======================= +org.bluez.MediaEndpoint +======================= + +------------------------------------------- +BlueZ D-Bus MediaEndpoint API documentation +------------------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: unique name (Server role) + org.bluez (Client role) +:Interface: org.bluez.MediaEndpoint1 +:Object path: freely definable (Server role) + [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/sepX + (Client role) + +Methods +------- + +.. _SetConfiguration: + +void SetConfiguration(object transport, dict properties) +```````````````````````````````````````````````````````` + + Set configuration for the transport. + + :object transport: + + Configured transport object. + + :dict properties: + + Configured **org.bluez.MediaTransport(5)** properties. + + For client role transport must be set with a server endpoint + object which will be configured and the properties must + contain the following properties: + + :array{byte} Capabilities [Mandatory]: + + See Capabilities property. + + :array{byte} Metadata [ISO only]: + + See Metadata property. + + :dict QoS [ISO only]: + + See **org.bluez.MediaTransport(5)** QoS property. + +array{byte} SelectConfiguration(array{byte} capabilities) +````````````````````````````````````````````````````````` + + Select preferable configuration from the supported capabilities. + + Returns a configuration which can be used to setup a transport, see + **org.bluez.MediaTransport(5)** for possible values. + + Note: There is no need to cache the selected configuration since on + success the configuration is send back as parameter of SetConfiguration. + +dict SelectProperties(dict capabilities) +```````````````````````````````````````` + + Select BAP unicast configuration from the supported capabilities: + + :object Endpoint: + + :array{byte} Capabilities: + + :array{byte} Metadata: + + :uint32 Locations: + + :dict QoS: + + :byte Framing: + :byte PHY: + :uint16 MaximumLatency: + :uint32 MinimumDelay: + :uint32 MaximumDelay: + :uint32 PreferredMinimumDelay: + :uint32 PreferredMaximumDelay: + + See `MediaEndpoint Properties`_ for their possible values. + + Returns a configuration which can be used to setup a transport: + + :array{byte} Capabilities: + :array{byte} Metadata [optional]: + :dict QoS: + + See `SetConfiguration`_ for their possible values. + + Note: There is no need to cache the selected properties since on + success the configuration is send back as parameter of SetConfiguration. + +void ClearConfiguration(object transport) +````````````````````````````````````````` + + Clear transport configuration. + +void Release() +`````````````` + + This method gets called when the service daemon unregisters the + endpoint. An endpoint can use it to do cleanup tasks. There is no need + to unregister the endpoint, because when this method gets called it has + already been unregistered. + +MediaEndpoint Properties +------------------------ + +string UUID [readonly, optional] +```````````````````````````````` + + UUID of the profile which the endpoint is for. + +byte Codec [readonly, optional] +``````````````````````````````` + + Assigned number of codec that the endpoint implements. + The values should match the profile specification which is indicated by + the UUID. + +uint32_t Vendor [readonly, Optional] +```````````````````````````````````` + + Vendor-specific Company ID, Codec ID tuple that the endpoint implements. + + It shall be set to appropriate value when Vendor Specific Codec (0xff) + is used. + +array{byte} Capabilities [readonly, optional] +````````````````````````````````````````````` + + Capabilities blob, it is used as it is so the size and byte order must + match. + +array{byte} Metadata [readonly, Optional] +````````````````````````````````````````` + + Metadata blob, it is used as it is so the size and byte order must + match. + +object Device [readonly, optional] +`````````````````````````````````` + + Device object which the endpoint is belongs to. + +bool DelayReporting [readonly, optional] +```````````````````````````````````````` + + Indicates if endpoint supports Delay Reporting. + +uint32 Locations [readonly, optional, ISO only, experimental] +````````````````````````````````````````````````````````````` + + Indicates endpoint supported locations. + +uint16 SupportedContext [readonly, optional, ISO only, experimental] +```````````````````````````````````````````````````````````````````` + + Indicates endpoint supported audio context. + +uint16 Context [readonly, optional, ISO only, experimental] +``````````````````````````````````````````````````````````` + + Indicates endpoint available audio context. + +dict QoS [readonly, optional, ISO only, experimental] +````````````````````````````````````````````````````` + + Indicates QoS capabilities. + + :byte Framing: + + Indicates endpoint support framing. + + + Possible Values: + + :0x00: + + Unframed PDUs supported. + + :0x01: + + Unframed PDUs not supported. + + :byte PHY: + + Indicates endpoint preferred PHY. + + Possible values: + + :bit 0: + + LE 1M preferred. + + :bit 1: + + LE 2M preferred. + + :bit 2: + + LE Coded preferred. + + :byte Retransmissions: + + Indicates endpoint preferred number of retransmissions. + + :uint16 MaximumLatency: + + Indicates endpoint maximum latency. + + :uint32 MinimumDelay: + + Indicates endpoint minimum presentation delay. + + :uint32 MaximumDelay: + + Indicates endpoint maximum presentation delay. + + :uint32 PreferredMinimumDelay: + + Indicates endpoint preferred minimum presentation delay. + + :uint32 PreferredMaximumDelay: + + Indicates endpoint preferred maximum presentation delay. diff -Nru bluez-5.70/doc/org.bluez.MediaFolder.5 bluez-5.71/doc/org.bluez.MediaFolder.5 --- bluez-5.70/doc/org.bluez.MediaFolder.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaFolder.5 2023-12-14 05:57:45.000000000 +0800 @@ -0,0 +1,156 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIAFOLDER" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.MediaFolder \- BlueZ D-Bus MediaFolder API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +unique name (Target role) +org.bluez (Controller role) +.TP +.B Interface +org.bluez.MediaFolder1 +.TP +.B Object path +freely definable (Target role) +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX +(Controller role) +.UNINDENT +.SS Methods +.SS object Search(string value, dict filter) +.INDENT 0.0 +.INDENT 3.5 +Return a folder object containing the search result. +.sp +To list the items found use the folder object returned and pass to +ChangeFolder. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{objects, properties} ListItems(dict filter) +.INDENT 0.0 +.INDENT 3.5 +Return a list of items found +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void ChangeFolder(object folder) +.INDENT 0.0 +.INDENT 3.5 +Change current folder. +.sp +Note: By changing folder the items of previous folder might be destroyed +and have to be listed again, the exception is NowPlaying folder which +should be always present while the player is active. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS uint32 NumberOfItems [readonly] +.INDENT 0.0 +.INDENT 3.5 +Number of items in the folder +.UNINDENT +.UNINDENT +.SS string Name [readonly] +.INDENT 0.0 +.INDENT 3.5 +Folder name: +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dq/Filesystem/...\(dq +Filesystem scope +.TP +.B \(dq/NowPlaying/...\(dq +NowPlaying scope +.UNINDENT +.sp +Note: /NowPlaying folder might not be listed if player is stopped, +folders created by Search are virtual so once another Search is perform +or the folder is changed using ChangeFolder it will no longer be listed. +.UNINDENT +.UNINDENT +.SS Filters +.INDENT 0.0 +.TP +.B uint32 Start +Offset of the first item. +.sp +Default value: 0 +.TP +.B uint32 End +Offset of the last item. +.sp +Default value: NumbeOfItems +.TP +.B array{string} Attributes +Item properties that should be included in the list. +.sp +Possible Values: +.INDENT 7.0 +.INDENT 3.5 +\(dqtitle\(dq, \(dqartist\(dq, \(dqalbum\(dq, \(dqgenre\(dq, \(dqnumber\-of\-tracks\(dq, +\(dqnumber\(dq, \(dqduration\(dq +.sp +Default Value: All +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaFolder.rst bluez-5.71/doc/org.bluez.MediaFolder.rst --- bluez-5.70/doc/org.bluez.MediaFolder.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaFolder.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,117 @@ +===================== +org.bluez.MediaFolder +===================== + +----------------------------------------- +BlueZ D-Bus MediaFolder API documentation +----------------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: unique name (Target role) + org.bluez (Controller role) +:Interface: org.bluez.MediaFolder1 +:Object path: freely definable (Target role) + [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX + (Controller role) + +Methods +------- + +object Search(string value, dict filter) +```````````````````````````````````````` + + Return a folder object containing the search result. + + To list the items found use the folder object returned and pass to + ChangeFolder. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +array{objects, properties} ListItems(dict filter) +````````````````````````````````````````````````` + + Return a list of items found + + Possible Errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void ChangeFolder(object folder) +```````````````````````````````` + + Change current folder. + + Note: By changing folder the items of previous folder might be destroyed + and have to be listed again, the exception is NowPlaying folder which + should be always present while the player is active. + + Possible Errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +Properties +---------- + +uint32 NumberOfItems [readonly] +``````````````````````````````` + + Number of items in the folder + +string Name [readonly] +`````````````````````` + + Folder name: + + Possible values: + + :"/Filesystem/...": + + Filesystem scope + + :"/NowPlaying/...": + + NowPlaying scope + + Note: /NowPlaying folder might not be listed if player is stopped, + folders created by Search are virtual so once another Search is perform + or the folder is changed using ChangeFolder it will no longer be listed. + +Filters +------- + +:uint32 Start: + + Offset of the first item. + + Default value: 0 + +:uint32 End: + + Offset of the last item. + + Default value: NumbeOfItems + +:array{string} Attributes: + + Item properties that should be included in the list. + + Possible Values: + + "title", "artist", "album", "genre", "number-of-tracks", + "number", "duration" + + Default Value: All diff -Nru bluez-5.70/doc/org.bluez.MediaItem.5 bluez-5.71/doc/org.bluez.MediaItem.5 --- bluez-5.70/doc/org.bluez.MediaItem.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaItem.5 2023-12-14 05:57:46.000000000 +0800 @@ -0,0 +1,163 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIAITEM" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.MediaItem \- BlueZ D-Bus MediaItem API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +unique name (Target role) +org.bluez (Controller role) +.TP +.B Interface +org.bluez.MediaItem1 +.TP +.B Object path +freely definable (Target role) +[variable +prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX +(Controller role) +.UNINDENT +.SS Methods +.SS void Play() +.INDENT 0.0 +.INDENT 3.5 +Play item +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void AddtoNowPlaying() +.INDENT 0.0 +.INDENT 3.5 +Add item to now playing list +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS object Player [readonly] +.INDENT 0.0 +.INDENT 3.5 +Player object path the item belongs to +.UNINDENT +.UNINDENT +.SS string Name [readonly] +.INDENT 0.0 +.INDENT 3.5 +Item displayable name +.UNINDENT +.UNINDENT +.SS string Type [readonly] +.INDENT 0.0 +.INDENT 3.5 +Item type +.sp +Possible values: \(dqvideo\(dq, \(dqaudio\(dq, \(dqfolder\(dq +.UNINDENT +.UNINDENT +.SS string FolderType [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Folder type. +.sp +Possible values: \(dqmixed\(dq, \(dqtitles\(dq, \(dqalbums\(dq, \(dqartists\(dq +.sp +Available if property Type is \(dqFolder\(dq +.UNINDENT +.UNINDENT +.SS boolean Playable [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the item can be played +.sp +Available if property Type is \(dqfolder\(dq +.UNINDENT +.UNINDENT +.SS dict Metadata [readonly] +.INDENT 0.0 +.INDENT 3.5 +Item metadata. +.sp +Possible values: +.INDENT 0.0 +.TP +.B string Title +Item title name +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.TP +.B string Artist +Item artist name +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.TP +.B string Album +Item album name +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.TP +.B string Genre +Item genre name +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.TP +.B uint32 NumberOfTracks +Item album number of tracks in total +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.TP +.B uint32 Number +Item album number +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.TP +.B uint32 Duration +Item duration in milliseconds +.sp +Available if property Type is \(dqaudio\(dq or \(dqvideo\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaItem.rst bluez-5.71/doc/org.bluez.MediaItem.rst --- bluez-5.70/doc/org.bluez.MediaItem.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaItem.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,131 @@ +=================== +org.bluez.MediaItem +=================== + +--------------------------------------- +BlueZ D-Bus MediaItem API documentation +--------------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: unique name (Target role) + org.bluez (Controller role) +:Interface: org.bluez.MediaItem1 +:Object path: freely definable (Target role) + [variable + prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX/itemX + (Controller role) + +Methods +------- + +void Play() +``````````` + + Play item + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void AddtoNowPlaying() +`````````````````````` + + Add item to now playing list + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +Properties +---------- + +object Player [readonly] +```````````````````````` + + Player object path the item belongs to + +string Name [readonly] +`````````````````````` + + Item displayable name + +string Type [readonly] +`````````````````````` + + Item type + + Possible values: "video", "audio", "folder" + +string FolderType [readonly, optional] +`````````````````````````````````````` + + Folder type. + + Possible values: "mixed", "titles", "albums", "artists" + + Available if property Type is "Folder" + +boolean Playable [readonly, optional] +````````````````````````````````````` + + Indicates if the item can be played + + Available if property Type is "folder" + +dict Metadata [readonly] +```````````````````````` + + Item metadata. + + Possible values: + + :string Title: + + Item title name + + Available if property Type is "audio" or "video" + + :string Artist: + + Item artist name + + Available if property Type is "audio" or "video" + + :string Album: + + Item album name + + Available if property Type is "audio" or "video" + + :string Genre: + + Item genre name + + Available if property Type is "audio" or "video" + + :uint32 NumberOfTracks: + + Item album number of tracks in total + + Available if property Type is "audio" or "video" + + :uint32 Number: + + Item album number + + Available if property Type is "audio" or "video" + + :uint32 Duration: + + Item duration in milliseconds + + Available if property Type is "audio" or "video" diff -Nru bluez-5.70/doc/org.bluez.MediaPlayer.5 bluez-5.71/doc/org.bluez.MediaPlayer.5 --- bluez-5.70/doc/org.bluez.MediaPlayer.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaPlayer.5 2023-12-14 05:57:44.000000000 +0800 @@ -0,0 +1,418 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIAPLAYER" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.MediaPlayer \- BlueZ D-Bus MediaPlayer API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez (Controller role) +.TP +.B Interface +org.bluez.MediaPlayer1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX +.UNINDENT +.SS Methods +.SS void Play() +.INDENT 0.0 +.INDENT 3.5 +Resume playback. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Pause() +.INDENT 0.0 +.INDENT 3.5 +Pause playback. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Stop() +.INDENT 0.0 +.INDENT 3.5 +Stop playback. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Next() +.INDENT 0.0 +.INDENT 3.5 +Next item. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Previous() +.INDENT 0.0 +.INDENT 3.5 +Previous item. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void FastForward() +.INDENT 0.0 +.INDENT 3.5 +Fast forward playback, this action is only stopped when another method +in this interface is called. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Rewind() +.INDENT 0.0 +.INDENT 3.5 +Rewind playback, this action is only stopped when another method in +this interface is called. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Press(byte avc_key) +.INDENT 0.0 +.INDENT 3.5 +Press a specific key to send as passthrough command. The key will be +released automatically. Use Hold() instead if the intention is to hold +down the key. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Hold(byte avc_key) +.INDENT 0.0 +.INDENT 3.5 +Press and hold a specific key to send as passthrough command. It is +your responsibility to make sure that Release() is called after calling +this method. The held key will also be released when any other method +in this interface is called. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Release() +.INDENT 0.0 +.INDENT 3.5 +Release the previously held key invoked using Hold(). +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string Equalizer [readwrite] +.INDENT 0.0 +.INDENT 3.5 +Indicates Player Equalizer setting. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqoff\(dq +.TP +.B \(dqon\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Repeat [readwrite] +.INDENT 0.0 +.INDENT 3.5 +Indicates Player Repeat setting. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqoff\(dq +.TP +.B \(dqsingletrack\(dq +.TP +.B \(dqalltracks\(dq +.TP +.B \(dqgroup\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Shuffle [readwrite] +.INDENT 0.0 +.INDENT 3.5 +Indicates Player Suffle setting. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqoff\(dq +.TP +.B \(dqalltracks\(dq +.TP +.B \(dqgroup\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Scan [readwrite] +.INDENT 0.0 +.INDENT 3.5 +Indicates Player Scan setting. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqoff\(dq +.TP +.B \(dqalltracks\(dq +.TP +.B \(dqgroup\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Status [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates Player Status setting. +.sp +Possible status: +.INDENT 0.0 +.TP +.B \(dqplaying\(dq +.TP +.B \(dqstopped\(dq +.TP +.B \(dqpaused\(dq +.TP +.B \(dqforward\-seek\(dq +.TP +.B \(dqreverse\-seek\(dq +.TP +.B \(dqerror\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint32 Position [readonly] +.INDENT 0.0 +.INDENT 3.5 +Playback position in milliseconds. Changing the position may generate +additional events that will be sent to the remote device. When position +is 0 it means the track is starting and when it\(aqs greater than or equal +to track\(aqs duration the track has ended. +.sp +Note that even if duration is not available in metadata it\(aqs possible +to signal its end by setting position to the maximum uint32 value. +.UNINDENT +.UNINDENT +.SS dict Track [readonly] +.INDENT 0.0 +.INDENT 3.5 +Track metadata. +.sp +Possible values: +.INDENT 0.0 +.TP +.B string Title +Track title name +.TP +.B string Artist +Track artist name +.TP +.B string Album +Track album name +.TP +.B string Genre +Track genre name +.TP +.B uint32 NumberOfTracks +Number of tracks in total +.TP +.B uint32 TrackNumber +Track number +.TP +.B uint32 Duration +Track duration in milliseconds +.UNINDENT +.UNINDENT +.UNINDENT +.SS object Device [readonly] +.INDENT 0.0 +.INDENT 3.5 +Device object path. +.UNINDENT +.UNINDENT +.SS string Name [readonly] +.INDENT 0.0 +.INDENT 3.5 +Player name +.UNINDENT +.UNINDENT +.SS string Type [readonly] +.INDENT 0.0 +.INDENT 3.5 +Player type +.sp +Possible values: +.INDENT 0.0 +.INDENT 3.5 +\(dqAudio\(dq +\(dqVideo\(dq +\(dqAudio Broadcasting\(dq +\(dqVideo Broadcasting\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS string Subtype [readonly] +.INDENT 0.0 +.INDENT 3.5 +Player subtype +.sp +Possible values: +.INDENT 0.0 +.INDENT 3.5 +\(dqAudio Book\(dq +\(dqPodcast\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS boolean Browsable [readonly] +.INDENT 0.0 +.INDENT 3.5 +If present indicates the player can be browsed using MediaFolder +interface. +.sp +Possible values: +.INDENT 0.0 +.TP +.B True +Supported and active +.TP +.B False +Supported but inactive +.UNINDENT +.sp +Note: If supported but inactive clients can enable it by using +MediaFolder interface but it might interfere in the playback of other +players. +.UNINDENT +.UNINDENT +.SS boolean Searchable [readonly] +.INDENT 0.0 +.INDENT 3.5 +If present indicates the player can be searched using MediaFolder +interface. +.sp +Possible values: +.INDENT 0.0 +.TP +.B True +Supported and active +.TP +.B False +Supported but inactive +.UNINDENT +.sp +Note: If supported but inactive clients can enable it by using +MediaFolder interface but it might interfere in the playback of other +players. +.UNINDENT +.UNINDENT +.SS object Playlist +.INDENT 0.0 +.INDENT 3.5 +Playlist object path. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaPlayer.rst bluez-5.71/doc/org.bluez.MediaPlayer.rst --- bluez-5.70/doc/org.bluez.MediaPlayer.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaPlayer.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,315 @@ +===================== +org.bluez.MediaPlayer +===================== + +----------------------------------------- +BlueZ D-Bus MediaPlayer API documentation +----------------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez (Controller role) +:Interface: org.bluez.MediaPlayer1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX + +Methods +------- + +void Play() +``````````` + + Resume playback. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Pause() +```````````` + + Pause playback. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Stop() +``````````` + + Stop playback. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Next() +``````````` + + Next item. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Previous() +``````````````` + + Previous item. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void FastForward() +`````````````````` + + Fast forward playback, this action is only stopped when another method + in this interface is called. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Rewind() +````````````` + + Rewind playback, this action is only stopped when another method in + this interface is called. + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Press(byte avc_key) +```````````````````````` + + Press a specific key to send as passthrough command. The key will be + released automatically. Use Hold() instead if the intention is to hold + down the key. + + Possible Errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Hold(byte avc_key) +``````````````````````` + + Press and hold a specific key to send as passthrough command. It is + your responsibility to make sure that Release() is called after calling + this method. The held key will also be released when any other method + in this interface is called. + + Possible Errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +void Release() +`````````````` + + Release the previously held key invoked using Hold(). + + Possible Errors: + + :org.bluez.Error.NotSupported: + :org.bluez.Error.Failed: + +Properties +---------- + +string Equalizer [readwrite] +```````````````````````````` + + Indicates Player Equalizer setting. + + Possible values: + + :"off": + :"on": + +string Repeat [readwrite] +````````````````````````` + + Indicates Player Repeat setting. + + Possible values: + + :"off": + :"singletrack": + :"alltracks": + :"group": + +string Shuffle [readwrite] +`````````````````````````` + + Indicates Player Suffle setting. + + Possible values: + + :"off": + :"alltracks": + :"group": + +string Scan [readwrite] +``````````````````````` + + Indicates Player Scan setting. + + Possible values: + + :"off": + :"alltracks": + :"group": + +string Status [readonly] +```````````````````````` + + Indicates Player Status setting. + + Possible status: + + :"playing": + :"stopped": + :"paused": + :"forward-seek": + :"reverse-seek": + :"error": + +uint32 Position [readonly] +`````````````````````````` + + Playback position in milliseconds. Changing the position may generate + additional events that will be sent to the remote device. When position + is 0 it means the track is starting and when it's greater than or equal + to track's duration the track has ended. + + Note that even if duration is not available in metadata it's possible + to signal its end by setting position to the maximum uint32 value. + +dict Track [readonly] +````````````````````` + + Track metadata. + + Possible values: + + :string Title: + + Track title name + + :string Artist: + + Track artist name + + :string Album: + + Track album name + + :string Genre: + + Track genre name + + :uint32 NumberOfTracks: + + Number of tracks in total + + :uint32 TrackNumber: + + Track number + + :uint32 Duration: + + Track duration in milliseconds + +object Device [readonly] +```````````````````````` + + Device object path. + +string Name [readonly] +`````````````````````` + + Player name + +string Type [readonly] +`````````````````````` + + Player type + + Possible values: + + "Audio" + "Video" + "Audio Broadcasting" + "Video Broadcasting" + +string Subtype [readonly] +````````````````````````` + + Player subtype + + Possible values: + + "Audio Book" + "Podcast" + +boolean Browsable [readonly] +```````````````````````````` + + If present indicates the player can be browsed using MediaFolder + interface. + + Possible values: + + :True: + + Supported and active + + :False: + + Supported but inactive + + Note: If supported but inactive clients can enable it by using + MediaFolder interface but it might interfere in the playback of other + players. + +boolean Searchable [readonly] +````````````````````````````` + + If present indicates the player can be searched using MediaFolder + interface. + + Possible values: + + :True: + + Supported and active + + :False: + + Supported but inactive + + Note: If supported but inactive clients can enable it by using + MediaFolder interface but it might interfere in the playback of other + players. + +object Playlist +``````````````` + + Playlist object path. diff -Nru bluez-5.70/doc/org.bluez.Media.rst bluez-5.71/doc/org.bluez.Media.rst --- bluez-5.70/doc/org.bluez.Media.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Media.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,133 @@ +=============== +org.bluez.Media +=============== + +----------------------------------- +BlueZ D-Bus Media API documentation +----------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.Media1 +:Object path: [variable prefix]/{hci0,hci1,...} + +Methods +------- + +void RegisterEndpoint(object endpoint, dict properties) +``````````````````````````````````````````````````````` + + Register a local end point to sender, the sender can register as many + end points as it likes. + + Note: If the sender disconnects the end points are automatically + unregistered. + + possible properties: + + :string UUID: + + UUID of the profile which the endpoint is for. + + UUID must be in the list of SupportedUUIDS. + + :byte Codec: + + Assigned number of codec that the endpoint implements. The + values should match the profile specification which is + indicated by the UUID. + + :uint32_t Vendor [Optional]: + + Vendor-specific Company ID, Codec ID tuple that the endpoint + implements. + + It shall be set to appropriate value when Vendor Specific Codec + (0xff) is used. + + :array{byte} Capabilities: + + Capabilities blob, it is used as it is so the size and byte + order must match. + + :array{byte} Metadata [Optional]: + + Metadata blob, it is used as it is so the size and byte order + must match. + + Possible Errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + + emitted when interface for the end-point is disabled + +void UnregisterEndpoint(object endpoint) +```````````````````````````````````````` + Unregister sender end point. + +void RegisterPlayer(object player, dict properties) +``````````````````````````````````````````````````` + + Register a media player object to sender, the sender can register as + many objects as it likes. + + Object must implement at least org.mpris.MediaPlayer2.Player as defined + in MPRIS 2.2 spec: + + http://specifications.freedesktop.org/mpris-spec/latest/ + + Note: If the sender disconnects its objects are automatically + unregistered. + + Possible Errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + +void UnregisterPlayer(object player) +```````````````````````````````````` + + Unregister sender media player. + +void RegisterApplication(object root, dict options) +``````````````````````````````````````````````````` + + Register endpoints an player objects within root object which must + implement ObjectManager. + + The application object path together with the D-Bus system bus + connection ID define the identification of the application. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + +void UnregisterApplication(object application) +`````````````````````````````````````````````` + + This unregisters the services that has been previously registered. The + object path parameter must match the same value that has been used on + registration. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.DoesNotExist: + +Properties +---------- + +array{string} SupportedUUIDs [readonly] +``````````````````````````````````````` + + List of 128-bit UUIDs that represents the supported Endpoint + registration. diff -Nru bluez-5.70/doc/org.bluez.MediaTransport.5 bluez-5.71/doc/org.bluez.MediaTransport.5 --- bluez-5.70/doc/org.bluez.MediaTransport.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaTransport.5 2023-12-14 05:57:47.000000000 +0800 @@ -0,0 +1,309 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.MEDIATRANSPORT" 5 "September 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.MediaTransport \- BlueZ D-Bus MediaTransport API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.MediaTransport1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX +.UNINDENT +.SS Methods +.SS fd, uint16, uint16 Acquire() +.INDENT 0.0 +.INDENT 3.5 +Acquire transport file descriptor and the MTU for read and write +respectively. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotAuthorized +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS fd, uint16, uint16 TryAcquire() +.INDENT 0.0 +.INDENT 3.5 +Acquire transport file descriptor only if the transport is in \(dqpending\(dq +state at the time the message is received by BlueZ. Otherwise no request +will be sent to the remote device and the function will just fail with +org.bluez.Error.NotAvailable. +.sp +Possible Errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.NotAuthorized +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.NotAvailable +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Release() +.INDENT 0.0 +.INDENT 3.5 +Releases file descriptor. +.UNINDENT +.UNINDENT +.SS Properties +.SS object Device [readonly] +.INDENT 0.0 +.INDENT 3.5 +Device object which the transport is connected to. +.UNINDENT +.UNINDENT +.SS string UUID [readonly] +.INDENT 0.0 +.INDENT 3.5 +UUID of the profile which the transport is for. +.UNINDENT +.UNINDENT +.SS byte Codec [readonly] +.INDENT 0.0 +.INDENT 3.5 +Assigned number of codec that the transport support. +The values should match the profile specification which is indicated by +the UUID. +.UNINDENT +.UNINDENT +.SS array{byte} Configuration [readonly] +.INDENT 0.0 +.INDENT 3.5 +Configuration blob, it is used as it is so the size and byte order must +match. +.UNINDENT +.UNINDENT +.SS string State [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates the state of the transport. Possible values are: +.INDENT 0.0 +.TP +.B \(dqidle\(dq +not streaming +.TP +.B \(dqpending\(dq +streaming but not acquired +.TP +.B \(dqactive\(dq +streaming and acquired +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint16 Delay [readwrite, optional] +.INDENT 0.0 +.INDENT 3.5 +Transport delay in 1/10 of millisecond, this property is only writeable +when the transport was acquired by the sender. +.UNINDENT +.UNINDENT +.SS uint16 Volume [readwrite, optional] +.INDENT 0.0 +.INDENT 3.5 +Indicates volume level of the transport, this property is only writeable +when the transport was acquired by the sender. +.sp +Possible Values: 0\-127 +.UNINDENT +.UNINDENT +.SS object Endpoint [readonly, optional, experimental] +.INDENT 0.0 +.INDENT 3.5 +Endpoint object which the transport is associated with. +.UNINDENT +.UNINDENT +.SS uint32 Location [readonly, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates transport Audio Location. +.UNINDENT +.UNINDENT +.SS array{byte} Metadata [readwrite, ISO Only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Indicates transport Metadata. +.UNINDENT +.UNINDENT +.SS array{object} Links [readonly, optional, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Linked transport objects which the transport is associated with. +.UNINDENT +.UNINDENT +.SS dict QoS [readonly, optional, ISO only, experimental] +.INDENT 0.0 +.INDENT 3.5 +Only present when QoS is configured. +.sp +Possible values for Unicast: +.INDENT 0.0 +.TP +.B byte CIG +Indicates configured CIG. +.sp +Possible values: +.INDENT 7.0 +.TP +.B 0x00 \- 0xef +Valid ID range. +.TP +.B 0xff +Auto allocate. +.UNINDENT +.TP +.B byte CIS +Indicates configured CIS. +.sp +Possible values: +.INDENT 7.0 +.TP +.B 0x00 \- 0xef +Valid ID range. +.TP +.B 0xff +Auto allocate. +.UNINDENT +.TP +.B byte Framing +Indicates configured framing. +.sp +Possible values: +.INDENT 7.0 +.TP +.B 0x00 +Unframed. +.TP +.B 0x01 +Framed. +.UNINDENT +.TP +.B uint32 PresentationDelay +Indicates configured transport presentation delay (us). +.TP +.B byte TargetLatency +Indicates the requested target latency. +.sp +Possible values: +.INDENT 7.0 +.TP +.B 0x01 +Low Latency. +.TP +.B 0x02 +Balanced Latency/Reliability. +.TP +.B 0x03 +High Reliability. +.UNINDENT +.UNINDENT +.sp +Possible values for Broadcast: +.INDENT 0.0 +.TP +.B byte BIG +Indicates configured QoS BIG. +.TP +.B byte BIS +Indicates configured BIS. +.TP +.B byte SyncFactor +Indicates configured broadcast sync factor. +.TP +.B byte Packing +Indicates configured packing. +.TP +.B byte Framing +Indicates configured framing. +.TP +.B byte Options +Indicates configured broadcast options. +.TP +.B uint16 Skip +Indicates configured broadcast skip. +.TP +.B byte SyncTimeout +Indicates configured broadcast sync timeout. +.TP +.B byte SyncType +Indicates configured broadcast sync CTE type. +.TP +.B byte MSE +Indicates configured broadcast MSE. +.TP +.B uint16 Timeout +Indicates configured broadcast timeout. +.UNINDENT +.sp +Possible values for both Unicast and Broadcast: +.INDENT 0.0 +.TP +.B uint32 Interval +Indicates configured ISO interval (us). +.TP +.B uint16 Latency +Indicates configured transport latency (ms). +.TP +.B uint16 SDU +Indicates configured maximum SDU. +.TP +.B byte PHY +Indicates configured PHY. +.sp +Possible values: +.INDENT 7.0 +.TP +.B bit 0 +LE 1M +.TP +.B bit 1 +LE 2M +.TP +.B bit 2 +LE Coded +.UNINDENT +.TP +.B byte Retransmissions +Indicates configured retransmissions. +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.MediaTransport.rst bluez-5.71/doc/org.bluez.MediaTransport.rst --- bluez-5.70/doc/org.bluez.MediaTransport.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.MediaTransport.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,274 @@ +======================== +org.bluez.MediaTransport +======================== + +-------------------------------------------- +BlueZ D-Bus MediaTransport API documentation +-------------------------------------------- + +:Version: BlueZ +:Date: September 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.MediaTransport1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/fdX + +Methods +------- + +fd, uint16, uint16 Acquire() +```````````````````````````` + + Acquire transport file descriptor and the MTU for read and write + respectively. + + Possible Errors: + + :org.bluez.Error.NotAuthorized: + :org.bluez.Error.Failed: + +fd, uint16, uint16 TryAcquire() +``````````````````````````````` + + Acquire transport file descriptor only if the transport is in "pending" + state at the time the message is received by BlueZ. Otherwise no request + will be sent to the remote device and the function will just fail with + org.bluez.Error.NotAvailable. + + Possible Errors: + + :org.bluez.Error.NotAuthorized: + :org.bluez.Error.Failed: + :org.bluez.Error.NotAvailable: + +void Release() +`````````````` + + Releases file descriptor. + +Properties +---------- + +object Device [readonly] +```````````````````````` + + Device object which the transport is connected to. + +string UUID [readonly] +`````````````````````` + + UUID of the profile which the transport is for. + +byte Codec [readonly] +````````````````````` + + Assigned number of codec that the transport support. + The values should match the profile specification which is indicated by + the UUID. + +array{byte} Configuration [readonly] +```````````````````````````````````` + + Configuration blob, it is used as it is so the size and byte order must + match. + +string State [readonly] +``````````````````````` + + Indicates the state of the transport. Possible values are: + + :"idle": not streaming + :"pending": streaming but not acquired + :"active": streaming and acquired + +uint16 Delay [readwrite, optional] +`````````````````````````````````` + + Transport delay in 1/10 of millisecond, this property is only writeable + when the transport was acquired by the sender. + +uint16 Volume [readwrite, optional] +``````````````````````````````````` + + Indicates volume level of the transport, this property is only writeable + when the transport was acquired by the sender. + + Possible Values: 0-127 + +object Endpoint [readonly, optional, experimental] +`````````````````````````````````````````````````` + + Endpoint object which the transport is associated with. + +uint32 Location [readonly, ISO only, experimental] +`````````````````````````````````````````````````` + + Indicates transport Audio Location. + +array{byte} Metadata [readwrite, ISO Only, experimental] +```````````````````````````````````````````````````````` + + Indicates transport Metadata. + +array{object} Links [readonly, optional, ISO only, experimental] +```````````````````````````````````````````````````````````````` + + Linked transport objects which the transport is associated with. + +dict QoS [readonly, optional, ISO only, experimental] +````````````````````````````````````````````````````` + + Only present when QoS is configured. + + Possible values for Unicast: + + :byte CIG: + + Indicates configured CIG. + + Possible values: + + :0x00 - 0xef: + + Valid ID range. + + :0xff: + + Auto allocate. + + :byte CIS: + + Indicates configured CIS. + + Possible values: + + :0x00 - 0xef: + + Valid ID range. + + :0xff: + + Auto allocate. + + :byte Framing: + + Indicates configured framing. + + Possible values: + + :0x00: + + Unframed. + + :0x01: + + Framed. + + :uint32 PresentationDelay: + + Indicates configured transport presentation delay (us). + + :byte TargetLatency: + + Indicates the requested target latency. + + Possible values: + + :0x01: + + Low Latency. + + :0x02: + + Balanced Latency/Reliability. + + :0x03: + + High Reliability. + + Possible values for Broadcast: + + :byte BIG: + + Indicates configured QoS BIG. + + :byte BIS: + + Indicates configured BIS. + + :byte SyncFactor: + + Indicates configured broadcast sync factor. + + :byte Packing: + + Indicates configured packing. + + :byte Framing: + + Indicates configured framing. + + :byte Options: + + Indicates configured broadcast options. + + :uint16 Skip: + + Indicates configured broadcast skip. + + :byte SyncTimeout: + + Indicates configured broadcast sync timeout. + + :byte SyncType: + + Indicates configured broadcast sync CTE type. + + :byte MSE: + + Indicates configured broadcast MSE. + + :uint16 Timeout: + + Indicates configured broadcast timeout. + + Possible values for both Unicast and Broadcast: + + :uint32 Interval: + + Indicates configured ISO interval (us). + + :uint16 Latency: + + Indicates configured transport latency (ms). + + :uint16 SDU: + + Indicates configured maximum SDU. + + :byte PHY: + + Indicates configured PHY. + + Possible values: + + :bit 0: + + LE 1M + + :bit 1: + + LE 2M + + :bit 2: + + LE Coded + + :byte Retransmissions: + + Indicates configured retransmissions. diff -Nru bluez-5.70/doc/org.bluez.Network.5 bluez-5.71/doc/org.bluez.Network.5 --- bluez-5.70/doc/org.bluez.Network.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Network.5 2023-12-14 05:57:38.000000000 +0800 @@ -0,0 +1,118 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.NETWORK" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Network \- BlueZ D-Bus Network API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.Network1 +.TP +.B Object path +[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX +.UNINDENT +.SS Methods +.SS string Connect(string uuid) +.INDENT 0.0 +.INDENT 3.5 +Connects to the network device and return the network interface name. +.sp +Possible uuid values: +.INDENT 0.0 +.TP +.B \(dqpanu\(dq, \(dq00001115\-0000\-1000\-8000\-00805f9b34fb\(dq +Personal Network User role. +.TP +.B \(dqnap\(dq, \(dq00001116\-0000\-1000\-8000\-00805f9b34fb\(dq +Network Access Point role. +.TP +.B \(dqgn\(dq, \(dq00001117\-0000\-1000\-8000\-00805f9b34fb\(dq +Group Network role. +.UNINDENT +.sp +The connection will be closed and network device released either upon +calling \fBDisconnect()\fP or when the client disappears from the +message bus. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.NotSupported +.TP +.B org.bluez.Error.InProgress +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Disconnect() +.INDENT 0.0 +.INDENT 3.5 +Disconnects from the network device. +.sp +To abort a connection attempt in case of errors or timeouts in the +client it is fine to call this method. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Failed +.TP +.B org.bluez.Error.NotConnected +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS boolean Connected [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates if the device is connected. +.UNINDENT +.UNINDENT +.SS string Interface [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Indicates the network interface name when available. +.UNINDENT +.UNINDENT +.SS string UUID [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Indicates the connection role when available. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.Network.rst bluez-5.71/doc/org.bluez.Network.rst --- bluez-5.70/doc/org.bluez.Network.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Network.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,83 @@ +================= +org.bluez.Network +================= + +------------------------------------- +BlueZ D-Bus Network API documentation +------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.Network1 +:Object path: [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX + +Methods +------- + +string Connect(string uuid) +``````````````````````````` + + Connects to the network device and return the network interface name. + + Possible uuid values: + + :"panu", "00001115-0000-1000-8000-00805f9b34fb": + + Personal Network User role. + + :"nap", "00001116-0000-1000-8000-00805f9b34fb": + + Network Access Point role. + + :"gn", "00001117-0000-1000-8000-00805f9b34fb": + + Group Network role. + + The connection will be closed and network device released either upon + calling **Disconnect()** or when the client disappears from the + message bus. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.NotSupported: + :org.bluez.Error.InProgress: + :org.bluez.Error.Failed: + +void Disconnect() +````````````````` + + Disconnects from the network device. + + To abort a connection attempt in case of errors or timeouts in the + client it is fine to call this method. + + Possible errors: + + :org.bluez.Error.Failed: + :org.bluez.Error.NotConnected: + +Properties +---------- + +boolean Connected [readonly] +```````````````````````````` + + Indicates if the device is connected. + +string Interface [readonly, optional] +````````````````````````````````````` + + Indicates the network interface name when available. + +string UUID [readonly, optional] +```````````````````````````````` + + Indicates the connection role when available. diff -Nru bluez-5.70/doc/org.bluez.NetworkServer.5 bluez-5.71/doc/org.bluez.NetworkServer.5 --- bluez-5.70/doc/org.bluez.NetworkServer.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.NetworkServer.5 2023-12-14 05:57:38.000000000 +0800 @@ -0,0 +1,100 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.NETWORKSERVER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.NetworkServer \- BlueZ D-Bus NetworkServer API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.NetworkServer1 +.TP +.B Object path +/org/bluez/{hci0,hci1,...} +.UNINDENT +.SS Methods +.SS void Register(string uuid, string bridge) +.INDENT 0.0 +.INDENT 3.5 +Registers server for the provided UUID. +.sp +Every new connection to this server will be added the bridge interface. +.sp +Possible uuid values: +.INDENT 0.0 +.TP +.B \(dqpanu\(dq, \(dq00001115\-0000\-1000\-8000\-00805f9b34fb\(dq +Personal Network User role. +.TP +.B \(dqnap\(dq, \(dq00001116\-0000\-1000\-8000\-00805f9b34fb\(dq +Network Access Point role. +.TP +.B \(dqgn\(dq, \(dq00001117\-0000\-1000\-8000\-00805f9b34fb\(dq +Group Network role. +.UNINDENT +.sp +Initially no network server SDP is provided. Only after this method a +SDP record will be available and the BNEP server will be ready for +incoming connections. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Unregister(string uuid) +.INDENT 0.0 +.INDENT 3.5 +Unregisters the server for provided UUID which was previously +registered with \fBRegister()\fP method. +.sp +All servers will be automatically unregistered when the calling +application terminates. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.NetworkServer.rst bluez-5.71/doc/org.bluez.NetworkServer.rst --- bluez-5.70/doc/org.bluez.NetworkServer.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.NetworkServer.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,68 @@ +======================= +org.bluez.NetworkServer +======================= + +------------------------------------------- +BlueZ D-Bus NetworkServer API documentation +------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.NetworkServer1 +:Object path: /org/bluez/{hci0,hci1,...} + + +Methods +------- + +void Register(string uuid, string bridge) +````````````````````````````````````````` + + Registers server for the provided UUID. + + Every new connection to this server will be added the bridge interface. + + Possible uuid values: + + :"panu", "00001115-0000-1000-8000-00805f9b34fb": + + Personal Network User role. + + :"nap", "00001116-0000-1000-8000-00805f9b34fb": + + Network Access Point role. + + :"gn", "00001117-0000-1000-8000-00805f9b34fb": + + Group Network role. + + Initially no network server SDP is provided. Only after this method a + SDP record will be available and the BNEP server will be ready for + incoming connections. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + :org.bluez.Error.Failed: + +void Unregister(string uuid) +```````````````````````````` + + Unregisters the server for provided UUID which was previously + registered with **Register()** method. + + All servers will be automatically unregistered when the calling + application terminates. + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.Failed: diff -Nru bluez-5.70/doc/org.bluez.obex.Agent.5 bluez-5.71/doc/org.bluez.obex.Agent.5 --- bluez-5.70/doc/org.bluez.obex.Agent.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Agent.5 2023-12-14 05:58:01.000000000 +0800 @@ -0,0 +1,78 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.AGENT" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.Agent \- BlueZ D-Bus OBEX Agent API documentation +.SH INTERFACE +.sp +;Service: unique name +:Interface: org.bluez.obex.Agent1 +:Object path: freely definable +.SS Methods +.SS void Release() +.INDENT 0.0 +.INDENT 3.5 +This method gets called when \fBobexd(8)\fP daemon unregisters the agent. +An agent can use it to do cleanup tasks. There is no need to unregister +the agent, because when this method gets called it has already been +unregistered. +.UNINDENT +.UNINDENT +.SS string AuthorizePush(object transfer) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the \fBobexd(8)\fP needs to accept/reject a +Bluetooth object push request. +.sp +Returns the full path (including the filename) or the folder name +suffixed with \(aq/\(aq where the object shall be stored. +.sp +The transfer object, see \fBorg.bluez.obex.Transfer(5)\fP will contain a +Filename property that contains the default location and name that can +be returned. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.Rejected +.TP +.B org.bluez.obex.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Cancel() +.INDENT 0.0 +.INDENT 3.5 +This method gets called to indicate that the agent request failed before +a reply was returned. It cancels the previous request. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.AgentManager.5 bluez-5.71/doc/org.bluez.obex.AgentManager.5 --- bluez-5.70/doc/org.bluez.obex.AgentManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.AgentManager.5 2023-12-14 05:58:01.000000000 +0800 @@ -0,0 +1,76 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.AGENTMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.AgentManager \- BlueZ D-Bus OBEX AgentManager API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.AgentManager1 +.TP +.B Object path +/org/bluez/obex +.UNINDENT +.SS Methods +.SS void RegisterAgent(object agent) +.INDENT 0.0 +.INDENT 3.5 +Registers an agent, which must implement \fBorg.bluez.obex.Agent(5)\fP, to +request authorization of the user to accept/reject objects. +.sp +Object push service needs to authorize each received object. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.AlreadyExists +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterAgent(object agent) +.INDENT 0.0 +.INDENT 3.5 +Unregisters the agent that has been previously registered using +\fBRegisterAgent()\fP\&. The object path parameter must match the same value +that has been used on registration. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.AgentManager.rst bluez-5.71/doc/org.bluez.obex.AgentManager.rst --- bluez-5.70/doc/org.bluez.obex.AgentManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.AgentManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,45 @@ +=========================== +org.bluez.obex.AgentManager +=========================== + +----------------------------------------------- +BlueZ D-Bus OBEX AgentManager API documentation +----------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.AgentManager1 +:Object path: /org/bluez/obex + +Methods +``````` + +void RegisterAgent(object agent) +```````````````````````````````` + + Registers an agent, which must implement **org.bluez.obex.Agent(5)**, to + request authorization of the user to accept/reject objects. + + Object push service needs to authorize each received object. + + Possible errors: + + :org.bluez.obex.Error.AlreadyExists: + +void UnregisterAgent(object agent) +`````````````````````````````````` + + Unregisters the agent that has been previously registered using + **RegisterAgent()**. The object path parameter must match the same value + that has been used on registration. + + Possible errors: + + :org.bluez.obex.Error.DoesNotExist: diff -Nru bluez-5.70/doc/org.bluez.obex.Agent.rst bluez-5.71/doc/org.bluez.obex.Agent.rst --- bluez-5.70/doc/org.bluez.obex.Agent.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Agent.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,54 @@ +==================== +org.bluez.obex.Agent +==================== + +---------------------------------------- +BlueZ D-Bus OBEX Agent API documentation +---------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +;Service: unique name +:Interface: org.bluez.obex.Agent1 +:Object path: freely definable + +Methods +------- + +void Release() +`````````````` + + This method gets called when **obexd(8)** daemon unregisters the agent. + An agent can use it to do cleanup tasks. There is no need to unregister + the agent, because when this method gets called it has already been + unregistered. + +string AuthorizePush(object transfer) +````````````````````````````````````` + + This method gets called when the **obexd(8)** needs to accept/reject a + Bluetooth object push request. + + Returns the full path (including the filename) or the folder name + suffixed with '/' where the object shall be stored. + + The transfer object, see **org.bluez.obex.Transfer(5)** will contain a + Filename property that contains the default location and name that can + be returned. + + Possible errors: + + :org.bluez.obex.Error.Rejected: + :org.bluez.obex.Error.Canceled: + +void Cancel() +````````````` + + This method gets called to indicate that the agent request failed before + a reply was returned. It cancels the previous request. diff -Nru bluez-5.70/doc/org.bluez.obex.Client.5 bluez-5.71/doc/org.bluez.obex.Client.5 --- bluez-5.70/doc/org.bluez.obex.Client.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Client.5 2023-12-14 05:57:54.000000000 +0800 @@ -0,0 +1,107 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.CLIENT" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.Client \- BlueZ D-Bus OBEX Client API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.Client1 +.TP +.B Object path +/org/bluez/obex +.UNINDENT +.SS Methods +.SS object CreateSession(string destination, dict args) +.INDENT 0.0 +.INDENT 3.5 +Connects to the destination address and then proceed to create an OBEX +session object which implements \fBorg.bluez.obex.Session(5)\fP interface. +.sp +The last parameter is a dictionary to hold optional or type\-specific +parameters. +.sp +Possible args values: +.INDENT 0.0 +.TP +.B string Target +Type of session to be created. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqftp\(dq +.TP +.B \(dqmap\(dq +.TP +.B \(dqopp\(dq +.TP +.B \(dqpbap\(dq +.TP +.B \(dqsync\(dq +.UNINDENT +.TP +.B string Source +Local address to be used. +.TP +.B byte Channel +Channel to be used. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void RemoveSession(object session) +.INDENT 0.0 +.INDENT 3.5 +Disconnects and removes session previously created by +\fBCreateSession()\fP aborting any pending transfers. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.NotAuthorized +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.Client.rst bluez-5.71/doc/org.bluez.obex.Client.rst --- bluez-5.70/doc/org.bluez.obex.Client.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Client.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,69 @@ +===================== +org.bluez.obex.Client +===================== + +----------------------------------------- +BlueZ D-Bus OBEX Client API documentation +----------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.Client1 +:Object path: /org/bluez/obex + +Methods +------- + +object CreateSession(string destination, dict args) +``````````````````````````````````````````````````` + + Connects to the destination address and then proceed to create an OBEX + session object which implements **org.bluez.obex.Session(5)** interface. + + The last parameter is a dictionary to hold optional or type-specific + parameters. + + Possible args values: + + :string Target: + + Type of session to be created. + + Possible values: + + :"ftp": + :"map": + :"opp": + :"pbap": + :"sync": + + :string Source: + + Local address to be used. + + :byte Channel: + + Channel to be used. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +void RemoveSession(object session) +`````````````````````````````````` + + Disconnects and removes session previously created by + **CreateSession()** aborting any pending transfers. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.NotAuthorized: diff -Nru bluez-5.70/doc/org.bluez.obex.FileTransfer.5 bluez-5.71/doc/org.bluez.obex.FileTransfer.5 --- bluez-5.70/doc/org.bluez.obex.FileTransfer.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.FileTransfer.5 2023-12-14 05:57:57.000000000 +0800 @@ -0,0 +1,203 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.FILETRANSFER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.FileTransfer \- BlueZ D-Bus OBEX FileTransfer API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.FileTransfer1 +.TP +.B Object path +[Session object path] +.UNINDENT +.SS Methods +.SS void ChangeFolder(string folder) +.INDENT 0.0 +.INDENT 3.5 +Changes the current folder of the remote device. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void CreateFolder(string folder) +.INDENT 0.0 +.INDENT 3.5 +Creates a new folder in the remote device. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{dict} ListFolder() +.INDENT 0.0 +.INDENT 3.5 +Returns a dictionary containing information about the current folder +content. +.sp +Possible return values: +.INDENT 0.0 +.TP +.B string Name +Object name in UTF\-8 format. +.TP +.B string Type +Either \(dqfolder\(dq or \(dqfile\(dq. +.TP +.B uint64 Size +Object size or number of items in folder. +.TP +.B string Permission +Group, owner and other permission. +.TP +.B uint64 Modified +Last change. +.TP +.B uint64 Accessed +Last access. +.TP +.B uint64 Created +Creation date. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict GetFile(string targetfile, string sourcefile) +.INDENT 0.0 +.INDENT 3.5 +Copies the contents of the source file (from remote device) to the +target file (on local filesystem). +.sp +If an empty target file is given, a name will be automatically generated +for the temporary file. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or +if the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict PutFile(string sourcefile, string targetfile) +.INDENT 0.0 +.INDENT 3.5 +Copies the contents of the source file (from local filesystem) to the +target file (on remote device). +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void CopyFile(string sourcefile, string targetfile) +.INDENT 0.0 +.INDENT 3.5 +Copies the contents from source file to target file on the remote +device. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void MoveFile(string sourcefile, string targetfile) +.INDENT 0.0 +.INDENT 3.5 +Moves a file within the remote device from source file to the target +file. +.sp +Possible errors: +.sp +;org.bluez.obex.Error.InvalidArguments: +:org.bluez.obex.Error.Failed: +.UNINDENT +.UNINDENT +.SS void Delete(string file) +.INDENT 0.0 +.INDENT 3.5 +Deletes the specified file/folder. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.FileTransfer.rst bluez-5.71/doc/org.bluez.obex.FileTransfer.rst --- bluez-5.70/doc/org.bluez.obex.FileTransfer.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.FileTransfer.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,155 @@ +=========================== +org.bluez.obex.FileTransfer +=========================== + +----------------------------------------------- +BlueZ D-Bus OBEX FileTransfer API documentation +----------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.FileTransfer1 +:Object path: [Session object path] + +Methods +------- + +void ChangeFolder(string folder) +```````````````````````````````` + + Changes the current folder of the remote device. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +void CreateFolder(string folder) +```````````````````````````````` + + Creates a new folder in the remote device. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +array{dict} ListFolder() +```````````````````````` + + Returns a dictionary containing information about the current folder + content. + + Possible return values: + + :string Name: + + Object name in UTF-8 format. + + :string Type: + + Either "folder" or "file". + + :uint64 Size: + + Object size or number of items in folder. + + :string Permission: + + Group, owner and other permission. + + :uint64 Modified: + + Last change. + + :uint64 Accessed: + + Last access. + + :uint64 Created: + + Creation date. + + Possible errors: + + :org.bluez.obex.Error.Failed: + +object, dict GetFile(string targetfile, string sourcefile) +`````````````````````````````````````````````````````````` + + Copies the contents of the source file (from remote device) to the + target file (on local filesystem). + + If an empty target file is given, a name will be automatically generated + for the temporary file. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or + if the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +object, dict PutFile(string sourcefile, string targetfile) +`````````````````````````````````````````````````````````` + + Copies the contents of the source file (from local filesystem) to the + target file (on remote device). + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +void CopyFile(string sourcefile, string targetfile) +``````````````````````````````````````````````````` + + Copies the contents from source file to target file on the remote + device. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +void MoveFile(string sourcefile, string targetfile) +``````````````````````````````````````````````````` + + Moves a file within the remote device from source file to the target + file. + + Possible errors: + + ;org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +void Delete(string file) +```````````````````````` + + Deletes the specified file/folder. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: diff -Nru bluez-5.70/doc/org.bluez.obex.Message.5 bluez-5.71/doc/org.bluez.obex.Message.5 --- bluez-5.70/doc/org.bluez.obex.Message.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Message.5 2023-12-14 05:58:00.000000000 +0800 @@ -0,0 +1,191 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.MESSAGE" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.Message \- BlueZ D-Bus OBEX Message API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.Message1 +.TP +.B Object path +[Session object path]/message{#} +.UNINDENT +.SS Methods +.SS object, dict Get(string targetfile, boolean attachment) +.INDENT 0.0 +.INDENT 3.5 +Download message and store it in the target file. +.sp +If an empty target file is given, a temporary file will be automatically +generated. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string Folder [readonly] +.INDENT 0.0 +.INDENT 3.5 +Folder which the message belongs to +.UNINDENT +.UNINDENT +.SS string Subject [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message subject +.UNINDENT +.UNINDENT +.SS string Timestamp [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message timestamp +.UNINDENT +.UNINDENT +.SS string Sender [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message sender name +.UNINDENT +.UNINDENT +.SS string SenderAddress [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message sender address +.UNINDENT +.UNINDENT +.SS string ReplyTo [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message Reply\-To address +.UNINDENT +.UNINDENT +.SS string Recipient [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message recipient name +.UNINDENT +.UNINDENT +.SS string RecipientAddress [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message recipient address +.UNINDENT +.UNINDENT +.SS string Type [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message type +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqemail\(dq +.TP +.B \(dqsms\-gsm\(dq +.TP +.B \(dqsms\-cdma\(dq +.TP +.B \(dqmms\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint64 Size [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message size in bytes +.UNINDENT +.UNINDENT +.SS string Status [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message reception status +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqcomplete\(dq +.TP +.B \(dqfractioned\(dq +.TP +.B \(dqnotification\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS boolean Priority [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message priority flag +.UNINDENT +.UNINDENT +.SS boolean Read [read/write] +.INDENT 0.0 +.INDENT 3.5 +Message read flag +.UNINDENT +.UNINDENT +.SS boolean Deleted [writeonly] +.INDENT 0.0 +.INDENT 3.5 +Message deleted flag +.UNINDENT +.UNINDENT +.SS boolean Sent [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message sent flag +.UNINDENT +.UNINDENT +.SS boolean Protected [readonly] +.INDENT 0.0 +.INDENT 3.5 +Message protected flag +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.MessageAccess.5 bluez-5.71/doc/org.bluez.obex.MessageAccess.5 --- bluez-5.70/doc/org.bluez.obex.MessageAccess.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.MessageAccess.5 2023-12-14 05:57:59.000000000 +0800 @@ -0,0 +1,279 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.MESSAGEACCESS" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.MessageAccess \- BlueZ D-Bus OBEX MessageAccess API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.MessageAccess1 +.TP +.B Object path +[Session object path] +.UNINDENT +.SS Methods +.SS void SetFolder(string name) +.INDENT 0.0 +.INDENT 3.5 +Set working directory for current session. +.sp +Possible name: +.INDENT 0.0 +.INDENT 3.5 +Directory name or \(aq..[/dir]\(aq. +.UNINDENT +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{dict} ListFolders(dict filter) +.INDENT 0.0 +.INDENT 3.5 +Returns a dictionary containing information about the current folder +content. +.sp +Possible filter: +.INDENT 0.0 +.TP +.B uint16 Offset (default 0) +Offset of the first item. +.TP +.B uint16 MaxCount (default 1024) +Maximum number of items. +.UNINDENT +.sp +Possible return: +.INDENT 0.0 +.TP +.B string Name +Folder name +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} ListFilterFields() +.INDENT 0.0 +.INDENT 3.5 +Return all available fields that can be used in \fBFields\fP filter. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqsubject\(dq +.TP +.B \(dqtimestamp\(dq +.TP +.B \(dqsender\(dq +.TP +.B \(dqsender\-address\(dq +.TP +.B \(dqrecipient\(dq +.TP +.B \(dqrecipient\-address\(dq +.TP +.B \(dqtype\(dq +.TP +.B \(dqsize\(dq +.TP +.B \(dqstatus\(dq +.TP +.B \(dqtext\(dq +.TP +.B \(dqattachment\(dq +.TP +.B \(dqpriority\(dq +.TP +.B \(dqread\(dq +.TP +.B \(dqsent\(dq +.TP +.B \(dqprotected\(dq +.TP +.B \(dqreplyto\(dq +.UNINDENT +.sp +Possible errors: None +.UNINDENT +.UNINDENT +.SS array{object, dict} ListMessages(string folder, dict filter) +.INDENT 0.0 +.INDENT 3.5 +Returns an array containing the messages objects found in the given +subfolder of the current folder, or in the current folder if folder is +empty. +.sp +Possible Filters: +.INDENT 0.0 +.TP +.B uint16 Offset (default 0) +Offset of the first item. +.UNINDENT +.sp +uint16 MaxCount (default 1024): +.INDENT 0.0 +.INDENT 3.5 +Maximum number of items. +.UNINDENT +.UNINDENT +.INDENT 0.0 +.TP +.B byte SubjectLength (default 256) +Maximum length of the Subject property in the message. +.TP +.B array{string} Fields +Message fields, default is all values. +.sp +See \fBListFilterFields()\fP for possible values. +.TP +.B array{string} Types +Filter messages by type. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqsms\(dq +.TP +.B \(dqemail\(dq +.TP +.B \(dqmms\(dq +.UNINDENT +.TP +.B string PeriodBegin +Filter messages by starting period. +.sp +Possible values: +.INDENT 7.0 +.INDENT 3.5 +Date in \(dqYYYYMMDDTHHMMSS\(dq format. +.UNINDENT +.UNINDENT +.TP +.B string PeriodEnd +Filter messages by ending period. +.sp +Possible values: +.INDENT 7.0 +.INDENT 3.5 +Date in \(dqYYYYMMDDTHHMMSS\(dq format. +.UNINDENT +.UNINDENT +.TP +.B boolean Read +Filter messages by read flag. +.sp +Possible values: +.INDENT 7.0 +.INDENT 3.5 +True for read or False for unread +.UNINDENT +.UNINDENT +.TP +.B string Recipient +Filter messages by recipient address. +.TP +.B string Sender +Filter messages by sender address. +.TP +.B boolean Priority +Filter messages by priority flag. +.sp +Possible values: +.INDENT 7.0 +.INDENT 3.5 +True for high priority or False for non\-high priority. +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Each message is represented by an object path, which implements +\fBorg.bluez.obex.Message(5)\fP interface, followed by a dictionary +of its properties. +.UNINDENT +.UNINDENT +.sp +void UpdateInbox(void) +.INDENT 0.0 +.INDENT 3.5 +Requests remote to update its inbox. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict PushMessage(string sourcefile, string folder, dict args) +.INDENT 0.0 +.INDENT 3.5 +Transfers a message (in bMessage format) to the remote device. +.sp +The message is transferred either to the given subfolder of the current +folder, or to the current folder if folder is empty. +.sp +Possible args: Transparent, Retry, Charset +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.MessageAccess.rst bluez-5.71/doc/org.bluez.obex.MessageAccess.rst --- bluez-5.70/doc/org.bluez.obex.MessageAccess.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.MessageAccess.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,201 @@ +============================ +org.bluez.obex.MessageAccess +============================ + +------------------------------------------------ +BlueZ D-Bus OBEX MessageAccess API documentation +------------------------------------------------ + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.MessageAccess1 +:Object path: [Session object path] + +Methods +------- + +void SetFolder(string name) +``````````````````````````` + + Set working directory for current session. + + Possible name: + + Directory name or '..[/dir]'. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +array{dict} ListFolders(dict filter) +```````````````````````````````````` + + Returns a dictionary containing information about the current folder + content. + + Possible filter: + + :uint16 Offset (default 0): + + Offset of the first item. + + :uint16 MaxCount (default 1024): + + Maximum number of items. + + Possible return: + + :string Name: + + Folder name + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +array{string} ListFilterFields() +```````````````````````````````` + + Return all available fields that can be used in **Fields** filter. + + Possible values: + + :"subject": + :"timestamp": + :"sender": + :"sender-address": + :"recipient": + :"recipient-address": + :"type": + :"size": + :"status": + :"text": + :"attachment": + :"priority": + :"read": + :"sent": + :"protected": + :"replyto": + + Possible errors: None + +array{object, dict} ListMessages(string folder, dict filter) +```````````````````````````````````````````````````````````` + + Returns an array containing the messages objects found in the given + subfolder of the current folder, or in the current folder if folder is + empty. + + Possible Filters: + + :uint16 Offset (default 0): + + Offset of the first item. + + uint16 MaxCount (default 1024): + + Maximum number of items. + + :byte SubjectLength (default 256): + + Maximum length of the Subject property in the message. + + :array{string} Fields: + + Message fields, default is all values. + + See **ListFilterFields()** for possible values. + + :array{string} Types: + + Filter messages by type. + + Possible values: + + :"sms": + :"email": + :"mms": + + :string PeriodBegin: + + Filter messages by starting period. + + Possible values: + + Date in "YYYYMMDDTHHMMSS" format. + + :string PeriodEnd: + + Filter messages by ending period. + + Possible values: + + Date in "YYYYMMDDTHHMMSS" format. + + :boolean Read: + + Filter messages by read flag. + + Possible values: + + True for read or False for unread + + :string Recipient: + + Filter messages by recipient address. + + :string Sender: + + Filter messages by sender address. + + :boolean Priority: + + Filter messages by priority flag. + + Possible values: + + True for high priority or False for non-high priority. + + Each message is represented by an object path, which implements + **org.bluez.obex.Message(5)** interface, followed by a dictionary + of its properties. + +void UpdateInbox(void) + + Requests remote to update its inbox. + + Possible errors: + + :org.bluez.obex.Error.Failed: + +object, dict PushMessage(string sourcefile, string folder, dict args) +````````````````````````````````````````````````````````````````````` + + Transfers a message (in bMessage format) to the remote device. + + The message is transferred either to the given subfolder of the current + folder, or to the current folder if folder is empty. + + Possible args: Transparent, Retry, Charset + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: diff -Nru bluez-5.70/doc/org.bluez.obex.Message.rst bluez-5.71/doc/org.bluez.obex.Message.rst --- bluez-5.70/doc/org.bluez.obex.Message.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Message.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,139 @@ +====================== +org.bluez.obex.Message +====================== + +------------------------------------------ +BlueZ D-Bus OBEX Message API documentation +------------------------------------------ + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.Message1 +:Object path: [Session object path]/message{#} + +Methods +------- + +object, dict Get(string targetfile, boolean attachment) +``````````````````````````````````````````````````````` + + Download message and store it in the target file. + + If an empty target file is given, a temporary file will be automatically + generated. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +Properties +---------- + +string Folder [readonly] +```````````````````````` + + Folder which the message belongs to + +string Subject [readonly] +````````````````````````` + + Message subject + +string Timestamp [readonly] +``````````````````````````` + + Message timestamp + +string Sender [readonly] +```````````````````````` + + Message sender name + +string SenderAddress [readonly] +``````````````````````````````` + + Message sender address + +string ReplyTo [readonly] +````````````````````````` + + Message Reply-To address + +string Recipient [readonly] +``````````````````````````` + + Message recipient name + +string RecipientAddress [readonly] +`````````````````````````````````` + + Message recipient address + +string Type [readonly] +`````````````````````` + + Message type + + Possible values: + + :"email": + :"sms-gsm": + :"sms-cdma": + :"mms": + +uint64 Size [readonly] +`````````````````````` + + Message size in bytes + +string Status [readonly] +```````````````````````` + + Message reception status + + Possible values: + + :"complete": + :"fractioned": + :"notification": + +boolean Priority [readonly] +``````````````````````````` + + Message priority flag + +boolean Read [read/write] +````````````````````````` + + Message read flag + +boolean Deleted [writeonly] +``````````````````````````` + + Message deleted flag + +boolean Sent [readonly] +``````````````````````` + + Message sent flag + +boolean Protected [readonly] +```````````````````````````` + + Message protected flag diff -Nru bluez-5.70/doc/org.bluez.obex.ObjectPush.5 bluez-5.71/doc/org.bluez.obex.ObjectPush.5 --- bluez-5.70/doc/org.bluez.obex.ObjectPush.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.ObjectPush.5 2023-12-14 05:57:56.000000000 +0800 @@ -0,0 +1,121 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.OBJECTPUSH" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.ObjectPush \- BlueZ D-Bus OBEX ObjectPush API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.ObjectPush1 +.TP +.B Object path +[Session object path] +.UNINDENT +.SS Methods +.SS object, dict SendFile(string sourcefile) +.INDENT 0.0 +.INDENT 3.5 +Sends local file to the remote device. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict PullBusinessCard(string targetfile) +.INDENT 0.0 +.INDENT 3.5 +Request the business card from a remote device and store it in the local +file. +.sp +If an empty target file is given, a name will be automatically +generated for the temporary file. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict ExchangeBusinessCards(string clientfile, string targetfile) +.INDENT 0.0 +.INDENT 3.5 +Push the client\(aqs business card to the remote device and then retrieve +the remote business card and store it in a local file. +.sp +If an empty target file is given, a name will be automatically +generated for the temporary file. +.sp +The returned path represents the newly created transfer, which should +be used to find out if the content has been successfully transferred or +if the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.ObjectPush.rst bluez-5.71/doc/org.bluez.obex.ObjectPush.rst --- bluez-5.70/doc/org.bluez.obex.ObjectPush.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.ObjectPush.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,84 @@ +========================= +org.bluez.obex.ObjectPush +========================= + +--------------------------------------------- +BlueZ D-Bus OBEX ObjectPush API documentation +--------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.ObjectPush1 +:Object path: [Session object path] + +Methods +------- + +object, dict SendFile(string sourcefile) +```````````````````````````````````````` + + Sends local file to the remote device. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +object, dict PullBusinessCard(string targetfile) +```````````````````````````````````````````````` + + Request the business card from a remote device and store it in the local + file. + + If an empty target file is given, a name will be automatically + generated for the temporary file. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +object, dict ExchangeBusinessCards(string clientfile, string targetfile) +```````````````````````````````````````````````````````````````````````` + + Push the client's business card to the remote device and then retrieve + the remote business card and store it in a local file. + + If an empty target file is given, a name will be automatically + generated for the temporary file. + + The returned path represents the newly created transfer, which should + be used to find out if the content has been successfully transferred or + if the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: diff -Nru bluez-5.70/doc/org.bluez.obex.PhonebookAccess.5 bluez-5.71/doc/org.bluez.obex.PhonebookAccess.5 --- bluez-5.70/doc/org.bluez.obex.PhonebookAccess.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.PhonebookAccess.5 2023-12-14 05:57:59.000000000 +0800 @@ -0,0 +1,515 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.PHONEBOOKACCESS" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.PhonebookAccess \- BlueZ D-Bus OBEX PhonebookAccess API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.PhonebookAccess1 +.TP +.B Object path +[Session object path] +.UNINDENT +.SS Methods +.SS void Select(string location, string phonebook) +.INDENT 0.0 +.INDENT 3.5 +Selects the phonebook object for other operations. Should be call before +all the other operations. +.sp +Possible location values: +.INDENT 0.0 +.TP +.B \(dqint\(dq, \(dqinternal\(dq (default) +Store in the Internal memory. +.TP +.B \(dqsim{#}\(dq +Store in the sim number. +.UNINDENT +.sp +Possible phonebook values: +.INDENT 0.0 +.TP +.B \(dqpb\(dq +Store as contact. +.TP +.B \(dqich\(dq +Store as incoming call. +.TP +.B \(dqoch\(dq +Store as outgoing call. +.TP +.B \(dqmch\(dq +Store as missing call. +.TP +.B \(dqcch\(dq +Store as a combination of incoming, outgoing and missing call. +.UNINDENT +.sp +\(dqspd\(dq: +.INDENT 0.0 +.INDENT 3.5 +Store as speed dials entry ( only for \(dqinternal\(dq ) +.UNINDENT +.UNINDENT +.sp +\(dqfav\(dq: +.INDENT 0.0 +.INDENT 3.5 +Store as favorites entry ( only for \(dqinternal\(dq ) +.UNINDENT +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict PullAll(string targetfile, dict filters) +.INDENT 0.0 +.INDENT 3.5 +Returns the entire phonebook object from the PSE server in plain string +with vcard format, and store it in a local file. +.sp +If an empty target file is given, a name will be automatically generated +for the temporary file. +.sp +The returned path represents the newly created transfer, which should +be used to find out if the content has been successfully transferred or +if the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible filters: +.INDENT 0.0 +.TP +.B string Format +Items vcard format. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqvcard21\(dq (default) +.TP +.B \(dqvcard30\(dq +.UNINDENT +.TP +.B string Order +Items order. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dq\(dq +.TP +.B \(dqindexed\(dq +.TP +.B \(dqalphanumeric\(dq +.TP +.B \(dqphonetic\(dq +.UNINDENT +.TP +.B uint16 Offset (default 0) +Offset of the first item. +.TP +.B uint16 MaxCount (default 65535) +Maximum number of items. +.TP +.B array{string} Fields (default all fields) +Item vcard fields. +.sp +See \fBListFilterFields()\fP for possible values. +.TP +.B array{string} FilterAll +Filter items by fields using AND logic, cannot be used +together with \fBFilterAny\fP\&. +.sp +See \fBListFilterFields()\fP for possible values. +.TP +.B array{string} FilterAny +Filter items by fields using OR logic, cannot be used together +with \fBFilterAll\fP\&. +.sp +See \fBListFilterFields()\fP for possible values. +.TP +.B bool ResetNewMissedCalls +Reset new the missed calls items, shall only be used for folders +mch and cch. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Forbidden +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string vcard, string name} List(dict filters) +.INDENT 0.0 +.INDENT 3.5 +Returns array of vcard\-listing data where every entry consists of a +pair of strings containing the vcard handle and the contact name. +For example: +.INDENT 0.0 +.TP +.B \(dq1.vcf\(dq +\(dqJohn\(dq +.UNINDENT +.sp +Possible filters: +.INDENT 0.0 +.TP +.B string Order +Contact order. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dq\(dq +.TP +.B \(dqindexed\(dq +.TP +.B \(dqalphanumeric\(dq +.TP +.B \(dqphonetic\(dq +.UNINDENT +.TP +.B uint16 Offset +Start offset. +.TP +.B uint16 MaxCount +Maximum number of contacts. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Forbidden +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict Pull(string vcard, string targetfile, dict filters) +.INDENT 0.0 +.INDENT 3.5 +Retrieves the vcard in the current phonebook object and store it in a +local file. +.sp +If an empty target file is given, a name will be automatically generated +for the temporary file. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible filters: +.INDENT 0.0 +.TP +.B string Format +Contact data format. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dq\(dq +.TP +.B \(dqvcard21\(dq +.TP +.B \(dqvcard30\(dq +.UNINDENT +.TP +.B array{string} Fields +See \fBListFilterFields()\fP for possible values. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Forbidden +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string vcard, string name} Search(string field, string value, dict filters) +.INDENT 0.0 +.INDENT 3.5 +Searches for entries matching the given condition and return an array of +vcard\-listing data where every entry consists of a pair of strings +containing the vcard handle and the contact name. +.sp +Possible field values: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B \(dqname\(dq (default) +Search by name. +.TP +.B \(dqnumber\(dq +Search by number. +.TP +.B \(dqsound\(dq +Search by sound. +.UNINDENT +.UNINDENT +.UNINDENT +.sp +value: the string value to search for +.sp +Possible filters: +.INDENT 0.0 +.TP +.B string Order +Contact order. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dq\(dq +.TP +.B \(dqindexed\(dq +.TP +.B \(dqalphanumeric\(dq +.TP +.B \(dqphonetic\(dq +.UNINDENT +.TP +.B uint16 Offset +Start offset. +.TP +.B uint16 MaxCount +Maximum number of contacts. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Forbidden +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS uint16 GetSize() +.INDENT 0.0 +.INDENT 3.5 +Returns the number of entries in the selected phonebook object that are +actually used (i.e. indexes that correspond to non\-NULL entries). +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.Forbidden +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UpdateVersion() +.INDENT 0.0 +.INDENT 3.5 +Attempts to update PrimaryCounter and SecondaryCounter. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.NotSupported +.TP +.B org.bluez.obex.Error.Forbidden +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS array{string} ListFilterFields() +.INDENT 0.0 +.INDENT 3.5 +Returns all Available fields that can be used in Fields filter. +.sp +Possible return: +.INDENT 0.0 +.TP +.B \(dqVERSION\(dq +.TP +.B \(dqFN\(dq +.TP +.B \(dqN\(dq +.TP +.B \(dqPHOTO\(dq +.TP +.B \(dqBDAY\(dq +.TP +.B \(dqADR\(dq +.TP +.B \(dqLABEL\(dq +.TP +.B \(dqTEL\(dq +.TP +.B \(dqEMAIL\(dq +.TP +.B \(dqMAILER\(dq +.TP +.B \(dqTZ\(dq +.TP +.B \(dqGEO\(dq +.TP +.B \(dqTITLE\(dq +.TP +.B \(dqROLE\(dq +.TP +.B \(dqLOGO\(dq +.TP +.B \(dqAGENT\(dq +.TP +.B \(dqORG\(dq +.TP +.B \(dqNOTE\(dq +.TP +.B \(dqREV\(dq +.TP +.B \(dqSOUND\(dq +.TP +.B \(dqURL\(dq +.TP +.B \(dqUID\(dq +.TP +.B \(dqKEY\(dq +.TP +.B \(dqNICKNAME\(dq +.TP +.B \(dqCATEGORIES\(dq +.TP +.B \(dqPROID\(dq +.TP +.B \(dqCLASS\(dq +.TP +.B \(dqSORT\-STRING\(dq +.TP +.B \(dqX\-IRMC\-CALL\-DATETIME\(dq +.TP +.B \(dqX\-BT\-SPEEDDIALKEY\(dq +.TP +.B \(dqX\-BT\-UCI\(dq +.TP +.B \(dqX\-BT\-UID\(dq +.TP +.B \(dqBIT\-{#}\(dq +.UNINDENT +.sp +Possible errors: None +.UNINDENT +.UNINDENT +.SS Properties +.SS string Folder [readonly] +.INDENT 0.0 +.INDENT 3.5 +Current folder. +.UNINDENT +.UNINDENT +.SS string DatabaseIdentifier [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +128 bits persistent database identifier. +.sp +Possible values: +.INDENT 0.0 +.INDENT 3.5 +32\-character hexadecimal such as +A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS string PrimaryCounter [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +128 bits primary version counter. +.sp +Possible values: +.INDENT 0.0 +.INDENT 3.5 +32\-character hexadecimal such as +A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS string SecondaryCounter [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +128 bits secondary version counter. +.sp +Possible values: +.INDENT 0.0 +.INDENT 3.5 +32\-character hexadecimal such as +A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.SS bool FixedImageSize [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Indicate support for fixed image size. +.sp +Possible values: +.INDENT 0.0 +.INDENT 3.5 +True if image is JPEG 300x300 pixels otherwise False. +.UNINDENT +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.PhonebookAccess.rst bluez-5.71/doc/org.bluez.obex.PhonebookAccess.rst --- bluez-5.70/doc/org.bluez.obex.PhonebookAccess.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.PhonebookAccess.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,386 @@ +============================== +org.bluez.obex.PhonebookAccess +============================== + +-------------------------------------------------- +BlueZ D-Bus OBEX PhonebookAccess API documentation +-------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.PhonebookAccess1 +:Object path: [Session object path] + +Methods +------- + +void Select(string location, string phonebook) +`````````````````````````````````````````````` + + Selects the phonebook object for other operations. Should be call before + all the other operations. + + Possible location values: + + :"int", "internal" (default): + + Store in the Internal memory. + + :"sim{#}": + + Store in the sim number. + + Possible phonebook values: + + :"pb": + + Store as contact. + + :"ich": + + Store as incoming call. + + :"och": + + Store as outgoing call. + + :"mch": + + Store as missing call. + + :"cch": + + Store as a combination of incoming, outgoing and missing call. + + "spd": + + Store as speed dials entry ( only for "internal" ) + + "fav": + + Store as favorites entry ( only for "internal" ) + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +object, dict PullAll(string targetfile, dict filters) +````````````````````````````````````````````````````` + + Returns the entire phonebook object from the PSE server in plain string + with vcard format, and store it in a local file. + + If an empty target file is given, a name will be automatically generated + for the temporary file. + + The returned path represents the newly created transfer, which should + be used to find out if the content has been successfully transferred or + if the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible filters: + + :string Format: + + Items vcard format. + + Possible values: + + :"vcard21" (default): + :"vcard30": + + :string Order: + + Items order. + + Possible values: + + :"": + :"indexed": + :"alphanumeric": + :"phonetic": + + :uint16 Offset (default 0): + + Offset of the first item. + + :uint16 MaxCount (default 65535): + + Maximum number of items. + + :array{string} Fields (default all fields): + + Item vcard fields. + + See **ListFilterFields()** for possible values. + + :array{string} FilterAll: + + Filter items by fields using AND logic, cannot be used + together with **FilterAny**. + + See **ListFilterFields()** for possible values. + + :array{string} FilterAny: + + Filter items by fields using OR logic, cannot be used together + with **FilterAll**. + + See **ListFilterFields()** for possible values. + + :bool ResetNewMissedCalls: + + Reset new the missed calls items, shall only be used for folders + mch and cch. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Forbidden: + +array{string vcard, string name} List(dict filters) +``````````````````````````````````````````````````` + + Returns array of vcard-listing data where every entry consists of a + pair of strings containing the vcard handle and the contact name. + For example: + + :"1.vcf": "John" + + Possible filters: + + :string Order: + + Contact order. + + Possible values: + + :"": + :"indexed": + :"alphanumeric": + :"phonetic": + + :uint16 Offset: + + Start offset. + + :uint16 MaxCount: + + Maximum number of contacts. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Forbidden: + +object, dict Pull(string vcard, string targetfile, dict filters) +```````````````````````````````````````````````````````````````` + + Retrieves the vcard in the current phonebook object and store it in a + local file. + + If an empty target file is given, a name will be automatically generated + for the temporary file. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible filters: + + :string Format: + + Contact data format. + + Possible values: + + :"": + :"vcard21": + :"vcard30": + + :array{string} Fields: + + See **ListFilterFields()** for possible values. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Forbidden: + :org.bluez.obex.Error.Failed: + +array{string vcard, string name} Search(string field, string value, dict filters) +````````````````````````````````````````````````````````````````````````````````` + + Searches for entries matching the given condition and return an array of + vcard-listing data where every entry consists of a pair of strings + containing the vcard handle and the contact name. + + Possible field values: + + :"name" (default): + + Search by name. + + :"number": + + Search by number. + + :"sound": + + Search by sound. + + value: the string value to search for + + Possible filters: + + :string Order: + + Contact order. + + Possible values: + + :"": + :"indexed": + :"alphanumeric": + :"phonetic": + + :uint16 Offset: + + Start offset. + + :uint16 MaxCount: + + Maximum number of contacts. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Forbidden: + :org.bluez.obex.Error.Failed: + +uint16 GetSize() +```````````````` + + Returns the number of entries in the selected phonebook object that are + actually used (i.e. indexes that correspond to non-NULL entries). + + Possible errors: + + :org.bluez.obex.Error.Forbidden: + :org.bluez.obex.Error.Failed: + +void UpdateVersion() +```````````````````` + + Attempts to update PrimaryCounter and SecondaryCounter. + + Possible errors: + + :org.bluez.obex.Error.NotSupported: + :org.bluez.obex.Error.Forbidden: + :org.bluez.obex.Error.Failed: + +array{string} ListFilterFields() +```````````````````````````````` + + Returns all Available fields that can be used in Fields filter. + + Possible return: + + :"VERSION": + :"FN": + :"N": + :"PHOTO": + :"BDAY": + :"ADR": + :"LABEL": + :"TEL": + :"EMAIL": + :"MAILER": + :"TZ": + :"GEO": + :"TITLE": + :"ROLE": + :"LOGO": + :"AGENT": + :"ORG": + :"NOTE": + :"REV": + :"SOUND": + :"URL": + :"UID": + :"KEY": + :"NICKNAME": + :"CATEGORIES": + :"PROID": + :"CLASS": + :"SORT-STRING": + :"X-IRMC-CALL-DATETIME": + :"X-BT-SPEEDDIALKEY": + :"X-BT-UCI": + :"X-BT-UID": + :"BIT-{#}": + + Possible errors: None + +Properties +---------- + +string Folder [readonly] +```````````````````````` + + Current folder. + +string DatabaseIdentifier [readonly, optional] +`````````````````````````````````````````````` + + 128 bits persistent database identifier. + + Possible values: + + 32-character hexadecimal such as + A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 + +string PrimaryCounter [readonly, optional] +`````````````````````````````````````````` + + 128 bits primary version counter. + + Possible values: + + 32-character hexadecimal such as + A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 + +string SecondaryCounter [readonly, optional] +```````````````````````````````````````````` + + 128 bits secondary version counter. + + Possible values: + + 32-character hexadecimal such as + A1A2A3A4B1B2C1C2D1D2E1E2E3E4E5E6 + +bool FixedImageSize [readonly, optional] +```````````````````````````````````````` + + Indicate support for fixed image size. + + Possible values: + + True if image is JPEG 300x300 pixels otherwise False. diff -Nru bluez-5.70/doc/org.bluez.obex.Session.5 bluez-5.71/doc/org.bluez.obex.Session.5 --- bluez-5.70/doc/org.bluez.obex.Session.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Session.5 2023-12-14 05:57:55.000000000 +0800 @@ -0,0 +1,93 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.SESSION" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.Session \- BlueZ D-Bus OBEX Client API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.Session1 +.TP +.B Object path +/org/bluez/obex/server/session{#} or +/org/bluez/obex/client/session{#} +.UNINDENT +.SS Methods +.SS string GetCapabilities() +.INDENT 0.0 +.INDENT 3.5 +Get remote device capabilities. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.NotSupported +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string Source [readonly] +.INDENT 0.0 +.INDENT 3.5 +Bluetooth adapter address +.UNINDENT +.UNINDENT +.SS string Destination [readonly] +.INDENT 0.0 +.INDENT 3.5 +Bluetooth device address +.UNINDENT +.UNINDENT +.SS byte Channel [readonly] +.INDENT 0.0 +.INDENT 3.5 +Bluetooth channel +.UNINDENT +.UNINDENT +.SS string Target [readonly] +.INDENT 0.0 +.INDENT 3.5 +Target UUID +.UNINDENT +.UNINDENT +.SS string Root [readonly] +.INDENT 0.0 +.INDENT 3.5 +Root path +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.Session.rst bluez-5.71/doc/org.bluez.obex.Session.rst --- bluez-5.70/doc/org.bluez.obex.Session.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Session.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,61 @@ +====================== +org.bluez.obex.Session +====================== + +----------------------------------------- +BlueZ D-Bus OBEX Client API documentation +----------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.Session1 +:Object path: /org/bluez/obex/server/session{#} or + /org/bluez/obex/client/session{#} + +Methods +------- + +string GetCapabilities() +```````````````````````` + + Get remote device capabilities. + + Possible errors: + + :org.bluez.obex.Error.NotSupported: + :org.bluez.obex.Error.Failed: + +Properties +---------- + +string Source [readonly] +```````````````````````` + + Bluetooth adapter address + +string Destination [readonly] +````````````````````````````` + + Bluetooth device address + +byte Channel [readonly] +``````````````````````` + + Bluetooth channel + +string Target [readonly] +```````````````````````` + + Target UUID + +string Root [readonly] +`````````````````````` + + Root path diff -Nru bluez-5.70/doc/org.bluez.obex.Synchronization.5 bluez-5.71/doc/org.bluez.obex.Synchronization.5 --- bluez-5.70/doc/org.bluez.obex.Synchronization.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Synchronization.5 2023-12-14 05:57:58.000000000 +0800 @@ -0,0 +1,118 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.SYNCHRONIZATION" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.Synchronization \- BlueZ D-Bus OBEX Synchronization API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.Synchronization1 +.TP +.B Object path +[Session object path] +.UNINDENT +.SS Methods +.SS void SetLocation(string location) +.INDENT 0.0 +.INDENT 3.5 +Sets the phonebook object store location for other operations. Should be +called before all the other operations. +.sp +Possible location: +.INDENT 0.0 +.TP +.B \(dqint\(dq ( \(dqinternal\(dq which is default ) +Store in the interval memory. +.TP +.B \(dqsim{#}\(dq +Store in sim card number #. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict GetPhonebook(string targetfile) +.INDENT 0.0 +.INDENT 3.5 +Retrieves an entire Phonebook Object store from remote device, and +stores it in a local file. +.sp +If an empty target file is given, a name will be automatically +calculated for the temporary file. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS object, dict PutPhonebook(string sourcefile) +.INDENT 0.0 +.INDENT 3.5 +Sends an entire Phonebook Object store to remote device. +.sp +The returned path represents the newly created transfer, which should be +used to find out if the content has been successfully transferred or if +the operation fails. +.sp +The properties of this transfer are also returned along with the object +path, to avoid a call to GetProperties, see +\fBorg.bluez.obex.Transfer(5)\fP for the possible list of properties. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.InvalidArguments +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.Synchronization.rst bluez-5.71/doc/org.bluez.obex.Synchronization.rst --- bluez-5.70/doc/org.bluez.obex.Synchronization.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Synchronization.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,82 @@ +============================== +org.bluez.obex.Synchronization +============================== + +-------------------------------------------------- +BlueZ D-Bus OBEX Synchronization API documentation +-------------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.Synchronization1 +:Object path: [Session object path] + +Methods +------- + +void SetLocation(string location) +````````````````````````````````` + + Sets the phonebook object store location for other operations. Should be + called before all the other operations. + + Possible location: + + :"int" ( "internal" which is default ): + + Store in the interval memory. + + :"sim{#}": + + Store in sim card number #. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + +object, dict GetPhonebook(string targetfile) +```````````````````````````````````````````` + + Retrieves an entire Phonebook Object store from remote device, and + stores it in a local file. + + If an empty target file is given, a name will be automatically + calculated for the temporary file. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: + +object, dict PutPhonebook(string sourcefile) +```````````````````````````````````````````` + + Sends an entire Phonebook Object store to remote device. + + The returned path represents the newly created transfer, which should be + used to find out if the content has been successfully transferred or if + the operation fails. + + The properties of this transfer are also returned along with the object + path, to avoid a call to GetProperties, see + **org.bluez.obex.Transfer(5)** for the possible list of properties. + + Possible errors: + + :org.bluez.obex.Error.InvalidArguments: + :org.bluez.obex.Error.Failed: diff -Nru bluez-5.70/doc/org.bluez.obex.Transfer.5 bluez-5.71/doc/org.bluez.obex.Transfer.5 --- bluez-5.70/doc/org.bluez.obex.Transfer.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Transfer.5 2023-12-14 05:57:56.000000000 +0800 @@ -0,0 +1,171 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.OBEX.TRANSFER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.obex.Transfer \- BlueZ D-Bus OBEX Transfer API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez.obex +.TP +.B Interface +org.bluez.obex.Transfer1 +.TP +.B Object path +[Session object path]/transfer{#} +.UNINDENT +.SS Methods +.SS void Cancel() +.INDENT 0.0 +.INDENT 3.5 +Cancels the current transference. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.NotAuthorized +.TP +.B org.bluez.obex.Error.InProgress +.TP +.B org.bluez.obex.Error.Failed +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Suspend() +.INDENT 0.0 +.INDENT 3.5 +Suspends transference. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.NotAuthorized +.TP +.B org.bluez.obex.Error.NotInProgress +If transfer is still in with \fBStatus\fP \fB\(dqqueued\(dq\fP\&. +.UNINDENT +.UNINDENT +.UNINDENT +.SS void Resume() +.INDENT 0.0 +.INDENT 3.5 +Resumes transference previously suspended with use of \fBSuspend()\fP +method. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.obex.Error.NotAuthorized +.TP +.B org.bluez.obex.Error.NotInProgress +If transfer is still in with \fBStatus\fP \fB\(dqqueued\(dq\fP\&. +.UNINDENT +.UNINDENT +.UNINDENT +.SS Properties +.SS string Status [readonly] +.INDENT 0.0 +.INDENT 3.5 +Indicates the current status of the transfer. +.sp +Possible values: +.INDENT 0.0 +.TP +.B \(dqqueued\(dq +.TP +.B \(dqactive\(dq +.TP +.B \(dqsuspended\(dq +.TP +.B \(dqcomplete\(dq +.TP +.B \(dqerror\(dq +.UNINDENT +.UNINDENT +.UNINDENT +.SS object Session [readonly] +.INDENT 0.0 +.INDENT 3.5 +The object path of the session the transfer belongs to. +.UNINDENT +.UNINDENT +.SS string Name [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Name of the object being transferred. +.sp +Either Name or Type or both will be present. +.UNINDENT +.UNINDENT +.SS string Type [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Type of the object transferred being transferred. +.sp +Either Name or Type or both will be present. +.UNINDENT +.UNINDENT +.SS uint64 Time [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Time of the object being transferred if this is provided by the remote +party. +.UNINDENT +.UNINDENT +.SS uint64 Size [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Size of the object being transferred. +.sp +If the size is unknown, then this property will not be present. +.UNINDENT +.UNINDENT +.SS uint64 Transferred [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Number of bytes transferred. +.sp +For transfers with \fBStatus\fP set to \fB\(dqqueued\(dq\fP, this value will not +be present. +.UNINDENT +.UNINDENT +.SS string Filename [readonly, optional] +.INDENT 0.0 +.INDENT 3.5 +Complete name of the file being received or sent. +.sp +For incoming object push transaction, this will be the proposed default +location and name. It can be overwritten by the \fBAuthorizePush()\fP in +\fBorg.bluez.obex.Agent(5)\fP and will be then updated accordingly. +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.obex.Transfer.rst bluez-5.71/doc/org.bluez.obex.Transfer.rst --- bluez-5.70/doc/org.bluez.obex.Transfer.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.obex.Transfer.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,123 @@ +======================= +org.bluez.obex.Transfer +======================= + +------------------------------------------- +BlueZ D-Bus OBEX Transfer API documentation +------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez.obex +:Interface: org.bluez.obex.Transfer1 +:Object path: [Session object path]/transfer{#} + +Methods +------- + +void Cancel() +````````````` + + Cancels the current transference. + + Possible errors: + + :org.bluez.obex.Error.NotAuthorized: + :org.bluez.obex.Error.InProgress: + :org.bluez.obex.Error.Failed: + +void Suspend() +`````````````` + + Suspends transference. + + Possible errors: + + :org.bluez.obex.Error.NotAuthorized: + :org.bluez.obex.Error.NotInProgress: + + If transfer is still in with **Status** **"queued"**. + +void Resume() +````````````` + + Resumes transference previously suspended with use of **Suspend()** + method. + + Possible errors: + + :org.bluez.obex.Error.NotAuthorized: + :org.bluez.obex.Error.NotInProgress: + + If transfer is still in with **Status** **"queued"**. + +Properties +---------- + +string Status [readonly] +```````````````````````` + + Indicates the current status of the transfer. + + Possible values: + + :"queued": + :"active": + :"suspended": + :"complete": + :"error": + +object Session [readonly] +````````````````````````` + + The object path of the session the transfer belongs to. + +string Name [readonly, optional] +```````````````````````````````` + + Name of the object being transferred. + + Either Name or Type or both will be present. + +string Type [readonly, optional] +```````````````````````````````` + + Type of the object transferred being transferred. + + Either Name or Type or both will be present. + +uint64 Time [readonly, optional] +```````````````````````````````` + + Time of the object being transferred if this is provided by the remote + party. + +uint64 Size [readonly, optional] +```````````````````````````````` + + Size of the object being transferred. + + If the size is unknown, then this property will not be present. + +uint64 Transferred [readonly, optional] +``````````````````````````````````````` + + Number of bytes transferred. + + For transfers with **Status** set to **"queued"**, this value will not + be present. + +string Filename [readonly, optional] +```````````````````````````````````` + + Complete name of the file being received or sent. + + For incoming object push transaction, this will be the proposed default + location and name. It can be overwritten by the **AuthorizePush()** in + **org.bluez.obex.Agent(5)** and will be then updated accordingly. diff -Nru bluez-5.70/doc/org.bluez.Profile.5 bluez-5.71/doc/org.bluez.Profile.5 --- bluez-5.70/doc/org.bluez.Profile.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Profile.5 2023-12-14 05:57:37.000000000 +0800 @@ -0,0 +1,81 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.PROFILE" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.Profile \- BlueZ D-Bus Profile API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +unique name +.TP +.B Interface +org.bluez.Profile1 +.TP +.B Object path +freely definable +.UNINDENT +.SS Methods +.SS void Release() [noreply] +.INDENT 0.0 +.INDENT 3.5 +This method gets called when the service daemon unregisters the profile. +A profile can use it to do cleanup tasks. There is no need to unregister +the profile, because when this method gets called it has already been +unregistered. +.UNINDENT +.UNINDENT +.SS void NewConnection(object device, fd, dict fd_properties) +.INDENT 0.0 +.INDENT 3.5 +This method gets called when a new service level connection has been +made and authorized. +.sp +Possible fd_properties values: +.INDENT 0.0 +.TP +.B uint16 Version [optional] +Profile version. +.TP +.B uint16 Features [optional] +Profile features. +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.Rejected +.TP +.B org.bluez.Error.Canceled +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.ProfileManager.5 bluez-5.71/doc/org.bluez.ProfileManager.5 --- bluez-5.70/doc/org.bluez.ProfileManager.5 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.ProfileManager.5 2023-12-14 05:57:36.000000000 +0800 @@ -0,0 +1,164 @@ +.\" Man page generated from reStructuredText. +. +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.TH "ORG.BLUEZ.PROFILEMANAGER" 5 "October 2023" "BlueZ" "Linux System Administration" +.SH NAME +org.bluez.ProfileManager \- BlueZ D-Bus ProfileManager API documentation +.SH INTERFACE +.INDENT 0.0 +.TP +.B Service +org.bluez +.TP +.B Interface +org.bluez.ProfileManager1 +.TP +.B Object path +/org/bluez +.UNINDENT +.SS Methods +.SS void RegisterProfile(object profile, string uuid, dict options) +.INDENT 0.0 +.INDENT 3.5 +Registers profile agent. +.sp +The object path defines the path of the profile that will be called +when there is a connection and must implement \fBorg.bluez.Profile(5)\fP +interface. +.sp +If an application disconnects from the bus all its registered profiles +will be removed. +.sp +Possible uuid values: +.INDENT 0.0 +.TP +.B \(dq0000111f\-0000\-1000\-8000\-00805f9b34fb\(dq +HFP AG, default profile Version is 1.7, profile Features is +0b001001 and RFCOMM channel is 13. Authentication is required. +.TP +.B \(dq0000111e\-0000\-1000\-8000\-00805f9b34fb\(dq +HFP HS, default profile Version is 1.7, profile Features is +0b000000 and RFCOMM channel is 7. Authentication is required. +.TP +.B \(dq00001112\-0000\-1000\-8000\-00805f9b34fb\(dq +HSP AG, default profile Version is 1.2, RFCOMM channel is 12 and +Authentication is required. Does not support any Features, +option is ignored. +.TP +.B \(dq00001108\-0000\-1000\-8000\-00805f9b34fb\(dq +HSP HS, default profile Version is 1.2, profile Features is 0b0 +and RFCOMM channel is 6. Authentication is required. +Features is one bit value, specify capability of Remote Audio +Volume Control (by default turned off). +.TP +.B \(dq\(dq +Vendor defined UUID, no defaults, must set options. +.UNINDENT +.sp +Possible options values: +.INDENT 0.0 +.TP +.B string Name +Human readable name for the profile +.TP +.B string Service +The primary service class UUID (if different from the actual +profile UUID). +.TP +.B string Role +For asymmetric profiles that do not have UUIDs available to +uniquely identify each side this parameter allows specifying the +precise local role. +.sp +Possible values: +.INDENT 7.0 +.TP +.B \(dqclient\(dq +.TP +.B \(dqserver\(dq +.UNINDENT +.TP +.B uint16 Channel +RFCOMM channel number that is used for client and server UUIDs. +.sp +If applicable it will be used in the SDP record as well. +.TP +.B uint16 PSM +PSM number that is used for client and server UUIDs. +.sp +If applicable it will be used in the SDP record as well. +.TP +.B boolean RequireAuthentication +Pairing is required before connections will be established. +No devices will be connected if not paired. +.TP +.B boolean RequireAuthorization +Request authorization before any connection will be established. +.TP +.B boolean AutoConnect +In case of a client UUID this will force connection of the +RFCOMM or L2CAP channels when a remote device is connected. +.TP +.B string ServiceRecord +Provide a manual SDP record. +.TP +.B uint16 Version +Profile version (for SDP record) +.TP +.B uint16 Features +Profile features (for SDP record) +.UNINDENT +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.InvalidArguments +.TP +.B org.bluez.Error.AlreadyExists +.UNINDENT +.UNINDENT +.UNINDENT +.SS void UnregisterProfile(object profile) +.INDENT 0.0 +.INDENT 3.5 +Unregisters profile object that has been previously registered using +\fBRegisterProfile\fP\&. +.sp +The object path parameter must match the same value that has been used +on registration. +.sp +Possible errors: +.INDENT 0.0 +.TP +.B org.bluez.Error.DoesNotExist +.UNINDENT +.UNINDENT +.UNINDENT +.\" Generated by docutils manpage writer. +. diff -Nru bluez-5.70/doc/org.bluez.ProfileManager.rst bluez-5.71/doc/org.bluez.ProfileManager.rst --- bluez-5.70/doc/org.bluez.ProfileManager.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.ProfileManager.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,141 @@ +======================== +org.bluez.ProfileManager +======================== + +-------------------------------------------- +BlueZ D-Bus ProfileManager API documentation +-------------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: org.bluez +:Interface: org.bluez.ProfileManager1 +:Object path: /org/bluez + +Methods +------- + +void RegisterProfile(object profile, string uuid, dict options) +``````````````````````````````````````````````````````````````` + + Registers profile agent. + + The object path defines the path of the profile that will be called + when there is a connection and must implement **org.bluez.Profile(5)** + interface. + + If an application disconnects from the bus all its registered profiles + will be removed. + + Possible uuid values: + + :"0000111f-0000-1000-8000-00805f9b34fb": + + HFP AG, default profile Version is 1.7, profile Features is + 0b001001 and RFCOMM channel is 13. Authentication is required. + + :"0000111e-0000-1000-8000-00805f9b34fb": + + HFP HS, default profile Version is 1.7, profile Features is + 0b000000 and RFCOMM channel is 7. Authentication is required. + + :"00001112-0000-1000-8000-00805f9b34fb": + + HSP AG, default profile Version is 1.2, RFCOMM channel is 12 and + Authentication is required. Does not support any Features, + option is ignored. + + :"00001108-0000-1000-8000-00805f9b34fb": + + HSP HS, default profile Version is 1.2, profile Features is 0b0 + and RFCOMM channel is 6. Authentication is required. + Features is one bit value, specify capability of Remote Audio + Volume Control (by default turned off). + + :"": + + Vendor defined UUID, no defaults, must set options. + + Possible options values: + + :string Name: + + Human readable name for the profile + + :string Service: + + The primary service class UUID (if different from the actual + profile UUID). + + :string Role: + + For asymmetric profiles that do not have UUIDs available to + uniquely identify each side this parameter allows specifying the + precise local role. + + Possible values: + + :"client": + :"server": + + :uint16 Channel: + + RFCOMM channel number that is used for client and server UUIDs. + + If applicable it will be used in the SDP record as well. + + :uint16 PSM: + + PSM number that is used for client and server UUIDs. + + If applicable it will be used in the SDP record as well. + + :boolean RequireAuthentication: + + Pairing is required before connections will be established. + No devices will be connected if not paired. + + :boolean RequireAuthorization: + + Request authorization before any connection will be established. + + :boolean AutoConnect: + + In case of a client UUID this will force connection of the + RFCOMM or L2CAP channels when a remote device is connected. + + :string ServiceRecord: + + Provide a manual SDP record. + + :uint16 Version: + + Profile version (for SDP record) + + :uint16 Features: + + Profile features (for SDP record) + + Possible errors: + + :org.bluez.Error.InvalidArguments: + :org.bluez.Error.AlreadyExists: + +void UnregisterProfile(object profile) +`````````````````````````````````````` + + Unregisters profile object that has been previously registered using + **RegisterProfile**. + + The object path parameter must match the same value that has been used + on registration. + + Possible errors: + + :org.bluez.Error.DoesNotExist: diff -Nru bluez-5.70/doc/org.bluez.Profile.rst bluez-5.71/doc/org.bluez.Profile.rst --- bluez-5.70/doc/org.bluez.Profile.rst 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/doc/org.bluez.Profile.rst 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,51 @@ +================= +org.bluez.Profile +================= + +------------------------------------- +BlueZ D-Bus Profile API documentation +------------------------------------- + +:Version: BlueZ +:Date: October 2023 +:Manual section: 5 +:Manual group: Linux System Administration + +Interface +========= + +:Service: unique name +:Interface: org.bluez.Profile1 +:Object path: freely definable + +Methods +------- + +void Release() [noreply] +```````````````````````` + + This method gets called when the service daemon unregisters the profile. + A profile can use it to do cleanup tasks. There is no need to unregister + the profile, because when this method gets called it has already been + unregistered. + +void NewConnection(object device, fd, dict fd_properties) +````````````````````````````````````````````````````````` + + This method gets called when a new service level connection has been + made and authorized. + + Possible fd_properties values: + + :uint16 Version [optional]: + + Profile version. + + :uint16 Features [optional]: + + Profile features. + + Possible errors: + + :org.bluez.Error.Rejected: + :org.bluez.Error.Canceled: diff -Nru bluez-5.70/doc/profile-api.txt bluez-5.71/doc/profile-api.txt --- bluez-5.70/doc/profile-api.txt 2020-09-06 21:53:08.000000000 +0800 +++ bluez-5.71/doc/profile-api.txt 1970-01-01 08:00:00.000000000 +0800 @@ -1,170 +0,0 @@ -BlueZ D-Bus Profile API description -*********************************** - - -Profile Manager hierarchy -========================= - -Service org.bluez -Interface org.bluez.ProfileManager1 -Object path /org/bluez - - void RegisterProfile(object profile, string uuid, dict options) - - This registers a profile implementation. - - If an application disconnects from the bus all - its registered profiles will be removed. - - Some predefined services: - - HFP AG UUID: 0000111f-0000-1000-8000-00805f9b34fb - - Default profile Version is 1.7, profile Features - is 0b001001 and RFCOMM channel is 13. - Authentication is required. - - HFP HS UUID: 0000111e-0000-1000-8000-00805f9b34fb - - Default profile Version is 1.7, profile Features - is 0b000000 and RFCOMM channel is 7. - Authentication is required. - - HSP AG UUID: 00001112-0000-1000-8000-00805f9b34fb - - Default profile Version is 1.2, RFCOMM channel - is 12 and Authentication is required. Does not - support any Features, option is ignored. - - HSP HS UUID: 00001108-0000-1000-8000-00805f9b34fb - - Default profile Version is 1.2, profile Features - is 0b0 and RFCOMM channel is 6. Authentication - is required. Features is one bit value, specify - capability of Remote Audio Volume Control - (by default turned off). - - Available options: - - string Name - - Human readable name for the profile - - string Service - - The primary service class UUID - (if different from the actual - profile UUID) - - string Role - - For asymmetric profiles that do not - have UUIDs available to uniquely - identify each side this - parameter allows specifying the - precise local role. - - Possible values: "client", "server" - - uint16 Channel - - RFCOMM channel number that is used - for client and server UUIDs. - - If applicable it will be used in the - SDP record as well. - - uint16 PSM - - PSM number that is used for client - and server UUIDs. - - If applicable it will be used in the - SDP record as well. - - boolean RequireAuthentication - - Pairing is required before connections - will be established. No devices will - be connected if not paired. - - boolean RequireAuthorization - - Request authorization before any - connection will be established. - - boolean AutoConnect - - In case of a client UUID this will - force connection of the RFCOMM or - L2CAP channels when a remote device - is connected. - - string ServiceRecord - - Provide a manual SDP record. - - uint16 Version - - Profile version (for SDP record) - - uint16 Features - - Profile features (for SDP record) - - Possible errors: org.bluez.Error.InvalidArguments - org.bluez.Error.AlreadyExists - - void UnregisterProfile(object profile) - - This unregisters the profile that has been previously - registered. The object path parameter must match the - same value that has been used on registration. - - Possible errors: org.bluez.Error.DoesNotExist - - -Profile hierarchy -================= - -Service unique name -Interface org.bluez.Profile1 -Object path freely definable - -Methods void Release() [noreply] - - This method gets called when the service daemon - unregisters the profile. A profile can use it to do - cleanup tasks. There is no need to unregister the - profile, because when this method gets called it has - already been unregistered. - - void NewConnection(object device, fd, dict fd_properties) - - This method gets called when a new service level - connection has been made and authorized. - - Common fd_properties: - - uint16 Version Profile version (optional) - uint16 Features Profile features (optional) - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled - - void RequestDisconnection(object device) - - This method gets called when a profile gets - disconnected. - - The file descriptor is no longer owned by the service - daemon and the profile implementation needs to take - care of cleaning up all connections. - - If multiple file descriptors are indicated via - NewConnection, it is expected that all of them - are disconnected before returning from this - method call. - - Possible errors: org.bluez.Error.Rejected - org.bluez.Error.Canceled diff -Nru bluez-5.70/ell/cipher.c bluez-5.71/ell/cipher.c --- bluez-5.70/ell/cipher.c 2023-09-27 17:03:04.000000000 +0800 +++ bluez-5.71/ell/cipher.c 2023-11-20 01:31:06.000000000 +0800 @@ -731,8 +731,6 @@ /* ARC4 implementation copyright (c) 2001 Niels Möller */ -#define SWAP(a, b) do { uint8_t _t = a; a = b; b = _t; } while (0) - static void arc4_set_key(uint8_t *S, const uint8_t *key, size_t key_length) { unsigned int i; diff -Nru bluez-5.70/ell/ecc.c bluez-5.71/ell/ecc.c --- bluez-5.70/ell/ecc.c 2023-09-27 17:03:04.000000000 +0800 +++ bluez-5.71/ell/ecc.c 2023-11-20 01:31:06.000000000 +0800 @@ -547,8 +547,24 @@ if (!_ecc_compute_y(curve, p->y, p->x)) goto failed; + /* + * This is determining whether or not to subtract the Y + * coordinate from P. According to ANSI X9.62 an even Y should + * be prefixed with 02 (BIT0) and an odd Y should be prefixed + * with 03 (BIT1). If this is not the case, subtract Y from P. + * + * ANSI X9.62 + * 4.3.6 Point-to-Octet-String Conversion + * + * 2. If the compressed form is used, then do the following: + * 2.1. Compute the bit ~Yp . (See Section 4.2.) + * 2.2. Assign the value 02 to the single octet PC if ~Yp + * is 0, or the value 03 if ~Yp is 1. + * 2.3. The result is the octet string PO = PC || X + */ + sub = secure_select(type == L_ECC_POINT_TYPE_COMPRESSED_BIT0, - !(p->y[0] & 1), p->y[0] & 1); + p->y[0] & 1, !(p->y[0] & 1)); _vli_mod_sub(tmp, curve->p, p->y, curve->p, curve->ndigits); @@ -830,6 +846,41 @@ return NULL; } +LIB_EXPORT struct l_ecc_scalar *l_ecc_scalar_new_modn( + const struct l_ecc_curve *curve, + const void *bytes, size_t len) +{ + struct l_ecc_scalar *c; + uint64_t tmp[2 * L_ECC_MAX_DIGITS]; + unsigned int ndigits = len / 8; + + if (!bytes) + return NULL; + + if (len % 8) + return NULL; + + if (ndigits > curve->ndigits * 2) + return NULL; + + c = _ecc_constant_new(curve, NULL, 0); + if (!c) + return NULL; + + memset(tmp, 0, sizeof(tmp)); + _ecc_be2native(tmp, bytes, ndigits); + + _vli_mmod_slow(c->c, tmp, curve->n, curve->ndigits); + + if (!_vli_is_zero_or_one(c->c, curve->ndigits) && + secure_memcmp_64(curve->n, c->c, curve->ndigits) > 0) + return c; + + l_ecc_scalar_free(c); + + return NULL; +} + /* * Takes a buffer of the same size as the curve and scales it to a range * 1..n using value = (value mod (n - 1)) + 1. For the curves we support @@ -924,6 +975,18 @@ return true; } +LIB_EXPORT bool l_ecc_point_multiply_g(struct l_ecc_point *ret, + const struct l_ecc_scalar *scalar) +{ + if (unlikely(!ret || !scalar)) + return false; + + _ecc_point_mult(ret, &scalar->curve->g, scalar->c, NULL, + scalar->curve->p); + + return true; +} + LIB_EXPORT bool l_ecc_point_add(struct l_ecc_point *ret, const struct l_ecc_point *a, const struct l_ecc_point *b) @@ -995,3 +1058,8 @@ return ((memcmp(a->x, b->x, a->curve->ndigits * 8) == 0) && (memcmp(a->y, b->y, a->curve->ndigits * 8) == 0)); } + +LIB_EXPORT bool l_ecc_point_is_infinity(const struct l_ecc_point *p) +{ + return _ecc_point_is_zero(p); +} diff -Nru bluez-5.70/ell/ecc-external.c bluez-5.71/ell/ecc-external.c --- bluez-5.70/ell/ecc-external.c 2021-08-02 03:49:37.000000000 +0800 +++ bluez-5.71/ell/ecc-external.c 2023-11-20 01:31:06.000000000 +0800 @@ -314,6 +314,81 @@ _vli_add(result, result, mod, ndigits); } +/* Counts the number of 64-bit "digits" in vli. */ +static unsigned int _vli_num_digits(const uint64_t *vli, unsigned int ndigits) +{ + int i; + + /* Search from the end until we find a non-zero digit. + * We do it in reverse because we expect that most digits will + * be nonzero. + */ + for (i = ndigits - 1; i >= 0 && vli[i] == 0; i--); + + return (i + 1); +} + +/* Counts the number of bits required for vli. */ +static unsigned int _vli_num_bits(const uint64_t *vli, unsigned int ndigits) +{ + unsigned int i, num_digits; + uint64_t digit; + + num_digits = _vli_num_digits(vli, ndigits); + if (num_digits == 0) + return 0; + + digit = vli[num_digits - 1]; + for (i = 0; digit; i++) + digit >>= 1; + + return ((num_digits - 1) * 64 + i); +} + +/* Computes result = product % mod, where product is 2N words long. + * Currently only designed to work for curve_p or curve_n. + */ +void _vli_mmod_slow(uint64_t *result, const uint64_t *product, + const uint64_t *mod, unsigned int ndigits) +{ + uint64_t mod_m[2 * L_ECC_MAX_DIGITS]; + uint64_t tmp[2 * L_ECC_MAX_DIGITS]; + uint64_t *v[2] = { tmp, (uint64_t *) product }; + uint64_t carry = 0; + unsigned int i; + /* Shift mod so its highest set bit is at the maximum position. */ + int shift = (ndigits * 2 * 64) - _vli_num_bits(mod, ndigits); + int word_shift = shift / 64; + int bit_shift = shift % 64; + + vli_clear(mod_m, word_shift); + if (bit_shift > 0) { + for (i = 0; i < ndigits; ++i) { + mod_m[word_shift + i] = (mod[i] << bit_shift) | carry; + carry = mod[i] >> (64 - bit_shift); + } + } else + vli_set(mod_m + word_shift, mod, ndigits); + + for (i = 1; shift >= 0; --shift) { + uint64_t borrow = 0; + unsigned int j; + + for (j = 0; j < ndigits * 2; ++j) { + uint64_t diff = v[i][j] - mod_m[j] - borrow; + + if (diff != v[i][j]) + borrow = (diff > v[i][j]); + v[1 - i][j] = diff; + } + i = !(i ^ borrow); /* Swap the index if there was no borrow */ + _vli_rshift1(mod_m, ndigits); + mod_m[ndigits - 1] |= mod_m[ndigits] << (64 - 1); + _vli_rshift1(mod_m + ndigits, ndigits); + } + vli_set(result, v[i], ndigits); +} + /* Computes p_result = p_product % curve_p. * See algorithm 5 and 6 from * http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf @@ -550,7 +625,7 @@ /* Computes result = product % curve_prime * from http://www.nsa.gov/ia/_files/nist-routines.pdf */ -bool _vli_mmod_fast(uint64_t *result, uint64_t *product, +bool _vli_mmod_fast(uint64_t *result, const uint64_t *product, const uint64_t *curve_prime, unsigned int ndigits) { uint64_t tmp[2 * L_ECC_MAX_DIGITS]; diff -Nru bluez-5.70/ell/ecc.h bluez-5.71/ell/ecc.h --- bluez-5.70/ell/ecc.h 2023-09-27 17:03:04.000000000 +0800 +++ bluez-5.71/ell/ecc.h 2023-11-20 01:31:06.000000000 +0800 @@ -66,6 +66,8 @@ const struct l_ecc_curve *curve); struct l_ecc_scalar *l_ecc_scalar_new_modp(const struct l_ecc_curve *curve, const void *buf, size_t len); +struct l_ecc_scalar *l_ecc_scalar_new_modn(const struct l_ecc_curve *curve, + const void *buf, size_t len); struct l_ecc_scalar *l_ecc_scalar_new_reduced_1_to_n( const struct l_ecc_curve *curve, const void *buf, size_t len); @@ -83,6 +85,8 @@ bool l_ecc_point_multiply(struct l_ecc_point *ret, const struct l_ecc_scalar *scalar, const struct l_ecc_point *point); +bool l_ecc_point_multiply_g(struct l_ecc_point *ret, + const struct l_ecc_scalar *scalar); bool l_ecc_point_add(struct l_ecc_point *ret, const struct l_ecc_point *a, const struct l_ecc_point *b); bool l_ecc_point_inverse(struct l_ecc_point *p); @@ -99,6 +103,7 @@ bool l_ecc_points_are_equal(const struct l_ecc_point *a, const struct l_ecc_point *b); +bool l_ecc_point_is_infinity(const struct l_ecc_point *p); #ifdef __cplusplus } diff -Nru bluez-5.70/ell/ecc-private.h bluez-5.71/ell/ecc-private.h --- bluez-5.70/ell/ecc-private.h 2023-09-27 17:03:04.000000000 +0800 +++ bluez-5.71/ell/ecc-private.h 2023-11-20 01:31:06.000000000 +0800 @@ -86,7 +86,10 @@ void _vli_rshift1(uint64_t *vli, unsigned int ndigits); -bool _vli_mmod_fast(uint64_t *result, uint64_t *product, +void _vli_mmod_slow(uint64_t *result, const uint64_t *product, + const uint64_t *mod, unsigned int ndigits); + +bool _vli_mmod_fast(uint64_t *result, const uint64_t *product, const uint64_t *curve_prime, unsigned int ndigits); void _vli_mod_mult_fast(uint64_t *result, const uint64_t *left, diff -Nru bluez-5.70/ell/useful.h bluez-5.71/ell/useful.h --- bluez-5.70/ell/useful.h 2023-09-27 17:03:04.000000000 +0800 +++ bluez-5.71/ell/useful.h 2023-11-20 01:31:06.000000000 +0800 @@ -15,6 +15,13 @@ #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) +#define SWAP(l, r) \ + do { typeof(l) __tmp = (l); (l) = (r); (r) = __tmp; } while (0) + +#ifndef __always_inline +#define __always_inline inline __attribute__((always_inline)) +#endif + static inline size_t minsize(size_t a, size_t b) { if (a <= b) diff -Nru bluez-5.70/ell/util.h bluez-5.71/ell/util.h --- bluez-5.70/ell/util.h 2023-09-27 17:03:04.000000000 +0800 +++ bluez-5.71/ell/util.h 2023-11-20 01:31:06.000000000 +0800 @@ -252,6 +252,26 @@ __p; \ })) +/** + * l_newa: + * @type: type of structure + * @count: amount of structures + * + * Allocates stack space for @count structures of @type. Memory is allocated + * using alloca and initialized to 0. + * + * Returns: Pointer to memory allocated on the stack. + */ +#define l_newa(type, count) \ + (type *) (__extension__ ({ \ + size_t __n = (size_t) (count); \ + size_t __s = sizeof(type); \ + void *__p; \ + __p = alloca(__n * __s); \ + memset(__p, 0, __n * __s); \ + __p; \ + })) + char *l_strdup(const char *str); char *l_strndup(const char *str, size_t max); char *l_strdup_printf(const char *format, ...) diff -Nru bluez-5.70/emulator/hciemu.c bluez-5.71/emulator/hciemu.c --- bluez-5.70/emulator/hciemu.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/emulator/hciemu.c 2023-12-14 05:40:27.000000000 +0800 @@ -550,6 +550,15 @@ return btdev_get_bdaddr(client->dev); } +bool hciemu_set_client_bdaddr(struct hciemu_client *client, + const uint8_t *bdaddr) +{ + if (!client) + return NULL; + + return btdev_set_bdaddr(client->dev, bdaddr); +} + const uint8_t *hciemu_get_client_bdaddr(struct hciemu *hciemu) { struct hciemu_client *client; diff -Nru bluez-5.70/emulator/hciemu.h bluez-5.71/emulator/hciemu.h --- bluez-5.70/emulator/hciemu.h 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/emulator/hciemu.h 2023-12-14 05:40:27.000000000 +0800 @@ -39,6 +39,8 @@ struct hciemu_client *hciemu_get_client(struct hciemu *hciemu, int num); struct bthost *hciemu_client_host(struct hciemu_client *client); const uint8_t *hciemu_client_bdaddr(struct hciemu_client *client); +bool hciemu_set_client_bdaddr(struct hciemu_client *client, + const uint8_t *bdaddr); typedef void (*hciemu_debug_func_t)(const char *str, void *user_data); typedef void (*hciemu_destroy_func_t)(void *user_data); diff -Nru bluez-5.70/lib/bluetooth.h bluez-5.71/lib/bluetooth.h --- bluez-5.70/lib/bluetooth.h 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/lib/bluetooth.h 2023-12-14 05:40:27.000000000 +0800 @@ -174,7 +174,7 @@ struct bt_iso_bcast_qos { uint8_t big; uint8_t bis; - uint8_t sync_interval; + uint8_t sync_factor; uint8_t packing; uint8_t framing; struct bt_iso_io_qos in; diff -Nru bluez-5.70/lib/hci.c bluez-5.71/lib/hci.c --- bluez-5.70/lib/hci.c 2022-03-16 23:06:20.000000000 +0800 +++ bluez-5.71/lib/hci.c 2023-12-14 05:40:27.000000000 +0800 @@ -658,6 +658,8 @@ { "5.0", 0x09 }, { "5.1", 0x0a }, { "5.2", 0x0b }, + { "5.3", 0x0c }, + { "5.4", 0x0d }, { NULL } }; diff -Nru bluez-5.70/lib/sdp.c bluez-5.71/lib/sdp.c --- bluez-5.70/lib/sdp.c 2021-02-23 04:26:59.000000000 +0800 +++ bluez-5.71/lib/sdp.c 2023-12-14 05:40:27.000000000 +0800 @@ -420,7 +420,7 @@ d->unitSize += length; if (length <= USHRT_MAX) { - d->val.str = malloc(length); + d->val.str = bt_malloc0(length + 1); if (!d->val.str) { free(d); return NULL; @@ -1505,7 +1505,7 @@ case SDP_TEXT_STR32: val = data->val.str; if (len) - *len = data->unitSize - 1; + *len = data->unitSize - sizeof(uint8_t); break; case SDP_ALT8: case SDP_ALT16: @@ -1527,10 +1527,10 @@ for (tmp = data; tmp; tmp = tmp->next) { sdp_data_t *datatmp; void *value; + uint32_t len = 0; - value = sdp_data_value(tmp, NULL); - datatmp = sdp_data_alloc_with_length(tmp->dtd, value, - tmp->unitSize); + value = sdp_data_value(tmp, &len); + datatmp = sdp_data_alloc_with_length(tmp->dtd, value, len); if (cur) cur->next = datatmp; @@ -2180,16 +2180,21 @@ } int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, - int valuelen) + size_t valuelen) { sdp_data_t *sdpdata = sdp_data_get(rec, attrid); - if (sdpdata) - /* Verify that it is what the caller expects */ - if (SDP_IS_TEXT_STR(sdpdata->dtd)) - if ((int) strlen(sdpdata->val.str) < valuelen) { - strcpy(value, sdpdata->val.str); - return 0; - } + + /* Verify that it is what the caller expects */ + if (!sdpdata || !SDP_IS_TEXT_STR(sdpdata->dtd)) + goto fail; + + /* Have to copy the NULL terminator too, so check len < valuelen. */ + if (strlen(sdpdata->val.str) < valuelen) { + strcpy(value, sdpdata->val.str); + return 0; + } + +fail: errno = EINVAL; return -1; } diff -Nru bluez-5.70/lib/sdp_lib.h bluez-5.71/lib/sdp_lib.h --- bluez-5.70/lib/sdp_lib.h 2021-02-23 04:26:59.000000000 +0800 +++ bluez-5.71/lib/sdp_lib.h 2023-12-14 05:40:27.000000000 +0800 @@ -141,7 +141,8 @@ /* flexible extraction of basic attributes - Jean II */ int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attr, int *value); -int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attr, char *value, int valuelen); +int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attr, char *value, + size_t valuelen); /* * Basic sdp data functions @@ -543,32 +544,38 @@ int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo); int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState); -static inline int sdp_get_service_name(const sdp_record_t *rec, char *str, int len) +static inline int sdp_get_service_name(const sdp_record_t *rec, char *str, + size_t len) { return sdp_get_string_attr(rec, SDP_ATTR_SVCNAME_PRIMARY, str, len); } -static inline int sdp_get_service_desc(const sdp_record_t *rec, char *str, int len) +static inline int sdp_get_service_desc(const sdp_record_t *rec, char *str, + size_t len) { return sdp_get_string_attr(rec, SDP_ATTR_SVCDESC_PRIMARY, str, len); } -static inline int sdp_get_provider_name(const sdp_record_t *rec, char *str, int len) +static inline int sdp_get_provider_name(const sdp_record_t *rec, char *str, + size_t len) { return sdp_get_string_attr(rec, SDP_ATTR_PROVNAME_PRIMARY, str, len); } -static inline int sdp_get_doc_url(const sdp_record_t *rec, char *str, int len) +static inline int sdp_get_doc_url(const sdp_record_t *rec, char *str, + size_t len) { return sdp_get_string_attr(rec, SDP_ATTR_DOC_URL, str, len); } -static inline int sdp_get_clnt_exec_url(const sdp_record_t *rec, char *str, int len) +static inline int sdp_get_clnt_exec_url(const sdp_record_t *rec, char *str, + size_t len) { return sdp_get_string_attr(rec, SDP_ATTR_CLNT_EXEC_URL, str, len); } -static inline int sdp_get_icon_url(const sdp_record_t *rec, char *str, int len) +static inline int sdp_get_icon_url(const sdp_record_t *rec, char *str, + size_t len) { return sdp_get_string_attr(rec, SDP_ATTR_ICON_URL, str, len); } diff -Nru bluez-5.70/Makefile.am bluez-5.71/Makefile.am --- bluez-5.70/Makefile.am 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/Makefile.am 2023-12-14 05:40:27.000000000 +0800 @@ -82,7 +82,7 @@ lib_LTLIBRARIES += lib/libbluetooth.la lib_libbluetooth_la_SOURCES = $(lib_headers) $(lib_sources) -lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 22:10:19 +lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 22:11:19 lib_libbluetooth_la_DEPENDENCIES = $(local_headers) endif @@ -231,6 +231,7 @@ src/shared/gap.h src/shared/gap.c \ src/shared/log.h src/shared/log.c \ src/shared/bap.h src/shared/bap.c src/shared/ascs.h \ + src/shared/bap-debug.h src/shared/bap-debug.c \ src/shared/mcs.h src/shared/mcp.h src/shared/mcp.c \ src/shared/vcp.c src/shared/vcp.h \ src/shared/micp.c src/shared/micp.h \ @@ -357,8 +358,68 @@ if MANPAGES man_MANS += src/bluetoothd.8 +man_MANS += doc/org.bluez.Adapter.5 doc/org.bluez.Device.5 \ + doc/org.bluez.DeviceSet.5 doc/org.bluez.AgentManager.5 \ + doc/org.bluez.Agent.5 doc/org.bluez.ProfileManager.5 \ + doc/org.bluez.Profile.5 doc/org.bluez.NetworkServer.5 \ + doc/org.bluez.Network.5 doc/org.bluez.Input.5 \ + doc/org.bluez.BatteryProviderManager.5 \ + doc/org.bluez.BatteryProvider.5 doc/org.bluez.Battery.5 \ + doc/org.bluez.AdminPolicySet.5 \ + doc/org.bluez.AdminPolicyStatus.5 +man_MANS += doc/org.bluez.Media.5 doc/org.bluez.MediaControl.5 \ + doc/org.bluez.MediaPlayer.5 doc/org.bluez.MediaFolder.5 \ + doc/org.bluez.MediaItem.5 doc/org.bluez.MediaEndpoint.5 \ + doc/org.bluez.MediaTransport.5 +man_MANS += doc/org.bluez.GattManager.5 doc/org.bluez.GattProfile.5 \ + doc/org.bluez.GattService.5 \ + doc/org.bluez.GattCharacteristic.5 \ + doc/org.bluez.GattDescriptor.5 \ + doc/org.bluez.LEAdvertisingManager.5 \ + doc/org.bluez.LEAdvertisement.5 \ + doc/org.bluez.AdvertisementMonitorManager.5 \ + doc/org.bluez.AdvertisementMonitor.5 +man_MANS += doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \ + doc/org.bluez.obex.Transfer.5 \ + doc/org.bluez.obex.ObjectPush.5 \ + doc/org.bluez.obex.FileTransfer.5 \ + doc/org.bluez.obex.Synchronization.5 \ + doc/org.bluez.obex.PhonebookAccess.5 \ + doc/org.bluez.obex.MessageAccess.5 \ + doc/org.bluez.obex.Message.5 \ + doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5 endif manual_pages += src/bluetoothd.8 +manual_pages += doc/org.bluez.Adapter.5 doc/org.bluez.Device.5 \ + doc/org.bluez.DeviceSet.5 doc/org.bluez.AgentManager.5 \ + doc/org.bluez.Agent.5 doc/org.bluez.ProfileManager.5 \ + doc/org.bluez.Profile.5 doc/org.bluez.NetworkServer.5 \ + doc/org.bluez.Network.5 doc/org.bluez.Input.5\ + doc/org.bluez.BatteryProviderManager.5 \ + doc/org.bluez.BatteryProvider.5 doc/org.bluez.Battery.5 \ + doc/org.bluez.AdminPolicySet.5 \ + doc/org.bluez.AdminPolicyStatus.5 +manual_pages += doc/org.bluez.Media.5 doc/org.bluez.MediaControl.5 \ + doc/org.bluez.MediaPlayer.5 doc/org.bluez.MediaFolder.5 \ + doc/org.bluez.MediaItem.5 doc/org.bluez.MediaEndpoint.5 \ + doc/org.bluez.MediaTransport.5 +manual_pages += doc/org.bluez.GattManager.5 doc/org.bluez.GattProfile.5 \ + doc/org.bluez.GattService.5 \ + doc/org.bluez.GattCharacteristic.5 \ + doc/org.bluez.GattDescriptor.5 \ + doc/org.bluez.LEAdvertisingManager.5 \ + doc/org.bluez.LEAdvertisement.5 \ + doc/org.bluez.AdvertisementMonitorManager.5 \ + doc/org.bluez.AdvertisementMonitor.5 +manual_pages += doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \ + doc/org.bluez.obex.Transfer.5 \ + doc/org.bluez.obex.ObjectPush.5 \ + doc/org.bluez.obex.FileTransfer.5 \ + doc/org.bluez.obex.Synchronization.5 \ + doc/org.bluez.obex.PhonebookAccess.5 \ + doc/org.bluez.obex.MessageAccess.5 \ + doc/org.bluez.obex.Message.5 \ + doc/org.bluez.obex.AgentManager.5 doc/org.bluez.obex.Agent.5 EXTRA_DIST += src/genbuiltin src/bluetooth.conf \ src/main.conf profiles/network/network.conf \ @@ -395,15 +456,42 @@ doc/settings-storage.txt EXTRA_DIST += doc/mgmt-api.txt \ - doc/adapter-api.txt doc/device-api.txt \ - doc/agent-api.txt doc/profile-api.txt \ - doc/network-api.txt doc/media-api.rst \ - doc/health-api.txt doc/sap-api.txt \ - doc/input-api.txt + doc/health-api.txt \ + doc/sap-api.txt -EXTRA_DIST += doc/gatt-api.txt doc/advertising-api.txt - -EXTRA_DIST += doc/obex-api.txt doc/obex-agent-api.txt +EXTRA_DIST += doc/org.bluez.Adapter.rst doc/org.bluez.Device.rst \ + doc/org.bluez.DeviceSet.rst doc/org.bluez.AgentManager.rst \ + doc/org.bluez.Agent.rst doc/org.bluez.ProfileManager.rst \ + doc/org.bluez.Profile.rst doc/org.bluez.NetworkServer.rst \ + doc/org.bluez.Network.rst doc/org.bluez.Input.rst \ + doc/org.bluez.BatteryProviderManager.rst \ + doc/org.bluez.BatteryProvider.rst doc/org.bluez.Battery.rst \ + doc/org.bluez.AdminPolicySet.rst \ + doc/org.bluez.AdminPolicyStatus.rst + +EXTRA_DIST += doc/org.bluez.Media.rst doc/org.bluez.MediaControl.rst \ + doc/org.bluez.MediaPlayer.rst doc/org.bluez.MediaFolder.rst \ + doc/org.bluez.MediaItem.rst doc/org.bluez.MediaEndpoint.rst \ + doc/org.bluez.MediaTransport.rst + +EXTRA_DIST += doc/org.bluez.GattManager.rst doc/org.bluez.GattProfile.rst\ + doc/org.bluez.GattService.rst \ + doc/org.bluez.GattCharacteristic.rst \ + doc/org.bluez.GattDescriptor.rst \ + doc/org.bluez.LEAdvertisingManager.rst \ + doc/org.bluez.LEAdvertisement.rst \ + doc/org.bluez.AdvertisementMonitorManager.rst \ + doc/org.bluez.AdvertisementMonitor.rst + +EXTRA_DIST += doc/org.bluez.obex.Client.rst doc/org.bluez.obex.Session.rst \ + doc/org.bluez.obex.Transfer.rst \ + doc/org.bluez.obex.ObjectPush.rst \ + doc/org.bluez.obex.FileTransfer.rst \ + doc/org.bluez.obex.Synchronization.rst \ + doc/org.bluez.obex.PhonebookAccess.rst \ + doc/org.bluez.obex.MessageAccess.rst \ + doc/org.bluez.obex.Message.rst \ + doc/org.bluez.obex.AgentManager.rst doc/org.bluez.obex.Agent.rst EXTRA_DIST += doc/pics-opp.txt doc/pixit-opp.txt \ doc/pts-opp.txt @@ -579,12 +667,24 @@ unit_test_bap_LDADD = src/libshared-glib.la \ lib/libbluetooth-internal.la $(GLIB_LIBS) +unit_tests += unit/test-micp + +unit_test_micp_SOURCES = unit/test-micp.c +unit_test_micp_LDADD = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(GLIB_LIBS) + unit_tests += unit/test-bass unit_test_bass_SOURCES = unit/test-bass.c $(btio_sources) unit_test_bass_LDADD = src/libshared-glib.la \ lib/libbluetooth-internal.la $(GLIB_LIBS) +unit_tests += unit/test-vcp + +unit_test_vcp_SOURCES = unit/test-vcp.c $(btio_sources) +unit_test_vcp_LDADD = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(GLIB_LIBS) + if MIDI unit_tests += unit/test-midi unit_test_midi_CPPFLAGS = $(AM_CPPFLAGS) $(ALSA_CFLAGS) -DMIDI_TEST @@ -667,6 +767,9 @@ %.1: %.rst Makefile $(RST2MAN_PROCESS) +%.5: %.rst Makefile + $(RST2MAN_PROCESS) + %.8: %.rst Makefile $(RST2MAN_PROCESS) diff -Nru bluez-5.70/Makefile.in bluez-5.71/Makefile.in --- bluez-5.70/Makefile.in 2023-09-29 03:54:32.000000000 +0800 +++ bluez-5.71/Makefile.in 2023-12-14 05:41:55.000000000 +0800 @@ -214,7 +214,10 @@ @MANPAGES_TRUE@@TOOLS_TRUE@am__append_51 = tools/rctest.1 tools/l2ping.1 tools/btattach.1 tools/isotest.1 \ @MANPAGES_TRUE@@TOOLS_TRUE@ tools/btmgmt.1 client/bluetoothctl-mgmt.1 \ -@MANPAGES_TRUE@@TOOLS_TRUE@ client/bluetoothctl-monitor.1 +@MANPAGES_TRUE@@TOOLS_TRUE@ client/bluetoothctl-monitor.1 client/bluetoothctl-admin.1 \ +@MANPAGES_TRUE@@TOOLS_TRUE@ client/bluetoothctl-advertise.1 client/bluetoothctl-endpoint.1 \ +@MANPAGES_TRUE@@TOOLS_TRUE@ client/bluetoothctl-gatt.1 client/bluetoothctl-player.1 \ +@MANPAGES_TRUE@@TOOLS_TRUE@ client/bluetoothctl-scan.1 client/bluetoothctl-transport.1 @DEPRECATED_TRUE@@MESH_TRUE@@TOOLS_TRUE@am__append_52 = tools/meshctl @DEPRECATED_TRUE@@MESH_TRUE@@TOOLS_TRUE@am__append_53 = tools/mesh-gatt/local_node.json tools/mesh-gatt/prov_db.json @@ -304,8 +307,9 @@ "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(udevdir)" \ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ "$(DESTDIR)$(testdir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(confdir)" \ - "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(dbussessionbusdir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(confdir)" "$(DESTDIR)$(dbusdir)" \ + "$(DESTDIR)$(dbussessionbusdir)" \ "$(DESTDIR)$(dbussystembusdir)" \ "$(DESTDIR)$(zshcompletiondir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(rulesdir)" "$(DESTDIR)$(statedir)" \ @@ -381,7 +385,8 @@ $(am__EXEEXT_14) unit/test-lib$(EXEEXT) \ unit/test-gatt$(EXEEXT) unit/test-hog$(EXEEXT) \ unit/test-gattrib$(EXEEXT) unit/test-bap$(EXEEXT) \ - unit/test-bass$(EXEEXT) $(am__EXEEXT_15) $(am__EXEEXT_16) + unit/test-micp$(EXEEXT) unit/test-bass$(EXEEXT) \ + unit/test-vcp$(EXEEXT) $(am__EXEEXT_15) $(am__EXEEXT_16) @MAINTAINER_MODE_TRUE@am__EXEEXT_18 = $(am__EXEEXT_17) @LOGGER_TRUE@am__EXEEXT_19 = tools/btmon-logger$(EXEEXT) @OBEX_TRUE@am__EXEEXT_20 = obexd/src/obexd$(EXEEXT) @@ -612,12 +617,13 @@ src/shared/gatt-server.c src/shared/gatt-db.h \ src/shared/gatt-db.c src/shared/gap.h src/shared/gap.c \ src/shared/log.h src/shared/log.c src/shared/bap.h \ - src/shared/bap.c src/shared/ascs.h src/shared/mcs.h \ - src/shared/mcp.h src/shared/mcp.c src/shared/vcp.c \ - src/shared/vcp.h src/shared/micp.c src/shared/micp.h \ - src/shared/csip.c src/shared/csip.h src/shared/bass.h \ - src/shared/bass.c src/shared/lc3.h src/shared/tty.h \ - src/shared/shell.c src/shared/shell.h src/shared/io-ell.c \ + src/shared/bap.c src/shared/ascs.h src/shared/bap-debug.h \ + src/shared/bap-debug.c src/shared/mcs.h src/shared/mcp.h \ + src/shared/mcp.c src/shared/vcp.c src/shared/vcp.h \ + src/shared/micp.c src/shared/micp.h src/shared/csip.c \ + src/shared/csip.h src/shared/bass.h src/shared/bass.c \ + src/shared/lc3.h src/shared/tty.h src/shared/shell.c \ + src/shared/shell.h src/shared/io-ell.c \ src/shared/timeout-ell.c src/shared/mainloop.h \ src/shared/mainloop-ell.c @READLINE_TRUE@am__objects_5 = src/shared/libshared_ell_la-shell.lo @@ -642,6 +648,7 @@ src/shared/libshared_ell_la-gap.lo \ src/shared/libshared_ell_la-log.lo \ src/shared/libshared_ell_la-bap.lo \ + src/shared/libshared_ell_la-bap-debug.lo \ src/shared/libshared_ell_la-mcp.lo \ src/shared/libshared_ell_la-vcp.lo \ src/shared/libshared_ell_la-micp.lo \ @@ -676,12 +683,13 @@ src/shared/gatt-server.c src/shared/gatt-db.h \ src/shared/gatt-db.c src/shared/gap.h src/shared/gap.c \ src/shared/log.h src/shared/log.c src/shared/bap.h \ - src/shared/bap.c src/shared/ascs.h src/shared/mcs.h \ - src/shared/mcp.h src/shared/mcp.c src/shared/vcp.c \ - src/shared/vcp.h src/shared/micp.c src/shared/micp.h \ - src/shared/csip.c src/shared/csip.h src/shared/bass.h \ - src/shared/bass.c src/shared/lc3.h src/shared/tty.h \ - src/shared/shell.c src/shared/shell.h src/shared/io-glib.c \ + src/shared/bap.c src/shared/ascs.h src/shared/bap-debug.h \ + src/shared/bap-debug.c src/shared/mcs.h src/shared/mcp.h \ + src/shared/mcp.c src/shared/vcp.c src/shared/vcp.h \ + src/shared/micp.c src/shared/micp.h src/shared/csip.c \ + src/shared/csip.h src/shared/bass.h src/shared/bass.c \ + src/shared/lc3.h src/shared/tty.h src/shared/shell.c \ + src/shared/shell.h src/shared/io-glib.c \ src/shared/timeout-glib.c src/shared/mainloop-glib.c \ src/shared/mainloop-notify.h src/shared/mainloop-notify.c \ src/shared/tester.c @@ -707,6 +715,7 @@ src/shared/libshared_glib_la-gap.lo \ src/shared/libshared_glib_la-log.lo \ src/shared/libshared_glib_la-bap.lo \ + src/shared/libshared_glib_la-bap-debug.lo \ src/shared/libshared_glib_la-mcp.lo \ src/shared/libshared_glib_la-vcp.lo \ src/shared/libshared_glib_la-micp.lo \ @@ -741,12 +750,13 @@ src/shared/gatt-server.c src/shared/gatt-db.h \ src/shared/gatt-db.c src/shared/gap.h src/shared/gap.c \ src/shared/log.h src/shared/log.c src/shared/bap.h \ - src/shared/bap.c src/shared/ascs.h src/shared/mcs.h \ - src/shared/mcp.h src/shared/mcp.c src/shared/vcp.c \ - src/shared/vcp.h src/shared/micp.c src/shared/micp.h \ - src/shared/csip.c src/shared/csip.h src/shared/bass.h \ - src/shared/bass.c src/shared/lc3.h src/shared/tty.h \ - src/shared/shell.c src/shared/shell.h src/shared/io-mainloop.c \ + src/shared/bap.c src/shared/ascs.h src/shared/bap-debug.h \ + src/shared/bap-debug.c src/shared/mcs.h src/shared/mcp.h \ + src/shared/mcp.c src/shared/vcp.c src/shared/vcp.h \ + src/shared/micp.c src/shared/micp.h src/shared/csip.c \ + src/shared/csip.h src/shared/bass.h src/shared/bass.c \ + src/shared/lc3.h src/shared/tty.h src/shared/shell.c \ + src/shared/shell.h src/shared/io-mainloop.c \ src/shared/timeout-mainloop.c src/shared/mainloop.h \ src/shared/mainloop.c src/shared/mainloop-notify.h \ src/shared/mainloop-notify.c @@ -773,6 +783,7 @@ src/shared/libshared_mainloop_la-gap.lo \ src/shared/libshared_mainloop_la-log.lo \ src/shared/libshared_mainloop_la-bap.lo \ + src/shared/libshared_mainloop_la-bap-debug.lo \ src/shared/libshared_mainloop_la-mcp.lo \ src/shared/libshared_mainloop_la-vcp.lo \ src/shared/libshared_mainloop_la-micp.lo \ @@ -2119,6 +2130,10 @@ unit_test_mgmt_OBJECTS = $(am_unit_test_mgmt_OBJECTS) unit_test_mgmt_DEPENDENCIES = src/libshared-glib.la \ $(am__DEPENDENCIES_1) +am_unit_test_micp_OBJECTS = unit/test-micp.$(OBJEXT) +unit_test_micp_OBJECTS = $(am_unit_test_micp_OBJECTS) +unit_test_micp_DEPENDENCIES = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(am__DEPENDENCIES_1) am__unit_test_midi_SOURCES_DIST = unit/test-midi.c \ profiles/midi/libmidi.h profiles/midi/libmidi.c @MIDI_TRUE@am_unit_test_midi_OBJECTS = \ @@ -2158,6 +2173,10 @@ unit_test_uuid_OBJECTS = $(am_unit_test_uuid_OBJECTS) unit_test_uuid_DEPENDENCIES = src/libshared-glib.la \ lib/libbluetooth-internal.la $(am__DEPENDENCIES_1) +am_unit_test_vcp_OBJECTS = unit/test-vcp.$(OBJEXT) $(am__objects_37) +unit_test_vcp_OBJECTS = $(am_unit_test_vcp_OBJECTS) +unit_test_vcp_DEPENDENCIES = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(am__DEPENDENCIES_1) SCRIPTS = $(test_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -2480,6 +2499,7 @@ src/shared/$(DEPDIR)/btp.Po \ src/shared/$(DEPDIR)/libshared_ell_la-ad.Plo \ src/shared/$(DEPDIR)/libshared_ell_la-att.Plo \ + src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Plo \ src/shared/$(DEPDIR)/libshared_ell_la-bap.Plo \ src/shared/$(DEPDIR)/libshared_ell_la-bass.Plo \ src/shared/$(DEPDIR)/libshared_ell_la-btsnoop.Plo \ @@ -2510,6 +2530,7 @@ src/shared/$(DEPDIR)/libshared_ell_la-vcp.Plo \ src/shared/$(DEPDIR)/libshared_glib_la-ad.Plo \ src/shared/$(DEPDIR)/libshared_glib_la-att.Plo \ + src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Plo \ src/shared/$(DEPDIR)/libshared_glib_la-bap.Plo \ src/shared/$(DEPDIR)/libshared_glib_la-bass.Plo \ src/shared/$(DEPDIR)/libshared_glib_la-btsnoop.Plo \ @@ -2542,6 +2563,7 @@ src/shared/$(DEPDIR)/libshared_glib_la-vcp.Plo \ src/shared/$(DEPDIR)/libshared_mainloop_la-ad.Plo \ src/shared/$(DEPDIR)/libshared_mainloop_la-att.Plo \ + src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Plo \ src/shared/$(DEPDIR)/libshared_mainloop_la-bap.Plo \ src/shared/$(DEPDIR)/libshared_mainloop_la-bass.Plo \ src/shared/$(DEPDIR)/libshared_mainloop_la-btsnoop.Plo \ @@ -2655,10 +2677,11 @@ unit/$(DEPDIR)/test-gobex-transfer.Po \ unit/$(DEPDIR)/test-gobex.Po unit/$(DEPDIR)/test-hfp.Po \ unit/$(DEPDIR)/test-hog.Po unit/$(DEPDIR)/test-lib.Po \ - unit/$(DEPDIR)/test-mgmt.Po unit/$(DEPDIR)/test-queue.Po \ - unit/$(DEPDIR)/test-ringbuf.Po unit/$(DEPDIR)/test-sdp.Po \ - unit/$(DEPDIR)/test-tester.Po unit/$(DEPDIR)/test-textfile.Po \ - unit/$(DEPDIR)/test-uhid.Po unit/$(DEPDIR)/test-uuid.Po \ + unit/$(DEPDIR)/test-mgmt.Po unit/$(DEPDIR)/test-micp.Po \ + unit/$(DEPDIR)/test-queue.Po unit/$(DEPDIR)/test-ringbuf.Po \ + unit/$(DEPDIR)/test-sdp.Po unit/$(DEPDIR)/test-tester.Po \ + unit/$(DEPDIR)/test-textfile.Po unit/$(DEPDIR)/test-uhid.Po \ + unit/$(DEPDIR)/test-uuid.Po unit/$(DEPDIR)/test-vcp.Po \ unit/$(DEPDIR)/test_mesh_crypto-test-mesh-crypto.Po \ unit/$(DEPDIR)/test_midi-test-midi.Po unit/$(DEPDIR)/util.Po am__mv = mv -f @@ -2749,10 +2772,11 @@ $(unit_test_gobex_transfer_SOURCES) $(unit_test_hfp_SOURCES) \ $(unit_test_hog_SOURCES) $(unit_test_lib_SOURCES) \ $(unit_test_mesh_crypto_SOURCES) $(unit_test_mgmt_SOURCES) \ - $(unit_test_midi_SOURCES) $(unit_test_queue_SOURCES) \ - $(unit_test_ringbuf_SOURCES) $(unit_test_sdp_SOURCES) \ - $(unit_test_tester_SOURCES) $(unit_test_textfile_SOURCES) \ - $(unit_test_uhid_SOURCES) $(unit_test_uuid_SOURCES) + $(unit_test_micp_SOURCES) $(unit_test_midi_SOURCES) \ + $(unit_test_queue_SOURCES) $(unit_test_ringbuf_SOURCES) \ + $(unit_test_sdp_SOURCES) $(unit_test_tester_SOURCES) \ + $(unit_test_textfile_SOURCES) $(unit_test_uhid_SOURCES) \ + $(unit_test_uuid_SOURCES) $(unit_test_vcp_SOURCES) DIST_SOURCES = $(am__android_audio_a2dp_default_la_SOURCES_DIST) \ $(am__android_audio_sco_default_la_SOURCES_DIST) \ $(am__android_bluetooth_default_la_SOURCES_DIST) \ @@ -2853,17 +2877,19 @@ $(unit_test_hfp_SOURCES) $(unit_test_hog_SOURCES) \ $(unit_test_lib_SOURCES) \ $(am__unit_test_mesh_crypto_SOURCES_DIST) \ - $(unit_test_mgmt_SOURCES) $(am__unit_test_midi_SOURCES_DIST) \ - $(unit_test_queue_SOURCES) $(unit_test_ringbuf_SOURCES) \ - $(unit_test_sdp_SOURCES) $(unit_test_tester_SOURCES) \ - $(unit_test_textfile_SOURCES) $(unit_test_uhid_SOURCES) \ - $(unit_test_uuid_SOURCES) + $(unit_test_mgmt_SOURCES) $(unit_test_micp_SOURCES) \ + $(am__unit_test_midi_SOURCES_DIST) $(unit_test_queue_SOURCES) \ + $(unit_test_ringbuf_SOURCES) $(unit_test_sdp_SOURCES) \ + $(unit_test_tester_SOURCES) $(unit_test_textfile_SOURCES) \ + $(unit_test_uhid_SOURCES) $(unit_test_uuid_SOURCES) \ + $(unit_test_vcp_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man1dir = $(mandir)/man1 +man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) @@ -3341,14 +3367,40 @@ tools/hid2hci.rules $(test_scripts) doc/assigned-numbers.txt \ doc/supported-features.txt doc/test-coverage.txt \ doc/test-runner.rst doc/settings-storage.txt doc/mgmt-api.txt \ - doc/adapter-api.txt doc/device-api.txt doc/agent-api.txt \ - doc/profile-api.txt doc/network-api.txt doc/media-api.rst \ - doc/health-api.txt doc/sap-api.txt doc/input-api.txt \ - doc/gatt-api.txt doc/advertising-api.txt doc/obex-api.txt \ - doc/obex-agent-api.txt doc/pics-opp.txt doc/pixit-opp.txt \ - doc/pts-opp.txt doc/btsnoop.txt tools/magic.btsnoop \ - $(manual_pages) $(patsubst %.1,%.rst, $(patsubst \ - %.8,%.rst,$(manual_pages))) + doc/health-api.txt doc/sap-api.txt doc/org.bluez.Adapter.rst \ + doc/org.bluez.Device.rst doc/org.bluez.DeviceSet.rst \ + doc/org.bluez.AgentManager.rst doc/org.bluez.Agent.rst \ + doc/org.bluez.ProfileManager.rst doc/org.bluez.Profile.rst \ + doc/org.bluez.NetworkServer.rst doc/org.bluez.Network.rst \ + doc/org.bluez.Input.rst \ + doc/org.bluez.BatteryProviderManager.rst \ + doc/org.bluez.BatteryProvider.rst doc/org.bluez.Battery.rst \ + doc/org.bluez.AdminPolicySet.rst \ + doc/org.bluez.AdminPolicyStatus.rst doc/org.bluez.Media.rst \ + doc/org.bluez.MediaControl.rst doc/org.bluez.MediaPlayer.rst \ + doc/org.bluez.MediaFolder.rst doc/org.bluez.MediaItem.rst \ + doc/org.bluez.MediaEndpoint.rst \ + doc/org.bluez.MediaTransport.rst doc/org.bluez.GattManager.rst \ + doc/org.bluez.GattProfile.rst doc/org.bluez.GattService.rst \ + doc/org.bluez.GattCharacteristic.rst \ + doc/org.bluez.GattDescriptor.rst \ + doc/org.bluez.LEAdvertisingManager.rst \ + doc/org.bluez.LEAdvertisement.rst \ + doc/org.bluez.AdvertisementMonitorManager.rst \ + doc/org.bluez.AdvertisementMonitor.rst \ + doc/org.bluez.obex.Client.rst doc/org.bluez.obex.Session.rst \ + doc/org.bluez.obex.Transfer.rst \ + doc/org.bluez.obex.ObjectPush.rst \ + doc/org.bluez.obex.FileTransfer.rst \ + doc/org.bluez.obex.Synchronization.rst \ + doc/org.bluez.obex.PhonebookAccess.rst \ + doc/org.bluez.obex.MessageAccess.rst \ + doc/org.bluez.obex.Message.rst \ + doc/org.bluez.obex.AgentManager.rst \ + doc/org.bluez.obex.Agent.rst doc/pics-opp.txt \ + doc/pixit-opp.txt doc/pts-opp.txt doc/btsnoop.txt \ + tools/magic.btsnoop $(manual_pages) $(patsubst %.1,%.rst, \ + $(patsubst %.8,%.rst,$(manual_pages))) pkginclude_HEADERS = $(am__append_1) AM_CFLAGS = $(MISC_CFLAGS) $(WARNING_CFLAGS) $(UDEV_CFLAGS) $(LIBEBOOK_CFLAGS) \ $(LIBEDATASERVER_CFLAGS) $(ell_cflags) @@ -3369,15 +3421,85 @@ plugindir = $(libdir)/bluetooth/plugins @MAINTAINER_MODE_FALSE@build_plugindir = $(plugindir) @MAINTAINER_MODE_TRUE@build_plugindir = $(abs_top_srcdir)/plugins/.libs -@MANPAGES_TRUE@man_MANS = src/bluetoothd.8 $(am__append_45) \ +@MANPAGES_TRUE@man_MANS = src/bluetoothd.8 doc/org.bluez.Adapter.5 \ +@MANPAGES_TRUE@ doc/org.bluez.Device.5 \ +@MANPAGES_TRUE@ doc/org.bluez.DeviceSet.5 \ +@MANPAGES_TRUE@ doc/org.bluez.AgentManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.Agent.5 \ +@MANPAGES_TRUE@ doc/org.bluez.ProfileManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.Profile.5 \ +@MANPAGES_TRUE@ doc/org.bluez.NetworkServer.5 \ +@MANPAGES_TRUE@ doc/org.bluez.Network.5 doc/org.bluez.Input.5 \ +@MANPAGES_TRUE@ doc/org.bluez.BatteryProviderManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.BatteryProvider.5 \ +@MANPAGES_TRUE@ doc/org.bluez.Battery.5 \ +@MANPAGES_TRUE@ doc/org.bluez.AdminPolicySet.5 \ +@MANPAGES_TRUE@ doc/org.bluez.AdminPolicyStatus.5 \ +@MANPAGES_TRUE@ doc/org.bluez.Media.5 \ +@MANPAGES_TRUE@ doc/org.bluez.MediaControl.5 \ +@MANPAGES_TRUE@ doc/org.bluez.MediaPlayer.5 \ +@MANPAGES_TRUE@ doc/org.bluez.MediaFolder.5 \ +@MANPAGES_TRUE@ doc/org.bluez.MediaItem.5 \ +@MANPAGES_TRUE@ doc/org.bluez.MediaEndpoint.5 \ +@MANPAGES_TRUE@ doc/org.bluez.MediaTransport.5 \ +@MANPAGES_TRUE@ doc/org.bluez.GattManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.GattProfile.5 \ +@MANPAGES_TRUE@ doc/org.bluez.GattService.5 \ +@MANPAGES_TRUE@ doc/org.bluez.GattCharacteristic.5 \ +@MANPAGES_TRUE@ doc/org.bluez.GattDescriptor.5 \ +@MANPAGES_TRUE@ doc/org.bluez.LEAdvertisingManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.LEAdvertisement.5 \ +@MANPAGES_TRUE@ doc/org.bluez.AdvertisementMonitorManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.AdvertisementMonitor.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.Client.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.Session.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.Transfer.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.ObjectPush.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.FileTransfer.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.Synchronization.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.PhonebookAccess.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.MessageAccess.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.Message.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.AgentManager.5 \ +@MANPAGES_TRUE@ doc/org.bluez.obex.Agent.5 $(am__append_45) \ @MANPAGES_TRUE@ $(am__append_51) $(am__append_56) \ @MANPAGES_TRUE@ $(am__append_57) $(am__append_73) -manual_pages = src/bluetoothd.8 monitor/btmon.1 tools/hciattach.1 \ +manual_pages = src/bluetoothd.8 doc/org.bluez.Adapter.5 \ + doc/org.bluez.Device.5 doc/org.bluez.DeviceSet.5 \ + doc/org.bluez.AgentManager.5 doc/org.bluez.Agent.5 \ + doc/org.bluez.ProfileManager.5 doc/org.bluez.Profile.5 \ + doc/org.bluez.NetworkServer.5 doc/org.bluez.Network.5 \ + doc/org.bluez.Input.5 doc/org.bluez.BatteryProviderManager.5 \ + doc/org.bluez.BatteryProvider.5 doc/org.bluez.Battery.5 \ + doc/org.bluez.AdminPolicySet.5 \ + doc/org.bluez.AdminPolicyStatus.5 doc/org.bluez.Media.5 \ + doc/org.bluez.MediaControl.5 doc/org.bluez.MediaPlayer.5 \ + doc/org.bluez.MediaFolder.5 doc/org.bluez.MediaItem.5 \ + doc/org.bluez.MediaEndpoint.5 doc/org.bluez.MediaTransport.5 \ + doc/org.bluez.GattManager.5 doc/org.bluez.GattProfile.5 \ + doc/org.bluez.GattService.5 doc/org.bluez.GattCharacteristic.5 \ + doc/org.bluez.GattDescriptor.5 \ + doc/org.bluez.LEAdvertisingManager.5 \ + doc/org.bluez.LEAdvertisement.5 \ + doc/org.bluez.AdvertisementMonitorManager.5 \ + doc/org.bluez.AdvertisementMonitor.5 \ + doc/org.bluez.obex.Client.5 doc/org.bluez.obex.Session.5 \ + doc/org.bluez.obex.Transfer.5 doc/org.bluez.obex.ObjectPush.5 \ + doc/org.bluez.obex.FileTransfer.5 \ + doc/org.bluez.obex.Synchronization.5 \ + doc/org.bluez.obex.PhonebookAccess.5 \ + doc/org.bluez.obex.MessageAccess.5 \ + doc/org.bluez.obex.Message.5 doc/org.bluez.obex.AgentManager.5 \ + doc/org.bluez.obex.Agent.5 monitor/btmon.1 tools/hciattach.1 \ tools/hciconfig.1 tools/hcitool.1 tools/hcidump.1 \ tools/rfcomm.1 tools/sdptool.1 tools/ciptool.1 tools/rctest.1 \ tools/l2ping.1 tools/btattach.1 tools/bdaddr.1 tools/isotest.1 \ tools/btmgmt.1 client/bluetoothctl-mgmt.1 \ - client/bluetoothctl-monitor.1 tools/hid2hci.1 $(am__append_74) + client/bluetoothctl-monitor.1 client/bluetoothctl-admin.1 \ + client/bluetoothctl-advertise.1 client/bluetoothctl-endpoint.1 \ + client/bluetoothctl-gatt.1 client/bluetoothctl-player.1 \ + client/bluetoothctl-scan.1 client/bluetoothctl-transport.1 \ + tools/hid2hci.1 $(am__append_74) plugin_LTLIBRARIES = $(am__append_29) $(am__append_42) \ $(am__append_67) lib_sources = lib/bluetooth.c lib/hci.c lib/sdp.c @@ -3391,7 +3513,7 @@ BUILT_SOURCES = $(local_headers) $(ell_built_sources) src/builtin.h \ obexd/src/builtin.h @LIBRARY_TRUE@lib_libbluetooth_la_SOURCES = $(lib_headers) $(lib_sources) -@LIBRARY_TRUE@lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 22:10:19 +@LIBRARY_TRUE@lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 22:11:19 @LIBRARY_TRUE@lib_libbluetooth_la_DEPENDENCIES = $(local_headers) lib_libbluetooth_internal_la_SOURCES = $(lib_headers) $(lib_sources) \ $(extra_headers) $(extra_sources) @@ -3511,12 +3633,12 @@ src/shared/gatt-server.c src/shared/gatt-db.h \ src/shared/gatt-db.c src/shared/gap.h src/shared/gap.c \ src/shared/log.h src/shared/log.c src/shared/bap.h \ - src/shared/bap.c src/shared/ascs.h src/shared/mcs.h \ - src/shared/mcp.h src/shared/mcp.c src/shared/vcp.c \ - src/shared/vcp.h src/shared/micp.c src/shared/micp.h \ - src/shared/csip.c src/shared/csip.h src/shared/bass.h \ - src/shared/bass.c src/shared/lc3.h src/shared/tty.h \ - $(am__append_5) + src/shared/bap.c src/shared/ascs.h src/shared/bap-debug.h \ + src/shared/bap-debug.c src/shared/mcs.h src/shared/mcp.h \ + src/shared/mcp.c src/shared/vcp.c src/shared/vcp.h \ + src/shared/micp.c src/shared/micp.h src/shared/csip.c \ + src/shared/csip.h src/shared/bass.h src/shared/bass.c \ + src/shared/lc3.h src/shared/tty.h $(am__append_5) src_libshared_glib_la_SOURCES = $(shared_sources) \ src/shared/io-glib.c \ src/shared/timeout-glib.c \ @@ -3656,7 +3778,8 @@ unit/test-avdtp unit/test-avctp unit/test-avrcp unit/test-hfp \ unit/test-gdbus-client $(am__append_77) unit/test-lib \ unit/test-gatt unit/test-hog unit/test-gattrib unit/test-bap \ - unit/test-bass $(am__append_78) $(am__append_79) + unit/test-micp unit/test-bass unit/test-vcp $(am__append_78) \ + $(am__append_79) @CLIENT_TRUE@client_bluetoothctl_SOURCES = client/main.c \ @CLIENT_TRUE@ client/print.h client/print.c \ @CLIENT_TRUE@ client/display.h client/display.c \ @@ -4498,10 +4621,18 @@ unit_test_bap_LDADD = src/libshared-glib.la \ lib/libbluetooth-internal.la $(GLIB_LIBS) +unit_test_micp_SOURCES = unit/test-micp.c +unit_test_micp_LDADD = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(GLIB_LIBS) + unit_test_bass_SOURCES = unit/test-bass.c $(btio_sources) unit_test_bass_LDADD = src/libshared-glib.la \ lib/libbluetooth-internal.la $(GLIB_LIBS) +unit_test_vcp_SOURCES = unit/test-vcp.c $(btio_sources) +unit_test_vcp_LDADD = src/libshared-glib.la \ + lib/libbluetooth-internal.la $(GLIB_LIBS) + @MIDI_TRUE@unit_test_midi_CPPFLAGS = $(AM_CPPFLAGS) $(ALSA_CFLAGS) -DMIDI_TEST @MIDI_TRUE@unit_test_midi_SOURCES = unit/test-midi.c \ @MIDI_TRUE@ profiles/midi/libmidi.h \ @@ -5113,6 +5244,8 @@ src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_ell_la-bap.lo: src/shared/$(am__dirstamp) \ src/shared/$(DEPDIR)/$(am__dirstamp) +src/shared/libshared_ell_la-bap-debug.lo: src/shared/$(am__dirstamp) \ + src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_ell_la-mcp.lo: src/shared/$(am__dirstamp) \ src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_ell_la-vcp.lo: src/shared/$(am__dirstamp) \ @@ -5185,6 +5318,8 @@ src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_glib_la-bap.lo: src/shared/$(am__dirstamp) \ src/shared/$(DEPDIR)/$(am__dirstamp) +src/shared/libshared_glib_la-bap-debug.lo: src/shared/$(am__dirstamp) \ + src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_glib_la-mcp.lo: src/shared/$(am__dirstamp) \ src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_glib_la-vcp.lo: src/shared/$(am__dirstamp) \ @@ -5263,6 +5398,9 @@ src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_mainloop_la-bap.lo: src/shared/$(am__dirstamp) \ src/shared/$(DEPDIR)/$(am__dirstamp) +src/shared/libshared_mainloop_la-bap-debug.lo: \ + src/shared/$(am__dirstamp) \ + src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_mainloop_la-mcp.lo: src/shared/$(am__dirstamp) \ src/shared/$(DEPDIR)/$(am__dirstamp) src/shared/libshared_mainloop_la-vcp.lo: src/shared/$(am__dirstamp) \ @@ -6901,6 +7039,12 @@ unit/test-mgmt$(EXEEXT): $(unit_test_mgmt_OBJECTS) $(unit_test_mgmt_DEPENDENCIES) $(EXTRA_unit_test_mgmt_DEPENDENCIES) unit/$(am__dirstamp) @rm -f unit/test-mgmt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(unit_test_mgmt_OBJECTS) $(unit_test_mgmt_LDADD) $(LIBS) +unit/test-micp.$(OBJEXT): unit/$(am__dirstamp) \ + unit/$(DEPDIR)/$(am__dirstamp) + +unit/test-micp$(EXEEXT): $(unit_test_micp_OBJECTS) $(unit_test_micp_DEPENDENCIES) $(EXTRA_unit_test_micp_DEPENDENCIES) unit/$(am__dirstamp) + @rm -f unit/test-micp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(unit_test_micp_OBJECTS) $(unit_test_micp_LDADD) $(LIBS) unit/test_midi-test-midi.$(OBJEXT): unit/$(am__dirstamp) \ unit/$(DEPDIR)/$(am__dirstamp) profiles/midi/unit_test_midi-libmidi.$(OBJEXT): \ @@ -6952,6 +7096,12 @@ unit/test-uuid$(EXEEXT): $(unit_test_uuid_OBJECTS) $(unit_test_uuid_DEPENDENCIES) $(EXTRA_unit_test_uuid_DEPENDENCIES) unit/$(am__dirstamp) @rm -f unit/test-uuid$(EXEEXT) $(AM_V_CCLD)$(LINK) $(unit_test_uuid_OBJECTS) $(unit_test_uuid_LDADD) $(LIBS) +unit/test-vcp.$(OBJEXT): unit/$(am__dirstamp) \ + unit/$(DEPDIR)/$(am__dirstamp) + +unit/test-vcp$(EXEEXT): $(unit_test_vcp_OBJECTS) $(unit_test_vcp_DEPENDENCIES) $(EXTRA_unit_test_vcp_DEPENDENCIES) unit/$(am__dirstamp) + @rm -f unit/test-vcp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(unit_test_vcp_OBJECTS) $(unit_test_vcp_LDADD) $(LIBS) install-testSCRIPTS: $(test_SCRIPTS) @$(NORMAL_INSTALL) @list='$(test_SCRIPTS)'; test -n "$(testdir)" || list=; \ @@ -7427,6 +7577,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/btp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-ad.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-att.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-bap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-bass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-btsnoop.Plo@am__quote@ # am--include-marker @@ -7457,6 +7608,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_ell_la-vcp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-ad.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-att.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-bap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-bass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-btsnoop.Plo@am__quote@ # am--include-marker @@ -7489,6 +7641,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_glib_la-vcp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_mainloop_la-ad.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_mainloop_la-att.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_mainloop_la-bap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_mainloop_la-bass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/libshared_mainloop_la-btsnoop.Plo@am__quote@ # am--include-marker @@ -7656,6 +7809,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-hog.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-lib.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-mgmt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-micp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-queue.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-ringbuf.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-sdp.Po@am__quote@ # am--include-marker @@ -7663,6 +7817,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-textfile.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-uhid.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-uuid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test-vcp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_mesh_crypto-test-mesh-crypto.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/test_midi-test-midi.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@unit/$(DEPDIR)/util.Po@am__quote@ # am--include-marker @@ -7998,6 +8153,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_ell_la_CFLAGS) $(CFLAGS) -c -o src/shared/libshared_ell_la-bap.lo `test -f 'src/shared/bap.c' || echo '$(srcdir)/'`src/shared/bap.c +src/shared/libshared_ell_la-bap-debug.lo: src/shared/bap-debug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_ell_la_CFLAGS) $(CFLAGS) -MT src/shared/libshared_ell_la-bap-debug.lo -MD -MP -MF src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Tpo -c -o src/shared/libshared_ell_la-bap-debug.lo `test -f 'src/shared/bap-debug.c' || echo '$(srcdir)/'`src/shared/bap-debug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Tpo src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shared/bap-debug.c' object='src/shared/libshared_ell_la-bap-debug.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_ell_la_CFLAGS) $(CFLAGS) -c -o src/shared/libshared_ell_la-bap-debug.lo `test -f 'src/shared/bap-debug.c' || echo '$(srcdir)/'`src/shared/bap-debug.c + src/shared/libshared_ell_la-mcp.lo: src/shared/mcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_ell_la_CFLAGS) $(CFLAGS) -MT src/shared/libshared_ell_la-mcp.lo -MD -MP -MF src/shared/$(DEPDIR)/libshared_ell_la-mcp.Tpo -c -o src/shared/libshared_ell_la-mcp.lo `test -f 'src/shared/mcp.c' || echo '$(srcdir)/'`src/shared/mcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/shared/$(DEPDIR)/libshared_ell_la-mcp.Tpo src/shared/$(DEPDIR)/libshared_ell_la-mcp.Plo @@ -8208,6 +8370,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_glib_la_CFLAGS) $(CFLAGS) -c -o src/shared/libshared_glib_la-bap.lo `test -f 'src/shared/bap.c' || echo '$(srcdir)/'`src/shared/bap.c +src/shared/libshared_glib_la-bap-debug.lo: src/shared/bap-debug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_glib_la_CFLAGS) $(CFLAGS) -MT src/shared/libshared_glib_la-bap-debug.lo -MD -MP -MF src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Tpo -c -o src/shared/libshared_glib_la-bap-debug.lo `test -f 'src/shared/bap-debug.c' || echo '$(srcdir)/'`src/shared/bap-debug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Tpo src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shared/bap-debug.c' object='src/shared/libshared_glib_la-bap-debug.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_glib_la_CFLAGS) $(CFLAGS) -c -o src/shared/libshared_glib_la-bap-debug.lo `test -f 'src/shared/bap-debug.c' || echo '$(srcdir)/'`src/shared/bap-debug.c + src/shared/libshared_glib_la-mcp.lo: src/shared/mcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_glib_la_CFLAGS) $(CFLAGS) -MT src/shared/libshared_glib_la-mcp.lo -MD -MP -MF src/shared/$(DEPDIR)/libshared_glib_la-mcp.Tpo -c -o src/shared/libshared_glib_la-mcp.lo `test -f 'src/shared/mcp.c' || echo '$(srcdir)/'`src/shared/mcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/shared/$(DEPDIR)/libshared_glib_la-mcp.Tpo src/shared/$(DEPDIR)/libshared_glib_la-mcp.Plo @@ -8432,6 +8601,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_mainloop_la_CFLAGS) $(CFLAGS) -c -o src/shared/libshared_mainloop_la-bap.lo `test -f 'src/shared/bap.c' || echo '$(srcdir)/'`src/shared/bap.c +src/shared/libshared_mainloop_la-bap-debug.lo: src/shared/bap-debug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_mainloop_la_CFLAGS) $(CFLAGS) -MT src/shared/libshared_mainloop_la-bap-debug.lo -MD -MP -MF src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Tpo -c -o src/shared/libshared_mainloop_la-bap-debug.lo `test -f 'src/shared/bap-debug.c' || echo '$(srcdir)/'`src/shared/bap-debug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Tpo src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shared/bap-debug.c' object='src/shared/libshared_mainloop_la-bap-debug.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_mainloop_la_CFLAGS) $(CFLAGS) -c -o src/shared/libshared_mainloop_la-bap-debug.lo `test -f 'src/shared/bap-debug.c' || echo '$(srcdir)/'`src/shared/bap-debug.c + src/shared/libshared_mainloop_la-mcp.lo: src/shared/mcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_libshared_mainloop_la_CFLAGS) $(CFLAGS) -MT src/shared/libshared_mainloop_la-mcp.lo -MD -MP -MF src/shared/$(DEPDIR)/libshared_mainloop_la-mcp.Tpo -c -o src/shared/libshared_mainloop_la-mcp.lo `test -f 'src/shared/mcp.c' || echo '$(srcdir)/'`src/shared/mcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/shared/$(DEPDIR)/libshared_mainloop_la-mcp.Tpo src/shared/$(DEPDIR)/libshared_mainloop_la-mcp.Plo @@ -11064,6 +11240,49 @@ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man5: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man5dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.5[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) install-man8: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ @@ -11735,6 +11954,13 @@ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +unit/test-micp.log: unit/test-micp$(EXEEXT) + @p='unit/test-micp$(EXEEXT)'; \ + b='unit/test-micp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) unit/test-bass.log: unit/test-bass$(EXEEXT) @p='unit/test-bass$(EXEEXT)'; \ b='unit/test-bass'; \ @@ -11742,6 +11968,13 @@ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +unit/test-vcp.log: unit/test-vcp$(EXEEXT) + @p='unit/test-vcp$(EXEEXT)'; \ + b='unit/test-vcp'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) unit/test-midi.log: unit/test-midi$(EXEEXT) @p='unit/test-midi$(EXEEXT)'; \ b='unit/test-midi'; \ @@ -11958,7 +12191,7 @@ install-pluginLTLIBRARIES: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cupsdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(udevdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(testdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(confdir)" "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(dbussessionbusdir)" "$(DESTDIR)$(dbussystembusdir)" "$(DESTDIR)$(zshcompletiondir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(rulesdir)" "$(DESTDIR)$(statedir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(systemduserunitdir)" "$(DESTDIR)$(pkgincludedir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cupsdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(udevdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(testdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(confdir)" "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(dbussessionbusdir)" "$(DESTDIR)$(dbussystembusdir)" "$(DESTDIR)$(zshcompletiondir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(rulesdir)" "$(DESTDIR)$(statedir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(systemduserunitdir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -12474,6 +12707,7 @@ -rm -f src/shared/$(DEPDIR)/btp.Po -rm -f src/shared/$(DEPDIR)/libshared_ell_la-ad.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-att.Plo + -rm -f src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-bap.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-bass.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-btsnoop.Plo @@ -12504,6 +12738,7 @@ -rm -f src/shared/$(DEPDIR)/libshared_ell_la-vcp.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-ad.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-att.Plo + -rm -f src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-bap.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-bass.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-btsnoop.Plo @@ -12536,6 +12771,7 @@ -rm -f src/shared/$(DEPDIR)/libshared_glib_la-vcp.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-ad.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-att.Plo + -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-bap.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-bass.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-btsnoop.Plo @@ -12703,6 +12939,7 @@ -rm -f unit/$(DEPDIR)/test-hog.Po -rm -f unit/$(DEPDIR)/test-lib.Po -rm -f unit/$(DEPDIR)/test-mgmt.Po + -rm -f unit/$(DEPDIR)/test-micp.Po -rm -f unit/$(DEPDIR)/test-queue.Po -rm -f unit/$(DEPDIR)/test-ringbuf.Po -rm -f unit/$(DEPDIR)/test-sdp.Po @@ -12710,6 +12947,7 @@ -rm -f unit/$(DEPDIR)/test-textfile.Po -rm -f unit/$(DEPDIR)/test-uhid.Po -rm -f unit/$(DEPDIR)/test-uuid.Po + -rm -f unit/$(DEPDIR)/test-vcp.Po -rm -f unit/$(DEPDIR)/test_mesh_crypto-test-mesh-crypto.Po -rm -f unit/$(DEPDIR)/test_midi-test-midi.Po -rm -f unit/$(DEPDIR)/util.Po @@ -12752,7 +12990,7 @@ install-info-am: -install-man: install-man1 install-man8 +install-man: install-man1 install-man5 install-man8 install-pdf: install-pdf-am @@ -13155,6 +13393,7 @@ -rm -f src/shared/$(DEPDIR)/btp.Po -rm -f src/shared/$(DEPDIR)/libshared_ell_la-ad.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-att.Plo + -rm -f src/shared/$(DEPDIR)/libshared_ell_la-bap-debug.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-bap.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-bass.Plo -rm -f src/shared/$(DEPDIR)/libshared_ell_la-btsnoop.Plo @@ -13185,6 +13424,7 @@ -rm -f src/shared/$(DEPDIR)/libshared_ell_la-vcp.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-ad.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-att.Plo + -rm -f src/shared/$(DEPDIR)/libshared_glib_la-bap-debug.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-bap.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-bass.Plo -rm -f src/shared/$(DEPDIR)/libshared_glib_la-btsnoop.Plo @@ -13217,6 +13457,7 @@ -rm -f src/shared/$(DEPDIR)/libshared_glib_la-vcp.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-ad.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-att.Plo + -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-bap-debug.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-bap.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-bass.Plo -rm -f src/shared/$(DEPDIR)/libshared_mainloop_la-btsnoop.Plo @@ -13384,6 +13625,7 @@ -rm -f unit/$(DEPDIR)/test-hog.Po -rm -f unit/$(DEPDIR)/test-lib.Po -rm -f unit/$(DEPDIR)/test-mgmt.Po + -rm -f unit/$(DEPDIR)/test-micp.Po -rm -f unit/$(DEPDIR)/test-queue.Po -rm -f unit/$(DEPDIR)/test-ringbuf.Po -rm -f unit/$(DEPDIR)/test-sdp.Po @@ -13391,6 +13633,7 @@ -rm -f unit/$(DEPDIR)/test-textfile.Po -rm -f unit/$(DEPDIR)/test-uhid.Po -rm -f unit/$(DEPDIR)/test-uuid.Po + -rm -f unit/$(DEPDIR)/test-vcp.Po -rm -f unit/$(DEPDIR)/test_mesh_crypto-test-mesh-crypto.Po -rm -f unit/$(DEPDIR)/test_midi-test-midi.Po -rm -f unit/$(DEPDIR)/util.Po @@ -13422,7 +13665,7 @@ uninstall-systemduserunitDATA uninstall-testSCRIPTS \ uninstall-udevPROGRAMS -uninstall-man: uninstall-man1 uninstall-man8 +uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 .MAKE: all check check-am install install-am install-exec \ install-strip @@ -13445,8 +13688,8 @@ install-dbussystembusDATA install-dist_zshcompletionDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-man1 install-man8 \ - install-pdf install-pdf-am install-pkgconfigDATA \ + install-libLTLIBRARIES install-man install-man1 install-man5 \ + install-man8 install-pdf install-pdf-am install-pkgconfigDATA \ install-pkgincludeHEADERS install-pkglibexecPROGRAMS \ install-pluginLTLIBRARIES install-ps install-ps-am \ install-rulesDATA install-stateDATA install-strip \ @@ -13460,7 +13703,7 @@ uninstall-cupsPROGRAMS uninstall-dbusDATA \ uninstall-dbussessionbusDATA uninstall-dbussystembusDATA \ uninstall-dist_zshcompletionDATA uninstall-libLTLIBRARIES \ - uninstall-man uninstall-man1 uninstall-man8 \ + uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 \ uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS \ uninstall-pkglibexecPROGRAMS uninstall-pluginLTLIBRARIES \ uninstall-rulesDATA uninstall-stateDATA \ @@ -13486,6 +13729,9 @@ %.1: %.rst Makefile $(RST2MAN_PROCESS) +%.5: %.rst Makefile + $(RST2MAN_PROCESS) + %.8: %.rst Makefile $(RST2MAN_PROCESS) diff -Nru bluez-5.70/Makefile.tools bluez-5.71/Makefile.tools --- bluez-5.70/Makefile.tools 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/Makefile.tools 2023-12-14 05:40:27.000000000 +0800 @@ -349,7 +349,11 @@ if MANPAGES man_MANS += tools/rctest.1 tools/l2ping.1 tools/btattach.1 tools/isotest.1 \ tools/btmgmt.1 client/bluetoothctl-mgmt.1 \ - client/bluetoothctl-monitor.1 + client/bluetoothctl-monitor.1 client/bluetoothctl-admin.1 \ + client/bluetoothctl-advertise.1 client/bluetoothctl-endpoint.1 \ + client/bluetoothctl-gatt.1 client/bluetoothctl-player.1 \ + client/bluetoothctl-scan.1 client/bluetoothctl-transport.1 + endif if MESH @@ -472,7 +476,14 @@ tools/rctest.1 tools/l2ping.1 tools/btattach.1 \ tools/bdaddr.1 tools/isotest.1 tools/btmgmt.1 \ client/bluetoothctl-mgmt.1 \ - client/bluetoothctl-monitor.1 + client/bluetoothctl-monitor.1 \ + client/bluetoothctl-admin.1 \ + client/bluetoothctl-advertise.1 \ + client/bluetoothctl-endpoint.1 \ + client/bluetoothctl-gatt.1 \ + client/bluetoothctl-player.1 \ + client/bluetoothctl-scan.1 \ + client/bluetoothctl-transport.1 if HID2HCI udevdir = $(UDEV_DIR) diff -Nru bluez-5.70/mesh/mesh-io-generic.c bluez-5.71/mesh/mesh-io-generic.c --- bluez-5.70/mesh/mesh-io-generic.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/mesh/mesh-io-generic.c 2023-12-14 05:40:27.000000000 +0800 @@ -781,7 +781,7 @@ bool already_scanning; bool active = false; - already_scanning = !l_queue_isempty(io->rx_regs); + already_scanning = l_queue_length(io->rx_regs) > 1; /* Look for any AD types requiring Active Scanning */ if (l_queue_find(io->rx_regs, find_active, NULL)) diff -Nru bluez-5.70/monitor/att.c bluez-5.71/monitor/att.c --- bluez-5.70/monitor/att.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/monitor/att.c 2023-12-14 05:40:27.000000000 +0800 @@ -675,8 +675,15 @@ return true; } +static void print_ltv(const char *str, void *user_data) +{ + const char *label = user_data; + + print_field("%s: %s", label, str); +} + static bool print_ase_lv(const struct l2cap_frame *frame, const char *label, - struct packet_ltv_decoder *decoder, size_t decoder_len) + struct util_ltv_debugger *decoder, size_t decoder_len) { struct bt_hci_lv_data *lv; @@ -691,13 +698,14 @@ return false; } - packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len); + util_debug_ltv(lv->data, lv->len, decoder, decoder_len, print_ltv, + (void *) label); return true; } static bool print_ase_cc(const struct l2cap_frame *frame, const char *label, - struct packet_ltv_decoder *decoder, size_t decoder_len) + struct util_ltv_debugger *decoder, size_t decoder_len) { return print_ase_lv(frame, label, decoder, decoder_len); } @@ -744,7 +752,8 @@ print_hex_field(" Data", frame->data, frame->size); } -static void ase_decode_preferred_context(const uint8_t *data, uint8_t len) +static void ase_debug_preferred_context(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; @@ -753,7 +762,8 @@ print_context(&frame, " Preferred Context"); } -static void ase_decode_context(const uint8_t *data, uint8_t len) +static void ase_debug_context(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; @@ -762,7 +772,8 @@ print_context(&frame, " Context"); } -static void ase_decode_program_info(const uint8_t *data, uint8_t len) +static void ase_debug_program_info(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; const char *str; @@ -782,7 +793,8 @@ print_hex_field(" Data", frame.data, frame.size); } -static void ase_decode_language(const uint8_t *data, uint8_t len) +static void ase_debug_language(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint32_t value; @@ -801,16 +813,17 @@ print_hex_field(" Data", frame.data, frame.size); } -struct packet_ltv_decoder ase_metadata_table[] = { - LTV_DEC(0x01, ase_decode_preferred_context), - LTV_DEC(0x02, ase_decode_context), - LTV_DEC(0x03, ase_decode_program_info), - LTV_DEC(0x04, ase_decode_language) +struct util_ltv_debugger ase_metadata_table[] = { + UTIL_LTV_DEBUG(0x01, ase_debug_preferred_context), + UTIL_LTV_DEBUG(0x02, ase_debug_context), + UTIL_LTV_DEBUG(0x03, ase_debug_program_info), + UTIL_LTV_DEBUG(0x04, ase_debug_language) }; static bool print_ase_metadata(const struct l2cap_frame *frame) { - return print_ase_lv(frame, " Metadata", NULL, 0); + return print_ase_lv(frame, " Metadata", ase_metadata_table, + ARRAY_SIZE(ase_metadata_table)); } static const struct bitfield_data pac_freq_table[] = { @@ -833,7 +846,8 @@ { } }; -static void pac_decode_freq(const uint8_t *data, uint8_t len) +static void pac_decode_freq(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint16_t value; @@ -870,7 +884,8 @@ { } }; -static void pac_decode_duration(const uint8_t *data, uint8_t len) +static void pac_decode_duration(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint8_t value; @@ -907,7 +922,8 @@ { } }; -static void pac_decode_channels(const uint8_t *data, uint8_t len) +static void pac_decode_channels(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint8_t value; @@ -932,7 +948,8 @@ print_hex_field(" Data", frame.data, frame.size); } -static void pac_decode_frame_length(const uint8_t *data, uint8_t len) +static void pac_decode_frame_length(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint16_t min, max; @@ -957,7 +974,8 @@ print_hex_field(" Data", frame.data, frame.size); } -static void pac_decode_sdu(const uint8_t *data, uint8_t len) +static void pac_decode_sdu(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint8_t value; @@ -976,12 +994,12 @@ print_hex_field(" Data", frame.data, frame.size); } -struct packet_ltv_decoder pac_cap_table[] = { - LTV_DEC(0x01, pac_decode_freq), - LTV_DEC(0x02, pac_decode_duration), - LTV_DEC(0x03, pac_decode_channels), - LTV_DEC(0x04, pac_decode_frame_length), - LTV_DEC(0x05, pac_decode_sdu) +struct util_ltv_debugger pac_cap_table[] = { + UTIL_LTV_DEBUG(0x01, pac_decode_freq), + UTIL_LTV_DEBUG(0x02, pac_decode_duration), + UTIL_LTV_DEBUG(0x03, pac_decode_channels), + UTIL_LTV_DEBUG(0x04, pac_decode_frame_length), + UTIL_LTV_DEBUG(0x05, pac_decode_sdu) }; static void print_pac(const struct l2cap_frame *frame) @@ -1117,7 +1135,8 @@ return true; } -static void ase_decode_freq(const uint8_t *data, uint8_t len) +static void ase_debug_freq(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint8_t value; @@ -1179,7 +1198,8 @@ print_hex_field(" Data", frame.data, frame.size); } -static void ase_decode_duration(const uint8_t *data, uint8_t len) +static void ase_debug_duration(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint8_t value; @@ -1266,7 +1286,8 @@ print_hex_field(" Data", frame->data, frame->size); } -static void ase_decode_location(const uint8_t *data, uint8_t len) +static void ase_debug_location(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; @@ -1275,7 +1296,8 @@ print_location(&frame); } -static void ase_decode_frame_length(const uint8_t *data, uint8_t len) +static void ase_debug_frame_length(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint16_t value; @@ -1294,7 +1316,8 @@ print_hex_field(" Data", frame.data, frame.size); } -static void ase_decode_blocks(const uint8_t *data, uint8_t len) +static void ase_debug_blocks(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) { struct l2cap_frame frame; uint8_t value; @@ -1313,12 +1336,12 @@ print_hex_field(" Data", frame.data, frame.size); } -struct packet_ltv_decoder ase_cc_table[] = { - LTV_DEC(0x01, ase_decode_freq), - LTV_DEC(0x02, ase_decode_duration), - LTV_DEC(0x03, ase_decode_location), - LTV_DEC(0x04, ase_decode_frame_length), - LTV_DEC(0x05, ase_decode_blocks) +struct util_ltv_debugger ase_cc_table[] = { + UTIL_LTV_DEBUG(0x01, ase_debug_freq), + UTIL_LTV_DEBUG(0x02, ase_debug_duration), + UTIL_LTV_DEBUG(0x03, ase_debug_location), + UTIL_LTV_DEBUG(0x04, ase_debug_frame_length), + UTIL_LTV_DEBUG(0x05, ase_debug_blocks) }; static void print_ase_config(const struct l2cap_frame *frame) @@ -2745,8 +2768,9 @@ }; static bool print_subgroup_lv(const struct l2cap_frame *frame, - const char *label, struct packet_ltv_decoder *decoder, - size_t decoder_len) + const char *label, + struct util_ltv_debugger *debugger, + size_t debugger_len) { struct bt_hci_lv_data *lv; @@ -2761,7 +2785,8 @@ return false; } - packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len); + util_debug_ltv(lv->data, lv->len, debugger, debugger_len, + print_ltv, (void *)label); return true; } @@ -3170,6 +3195,140 @@ print_bcast_audio_scan_cp_cmd(frame); } +static const struct bitfield_data gmap_role_table[] = { + { 0, "Unicast Game Gateway (UGG) (0x0001)" }, + { 1, "Unicast Game Terminal (UGT) (0x0002)" }, + { 2, "Broadcast Game Sender (BGS) (0x0004)" }, + { 3, "Broadcast Game Receiver (BGR) (0x0008)" }, + { } +}; + +static void gmap_role_read(const struct l2cap_frame *frame) +{ + uint8_t role; + uint8_t mask; + + if (!l2cap_frame_get_u8((void *)frame, &role)) { + print_text(COLOR_ERROR, " invalid size"); + return; + } + + print_field(" Role: 0x%2.2x", role); + + mask = print_bitfield(6, role, gmap_role_table); + if (mask) + print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)", + mask); +} + +static const struct bitfield_data ugg_features_table[] = { + { 0, "UGG Multiplex (0x0001)" }, + { 1, "UGG 96 kbps Source (0x0002)" }, + { 2, "UGG Multilink (0x0004)" }, + { } +}; + +static void ugg_features_read(const struct l2cap_frame *frame) +{ + uint8_t value; + uint8_t mask; + + if (!l2cap_frame_get_u8((void *)frame, &value)) { + print_text(COLOR_ERROR, " invalid size"); + return; + } + + print_field(" Value: 0x%2.2x", value); + + mask = print_bitfield(6, value, ugg_features_table); + if (mask) + print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)", + mask); +} + +static const struct bitfield_data ugt_features_table[] = { + { 0, "UGT Source (0x0001)" }, + { 1, "UGT 80 kbps Source (0x0002)" }, + { 2, "UGT Sink (0x0004)" }, + { 3, "UGT 64 kbps Sink (0x0008)" }, + { 4, "UGT Multiplex (0x0010)" }, + { 5, "UGT Multisink (0x0020)" }, + { 6, "UGT Multisource (0x0040)" }, + { } +}; + +static void ugt_features_read(const struct l2cap_frame *frame) +{ + uint8_t value; + uint8_t mask; + + if (!l2cap_frame_get_u8((void *)frame, &value)) { + print_text(COLOR_ERROR, " invalid size"); + return; + } + + print_field(" Value: 0x%2.2x", value); + + mask = print_bitfield(6, value, ugt_features_table); + if (mask) + print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)", + mask); +} + +static const struct bitfield_data bgs_features_table[] = { + { 0, "BGS 96 kbps (0x0001)" }, + { } +}; + +static void bgs_features_read(const struct l2cap_frame *frame) +{ + uint8_t value; + uint8_t mask; + + if (!l2cap_frame_get_u8((void *)frame, &value)) { + print_text(COLOR_ERROR, " invalid size"); + return; + } + + print_field(" Value: 0x%2.2x", value); + + mask = print_bitfield(6, value, bgs_features_table); + if (mask) + print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)", + mask); +} + +static const struct bitfield_data bgr_features_table[] = { + { 0, "BGR Multisink (0x0001)" }, + { 1, "BGR Multiplex (0x0002)" }, + { } +}; + +static void bgr_features_read(const struct l2cap_frame *frame) +{ + uint8_t value; + uint8_t mask; + + if (!l2cap_frame_get_u8((void *)frame, &value)) { + print_text(COLOR_ERROR, " invalid size"); + return; + } + + print_field(" Value: 0x%2.2x", value); + + mask = print_bitfield(6, value, bgr_features_table); + if (mask) + print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)", + mask); +} + +#define GMAS \ + GATT_HANDLER(0x2c00, gmap_role_read, NULL, NULL), \ + GATT_HANDLER(0x2c01, ugg_features_read, NULL, NULL), \ + GATT_HANDLER(0x2c02, ugt_features_read, NULL, NULL), \ + GATT_HANDLER(0x2c02, bgs_features_read, NULL, NULL), \ + GATT_HANDLER(0x2c03, bgr_features_read, NULL, NULL) + #define GATT_HANDLER(_uuid, _read, _write, _notify) \ { \ .uuid = { \ @@ -3230,6 +3389,7 @@ GATT_HANDLER(0x2bc7, NULL, bcast_audio_scan_cp_write, NULL), GATT_HANDLER(0x2bc8, bcast_recv_state_read, NULL, bcast_recv_state_notify), + GMAS }; static struct gatt_handler *get_handler_uuid(const bt_uuid_t *uuid) diff -Nru bluez-5.70/monitor/btmon.1 bluez-5.71/monitor/btmon.1 --- bluez-5.70/monitor/btmon.1 2023-09-29 04:09:17.000000000 +0800 +++ bluez-5.71/monitor/btmon.1 2023-12-14 05:58:03.000000000 +0800 @@ -1,3 +1,4 @@ +'\" t .\" Man page generated from reStructuredText. . . diff -Nru bluez-5.70/monitor/packet.c bluez-5.71/monitor/packet.c --- bluez-5.70/monitor/packet.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/monitor/packet.c 2023-12-14 05:40:27.000000000 +0800 @@ -35,6 +35,7 @@ #include "src/shared/util.h" #include "src/shared/btsnoop.h" #include "src/shared/queue.h" +#include "src/shared/bap-debug.h" #include "display.h" #include "bt.h" #include "ll.h" @@ -2451,6 +2452,9 @@ case 0x0c: str = "Bluetooth 5.3"; break; + case 0x0d: + str = "Bluetooth 5.4"; + break; default: str = "Reserved"; break; @@ -3402,86 +3406,11 @@ } } -static void *iov_pull(struct iovec *iov, size_t len) +static void print_ltv(const char *str, void *user_data) { - void *data; - - if (iov->iov_len < len) - return NULL; - - data = iov->iov_base; - iov->iov_base += len; - iov->iov_len -= len; - - return data; -} - -static struct packet_ltv_decoder* -get_ltv_decoder(struct packet_ltv_decoder *decoder, size_t num, uint8_t type) -{ - size_t i; - - if (!decoder || !num) - return NULL; - - for (i = 0; i < num; i++) { - struct packet_ltv_decoder *dec = &decoder[i]; - - if (dec->type == type) - return dec; - } - - return NULL; -} - -static void print_ltv(const char *label, const uint8_t *data, uint8_t len, - struct packet_ltv_decoder *decoder, size_t num) -{ - struct iovec iov; - int i; - - iov.iov_base = (void *) data; - iov.iov_len = len; + const char *label = user_data; - for (i = 0; iov.iov_len; i++) { - uint8_t l, t, *v; - struct packet_ltv_decoder *dec; - - l = get_u8(iov_pull(&iov, sizeof(l))); - if (!l) { - print_field("%s #%d: len 0x%02x", label, i, l); - break; - } - - v = iov_pull(&iov, sizeof(*v)); - if (!v) - break; - - t = get_u8(v); - - print_field("%s #%d: len 0x%02x type 0x%02x", label, i, l, t); - - l -= 1; - - v = iov_pull(&iov, l); - if (!v) - break; - - dec = get_ltv_decoder(decoder, num, t); - if (dec) - dec->func(v, l); - else - print_hex_field(label, v, l); - } - - if (iov.iov_len) - print_hex_field(label, iov.iov_base, iov.iov_len); -} - -void packet_print_ltv(const char *label, const uint8_t *data, uint8_t len, - struct packet_ltv_decoder *decoder, size_t decoder_len) -{ - print_ltv(label, data, len, decoder, decoder_len); + print_field("%s: %s", label, str); } static void print_base_annoucement(const uint8_t *data, uint8_t data_len) @@ -3493,7 +3422,7 @@ iov.iov_base = (void *) data; iov.iov_len = data_len; - base_data = iov_pull(&iov, sizeof(*base_data)); + base_data = util_iov_pull_mem(&iov, sizeof(*base_data)); if (!base_data) goto done; @@ -3507,10 +3436,11 @@ struct bt_hci_lv_data *codec_cfg; struct bt_hci_lv_data *metadata; uint8_t j; + const char *label; print_field(" Subgroup #%u:", i); - subgroup = iov_pull(&iov, sizeof(*subgroup)); + subgroup = util_iov_pull_mem(&iov, sizeof(*subgroup)); if (!subgroup) goto done; @@ -3527,26 +3457,31 @@ subgroup->codec.vid); } - codec_cfg = iov_pull(&iov, sizeof(*codec_cfg)); + codec_cfg = util_iov_pull_mem(&iov, sizeof(*codec_cfg)); if (!codec_cfg) goto done; - if (!iov_pull(&iov, codec_cfg->len)) + if (!util_iov_pull_mem(&iov, codec_cfg->len)) goto done; - print_ltv(" Codec Specific Configuration", - codec_cfg->data, codec_cfg->len, - NULL, 0); + label = " Codec Specific Configuration"; + + bt_bap_debug_config(codec_cfg->data, codec_cfg->len, + print_ltv, (void *)label); - metadata = iov_pull(&iov, sizeof(*metadata)); + metadata = util_iov_pull_mem(&iov, sizeof(*metadata)); if (!metadata) goto done; - if (!iov_pull(&iov, metadata->len)) + if (!util_iov_pull(&iov, metadata->len)) goto done; - print_ltv(" Metadata", metadata->data, metadata->len, - NULL, 0); + label = " Metadata"; + + bt_bap_debug_metadata(metadata->data, metadata->len, + print_ltv, (void *)label); + + label = " Codec Specific Configuration"; /* Level 3 - BIS(s)*/ for (j = 0; j < subgroup->num_bis; j++) { @@ -3554,21 +3489,21 @@ print_field(" BIS #%u:", j); - bis = iov_pull(&iov, sizeof(*bis)); + bis = util_iov_pull_mem(&iov, sizeof(*bis)); if (!bis) goto done; print_field(" Index: %u", bis->index); - codec_cfg = iov_pull(&iov, sizeof(*codec_cfg)); + codec_cfg = util_iov_pull_mem(&iov, sizeof(*codec_cfg)); if (!codec_cfg) goto done; - if (!iov_pull(&iov, codec_cfg->len)) + if (!util_iov_pull(&iov, codec_cfg->len)) goto done; - print_hex_field(" Codec Specific Configuration", - codec_cfg->data, codec_cfg->len); + bt_bap_debug_config(codec_cfg->data, codec_cfg->len, + print_ltv, (void *)label); } } @@ -10497,7 +10432,7 @@ const struct bt_hci_evt_num_completed_packets *evt = data; int i; - iov_pull(&iov, 1); + util_iov_pull(&iov, 1); print_field("Num handles: %d", evt->num_handles); diff -Nru bluez-5.70/monitor/packet.h bluez-5.71/monitor/packet.h --- bluez-5.70/monitor/packet.h 2023-08-25 01:02:39.000000000 +0800 +++ bluez-5.71/monitor/packet.h 2023-12-14 05:40:27.000000000 +0800 @@ -84,20 +84,6 @@ void packet_print_io_authentication(uint8_t authentication); void packet_print_codec_id(const char *label, uint8_t codec); -#define LTV_DEC(_type, _func) \ -{ \ - .type = _type, \ - .func = _func, \ -} - -struct packet_ltv_decoder { - uint8_t type; - void (*func)(const uint8_t *data, uint8_t len); -}; - -void packet_print_ltv(const char *label, const uint8_t *data, uint8_t len, - struct packet_ltv_decoder *decoder, size_t num); - void packet_control(struct timeval *tv, struct ucred *cred, uint16_t index, uint16_t opcode, const void *data, uint16_t size); diff -Nru bluez-5.70/profiles/audio/bap.c bluez-5.71/profiles/audio/bap.c --- bluez-5.70/profiles/audio/bap.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/profiles/audio/bap.c 2023-12-14 05:40:27.000000000 +0800 @@ -263,6 +263,88 @@ return TRUE; } +static gboolean get_locations(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct bap_ep *ep = data; + uint32_t locations = bt_bap_pac_get_locations(ep->rpac); + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &locations); + + return TRUE; +} + +static gboolean get_supported_context(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct bap_ep *ep = data; + uint16_t context = bt_bap_pac_get_supported_context(ep->rpac); + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &context); + + return TRUE; +} + +static gboolean get_context(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct bap_ep *ep = data; + uint16_t context = bt_bap_pac_get_context(ep->rpac); + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &context); + + return TRUE; +} + +static gboolean qos_exists(const GDBusPropertyTable *property, void *data) +{ + struct bap_ep *ep = data; + struct bt_bap_pac_qos *qos; + + qos = bt_bap_pac_get_qos(ep->rpac); + if (!qos) + return FALSE; + + return TRUE; +} + +static gboolean get_qos(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct bap_ep *ep = data; + struct bt_bap_pac_qos *qos; + DBusMessageIter dict; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + qos = bt_bap_pac_get_qos(ep->rpac); + if (!qos) + return FALSE; + + dict_append_entry(&dict, "Framing", DBUS_TYPE_BYTE, &qos->framing); + dict_append_entry(&dict, "PHY", DBUS_TYPE_BYTE, &qos->phy); + dict_append_entry(&dict, "Retransmissions", DBUS_TYPE_BYTE, &qos->rtn); + dict_append_entry(&dict, "MaximumLatency", DBUS_TYPE_UINT16, + &qos->latency); + dict_append_entry(&dict, "MimimumDelay", DBUS_TYPE_UINT32, + &qos->pd_min); + dict_append_entry(&dict, "MaximumDelay", DBUS_TYPE_UINT32, + &qos->pd_max); + dict_append_entry(&dict, "PreferredMimimumDelay", DBUS_TYPE_UINT32, + &qos->ppd_min); + dict_append_entry(&dict, "PreferredMaximumDelay", DBUS_TYPE_UINT32, + &qos->ppd_max); + + dbus_message_iter_close_container(iter, &dict); + + return TRUE; +} + static const GDBusPropertyTable ep_properties[] = { { "UUID", "s", get_uuid, NULL, NULL, G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, @@ -272,22 +354,28 @@ G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, { "Device", "o", get_device, NULL, NULL, G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, + { "Locations", "u", get_locations, NULL, NULL, + G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, + { "SupportedContext", "q", get_supported_context, NULL, NULL, + G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, + { "Context", "q", get_context, NULL, NULL, + G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, + { "QoS", "a{sv}", get_qos, NULL, qos_exists, + G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, { } }; -static int parse_array(DBusMessageIter *iter, struct iovec **iov) +static int parse_array(DBusMessageIter *iter, struct iovec *iov) { DBusMessageIter array; if (!iov) return 0; - if (!(*iov)) - *iov = new0(struct iovec, 1); - dbus_message_iter_recurse(iter, &array); - dbus_message_iter_get_fixed_array(&array, &(*iov)->iov_base, - (int *)&(*iov)->iov_len); + dbus_message_iter_get_fixed_array(&array, &iov->iov_base, + (int *)&iov->iov_len); + return 0; } @@ -388,192 +476,240 @@ return true; } -static int parse_properties(DBusMessageIter *props, struct iovec **caps, - struct iovec **metadata, struct iovec **base, +static int parse_io_qos(const char *key, int var, DBusMessageIter *iter, + struct bt_bap_io_qos *qos) +{ + if (!strcasecmp(key, "Interval")) { + if (var != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->interval); + } else if (!strcasecmp(key, "PHY")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->phy); + } else if (!strcasecmp(key, "SDU")) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->sdu); + } else if (!strcasecmp(key, "Retransmissions")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->rtn); + } else if (!strcasecmp(key, "Latency")) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->latency); + } + + return 0; +} + +static int parse_ucast_qos(const char *key, int var, DBusMessageIter *iter, struct bt_bap_qos *qos) { - const char *key; - struct bt_bap_io_qos io_qos; - uint8_t framing = 0; - bool broadcast = false; + if (!strcasecmp(key, "CIG")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->ucast.cig_id); + } else if (!strcasecmp(key, "CIS")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->ucast.cis_id); + } else if (!strcasecmp(key, "Framing")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->ucast.framing); + } else if (!strcasecmp(key, "PresentationDelay")) { + if (var != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->ucast.delay); + } else if (!strcasecmp(key, "TargetLatency")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; - memset(&io_qos, 0, sizeof(io_qos)); - while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter value, entry; - int var; + dbus_message_iter_get_basic(iter, &qos->ucast.target_latency); + } else { + int err; - dbus_message_iter_recurse(props, &entry); - dbus_message_iter_get_basic(&entry, &key); + err = parse_io_qos(key, var, iter, &qos->ucast.io_qos); + if (err) + return err; + } - dbus_message_iter_next(&entry); - dbus_message_iter_recurse(&entry, &value); + return 0; +} - var = dbus_message_iter_get_arg_type(&value); +static int parse_bcast_qos(const char *key, int var, DBusMessageIter *iter, + struct bt_bap_qos *qos) +{ + if (!strcasecmp(key, "Encryption")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.encryption); + } else if (!strcasecmp(key, "Options")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.options); + } else if (!strcasecmp(key, "Skip")) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.skip); + } else if (!strcasecmp(key, "SyncTimeout")) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.sync_timeout); + } else if (!strcasecmp(key, "SyncType")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.sync_cte_type); + } else if (!strcasecmp(key, "SyncFactor")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.sync_factor); + } else if (!strcasecmp(key, "MSE")) { + if (var != DBUS_TYPE_BYTE) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.mse); + } else if (!strcasecmp(key, "Timeout")) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + + dbus_message_iter_get_basic(iter, &qos->bcast.timeout); + } else if (!strcasecmp(key, "BCode")) { + struct iovec iov; - if (!strcasecmp(key, "Capabilities")) { - if (var != DBUS_TYPE_ARRAY) - goto fail; + if (var != DBUS_TYPE_ARRAY) + return -EINVAL; - if (parse_array(&value, caps)) - goto fail; - } else if (!strcasecmp(key, "Metadata")) { - if (var != DBUS_TYPE_ARRAY) - goto fail; + parse_array(iter, &iov); - if (parse_array(&value, metadata)) - goto fail; - } else if (!strcasecmp(key, "CIG")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + util_iov_free(qos->bcast.bcode, 1); + qos->bcast.bcode = util_iov_dup(&iov, 1); + } else { + int err; - dbus_message_iter_get_basic(&value, &qos->ucast.cig_id); - } else if (!strcasecmp(key, "BIG")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + err = parse_io_qos(key, var, iter, &qos->bcast.io_qos); + if (err) + return err; + } - dbus_message_iter_get_basic(&value, &qos->bcast.big); - } else if (!strcasecmp(key, "CIS")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + return 0; +} - dbus_message_iter_get_basic(&value, &qos->ucast.cis_id); - } else if (!strcasecmp(key, "BIS")) { - if (var != DBUS_TYPE_BYTE) - goto fail; +static int parse_qos(DBusMessageIter *iter, struct bt_bap_qos *qos, + struct iovec **base) +{ + DBusMessageIter array; + const char *key; + int (*parser)(const char *key, int var, DBusMessageIter *iter, + struct bt_bap_qos *qos); - dbus_message_iter_get_basic(&value, &qos->bcast.bis); - } else if (!strcasecmp(key, "Interval")) { - if (var != DBUS_TYPE_UINT32) - goto fail; + if (*base) + parser = parse_bcast_qos; + else + parser = parse_ucast_qos; - dbus_message_iter_get_basic(&value, &io_qos.interval); - } else if (!strcasecmp(key, "Framing")) { - dbus_bool_t val; + dbus_message_iter_recurse(iter, &array); - if (var != DBUS_TYPE_BOOLEAN) - goto fail; + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter value, entry; + int var, err; - dbus_message_iter_get_basic(&value, &val); + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &key); - framing = val; - } else if (!strcasecmp(key, "PHY")) { - const char *str; + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &value); - if (var != DBUS_TYPE_STRING) - goto fail; + var = dbus_message_iter_get_arg_type(&value); - dbus_message_iter_get_basic(&value, &str); + err = parser(key, var, &value, qos); + if (err) { + DBG("Failed parsing %s", key); + return err; + } - if (!strcasecmp(str, "1M")) - io_qos.phy = 0x01; - else if (!strcasecmp(str, "2M")) - io_qos.phy = 0x02; - else - goto fail; - } else if (!strcasecmp(key, "SDU")) { - if (var != DBUS_TYPE_UINT16) - goto fail; + dbus_message_iter_next(&array); + } - dbus_message_iter_get_basic(&value, &io_qos.sdu); - } else if (!strcasecmp(key, "Retransmissions")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + return 0; +} - dbus_message_iter_get_basic(&value, &io_qos.rtn); - } else if (!strcasecmp(key, "Latency")) { - if (var != DBUS_TYPE_UINT16) - goto fail; +static int parse_configuration(DBusMessageIter *props, struct iovec **caps, + struct iovec **metadata, struct iovec **base, + struct bt_bap_qos *qos) +{ + const char *key; + struct iovec iov; - dbus_message_iter_get_basic(&value, &io_qos.latency); - } else if (!strcasecmp(key, "Delay")) { - if (var != DBUS_TYPE_UINT32) - goto fail; + memset(&iov, 0, sizeof(iov)); - dbus_message_iter_get_basic(&value, &qos->ucast.delay); - } else if (!strcasecmp(key, "TargetLatency")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter value, entry; + int var; - dbus_message_iter_get_basic(&value, - &qos->ucast.target_latency); - } else if (!strcasecmp(key, "Encryption")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + dbus_message_iter_recurse(props, &entry); + dbus_message_iter_get_basic(&entry, &key); - dbus_message_iter_get_basic(&value, - &qos->bcast.encryption); - broadcast = true; - } else if (!strcasecmp(key, "Options")) { - if (var != DBUS_TYPE_BYTE) - goto fail; + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &value); - dbus_message_iter_get_basic(&value, - &qos->bcast.options); - } else if (!strcasecmp(key, "Skip")) { - if (var != DBUS_TYPE_UINT16) - goto fail; + var = dbus_message_iter_get_arg_type(&value); - dbus_message_iter_get_basic(&value, - &qos->bcast.skip); - } else if (!strcasecmp(key, "SyncTimeout")) { - if (var != DBUS_TYPE_UINT16) + if (!strcasecmp(key, "Capabilities")) { + if (var != DBUS_TYPE_ARRAY) goto fail; - dbus_message_iter_get_basic(&value, - &qos->bcast.sync_timeout); - } else if (!strcasecmp(key, "SyncCteType")) { - if (var != DBUS_TYPE_BYTE) + if (parse_array(&value, &iov)) goto fail; - dbus_message_iter_get_basic(&value, - &qos->bcast.sync_cte_type); - - } else if (!strcasecmp(key, "SyncInterval")) { - if (var != DBUS_TYPE_BYTE) + util_iov_free(*caps, 1); + *caps = util_iov_dup(&iov, 1); + } else if (!strcasecmp(key, "Metadata")) { + if (var != DBUS_TYPE_ARRAY) goto fail; - dbus_message_iter_get_basic(&value, - &qos->bcast.sync_interval); - } else if (!strcasecmp(key, "MSE")) { - if (var != DBUS_TYPE_BYTE) + if (parse_array(&value, &iov)) goto fail; - dbus_message_iter_get_basic(&value, - &qos->bcast.mse); - } else if (!strcasecmp(key, "Timeout")) { - if (var != DBUS_TYPE_UINT16) + util_iov_free(*metadata, 1); + *metadata = util_iov_dup(&iov, 1); + } else if (!strcasecmp(key, "QoS")) { + if (var != DBUS_TYPE_ARRAY) goto fail; - dbus_message_iter_get_basic(&value, - &qos->bcast.timeout); - } else if (!strcasecmp(key, "BroadcastCode")) { - if (var != DBUS_TYPE_ARRAY) + if (parse_qos(&value, qos, base)) goto fail; - parse_array(&value, &qos->bcast.bcode); } dbus_message_iter_next(props); } - if (broadcast) { + if (*base) { uint32_t presDelay; uint8_t numSubgroups, numBis; struct bt_bap_codec codec; - memcpy(&qos->bcast.io_qos, &io_qos, sizeof(io_qos)); - qos->bcast.framing = framing; - - if (!base) - return 0; - if (!(*base)) - *base = new0(struct iovec, 1); util_iov_memcpy(*base, (*caps)->iov_base, (*caps)->iov_len); parse_base((*caps)->iov_base, (*caps)->iov_len, bap_debug, &presDelay, &numSubgroups, &numBis, &codec, caps, NULL); - } else { - memcpy(&qos->ucast.io_qos, &io_qos, sizeof(io_qos)); - qos->ucast.framing = framing; } return 0; @@ -695,9 +831,9 @@ ep->qos.ucast.cis_id = BT_ISO_QOS_CIS_UNSET; } - if (parse_properties(&props, &ep->caps, &ep->metadata, + if (parse_configuration(&props, &ep->caps, &ep->metadata, &ep->base, &ep->qos) < 0) { - DBG("Unable to parse properties"); + DBG("Unable to parse configuration"); return btd_error_invalid_args(msg); } @@ -744,7 +880,7 @@ { bap_qos->bcast.big = qos->bcast.big; bap_qos->bcast.bis = qos->bcast.bis; - bap_qos->bcast.sync_interval = qos->bcast.sync_interval; + bap_qos->bcast.sync_factor = qos->bcast.sync_factor; bap_qos->bcast.packing = qos->bcast.packing; bap_qos->bcast.framing = qos->bcast.framing; bap_qos->bcast.encryption = qos->bcast.encryption; @@ -845,7 +981,7 @@ GError *err = NULL; if (!bt_io_bcast_accept(io, iso_bcast_confirm_cb, - user_data, NULL, &err)) { + user_data, NULL, &err, BT_IO_OPT_INVALID)) { error("bt_io_bcast_accept: %s", err->message); g_error_free(err); g_io_channel_shutdown(io, TRUE, NULL); @@ -864,7 +1000,7 @@ static const GDBusMethodTable ep_methods[] = { { GDBUS_EXPERIMENTAL_ASYNC_METHOD("SetConfiguration", GDBUS_ARGS({ "endpoint", "o" }, - { "properties", "a{sv}" } ), + { "Configuration", "a{sv}" } ), NULL, set_configuration) }, { }, }; @@ -914,7 +1050,7 @@ const char *suffix; struct match_ep match = { lpac, rpac }; - switch (bt_bap_pac_get_type(rpac)) { + switch (bt_bap_pac_get_type(lpac)) { case BT_BAP_BCAST_SOURCE: case BT_BAP_BCAST_SINK: queue = data->bcast; @@ -937,14 +1073,16 @@ if (device) ep->data->device = device; - switch (bt_bap_pac_get_type(rpac)) { - case BT_BAP_BCAST_SINK: + switch (bt_bap_pac_get_type(lpac)) { + case BT_BAP_BCAST_SOURCE: err = asprintf(&ep->path, "%s/pac_%s%d", - adapter_get_path(adapter), suffix, i); + adapter_get_path(adapter), suffix, i); + ep->base = new0(struct iovec, 1); break; - case BT_BAP_BCAST_SOURCE: + case BT_BAP_BCAST_SINK: err = asprintf(&ep->path, "%s/pac_%s%d", device_get_path(device), suffix, i); + ep->base = new0(struct iovec, 1); break; } @@ -963,7 +1101,15 @@ ep_free(ep); return NULL; } - bt_bap_pac_set_user_data(rpac, ep->path); + + /* + * The broadcast source local endpoint has only lpac and broadcast + * sink local endpoint has a rpac and a lpac + */ + if (rpac) + bt_bap_pac_set_user_data(rpac, ep->path); + else + bt_bap_pac_set_user_data(lpac, ep->path); DBG("ep %p lpac %p rpac %p path %s", ep, ep->lpac, ep->rpac, ep->path); @@ -1076,6 +1222,7 @@ goto done; } + util_iov_free(ep->caps, 1); ep->caps = util_iov_dup(caps, 1); if (metadata && metadata->iov_base && metadata->iov_len) { @@ -1173,6 +1320,32 @@ return NULL; } +static void iso_connect_bcast_cb(GIOChannel *chan, GError *err, + gpointer user_data) +{ + struct bt_bap_stream *stream = user_data; + int fd; + + if (err) { + error("%s", err->message); + bt_bap_stream_set_io(stream, -1); + return; + } + + DBG("ISO connected"); + + fd = g_io_channel_unix_get_fd(chan); + + if (bt_bap_stream_set_io(stream, fd)) { + bt_bap_stream_start(stream, NULL, NULL); + g_io_channel_set_close_on_unref(chan, FALSE); + return; + } + + error("Unable to set IO"); + bt_bap_stream_set_io(stream, -1); +} + static void iso_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct bt_bap_stream *stream = user_data; @@ -1421,6 +1594,17 @@ return FALSE; } +static void bap_connect_bcast_io_cb(GIOChannel *chan, GError *err, + gpointer user_data) +{ + struct bap_ep *ep = user_data; + + if (!ep->stream) + return; + + iso_connect_bcast_cb(chan, err, ep->stream); +} + static void bap_connect_io_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct bap_ep *ep = user_data; @@ -1522,7 +1706,7 @@ DBG("ep %p stream %p ", ep, stream); ba2str(btd_adapter_get_address(adapter), addr); - io = bt_io_connect(bap_connect_io_cb, ep, NULL, &err, + io = bt_io_connect(bap_connect_bcast_io_cb, ep, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, btd_adapter_get_address(adapter), BT_IO_OPT_DEST_BDADDR, @@ -1566,9 +1750,9 @@ BT_IO_OPT_SOURCE_BDADDR, btd_adapter_get_address(adapter), BT_IO_OPT_DEST_BDADDR, - device_get_address(data->device), + BDADDR_ANY, BT_IO_OPT_DEST_TYPE, - device_get_le_address_type(data->device), + BDADDR_LE_PUBLIC, BT_IO_OPT_MODE, BT_IO_MODE_ISO, BT_IO_OPT_QOS, qos, BT_IO_OPT_INVALID); @@ -1616,7 +1800,7 @@ error("%s", err->message); g_error_free(err); } - + ep->io = io; ep->data->listen_io = io; } @@ -1659,7 +1843,7 @@ iso_qos.bcast.big = ep->qos.bcast.big; iso_qos.bcast.bis = ep->qos.bcast.bis; - iso_qos.bcast.sync_interval = ep->qos.bcast.sync_interval; + iso_qos.bcast.sync_factor = ep->qos.bcast.sync_factor; iso_qos.bcast.packing = ep->qos.bcast.packing; iso_qos.bcast.framing = ep->qos.bcast.framing; iso_qos.bcast.encryption = ep->qos.bcast.encryption; @@ -1711,7 +1895,11 @@ bt_bap_stream_statestr(old_state), old_state, bt_bap_stream_statestr(new_state), new_state); - if (new_state == old_state) + /* Ignore transitions back to same state (ASCS allows some of these). + * Of these we need to handle only the config->config case, which will + * occur when reconfiguring the codec from initial config state. + */ + if (new_state == old_state && new_state != BT_BAP_STREAM_STATE_CONFIG) return; ep = bap_find_ep_by_stream(data, stream); @@ -1730,7 +1918,9 @@ bap_create_io(data, ep, stream, true); if (!ep->io) { error("Unable to create io"); - bt_bap_stream_release(stream, NULL, NULL); + if (old_state != BT_BAP_STREAM_STATE_RELEASING) + bt_bap_stream_release(stream, NULL, + NULL); return; } @@ -1748,18 +1938,16 @@ } break; case BT_BAP_STREAM_STATE_QOS: - bap_create_io(data, ep, stream, true); + if (bt_bap_stream_get_type(stream) == + BT_BAP_STREAM_TYPE_UCAST) { + bap_create_io(data, ep, stream, true); + } break; case BT_BAP_STREAM_STATE_ENABLING: if (ep) bap_create_io(data, ep, stream, false); break; case BT_BAP_STREAM_STATE_STREAMING: - if (bt_bap_stream_get_type(stream) == - BT_BAP_STREAM_TYPE_BCAST) { - if (ep) - bap_create_io(data, ep, stream, false); - } break; } } @@ -1784,12 +1972,18 @@ { struct bap_data *data = user_data; - if (bt_bap_pac_get_type(pac) == BT_BAP_BCAST_SOURCE) - bt_bap_foreach_pac(data->bap, BT_BAP_BCAST_SOURCE, - pac_found_bcast, data); - else if (bt_bap_pac_get_type(pac) == BT_BAP_BCAST_SINK) - bt_bap_foreach_pac(data->bap, BT_BAP_BCAST_SINK, - pac_found_bcast, data); + /* + * If pac type is BT_BAP_BCAST_SOURCE locally create an endpoint + * without a remote pac. + * If pac type is BT_BAP_BCAST_SOURCE and remote then look for a + * local broadcast sink pac locally before creating an endpoint. + */ + if (bt_bap_pac_bcast_is_local(data->bap, pac) && + (bt_bap_pac_get_type(pac) == BT_BAP_BCAST_SOURCE)) + pac_found_bcast(pac, NULL, user_data); + else + bt_bap_foreach_pac(data->bap, bt_bap_pac_get_type(pac), + pac_found_bcast, data); } static bool ep_match_pac(const void *data, const void *match_data) @@ -1977,6 +2171,8 @@ ep->qos.bcast.big = qos.bcast.big; ep->qos.bcast.bis = qos.bcast.bis; + bt_bap_stream_config(ep->stream, &ep->qos, + ep->caps, NULL, NULL); } DBG("stream %p fd %d: BIG 0x%02x BIS 0x%02x", stream, fd, diff -Nru bluez-5.70/profiles/audio/csip.c bluez-5.71/profiles/audio/csip.c --- bluez-5.70/profiles/audio/csip.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/profiles/audio/csip.c 2023-12-14 05:40:27.000000000 +0800 @@ -40,6 +40,7 @@ #include "src/shared/gatt-client.h" #include "src/shared/gatt-server.h" #include "src/shared/csip.h" +#include "src/shared/crypto.h" #include "btio/btio.h" #include "src/plugin.h" @@ -54,7 +55,13 @@ #define CSIS_UUID_STR "00001846-0000-1000-8000-00805f9b34fb" +struct csis_data { + struct btd_adapter *adapter; + struct bt_csip *csip; +}; + struct csip_data { + struct btd_adapter *adapter; struct btd_device *device; struct btd_service *service; struct bt_csip *csip; @@ -62,6 +69,7 @@ }; static struct queue *sessions; +static struct queue *servers; static void csip_debug(const char *str, void *user_data) { @@ -78,12 +86,6 @@ return data; } -static bool csip_ltk_read(struct bt_csip *csip, uint8_t k[16], void *user_data) -{ - /* TODO: Retrieve LTK using device object */ - return false; -} - static void csip_data_add(struct csip_data *data) { DBG("data %p", data); @@ -95,10 +97,6 @@ bt_csip_set_debug(data->csip, csip_debug, NULL, NULL); - bt_csip_set_sirk(data->csip, btd_opts.csis.encrypt, btd_opts.csis.sirk, - btd_opts.csis.size, btd_opts.csis.rank, - csip_ltk_read, data); - if (!sessions) sessions = queue_new(); @@ -201,25 +199,6 @@ data->csip = csip; csip_data_add(data); - -} - -static int csip_server_probe(struct btd_profile *p, - struct btd_adapter *adapter) -{ - struct btd_gatt_database *database = btd_adapter_get_database(adapter); - - DBG("CSIP path %s", adapter_get_path(adapter)); - - bt_csip_add_db(btd_gatt_database_get_db(database)); - - return 0; -} - -static void csip_server_remove(struct btd_profile *p, - struct btd_adapter *adapter) -{ - DBG("CSIP remove Adapter"); } static int csip_accept(struct btd_service *service) @@ -332,9 +311,141 @@ .accept = csip_accept, .disconnect = csip_disconnect, - .adapter_probe = csip_server_probe, - .adapter_remove = csip_server_remove, + .experimental = true, +}; + +static bool csis_encrypt(struct bt_att *att, uint8_t val[16]) +{ + struct btd_device *device; + struct bt_crypto *crypto; + uint8_t ltk[16]; + bool ret; + + device = btd_adapter_find_device_by_fd(bt_att_get_fd(att)); + if (!device) { + error("Unable to find device"); + return false; + } + + if (!btd_device_get_ltk(device, ltk, NULL, NULL)) { + error("Unable to get device LTK"); + return false; + } + + crypto = bt_crypto_new(); + if (!crypto) { + error("Failed to open crypto"); + return false; + } + + ret = bt_crypto_sef(crypto, ltk, val, val); + if (!ret) + error("Failed to encrypt SIRK using LTK"); + + bt_crypto_unref(crypto); + + return ret; +} + +static void csis_data_add(struct csis_data *data) +{ + DBG("data %p", data); + + if (queue_find(servers, NULL, data)) { + error("data %p already added", data); + return; + } + + bt_csip_set_debug(data->csip, csip_debug, NULL, NULL); + + bt_csip_set_sirk(data->csip, btd_opts.csis.encrypt, btd_opts.csis.sirk, + btd_opts.csis.size, btd_opts.csis.rank, + csis_encrypt); + + if (!servers) + servers = queue_new(); + queue_push_tail(servers, data); +} + +static struct csis_data *csis_data_new(struct btd_adapter *adapter) +{ + struct csis_data *data; + + data = new0(struct csis_data, 1); + data->adapter = adapter; + + return data; +} + +static int csis_server_probe(struct btd_profile *p, struct btd_adapter *adapter) +{ + struct btd_gatt_database *database = btd_adapter_get_database(adapter); + struct csis_data *data; + + DBG("path %s", adapter_get_path(adapter)); + + data = csis_data_new(adapter); + + data->csip = bt_csip_new(btd_gatt_database_get_db(database), NULL); + if (!data->csip) { + error("Unable to create CSIP instance"); + free(data); + return -EINVAL; + } + + csis_data_add(data); + + return 0; +} + +static bool match_csis(const void *data, const void *match_data) +{ + const struct csis_data *csis = data; + const struct btd_adapter *adapter = match_data; + + return csis->adapter == adapter; +} + +static void csis_data_free(struct csis_data *data) +{ + bt_csip_unref(data->csip); + free(data); +} + +static void csis_data_remove(struct csis_data *data) +{ + DBG("data %p", data); + + csis_data_free(data); + + if (queue_isempty(servers)) { + queue_destroy(servers, NULL); + servers = NULL; + } +} + +static void csis_server_remove(struct btd_profile *p, + struct btd_adapter *adapter) +{ + struct csis_data *data; + + DBG("path %s", adapter_get_path(adapter)); + + data = queue_remove_if(servers, match_csis, adapter); + if (!data) + return; + + csis_data_remove(data); +} + +static struct btd_profile csis_profile = { + .name = "csis", + .priority = BTD_PROFILE_PRIORITY_MEDIUM, + .local_uuid = CSIS_UUID_STR, + + .adapter_probe = csis_server_probe, + .adapter_remove = csis_server_remove, .experimental = true, }; @@ -344,6 +455,10 @@ { int err; + err = btd_profile_register(&csis_profile); + if (err) + return err; + err = btd_profile_register(&csip_profile); if (err) return err; @@ -355,6 +470,7 @@ static void csip_exit(void) { + btd_profile_unregister(&csis_profile); btd_profile_unregister(&csip_profile); bt_csip_unregister(csip_id); } diff -Nru bluez-5.70/profiles/audio/media.c bluez-5.71/profiles/audio/media.c --- bluez-5.70/profiles/audio/media.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/profiles/audio/media.c 2023-12-14 05:40:27.000000000 +0800 @@ -42,6 +42,7 @@ #include "src/shared/queue.h" #include "src/shared/att.h" #include "src/shared/bap.h" +#include "src/shared/bap-debug.h" #include "avdtp.h" #include "media.h" @@ -743,20 +744,20 @@ return 0; } -static int parse_select_properties(DBusMessageIter *props, struct iovec *caps, - struct iovec *metadata, - struct bt_bap_qos *qos) +static int parse_ucast_qos(DBusMessageIter *iter, struct bt_bap_qos *qos) { + DBusMessageIter array; const char *key; struct bt_bap_io_qos io_qos; - uint8_t framing = 0; + + dbus_message_iter_recurse(iter, &array); memset(&io_qos, 0, sizeof(io_qos)); - while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) { + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter value, entry; int var; - dbus_message_iter_recurse(props, &entry); + dbus_message_iter_recurse(&array, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); @@ -764,19 +765,7 @@ var = dbus_message_iter_get_arg_type(&value); - if (!strcasecmp(key, "Capabilities")) { - if (var != DBUS_TYPE_ARRAY) - goto fail; - - if (parse_array(&value, caps)) - goto fail; - } else if (!strcasecmp(key, "Metadata")) { - if (var != DBUS_TYPE_ARRAY) - goto fail; - - if (parse_array(&value, metadata)) - goto fail; - } else if (!strcasecmp(key, "CIG")) { + if (!strcasecmp(key, "CIG")) { if (var != DBUS_TYPE_BYTE) goto fail; @@ -792,28 +781,16 @@ dbus_message_iter_get_basic(&value, &io_qos.interval); } else if (!strcasecmp(key, "Framing")) { - dbus_bool_t val; - - if (var != DBUS_TYPE_BOOLEAN) + if (var != DBUS_TYPE_BYTE) goto fail; - dbus_message_iter_get_basic(&value, &val); - - framing = val; + dbus_message_iter_get_basic(&value, + &qos->ucast.framing); } else if (!strcasecmp(key, "PHY")) { - const char *str; - - if (var != DBUS_TYPE_STRING) + if (var != DBUS_TYPE_BYTE) goto fail; - dbus_message_iter_get_basic(&value, &str); - - if (!strcasecmp(str, "1M")) - io_qos.phy = 0x01; - else if (!strcasecmp(str, "2M")) - io_qos.phy = 0x02; - else - goto fail; + dbus_message_iter_get_basic(&value, &io_qos.phy); } else if (!strcasecmp(key, "SDU")) { if (var != DBUS_TYPE_UINT16) goto fail; @@ -829,7 +806,7 @@ goto fail; dbus_message_iter_get_basic(&value, &io_qos.latency); - } else if (!strcasecmp(key, "Delay")) { + } else if (!strcasecmp(key, "PresentationDelay")) { if (var != DBUS_TYPE_UINT32) goto fail; @@ -842,11 +819,60 @@ &qos->ucast.target_latency); } - dbus_message_iter_next(props); + dbus_message_iter_next(&array); } memcpy(&qos->ucast.io_qos, &io_qos, sizeof(io_qos)); - qos->ucast.framing = framing; + + return 0; + +fail: + DBG("Failed parsing %s", key); + + return -EINVAL; +} + +static int parse_select_properties(DBusMessageIter *props, struct iovec *caps, + struct iovec *metadata, + struct bt_bap_qos *qos) +{ + const char *key; + + while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter value, entry; + int var; + + dbus_message_iter_recurse(props, &entry); + dbus_message_iter_get_basic(&entry, &key); + + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &value); + + var = dbus_message_iter_get_arg_type(&value); + + if (!strcasecmp(key, "Capabilities")) { + if (var != DBUS_TYPE_ARRAY) + goto fail; + + if (parse_array(&value, caps)) + goto fail; + } else if (!strcasecmp(key, "Metadata")) { + if (var != DBUS_TYPE_ARRAY) + goto fail; + + if (parse_array(&value, metadata)) + goto fail; + } else if (!strcasecmp(key, "QoS")) { + if (var != DBUS_TYPE_ARRAY) + goto fail; + + if (parse_ucast_qos(&value, qos)) + goto fail; + } + + dbus_message_iter_next(props); + } + return 0; fail: @@ -940,7 +966,7 @@ loc = bt_bap_pac_get_locations(rpac); if (loc) - g_dbus_dict_append_entry(&dict, "Location", DBUS_TYPE_UINT32, + g_dbus_dict_append_entry(&dict, "Locations", DBUS_TYPE_UINT32, &loc); if (metadata) { @@ -952,26 +978,44 @@ } if (qos && qos->phy) { - g_dbus_dict_append_entry(&dict, "Framing", DBUS_TYPE_BYTE, + DBusMessageIter entry, variant, qos_dict; + + key = "QoS"; + dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, + "a{sv}", &variant); + dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, + "{sv}", &qos_dict); + + g_dbus_dict_append_entry(&qos_dict, "Framing", DBUS_TYPE_BYTE, &qos->framing); - g_dbus_dict_append_entry(&dict, "PHY", DBUS_TYPE_BYTE, + g_dbus_dict_append_entry(&qos_dict, "PHY", DBUS_TYPE_BYTE, &qos->phy); - g_dbus_dict_append_entry(&dict, "Latency", DBUS_TYPE_UINT16, - &qos->latency); + g_dbus_dict_append_entry(&qos_dict, "Retransmissions", + DBUS_TYPE_BYTE, &qos->rtn); + + g_dbus_dict_append_entry(&qos_dict, "MaximumLatency", + DBUS_TYPE_UINT16, &qos->latency); - g_dbus_dict_append_entry(&dict, "MinimumDelay", + g_dbus_dict_append_entry(&qos_dict, "MinimumDelay", DBUS_TYPE_UINT32, &qos->pd_min); - g_dbus_dict_append_entry(&dict, "MaximumDelay", + g_dbus_dict_append_entry(&qos_dict, "MaximumDelay", DBUS_TYPE_UINT32, &qos->pd_max); - g_dbus_dict_append_entry(&dict, "PreferredMinimumDelay", + g_dbus_dict_append_entry(&qos_dict, "PreferredMinimumDelay", DBUS_TYPE_UINT32, &qos->ppd_min); - g_dbus_dict_append_entry(&dict, "PreferredMaximumDelay", - DBUS_TYPE_UINT32, &qos->ppd_min); + g_dbus_dict_append_entry(&qos_dict, "PreferredMaximumDelay", + DBUS_TYPE_UINT32, &qos->ppd_max); + + dbus_message_iter_close_container(&variant, &qos_dict); + dbus_message_iter_close_container(&entry, &variant); + dbus_message_iter_close_container(&dict, &entry); } dbus_message_iter_close_container(&iter, &dict); @@ -1177,13 +1221,13 @@ return false; } - if (!bap_print_cc(endpoint->capabilities, endpoint->size, bap_debug, - NULL)) { + if (!bt_bap_debug_caps(endpoint->capabilities, endpoint->size, + bap_debug, NULL)) { error("Unable to parse endpoint capabilities"); return false; } - if (!bap_print_cc(endpoint->metadata, endpoint->metadata_size, + if (!bt_bap_debug_metadata(endpoint->metadata, endpoint->metadata_size, bap_debug, NULL)) { error("Unable to parse endpoint metadata"); return false; @@ -1549,7 +1593,7 @@ if (var != DBUS_TYPE_BYTE) return -EINVAL; dbus_message_iter_get_basic(&value, &qos->phy); - } else if (strcasecmp(key, "RTN") == 0) { + } else if (strcasecmp(key, "Retransmissions") == 0) { if (var != DBUS_TYPE_BYTE) return -EINVAL; dbus_message_iter_get_basic(&value, &qos->rtn); @@ -1569,6 +1613,19 @@ if (var != DBUS_TYPE_UINT16) return -EINVAL; dbus_message_iter_get_basic(&value, &qos->ppd_max); + } else if (strcasecmp(key, "Locations") == 0) { + if (var != DBUS_TYPE_UINT32) + return -EINVAL; + dbus_message_iter_get_basic(&value, &qos->location); + } else if (strcasecmp(key, "Context") == 0) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + dbus_message_iter_get_basic(&value, &qos->context); + } else if (strcasecmp(key, "SupportedContext") == 0) { + if (var != DBUS_TYPE_UINT16) + return -EINVAL; + dbus_message_iter_get_basic(&value, + &qos->supported_context); } dbus_message_iter_next(props); @@ -2724,7 +2781,7 @@ dbus_message_iter_get_basic(&iter, &qos.phy); } - if (g_dbus_proxy_get_property(proxy, "Latency", &iter)) { + if (g_dbus_proxy_get_property(proxy, "MaximumLatency", &iter)) { if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16) goto fail; @@ -2759,6 +2816,27 @@ dbus_message_iter_get_basic(&iter, &qos.ppd_min); } + if (g_dbus_proxy_get_property(proxy, "Locations", &iter)) { + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + goto fail; + + dbus_message_iter_get_basic(&iter, &qos.location); + } + + if (g_dbus_proxy_get_property(proxy, "Context", &iter)) { + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16) + goto fail; + + dbus_message_iter_get_basic(&iter, &qos.context); + } + + if (g_dbus_proxy_get_property(proxy, "SupportedContext", &iter)) { + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16) + goto fail; + + dbus_message_iter_get_basic(&iter, &qos.supported_context); + } + endpoint = media_endpoint_create(app->adapter, app->sender, path, uuid, delay_reporting, codec, vendor.cid, vendor.vid, &qos, diff -Nru bluez-5.70/profiles/audio/media.h bluez-5.71/profiles/audio/media.h --- bluez-5.70/profiles/audio/media.h 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/profiles/audio/media.h 2023-12-14 05:40:27.000000000 +0800 @@ -22,6 +22,5 @@ uint8_t media_endpoint_get_codec(struct media_endpoint *endpoint); struct btd_adapter *media_endpoint_get_btd_adapter( struct media_endpoint *endpoint); -bool media_endpoint_is_broadcast( - struct media_endpoint *endpoint); +bool media_endpoint_is_broadcast(struct media_endpoint *endpoint); int8_t media_player_get_device_volume(struct btd_device *device); diff -Nru bluez-5.70/profiles/audio/transport.c bluez-5.71/profiles/audio/transport.c --- bluez-5.70/profiles/audio/transport.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/profiles/audio/transport.c 2023-12-14 05:40:27.000000000 +0800 @@ -606,11 +606,38 @@ return NULL; } +static void bap_stop_complete(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + struct media_owner *owner = user_data; + struct media_request *req = owner->pending; + struct media_transport *transport = owner->transport; + + /* Release always succeeds */ + if (req) { + req->id = 0; + media_request_reply(req, 0); + media_owner_remove(owner); + } + + transport_set_state(transport, TRANSPORT_STATE_IDLE); + media_transport_remove_owner(transport); +} + +static void bap_disable_complete(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + bap_stop_complete(stream, code, reason, user_data); +} + static DBusMessage *release(DBusConnection *conn, DBusMessage *msg, void *data) { struct media_transport *transport = data; struct media_owner *owner = transport->owner; + struct bap_transport *bap = transport->data; const char *sender; struct media_request *req; guint id; @@ -642,6 +669,11 @@ req = media_request_create(msg, id); media_owner_add(owner, req); + if (bt_bap_stream_get_type(bap->stream) == + BT_BAP_STREAM_TYPE_BCAST) { + bap_disable_complete(bap->stream, 0x00, 0x00, owner); + } + return NULL; } @@ -850,160 +882,41 @@ { } }; -static gboolean qos_exists(const GDBusPropertyTable *property, void *data) +static void append_io_qos(DBusMessageIter *dict, struct bt_bap_io_qos *qos) { - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - if (media_endpoint_is_broadcast(transport->endpoint)) - return bap->qos.bcast.io_qos.sdu != 0x00; - - return bap->qos.ucast.io_qos.phy != 0x00; + dict_append_entry(dict, "Interval", DBUS_TYPE_UINT32, &qos->interval); + dict_append_entry(dict, "Latency", DBUS_TYPE_UINT16, &qos->latency); + dict_append_entry(dict, "SDU", DBUS_TYPE_UINT16, &qos->sdu); + dict_append_entry(dict, "PHY", DBUS_TYPE_BYTE, &qos->phy); + dict_append_entry(dict, "Retransmissions", DBUS_TYPE_BYTE, &qos->rtn); } -static gboolean get_cig(const GDBusPropertyTable *property, +static gboolean get_ucast_qos(const GDBusPropertyTable *property, DBusMessageIter *iter, void *data) { struct media_transport *transport = data; struct bap_transport *bap = transport->data; + DBusMessageIter dict; - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.ucast.cig_id); - - return TRUE; -} - -static gboolean get_big(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.bcast.big); - - return TRUE; -} - -static gboolean get_cis(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.ucast.cis_id); - - return TRUE; -} - -static gboolean get_bis(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.bcast.bis); - - return TRUE; -} - -static gboolean get_interval(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, - &bap->qos.ucast.io_qos.interval); - - return TRUE; -} - -static gboolean get_framing(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - dbus_bool_t val = bap->qos.ucast.framing; - - if (media_endpoint_is_broadcast(transport->endpoint)) - val = bap->qos.bcast.framing; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val); - - return TRUE; -} - -static gboolean get_phy(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - if (media_endpoint_is_broadcast(transport->endpoint)) { - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.bcast.io_qos.phy); - return TRUE; - } - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.ucast.io_qos.phy); - - return TRUE; -} - -static gboolean get_sdu(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - if (media_endpoint_is_broadcast(transport->endpoint)) { - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, - &bap->qos.bcast.io_qos.sdu); - return TRUE; - } - - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, - &bap->qos.ucast.io_qos.sdu); - - return TRUE; -} - -static gboolean get_retransmissions(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.ucast.io_qos.rtn); - - return TRUE; -} - -static gboolean get_latency(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, - &bap->qos.ucast.io_qos.latency); - - return TRUE; -} + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + dict_append_entry(&dict, "CIG", DBUS_TYPE_BYTE, + &bap->qos.ucast.cig_id); + dict_append_entry(&dict, "CIS", DBUS_TYPE_BYTE, + &bap->qos.ucast.cis_id); + dict_append_entry(&dict, "Framing", DBUS_TYPE_BYTE, + &bap->qos.ucast.framing); + dict_append_entry(&dict, "PresentationDelay", DBUS_TYPE_UINT32, + &bap->qos.ucast.delay); -static gboolean get_delay(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; + append_io_qos(&dict, &bap->qos.ucast.io_qos); - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, - &bap->qos.ucast.delay); + dbus_message_iter_close_container(iter, &dict); return TRUE; } @@ -1084,161 +997,91 @@ return TRUE; } -static gboolean get_sync_interval(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) +static gboolean qos_ucast_exists(const GDBusPropertyTable *property, void *data) { struct media_transport *transport = data; struct bap_transport *bap = transport->data; - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.bcast.sync_interval); - - return TRUE; + return bap->qos.ucast.io_qos.phy != 0x00; } -static gboolean get_packing(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.bcast.packing); - - return TRUE; -} +static const GDBusPropertyTable bap_ucast_properties[] = { + { "Device", "o", get_device }, + { "UUID", "s", get_uuid }, + { "Codec", "y", get_codec }, + { "Configuration", "ay", get_configuration }, + { "State", "s", get_state }, + { "QoS", "a{sv}", get_ucast_qos, NULL, qos_ucast_exists }, + { "Endpoint", "o", get_endpoint, NULL, endpoint_exists }, + { "Location", "u", get_location }, + { "Metadata", "ay", get_metadata }, + { "Links", "ao", get_links, NULL, links_exists }, + { } +}; -static gboolean get_bcode(const GDBusPropertyTable *property, +static gboolean get_bcast_qos(const GDBusPropertyTable *property, DBusMessageIter *iter, void *data) { struct media_transport *transport = data; struct bap_transport *bap = transport->data; - DBusMessageIter array; + DBusMessageIter dict; dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, - DBUS_TYPE_BYTE_AS_STRING, &array); - - if (bap->qos.bcast.bcode && bap->qos.bcast.bcode->iov_len) - dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE, - &bap->qos.bcast.bcode->iov_base, - bap->qos.bcast.bcode->iov_len); - - dbus_message_iter_close_container(iter, &array); - return TRUE; -} - -static gboolean get_options(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + dict_append_entry(&dict, "BIG", DBUS_TYPE_BYTE, + &bap->qos.bcast.big); + dict_append_entry(&dict, "BIS", DBUS_TYPE_BYTE, + &bap->qos.bcast.bis); + dict_append_entry(&dict, "SyncFactor", DBUS_TYPE_BYTE, + &bap->qos.bcast.sync_factor); + dict_append_entry(&dict, "Packing", DBUS_TYPE_BYTE, + &bap->qos.bcast.packing); + dict_append_entry(&dict, "Framing", DBUS_TYPE_BYTE, + &bap->qos.bcast.framing); + if (bap->qos.bcast.bcode) + dict_append_array(&dict, "BCode", DBUS_TYPE_BYTE, + &bap->qos.bcast.bcode->iov_base, + bap->qos.bcast.bcode->iov_len); + dict_append_entry(&dict, "Options", DBUS_TYPE_BYTE, &bap->qos.bcast.options); - - return TRUE; -} - -static gboolean get_skip(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, + dict_append_entry(&dict, "Skip", DBUS_TYPE_UINT16, &bap->qos.bcast.skip); - - return TRUE; -} - -static gboolean get_sync_timeout(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, + dict_append_entry(&dict, "SyncTimeout", DBUS_TYPE_UINT16, &bap->qos.bcast.sync_timeout); - - return TRUE; -} - -static gboolean get_sync_cte_type(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, + dict_append_entry(&dict, "SyncType", DBUS_TYPE_BYTE, &bap->qos.bcast.sync_cte_type); + dict_append_entry(&dict, "MSE", DBUS_TYPE_BYTE, + &bap->qos.bcast.mse); + dict_append_entry(&dict, "Timeout", DBUS_TYPE_UINT16, + &bap->qos.bcast.timeout); - return TRUE; -} - -static gboolean get_mse(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) -{ - struct media_transport *transport = data; - struct bap_transport *bap = transport->data; + append_io_qos(&dict, &bap->qos.bcast.io_qos); - dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, - &bap->qos.bcast.mse); + dbus_message_iter_close_container(iter, &dict); return TRUE; } -static gboolean get_timeout(const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) +static gboolean qos_bcast_exists(const GDBusPropertyTable *property, void *data) { struct media_transport *transport = data; struct bap_transport *bap = transport->data; - dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, - &bap->qos.bcast.timeout); - - return TRUE; + return bap->qos.bcast.io_qos.phy != 0x00; } -static const GDBusPropertyTable bap_ucast_properties[] = { - { "Device", "o", get_device }, - { "UUID", "s", get_uuid }, - { "Codec", "y", get_codec }, - { "Configuration", "ay", get_configuration }, - { "State", "s", get_state }, - { "CIG", "y", get_cig, NULL, qos_exists }, - { "CIS", "y", get_cis, NULL, qos_exists }, - { "Interval", "u", get_interval, NULL, qos_exists }, - { "Framing", "b", get_framing, NULL, qos_exists }, - { "PHY", "y", get_phy, NULL, qos_exists }, - { "SDU", "q", get_sdu, NULL, qos_exists }, - { "Retransmissions", "y", get_retransmissions, NULL, qos_exists }, - { "Latency", "q", get_latency, NULL, qos_exists }, - { "Delay", "u", get_delay, NULL, qos_exists }, - { "Endpoint", "o", get_endpoint, NULL, endpoint_exists }, - { "Location", "u", get_location }, - { "Metadata", "ay", get_metadata }, - { "Links", "ao", get_links, NULL, links_exists }, - { } -}; - - static const GDBusPropertyTable bap_bcast_properties[] = { { "Device", "o", get_device }, { "UUID", "s", get_uuid }, { "Codec", "y", get_codec }, { "Configuration", "ay", get_configuration }, { "State", "s", get_state }, - { "BIG", "y", get_big, NULL, qos_exists }, - { "BIS", "y", get_bis, NULL, qos_exists }, - { "SyncInterval", "y", get_sync_interval, NULL, qos_exists }, - { "Packing", "y", get_packing, NULL, qos_exists }, - { "BCode", "ay", get_bcode, NULL, qos_exists }, - { "Options", "y", get_options, NULL, qos_exists }, - { "Skip", "q", get_skip, NULL, qos_exists }, - { "SyncTimeout", "q", get_sync_timeout, NULL, qos_exists }, - { "SyncCteType", "y", get_sync_cte_type, NULL, qos_exists }, - { "MSE", "y", get_mse, NULL, qos_exists }, - { "Timeout", "q", get_timeout, NULL, qos_exists }, + { "QoS", "a{sv}", get_bcast_qos, NULL, qos_bcast_exists }, { "Endpoint", "o", get_endpoint, NULL, endpoint_exists }, { "Location", "u", get_location }, { "Metadata", "ay", get_metadata }, @@ -1471,31 +1314,7 @@ g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path, MEDIA_TRANSPORT_INTERFACE, - "CIG"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "CIS"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Interval"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Framing"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "PHY"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "SDU"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Retransmissions"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Latency"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Delay"); + "QoS"); } static gboolean bap_resume_complete_cb(void *data) @@ -1538,55 +1357,7 @@ g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path, MEDIA_TRANSPORT_INTERFACE, - "BIG"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "BIS"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "SyncInterval"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Packing"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Framing"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "BCode"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Options"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Skip"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "SyncTimeout"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "SyncCteType"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "MSE"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Timeout"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Interval"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "Latency"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "PHY"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "SDU"); - g_dbus_emit_property_changed(btd_get_dbus_connection(), - transport->path, MEDIA_TRANSPORT_INTERFACE, - "RTN"); + "QoS"); g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path, MEDIA_TRANSPORT_INTERFACE, "Codec"); @@ -1631,32 +1402,6 @@ return id; } -static void bap_stop_complete(struct bt_bap_stream *stream, - uint8_t code, uint8_t reason, - void *user_data) -{ - struct media_owner *owner = user_data; - struct media_request *req = owner->pending; - struct media_transport *transport = owner->transport; - - /* Release always succeeds */ - if (req) { - req->id = 0; - media_request_reply(req, 0); - media_owner_remove(owner); - } - - transport_set_state(transport, TRANSPORT_STATE_IDLE); - media_transport_remove_owner(transport); -} - -static void bap_disable_complete(struct bt_bap_stream *stream, - uint8_t code, uint8_t reason, - void *user_data) -{ - bap_stop_complete(stream, code, reason, user_data); -} - static guint suspend_bap(struct media_transport *transport, struct media_owner *owner) { @@ -1760,9 +1505,14 @@ return; break; case BT_BAP_STREAM_STATE_STREAMING: - if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) + if ((bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) || + (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SINK)) bap_update_bcast_qos(transport); break; + case BT_BAP_STREAM_STATE_RELEASING: + if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SINK) + return; + break; } io = bt_bap_stream_get_io(stream); diff -Nru bluez-5.70/profiles/input/device.c bluez-5.71/profiles/input/device.c --- bluez-5.70/profiles/input/device.c 2022-07-25 05:02:15.000000000 +0800 +++ bluez-5.71/profiles/input/device.c 2023-12-14 05:40:27.000000000 +0800 @@ -20,6 +20,7 @@ #include #include #include +#include #include "lib/bluetooth.h" #include "lib/hidp.h" @@ -60,7 +61,7 @@ char *path; bdaddr_t src; bdaddr_t dst; - uint32_t handle; + const sdp_record_t *rec; GIOChannel *ctrl_io; GIOChannel *intr_io; guint ctrl_watch; @@ -81,7 +82,7 @@ static int idle_timeout = 0; static bool uhid_enabled = false; -static bool classic_bonded_only = false; +static bool classic_bonded_only = true; void input_set_idle_timeout(int timeout) { @@ -162,32 +163,33 @@ { int fd; ssize_t len; - uint8_t msg[size + 1]; + struct iovec iov[2]; if (!chan) { error("BT socket not connected"); return false; } + iov[0].iov_base = &hdr; + iov[0].iov_len = sizeof(hdr); + if (data == NULL) size = 0; - msg[0] = hdr; - if (size > 0) - memcpy(&msg[1], data, size); - ++size; + iov[1].iov_base = (void *)data; + iov[1].iov_len = size; fd = g_io_channel_unix_get_fd(chan); - len = write(fd, msg, size); + len = writev(fd, iov, 2); if (len < 0) { error("BT socket write error: %s (%d)", strerror(errno), errno); return false; } - if ((size_t) len < size) { + if ((size_t) len < size + 1) { error("BT socket write error: partial write (%zd of %zu bytes)", - len, size); + len, size + 1); return false; } @@ -754,7 +756,8 @@ } } -static int create_hid_dev_name(sdp_record_t *rec, struct hidp_connadd_req *req) +static int create_hid_dev_name(const sdp_record_t *rec, + struct hidp_connadd_req *req) { char sdesc[sizeof(req->name) / 2]; @@ -776,7 +779,7 @@ /* See HID profile specification v1.0, "7.11.6 HIDDescriptorList" for details * on the attribute format. */ -static int extract_hid_desc_data(sdp_record_t *rec, +static int extract_hid_desc_data(const sdp_record_t *rec, struct hidp_connadd_req *req) { sdp_data_t *d; @@ -817,36 +820,40 @@ return -EINVAL; } -static int extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req) +static int extract_hid_record(struct input_device *idev, + struct hidp_connadd_req *req) { sdp_data_t *pdlist; uint8_t attr_val; int err; - err = create_hid_dev_name(rec, req); + if (!idev->rec) + return -ENOENT; + + err = create_hid_dev_name(idev->rec, req); if (err < 0) DBG("No valid Service Name or Service Description found"); - pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION); + pdlist = sdp_data_get(idev->rec, SDP_ATTR_HID_PARSER_VERSION); req->parser = pdlist ? pdlist->val.uint16 : 0x0100; - pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS); + pdlist = sdp_data_get(idev->rec, SDP_ATTR_HID_DEVICE_SUBCLASS); req->subclass = pdlist ? pdlist->val.uint8 : 0; - pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE); + pdlist = sdp_data_get(idev->rec, SDP_ATTR_HID_COUNTRY_CODE); req->country = pdlist ? pdlist->val.uint8 : 0; - pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE); + pdlist = sdp_data_get(idev->rec, SDP_ATTR_HID_VIRTUAL_CABLE); attr_val = pdlist ? pdlist->val.uint8 : 0; if (attr_val) req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG); - pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE); + pdlist = sdp_data_get(idev->rec, SDP_ATTR_HID_BOOT_DEVICE); attr_val = pdlist ? pdlist->val.uint8 : 0; if (attr_val) req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); - err = extract_hid_desc_data(rec, req); + err = extract_hid_desc_data(idev->rec, req); if (err < 0) return err; @@ -1035,11 +1042,6 @@ static int hidp_add_connection(struct input_device *idev) { struct hidp_connadd_req *req; - sdp_record_t *rec; - char src_addr[18], dst_addr[18]; - char filename[PATH_MAX]; - GKeyFile *key_file; - char handle[11], *str; GError *gerr = NULL; int err; @@ -1049,33 +1051,7 @@ req->flags = 0; req->idle_to = idle_timeout; - ba2str(&idev->src, src_addr); - ba2str(&idev->dst, dst_addr); - - snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", src_addr, - dst_addr); - sprintf(handle, "0x%8.8X", idev->handle); - - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) { - error("Unable to load key file from %s: (%s)", filename, - gerr->message); - g_clear_error(&gerr); - } - str = g_key_file_get_string(key_file, "ServiceRecords", handle, NULL); - g_key_file_free(key_file); - - if (!str) { - error("Rejected connection from unknown device %s", dst_addr); - err = -EPERM; - goto cleanup; - } - - rec = record_from_string(str); - g_free(str); - - err = extract_hid_record(rec, req); - sdp_record_free(rec); + err = extract_hid_record(idev, req); if (err < 0) { error("Could not parse HID SDP record: %s (%d)", strerror(-err), -err); @@ -1091,7 +1067,7 @@ /* Make sure the device is bonded if required */ if (classic_bonded_only && !input_device_bonded(idev)) { - error("Rejected connection from !bonded device %s", dst_addr); + error("Rejected connection from !bonded device %s", idev->path); goto cleanup; } @@ -1161,6 +1137,68 @@ return ioctl_disconnect(idev, flags); } +static bool is_device_sdp_disable(const sdp_record_t *rec) +{ + sdp_data_t *data; + + data = sdp_data_get(rec, SDP_ATTR_HID_SDP_DISABLE); + + return data && data->val.uint8; +} + +static enum reconnect_mode_t hid_reconnection_mode(bool reconnect_initiate, + bool normally_connectable) +{ + if (!reconnect_initiate && !normally_connectable) + return RECONNECT_NONE; + else if (!reconnect_initiate && normally_connectable) + return RECONNECT_HOST; + else if (reconnect_initiate && !normally_connectable) + return RECONNECT_DEVICE; + else /* (reconnect_initiate && normally_connectable) */ + return RECONNECT_ANY; +} + +static void extract_hid_props(struct input_device *idev, + const sdp_record_t *rec) +{ + /* Extract HID connectability */ + bool reconnect_initiate, normally_connectable; + sdp_data_t *pdlist; + + /* HIDNormallyConnectable is optional and assumed FALSE if not + * present. + */ + pdlist = sdp_data_get(rec, SDP_ATTR_HID_RECONNECT_INITIATE); + reconnect_initiate = pdlist ? pdlist->val.uint8 : TRUE; + + pdlist = sdp_data_get(rec, SDP_ATTR_HID_NORMALLY_CONNECTABLE); + normally_connectable = pdlist ? pdlist->val.uint8 : FALSE; + + /* Update local values */ + idev->reconnect_mode = + hid_reconnection_mode(reconnect_initiate, normally_connectable); +} + +static void input_device_update_rec(struct input_device *idev) +{ + struct btd_profile *p = btd_service_get_profile(idev->service); + const sdp_record_t *rec; + + rec = btd_device_get_record(idev->device, p->remote_uuid); + if (!rec || idev->rec == rec) + return; + + idev->rec = rec; + idev->disable_sdp = is_device_sdp_disable(rec); + + /* Initialize device properties */ + extract_hid_props(idev, rec); + + if (idev->disable_sdp) + device_set_refresh_discovery(idev->device, false); +} + static int input_device_connected(struct input_device *idev) { int err; @@ -1168,6 +1206,9 @@ if (idev->intr_io == NULL || idev->ctrl_io == NULL) return -ENOTCONN; + /* Attempt to update SDP record if it had changed */ + input_device_update_rec(idev); + err = hidp_add_connection(idev); if (err < 0) return err; @@ -1411,74 +1452,21 @@ return 0; } -static bool is_device_sdp_disable(const sdp_record_t *rec) -{ - sdp_data_t *data; - - data = sdp_data_get(rec, SDP_ATTR_HID_SDP_DISABLE); - - return data && data->val.uint8; -} - -static enum reconnect_mode_t hid_reconnection_mode(bool reconnect_initiate, - bool normally_connectable) -{ - if (!reconnect_initiate && !normally_connectable) - return RECONNECT_NONE; - else if (!reconnect_initiate && normally_connectable) - return RECONNECT_HOST; - else if (reconnect_initiate && !normally_connectable) - return RECONNECT_DEVICE; - else /* (reconnect_initiate && normally_connectable) */ - return RECONNECT_ANY; -} - -static void extract_hid_props(struct input_device *idev, - const sdp_record_t *rec) -{ - /* Extract HID connectability */ - bool reconnect_initiate, normally_connectable; - sdp_data_t *pdlist; - - /* HIDNormallyConnectable is optional and assumed FALSE - * if not present. */ - pdlist = sdp_data_get(rec, SDP_ATTR_HID_RECONNECT_INITIATE); - reconnect_initiate = pdlist ? pdlist->val.uint8 : TRUE; - - pdlist = sdp_data_get(rec, SDP_ATTR_HID_NORMALLY_CONNECTABLE); - normally_connectable = pdlist ? pdlist->val.uint8 : FALSE; - - /* Update local values */ - idev->reconnect_mode = - hid_reconnection_mode(reconnect_initiate, normally_connectable); -} - static struct input_device *input_device_new(struct btd_service *service) { struct btd_device *device = btd_service_get_device(service); - struct btd_profile *p = btd_service_get_profile(service); const char *path = device_get_path(device); - const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid); struct btd_adapter *adapter = device_get_adapter(device); struct input_device *idev; - if (!rec) - return NULL; - idev = g_new0(struct input_device, 1); bacpy(&idev->src, btd_adapter_get_address(adapter)); bacpy(&idev->dst, device_get_address(device)); idev->service = btd_service_ref(service); idev->device = btd_device_ref(device); idev->path = g_strdup(path); - idev->handle = rec->handle; - idev->disable_sdp = is_device_sdp_disable(rec); - - /* Initialize device properties */ - extract_hid_props(idev, rec); - if (idev->disable_sdp) - device_set_refresh_discovery(device, false); + input_device_update_rec(idev); return idev; } diff -Nru bluez-5.70/profiles/input/input.conf bluez-5.71/profiles/input/input.conf --- bluez-5.70/profiles/input/input.conf 2020-09-06 21:53:08.000000000 +0800 +++ bluez-5.71/profiles/input/input.conf 2023-12-14 05:40:27.000000000 +0800 @@ -17,7 +17,7 @@ # platforms may want to make sure that input connections only come from bonded # device connections. Several older mice have been known for not supporting # pairing/encryption. -# Defaults to false to maximize device compatibility. +# Defaults to true for security. #ClassicBondedOnly=true # LE upgrade security diff -Nru bluez-5.70/src/adapter.c bluez-5.71/src/adapter.c --- bluez-5.70/src/adapter.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/adapter.c 2023-12-14 05:40:27.000000000 +0800 @@ -170,6 +170,7 @@ struct link_key_info { bdaddr_t bdaddr; + uint8_t bdaddr_type; unsigned char key[16]; uint8_t type; uint8_t pin_len; @@ -260,6 +261,7 @@ bdaddr_t bdaddr; /* controller Bluetooth address */ uint8_t bdaddr_type; /* address type */ + uint8_t version; /* controller core spec version */ uint32_t dev_class; /* controller class of device */ char *name; /* controller device name */ char *short_name; /* controller short name */ @@ -2645,10 +2647,13 @@ static bool parse_duplicate_data(DBusMessageIter *value, struct discovery_filter *filter) { + dbus_bool_t duplicate = false; + if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) return false; - dbus_message_iter_get_basic(value, &filter->duplicate); + dbus_message_iter_get_basic(value, &duplicate); + filter->duplicate = duplicate; return true; } @@ -2656,10 +2661,13 @@ static bool parse_discoverable(DBusMessageIter *value, struct discovery_filter *filter) { + dbus_bool_t discoverable = false; + if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) return false; - dbus_message_iter_get_basic(value, &filter->discoverable); + dbus_message_iter_get_basic(value, &discoverable); + filter->discoverable = discoverable; return true; } @@ -3540,6 +3548,29 @@ return !queue_isempty(adapter->exps); } +static gboolean property_get_manufacturer(const GDBusPropertyTable *property, + DBusMessageIter *iter, + void *user_data) +{ + struct btd_adapter *adapter = user_data; + dbus_uint16_t val = adapter->manufacturer; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val); + + return TRUE; +} + +static gboolean property_get_version(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) +{ + struct btd_adapter *adapter = user_data; + uint8_t val = adapter->version; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &val); + + return TRUE; +} + static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -3898,6 +3929,8 @@ { "Roles", "as", property_get_roles }, { "ExperimentalFeatures", "as", property_get_experimental, NULL, property_experimental_exists }, + { "Manufacturer", "q", property_get_manufacturer }, + { "Version", "y", property_get_version }, { } }; @@ -3932,7 +3965,9 @@ return false; } -static struct link_key_info *get_key_info(GKeyFile *key_file, const char *peer) +static struct link_key_info *get_key_info(GKeyFile *key_file, const char *peer, + uint8_t bdaddr_type) + { struct link_key_info *info = NULL; char *str; @@ -3944,6 +3979,7 @@ info = g_new0(struct link_key_info, 1); str2ba(peer, &info->bdaddr); + info->bdaddr_type = bdaddr_type; if (!strncmp(str, "0x", 2)) str2buf(&str[2], info->key, sizeof(info->key)); @@ -4311,7 +4347,7 @@ struct link_key_info *info = l->data; bacpy(&key->addr.bdaddr, &info->bdaddr); - key->addr.type = BDADDR_BREDR; + key->addr.type = info->bdaddr_type; key->type = info->type; memcpy(key->val, info->key, 16); key->pin_len = info->pin_len; @@ -4566,14 +4602,18 @@ btd_error(adapter->dev_id, "Load connection parameters failed"); } -static uint8_t get_le_addr_type(GKeyFile *keyfile) +static uint8_t get_addr_type(GKeyFile *keyfile) { uint8_t addr_type; char *type; + /* The AddressType is written to file only When dev->le is + * set to true, as referenced in the update_technologies(). + * Therefore, When type is NULL, it default to BDADDR_BREDR. + */ type = g_key_file_get_string(keyfile, "General", "AddressType", NULL); if (!type) - return BDADDR_LE_PUBLIC; + return BDADDR_BREDR; if (g_str_equal(type, "public")) addr_type = BDADDR_LE_PUBLIC; @@ -4882,9 +4922,9 @@ g_clear_error(&gerr); } - key_info = get_key_info(key_file, entry->d_name); + bdaddr_type = get_addr_type(key_file); - bdaddr_type = get_le_addr_type(key_file); + key_info = get_key_info(key_file, entry->d_name, bdaddr_type); ltk_info = get_ltk_info(key_file, entry->d_name, bdaddr_type); @@ -9260,10 +9300,8 @@ agent_unref(agent); } - if (g_dbus_get_flags() & G_DBUS_FLAG_ENABLE_EXPERIMENTAL) { - adapter->battery_provider_manager = - btd_battery_provider_manager_create(adapter); - } + adapter->battery_provider_manager = + btd_battery_provider_manager_create(adapter); /* Don't start GATT database and advertising managers on * non-LE controllers. @@ -10164,6 +10202,8 @@ adapter->supported_settings = btohl(rp->supported_settings); adapter->current_settings = btohl(rp->current_settings); + adapter->version = rp->version; + clear_uuids(adapter); clear_devices(adapter); @@ -10197,12 +10237,12 @@ switch (btd_opts.mode) { case BT_MODE_DUAL: - if (missing_settings & MGMT_SETTING_SSP) - set_mode(adapter, MGMT_OP_SET_SSP, 0x01); if (missing_settings & MGMT_SETTING_LE) set_mode(adapter, MGMT_OP_SET_LE, 0x01); if (missing_settings & MGMT_SETTING_BREDR) set_mode(adapter, MGMT_OP_SET_BREDR, 0x01); + if (missing_settings & MGMT_SETTING_SSP) + set_mode(adapter, MGMT_OP_SET_SSP, 0x01); break; case BT_MODE_BREDR: if (!(adapter->supported_settings & MGMT_SETTING_BREDR)) { @@ -10211,10 +10251,10 @@ goto failed; } - if (missing_settings & MGMT_SETTING_SSP) - set_mode(adapter, MGMT_OP_SET_SSP, 0x01); if (missing_settings & MGMT_SETTING_BREDR) set_mode(adapter, MGMT_OP_SET_BREDR, 0x01); + if (missing_settings & MGMT_SETTING_SSP) + set_mode(adapter, MGMT_OP_SET_SSP, 0x01); if (adapter->current_settings & MGMT_SETTING_LE) set_mode(adapter, MGMT_OP_SET_LE, 0x00); break; diff -Nru bluez-5.70/src/battery.c bluez-5.71/src/battery.c --- bluez-5.70/src/battery.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/battery.c 2023-12-14 05:40:27.000000000 +0800 @@ -152,8 +152,7 @@ static const GDBusPropertyTable battery_properties[] = { { "Percentage", "y", property_percentage_get, NULL, property_percentage_exists }, - { "Source", "s", property_source_get, NULL, property_source_exists, - G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, + { "Source", "s", property_source_get, NULL, property_source_exists }, {} }; @@ -523,10 +522,10 @@ } static const GDBusMethodTable methods[] = { - { GDBUS_EXPERIMENTAL_METHOD("RegisterBatteryProvider", + { GDBUS_METHOD("RegisterBatteryProvider", GDBUS_ARGS({ "provider", "o" }), NULL, register_battery_provider) }, - { GDBUS_EXPERIMENTAL_METHOD("UnregisterBatteryProvider", + { GDBUS_METHOD("UnregisterBatteryProvider", GDBUS_ARGS({ "provider", "o" }), NULL, unregister_battery_provider) }, {} diff -Nru bluez-5.70/src/device.c bluez-5.71/src/device.c --- bluez-5.70/src/device.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/device.c 2023-12-14 05:40:27.000000000 +0800 @@ -1938,6 +1938,23 @@ queue_foreach(device->sirks, add_set, device); } +bool btd_device_get_ltk(struct btd_device *device, uint8_t key[16], + bool *central, uint8_t *enc_size) +{ + if (!device || !device->ltk || !key) + return false; + + memcpy(key, device->ltk->key, sizeof(device->ltk->key)); + + if (central) + *central = device->ltk->central; + + if (enc_size) + *enc_size = device->ltk->enc_size; + + return true; +} + static bool match_sirk(const void *data, const void *match_data) { const struct sirk_info *sirk = data; @@ -4455,6 +4472,9 @@ device->le = true; device->bdaddr_type = bdaddr_type; + g_dbus_emit_property_changed(dbus_conn, device->path, + DEVICE_INTERFACE, "AddressType"); + store_device_info(device); } diff -Nru bluez-5.70/src/device.h bluez-5.71/src/device.h --- bluez-5.70/src/device.h 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/device.h 2023-12-14 05:40:27.000000000 +0800 @@ -132,6 +132,8 @@ bool device_is_disconnecting(struct btd_device *device); void device_set_ltk(struct btd_device *device, const uint8_t val[16], bool central, uint8_t enc_size); +bool btd_device_get_ltk(struct btd_device *device, uint8_t val[16], + bool *central, uint8_t *enc_size); bool btd_device_add_set(struct btd_device *device, bool encrypted, uint8_t sirk[16], uint8_t size, uint8_t rank); void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type, diff -Nru bluez-5.70/src/main.c bluez-5.71/src/main.c --- bluez-5.70/src/main.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/main.c 2023-12-14 05:40:27.000000000 +0800 @@ -1082,7 +1082,7 @@ &btd_opts.csis.encrypt); parse_config_u8(config, "CSIS", "Size", &btd_opts.csis.size, 0, UINT8_MAX); - parse_config_u8(config, "CSIS", "Rank", &btd_opts.csis.size, + parse_config_u8(config, "CSIS", "Rank", &btd_opts.csis.rank, 0, UINT8_MAX); } @@ -1195,6 +1195,7 @@ btd_opts.avdtp.stream_mode = BT_IO_MODE_BASIC; btd_opts.advmon.rssi_sampling_period = 0xFF; + btd_opts.csis.encrypt = true; } static void log_handler(const gchar *log_domain, GLogLevelFlags log_level, diff -Nru bluez-5.70/src/shared/ad.c bluez-5.71/src/shared/ad.c --- bluez-5.70/src/shared/ad.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/src/shared/ad.c 2023-12-14 05:40:27.000000000 +0800 @@ -1324,36 +1324,110 @@ return pattern; } -static void pattern_ad_data_match(void *data, void *user_data) +static bool match_manufacturer(const void *data, const void *user_data) { - struct bt_ad_data *ad_data = data; - struct pattern_match_info *info = user_data; - struct bt_ad_pattern *pattern; + const struct bt_ad_manufacturer_data *manufacturer_data = data; + const struct pattern_match_info *info = user_data; + const struct bt_ad_pattern *pattern; + uint8_t all_data[BT_AD_MAX_DATA_LEN]; + + if (!manufacturer_data || !info) + return false; + + if (info->matched_pattern) + return false; + + pattern = info->current_pattern; + + if (!pattern || pattern->type != BT_AD_MANUFACTURER_DATA) + return false; + + /* Take the manufacturer ID into account */ + if (manufacturer_data->len + 2 < pattern->offset + pattern->len) + return false; + + memcpy(&all_data[0], &manufacturer_data->manufacturer_id, 2); + memcpy(&all_data[2], manufacturer_data->data, manufacturer_data->len); + + if (!memcmp(all_data + pattern->offset, pattern->data, + pattern->len)) { + return true; + } + + return false; +} + +static bool match_service(const void *data, const void *user_data) +{ + const struct bt_ad_service_data *service_data = data; + const struct pattern_match_info *info = user_data; + const struct bt_ad_pattern *pattern; + + if (!service_data || !info) + return false; + + if (info->matched_pattern) + return false; + + pattern = info->current_pattern; + + if (!pattern) + return false; + + switch (pattern->type) { + case BT_AD_SERVICE_DATA16: + case BT_AD_SERVICE_DATA32: + case BT_AD_SERVICE_DATA128: + break; + default: + return false; + } + + if (service_data->len < pattern->offset + pattern->len) + return false; + + if (!memcmp(service_data->data + pattern->offset, pattern->data, + pattern->len)) { + return true; + } + + return false; +} + +static bool match_ad_data(const void *data, const void *user_data) +{ + const struct bt_ad_data *ad_data = data; + const struct pattern_match_info *info = user_data; + const struct bt_ad_pattern *pattern; if (!ad_data || !info) - return; + return false; if (info->matched_pattern) - return; + return false; pattern = info->current_pattern; if (!pattern || ad_data->type != pattern->type) - return; + return false; if (ad_data->len < pattern->offset + pattern->len) - return; + return false; if (!memcmp(ad_data->data + pattern->offset, pattern->data, pattern->len)) { - info->matched_pattern = pattern; + return true; } + + return false; } static void pattern_match(void *data, void *user_data) { struct bt_ad_pattern *pattern = data; struct pattern_match_info *info = user_data; + struct bt_ad *ad; + void *matched = NULL; if (!pattern || !info) return; @@ -1362,8 +1436,29 @@ return; info->current_pattern = pattern; + ad = info->ad; + + if (!ad) + return; + + switch (pattern->type) { + case BT_AD_MANUFACTURER_DATA: + matched = queue_find(ad->manufacturer_data, match_manufacturer, + user_data); + break; + case BT_AD_SERVICE_DATA16: + case BT_AD_SERVICE_DATA32: + case BT_AD_SERVICE_DATA128: + matched = queue_find(ad->service_data, match_service, + user_data); + break; + default: + matched = queue_find(ad->data, match_ad_data, user_data); + break; + } - bt_ad_foreach_data(info->ad, pattern_ad_data_match, info); + if (matched) + info->matched_pattern = info->current_pattern; } struct bt_ad_pattern *bt_ad_pattern_match(struct bt_ad *ad, diff -Nru bluez-5.70/src/shared/att.c bluez-5.71/src/shared/att.c --- bluez-5.70/src/shared/att.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/shared/att.c 2023-12-14 05:40:27.000000000 +0800 @@ -193,6 +193,7 @@ uint8_t opcode; void *pdu; uint16_t len; + bool retry; bt_att_response_func_t callback; bt_att_destroy_func_t destroy; void *user_data; @@ -785,6 +786,12 @@ *opcode = rsp->opcode; + /* If operation has already been marked as retry don't attempt to change + * the security again. + */ + if (op->retry) + return false; + /* Attempt to change security */ if (!change_security(chan, rsp->ecode)) return false; @@ -798,6 +805,7 @@ DBG(att, "(chan %p) Retrying operation %p", chan, op); chan->pending_req = NULL; + op->retry = true; /* Push operation back to channel queue */ return queue_push_head(chan->queue, op); diff -Nru bluez-5.70/src/shared/bap.c bluez-5.71/src/shared/bap.c --- bluez-5.70/src/shared/bap.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/src/shared/bap.c 2023-12-14 05:40:27.000000000 +0800 @@ -29,6 +29,7 @@ #include "src/shared/gatt-client.h" #include "src/shared/bap.h" #include "src/shared/ascs.h" +#include "src/shared/bap-debug.h" /* Maximum number of ASE(s) */ #define NUM_SINKS 2 @@ -47,14 +48,6 @@ #define BAP_PROCESS_TIMEOUT 10 -#define PACS_SRC_LOCATION 0x00000001 -#define PACS_SNK_LOCATION 0x00000003 - -#define PACS_SRC_CTXT 0x000f -#define PACS_SUPPORTED_SRC_CTXT PACS_SRC_CTXT -#define PACS_SNK_CTXT 0x0fff -#define PACS_SUPPORTED_SNK_CTXT PACS_SNK_CTXT - struct bt_bap_pac_changed { unsigned int id; bt_bap_pac_func_t added; @@ -474,14 +467,6 @@ pacs = new0(struct bt_pacs, 1); - /* Set default values */ - pacs->sink_loc_value = PACS_SNK_LOCATION; - pacs->source_loc_value = PACS_SRC_LOCATION; - pacs->sink_context_value = PACS_SNK_CTXT; - pacs->source_context_value = PACS_SRC_CTXT; - pacs->supported_sink_context_value = PACS_SUPPORTED_SNK_CTXT; - pacs->supported_source_context_value = PACS_SUPPORTED_SRC_CTXT; - /* Populate DB with PACS attributes */ bt_uuid16_create(&uuid, PACS_UUID); pacs->service = gatt_db_add_service(db, &uuid, true, 19); @@ -644,7 +629,7 @@ if (type == BT_BAP_BCAST_SINK) ep->dir = BT_BAP_BCAST_SOURCE; else - ep->dir = BT_BAP_BCAST_SINK; + ep->dir = 0; return ep; } @@ -1247,6 +1232,47 @@ bap_stream_io_detach(stream); } +static void bap_req_free(void *data) +{ + struct bt_bap_req *req = data; + size_t i; + + queue_destroy(req->group, bap_req_free); + + for (i = 0; i < req->len; i++) + free(req->iov[i].iov_base); + + free(req->iov); + free(req); +} + +static void bap_req_complete(struct bt_bap_req *req, + const struct bt_ascs_ase_rsp *rsp) +{ + struct queue *group; + + if (!req->func) + goto done; + + if (rsp) + req->func(req->stream, rsp->code, rsp->reason, req->user_data); + else + req->func(req->stream, BT_ASCS_RSP_UNSPECIFIED, 0x00, + req->user_data); + +done: + /* Detach from request so it can be freed separately */ + group = req->group; + req->group = NULL; + + queue_foreach(group, (queue_foreach_func_t)bap_req_complete, + (void *)rsp); + + queue_destroy(group, NULL); + + bap_req_free(req); +} + static void bap_stream_state_changed(struct bt_bap_stream *stream) { struct bt_bap *bap = stream->bap; @@ -1301,6 +1327,10 @@ /* Post notification updates */ switch (stream->ep->state) { case BT_ASCS_ASE_STATE_IDLE: + if (bap->req && bap->req->stream == stream) { + bap_req_complete(bap->req, NULL); + bap->req = NULL; + } bap_stream_detach(stream); break; case BT_ASCS_ASE_STATE_QOS: @@ -1331,6 +1361,11 @@ ep->old_state = ep->state; ep->state = state; + DBG(bap, "stream %p dir 0x%02x: %s -> %s", stream, + bt_bap_stream_get_dir(stream), + bt_bap_stream_statestr(stream->ep->old_state), + bt_bap_stream_statestr(stream->ep->state)); + bt_bap_ref(bap); for (entry = queue_get_entries(bap->state_cbs); entry; @@ -1347,6 +1382,9 @@ case BT_ASCS_ASE_STATE_IDLE: bap_stream_detach(stream); break; + case BT_ASCS_ASE_STATE_RELEASING: + bap_stream_io_detach(stream); + break; } bt_bap_unref(bap); @@ -1492,7 +1530,12 @@ return; if (bt_bap_stream_get_type(stream) == BT_BAP_STREAM_TYPE_BCAST) { - stream_set_state_broadcast(stream, BT_BAP_STREAM_STATE_CONFIG); + if (!bt_bap_stream_io_dir(stream)) + stream_set_state_broadcast(stream, + BT_BAP_STREAM_STATE_QOS); + else if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) + stream_set_state_broadcast(stream, + BT_BAP_STREAM_STATE_CONFIG); return; } @@ -1555,7 +1598,7 @@ cc.iov_base = util_iov_pull_mem(iov, req->cc_len); cc.iov_len = req->cc_len; - if (!bap_print_cc(cc.iov_base, cc.iov_len, bap->debug_func, + if (!bt_bap_debug_caps(cc.iov_base, cc.iov_len, bap->debug_func, bap->debug_data)) { ascs_ase_rsp_add(rsp, req->ase, BT_ASCS_RSP_CONF_INVALID, @@ -1722,49 +1765,6 @@ return 0; } -static bool bap_print_ltv(const char *label, void *data, size_t len, - util_debug_func_t func, void *user_data) -{ - struct iovec iov = { - .iov_base = data, - .iov_len = len, - }; - int i; - - util_debug(func, user_data, "Length %zu", iov.iov_len); - - for (i = 0; iov.iov_len > 1; i++) { - struct bt_ltv *ltv = util_iov_pull_mem(&iov, sizeof(*ltv)); - uint8_t *data; - - if (!ltv) { - util_debug(func, user_data, "Unable to parse %s", - label); - return false; - } - - util_debug(func, user_data, "%s #%u: len %u type %u", - label, i, ltv->len, ltv->type); - - data = util_iov_pull_mem(&iov, ltv->len - 1); - if (!data) { - util_debug(func, user_data, "Unable to parse %s", - label); - return false; - } - - util_hexdump(' ', ltv->value, ltv->len - 1, func, user_data); - } - - return true; -} - -static bool bap_print_metadata(void *data, size_t len, util_debug_func_t func, - void *user_data) -{ - return bap_print_ltv("Metadata", data, len, func, user_data); -} - static uint8_t ep_enable(struct bt_bap_endpoint *ep, struct bt_bap *bap, struct bt_ascs_enable *req, struct iovec *iov, struct iovec *rsp) @@ -1788,8 +1788,8 @@ meta.iov_base = util_iov_pull_mem(iov, req->meta.len); meta.iov_len = req->meta.len; - if (!bap_print_metadata(meta.iov_base, meta.iov_len, bap->debug_func, - bap->debug_data)) { + if (!bt_bap_debug_metadata(meta.iov_base, meta.iov_len, + bap->debug_func, bap->debug_data)) { ascs_ase_rsp_add(rsp, ep->id, BT_ASCS_RSP_METADATA_INVALID, BT_ASCS_REASON_NONE); @@ -2468,6 +2468,78 @@ free(pac); } +static void pacs_sink_location_changed(struct bt_pacs *pacs) +{ + uint32_t location = cpu_to_le32(pacs->sink_loc_value); + + gatt_db_attribute_notify(pacs->sink_loc, (void *)&location, + sizeof(location), NULL); +} + +static void pacs_add_sink_location(struct bt_pacs *pacs, uint32_t location) +{ + /* Check if location value needs updating */ + if (location == pacs->sink_loc_value) + return; + + pacs->sink_loc_value |= location; + + pacs_sink_location_changed(pacs); +} + +static void pacs_supported_context_changed(struct bt_pacs *pacs) +{ + struct bt_pacs_context ctx; + + memset(&ctx, 0, sizeof(ctx)); + + ctx.snk = cpu_to_le16(pacs->supported_sink_context_value); + ctx.src = cpu_to_le16(pacs->supported_source_context_value); + + gatt_db_attribute_notify(pacs->supported_context, (void *)&ctx, + sizeof(ctx), NULL); +} + +static void pacs_add_sink_supported_context(struct bt_pacs *pacs, + uint16_t context) +{ + context |= pacs->supported_sink_context_value; + + /* Check if context value needs updating */ + if (context == pacs->supported_sink_context_value) + return; + + pacs->supported_sink_context_value = context; + + pacs_supported_context_changed(pacs); +} + +static void pacs_context_changed(struct bt_pacs *pacs) +{ + struct bt_pacs_context ctx; + + memset(&ctx, 0, sizeof(ctx)); + + ctx.snk = cpu_to_le16(pacs->sink_context_value); + ctx.src = cpu_to_le16(pacs->source_context_value); + + gatt_db_attribute_notify(pacs->context, (void *)&ctx, sizeof(ctx), + NULL); +} + +static void pacs_add_sink_context(struct bt_pacs *pacs, uint16_t context) +{ + context |= pacs->supported_sink_context_value; + + /* Check if context value needs updating */ + if (context == pacs->sink_context_value) + return; + + pacs->sink_context_value = context; + + pacs_context_changed(pacs); +} + static void bap_add_sink(struct bt_bap_pac *pac) { struct iovec iov; @@ -2482,10 +2554,62 @@ queue_foreach(pac->bdb->sinks, pac_foreach, &iov); + pacs_add_sink_location(pac->bdb->pacs, pac->qos.location); + pacs_add_sink_supported_context(pac->bdb->pacs, + pac->qos.supported_context); + pacs_add_sink_context(pac->bdb->pacs, pac->qos.context); gatt_db_attribute_notify(pac->bdb->pacs->sink, iov.iov_base, iov.iov_len, NULL); } +static void pacs_source_location_changed(struct bt_pacs *pacs) +{ + uint32_t location = cpu_to_le32(pacs->source_loc_value); + + gatt_db_attribute_notify(pacs->source_loc, (void *)&location, + sizeof(location), NULL); +} + +static void pacs_add_source_location(struct bt_pacs *pacs, uint32_t location) +{ + location |= pacs->source_loc_value; + + /* Check if location value needs updating */ + if (location == pacs->source_loc_value) + return; + + pacs->source_loc_value = location; + + pacs_source_location_changed(pacs); +} + +static void pacs_add_source_supported_context(struct bt_pacs *pacs, + uint16_t context) +{ + context |= pacs->supported_source_context_value; + + /* Check if context value needs updating */ + if (context == pacs->supported_source_context_value) + return; + + pacs->supported_source_context_value = context; + + pacs_supported_context_changed(pacs); +} + +static void pacs_add_source_context(struct bt_pacs *pacs, uint16_t context) +{ + context |= pacs->supported_source_context_value; + + /* Check if context value needs updating */ + if (context == pacs->source_context_value) + return; + + pacs->source_context_value = context; + + pacs_context_changed(pacs); +} + static void bap_add_source(struct bt_bap_pac *pac) { struct iovec iov; @@ -2498,7 +2622,12 @@ iov.iov_base = value; iov.iov_len = 0; - queue_foreach(pac->bdb->sinks, pac_foreach, &iov); + queue_foreach(pac->bdb->sources, pac_foreach, &iov); + + pacs_add_source_location(pac->bdb->pacs, pac->qos.location); + pacs_add_source_supported_context(pac->bdb->pacs, + pac->qos.supported_context); + pacs_add_source_context(pac->bdb->pacs, pac->qos.context); gatt_db_attribute_notify(pac->bdb->pacs->source, iov.iov_base, iov.iov_len, NULL); @@ -2538,7 +2667,7 @@ struct iovec *metadata) { struct bt_bap_db *bdb; - struct bt_bap_pac *pac, *pac_broadcast_sink; + struct bt_bap_pac *pac; struct bt_bap_codec codec; if (!db) @@ -2566,15 +2695,6 @@ break; case BT_BAP_BCAST_SOURCE: bap_add_broadcast_source(pac); - if (queue_isempty(bdb->broadcast_sinks)) { - /* When adding a local broadcast source, add also a - * local broadcast sink - */ - pac_broadcast_sink = bap_pac_new(bdb, name, - BT_BAP_BCAST_SINK, &codec, qos, - data, metadata); - bap_add_broadcast_sink(pac_broadcast_sink); - } break; case BT_BAP_BCAST_SINK: bap_add_broadcast_sink(pac); @@ -2609,7 +2729,12 @@ uint32_t bt_bap_pac_get_locations(struct bt_bap_pac *pac) { - struct bt_pacs *pacs = pac->bdb->pacs; + struct bt_pacs *pacs; + + if (!pac) + return 0; + + pacs = pac->bdb->pacs; switch (pac->type) { case BT_BAP_SOURCE: @@ -2621,6 +2746,52 @@ } } +uint16_t bt_bap_pac_get_supported_context(struct bt_bap_pac *pac) +{ + struct bt_pacs *pacs; + + if (!pac) + return 0; + + pacs = pac->bdb->pacs; + + switch (pac->type) { + case BT_BAP_SOURCE: + return pacs->supported_source_context_value; + case BT_BAP_SINK: + return pacs->supported_sink_context_value; + default: + return 0; + } +} + +uint16_t bt_bap_pac_get_context(struct bt_bap_pac *pac) +{ + struct bt_pacs *pacs; + + if (!pac) + return 0; + + pacs = pac->bdb->pacs; + + switch (pac->type) { + case BT_BAP_SOURCE: + return pacs->source_context_value; + case BT_BAP_SINK: + return pacs->sink_context_value; + default: + return 0; + } +} + +struct bt_bap_pac_qos *bt_bap_pac_get_qos(struct bt_bap_pac *pac) +{ + if (!pac || !pac->qos.phy) + return NULL; + + return &pac->qos; +} + uint8_t bt_bap_stream_get_type(struct bt_bap_stream *stream) { if (!stream) @@ -2685,13 +2856,48 @@ bt_bap_stream_release(stream, NULL, NULL); } +static void bap_pac_sink_removed(void *data, void *user_data) +{ + struct bt_bap_pac *pac = data; + struct bt_bap_pac_qos *qos = user_data; + + qos->location |= pac->qos.location; + qos->supported_context |= pac->qos.supported_context; + qos->context |= pac->qos.context; +} + bool bt_bap_remove_pac(struct bt_bap_pac *pac) { if (!pac) return false; - if (queue_remove_if(pac->bdb->sinks, NULL, pac)) + if (queue_remove_if(pac->bdb->sinks, NULL, pac)) { + struct bt_pacs *pacs = pac->bdb->pacs; + struct bt_bap_pac_qos qos; + + memset(&qos, 0, sizeof(qos)); + queue_foreach(pac->bdb->sinks, bap_pac_sink_removed, &qos); + + if (pacs->sink_loc_value != qos.location) { + pacs->sink_loc_value = qos.location; + pacs_sink_location_changed(pacs); + } + + if (pacs->supported_sink_context_value != + qos.supported_context) { + pacs->supported_sink_context_value = + qos.supported_context; + pacs_supported_context_changed(pacs); + } + + if (pacs->sink_context_value != qos.context) { + pacs->sink_context_value = qos.context; + pacs_context_changed(pacs); + } + + goto found; + } if (queue_remove_if(pac->bdb->sources, NULL, pac)) goto found; @@ -2744,20 +2950,6 @@ free(state); } -static void bap_req_free(void *data) -{ - struct bt_bap_req *req = data; - size_t i; - - queue_destroy(req->group, bap_req_free); - - for (i = 0; i < req->len; i++) - free(req->iov[i].iov_base); - - free(req->iov); - free(req); -} - static void bap_detached(void *data, void *user_data) { struct bt_bap_cb *cb = data; @@ -2945,12 +3137,6 @@ bt_bap_unref(bap); } -bool bap_print_cc(void *data, size_t len, util_debug_func_t func, - void *user_data) -{ - return bap_print_ltv("CC", data, len, func, user_data); -} - static void bap_parse_pacs(struct bt_bap *bap, uint8_t type, struct queue *queue, const uint8_t *value, @@ -2991,7 +3177,7 @@ pac = NULL; - if (!bap_print_cc(iov.iov_base, p->cc_len, bap->debug_func, + if (!bt_bap_debug_caps(iov.iov_base, p->cc_len, bap->debug_func, bap->debug_data)) return; @@ -3654,6 +3840,11 @@ DBG(bap, "req %p len %u", req, iov.iov_len); + if (req->stream && !queue_find(bap->streams, NULL, req->stream)) { + DBG(bap, "stream %p detached, aborting op 0x%02x", req->op); + return false; + } + if (!gatt_db_attribute_get_char_data(ascs->ase_cp, NULL, &handle, NULL, NULL, NULL)) { DBG(bap, "Unable to find Control Point"); @@ -3688,33 +3879,6 @@ return true; } -static void bap_req_complete(struct bt_bap_req *req, - const struct bt_ascs_ase_rsp *rsp) -{ - struct queue *group; - - if (!req->func) - goto done; - - if (rsp) - req->func(req->stream, rsp->code, rsp->reason, req->user_data); - else - req->func(req->stream, BT_ASCS_RSP_UNSPECIFIED, 0x00, - req->user_data); - -done: - /* Detach from request so it can be freed separately */ - group = req->group; - req->group = NULL; - - queue_foreach(group, (queue_foreach_func_t)bap_req_complete, - (void *)rsp); - - queue_destroy(group, NULL); - - bap_req_free(req); -} - static bool bap_process_queue(void *data) { struct bt_bap *bap = data; @@ -4252,21 +4416,12 @@ func, user_data); case BT_BAP_SOURCE: return bap_foreach_pac(bap->ldb->sinks, bap->rdb->sources, - func, user_data); + func, user_data); case BT_BAP_BCAST_SOURCE: - if (queue_isempty(bap->rdb->broadcast_sources) - && queue_isempty(bap->rdb->broadcast_sinks)) - return bap_foreach_pac(bap->ldb->broadcast_sources, - bap->ldb->broadcast_sinks, - func, user_data); - - return bap_foreach_pac(bap->ldb->broadcast_sinks, - bap->rdb->broadcast_sources, - func, user_data); case BT_BAP_BCAST_SINK: return bap_foreach_pac(bap->ldb->broadcast_sinks, - bap->rdb->broadcast_sources, - func, user_data); + bap->rdb->broadcast_sources, + func, user_data); } } @@ -4311,6 +4466,20 @@ return pac->user_data; } +bool bt_bap_pac_bcast_is_local(struct bt_bap *bap, struct bt_bap_pac *pac) +{ + if (!bap->ldb) + return false; + + if (queue_find(bap->ldb->broadcast_sinks, NULL, pac)) + return true; + + if (queue_find(bap->ldb->broadcast_sources, NULL, pac)) + return true; + + return false; +} + static bool find_ep_unused(const void *data, const void *user_data) { const struct bt_bap_endpoint *ep = data; @@ -4319,7 +4488,10 @@ if (ep->stream) return false; - return ep->dir == match->rpac->type; + if (match->rpac) + return ep->dir == match->rpac->type; + else + return true; } static bool find_ep_pacs(const void *data, const void *user_data) @@ -4402,7 +4574,7 @@ iov[0].iov_len = sizeof(config); if (data) { - if (!bap_print_cc(data->iov_base, data->iov_len, + if (!bt_bap_debug_config(data->iov_base, data->iov_len, stream->bap->debug_func, stream->bap->debug_data)) return 0; @@ -4478,7 +4650,11 @@ struct bt_bap_endpoint *ep; struct match_pac match; - if (!bap || !bap->rdb || queue_isempty(bap->remote_eps)) + if (!bap) + return NULL; + + if (!rpac && (lpac->type != BT_BAP_BCAST_SOURCE) + && queue_isempty(bap->remote_eps)) return NULL; if (lpac && rpac) { @@ -4515,7 +4691,9 @@ return NULL; bt_bap_foreach_pac(bap, type, match_pac, &match); - if (!match.lpac || !match.rpac) + if (!match.lpac) + return NULL; + if (!match.rpac && (lpac->type != BT_BAP_BCAST_SOURCE)) return NULL; lpac = match.lpac; @@ -4697,8 +4875,13 @@ queue_foreach(stream->links, bap_stream_enable_link, metadata); break; case BT_BAP_STREAM_TYPE_BCAST: - stream_set_state_broadcast(stream, - BT_BAP_STREAM_STATE_STREAMING); + if (!bt_bap_stream_io_dir(stream)) + stream_set_state_broadcast(stream, + BT_BAP_STREAM_STATE_CONFIG); + else if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) + stream_set_state_broadcast(stream, + BT_BAP_STREAM_STATE_STREAMING); + return 1; } @@ -4716,30 +4899,40 @@ if (!bap_stream_valid(stream)) return 0; - if (!stream->client) { + switch (bt_bap_stream_get_type(stream)) { + case BT_BAP_STREAM_TYPE_UCAST: + if (!stream->client) { + if (stream->ep->dir == BT_BAP_SINK) + stream_start(stream, NULL); + return 0; + } + if (stream->ep->dir == BT_BAP_SINK) - stream_start(stream, NULL); - return 0; - } + return 0; - if (stream->ep->dir == BT_BAP_SINK) - return 0; + memset(&start, 0, sizeof(start)); - memset(&start, 0, sizeof(start)); + start.ase = stream->ep->id; - start.ase = stream->ep->id; + iov.iov_base = &start; + iov.iov_len = sizeof(start); - iov.iov_base = &start; - iov.iov_len = sizeof(start); + req = bap_req_new(stream, BT_ASCS_START, + &iov, 1, func, user_data); - req = bap_req_new(stream, BT_ASCS_START, &iov, 1, func, user_data); + if (!bap_queue_req(stream->bap, req)) { + bap_req_free(req); + return 0; + } - if (!bap_queue_req(stream->bap, req)) { - bap_req_free(req); - return 0; + return req->id; + case BT_BAP_STREAM_TYPE_BCAST: + stream_set_state_broadcast(stream, + BT_BAP_STREAM_STATE_STREAMING); + return 1; } - return req->id; + return 0; } static void bap_stream_disable_link(void *data, void *user_data) @@ -4779,24 +4972,36 @@ return 0; } - memset(&disable, 0, sizeof(disable)); + switch (bt_bap_stream_get_type(stream)) { + case BT_BAP_STREAM_TYPE_UCAST: + memset(&disable, 0, sizeof(disable)); - disable.ase = stream->ep->id; + disable.ase = stream->ep->id; - iov.iov_base = &disable; - iov.iov_len = sizeof(disable); + iov.iov_base = &disable; + iov.iov_len = sizeof(disable); - req = bap_req_new(stream, BT_ASCS_DISABLE, &iov, 1, func, user_data); + req = bap_req_new(stream, BT_ASCS_DISABLE, &iov, 1, func, + user_data); - if (!bap_queue_req(stream->bap, req)) { - bap_req_free(req); - return 0; - } + if (!bap_queue_req(stream->bap, req)) { + bap_req_free(req); + return 0; + } - if (disable_links) - queue_foreach(stream->links, bap_stream_disable_link, NULL); + if (disable_links) + queue_foreach(stream->links, bap_stream_disable_link, + NULL); - return req->id; + return req->id; + + case BT_BAP_STREAM_TYPE_BCAST: + stream_set_state_broadcast(stream, + BT_BAP_STREAM_STATE_RELEASING); + return 1; + } + + return 0; } unsigned int bt_bap_stream_stop(struct bt_bap_stream *stream, @@ -5210,10 +5415,6 @@ /* Add the remote source only if a local sink endpoint was registered */ if (queue_isempty(bap->ldb->broadcast_sinks)) - return false; - - /* Add the remote source only if a local sink endpoint was registered */ - if (queue_isempty(bap->ldb->broadcast_sinks)) return false; /* Add remote source endpoint */ diff -Nru bluez-5.70/src/shared/bap-debug.c bluez-5.71/src/shared/bap-debug.c --- bluez-5.70/src/shared/bap-debug.c 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/src/shared/bap-debug.c 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,543 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2023 Intel Corporation. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "src/shared/util.h" +#include "src/shared/bap-debug.h" + +static const struct util_bit_debugger pac_freq_table[] = { + UTIL_BIT_DEBUG(0, "8 Khz (0x0001)"), + UTIL_BIT_DEBUG(1, "11.25 Khz (0x0002)"), + UTIL_BIT_DEBUG(2, "16 Khz (0x0004)"), + UTIL_BIT_DEBUG(3, "22.05 Khz (0x0008)"), + UTIL_BIT_DEBUG(4, "24 Khz (0x0010)"), + UTIL_BIT_DEBUG(5, "32 Khz (0x0020)"), + UTIL_BIT_DEBUG(6, "44.1 Khz (0x0040)"), + UTIL_BIT_DEBUG(7, "48 Khz (0x0080)"), + UTIL_BIT_DEBUG(8, "88.2 Khz (0x0100)"), + UTIL_BIT_DEBUG(9, "96 Khz (0x0200)"), + UTIL_BIT_DEBUG(10, "176.4 Khz (0x0400)"), + UTIL_BIT_DEBUG(11, "192 Khz (0x0800)"), + UTIL_BIT_DEBUG(12, "384 Khz (0x1000)"), + UTIL_BIT_DEBUG(13, "RFU (0x2000)"), + UTIL_BIT_DEBUG(14, "RFU (0x4000)"), + UTIL_BIT_DEBUG(15, "RFU (0x8000)"), + { } +}; + +static void pac_debug_freq(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint16_t value; + uint16_t mask; + + if (!util_iov_pull_le16(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Sampling Frequencies: 0x%4.4x", value); + + mask = util_debug_bit("Sampling Frequency: ", value, pac_freq_table, + func, user_data); + if (mask) + util_debug(func, user_data, "Unknown fields (0x%4.4x)", + mask); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static const struct util_bit_debugger pac_duration_table[] = { + UTIL_BIT_DEBUG(0, "7.5 ms (0x01)"), + UTIL_BIT_DEBUG(1, "10 ms (0x02)"), + UTIL_BIT_DEBUG(2, "RFU (0x04)"), + UTIL_BIT_DEBUG(3, "RFU (0x08)"), + UTIL_BIT_DEBUG(4, "7.5 ms preferred (0x10)"), + UTIL_BIT_DEBUG(5, "10 ms preferred (0x20)"), + UTIL_BIT_DEBUG(6, "RFU (0x40)"), + UTIL_BIT_DEBUG(7, "RFU (0x80)"), + { } +}; + +static void pac_debug_duration(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint8_t value; + uint8_t mask; + + if (!util_iov_pull_u8(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Frame Duration: 0x%2.2x", value); + + mask = util_debug_bit("Frame Duration: ", value, pac_duration_table, + func, user_data); + if (mask) + util_debug(func, user_data, "Unknown fields (0x%2.2x)", + mask); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static const struct util_bit_debugger pac_channel_table[] = { + UTIL_BIT_DEBUG(0, "1 channel (0x01)"), + UTIL_BIT_DEBUG(1, "2 channel (0x02)"), + UTIL_BIT_DEBUG(2, "3 channel (0x04)"), + UTIL_BIT_DEBUG(3, "4 channel (0x08)"), + UTIL_BIT_DEBUG(4, "5 channel (0x10)"), + UTIL_BIT_DEBUG(5, "6 channel (0x20)"), + UTIL_BIT_DEBUG(6, "7 channel (0x40)"), + UTIL_BIT_DEBUG(7, "8 channel (0x80)"), + { } +}; + +static void pac_debug_channels(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint8_t value; + uint8_t mask; + + if (!util_iov_pull_u8(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Audio Channel Count: 0x%2.2x", value); + + mask = util_debug_bit("Audio Channel Count: ", value, + pac_channel_table, func, user_data); + if (mask) + util_debug(func, user_data, "Unknown fields (0x%2.2x)", + mask); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static void pac_debug_frame_length(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint16_t min, max; + + if (!util_iov_pull_le16(&frame, &min)) { + util_debug(func, user_data, "min: invalid size"); + goto done; + } + + if (!util_iov_pull_le16(&frame, &max)) { + util_debug(func, user_data, "max: invalid size"); + goto done; + } + + util_debug(func, user_data, + "Frame Length: %u (0x%4.4x) - %u (0x%4.4x)", + min, min, max, max); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static void pac_debug_sdu(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint8_t value; + + if (!util_iov_pull_u8(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Max SDU: %u (0x%2.2x)", value, value); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static const struct util_ltv_debugger pac_cap_table[] = { + UTIL_LTV_DEBUG(0x01, pac_debug_freq), + UTIL_LTV_DEBUG(0x02, pac_debug_duration), + UTIL_LTV_DEBUG(0x03, pac_debug_channels), + UTIL_LTV_DEBUG(0x04, pac_debug_frame_length), + UTIL_LTV_DEBUG(0x05, pac_debug_sdu) +}; + +bool bt_bap_debug_caps(void *data, size_t len, util_debug_func_t func, + void *user_data) +{ + return util_debug_ltv(data, len, pac_cap_table, + ARRAY_SIZE(pac_cap_table), + func, user_data); +} + +static void ase_debug_freq(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint8_t value; + + if (!util_iov_pull_u8(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + switch (value) { + case 0x01: + util_debug(func, user_data, "Sampling Frequency: 8 Khz (0x01)"); + break; + case 0x02: + util_debug(func, user_data, + "Sampling Frequency: 11.25 Khz (0x02)"); + break; + case 0x03: + util_debug(func, user_data, + "Sampling Frequency: 16 Khz (0x03)"); + break; + case 0x04: + util_debug(func, user_data, + "Sampling Frequency: 22.05 Khz (0x04)"); + break; + case 0x05: + util_debug(func, user_data, + "Sampling Frequency: 24 Khz (0x05)"); + break; + case 0x06: + util_debug(func, user_data, + "Sampling Frequency: 32 Khz (0x06)"); + break; + case 0x07: + util_debug(func, user_data, + "Sampling Frequency: 44.1 Khz (0x07)"); + break; + case 0x08: + util_debug(func, user_data, + "Sampling Frequency: 48 Khz (0x08)"); + break; + case 0x09: + util_debug(func, user_data, + "Sampling Frequency: 88.2 Khz (0x09)"); + break; + case 0x0a: + util_debug(func, user_data, + "Sampling Frequency: 96 Khz (0x0a)"); + break; + case 0x0b: + util_debug(func, user_data, + "Sampling Frequency: 176.4 Khz (0x0b)"); + break; + case 0x0c: + util_debug(func, user_data, + "Sampling Frequency: 192 Khz (0x0c)"); + break; + case 0x0d: + util_debug(func, user_data, + "Sampling Frequency: 384 Khz (0x0d)"); + break; + default: + util_debug(func, user_data, + "Sampling Frequency: RFU (0x%2.2x)", value); + break; + } + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static void ase_debug_duration(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint8_t value; + + if (!util_iov_pull_u8(&frame, &value)) { + util_debug(func, user_data, "\tvalue: invalid size\n"); + goto done; + } + + switch (value) { + case 0x00: + util_debug(func, user_data, "Frame Duration: 7.5 ms (0x00)"); + break; + case 0x01: + util_debug(func, user_data, "Frame Duration: 10 ms (0x01)"); + break; + default: + util_debug(func, user_data, "Frame Duration: RFU (0x%2.2x)", + value); + break; + } + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static const struct util_bit_debugger channel_location_table[] = { + UTIL_BIT_DEBUG(0, "Front Left (0x00000001)"), + UTIL_BIT_DEBUG(1, "Front Right (0x00000002)"), + UTIL_BIT_DEBUG(2, "Front Center (0x00000004)"), + UTIL_BIT_DEBUG(3, "Low Frequency Effects 1 (0x00000008)"), + UTIL_BIT_DEBUG(4, "Back Left (0x00000010)"), + UTIL_BIT_DEBUG(5, "Back Right (0x00000020)"), + UTIL_BIT_DEBUG(6, "Front Left of Center (0x00000040)"), + UTIL_BIT_DEBUG(7, "Front Right of Center (0x00000080)"), + UTIL_BIT_DEBUG(8, "Back Center (0x00000100)"), + UTIL_BIT_DEBUG(9, "Low Frequency Effects 2 (0x00000200)"), + UTIL_BIT_DEBUG(10, "Side Left (0x00000400)"), + UTIL_BIT_DEBUG(11, "Side Right (0x00000800)"), + UTIL_BIT_DEBUG(12, "Top Front Left (0x00001000)"), + UTIL_BIT_DEBUG(13, "Top Front Right (0x00002000)"), + UTIL_BIT_DEBUG(14, "Top Front Center (0x00004000)"), + UTIL_BIT_DEBUG(15, "Top Center (0x00008000)"), + UTIL_BIT_DEBUG(16, "Top Back Left (0x00010000)"), + UTIL_BIT_DEBUG(17, "Top Back Right (0x00020000)"), + UTIL_BIT_DEBUG(18, "Top Side Left (0x00040000)"), + UTIL_BIT_DEBUG(19, "Top Side Right (0x00080000)"), + UTIL_BIT_DEBUG(20, "Top Back Center (0x00100000)"), + UTIL_BIT_DEBUG(21, "Bottom Front Center (0x00200000)"), + UTIL_BIT_DEBUG(22, "Bottom Front Left (0x00400000)"), + UTIL_BIT_DEBUG(23, "Bottom Front Right (0x00800000)"), + UTIL_BIT_DEBUG(24, "Front Left Wide (0x01000000)"), + UTIL_BIT_DEBUG(25, "Front Right Wide (0x02000000)"), + UTIL_BIT_DEBUG(26, "Left Surround (0x04000000)"), + UTIL_BIT_DEBUG(27, "Right Surround (0x08000000)"), + UTIL_BIT_DEBUG(28, "RFU (0x10000000)"), + UTIL_BIT_DEBUG(29, "RFU (0x20000000)"), + UTIL_BIT_DEBUG(30, "RFU (0x40000000)"), + UTIL_BIT_DEBUG(31, "RFU (0x80000000)"), + { } +}; + +static void debug_location(const struct iovec *frame, util_debug_func_t func, + void *user_data) +{ + uint32_t value; + uint32_t mask; + + if (!util_iov_pull_le32((void *)frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Location: 0x%8.8x", value); + + mask = util_debug_bit("Location: ", value, channel_location_table, + func, user_data); + if (mask) + util_debug(func, user_data, "Unknown fields (0x%8.8x)", mask); + +done: + if (frame->iov_len) + util_hexdump(' ', frame->iov_base, frame->iov_len, func, + user_data); +} + +static void ase_debug_location(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + + debug_location(&frame, func, user_data); +} + +static void ase_debug_frame_length(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint16_t value; + + if (!util_iov_pull_le16(&frame, &value)) { + util_debug(func, user_data, "\tvalue: invalid size\n"); + goto done; + } + + util_debug(func, user_data, "Frame Length: %u (0x%4.4x)", + value, value); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static void ase_debug_blocks(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint8_t value; + + if (!util_iov_pull_u8(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Frame Blocks per SDU: %u (0x%2.2x)", + value, value); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static const struct util_ltv_debugger ase_cc_table[] = { + UTIL_LTV_DEBUG(0x01, ase_debug_freq), + UTIL_LTV_DEBUG(0x02, ase_debug_duration), + UTIL_LTV_DEBUG(0x03, ase_debug_location), + UTIL_LTV_DEBUG(0x04, ase_debug_frame_length), + UTIL_LTV_DEBUG(0x05, ase_debug_blocks) +}; + +bool bt_bap_debug_config(void *data, size_t len, util_debug_func_t func, + void *user_data) +{ + return util_debug_ltv(data, len, ase_cc_table, + ARRAY_SIZE(ase_cc_table), + func, user_data); +} + +static const struct util_bit_debugger pac_context_table[] = { + UTIL_BIT_DEBUG(0, "\tUnspecified (0x0001)"), + UTIL_BIT_DEBUG(1, "\tConversational (0x0002)"), + UTIL_BIT_DEBUG(2, "\tMedia (0x0004)"), + UTIL_BIT_DEBUG(3, "\tGame (0x0008)"), + UTIL_BIT_DEBUG(4, "\tInstructional (0x0010)"), + UTIL_BIT_DEBUG(5, "\tVoice Assistants (0x0020)"), + UTIL_BIT_DEBUG(6, "\tLive (0x0040)"), + UTIL_BIT_DEBUG(7, "\tSound Effects (0x0080)"), + UTIL_BIT_DEBUG(8, "\tNotifications (0x0100)"), + UTIL_BIT_DEBUG(9, "\tRingtone (0x0200)"), + UTIL_BIT_DEBUG(10, "\tAlerts (0x0400)"), + UTIL_BIT_DEBUG(11, "\tEmergency alarm (0x0800)"), + UTIL_BIT_DEBUG(12, "\tRFU (0x1000)"), + UTIL_BIT_DEBUG(13, "\tRFU (0x2000)"), + UTIL_BIT_DEBUG(14, "\tRFU (0x4000)"), + UTIL_BIT_DEBUG(15, "\tRFU (0x8000)"), + { } +}; + +static void debug_context(const struct iovec *frame, const char *label, + util_debug_func_t func, void *user_data) +{ + uint16_t value; + uint16_t mask; + + if (!util_iov_pull_le16((void *)frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "%s: 0x%4.4x", label, value); + + mask = util_debug_bit(label, value, pac_context_table, func, user_data); + if (mask) + util_debug(func, user_data, "Unknown fields (0x%4.4x)", mask); + +done: + if (frame->iov_len) + util_hexdump(' ', frame->iov_base, frame->iov_len, func, + user_data); +} + +static void ase_debug_preferred_context(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + + debug_context(&frame, "Preferred Context", func, user_data); +} + +static void ase_debug_context(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + + debug_context(&frame, "Context", func, user_data); +} + +static void ase_debug_program_info(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + const char *str; + + str = util_iov_pull_mem(&frame, len); + if (!str) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Program Info: %*s", len, str); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static void ase_debug_language(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data) +{ + struct iovec frame = { (void *)data, len }; + uint32_t value; + + if (!util_iov_pull_le24(&frame, &value)) { + util_debug(func, user_data, "value: invalid size"); + goto done; + } + + util_debug(func, user_data, "Language: 0x%6.6x\n", value); + +done: + if (frame.iov_len) + util_hexdump(' ', frame.iov_base, frame.iov_len, func, + user_data); +} + +static const struct util_ltv_debugger ase_metadata_table[] = { + UTIL_LTV_DEBUG(0x01, ase_debug_preferred_context), + UTIL_LTV_DEBUG(0x02, ase_debug_context), + UTIL_LTV_DEBUG(0x03, ase_debug_program_info), + UTIL_LTV_DEBUG(0x04, ase_debug_language) +}; + +bool bt_bap_debug_metadata(void *data, size_t len, util_debug_func_t func, + void *user_data) +{ + return util_debug_ltv(data, len, ase_metadata_table, + ARRAY_SIZE(ase_metadata_table), + func, user_data); +} diff -Nru bluez-5.70/src/shared/bap-debug.h bluez-5.71/src/shared/bap-debug.h --- bluez-5.70/src/shared/bap-debug.h 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/src/shared/bap-debug.h 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2023 Intel Corporation. + */ + +bool bt_bap_debug_caps(void *data, size_t len, util_debug_func_t func, + void *user_data); +bool bt_bap_debug_config(void *data, size_t len, util_debug_func_t func, + void *user_data); +bool bt_bap_debug_metadata(void *data, size_t len, util_debug_func_t func, + void *user_data); diff -Nru bluez-5.70/src/shared/bap.h bluez-5.71/src/shared/bap.h --- bluez-5.70/src/shared/bap.h 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/src/shared/bap.h 2023-12-14 05:40:27.000000000 +0800 @@ -75,7 +75,7 @@ struct bt_bap_bcast_qos { uint8_t big; uint8_t bis; - uint8_t sync_interval; + uint8_t sync_factor; uint8_t packing; uint8_t framing; uint8_t encryption; @@ -131,6 +131,9 @@ uint32_t pd_max; uint32_t ppd_min; uint32_t ppd_max; + uint32_t location; + uint16_t supported_context; + uint16_t context; }; struct bt_bap_pac *bt_bap_add_vendor_pac(struct gatt_db *db, @@ -165,6 +168,12 @@ uint32_t bt_bap_pac_get_locations(struct bt_bap_pac *pac); +uint16_t bt_bap_pac_get_supported_context(struct bt_bap_pac *pac); + +uint16_t bt_bap_pac_get_context(struct bt_bap_pac *pac); + +struct bt_bap_pac_qos *bt_bap_pac_get_qos(struct bt_bap_pac *pac); + uint8_t bt_bap_stream_get_type(struct bt_bap_stream *stream); struct bt_bap_stream *bt_bap_pac_get_stream(struct bt_bap_pac *pac); @@ -192,9 +201,6 @@ bool bt_bap_set_debug(struct bt_bap *bap, bt_bap_debug_func_t cb, void *user_data, bt_bap_destroy_func_t destroy); -bool bap_print_cc(void *data, size_t len, util_debug_func_t func, - void *user_data); - unsigned int bt_bap_pac_register(struct bt_bap *bap, bt_bap_pac_func_t added, bt_bap_pac_func_t removed, void *user_data, bt_bap_destroy_func_t destroy); @@ -311,3 +317,6 @@ struct bt_bap_codec *codec, struct iovec *data, struct iovec *metadata); + +bool bt_bap_pac_bcast_is_local(struct bt_bap *bap, struct bt_bap_pac *pac); + diff -Nru bluez-5.70/src/shared/bass.c bluez-5.71/src/shared/bass.c --- bluez-5.70/src/shared/bass.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/shared/bass.c 2023-12-14 05:40:27.000000000 +0800 @@ -102,7 +102,7 @@ .bcast = { .big = BT_ISO_QOS_BIG_UNSET, .bis = BT_ISO_QOS_BIS_UNSET, - .sync_interval = 0x07, + .sync_factor = 0x07, .packing = 0x00, .framing = 0x00, .in = DEFAULT_IO_QOS, @@ -132,22 +132,21 @@ va_end(ap); } -static int -bass_build_bcast_src_from_notif(struct bt_bcast_src *bcast_src, +static int bass_build_bcast_src(struct bt_bcast_src *bcast_src, const uint8_t *value, uint16_t length) { struct bt_bass_subgroup_data *subgroup_data = NULL; - uint8_t *id; - uint8_t *addr_type; + uint8_t id; + uint8_t addr_type; uint8_t *addr; - uint8_t *sid; + uint8_t sid; uint32_t bid; - uint8_t *pa_sync_state; - uint8_t *enc; + uint8_t pa_sync_state; + uint8_t enc; uint8_t *bad_code = NULL; - uint8_t *num_subgroups; + uint8_t num_subgroups; uint32_t bis_sync_state; - uint8_t *meta_len; + uint8_t meta_len; uint8_t *meta; struct iovec iov = { @@ -156,14 +155,12 @@ }; /* Extract all fields from notification */ - id = util_iov_pull_mem(&iov, sizeof(*id)); - if (!id) { + if (!util_iov_pull_u8(&iov, &id)) { DBG(bcast_src->bass, "Unable to parse Broadcast Receive State"); return -1; } - addr_type = util_iov_pull_mem(&iov, sizeof(*addr_type)); - if (!addr_type) { + if (!util_iov_pull_u8(&iov, &addr_type)) { DBG(bcast_src->bass, "Unable to parse Broadcast Receive State"); return -1; } @@ -174,8 +171,7 @@ return -1; } - sid = util_iov_pull_mem(&iov, sizeof(*sid)); - if (!sid) { + if (!util_iov_pull_u8(&iov, &sid)) { DBG(bcast_src->bass, "Unable to parse Broadcast Receive State"); return -1; } @@ -185,19 +181,17 @@ return -1; } - pa_sync_state = util_iov_pull_mem(&iov, sizeof(*pa_sync_state)); - if (!pa_sync_state) { + if (!util_iov_pull_u8(&iov, &pa_sync_state)) { DBG(bcast_src->bass, "Unable to parse Broadcast Receive State"); return -1; } - enc = util_iov_pull_mem(&iov, sizeof(*enc)); - if (!enc) { + if (!util_iov_pull_u8(&iov, &enc)) { DBG(bcast_src->bass, "Unable to parse Broadcast Receive State"); return -1; } - if (*enc == BT_BASS_BIG_ENC_STATE_BAD_CODE) { + if (enc == BT_BASS_BIG_ENC_STATE_BAD_CODE) { bad_code = util_iov_pull_mem(&iov, BT_BASS_BCAST_CODE_SIZE); if (!bad_code) { DBG(bcast_src->bass, "Unable to parse " @@ -206,24 +200,21 @@ } } - num_subgroups = util_iov_pull_mem(&iov, sizeof(*num_subgroups)); - if (!num_subgroups) { + if (!util_iov_pull_u8(&iov, &num_subgroups)) { DBG(bcast_src->bass, "Unable to parse Broadcast Receive State"); return -1; } - if (*num_subgroups == 0) + if (num_subgroups == 0) goto done; - subgroup_data = malloc((*num_subgroups) * sizeof(*subgroup_data)); + subgroup_data = new0(struct bt_bass_subgroup_data, 1); if (!subgroup_data) { DBG(bcast_src->bass, "Unable to allocate memory"); return -1; } - memset(subgroup_data, 0, (*num_subgroups) * sizeof(*subgroup_data)); - - for (int i = 0; i < *num_subgroups; i++) { + for (int i = 0; i < num_subgroups; i++) { if (!util_iov_pull_le32(&iov, &bis_sync_state)) { DBG(bcast_src->bass, "Unable to parse " "Broadcast Receive State"); @@ -237,8 +228,7 @@ subgroup_data[i].bis_sync = bis_sync_state; - meta_len = util_iov_pull_mem(&iov, sizeof(*meta_len)); - if (!meta_len) { + if (!util_iov_pull_u8(&iov, &meta_len)) { DBG(bcast_src->bass, "Unable to parse " "Broadcast Receive State"); @@ -249,12 +239,12 @@ return -1; } - subgroup_data[i].meta_len = *meta_len; + subgroup_data[i].meta_len = meta_len; - if (*meta_len == 0) + if (meta_len == 0) continue; - subgroup_data[i].meta = malloc(*meta_len); + subgroup_data[i].meta = malloc0(meta_len); if (!subgroup_data[i].meta) { DBG(bcast_src->bass, "Unable to allocate memory"); @@ -265,7 +255,7 @@ return -1; } - meta = util_iov_pull_mem(&iov, *meta_len); + meta = util_iov_pull_mem(&iov, meta_len); if (!meta) { DBG(bcast_src->bass, "Unable to parse " "Broadcast Receive State"); @@ -277,7 +267,7 @@ return -1; } - memcpy(subgroup_data[i].meta, meta, *meta_len); + memcpy(subgroup_data[i].meta, meta, meta_len); } done: @@ -292,41 +282,31 @@ free(bcast_src->subgroup_data); } - bcast_src->id = *id; - bcast_src->addr_type = *addr_type; + bcast_src->id = id; + bcast_src->addr_type = addr_type; memcpy(&bcast_src->addr, addr, sizeof(bdaddr_t)); - bcast_src->sid = *sid; + bcast_src->sid = sid; bcast_src->bid = bid; - bcast_src->sync_state = *pa_sync_state; - bcast_src->enc = *enc; + bcast_src->sync_state = pa_sync_state; + bcast_src->enc = enc; - if (*enc == BT_BASS_BIG_ENC_STATE_BAD_CODE) + if (enc == BT_BASS_BIG_ENC_STATE_BAD_CODE) memcpy(bcast_src->bad_code, bad_code, BT_BASS_BCAST_CODE_SIZE); else memset(bcast_src->bad_code, 0, BT_BASS_BCAST_CODE_SIZE); - bcast_src->num_subgroups = *num_subgroups; + bcast_src->num_subgroups = num_subgroups; bcast_src->subgroup_data = subgroup_data; return 0; } -static int -bass_build_bcast_src_from_read_rsp(struct bt_bcast_src *bcast_src, - const uint8_t *value, uint16_t length) -{ - return bass_build_bcast_src_from_notif(bcast_src, value, length); -} - -static uint8_t *bass_build_notif_from_bcast_src(struct bt_bcast_src *bcast_src, - size_t *notif_len) +static struct iovec *bass_parse_bcast_src(struct bt_bcast_src *bcast_src) { size_t len = 0; uint8_t *notif = NULL; - struct iovec iov; - - *notif_len = 0; + struct iovec *iov; if (!bcast_src) return NULL; @@ -342,61 +322,49 @@ len += bcast_src->subgroup_data[i].meta_len; } - notif = malloc(len); + notif = malloc0(len); if (!notif) return NULL; - memset(notif, 0, len); + iov = new0(struct iovec, 1); + if (!iov) { + free(notif); + return NULL; + } - iov.iov_base = notif; - iov.iov_len = 0; + iov->iov_base = notif; + iov->iov_len = 0; - util_iov_push_mem(&iov, sizeof(bcast_src->id), - &bcast_src->id); - util_iov_push_mem(&iov, sizeof(bcast_src->addr_type), - &bcast_src->addr_type); - util_iov_push_mem(&iov, sizeof(bcast_src->addr), + util_iov_push_u8(iov, bcast_src->id); + util_iov_push_u8(iov, bcast_src->addr_type); + util_iov_push_mem(iov, sizeof(bcast_src->addr), &bcast_src->addr); - util_iov_push_mem(&iov, sizeof(bcast_src->sid), - &bcast_src->sid); - util_iov_push_le24(&iov, bcast_src->bid); - util_iov_push_mem(&iov, sizeof(bcast_src->sync_state), - &bcast_src->sync_state); - util_iov_push_mem(&iov, sizeof(bcast_src->enc), - &bcast_src->enc); + util_iov_push_u8(iov, bcast_src->sid); + util_iov_push_le24(iov, bcast_src->bid); + util_iov_push_u8(iov, bcast_src->sync_state); + util_iov_push_u8(iov, bcast_src->enc); if (bcast_src->enc == BT_BASS_BIG_ENC_STATE_BAD_CODE) - util_iov_push_mem(&iov, sizeof(bcast_src->bad_code), + util_iov_push_mem(iov, sizeof(bcast_src->bad_code), bcast_src->bad_code); - util_iov_push_mem(&iov, sizeof(bcast_src->num_subgroups), - &bcast_src->num_subgroups); + util_iov_push_u8(iov, bcast_src->num_subgroups); for (size_t i = 0; i < bcast_src->num_subgroups; i++) { /* Add subgroup bis_sync */ - util_iov_push_le32(&iov, bcast_src->subgroup_data[i].bis_sync); + util_iov_push_le32(iov, bcast_src->subgroup_data[i].bis_sync); /* Add subgroup meta_len */ - util_iov_push_mem(&iov, - sizeof(bcast_src->subgroup_data[i].meta_len), - &bcast_src->subgroup_data[i].meta_len); + util_iov_push_u8(iov, bcast_src->subgroup_data[i].meta_len); /* Add subgroup metadata */ if (bcast_src->subgroup_data[i].meta_len > 0) - util_iov_push_mem(&iov, + util_iov_push_mem(iov, bcast_src->subgroup_data[i].meta_len, bcast_src->subgroup_data[i].meta); } - *notif_len = len; - return notif; -} - -static uint8_t * -bass_build_read_rsp_from_bcast_src(struct bt_bcast_src *bcast_src, - size_t *rsp_len) -{ - return bass_build_notif_from_bcast_src(bcast_src, rsp_len); + return iov; } static bool bass_check_cp_command_subgroup_data_len(uint8_t num_subgroups, @@ -504,8 +472,7 @@ struct iovec *iov, struct bt_att *att) { - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, 0x00); + gatt_db_attribute_write_result(attrib, id, 0x00); } static void bass_handle_remote_scan_started_op(struct bt_bass *bass, @@ -515,8 +482,7 @@ struct iovec *iov, struct bt_att *att) { - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, 0x00); + gatt_db_attribute_write_result(attrib, id, 0x00); } static bool bass_src_id_match(const void *data, const void *match_data) @@ -536,6 +502,7 @@ { struct bt_bass_remove_src_params *params; struct bt_bcast_src *bcast_src; + int att_err = 0; /* Get Remove Source command parameters */ params = util_iov_pull_mem(iov, sizeof(*params)); @@ -546,33 +513,31 @@ if (!bcast_src) { /* No source matches the written source id */ - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, - BT_BASS_ERROR_INVALID_SOURCE_ID); - - return; + att_err = BT_BASS_ERROR_INVALID_SOURCE_ID; + goto done; } /* Ignore if server is synchronized to the PA * of the source */ if (bcast_src->sync_state == BT_BASS_SYNCHRONIZED_TO_PA) - return; + goto done; /* Ignore if server is synchronized to any BIS * of the source */ for (int i = 0; i < bcast_src->num_subgroups; i++) if (bcast_src->subgroup_data[i].bis_sync) - return; + goto done; /* Accept the operation and remove source */ queue_remove(bass->ldb->bcast_srcs, bcast_src); gatt_db_attribute_notify(bcast_src->attr, NULL, 0, att); bass_bcast_src_free(bcast_src); - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, 0x00); +done: + gatt_db_attribute_write_result(attrib, id, + att_err); } static bool bass_src_attr_match(const void *data, const void *match_data) @@ -608,8 +573,7 @@ gpointer user_data) { struct bt_bcast_src *bcast_src = user_data; - uint8_t *notify_data; - size_t notify_data_len; + struct iovec *notif; int bis_idx; int i; @@ -681,25 +645,40 @@ } /* Send notification to client */ - notify_data = bass_build_notif_from_bcast_src(bcast_src, - ¬ify_data_len); + notif = bass_parse_bcast_src(bcast_src); + if (!notif) + return; gatt_db_attribute_notify(bcast_src->attr, - (void *)notify_data, - notify_data_len, + notif->iov_base, notif->iov_len, bt_bass_get_att(bcast_src->bass)); - free(notify_data); + free(notif->iov_base); + free(notif); +} + +static bool bass_trigger_big_sync(struct bt_bcast_src *bcast_src) +{ + for (int i = 0; i < bcast_src->num_subgroups; i++) { + struct bt_bass_subgroup_data *data = + &bcast_src->subgroup_data[i]; + + if (data->pending_bis_sync && + data->pending_bis_sync != BIS_SYNC_NO_PREF) + return true; + } + + return false; } + static void confirm_cb(GIOChannel *io, gpointer user_data) { struct bt_bcast_src *bcast_src = user_data; int sk, err; socklen_t len; struct bt_iso_qos qos; - uint8_t *notify_data; - size_t notify_data_len; + struct iovec *notif; GError *gerr = NULL; if (check_io_err(io)) { @@ -729,27 +708,34 @@ /* BIG is not encrypted. Try to synchronize */ bcast_src->enc = BT_BASS_BIG_ENC_STATE_NO_ENC; - if (!bt_io_bcast_accept(bcast_src->pa_sync_io, - connect_cb, bcast_src, NULL, &gerr)) { - DBG(bcast_src->bass, "bt_io_accept: %s", gerr->message); - g_error_free(gerr); + if (bass_trigger_big_sync(bcast_src)) { + if (!bt_io_bcast_accept(bcast_src->pa_sync_io, + connect_cb, bcast_src, NULL, &gerr, + BT_IO_OPT_INVALID)) { + DBG(bcast_src->bass, "bt_io_bcast_accept: %s", + gerr->message); + g_error_free(gerr); + } + return; } - return; + + goto notify; } /* BIG is encrypted. Wait for Client to provide the Broadcast_Code */ bcast_src->enc = BT_BASS_BIG_ENC_STATE_BCODE_REQ; notify: - notify_data = bass_build_notif_from_bcast_src(bcast_src, - ¬ify_data_len); + notif = bass_parse_bcast_src(bcast_src); + if (!notif) + return; gatt_db_attribute_notify(bcast_src->attr, - (void *)notify_data, - notify_data_len, + notif->iov_base, notif->iov_len, bt_bass_get_att(bcast_src->bass)); - free(notify_data); + free(notif->iov_base); + free(notif); } static struct bt_bass *bass_get_session(struct bt_att *att, struct gatt_db *db, @@ -773,6 +759,60 @@ return bass; } +static bool bass_validate_bis_sync(uint8_t num_subgroups, + struct iovec *iov) +{ + uint32_t bis_sync_state; + uint32_t bitmask = 0U; + uint8_t *meta_len; + + for (int i = 0; i < num_subgroups; i++) { + util_iov_pull_le32(iov, &bis_sync_state); + + if (bis_sync_state != BIS_SYNC_NO_PREF) + for (int bis_idx = 0; bis_idx < 31; bis_idx++) { + if (bis_sync_state & (1 << bis_idx)) { + if (bitmask & (1 << bis_idx)) + return false; + + bitmask |= (1 << bis_idx); + } + } + + meta_len = util_iov_pull_mem(iov, + sizeof(*meta_len)); + util_iov_pull_mem(iov, *meta_len); + } + + return true; +} + +static bool bass_validate_add_src_params(uint8_t *value, size_t len) +{ + struct bt_bass_add_src_params *params; + struct iovec iov = { + .iov_base = (void *)value, + .iov_len = len, + }; + + params = util_iov_pull_mem(&iov, sizeof(*params)); + + if (params->pa_sync > PA_SYNC_NO_PAST) + return false; + + if (params->addr_type > 0x01) + return false; + + if (params->sid > 0x0F) + return false; + + if (!bass_validate_bis_sync(params->num_subgroups, + &iov)) + return false; + + return true; +} + static void bass_handle_add_src_op(struct bt_bass *bass, struct gatt_db_attribute *attrib, uint8_t opcode, @@ -783,20 +823,23 @@ struct bt_bcast_src *bcast_src, *src; uint8_t src_id = 0; struct gatt_db_attribute *attr; - uint8_t *pa_sync; + uint8_t pa_sync; GIOChannel *io; GError *err = NULL; struct bt_iso_qos iso_qos = default_qos; uint8_t num_bis = 0; uint8_t bis[ISO_MAX_NUM_BIS]; - uint8_t *notify_data; - size_t notify_data_len; + struct iovec *notif; + uint8_t addr_type; + + gatt_db_attribute_write_result(attrib, id, 0x00); - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, 0x00); + /* Ignore operation if parameters are invalid */ + if (!bass_validate_add_src_params(iov->iov_base, iov->iov_len)) + return; /* Allocate a new broadcast source */ - bcast_src = malloc(sizeof(*bcast_src)); + bcast_src = new0(struct bt_bcast_src, 1); if (!bcast_src) { DBG(bass, "Unable to allocate broadcast source"); return; @@ -804,7 +847,6 @@ queue_push_tail(bass->ldb->bcast_srcs, bcast_src); - memset(bcast_src, 0, sizeof(*bcast_src)); memset(bis, 0, ISO_MAX_NUM_BIS); bcast_src->bass = bass; @@ -856,38 +898,32 @@ bcast_src->id = src_id; /* Populate broadcast source fields from command parameters */ - if (*(uint8_t *)util_iov_pull_mem(iov, sizeof(bcast_src->addr_type))) - bcast_src->addr_type = BDADDR_LE_RANDOM; - else - bcast_src->addr_type = BDADDR_LE_PUBLIC; + util_iov_pull_u8(iov, &bcast_src->addr_type); bacpy(&bcast_src->addr, (bdaddr_t *)util_iov_pull_mem(iov, sizeof(bdaddr_t))); - bcast_src->sid = *(uint8_t *)util_iov_pull_mem(iov, - sizeof(bcast_src->sid)); + + util_iov_pull_u8(iov, &bcast_src->sid); util_iov_pull_le24(iov, &bcast_src->bid); - pa_sync = util_iov_pull_mem(iov, sizeof(*pa_sync)); + util_iov_pull_u8(iov, &pa_sync); bcast_src->sync_state = BT_BASS_NOT_SYNCHRONIZED_TO_PA; /* TODO: Use the pa_interval field for the sync transfer procedure */ util_iov_pull_mem(iov, sizeof(uint16_t)); - bcast_src->num_subgroups = *(uint8_t *)util_iov_pull_mem(iov, - sizeof(bcast_src->num_subgroups)); + util_iov_pull_u8(iov, &bcast_src->num_subgroups); if (!bcast_src->num_subgroups) return; - bcast_src->subgroup_data = malloc(bcast_src->num_subgroups * - sizeof(*bcast_src->subgroup_data)); + bcast_src->subgroup_data = new0(struct bt_bass_subgroup_data, + bcast_src->num_subgroups); if (!bcast_src->subgroup_data) { DBG(bass, "Unable to allocate subgroup data"); goto err; } - memset(bcast_src->subgroup_data, 0, sizeof(*bcast_src->subgroup_data)); - for (int i = 0; i < bcast_src->num_subgroups; i++) { struct bt_bass_subgroup_data *data = &bcast_src->subgroup_data[i]; @@ -911,7 +947,7 @@ if (!data->meta_len) continue; - data->meta = malloc(data->meta_len); + data->meta = malloc0(data->meta_len); if (!data->meta) goto err; @@ -919,7 +955,13 @@ data->meta_len), data->meta_len); } - if (pa_sync != PA_SYNC_NO_SYNC && num_bis > 0) { + if (pa_sync != PA_SYNC_NO_SYNC) { + /* Convert to three-value type */ + if (bcast_src->addr_type) + addr_type = BDADDR_LE_RANDOM; + else + addr_type = BDADDR_LE_PUBLIC; + /* If requested by client, try to synchronize to the source */ io = bt_io_listen(NULL, confirm_cb, bcast_src, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, @@ -927,7 +969,7 @@ BT_IO_OPT_DEST_BDADDR, &bcast_src->addr, BT_IO_OPT_DEST_TYPE, - bcast_src->addr_type, + addr_type, BT_IO_OPT_MODE, BT_IO_MODE_ISO, BT_IO_OPT_QOS, &iso_qos, BT_IO_OPT_ISO_BC_SID, bcast_src->sid, @@ -944,22 +986,23 @@ bcast_src->listen_io = io; g_io_channel_ref(bcast_src->listen_io); - if (!bcast_src->bises) + if (num_bis > 0 && !bcast_src->bises) bcast_src->bises = queue_new(); } else { for (int i = 0; i < bcast_src->num_subgroups; i++) bcast_src->subgroup_data[i].bis_sync = bcast_src->subgroup_data[i].pending_bis_sync; - notify_data = bass_build_notif_from_bcast_src(bcast_src, - ¬ify_data_len); + notif = bass_parse_bcast_src(bcast_src); + if (!notif) + return; gatt_db_attribute_notify(bcast_src->attr, - (void *)notify_data, - notify_data_len, + notif->iov_base, notif->iov_len, bt_bass_get_att(bcast_src->bass)); - free(notify_data); + free(notif->iov_base); + free(notif); } return; @@ -988,9 +1031,7 @@ socklen_t len; struct bt_iso_qos qos; GError *gerr = NULL; - - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, 0x00); + struct iovec *notif; /* Get Set Broadcast Code command parameters */ params = util_iov_pull_mem(iov, sizeof(*params)); @@ -1001,13 +1042,30 @@ if (!bcast_src) { /* No source matches the written source id */ - if (opcode == BT_ATT_OP_WRITE_REQ) - gatt_db_attribute_write_result(attrib, id, + gatt_db_attribute_write_result(attrib, id, BT_BASS_ERROR_INVALID_SOURCE_ID); return; } + gatt_db_attribute_write_result(attrib, id, 0x00); + + if (!bass_trigger_big_sync(bcast_src)) { + bcast_src->enc = BT_BASS_BIG_ENC_STATE_DEC; + + notif = bass_parse_bcast_src(bcast_src); + if (!notif) + return; + + gatt_db_attribute_notify(bcast_src->attr, + notif->iov_base, notif->iov_len, + bt_bass_get_att(bcast_src->bass)); + + free(notif->iov_base); + free(notif); + return; + } + /* Try to sync to the source using the * received broadcast code */ @@ -1035,8 +1093,8 @@ } if (!bt_io_bcast_accept(bcast_src->pa_sync_io, connect_cb, - bcast_src, NULL, &gerr)) { - DBG(bcast_src->bass, "bt_io_accept: %s", gerr->message); + bcast_src, NULL, &gerr, BT_IO_OPT_INVALID)) { + DBG(bcast_src->bass, "bt_io_bcast_accept: %s", gerr->message); g_error_free(gerr); } } @@ -1091,10 +1149,8 @@ /* Validate written command length */ if (!bass_check_cp_command_len(value, len)) { - if (opcode == BT_ATT_OP_WRITE_REQ) { - gatt_db_attribute_write_result(attrib, id, - BT_ERROR_WRITE_REQUEST_REJECTED); - } + gatt_db_attribute_write_result(attrib, id, + BT_ERROR_WRITE_REQUEST_REJECTED); return; } @@ -1110,10 +1166,8 @@ } /* Send error response if unsupported opcode was written */ - if (opcode == BT_ATT_OP_WRITE_REQ) { - gatt_db_attribute_write_result(attrib, id, - BT_BASS_ERROR_OPCODE_NOT_SUPPORTED); - } + gatt_db_attribute_write_result(attrib, id, + BT_BASS_ERROR_OPCODE_NOT_SUPPORTED); } static bool bass_src_match_attrib(const void *data, const void *match_data) @@ -1130,8 +1184,7 @@ void *user_data) { struct bt_bass_db *bdb = user_data; - uint8_t *rsp; - size_t rsp_len; + struct iovec *rsp; struct bt_bcast_src *bcast_src; struct bt_bass *bass = bass_get_session(att, bdb->db, &bdb->adapter_bdaddr); @@ -1147,7 +1200,7 @@ } /* Build read response */ - rsp = bass_build_read_rsp_from_bcast_src(bcast_src, &rsp_len); + rsp = bass_parse_bcast_src(bcast_src); if (!rsp) { gatt_db_attribute_read_result(attrib, id, @@ -1156,9 +1209,10 @@ return; } - gatt_db_attribute_read_result(attrib, id, 0, (void *)rsp, - rsp_len); + gatt_db_attribute_read_result(attrib, id, 0, rsp->iov_base, + rsp->iov_len); + free(rsp->iov_base); free(rsp); } @@ -1257,7 +1311,7 @@ return; } - if (bass_build_bcast_src_from_read_rsp(bcast_src, value, length)) { + if (bass_build_bcast_src(bcast_src, value, length)) { queue_remove(bcast_src->bass->rdb->bcast_srcs, bcast_src); bass_bcast_src_free(bcast_src); return; @@ -1276,7 +1330,7 @@ bass_src_match_attrib, attr); if (!bcast_src) { new_src = true; - bcast_src = malloc(sizeof(*bcast_src)); + bcast_src = new0(struct bt_bcast_src, 1); if (!bcast_src) { DBG(bass, "Failed to allocate " @@ -1284,12 +1338,11 @@ return; } - memset(bcast_src, 0, sizeof(struct bt_bcast_src)); bcast_src->bass = bass; bcast_src->attr = attr; } - if (bass_build_bcast_src_from_notif(bcast_src, value, length) + if (bass_build_bcast_src(bcast_src, value, length) && new_src) { bass_bcast_src_free(bcast_src); return; @@ -1383,7 +1436,7 @@ bass_src_match_attrib, attr); if (!bcast_src) { - bcast_src = malloc(sizeof(struct bt_bcast_src)); + bcast_src = new0(struct bt_bcast_src, 1); if (bcast_src == NULL) { DBG(bass, "Failed to allocate " @@ -1391,7 +1444,6 @@ return; } - memset(bcast_src, 0, sizeof(struct bt_bcast_src)); bcast_src->bass = bass; bcast_src->attr = attr; @@ -1459,6 +1511,15 @@ return true; } +bool bt_bass_set_att(struct bt_bass *bass, struct bt_att *att) +{ + if (!bass) + return false; + + bass->att = att; + return true; +} + static void bass_detached(void *data, void *user_data) { struct bt_bass_cb *cb = data; diff -Nru bluez-5.70/src/shared/bass.h bluez-5.71/src/shared/bass.h --- bluez-5.70/src/shared/bass.h 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/shared/bass.h 2023-12-14 05:40:27.000000000 +0800 @@ -131,5 +131,6 @@ bool bt_bass_set_user_data(struct bt_bass *bass, void *user_data); void bt_bass_unref(struct bt_bass *bass); bool bt_bass_attach(struct bt_bass *bass, struct bt_gatt_client *client); +bool bt_bass_set_att(struct bt_bass *bass, struct bt_att *att); void bt_bass_detach(struct bt_bass *bass); void bt_bass_add_db(struct gatt_db *db, const bdaddr_t *adapter_bdaddr); diff -Nru bluez-5.70/src/shared/csip.c bluez-5.71/src/shared/csip.c --- bluez-5.70/src/shared/csip.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/shared/csip.c 2023-12-14 05:40:27.000000000 +0800 @@ -66,6 +66,7 @@ struct gatt_db_attribute *lock; struct gatt_db_attribute *lock_ccc; struct gatt_db_attribute *rank; + bt_csip_encrypt_func_t encrypt; }; struct bt_csip_cb { @@ -96,9 +97,6 @@ bt_csip_destroy_func_t debug_destroy; void *debug_data; - bt_csip_ltk_func_t ltk_func; - void *ltk_data; - bt_csip_sirk_func_t sirk_func; void *sirk_data; @@ -218,46 +216,6 @@ va_end(ap); } -static bool csip_match_att(const void *data, const void *match_data) -{ - const struct bt_csip *csip = data; - const struct bt_att *att = match_data; - - return bt_csip_get_att((void *)csip) == att; -} - -static bool csis_sirk_enc(struct bt_csis *csis, struct bt_att *att, - struct csis_sirk *sirk) -{ - struct bt_csip *csip; - uint8_t k[16]; - struct bt_crypto *crypto; - bool ret; - - csip = queue_find(sessions, csip_match_att, att); - if (!csip) - return false; - - if (!csip->ltk_func(csip, k, csip->ltk_data)) { - DBG(csip, "Unable to read sef key"); - return false; - } - - crypto = bt_crypto_new(); - if (!crypto) { - DBG(csip, "Failed to open crypto"); - return false; - } - - ret = bt_crypto_sef(crypto, k, sirk->val, sirk->val); - if (!ret) - DBG(csip, "Failed to encrypt SIRK using sef"); - - bt_crypto_unref(crypto); - - return ret; -} - static void csis_sirk_read(struct gatt_db_attribute *attrib, unsigned int id, uint16_t offset, uint8_t opcode, struct bt_att *att, @@ -270,7 +228,7 @@ memcpy(&sirk, csis->sirk_val, sizeof(sirk)); if (sirk.type == BT_CSIP_SIRK_ENCRYPT && - !csis_sirk_enc(csis, att, &sirk)) { + !csis->encrypt(att, sirk.val)) { gatt_db_attribute_read_result(attrib, id, BT_ATT_ERROR_UNLIKELY, NULL, 0); return; @@ -291,8 +249,8 @@ struct bt_csis *csis = user_data; struct iovec iov; - iov.iov_base = &csis->size; - iov.iov_len = sizeof(csis->size); + iov.iov_base = &csis->size_val; + iov.iov_len = sizeof(csis->size_val); gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, iov.iov_len); @@ -322,9 +280,13 @@ uint8_t opcode, struct bt_att *att, void *user_data) { - uint8_t value = CSIS_RANK; + struct bt_csis *csis = user_data; + struct iovec iov; - gatt_db_attribute_read_result(attrib, id, 0, &value, sizeof(value)); + iov.iov_base = &csis->rank_val; + iov.iov_len = sizeof(csis->rank_val); + + gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, iov.iov_len); } static struct bt_csis *csis_new(struct gatt_db *db) @@ -389,11 +351,6 @@ return csip_db_new(db); } -void bt_csip_add_db(struct gatt_db *db) -{ - csip_db_new(db); -} - bool bt_csip_set_debug(struct bt_csip *csip, bt_csip_debug_func_t func, void *user_data, bt_csip_destroy_func_t destroy) { @@ -602,7 +559,7 @@ DBG(csip, "SIRK found: handle 0x%04x", value_handle); csis = csip_get_csis(csip); - if (!csis || csis->sirk) + if (!csis) return; csis->sirk = attr; @@ -726,7 +683,8 @@ bt_uuid16_create(&uuid, CS_SIRK); csis->sirk = gatt_db_service_add_characteristic(csis->service, &uuid, - BT_ATT_PERM_READ, + BT_ATT_PERM_READ | + BT_ATT_PERM_READ_ENCRYPT, BT_GATT_CHRC_PROP_READ, csis_sirk_read, NULL, csis); @@ -734,7 +692,8 @@ bt_uuid16_create(&uuid, CS_SIZE); csis->size = gatt_db_service_add_characteristic(csis->service, &uuid, - BT_ATT_PERM_READ, + BT_ATT_PERM_READ | + BT_ATT_PERM_READ_ENCRYPT, BT_GATT_CHRC_PROP_READ, csis_size_read, NULL, csis); @@ -742,7 +701,10 @@ /* Lock */ bt_uuid16_create(&uuid, CS_LOCK); csis->lock = gatt_db_service_add_characteristic(csis->service, &uuid, - BT_ATT_PERM_READ, + BT_ATT_PERM_READ | + BT_ATT_PERM_READ_ENCRYPT | + BT_ATT_PERM_WRITE | + BT_ATT_PERM_WRITE_ENCRYPT, BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE | BT_GATT_CHRC_PROP_NOTIFY, @@ -756,7 +718,8 @@ /* Rank */ bt_uuid16_create(&uuid, CS_RANK); csis->rank = gatt_db_service_add_characteristic(csis->service, &uuid, - BT_ATT_PERM_READ, + BT_ATT_PERM_READ | + BT_ATT_PERM_READ_ENCRYPT, BT_GATT_CHRC_PROP_READ, csis_rank_read_cb, NULL, csis); @@ -775,7 +738,7 @@ bool bt_csip_set_sirk(struct bt_csip *csip, bool encrypt, uint8_t k[16], uint8_t size, uint8_t rank, - bt_csip_ltk_func_t func, void *user_data) + bt_csip_encrypt_func_t func) { uint8_t zero[16] = {}; uint8_t type; @@ -792,8 +755,7 @@ if (!sirk_new(csip->ldb->csis, csip->ldb->db, type, k, size, rank)) return false; - csip->ltk_func = func; - csip->ltk_data = user_data; + csip->ldb->csis->encrypt = func; return true; } diff -Nru bluez-5.70/src/shared/csip.h bluez-5.71/src/shared/csip.h --- bluez-5.70/src/shared/csip.h 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/shared/csip.h 2023-12-14 05:40:27.000000000 +0800 @@ -27,8 +27,7 @@ typedef void (*bt_csip_destroy_func_t)(void *user_data); typedef void (*bt_csip_debug_func_t)(const char *str, void *user_data); typedef void (*bt_csip_func_t)(struct bt_csip *csip, void *user_data); -typedef bool (*bt_csip_ltk_func_t)(struct bt_csip *csip, uint8_t k[16], - void *user_data); +typedef bool (*bt_csip_encrypt_func_t)(struct bt_att *att, uint8_t k[16]); typedef bool (*bt_csip_sirk_func_t)(struct bt_csip *csip, uint8_t type, uint8_t k[16], uint8_t size, uint8_t rank, void *user_data); @@ -36,8 +35,6 @@ struct bt_csip *bt_csip_ref(struct bt_csip *csip); void bt_csip_unref(struct bt_csip *csip); -void bt_csip_add_db(struct gatt_db *db); - bool bt_csip_attach(struct bt_csip *csip, struct bt_gatt_client *client); void bt_csip_detach(struct bt_csip *csip); @@ -56,7 +53,7 @@ bool bt_csip_set_sirk(struct bt_csip *csip, bool encrypt, uint8_t k[16], uint8_t size, uint8_t rank, - bt_csip_ltk_func_t func, void *user_data); + bt_csip_encrypt_func_t func); bool bt_csip_get_sirk(struct bt_csip *csip, uint8_t *type, uint8_t k[16], uint8_t *size, uint8_t *rank); diff -Nru bluez-5.70/src/shared/lc3.h bluez-5.71/src/shared/lc3.h --- bluez-5.70/src/shared/lc3.h 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/shared/lc3.h 2023-12-14 05:40:27.000000000 +0800 @@ -155,3 +155,156 @@ #define LC3_CONFIG_48_6 \ LC3_CONFIG_48(LC3_CONFIG_DURATION_10, 155u) + +#define LC3_QOS_UNFRAMED 0x00 +#define LC3_QOS_FRAMED 0x01 + +#define LC3_QOS_UCAST(_frame, _pd, _t_lat, _interval, _lat, _sdu, _rtn) \ +{ \ + .ucast.cig_id = 0x00, \ + .ucast.cis_id = 0x00, \ + .ucast.delay = _pd, \ + .ucast.target_latency = _t_lat, \ + .ucast.io_qos.interval = _interval, \ + .ucast.io_qos.latency = _lat, \ + .ucast.io_qos.sdu = _sdu, \ + .ucast.io_qos.phy = BT_BAP_CONFIG_PHY_2M, \ + .ucast.io_qos.rtn = _rtn, \ +} + +#define LC3_QOS_UCAST_7_5_UNFRAMED(_pd, _t_lat, _lat, _sdu, _rtn) \ + LC3_QOS_UCAST(LC3_QOS_UNFRAMED, _pd, _t_lat, 7500u, _lat, _sdu, _rtn) + +#define LC3_QOS_UCAST_10_UNFRAMED(_pd, _t_lat, _lat, _sdu, _rtn) \ + LC3_QOS_UCAST(LC3_QOS_UNFRAMED, _pd, _t_lat, 10000u, _lat, _sdu, _rtn) + +#define LC3_QOS_UCAST_FRAMED(_pd, _t_lat, _interval, _lat, _sdu, _rtn) \ + LC3_QOS_UCAST(LC3_QOS_FRAMED, _pd, _t_lat, _interval, _lat, _sdu, _rtn) + +#define LC3_QOS_8_1_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 8u, 26u, 2u) + +#define LC3_QOS_8_1_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 26u, 13u) + +#define LC3_QOS_8_2_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 10u, 30u, 2u) + +#define LC3_QOS_8_2_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 95u, 30u, 13u) + +#define LC3_QOS_16_1_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 8u, 30u, 2u) + +#define LC3_QOS_16_1_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 30u, 13u) + +#define LC3_QOS_16_2_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 10u, 40u, 2u) + +#define LC3_QOS_16_2_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 95u, 40u, 13u) + +#define LC3_QOS_24_1_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 8u, 45u, 2u) + +#define LC3_QOS_24_1_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 45u, 13u) + +#define LC3_QOS_24_2_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 10u, 60u, 2u) + +#define LC3_QOS_24_2_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 95u, 60u, 13u) + +#define LC3_QOS_32_1_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 8u, 60u, 2u) + +#define LC3_QOS_32_1_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 60u, 13u) + +#define LC3_QOS_32_2_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 10u, 80u, 2u) + +#define LC3_QOS_32_2_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 95u, 80u, 13u) + +#define LC3_QOS_44_1_1 \ + LC3_QOS_UCAST_FRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 8163u, 24u, 98u, 5u) + +#define LC3_QOS_44_1_2 \ + LC3_QOS_UCAST_FRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 8163u, 80u, 98u, 13u) + +#define LC3_QOS_44_2_1 \ + LC3_QOS_UCAST_FRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 10884u, 31u, 130u, 5u) + +#define LC3_QOS_44_2_2 \ + LC3_QOS_UCAST_FRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 10884u, 85u, 130u, 13u) + +#define LC3_QOS_48_1_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 15u, 75u, 5u) + +#define LC3_QOS_48_1_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 75u, 13u) + +#define LC3_QOS_48_2_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 20u, 100u, 5u) + +#define LC3_QOS_48_2_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 95u, 100u, 13u) + +#define LC3_QOS_48_3_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 15u, 90u, 5u) + +#define LC3_QOS_48_3_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 90u, 13u) + +#define LC3_QOS_48_4_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 20u, 120u, 5u) + +#define LC3_QOS_48_4_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 100u, 120u, 13u) + +#define LC3_QOS_48_5_1 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 15u, 117u, 5u) + +#define LC3_QOS_48_5_2 \ + LC3_QOS_UCAST_7_5_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 75u, 117u, 13u) + +#define LC3_QOS_48_6_1 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 20u, 155u, 5u) + +#define LC3_QOS_48_6_2 \ + LC3_QOS_UCAST_10_UNFRAMED(40000u, BT_BAP_CONFIG_LATENCY_BALANCED, \ + 100u, 155u, 13u) diff -Nru bluez-5.70/src/shared/micp.c bluez-5.71/src/shared/micp.c --- bluez-5.70/src/shared/micp.c 2023-09-29 03:53:28.000000000 +0800 +++ bluez-5.71/src/shared/micp.c 2023-12-14 05:40:27.000000000 +0800 @@ -138,6 +138,7 @@ if (!queue_remove(sessions, micp)) return; + bt_gatt_client_idle_unregister(micp->client, micp->idle_id); bt_gatt_client_unref(micp->client); micp->client = NULL; @@ -175,6 +176,7 @@ micp_db_free(micp->rdb); + queue_destroy(micp->notify, free); queue_destroy(micp->pending, NULL); queue_destroy(micp->ready_cbs, micp_ready_free); @@ -594,6 +596,7 @@ micp->ldb = mdb; micp->pending = queue_new(); micp->ready_cbs = queue_new(); + micp->notify = queue_new(); if (!rdb) goto done; diff -Nru bluez-5.70/src/shared/shell.c bluez-5.71/src/shared/shell.c --- bluez-5.70/src/shared/shell.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/shared/shell.c 2023-12-14 05:40:27.000000000 +0800 @@ -1128,7 +1128,7 @@ static const struct option main_options[] = { { "version", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, - { "init-script", required_argument, 0, 'i' }, + { "init-script", required_argument, 0, 's' }, { "timeout", required_argument, 0, 't' }, { "monitor", no_argument, 0, 'm' }, { "zsh-complete", no_argument, 0, 'z' }, @@ -1169,9 +1169,9 @@ if (opt) { memcpy(options + offset, opt->options, sizeof(struct option) * opt->optno); - snprintf(optstr, sizeof(optstr), "+mhvi:t:%s", opt->optstr); + snprintf(optstr, sizeof(optstr), "+mhvs:t:%s", opt->optstr); } else - snprintf(optstr, sizeof(optstr), "+mhvi:t:"); + snprintf(optstr, sizeof(optstr), "+mhvs:t:"); data.name = strrchr(argv[0], '/'); if (!data.name) @@ -1193,7 +1193,7 @@ data.argv = &cmplt; data.mode = 1; goto done; - case 'i': + case 's': if (optarg) data.init_fd = open(optarg, O_RDONLY); if (data.init_fd < 0) @@ -1419,10 +1419,18 @@ void bt_shell_set_prompt(const char *string) { + char *prompt; + if (!data.init || data.mode) return; - rl_set_prompt(string); + if (asprintf(&prompt, "\001%s\002", string) < 0) + rl_set_prompt(string); + else { + rl_set_prompt(prompt); + free(prompt); + } + rl_redisplay(); } diff -Nru bluez-5.70/src/shared/shell.h bluez-5.71/src/shared/shell.h --- bluez-5.70/src/shared/shell.h 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/src/shared/shell.h 2023-12-14 05:40:27.000000000 +0800 @@ -10,14 +10,14 @@ #include #include -#define COLOR_OFF "\001\x1B[0m\002" -#define COLOR_RED "\001\x1B[0;91m\002" -#define COLOR_GREEN "\001\x1B[0;92m\002" -#define COLOR_YELLOW "\001\x1B[0;93m\002" -#define COLOR_BLUE "\001\x1B[0;94m\002" -#define COLOR_BOLDGRAY "\001\x1B[1;30m\002" -#define COLOR_BOLDWHITE "\001\x1B[1;37m\002" -#define COLOR_HIGHLIGHT "\001\x1B[1;39m\002" +#define COLOR_OFF "\x1B[0m" +#define COLOR_RED "\x1B[0;91m" +#define COLOR_GREEN "\x1B[0;92m" +#define COLOR_YELLOW "\x1B[0;93m" +#define COLOR_BLUE "\x1B[0;94m" +#define COLOR_BOLDGRAY "\x1B[1;30m" +#define COLOR_BOLDWHITE "\x1B[1;37m" +#define COLOR_HIGHLIGHT "\x1B[1;39m" struct bt_shell_menu; diff -Nru bluez-5.70/src/shared/util.c bluez-5.71/src/shared/util.c --- bluez-5.70/src/shared/util.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/src/shared/util.c 2023-12-14 05:40:27.000000000 +0800 @@ -138,6 +138,96 @@ } } +/* Helper to print debug information of bitfields */ +uint64_t util_debug_bit(const char *label, uint64_t val, + const struct util_bit_debugger *table, + util_debug_func_t function, void *user_data) +{ + uint64_t mask = val; + int i; + + for (i = 0; table[i].str; i++) { + if (val & (((uint64_t) 1) << table[i].bit)) { + util_debug(function, user_data, "%s%s", label, + table[i].str); + mask &= ~(((uint64_t) 1) << table[i].bit); + } + } + + return mask; +} + +static const struct util_ltv_debugger* +ltv_debugger(const struct util_ltv_debugger *debugger, size_t num, uint8_t type) +{ + size_t i; + + if (!debugger || !num) + return NULL; + + for (i = 0; i < num; i++) { + const struct util_ltv_debugger *debug = &debugger[i]; + + if (debug->type == type) + return debug; + } + + return NULL; +} + +/* Helper to print debug information of LTV entries */ +bool util_debug_ltv(const uint8_t *data, uint8_t len, + const struct util_ltv_debugger *debugger, size_t num, + util_debug_func_t function, void *user_data) +{ + struct iovec iov; + int i; + + iov.iov_base = (void *) data; + iov.iov_len = len; + + for (i = 0; iov.iov_len; i++) { + uint8_t l, t, *v; + const struct util_ltv_debugger *debug; + + if (!util_iov_pull_u8(&iov, &l)) { + util_debug(function, user_data, + "Unable to pull length"); + return false; + } + + if (!l) { + util_debug(function, user_data, "#%d: len 0x%02x", + i, l); + continue; + } + + if (!util_iov_pull_u8(&iov, &t)) { + util_debug(function, user_data, "Unable to pull type"); + return false; + } + + util_debug(function, user_data, "#%d: len 0x%02x type 0x%02x", + i, l, t); + + l--; + + v = util_iov_pull_mem(&iov, l); + if (!v) { + util_debug(function, user_data, "Unable to pull value"); + return false; + } + + debug = ltv_debugger(debugger, num, t); + if (debug) + debug->func(v, l, function, user_data); + else + util_hexdump(' ', (void *)v, l, function, user_data); + } + + return true; +} + /* Helper for getting the dirent type in case readdir returns DT_UNKNOWN */ unsigned char util_get_dt(const char *parent, const char *name) { @@ -685,6 +775,7 @@ { 0x1854, "Hearing Aid" }, { 0x1855, "Telephony and Media Audio" }, { 0x1856, "Public Broadcast Announcement" }, + { 0x1858, "Gaming Audio" }, /* 0x1857 to 0x27ff undefined */ { 0x2800, "Primary Service" }, { 0x2801, "Secondary Service" }, @@ -993,6 +1084,11 @@ { 0x2bda, "Hearing Aid Features" }, { 0x2bdb, "Hearing Aid Preset Control Point" }, { 0x2bdc, "Active Preset Index" }, + { 0x2c00, "GMAP Role" }, + { 0x2c01, "UGG Features" }, + { 0x2c02, "UGT Features" }, + { 0x2c03, "BGS Features" }, + { 0x2c03, "BGR Features" }, /* vendor defined */ { 0xfeff, "GN Netcom" }, { 0xfefe, "GN ReSound A/S" }, diff -Nru bluez-5.70/src/shared/util.h bluez-5.71/src/shared/util.h --- bluez-5.70/src/shared/util.h 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/src/shared/util.h 2023-12-14 05:40:27.000000000 +0800 @@ -107,6 +107,37 @@ void util_hexdump(const char dir, const unsigned char *buf, size_t len, util_debug_func_t function, void *user_data); +#define UTIL_BIT_DEBUG(_bit, _str) \ +{ \ + .bit = _bit, \ + .str = _str, \ +} + +struct util_bit_debugger { + uint64_t bit; + const char *str; +}; + +uint64_t util_debug_bit(const char *label, uint64_t val, + const struct util_bit_debugger *table, + util_debug_func_t func, void *user_data); + +#define UTIL_LTV_DEBUG(_type, _func) \ +{ \ + .type = _type, \ + .func = _func, \ +} + +struct util_ltv_debugger { + uint8_t type; + void (*func)(const uint8_t *data, uint8_t len, + util_debug_func_t func, void *user_data); +}; + +bool util_debug_ltv(const uint8_t *data, uint8_t len, + const struct util_ltv_debugger *debugger, size_t num, + util_debug_func_t function, void *user_data); + unsigned char util_get_dt(const char *parent, const char *name); ssize_t util_getrandom(void *buf, size_t buflen, unsigned int flags); diff -Nru bluez-5.70/src/shared/vcp.c bluez-5.71/src/shared/vcp.c --- bluez-5.70/src/shared/vcp.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/src/shared/vcp.c 2023-12-14 05:40:27.000000000 +0800 @@ -683,7 +683,7 @@ struct iovec *iov) { struct bt_vcp_db *vdb; - struct vol_offset_state *vstate; + struct vol_offset_state *vstate, state; struct bt_vocs_set_vol_off *req; DBG(vcp, "Set Volume Offset"); @@ -709,17 +709,24 @@ return BT_ATT_ERROR_INVALID_CHANGE_COUNTER; } - if (req->set_vol_offset > VOCS_VOL_OFFSET_UPPER_LIMIT || - req->set_vol_offset < VOCS_VOL_OFFSET_LOWER_LIMIT) { + vstate->vol_offset = le16_to_cpu(req->set_vol_offset); + + if (vstate->vol_offset > VOCS_VOL_OFFSET_UPPER_LIMIT || + vstate->vol_offset < VOCS_VOL_OFFSET_LOWER_LIMIT) { DBG(vcp, "error: Value Out of Range"); return BT_ATT_ERROR_VALUE_OUT_OF_RANGE; } - vstate->vol_offset = req->set_vol_offset; - vstate->counter = -~vstate->counter; /*Increment Change Counter*/ - gatt_db_attribute_notify(vdb->vocs->vos, (void *)vstate, - sizeof(struct vol_offset_state), + /* Increment Change Counter */ + vstate->counter = -~vstate->counter; + + /* Notify change */ + state.vol_offset = req->set_vol_offset; + state.counter = vstate->counter; + + gatt_db_attribute_notify(vdb->vocs->vos, (void *)&state, sizeof(state), bt_vcp_get_att(vcp)); + return 0; } @@ -926,13 +933,13 @@ void *user_data) { struct bt_vocs *vocs = user_data; - struct iovec iov; + struct vol_offset_state state; - iov.iov_base = vocs->vostate; - iov.iov_len = sizeof(*vocs->vostate); + state.vol_offset = cpu_to_le16(vocs->vostate->vol_offset); + state.counter = vocs->vostate->counter; - gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, - iov.iov_len); + gatt_db_attribute_read_result(attrib, id, 0, (void *)&state, + sizeof(state)); } static void vcs_flag_read(struct gatt_db_attribute *attrib, @@ -956,13 +963,12 @@ void *user_data) { struct bt_vocs *vocs = user_data; - struct iovec iov; + uint32_t loc; - iov.iov_base = &vocs->vocs_audio_loc; - iov.iov_len = sizeof(vocs->vocs_audio_loc); + loc = cpu_to_le32(vocs->vocs_audio_loc); - gatt_db_attribute_read_result(attrib, id, 0, iov.iov_base, - iov.iov_len); + gatt_db_attribute_read_result(attrib, id, 0, (void *)&loc, + sizeof(loc)); } static void vocs_voaodec_read(struct gatt_db_attribute *attrib, @@ -1376,8 +1382,8 @@ return; } - DBG(vcp, "Vol Set:%x", vos->vol_offset); - DBG(vcp, "Vol Counter:%x", vos->counter); + DBG(vcp, "Vol Offset: 0x%04x", le16_to_cpu(vos->vol_offset)); + DBG(vcp, "Vol Counter: 0x%02x", vos->counter); } static void read_vocs_audio_location(struct bt_vcp *vcp, bool success, @@ -1386,6 +1392,7 @@ void *user_data) { uint32_t vocs_audio_loc; + struct iovec iov; if (!value) { DBG(vcp, "Unable to get VOCS Audio Location"); @@ -1398,9 +1405,15 @@ return; } - memcpy(&vocs_audio_loc, value, length); + iov.iov_base = (void *)value; + iov.iov_len = length; + + if (!util_iov_pull_le32(&iov, &vocs_audio_loc)) { + DBG(vcp, "Invalid size for VOCS Audio Location"); + return; + } - DBG(vcp, "VOCS Audio Loc: %x", vocs_audio_loc); + DBG(vcp, "VOCS Audio Loc: 0x%8x", vocs_audio_loc); } diff -Nru bluez-5.70/tools/avtest.c bluez-5.71/tools/avtest.c --- bluez-5.70/tools/avtest.c 2021-02-23 04:26:59.000000000 +0800 +++ bluez-5.71/tools/avtest.c 2023-12-14 05:40:27.000000000 +0800 @@ -188,7 +188,8 @@ } static void process_avdtp(int srv_sk, int sk, unsigned char reject, - int fragment) + int fragment, + int reject_code) { unsigned char buf[672]; ssize_t len; @@ -284,7 +285,8 @@ if (reject == AVDTP_SET_CONFIGURATION) { hdr->message_type = AVDTP_MSG_TYPE_REJECT; buf[2] = buf[4]; - buf[3] = 0x13; /* SEP In Use */ + buf[3] = reject_code ? reject_code : + 0x13; /* SEP In Use */ printf("Rejecting set configuration command\n"); len = write(sk, buf, 4); } else { @@ -443,7 +445,8 @@ return 0; } -static void do_listen(const bdaddr_t *src, unsigned char reject, int fragment) +static void do_listen(const bdaddr_t *src, unsigned char reject, int fragment, + int reject_code) { struct sockaddr_l2 addr; socklen_t optlen; @@ -483,7 +486,7 @@ continue; } - process_avdtp(sk, nsk, reject, fragment); + process_avdtp(sk, nsk, reject, fragment, reject_code); if (media_sock >= 0) { close(media_sock); @@ -709,6 +712,7 @@ printf("Options:\n" "\t--device HCI device\n" "\t--reject Reject command\n" + "\t--reject-code Reject code to use\n" "\t--send Send command\n" "\t--preconf Configure stream before actual command\n" "\t--wait Wait N seconds before exiting\n" @@ -720,6 +724,7 @@ { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, { "reject", 1, 0, 'r' }, + { "reject-code", 1, 0, 'R' }, { "send", 1, 0, 's' }, { "invalid", 1, 0, 'f' }, { "preconf", 0, 0, 'c' }, @@ -764,12 +769,12 @@ unsigned char cmd = 0x00; bdaddr_t src, dst; int opt, mode = MODE_NONE, sk, invalid = 0, preconf = 0, fragment = 0; - int avctp = 0, wait_before_exit = 0; + int avctp = 0, wait_before_exit = 0, reject_code = 0; bacpy(&src, BDADDR_ANY); bacpy(&dst, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:r:s:f:hcFCw:", + while ((opt = getopt_long(argc, argv, "+i:r:s:f:hcFCw:R:", main_options, NULL)) != EOF) { switch (opt) { case 'i': @@ -809,6 +814,10 @@ wait_before_exit = atoi(optarg); break; + case 'R': + reject_code = atoi(optarg); + break; + case 'h': default: usage(); @@ -826,7 +835,7 @@ switch (mode) { case MODE_REJECT: - do_listen(&src, cmd, fragment); + do_listen(&src, cmd, fragment, reject_code); break; case MODE_SEND: sk = do_connect(&src, &dst, avctp, fragment); diff -Nru bluez-5.70/tools/btattach.1 bluez-5.71/tools/btattach.1 --- bluez-5.70/tools/btattach.1 2023-09-29 04:09:19.000000000 +0800 +++ bluez-5.71/tools/btattach.1 2023-12-14 05:58:05.000000000 +0800 @@ -1,3 +1,4 @@ +'\" t .\" Man page generated from reStructuredText. . . diff -Nru bluez-5.70/tools/hciattach.1 bluez-5.71/tools/hciattach.1 --- bluez-5.70/tools/hciattach.1 2023-09-29 04:09:26.000000000 +0800 +++ bluez-5.71/tools/hciattach.1 2023-12-14 05:58:19.000000000 +0800 @@ -1,3 +1,4 @@ +'\" t .\" Man page generated from reStructuredText. . . diff -Nru bluez-5.70/tools/hciconfig.1 bluez-5.71/tools/hciconfig.1 --- bluez-5.70/tools/hciconfig.1 2023-09-29 04:09:27.000000000 +0800 +++ bluez-5.71/tools/hciconfig.1 2023-12-14 05:58:20.000000000 +0800 @@ -1,3 +1,4 @@ +'\" t .\" Man page generated from reStructuredText. . . diff -Nru bluez-5.70/tools/isotest.1 bluez-5.71/tools/isotest.1 --- bluez-5.70/tools/isotest.1 2023-09-29 04:09:20.000000000 +0800 +++ bluez-5.71/tools/isotest.1 2023-12-14 05:58:06.000000000 +0800 @@ -1,3 +1,4 @@ +'\" t .\" Man page generated from reStructuredText. . . diff -Nru bluez-5.70/tools/isotest.c bluez-5.71/tools/isotest.c --- bluez-5.70/tools/isotest.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/tools/isotest.c 2023-12-14 05:40:27.000000000 +0800 @@ -1028,7 +1028,7 @@ .bcast = { \ .big = BT_ISO_QOS_BIG_UNSET, \ .bis = BT_ISO_QOS_BIS_UNSET, \ - .sync_interval = 0x07, \ + .sync_factor = 0x07, \ .packing = 0x00, \ .framing = 0x00, \ .out = QOS_IO(_interval, _latency, _sdu, _phy, _rtn), \ @@ -1073,22 +1073,35 @@ QOS_PRESET("48_5_1", false, 7500, 15, 117, 0x02, 5), QOS_PRESET("44_6_1", false, 10000, 20, 155, 0x02, 5), /* QoS Configuration settings for high reliability audio data */ - QOS_PRESET("8_1_2", true, 7500, 45, 26, 0x02, 41), - QOS_PRESET("8_2_2", true, 10000, 60, 30, 0x02, 53), - QOS_PRESET("16_1_2", true, 7500, 45, 30, 0x02, 41), - QOS_PRESET("16_2_2", true, 10000, 60, 40, 0x02, 47), - QOS_PRESET("24_1_2", true, 7500, 45, 45, 0x02, 35), - QOS_PRESET("24_2_2", true, 10000, 60, 60, 0x02, 41), - QOS_PRESET("32_1_2", true, 7500, 45, 60, 0x02, 29), - QOS_PRESET("32_2_1", true, 10000, 60, 80, 0x02, 35), - QOS_PRESET("44_1_2", false, 8163, 54, 98, 0x02, 23), - QOS_PRESET("44_2_2", false, 10884, 71, 130, 0x02, 23), - QOS_PRESET("48_1_2", false, 7500, 45, 75, 0x02, 23), - QOS_PRESET("48_2_2", false, 10000, 60, 100, 0x02, 23), - QOS_PRESET("48_3_2", false, 7500, 45, 90, 0x02, 23), - QOS_PRESET("48_4_2", false, 10000, 60, 120, 0x02, 23), - QOS_PRESET("48_5_2", false, 7500, 45, 117, 0x02, 23), - QOS_PRESET("44_6_2", false, 10000, 60, 155, 0x02, 23), + QOS_PRESET("8_1_2", true, 7500, 75, 26, 0x02, 13), + QOS_PRESET("8_2_2", true, 10000, 95, 30, 0x02, 13), + QOS_PRESET("16_1_2", true, 7500, 75, 30, 0x02, 13), + QOS_PRESET("16_2_2", true, 10000, 95, 40, 0x02, 13), + QOS_PRESET("24_1_2", true, 7500, 75, 45, 0x02, 13), + QOS_PRESET("24_2_2", true, 10000, 95, 60, 0x02, 13), + QOS_PRESET("32_1_2", true, 7500, 75, 60, 0x02, 13), + QOS_PRESET("32_2_2", true, 10000, 95, 80, 0x02, 13), + QOS_PRESET("44_1_2", false, 8163, 80, 97, 0x02, 13), + QOS_PRESET("44_2_2", false, 10884, 85, 130, 0x02, 13), + QOS_PRESET("48_1_2", false, 7500, 75, 75, 0x02, 13), + QOS_PRESET("48_2_2", false, 10000, 95, 100, 0x02, 13), + QOS_PRESET("48_3_2", false, 7500, 75, 90, 0x02, 13), + QOS_PRESET("48_4_2", false, 10000, 100, 120, 0x02, 13), + QOS_PRESET("48_5_2", false, 7500, 75, 117, 0x02, 13), + QOS_PRESET("44_6_2", false, 10000, 100, 155, 0x02, 13), + /* QoS configuration support setting requirements for the UGG and UGT */ + QOS_PRESET("16_1_gs", true, 7500, 15, 30, 0x02, 1), + QOS_PRESET("16_2_gs", true, 10000, 20, 40, 0x02, 1), + QOS_PRESET("32_1_gs", true, 7500, 15, 60, 0x02, 1), + QOS_PRESET("32_2_gs", true, 10000, 20, 80, 0x02, 1), + QOS_PRESET("48_1_gs", true, 7500, 15, 75, 0x02, 1), + QOS_PRESET("48_2_gs", true, 10000, 20, 100, 0x02, 1), + QOS_PRESET("32_1_gr", true, 7500, 15, 60, 0x02, 1), + QOS_PRESET("32_2_gr", true, 10000, 20, 80, 0x02, 1), + QOS_PRESET("48_1_gr", true, 7500, 15, 75, 0x02, 1), + QOS_PRESET("48_2_gr", true, 10000, 20, 100, 0x02, 1), + QOS_PRESET("48_3_gr", true, 7500, 15, 90, 0x02, 1), + QOS_PRESET("48_4_gr", true, 10000, 20, 120, 0x02, 1), }; #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) diff -Nru bluez-5.70/tools/iso-tester.c bluez-5.71/tools/iso-tester.c --- bluez-5.70/tools/iso-tester.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/tools/iso-tester.c 2023-12-14 05:40:27.000000000 +0800 @@ -32,6 +32,7 @@ #include "src/shared/tester.h" #include "src/shared/mgmt.h" #include "src/shared/util.h" +#include "src/shared/queue.h" #define QOS_IO(_interval, _latency, _sdu, _phy, _rtn) \ { \ @@ -153,6 +154,19 @@ #define QOS_48_4_2 QOS_OUT(10000, 100, 120, 0x02, 13) #define QOS_48_5_2 QOS_OUT(7500, 75, 117, 0x02, 13) #define QOS_48_6_2 QOS_OUT(10000, 100, 155, 0x02, 13) +/* QoS configuration support setting requirements for the UGG and UGT */ +#define QOS_16_1_gs QOS(7500, 15, 30, 0x02, 1) +#define QOS_16_2_gs QOS(10000, 20, 40, 0x02, 1) +#define QOS_32_1_gs QOS(7500, 15, 60, 0x02, 1) +#define QOS_32_2_gs QOS(10000, 20, 80, 0x02, 1) +#define QOS_48_1_gs QOS(7500, 15, 75, 0x02, 1) +#define QOS_48_2_gs QOS(10000, 20, 100, 0x02, 1) +#define QOS_32_1_gr QOS(7500, 15, 60, 0x02, 1) +#define QOS_32_2_gr QOS(10000, 20, 80, 0x02, 1) +#define QOS_48_1_gr QOS(7500, 15, 75, 0x02, 1) +#define QOS_48_2_gr QOS(10000, 20, 100, 0x02, 1) +#define QOS_48_3_gr QOS(7500, 15, 90, 0x02, 1) +#define QOS_48_4_gr QOS(10000, 20, 120, 0x02, 1) /* One unidirectional CIS. Unicast Server is Audio Sink */ #define AC_1_4 QOS_OUT(10000, 10, 40, 0x02, 2) @@ -241,7 +255,7 @@ .bcast = { \ .big = _big, \ .bis = _bis, \ - .sync_interval = 0x07, \ + .sync_factor = 0x07, \ .packing = 0x00, \ .framing = 0x00, \ .in = _in, \ @@ -293,22 +307,81 @@ #define QOS_OUT_1_1_16_2_1 BCAST_QOS_OUT_1_1(10000, 10, 40, 0x02, 2) #define QOS_IN_16_2_1 BCAST_QOS_IN(10000, 10, 40, 0x02, 2) #define QOS_IN_ENC_16_2_1 BCAST_QOS_IN_ENC(10000, 10, 40, 0x02, 2) +#define QOS_OUT_48_1_g BCAST_QOS_OUT(7500, 8, 75, 0x02, 1) +#define QOS_OUT_48_2_g BCAST_QOS_OUT(10000, 10, 100, 0x02, 1) +#define QOS_OUT_48_3_g BCAST_QOS_OUT(7500, 8, 90, 0x02, 1) +#define QOS_OUT_48_4_g BCAST_QOS_OUT(10000, 10, 120, 0x02, 1) -static const uint8_t base_lc3_16_2_1[] = { - 0x28, 0x00, 0x00, /* Presentation Delay */ - 0x01, /* Number of Subgroups */ - 0x01, /* Number of BIS */ - 0x06, 0x00, 0x00, 0x00, 0x00, /* Code ID = LC3 (0x06) */ - 0x11, /* Codec Specific Configuration */ - 0x02, 0x01, 0x03, /* 16 KHZ */ - 0x02, 0x02, 0x01, /* 10 ms */ - 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, /* Front Left */ - 0x03, 0x04, 0x28, 0x00, /* Frame Length 40 bytes */ - 0x04, /* Metadata */ - 0x03, 0x02, 0x02, 0x00, /* Audio Context: Convertional */ - 0x01, /* BIS */ - 0x00, /* Codec Specific Configuration */ -}; +#define BASE(_pd, _sgrp, _nbis, _cfg...) \ +{ \ + _pd & 0xff, _pd >> 8, _pd >> 16, \ + _sgrp, \ + _nbis, \ + _cfg \ +} + +#define LC3_BASE(_pd, _sgrp, _nbis, _cc...) \ + BASE(_pd, _sgrp, _nbis, 0x06, 0x00, 0x00, 0x00, 0x00, _cc) + +/* 16 KHZ - 10 ms - Front Left - Frame Length 40 bytes */ +#define LC3_CONFIG_16_2_1 \ + 0x10, \ + 0x02, 0x01, 0x03, \ + 0x02, 0x02, 0x01, \ + 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, \ + 0x03, 0x04, 0x28, 0x00 + +/* Audio Context: Convertional */ +#define CTXT_CONVERSIONAL \ + 0x04, \ + 0x03, 0x02, 0x02, 0x00 + +static const uint8_t base_lc3_16_2_1[] = + LC3_BASE(40000, 1, 1, LC3_CONFIG_16_2_1, CTXT_CONVERSIONAL, + 0x01, /* BIS */ + 0x00 /* Codec Specific Configuration */); + +#define LC3_CONFIG_G(_freq, _dur, _len) \ + 0x0a, \ + 0x02, 0x01, _freq, \ + 0x02, 0x02, _dur, \ + 0x03, 0x04, _len, _len >> 8 + +#define LC3_CONFIG_FRONT_LEFT \ + 0x06, \ + 0x05, 0x03, 0x01, 0x00, 0x00, 0x00 + +/* 48 KHZ - 7.5 ms - Frame Length 75 bytes */ +#define LC3_CONFIG_48_1_G \ + LC3_CONFIG_G(0x08, 0x00, 75) + +static const uint8_t base_lc3_48_1_g[] = + LC3_BASE(10000, 1, 1, LC3_CONFIG_48_1_G, CTXT_CONVERSIONAL, + 0x01, LC3_CONFIG_FRONT_LEFT); + +/* 48 KHZ - 10 ms Frame Length 100 bytes */ +#define LC3_CONFIG_48_2_G \ + LC3_CONFIG_G(0x08, 0x01, 100) + +static const uint8_t base_lc3_48_2_g[] = + LC3_BASE(10000, 1, 1, LC3_CONFIG_48_2_G, CTXT_CONVERSIONAL, + 0x01, LC3_CONFIG_FRONT_LEFT); + +/* 48 KHZ - 7.5 ms Frame Length 90 bytes */ +#define LC3_CONFIG_48_3_G \ + LC3_CONFIG_G(0x08, 0x00, 90) + +static const uint8_t base_lc3_48_3_g[] = + LC3_BASE(10000, 1, 1, LC3_CONFIG_48_3_G, CTXT_CONVERSIONAL, + 0x01, LC3_CONFIG_FRONT_LEFT); + +/* 48 KHZ - 7.5 ms Frame Length 90 bytes */ +#define LC3_CONFIG_48_4_G \ + LC3_CONFIG_G(0x08, 0x00, 120) + +static const uint8_t base_lc3_48_4_g[] = + LC3_BASE(10000, 1, 1, LC3_CONFIG_48_3_G, CTXT_CONVERSIONAL, + 0x01, LC3_CONFIG_FRONT_LEFT); /* Single Audio Channel. One BIS. */ #define BCAST_AC_12 BCAST_QOS_OUT_1_1(10000, 10, 40, 0x02, 2) @@ -330,7 +403,8 @@ }; /* Multiple Audio Channels. Two BISes. */ -#define BCAST_AC_13 BCAST_QOS_OUT_1_1(10000, 10, 40, 0x02, 2) +#define BCAST_AC_13_1_1 BCAST_QOS_OUT_1_1(10000, 10, 40, 0x02, 2) +#define BCAST_AC_13_1 BCAST_QOS_OUT_1(10000, 10, 40, 0x02, 2) static const uint8_t base_lc3_ac_13[] = { 0x28, 0x00, 0x00, /* Presentation Delay */ @@ -387,7 +461,7 @@ uint8_t accept_reason; uint16_t handle; uint16_t acl_handle; - GIOChannel *io; + struct queue *io_queue; unsigned int io_id[2]; uint8_t client_num; int step; @@ -411,6 +485,8 @@ uint8_t pkt_status; const uint8_t *base; size_t base_len; + bool listen_bind; + bool pa_bind; }; static void mgmt_debug(const char *str, void *user_data) @@ -589,12 +665,19 @@ data->hciemu = NULL; } +static void io_free(void *data) +{ + GIOChannel *io = data; + + g_io_channel_unref(io); +} + static void test_data_free(void *test_data) { struct test_data *data = test_data; - if (data->io) - g_io_channel_unref(data->io); + if (data->io_queue) + queue_destroy(data->io_queue, io_free); if (data->io_id[0] > 0) g_source_remove(data->io_id[0]); @@ -799,6 +882,66 @@ .expect_err = 0 }; +static const struct iso_client_data connect_16_1_gs = { + .qos = QOS_16_1_gs, + .expect_err = 0 +}; + +static const struct iso_client_data connect_16_2_gs = { + .qos = QOS_16_2_gs, + .expect_err = 0 +}; + +static const struct iso_client_data connect_32_1_gs = { + .qos = QOS_32_1_gs, + .expect_err = 0 +}; + +static const struct iso_client_data connect_32_2_gs = { + .qos = QOS_32_2_gs, + .expect_err = 0 +}; + +static const struct iso_client_data connect_48_1_gs = { + .qos = QOS_48_1_gs, + .expect_err = 0 +}; + +static const struct iso_client_data connect_48_2_gs = { + .qos = QOS_48_2_gs, + .expect_err = 0 +}; + +static const struct iso_client_data connect_32_1_gr = { + .qos = QOS_32_1_gr, + .expect_err = 0 +}; + +static const struct iso_client_data connect_32_2_gr = { + .qos = QOS_32_2_gr, + .expect_err = 0 +}; + +static const struct iso_client_data connect_48_1_gr = { + .qos = QOS_48_1_gr, + .expect_err = 0 +}; + +static const struct iso_client_data connect_48_2_gr = { + .qos = QOS_48_2_gr, + .expect_err = 0 +}; + +static const struct iso_client_data connect_48_3_gr = { + .qos = QOS_48_3_gr, + .expect_err = 0 +}; + +static const struct iso_client_data connect_48_4_gr = { + .qos = QOS_48_4_gr, + .expect_err = 0 +}; + static const struct iso_client_data connect_invalid = { .qos = QOS(0, 0, 0, 0, 0), .expect_err = -EINVAL @@ -1082,6 +1225,38 @@ .mconn = true, }; +static const struct iso_client_data bcast_48_1_g = { + .qos = QOS_OUT_48_1_g, + .expect_err = 0, + .bcast = true, + .base = base_lc3_48_1_g, + .base_len = sizeof(base_lc3_48_1_g), +}; + +static const struct iso_client_data bcast_48_2_g = { + .qos = QOS_OUT_48_2_g, + .expect_err = 0, + .bcast = true, + .base = base_lc3_48_2_g, + .base_len = sizeof(base_lc3_48_2_g), +}; + +static const struct iso_client_data bcast_48_3_g = { + .qos = QOS_OUT_48_3_g, + .expect_err = 0, + .bcast = true, + .base = base_lc3_48_3_g, + .base_len = sizeof(base_lc3_48_3_g), +}; + +static const struct iso_client_data bcast_48_4_g = { + .qos = QOS_OUT_48_4_g, + .expect_err = 0, + .bcast = true, + .base = base_lc3_48_4_g, + .base_len = sizeof(base_lc3_48_4_g), +}; + static const struct iso_client_data bcast_16_2_1_send = { .qos = QOS_OUT_16_2_1, .expect_err = 0, @@ -1141,6 +1316,24 @@ .recv = &send_16_2_1, .bcast = true, .server = true, + .listen_bind = true, +}; + +static const struct iso_client_data bcast_16_2_1_recv_defer_no_bis = { + .qos = QOS_IN_16_2_1, + .expect_err = 0, + .defer = true, + .bcast = true, + .server = true, +}; + +static const struct iso_client_data bcast_16_2_1_recv_defer_pa_bind = { + .qos = QOS_IN_16_2_1, + .expect_err = 0, + .defer = true, + .bcast = true, + .server = true, + .pa_bind = true, }; static const struct iso_client_data bcast_ac_12 = { @@ -1151,8 +1344,27 @@ .base_len = sizeof(base_lc3_ac_12), }; -static const struct iso_client_data bcast_ac_13 = { - .qos = BCAST_AC_13, +static const struct iso_client_data bcast_ac_13_1_1 = { + .qos = BCAST_AC_13_1_1, + .expect_err = 0, + .bcast = true, + .mconn = true, + .base = base_lc3_ac_13, + .base_len = sizeof(base_lc3_ac_13), +}; + +static const struct iso_client_data bcast_ac_13_1_1_reconn = { + .qos = BCAST_AC_13_1_1, + .expect_err = 0, + .bcast = true, + .mconn = true, + .base = base_lc3_ac_13, + .base_len = sizeof(base_lc3_ac_13), + .disconnect = true, +}; + +static const struct iso_client_data bcast_ac_13_1 = { + .qos = BCAST_AC_13_1, .expect_err = 0, .bcast = true, .mconn = true, @@ -1676,9 +1888,9 @@ return false; } - if (qos1->bcast.sync_interval != qos2->bcast.sync_interval) { + if (qos1->bcast.sync_factor != qos2->bcast.sync_factor) { tester_warn("Unexpected QoS sync interval: 0x%02x != 0x%02x", - qos1->bcast.sync_interval, qos2->bcast.sync_interval); + qos1->bcast.sync_factor, qos2->bcast.sync_factor); return false; } @@ -1881,10 +2093,14 @@ gpointer user_data) { struct test_data *data = user_data; + const struct iso_client_data *isodata = data->test_data; data->io_id[0] = 0; - if ((cond & G_IO_HUP) && !data->handle) { + if (cond & G_IO_HUP) { + if (!isodata->bcast && data->handle) + tester_test_failed(); + tester_print("Successfully disconnected"); if (data->reconnect) { @@ -1975,6 +2191,7 @@ if (err < 0) { tester_warn("Can't get socket option : %s (%d)", strerror(errno), errno); + data->step = 0; tester_test_failed(); return FALSE; } @@ -1987,6 +2204,7 @@ if (!ret) { tester_warn("Unexpected QoS parameter"); + data->step = 0; tester_test_failed(); return FALSE; } @@ -2007,6 +2225,7 @@ tester_warn("Expect error: %s (%d) != %s (%d)", strerror(-isodata->expect_err), -isodata->expect_err, strerror(-err), -err); + data->step = 0; tester_test_failed(); } else { data->step--; @@ -2144,7 +2363,15 @@ data->io_id[num[i]] = g_io_add_watch(io, G_IO_OUT, func[i], NULL); - g_io_channel_unref(io); + if (!isodata->bcast || !data->reconnect) + g_io_channel_unref(io); + else if (data->io_queue) + /* For the broadcast reconnect scenario, do not + * unref channel here, to avoid closing the + * socket. All queued channels will be closed + * by test_data_free. + */ + queue_push_tail(data->io_queue, io); tester_print("Connect %d in progress", num[i]); @@ -2257,8 +2484,11 @@ bacpy(&addr->iso_bc->bc_bdaddr, (void *) dst); addr->iso_bc->bc_bdaddr_type = BDADDR_LE_PUBLIC; - addr->iso_bc->bc_num_bis = 1; - addr->iso_bc->bc_bis[0] = 1; + + if (!isodata->defer || isodata->listen_bind) { + addr->iso_bc->bc_num_bis = 1; + addr->iso_bc->bc_bis[0] = 1; + } err = bind(sk, (struct sockaddr *) addr, sizeof(*addr) + sizeof(*addr->iso_bc)); @@ -2358,9 +2588,28 @@ char c; struct pollfd pfd; const struct iso_client_data *isodata = data->test_data; + struct sockaddr_iso *addr = NULL; sk = g_io_channel_unix_get_fd(io); + if (isodata->pa_bind) { + addr = malloc(sizeof(*addr) + sizeof(*addr->iso_bc)); + memset(addr, 0, sizeof(*addr) + sizeof(*addr->iso_bc)); + addr->iso_family = AF_BLUETOOTH; + + addr->iso_bc->bc_num_bis = 1; + addr->iso_bc->bc_bis[0] = 1; + + if (bind(sk, (struct sockaddr *) addr, sizeof(*addr) + + sizeof(*addr->iso_bc)) < 0) { + tester_warn("bind: %s (%d)", strerror(errno), errno); + free(addr); + return false; + } + + free(addr); + } + memset(&pfd, 0, sizeof(pfd)); pfd.fd = sk; pfd.events = POLLOUT; @@ -2379,16 +2628,16 @@ tester_print("Accept deferred setup"); - data->io = io; + data->io_queue = queue_new(); + if (data->io_queue) + queue_push_tail(data->io_queue, io); - if (isodata->bcast) { + if (isodata->bcast) data->io_id[0] = g_io_add_watch(io, G_IO_IN, iso_accept_cb, NULL); - data->step++; - } else { + else data->io_id[0] = g_io_add_watch(io, G_IO_OUT, iso_connect_cb, NULL); - } return true; } @@ -2420,9 +2669,11 @@ return false; } - if (isodata->bcast && data->step > 1) { - data->step--; - goto connect; + if (isodata->bcast) { + iso_connect(io, cond, user_data); + + if (!data->step) + return false; } if (!iso_defer_accept(data, io)) { @@ -2444,7 +2695,6 @@ } } -connect: return iso_connect(io, cond, user_data); } @@ -2704,6 +2954,18 @@ setup_connect_many(data, 2, num, funcs); } +static void test_bcast2_reconn(const void *test_data) +{ + struct test_data *data = tester_get_data(); + uint8_t num[2] = {0, 1}; + GIOFunc funcs[2] = {iso_connect_cb, iso_connect2_cb}; + + data->io_queue = queue_new(); + + data->reconnect = true; + setup_connect_many(data, 2, num, funcs); +} + static void test_bcast_recv(const void *test_data) { struct test_data *data = tester_get_data(); @@ -2711,6 +2973,15 @@ setup_listen(data, 0, iso_accept_cb); } +static void test_bcast_recv_defer(const void *test_data) +{ + struct test_data *data = tester_get_data(); + + data->step = 1; + + setup_listen(data, 0, iso_accept_cb); +} + static void test_connect2_suspend(const void *test_data) { test_connect2(test_data); @@ -2838,6 +3109,54 @@ test_iso("ISO QoS 48_6_2 - Success", &connect_48_6_2, setup_powered, test_connect); + test_iso("ISO QoS 16_1_gs - Success", &connect_16_1_gs, setup_powered, + test_connect); + + test_iso("ISO QoS 16_2_gs - Success", &connect_16_2_gs, setup_powered, + test_connect); + + test_iso("ISO QoS 32_1_gs - Success", &connect_32_1_gs, setup_powered, + test_connect); + + test_iso("ISO QoS 32_2_gs - Success", &connect_32_2_gs, setup_powered, + test_connect); + + test_iso("ISO QoS 48_1_gs - Success", &connect_48_1_gs, setup_powered, + test_connect); + + test_iso("ISO QoS 48_2_gs - Success", &connect_48_2_gs, setup_powered, + test_connect); + + test_iso("ISO QoS 32_1_gr - Success", &connect_32_1_gr, setup_powered, + test_connect); + + test_iso("ISO QoS 32_2_gr - Success", &connect_32_2_gr, setup_powered, + test_connect); + + test_iso("ISO QoS 48_1_gr - Success", &connect_48_1_gr, setup_powered, + test_connect); + + test_iso("ISO QoS 48_2_gr - Success", &connect_48_2_gr, setup_powered, + test_connect); + + test_iso("ISO QoS 48_3_gr - Success", &connect_48_3_gr, setup_powered, + test_connect); + + test_iso("ISO QoS 48_4_gr - Success", &connect_48_4_gr, setup_powered, + test_connect); + + test_iso("ISO QoS 48_1_g - Success", &bcast_48_1_g, + setup_powered, test_bcast); + + test_iso("ISO QoS 48_2_g - Success", &bcast_48_2_g, + setup_powered, test_bcast); + + test_iso("ISO QoS 48_3_g - Success", &bcast_48_3_g, + setup_powered, test_bcast); + + test_iso("ISO QoS 48_4_g - Success", &bcast_48_4_g, + setup_powered, test_bcast); + test_iso("ISO QoS - Invalid", &connect_invalid, setup_powered, test_connect); @@ -3030,13 +3349,30 @@ test_iso("ISO Broadcaster Receiver Defer - Success", &bcast_16_2_1_recv_defer, setup_powered, + test_bcast_recv_defer); + test_iso("ISO Broadcaster Receiver Defer No BIS - Success", + &bcast_16_2_1_recv_defer_no_bis, + setup_powered, test_bcast_recv); + test_iso("ISO Broadcaster Receiver Defer PA Bind - Success", + &bcast_16_2_1_recv_defer_pa_bind, + setup_powered, + test_bcast_recv_defer); test_iso("ISO Broadcaster AC 12 - Success", &bcast_ac_12, setup_powered, test_bcast); - test_iso("ISO Broadcaster AC 13 - Success", &bcast_ac_13, setup_powered, - test_bcast2); + test_iso("ISO Broadcaster AC 13 BIG 0x01 BIS 0x01 - Success", + &bcast_ac_13_1_1, + setup_powered, + test_bcast2); + + test_iso("ISO Broadcaster AC 13 BIG 0x01 - Success", &bcast_ac_13_1, + setup_powered, test_bcast2); + + test_iso("ISO Broadcaster AC 13 Reconnect - Success", + &bcast_ac_13_1_1_reconn, setup_powered, + test_bcast2_reconn); test_iso("ISO Broadcaster AC 14 - Success", &bcast_ac_14, setup_powered, test_bcast); diff -Nru bluez-5.70/unit/test-bap.c bluez-5.71/unit/test-bap.c --- bluez-5.70/unit/test-bap.c 2023-06-30 16:10:20.000000000 +0800 +++ bluez-5.71/unit/test-bap.c 2023-12-14 05:40:27.000000000 +0800 @@ -39,6 +39,8 @@ bool snk; bool src; bool vs; + uint8_t state; + bt_bap_state_func_t state_func; }; struct test_data { @@ -334,7 +336,15 @@ tester_test_passed(); } -static void bap_config(struct bt_bap_stream *stream, +static void bap_disable(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + if (code) + tester_test_failed(); +} + +static void bap_start(struct bt_bap_stream *stream, uint8_t code, uint8_t reason, void *user_data) { @@ -342,6 +352,73 @@ tester_test_failed(); } +static void bap_enable(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + struct test_data *data = user_data; + unsigned int id = 0; + + if (code) { + tester_test_failed(); + return; + } + + switch (data->cfg->state) { + case BT_BAP_STREAM_STATE_ENABLING: + return; + case BT_BAP_STREAM_STATE_DISABLING: + id = bt_bap_stream_disable(data->stream, true, bap_disable, + data); + break; + case BT_BAP_STREAM_STATE_STREAMING: + id = bt_bap_stream_start(data->stream, bap_start, data); + break; + } + + g_assert(id); +} + +static void bap_qos(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + struct test_data *data = user_data; + + if (code) { + tester_test_failed(); + return; + } + + if (data->cfg->state > BT_BAP_STREAM_STATE_QOS) { + unsigned int qos_id; + + qos_id = bt_bap_stream_enable(data->stream, true, NULL, + bap_enable, data); + g_assert(qos_id); + } +} + +static void bap_config(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + struct test_data *data = user_data; + + if (code) { + tester_test_failed(); + return; + } + + if (data->cfg->state > BT_BAP_STREAM_STATE_CONFIG) { + unsigned int qos_id; + + qos_id = bt_bap_stream_qos(data->stream, &data->cfg->qos, + bap_qos, data); + g_assert(qos_id); + } +} + static bool pac_found(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, void *user_data) { @@ -422,6 +499,10 @@ bt_bap_ready_register(data->bap, bap_ready, data, NULL); + if (data->cfg && data->cfg->state_func) + bt_bap_state_register(data->bap, data->cfg->state_func, NULL, + data, NULL); + bt_bap_attach(data->bap, data->client); } @@ -1185,10 +1266,1575 @@ test_client, &cfg_src_vs, SCC_SRC_VS); } +static struct test_config cfg_snk_8_1_1 = { + .cc = LC3_CONFIG_8_1, + .qos = LC3_QOS_8_1_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_8_2_1 = { + .cc = LC3_CONFIG_8_2, + .qos = LC3_QOS_8_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_16_1_1 = { + .cc = LC3_CONFIG_16_1, + .qos = LC3_QOS_16_1_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_16_2_1 = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_24_1_1 = { + .cc = LC3_CONFIG_24_1, + .qos = LC3_QOS_24_1_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_24_2_1 = { + .cc = LC3_CONFIG_24_2, + .qos = LC3_QOS_24_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_32_1_1 = { + .cc = LC3_CONFIG_32_1, + .qos = LC3_QOS_32_1_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_32_2_1 = { + .cc = LC3_CONFIG_32_2, + .qos = LC3_QOS_32_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_44_1_1 = { + .cc = LC3_CONFIG_44_1, + .qos = LC3_QOS_44_1_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_44_2_1 = { + .cc = LC3_CONFIG_44_2, + .qos = LC3_QOS_44_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_1_1 = { + .cc = LC3_CONFIG_48_1, + .qos = LC3_QOS_48_1_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_2_1 = { + .cc = LC3_CONFIG_48_2, + .qos = LC3_QOS_48_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_3_1 = { + .cc = LC3_CONFIG_48_3, + .qos = LC3_QOS_48_3_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_4_1 = { + .cc = LC3_CONFIG_48_4, + .qos = LC3_QOS_48_4_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_5_1 = { + .cc = LC3_CONFIG_48_5, + .qos = LC3_QOS_48_5_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_6_1 = { + .cc = LC3_CONFIG_48_6, + .qos = LC3_QOS_48_6_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 02010000_qos + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0201010000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x0016 + * Data: 01010102010a00204e00409c00204e00409c00_qos + */ +#define QOS_SNK(_qos...) \ + IOV_DATA(0x52, 0x22, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, _qos), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x02, 0x00, 0x00, _qos) + +#define SCC_SNK_8_1_1 \ + SCC_SNK_8_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_8_2_1 \ + SCC_SNK_8_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_16_1_1 \ + SCC_SNK_16_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_16_2_1 \ + SCC_SNK_16_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_24_1_1 \ + SCC_SNK_24_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_24_2_1 \ + SCC_SNK_24_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_32_1_1 \ + SCC_SNK_32_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_32_2_1 \ + SCC_SNK_32_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_44_1_1 \ + SCC_SNK_44_1, \ + QOS_SNK(0xe3, 0x1f, 0x00, 0x00, 0x02, 0x62, 0x00, 0x05, 0x18, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_44_2_1 \ + SCC_SNK_44_2, \ + QOS_SNK(0x84, 0x2a, 0x00, 0x00, 0x02, 0x82, 0x00, 0x05, 0x1f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_1_1 \ + SCC_SNK_48_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x05, 0x0f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_2_1 \ + SCC_SNK_48_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x05, 0x14, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_3_1 \ + SCC_SNK_48_3, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x05, 0x0f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_4_1 \ + SCC_SNK_48_4, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x05, 0x14, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_5_1 \ + SCC_SNK_48_5, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x05, 0x0f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_6_1 \ + SCC_SNK_48_6, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x05, 0x14, 0x00, \ + 0x40, 0x9c, 0x00) + +static struct test_config cfg_src_8_1_1 = { + .cc = LC3_CONFIG_8_1, + .qos = LC3_QOS_8_1_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_8_2_1 = { + .cc = LC3_CONFIG_8_2, + .qos = LC3_QOS_8_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_16_1_1 = { + .cc = LC3_CONFIG_16_1, + .qos = LC3_QOS_16_1_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_16_2_1 = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_24_1_1 = { + .cc = LC3_CONFIG_24_1, + .qos = LC3_QOS_24_1_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_24_2_1 = { + .cc = LC3_CONFIG_24_2, + .qos = LC3_QOS_24_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_32_1_1 = { + .cc = LC3_CONFIG_32_1, + .qos = LC3_QOS_32_1_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_32_2_1 = { + .cc = LC3_CONFIG_32_2, + .qos = LC3_QOS_32_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_44_1_1 = { + .cc = LC3_CONFIG_44_1, + .qos = LC3_QOS_44_1_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_44_2_1 = { + .cc = LC3_CONFIG_44_2, + .qos = LC3_QOS_44_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_1_1 = { + .cc = LC3_CONFIG_48_1, + .qos = LC3_QOS_48_1_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_2_1 = { + .cc = LC3_CONFIG_48_2, + .qos = LC3_QOS_48_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_3_1 = { + .cc = LC3_CONFIG_48_3, + .qos = LC3_QOS_48_3_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_4_1 = { + .cc = LC3_CONFIG_48_4, + .qos = LC3_QOS_48_4_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_5_1 = { + .cc = LC3_CONFIG_48_5, + .qos = LC3_QOS_48_5_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_6_1 = { + .cc = LC3_CONFIG_48_6, + .qos = LC3_QOS_48_6_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 02030000_qos + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0201030000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x001c + * Data: 03010102010a00204e00409c00204e00409c00_qos + */ +#define QOS_SRC(_qos...) \ + IOV_DATA(0x52, 0x22, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, _qos), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x02, 0x00, 0x00, _qos) + +#define SCC_SRC_8_1_1 \ + SCC_SRC_8_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_8_2_1 \ + SCC_SRC_8_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_16_1_1 \ + SCC_SRC_16_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_16_2_1 \ + SCC_SRC_16_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_24_1_1 \ + SCC_SRC_24_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_24_2_1 \ + SCC_SRC_24_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_32_1_1 \ + SCC_SRC_32_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x02, 0x08, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_32_2_1 \ + SCC_SRC_32_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x02, 0x0a, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_44_1_1 \ + SCC_SRC_44_1, \ + QOS_SRC(0xe3, 0x1f, 0x00, 0x00, 0x02, 0x62, 0x00, 0x05, 0x18, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_44_2_1 \ + SCC_SRC_44_2, \ + QOS_SRC(0x84, 0x2a, 0x00, 0x00, 0x02, 0x82, 0x00, 0x05, 0x1f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_1_1 \ + SCC_SRC_48_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x05, 0x0f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_2_1 \ + SCC_SRC_48_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x05, 0x14, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_3_1 \ + SCC_SRC_48_3, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x05, 0x0f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_4_1 \ + SCC_SRC_48_4, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x05, 0x14, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_5_1 \ + SCC_SRC_48_5, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x05, 0x0f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_6_1 \ + SCC_SRC_48_6, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x05, 0x14, 0x00, \ + 0x40, 0x9c, 0x00) + +static struct test_config cfg_snk_8_1_2 = { + .cc = LC3_CONFIG_8_1, + .qos = LC3_QOS_8_1_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_8_2_2 = { + .cc = LC3_CONFIG_8_2, + .qos = LC3_QOS_8_2_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_16_1_2 = { + .cc = LC3_CONFIG_16_1, + .qos = LC3_QOS_16_1_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_16_2_2 = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_24_1_2 = { + .cc = LC3_CONFIG_24_1, + .qos = LC3_QOS_24_1_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_24_2_2 = { + .cc = LC3_CONFIG_24_2, + .qos = LC3_QOS_24_2_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_32_1_2 = { + .cc = LC3_CONFIG_32_1, + .qos = LC3_QOS_32_1_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_32_2_2 = { + .cc = LC3_CONFIG_32_2, + .qos = LC3_QOS_32_2_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_44_1_2 = { + .cc = LC3_CONFIG_44_1, + .qos = LC3_QOS_44_1_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_44_2_2 = { + .cc = LC3_CONFIG_44_2, + .qos = LC3_QOS_44_2_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_1_2 = { + .cc = LC3_CONFIG_48_1, + .qos = LC3_QOS_48_1_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_2_2 = { + .cc = LC3_CONFIG_48_2, + .qos = LC3_QOS_48_2_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_3_2 = { + .cc = LC3_CONFIG_48_3, + .qos = LC3_QOS_48_3_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_4_2 = { + .cc = LC3_CONFIG_48_4, + .qos = LC3_QOS_48_4_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_5_2 = { + .cc = LC3_CONFIG_48_5, + .qos = LC3_QOS_48_5_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_snk_48_6_2 = { + .cc = LC3_CONFIG_48_6, + .qos = LC3_QOS_48_6_2, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +#define SCC_SNK_8_1_2 \ + SCC_SNK_8_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_8_2_2 \ + SCC_SNK_8_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_16_1_2 \ + SCC_SNK_16_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_16_2_2 \ + SCC_SNK_16_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_24_1_2 \ + SCC_SNK_24_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_24_2_2 \ + SCC_SNK_24_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_32_1_2 \ + SCC_SNK_32_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_32_2_2 \ + SCC_SNK_32_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_44_1_2 \ + SCC_SNK_44_1, \ + QOS_SNK(0xe3, 0x1f, 0x00, 0x00, 0x02, 0x62, 0x00, 0x0d, 0x50, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_44_2_2 \ + SCC_SNK_44_2, \ + QOS_SNK(0x84, 0x2a, 0x00, 0x00, 0x02, 0x82, 0x00, 0x0d, 0x55, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_1_2 \ + SCC_SNK_48_1, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_2_2 \ + SCC_SNK_48_2, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_3_2 \ + SCC_SNK_48_3, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_4_2 \ + SCC_SNK_48_4, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x0d, 0x64, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_5_2 \ + SCC_SNK_48_5, \ + QOS_SNK(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SNK_48_6_2 \ + SCC_SNK_48_6, \ + QOS_SNK(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x0d, 0x64, 0x00, \ + 0x40, 0x9c, 0x00) + +static struct test_config cfg_src_8_1_2 = { + .cc = LC3_CONFIG_8_1, + .qos = LC3_QOS_8_1_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_8_2_2 = { + .cc = LC3_CONFIG_8_2, + .qos = LC3_QOS_8_2_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_16_1_2 = { + .cc = LC3_CONFIG_16_1, + .qos = LC3_QOS_16_1_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_16_2_2 = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_24_1_2 = { + .cc = LC3_CONFIG_24_1, + .qos = LC3_QOS_24_1_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_24_2_2 = { + .cc = LC3_CONFIG_24_2, + .qos = LC3_QOS_24_2_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_32_1_2 = { + .cc = LC3_CONFIG_32_1, + .qos = LC3_QOS_32_1_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_32_2_2 = { + .cc = LC3_CONFIG_32_2, + .qos = LC3_QOS_32_2_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_44_1_2 = { + .cc = LC3_CONFIG_44_1, + .qos = LC3_QOS_44_1_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_44_2_2 = { + .cc = LC3_CONFIG_44_2, + .qos = LC3_QOS_44_2_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_1_2 = { + .cc = LC3_CONFIG_48_1, + .qos = LC3_QOS_48_1_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_2_2 = { + .cc = LC3_CONFIG_48_2, + .qos = LC3_QOS_48_2_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_3_2 = { + .cc = LC3_CONFIG_48_3, + .qos = LC3_QOS_48_3_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_4_2 = { + .cc = LC3_CONFIG_48_4, + .qos = LC3_QOS_48_4_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_5_2 = { + .cc = LC3_CONFIG_48_5, + .qos = LC3_QOS_48_5_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +static struct test_config cfg_src_48_6_2 = { + .cc = LC3_CONFIG_48_6, + .qos = LC3_QOS_48_6_2, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, +}; + +#define SCC_SRC_8_1_2 \ + SCC_SRC_8_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_8_2_2 \ + SCC_SRC_8_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_16_1_2 \ + SCC_SRC_16_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x1e, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_16_2_2 \ + SCC_SRC_16_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x28, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_24_1_2 \ + SCC_SRC_24_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x2d, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_24_2_2 \ + SCC_SRC_24_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_32_1_2 \ + SCC_SRC_32_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x3c, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_32_2_2 \ + SCC_SRC_32_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x50, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_44_1_2 \ + SCC_SRC_44_1, \ + QOS_SRC(0xe3, 0x1f, 0x00, 0x00, 0x02, 0x62, 0x00, 0x0d, 0x50, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_44_2_2 \ + SCC_SRC_44_2, \ + QOS_SRC(0x84, 0x2a, 0x00, 0x00, 0x02, 0x82, 0x00, 0x0d, 0x55, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_1_2 \ + SCC_SRC_48_1, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x4b, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_2_2 \ + SCC_SRC_48_2, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x64, 0x00, 0x0d, 0x5f, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_3_2 \ + SCC_SRC_48_3, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x5a, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_4_2 \ + SCC_SRC_48_4, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x78, 0x00, 0x0d, 0x64, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_5_2 \ + SCC_SRC_48_5, \ + QOS_SRC(0x4c, 0x1d, 0x00, 0x00, 0x02, 0x75, 0x00, 0x0d, 0x4b, 0x00, \ + 0x40, 0x9c, 0x00) + +#define SCC_SRC_48_6_2 \ + SCC_SRC_48_6, \ + QOS_SRC(0x10, 0x27, 0x00, 0x00, 0x02, 0x9b, 0x00, 0x0d, 0x64, 0x00, \ + 0x40, 0x9c, 0x00) + +/* Test Purpose: + * Verify that a Unicast Client IUT can initiate a Config QoS operation for the + * LC3 codec. + * + * Pass verdict: + * The IUT successfully writes to the ASE Control Point characteristic with the + * opcode set to 0x02 (Config QoS) and the specified parameters. + */ +static void test_scc_qos_lc3(void) +{ + define_test("BAP/UCL/SCC/BV-035-C [UCL SRC Config QoS, LC3 8_1_1]", + test_client, &cfg_snk_8_1_1, SCC_SNK_8_1_1); + define_test("BAP/UCL/SCC/BV-036-C [UCL SRC Config QoS, LC3 8_2_1]", + test_client, &cfg_snk_8_2_1, SCC_SNK_8_2_1); + define_test("BAP/UCL/SCC/BV-037-C [UCL SRC Config QoS, LC3 16_1_1]", + test_client, &cfg_snk_16_1_1, SCC_SNK_16_1_1); + define_test("BAP/UCL/SCC/BV-038-C [UCL SRC Config QoS, LC3 16_2_1]", + test_client, &cfg_snk_16_2_1, SCC_SNK_16_2_1); + define_test("BAP/UCL/SCC/BV-039-C [UCL SRC Config QoS, LC3 24_1_1]", + test_client, &cfg_snk_24_1_1, SCC_SNK_24_1_1); + define_test("BAP/UCL/SCC/BV-040-C [UCL SRC Config QoS, LC3 24_2_1]", + test_client, &cfg_snk_24_2_1, SCC_SNK_24_2_1); + define_test("BAP/UCL/SCC/BV-041-C [UCL SRC Config QoS, LC3 32_1_1]", + test_client, &cfg_snk_32_1_1, SCC_SNK_32_1_1); + define_test("BAP/UCL/SCC/BV-042-C [UCL SRC Config QoS, LC3 32_2_1]", + test_client, &cfg_snk_32_2_1, SCC_SNK_32_2_1); + define_test("BAP/UCL/SCC/BV-043-C [UCL SRC Config QoS, LC3 44.1_1_1]", + test_client, &cfg_snk_44_1_1, SCC_SNK_44_1_1); + define_test("BAP/UCL/SCC/BV-044-C [UCL SRC Config QoS, LC3 44.1_2_1]", + test_client, &cfg_snk_44_2_1, SCC_SNK_44_2_1); + define_test("BAP/UCL/SCC/BV-045-C [UCL SRC Config QoS, LC3 48_1_1]", + test_client, &cfg_snk_48_1_1, SCC_SNK_48_1_1); + define_test("BAP/UCL/SCC/BV-046-C [UCL SRC Config QoS, LC3 48_2_1]", + test_client, &cfg_snk_48_2_1, SCC_SNK_48_2_1); + define_test("BAP/UCL/SCC/BV-047-C [UCL SRC Config QoS, LC3 48_3_1]", + test_client, &cfg_snk_48_3_1, SCC_SNK_48_3_1); + define_test("BAP/UCL/SCC/BV-048-C [UCL SRC Config QoS, LC3 48_4_1]", + test_client, &cfg_snk_48_4_1, SCC_SNK_48_4_1); + define_test("BAP/UCL/SCC/BV-049-C [UCL SRC Config QoS, LC3 48_5_1]", + test_client, &cfg_snk_48_5_1, SCC_SNK_48_5_1); + define_test("BAP/UCL/SCC/BV-050-C [UCL SRC Config QoS, LC3 48_6_1]", + test_client, &cfg_snk_48_6_1, SCC_SNK_48_6_1); + define_test("BAP/UCL/SCC/BV-051-C [UCL SNK Config QoS, LC3 8_1_1]", + test_client, &cfg_src_8_1_1, SCC_SRC_8_1_1); + define_test("BAP/UCL/SCC/BV-052-C [UCL SNK Config QoS, LC3 8_2_1]", + test_client, &cfg_src_8_2_1, SCC_SRC_8_2_1); + define_test("BAP/UCL/SCC/BV-053-C [UCL SNK Config QoS, LC3 16_1_1]", + test_client, &cfg_src_16_1_1, SCC_SRC_16_1_1); + define_test("BAP/UCL/SCC/BV-054-C [UCL SNK Config QoS, LC3 16_2_1]", + test_client, &cfg_src_16_2_1, SCC_SRC_16_2_1); + define_test("BAP/UCL/SCC/BV-055-C [UCL SNK Config QoS, LC3 24_1_1]", + test_client, &cfg_src_24_1_1, SCC_SRC_24_1_1); + define_test("BAP/UCL/SCC/BV-056-C [UCL SNK Config QoS, LC3 24_2_1]", + test_client, &cfg_src_24_2_1, SCC_SRC_24_2_1); + define_test("BAP/UCL/SCC/BV-057-C [UCL SNK Config QoS, LC3 32_1_1]", + test_client, &cfg_src_32_1_1, SCC_SRC_32_1_1); + define_test("BAP/UCL/SCC/BV-058-C [UCL SNK Config QoS, LC3 32_2_1]", + test_client, &cfg_src_32_2_1, SCC_SRC_32_2_1); + define_test("BAP/UCL/SCC/BV-059-C [UCL SNK Config QoS, LC3 44.1_1_1]", + test_client, &cfg_src_44_1_1, SCC_SRC_44_1_1); + define_test("BAP/UCL/SCC/BV-060-C [UCL SNK Config QoS, LC3 44.1_2_1]", + test_client, &cfg_src_44_2_1, SCC_SRC_44_2_1); + define_test("BAP/UCL/SCC/BV-061-C [UCL SNK Config QoS, LC3 48_1_1]", + test_client, &cfg_src_48_1_1, SCC_SRC_48_1_1); + define_test("BAP/UCL/SCC/BV-062-C [UCL SNK Config QoS, LC3 48_2_1]", + test_client, &cfg_src_48_2_1, SCC_SRC_48_2_1); + define_test("BAP/UCL/SCC/BV-063-C [UCL SNK Config QoS, LC3 48_3_1]", + test_client, &cfg_src_48_3_1, SCC_SRC_48_3_1); + define_test("BAP/UCL/SCC/BV-064-C [UCL SNK Config QoS, LC3 48_4_1]", + test_client, &cfg_src_48_4_1, SCC_SRC_48_4_1); + define_test("BAP/UCL/SCC/BV-065-C [UCL SNK Config QoS, LC3 48_5_1]", + test_client, &cfg_src_48_5_1, SCC_SRC_48_5_1); + define_test("BAP/UCL/SCC/BV-066-C [UCL SNK Config QoS, LC3 48_6_1]", + test_client, &cfg_src_48_6_1, SCC_SRC_48_6_1); + define_test("BAP/UCL/SCC/BV-067-C [UCL SRC Config QoS, LC3 8_1_2]", + test_client, &cfg_snk_8_1_2, SCC_SNK_8_1_2); + define_test("BAP/UCL/SCC/BV-068-C [UCL SRC Config QoS, LC3 8_2_2]", + test_client, &cfg_snk_8_2_2, SCC_SNK_8_2_2); + define_test("BAP/UCL/SCC/BV-069-C [UCL SRC Config QoS, LC3 16_1_2]", + test_client, &cfg_snk_16_1_2, SCC_SNK_16_1_2); + define_test("BAP/UCL/SCC/BV-070-C [UCL SRC Config QoS, LC3 16_2_2]", + test_client, &cfg_snk_16_2_2, SCC_SNK_16_2_2); + define_test("BAP/UCL/SCC/BV-071-C [UCL SRC Config QoS, LC3 24_1_2]", + test_client, &cfg_snk_24_1_2, SCC_SNK_24_1_2); + define_test("BAP/UCL/SCC/BV-072-C [UCL SRC Config QoS, LC3 24_2_2]", + test_client, &cfg_snk_24_2_2, SCC_SNK_24_2_2); + define_test("BAP/UCL/SCC/BV-073-C [UCL SRC Config QoS, LC3 32_1_2]", + test_client, &cfg_snk_32_1_2, SCC_SNK_32_1_2); + define_test("BAP/UCL/SCC/BV-074-C [UCL SRC Config QoS, LC3 32_2_2]", + test_client, &cfg_snk_32_2_2, SCC_SNK_32_2_2); + define_test("BAP/UCL/SCC/BV-075-C [UCL SRC Config QoS, LC3 44.1_1_2]", + test_client, &cfg_snk_44_1_2, SCC_SNK_44_1_2); + define_test("BAP/UCL/SCC/BV-076-C [UCL SRC Config QoS, LC3 44.1_2_2]", + test_client, &cfg_snk_44_2_2, SCC_SNK_44_2_2); + define_test("BAP/UCL/SCC/BV-077-C [UCL SRC Config QoS, LC3 48_1_2]", + test_client, &cfg_snk_48_1_2, SCC_SNK_48_1_2); + define_test("BAP/UCL/SCC/BV-078-C [UCL SRC Config QoS, LC3 48_2_2]", + test_client, &cfg_snk_48_2_2, SCC_SNK_48_2_2); + define_test("BAP/UCL/SCC/BV-079-C [UCL SRC Config QoS, LC3 48_3_2]", + test_client, &cfg_snk_48_3_2, SCC_SNK_48_3_2); + define_test("BAP/UCL/SCC/BV-080-C [UCL SRC Config QoS, LC3 48_4_2]", + test_client, &cfg_snk_48_4_2, SCC_SNK_48_4_2); + define_test("BAP/UCL/SCC/BV-081-C [UCL SRC Config QoS, LC3 48_5_2]", + test_client, &cfg_snk_48_5_2, SCC_SNK_48_5_2); + define_test("BAP/UCL/SCC/BV-082-C [UCL SRC Config QoS, LC3 48_6_2]", + test_client, &cfg_snk_48_6_2, SCC_SNK_48_6_2); + define_test("BAP/UCL/SCC/BV-083-C [UCL SNK Config QoS, LC3 8_1_2]", + test_client, &cfg_src_8_1_2, SCC_SRC_8_1_2); + define_test("BAP/UCL/SCC/BV-084-C [UCL SNK Config QoS, LC3 8_2_2]", + test_client, &cfg_src_8_2_2, SCC_SRC_8_2_2); + define_test("BAP/UCL/SCC/BV-085-C [UCL SNK Config QoS, LC3 16_1_2]", + test_client, &cfg_src_16_1_2, SCC_SRC_16_1_2); + define_test("BAP/UCL/SCC/BV-086-C [UCL SNK Config QoS, LC3 16_2_2]", + test_client, &cfg_src_16_2_2, SCC_SRC_16_2_2); + define_test("BAP/UCL/SCC/BV-087-C [UCL SNK Config QoS, LC3 24_1_2]", + test_client, &cfg_src_24_1_2, SCC_SRC_24_1_2); + define_test("BAP/UCL/SCC/BV-088-C [UCL SNK Config QoS, LC3 24_2_2]", + test_client, &cfg_src_24_2_2, SCC_SRC_24_2_2); + define_test("BAP/UCL/SCC/BV-089-C [UCL SNK Config QoS, LC3 32_1_2]", + test_client, &cfg_src_32_1_2, SCC_SRC_32_1_2); + define_test("BAP/UCL/SCC/BV-090-C [UCL SNK Config QoS, LC3 32_2_2]", + test_client, &cfg_src_32_2_2, SCC_SRC_32_2_2); + define_test("BAP/UCL/SCC/BV-091-C [UCL SNK Config QoS, LC3 44.1_1_2]", + test_client, &cfg_src_44_1_2, SCC_SRC_44_1_2); + define_test("BAP/UCL/SCC/BV-092-C [UCL SNK Config QoS, LC3 44.1_2_2]", + test_client, &cfg_src_44_2_2, SCC_SRC_44_2_2); + define_test("BAP/UCL/SCC/BV-093-C [UCL SNK Config QoS, LC3 48_1_2]", + test_client, &cfg_src_48_1_2, SCC_SRC_48_1_2); + define_test("BAP/UCL/SCC/BV-094-C [UCL SNK Config QoS, LC3 48_2_2]", + test_client, &cfg_src_48_2_2, SCC_SRC_48_2_2); + define_test("BAP/UCL/SCC/BV-095-C [UCL SNK Config QoS, LC3 48_3_2]", + test_client, &cfg_src_48_3_2, SCC_SRC_48_3_2); + define_test("BAP/UCL/SCC/BV-096-C [UCL SNK Config QoS, LC3 48_4_2]", + test_client, &cfg_src_48_4_2, SCC_SRC_48_4_2); + define_test("BAP/UCL/SCC/BV-097-C [UCL SNK Config QoS, LC3 48_5_2]", + test_client, &cfg_src_48_5_2, SCC_SRC_48_5_2); + define_test("BAP/UCL/SCC/BV-098-C [UCL SNK Config QoS, LC3 48_6_2]", + test_client, &cfg_src_48_6_2, SCC_SRC_48_6_2); +} + +static struct test_config cfg_snk_qos_vs = { + .cc = IOV_NULL, + .qos = QOS_UCAST, + .snk = true, + .vs = true, + .state = BT_BAP_STREAM_STATE_QOS +}; + +#define SCC_SNK_QOS_VS \ + SCC_SNK_VS, \ + QOS_SNK(0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00) + +static struct test_config cfg_src_qos_vs = { + .cc = IOV_NULL, + .qos = QOS_UCAST, + .src = true, + .vs = true, + .state = BT_BAP_STREAM_STATE_QOS +}; + +#define SCC_SRC_QOS_VS \ + SCC_SRC_VS, \ + QOS_SRC(0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00) + +/* Test Purpose: + * Verify that a Unicast Client IUT can initiate a Config QoS operation for a + * vendor-specific codec. + * + * Pass verdict: + * The IUT successfully writes to the ASE Control Point characteristic with the + * opcode set to 0x02 (Config QoS) and the specified parameters. + */ +static void test_scc_qos_vs(void) +{ + define_test("BAP/UCL/SCC/BV-099-C [UCL SNK Config QoS, VS]", + test_client, &cfg_src_qos_vs, SCC_SRC_QOS_VS); + define_test("BAP/UCL/SCC/BV-100-C [UCL SRC QoS Codec, VS]", + test_client, &cfg_snk_qos_vs, SCC_SNK_QOS_VS); +} + +static struct test_config cfg_snk_enable = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_ENABLING +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 03010104030201 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0301010000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x0016 + * Data: 0101010300403020100 + */ +#define SCC_SNK_ENABLE \ + SCC_SNK_16_2_1, \ + IOV_DATA(0x52, 0x22, 0x00, 0x03, 0x01, 0x01, 0x04, 0x03, 0x02, 0x01, \ + 00), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x03, 0x00, 0x00, 0x04, 0x03, 0x02, \ + 0x01, 0x00) + +static struct test_config cfg_src_enable = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_ENABLING +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 0301030403020100 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0301030000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x001c + * Data: 030300000403020100 + */ +#define SCC_SRC_ENABLE \ + SCC_SRC_16_2_1, \ + IOV_DATA(0x52, 0x22, 0x00, 0x03, 0x01, 0x03, 0x04, 0x03, 0x02, 0x01, \ + 00), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x03, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x03, 0x00, 0x00, 0x04, 0x03, 0x02, \ + 0x01, 0x00) + +/* Test Purpose: + * Verify that a Unicast Client IUT can initiate an Enable operation for an ASE + * with a Unicast Server that is either in the Audio Sink role or the Audio + * Source role. + * + * Pass verdict: + * The IUT successfully writes to the ASE Control Point characteristic with the + * opcode set to 0x03 (Enable) and the specified parameters. + */ +static void test_scc_enable(void) +{ + define_test("BAP/UCL/SCC/BV-101-C [UCL SRC Enable]", + test_client, &cfg_snk_enable, SCC_SNK_ENABLE); + define_test("BAP/UCL/SCC/BV-102-C [UCL SNK Enable]", + test_client, &cfg_src_enable, SCC_SRC_ENABLE); +} + +static struct test_config cfg_snk_disable = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_DISABLING +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 050101 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0501010000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x0016 + * Data: 01010102010a00204e00409c00204e00409c00_qos + */ +#define ASE_SNK_DISABLE \ + IOV_DATA(0x52, 0x22, 0x00, 0x05, 0x01, 0x01), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x05, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x02, 0x00, 0x00, 0x4c, 0x1d, 0x00, \ + 0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, 0x40, 0x9c, \ + 0x00) + +#define SCC_SNK_DISABLE \ + SCC_SNK_ENABLE, \ + ASE_SNK_DISABLE + +static struct test_config cfg_src_disable = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_DISABLING +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 050103 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0301030000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x001c + * Data: 030300000403020100 + */ +#define ASE_SRC_DISABLE \ + IOV_DATA(0x52, 0x22, 0x00, 0x05, 0x01, 0x03), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x05, 0x01, 0x03, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x05, 0x00, 0x00, 0x4c, 0x1d, 0x00, \ + 0x00, 0x02, 0x1a, 0x00, 0x04, 0x08, 0x00, 0x40, 0x9c, \ + 0x00) +#define SCC_SRC_DISABLE \ + SCC_SRC_ENABLE, \ + ASE_SRC_DISABLE + +static void state_start_disable(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_STREAMING: + id = bt_bap_stream_disable(data->stream, true, bap_disable, + data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_disable_streaming = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_STREAMING, + .state_func = state_start_disable +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 040101 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0401010000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x0016 + * Data: 0101010400403020100 + */ +#define ASE_SRC_START \ + IOV_DATA(0x52, 0x22, 0x00, 0x04, 0x01, 0x03), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x04, 0x01, 0x03, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x04, 0x00, 0x00, 0x04, 0x03, 0x02, \ + 0x01, 0x00) + +#define SCC_SRC_DISABLE_STREAMING \ + SCC_SRC_ENABLE, \ + ASE_SRC_START, \ + ASE_SRC_DISABLE + +/* Test Purpose: + * Verify that a Unicast Client IUT can initiate a Disable operation for an ASE + * in the Enabling or Streaming state. + * + * Pass verdict: + * The IUT successfully writes to the ASE Control Point characteristic with the + * opcode set to 0x05 (Disable) and the specified parameters. + */ +static void test_scc_disable(void) +{ + define_test("BAP/UCL/SCC/BV-103-C [UCL SNK Disable in Enabling State]", + test_client, &cfg_src_disable, SCC_SRC_DISABLE); + define_test("BAP/UCL/SCC/BV-104-C [UCL SRC Disable in Enabling or " + "Streaming state]", + test_client, &cfg_snk_disable, SCC_SNK_DISABLE); + define_test("BAP/UCL/SCC/BV-105-C [UCL SNK Disable in Streaming State]", + test_client, &cfg_src_disable_streaming, + SCC_SRC_DISABLE_STREAMING); +} + +static void bap_release(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + if (code) + tester_test_failed(); +} + +static void state_cc_release(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_CONFIG: + id = bt_bap_stream_release(data->stream, bap_release, data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_cc_release = { + .cc = LC3_CONFIG_16_2, + .qos = QOS_UCAST, + .src = true, + .state_func = state_cc_release, +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 080103 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0801030000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x001c + * Data: 0300 + */ +#define ASE_SRC_RELEASE \ + IOV_DATA(0x52, 0x22, 0x00, 0x08, 0x01, 0x03), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x00) + +#define SCC_SRC_CC_RELEASE \ + SCC_SRC_16_2, \ + ASE_SRC_RELEASE + +static struct test_config cfg_snk_cc_release = { + .cc = LC3_CONFIG_16_2, + .qos = QOS_UCAST, + .snk = true, + .state_func = state_cc_release, +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 080101 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0801010000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x0016 + * Data: 0300 + */ +#define ASE_SNK_RELEASE \ + IOV_DATA(0x52, 0x22, 0x00, 0x08, 0x01, 0x01), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x16, 0x00, 0x03, 0x00) + +#define SCC_SNK_CC_RELEASE \ + SCC_SNK_16_2, \ + ASE_SNK_RELEASE + +static void state_qos_release(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_QOS: + id = bt_bap_stream_release(data->stream, bap_release, data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_qos_release = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_QOS, + .state_func = state_qos_release, +}; + +#define SCC_SRC_QOS_RELEASE \ + SCC_SRC_16_2_1, \ + ASE_SRC_RELEASE + +static struct test_config cfg_snk_qos_release = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_QOS, + .state_func = state_qos_release, +}; + +#define SCC_SNK_QOS_RELEASE \ + SCC_SNK_16_2_1, \ + ASE_SNK_RELEASE + +static void state_enable_release(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_ENABLING: + id = bt_bap_stream_release(data->stream, bap_release, data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_enable_release = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_ENABLING, + .state_func = state_enable_release, +}; + +#define SCC_SRC_ENABLE_RELEASE \ + SCC_SRC_ENABLE, \ + ASE_SRC_RELEASE + +static struct test_config cfg_snk_enable_release = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_ENABLING, + .state_func = state_enable_release, +}; + +#define SCC_SNK_ENABLE_RELEASE \ + SCC_SNK_ENABLE, \ + ASE_SNK_RELEASE + +static void state_start_release(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_STREAMING: + id = bt_bap_stream_release(data->stream, bap_release, data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_start_release = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_STREAMING, + .state_func = state_start_release, +}; + +#define SCC_SRC_START_RELEASE \ + SCC_SRC_ENABLE, \ + ASE_SRC_START, \ + ASE_SRC_RELEASE + +static void state_disable_release(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_DISABLING: + id = bt_bap_stream_release(data->stream, bap_release, data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_disable_release = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_DISABLING, + .state_func = state_disable_release, +}; + +#define SCC_SRC_DISABLE_RELEASE \ + SCC_SRC_DISABLE, \ + ASE_SRC_RELEASE + +/* Test Purpose: + * Verify that a Unicast Client IUT can release an ASE by initiating a Release + * operation. + * + * Pass verdict: + * The IUT successfully writes to the ASE Control Point characteristic with the + * opcode set to 0x08 (Release) and the specified parameters. + */ +static void test_scc_release(void) +{ + define_test("BAP/UCL/SCC/BV-106-C [UCL SNK Release in Codec Configured" + " state]", + test_client, &cfg_src_cc_release, SCC_SRC_CC_RELEASE); + define_test("BAP/UCL/SCC/BV-107-C [UCL SRC Release in Codec Configured" + " state]", + test_client, &cfg_snk_cc_release, SCC_SNK_CC_RELEASE); + define_test("BAP/UCL/SCC/BV-108-C [UCL SNK Release in QoS Configured" + " state]", + test_client, &cfg_src_qos_release, SCC_SRC_QOS_RELEASE); + define_test("BAP/UCL/SCC/BV-109-C [UCL SRC Release in QoS Configured" + " state]", + test_client, &cfg_snk_qos_release, SCC_SNK_QOS_RELEASE); + define_test("BAP/UCL/SCC/BV-110-C [UCL SNK Release in Enabling state]", + test_client, &cfg_src_enable_release, + SCC_SRC_ENABLE_RELEASE); + define_test("BAP/UCL/SCC/BV-111-C [UCL SRC Release in Enabling or" + " Streaming state]", + test_client, &cfg_snk_enable_release, + SCC_SNK_ENABLE_RELEASE); + define_test("BAP/UCL/SCC/BV-112-C [UCL SNK Release in Streaming state]", + test_client, &cfg_src_start_release, + SCC_SRC_START_RELEASE); + define_test("BAP/UCL/SCC/BV-113-C [UCL SNK Release in Disabling state]", + test_client, &cfg_src_disable_release, + SCC_SRC_DISABLE_RELEASE); +} + +static void bap_metadata(struct bt_bap_stream *stream, + uint8_t code, uint8_t reason, + void *user_data) +{ + if (code) + tester_test_failed(); +} + +static void state_enable_metadata(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + struct iovec iov = {}; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_ENABLING: + id = bt_bap_stream_metadata(data->stream, &iov, bap_metadata, + data); + g_assert(id); + break; + } +} + +static struct test_config cfg_snk_metadata = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .snk = true, + .state = BT_BAP_STREAM_STATE_ENABLING, + .state_func = state_enable_metadata +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 07010100 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0701010000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x0016 + * Data: 01010102010a00204e00409c00204e00409c00_qos + */ +#define ASE_SNK_METADATA \ + IOV_DATA(0x52, 0x22, 0x00, 0x07, 0x01, 0x01, 0x00), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x05, 0x00, 0x00, 0x4c, 0x1d, 0x00, \ + 0x00, 0x02, 0x1a, 0x00, 0x02, 0x08, 0x00, 0x40, 0x9c, \ + 0x00) + +#define SCC_SNK_METADATA \ + SCC_SNK_ENABLE, \ + ASE_SNK_METADATA + +static struct test_config cfg_src_metadata = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_ENABLING, + .state_func = state_enable_metadata +}; + +/* ATT: Write Command (0x52) len 23 + * Handle: 0x0022 + * Data: 07010300 + * ATT: Handle Value Notification (0x1b) len 7 + * Handle: 0x0022 + * Data: 0701030000 + * ATT: Handle Value Notification (0x1b) len 37 + * Handle: 0x001c + * Data: 030300000403020100 + */ +#define ASE_SRC_METADATA \ + IOV_DATA(0x52, 0x22, 0x00, 0x07, 0x01, 0x03, 0x00), \ + IOV_DATA(0x1b, 0x22, 0x00, 0x07, 0x01, 0x03, 0x00, 0x00), \ + IOV_NULL, \ + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, 0x05, 0x00, 0x00, 0x4c, 0x1d, 0x00, \ + 0x00, 0x02, 0x1a, 0x00, 0x04, 0x08, 0x00, 0x40, 0x9c, \ + 0x00) +#define SCC_SRC_METADATA \ + SCC_SRC_ENABLE, \ + ASE_SRC_METADATA + +static void state_start_metadata(struct bt_bap_stream *stream, + uint8_t old_state, uint8_t new_state, + void *user_data) +{ + struct test_data *data = user_data; + struct iovec iov = {}; + uint8_t id; + + switch (new_state) { + case BT_BAP_STREAM_STATE_STREAMING: + id = bt_bap_stream_metadata(data->stream, &iov, bap_metadata, + data); + g_assert(id); + break; + } +} + +static struct test_config cfg_src_metadata_streaming = { + .cc = LC3_CONFIG_16_2, + .qos = LC3_QOS_16_2_1, + .src = true, + .state = BT_BAP_STREAM_STATE_STREAMING, + .state_func = state_start_metadata +}; + +#define SCC_SRC_METADATA_STREAMING \ + SCC_SRC_ENABLE, \ + ASE_SRC_START, \ + ASE_SRC_METADATA + +/* Unicast Client Initiates Update Metadata Operation + * + * Test Purpose: + * Verify that a Unicast Client IUT can update the Metadata of an ASE by + * initiating an Update Metadata operation. + * + * Pass verdict: + * The IUT successfully writes to the ASE Control Point characteristic with the + * opcode set to 0x07 (Update Metadata) and the specified parameters. + */ +static void test_scc_metadata(void) +{ + define_test("BAP/UCL/SCC/BV-115-C [UCL SNK Update Metadata in Enabling " + "State]", + test_client, &cfg_src_metadata, SCC_SRC_METADATA); + define_test("BAP/UCL/SCC/BV-116-C [UCL SRC Update Metadata in Enabling " + "or Streaming state]", + test_client, &cfg_snk_metadata, SCC_SNK_METADATA); + define_test("BAP/UCL/SCC/BV-117-C [UCL SNK Update Metadata in Streaming" + " State]", + test_client, &cfg_src_metadata_streaming, + SCC_SRC_METADATA_STREAMING); +} + static void test_scc(void) { test_scc_cc_lc3(); test_scc_cc_vs(); + test_scc_qos_lc3(); + test_scc_qos_vs(); + test_scc_enable(); + test_scc_disable(); + test_scc_release(); + test_scc_metadata(); } int main(int argc, char *argv[]) diff -Nru bluez-5.70/unit/test-bass.c bluez-5.71/unit/test-bass.c --- bluez-5.70/unit/test-bass.c 2023-08-25 01:02:40.000000000 +0800 +++ bluez-5.71/unit/test-bass.c 2023-12-14 05:40:27.000000000 +0800 @@ -190,6 +190,301 @@ DISC_BCAST_AUDIO_SCAN_CP, \ BASS_READ_CHAR_DESC +/* ATT: Write Request (0x12) len 4 + * Handle: 0x0004 Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + * ATT: Write Request (0x12) len 4 + * Handle: 0x0007 Type: Client Characteristic Configuration (0x2902) + * Data: 0100 + * Notification (0x01) + * ATT: Write Response (0x13) len 0 + */ +#define BASS_WRITE_CHAR_DESC \ + IOV_DATA(0x12, 0x04, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x12, 0x07, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13) + +/* ATT: Read Request (0x0a) len 2 + * Handle: 0x0003 Type: Broadcast Receive State (0x2bc8) + * ATT: Read Response (0x0b) len 0 + * Handle: 0x0003 Broadcast Receive State (0x2bc8) + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0006 Type: Broadcast Receive State (0x2bc8) + * ATT: Read Response (0x0b) len 0 + * Handle: 0x0006 Broadcast Receive State (0x2bc8) + */ +#define BASS_READ_BCAST_RECV_STATE_CHARS \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b), \ + IOV_DATA(0x0a, 0x06, 0x00), \ + IOV_DATA(0x0b) + +#define BASS_CP_WRITE_CMD(_op, _args...) \ + IOV_DATA(0x52, 0x09, 0x00, _op, _args) + +#define BASS_CP_WRITE_REQ(_op, _args...) \ + IOV_DATA(0x12, 0x09, 0x00, _op, _args) + +/* ATT: Write Command (0x52) len 19 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0401693C4572685526613465597073275455 + * Opcode: Set Broadcast_Code + * Source_ID: 1 + * Broadcast_Code: 0x55542773705965346126556872453c69 + * ATT: Write Command (0x52) len 2 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0501 + * Opcode: Remove Source + * Source_ID: 1 + */ +#define IGNORE_INVALID_SRC_ID \ + EXCHANGE_MTU, \ + BASS_FIND_BY_TYPE_VALUE, \ + DISC_BASS_CHAR, \ + BASS_FIND_INFO, \ + BASS_WRITE_CHAR_DESC, \ + BASS_READ_BCAST_RECV_STATE_CHARS, \ + BASS_CP_WRITE_CMD(0x04, 0x01, 0x69, 0x3C, 0x45, 0x72, 0x68, \ + 0x55, 0x26, 0x61, 0x34, 0x65, 0x59, 0x70, \ + 0x73, 0x27, 0x54, 0x55), \ + IOV_NULL, \ + BASS_CP_WRITE_CMD(0x05, 0x01) + +/* ATT: Write Command (0x52) len 26 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0200F2698BE807C0003412000610270200000000000000000000 + * Opcode: Add Source + * Advertiser_Address_Type: Public Device or Public Identity Address + * Advertiser_Address: c0:07:e8:8b:69:f2 + * Advertising_SID: 0x00 + * Broadcast_ID: 0x001234 + * PA_Sync: 0x06 (Reserved for Future Use) + * PA_Interval: 0x2710 + * Num_Subgroups: 2 + * Subgroup #0: + * BIS_Sync: 00000000000000000000000000000000 + * Metadata_Length: 0 + * Subgroup #1: + * BIS_Sync: 00000000000000000000000000000000 + * Metadata_Length: 0 + * ATT: Write Command (0x52) len 26 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0205F2698BE807C0003412000210270200000000000000000000 + * Opcode: Add Source + * Advertiser_Address_Type: 0x05 (Reserved for Future Use) + * Advertiser_Address: c0:07:e8:8b:69:f2 + * Advertising_SID: 0x00 + * Broadcast_ID: 0x001234 + * PA_Sync: Synchronize to PA (PAST not available) + * PA_Interval: 0x2710 + * Num_Subgroups: 2 + * Subgroup #0: + * BIS_Sync: 00000000000000000000000000000000 + * Metadata_Length: 0 + * Subgroup #1: + * BIS_Sync: 00000000000000000000000000000000 + * Metadata_Length: 0 + * ATT: Write Command (0x52) len 26 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0200F2698BE807C0003412000210270201000000000100000000 + * Opcode: Add Source + * Advertiser_Address_Type: Public Device or Public Identity Address + * Advertiser_Address: c0:07:e8:8b:69:f2 + * Advertising_SID: 0x00 + * Broadcast_ID: 0x001234 + * PA_Sync: Synchronize to PA (PAST not available) + * PA_Interval: 0x2710 + * Num_Subgroups: 2 + * Subgroup #0: + * BIS_Sync: 00000000000000000000000000000001 + * Metadata_Length: 0 + * Subgroup #1: + * BIS_Sync: 00000000000000000000000000000001 + * Metadata_Length: 0 + */ +#define ADD_SRC_INVALID_PARAMS \ + EXCHANGE_MTU, \ + BASS_FIND_BY_TYPE_VALUE, \ + DISC_BASS_CHAR, \ + BASS_FIND_INFO, \ + BASS_WRITE_CHAR_DESC,\ + BASS_READ_BCAST_RECV_STATE_CHARS, \ + BASS_CP_WRITE_CMD(0x02, 0x00, 0xF2, 0x69, 0x8B, 0xE8, 0x07, 0xC0, \ + 0x00, 0x34, 0x12, 0x00, 0x06, 0x10, 0x27, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00), \ + IOV_NULL, \ + BASS_CP_WRITE_CMD(0x02, 0x05, 0xF2, 0x69, 0x8B, 0xE8, 0x07, 0xC0, \ + 0x00, 0x34, 0x12, 0x00, 0x02, 0x10, 0x27, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00), \ + IOV_NULL, \ + BASS_CP_WRITE_CMD(0x02, 0x05, 0xF2, 0x69, 0x8B, 0xE8, 0x07, 0xC0, \ + 0x3F, 0x34, 0x12, 0x00, 0x02, 0x10, 0x27, 0x02, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00), \ + IOV_NULL, \ + BASS_CP_WRITE_CMD(0x02, 0x00, 0xF2, 0x69, 0x8B, 0xE8, 0x07, 0xC0, \ + 0x00, 0x34, 0x12, 0x00, 0x02, 0x10, 0x27, 0x02, \ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, \ + 0x00, 0x00) + +/* ATT: Write Request (0x12) len 3 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: FF + * Opcode: 0xff (Reserved For Future Use) + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Opcode Not Supported (0x80) + */ +#define OPCODE_NOT_SUPPORTED \ + EXCHANGE_MTU, \ + BASS_FIND_BY_TYPE_VALUE, \ + DISC_BASS_CHAR, \ + BASS_FIND_INFO, \ + BASS_WRITE_CHAR_DESC,\ + BASS_READ_BCAST_RECV_STATE_CHARS, \ + BASS_CP_WRITE_REQ(0xFF), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x80) + +/* ATT: Write Request (0x12) len 5 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 006dfe + * Opcode: Remote Scan Stopped + * Extra Data: 0xfe6d + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Write Request Rejected (0xFC) + * ATT: Write Request (0x12) len 5 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 006dfe + * Opcode: Remote Scan Started + * Extra Data: 0xa2c2 + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Write Request Rejected (0xFC) + * ATT: Write Request (0x12) len 25 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0200F2698BE807C0003412000210270100000000000000 + * Opcode: Add Source + * Advertiser_Address_Type: Public Device or Public Identity Address + * Advertiser_Address: c0:07:e8:8b:69:f2 + * Advertising_SID: 0x00 + * Broadcast_ID: 0x001234 + * PA_Sync: Synchronize to PA (PAST not available) + * PA_Interval: 0x2710 + * Num_Subgroups: 1 + * Subgroup #0: + * BIS_Sync: 00000000000000000000000000000001 + * Metadata_Length: 0 + * Extra Data: 0x0000 + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Write Request Rejected (0xFC) + * ATT: Write Request (0x12) len 13 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 03000210270100000000001500 + * Opcode: Modify Source + * Source_ID: 0x00 + * PA_Sync: Synchronize to PA (PAST not available) + * PA_Interval: 0x2710 + * Num_Subgroups: 1 + * Subgroup #0: + * BIS_Sync: 00000000000000000000000000000001 + * Metadata_Length: 0 + * Extra Data: 0x0015 + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Write Request Rejected (0xFC) + * ATT: Write Request (0x12) len 20 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0400B803EAC6AFBB65A25A41F153056802010000 + * Opcode: Set Broadcast_Code + * Source_ID: 0x00 + * Broadcast_Code: 0x0102680553f1415aa265bbafc6ea03b8 + * Extra Data: 0x0000 + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Write Request Rejected (0xFC) + * ATT: Write Request (0x12) len 4 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 05008F13 + * Opcode: Remove Source + * Source_ID: 0x00 + * Extra Data: 0x138f + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Write Request Rejected (0xFC) + */ +#define INVALID_LEN \ + EXCHANGE_MTU, \ + BASS_FIND_BY_TYPE_VALUE, \ + DISC_BASS_CHAR, \ + BASS_FIND_INFO, \ + BASS_WRITE_CHAR_DESC,\ + BASS_READ_BCAST_RECV_STATE_CHARS, \ + BASS_CP_WRITE_REQ(0x00, 0x6D, 0xFE), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0xFC), \ + BASS_CP_WRITE_REQ(0x01, 0xC2, 0xA2), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0xFC), \ + BASS_CP_WRITE_REQ(0x02, 0x00, 0xF2, 0x69, 0x8B, 0xE8, 0x07, 0xC0, \ + 0x00, 0x34, 0x12, 0x00, 0x02, 0x10, 0x27, 0x01, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0xFC), \ + BASS_CP_WRITE_REQ(0x03, 0x00, 0x02, 0x10, 0x27, 0x01, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x15, 0x00), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0xFC), \ + BASS_CP_WRITE_REQ(0x04, 0x00, 0xB8, 0x03, 0xEA, 0xC6, 0xAF, 0xBB, \ + 0x65, 0xA2, 0x5A, 0x41, 0xF1, 0x53, 0x05, 0x68, \ + 0x02, 0x01, 0x00, 0x00), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0xFC), \ + BASS_CP_WRITE_REQ(0x05, 0x00, 0x8F, 0x13), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0xFC) + +/* ATT: Write Request (0x12) len 20 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 0400B803EAC6AFBB65A25A41F153056802010000 + * Opcode: Set Broadcast_Code + * Source_ID: 0x05 + * Broadcast_Code: 0x0102680553f1415aa265bbafc6ea03b + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Invalid Source ID (0x81) + * ATT: Write Request (0x12) len 4 + * Handle: 0x0009 Type: Broadcast Audio Scan Control Point (0x2bc7) + * Data: 005 + * Opcode: Remove Source + * Source_ID: 0x05 + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Invalid Source ID (0x81) + */ +#define INVALID_SRC_ID \ + EXCHANGE_MTU, \ + BASS_FIND_BY_TYPE_VALUE, \ + DISC_BASS_CHAR, \ + BASS_FIND_INFO, \ + BASS_WRITE_CHAR_DESC, \ + BASS_READ_BCAST_RECV_STATE_CHARS, \ + BASS_CP_WRITE_REQ(0x04, 0x05, 0xB8, 0x03, 0xEA, 0xC6, 0xAF, 0xBB, \ + 0x65, 0xA2, 0x5A, 0x41, 0xF1, 0x53, 0x05, 0x68, \ + 0x02, 0x01), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x81), \ + BASS_CP_WRITE_REQ(0x05, 0x05), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x81) + #define iov_data(args...) ((const struct iovec[]) { args }) #define define_test(name, function, _cfg, args...) \ @@ -287,6 +582,63 @@ gatt_db_attribute_read_result(attrib, id, ecode, value, len); } +static void gatt_ccc_write_cb(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offset, + const uint8_t *value, size_t len, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct test_data *data = (void *)user_data; + struct ccc_state *ccc_state; + uint16_t val; + uint8_t ecode = 0; + + if (!value || len > 2) { + ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN; + goto done; + } + + if (offset > 2) { + ecode = BT_ATT_ERROR_INVALID_OFFSET; + goto done; + } + + if (len == 1) + val = *value; + else + val = get_le16(value); + + ccc_state = get_ccc_state(data, gatt_db_attribute_get_handle(attrib)); + if (!ccc_state) + return; + + /* If value is identical, then just succeed */ + if (val == ccc_state->value) + goto done; + + ccc_state->value = val; + +done: + gatt_db_attribute_write_result(attrib, id, ecode); +} + +static void gatt_notify_cb(struct gatt_db_attribute *attrib, + struct gatt_db_attribute *ccc, + const uint8_t *value, size_t len, + struct bt_att *att, void *user_data) +{ + struct test_data *data = user_data; + struct ccc_state *ccc_state; + + ccc_state = find_ccc_state(data, gatt_db_attribute_get_handle(ccc)); + if (!ccc_state || !(ccc_state->value & 0x0001)) + return; + + bt_gatt_server_send_notification(data->server, + gatt_db_attribute_get_handle(attrib), + value, len, false); +} + static void test_server(const void *user_data) { struct test_data *data = (void *)user_data; @@ -306,12 +658,17 @@ data->db = gatt_db_new(); g_assert(data->db); - gatt_db_ccc_register(data->db, gatt_ccc_read_cb, NULL, - NULL, data); + gatt_db_ccc_register(data->db, gatt_ccc_read_cb, gatt_ccc_write_cb, + gatt_notify_cb, data); data->bass = bt_bass_new(data->db, NULL, BDADDR_ANY); g_assert(data->bass); + bt_bass_set_att(data->bass, att); + bt_bass_attach(data->bass, NULL); + + bt_bass_set_debug(data->bass, print_debug, "bt_bass:", NULL); + data->server = bt_gatt_server_new(data->db, att, 64, 0); g_assert(data->server); @@ -387,11 +744,80 @@ DISC_BCAST_RECV_STATE); } +static void test_spe(void) +{ + /* BASS/SR/SPE/BI-01-C [Ignore Invalid Source ID] + * + * Test Purpose: + * Verify that the BASS Server IUT does not respond to a control point + * procedure call that uses an invalid Source_ID parameter. + * + * Pass verdict: + * The IUT does not send a notification of the Broadcast Receive State + * characteristic. + */ + define_test("BASS/SR/SPE/BI-01-C", test_server, NULL, + IGNORE_INVALID_SRC_ID); + + /* BASS/SR/SPE/BI-03-C [Add Source - Ignore Invalid Values] + * + * Test Purpose: + * Verify that the BASS Server IUT ignores Add Source control point + * procedure calls that include an RFU or Invalid parameter. + * + * Pass verdict: + * The IUT does not send a notification of the Broadcast Receive State + * characteristic. + */ + define_test("BASS/SR/SPE/BI-03-C", test_server, NULL, + ADD_SRC_INVALID_PARAMS); + + /* BASS/SR/SPE/BI-04-C [Opcode Not Supported] + * + * Test Purpose: + * Verify that the BASS Server IUT returns an Opcode Not Supported error + * response when the opcode written is not supported by the IUT or is + * within a range that is reserved for future use being written to the + * Broadcast Audio Scan Control Point. + * + * Pass verdict: + * The IUT sends an error response of OPCODE NOT SUPPORTED. + */ + define_test("BASS/SR/SPE/BI-04-C", test_server, NULL, + OPCODE_NOT_SUPPORTED); + + /* BASS/SR/SPE/BI-06-C [Invalid Length] + * + * Test Purpose: + * Verify that the BASS Server IUT rejects writing of an opcode with + * an invalid length. + * + * Pass verdict: + * The IUT rejects the opcode. + */ + define_test("BASS/SR/SPE/BI-06-C", test_server, NULL, + INVALID_LEN); + + /* BASS/SR/SPE/BI-07-C [Invalid Source ID] + * + * Test Purpose: + * Verify that the BASS Server IUT returns an error when a control + * point procedure passing an invalid Source_ID parameter is called. + * + * Pass verdict: + * The IUT sends an ATT Error Response with the Error Code set to + * Invalid Source_ID. + */ + define_test("BASS/SR/SPE/BI-07-C", test_server, NULL, + INVALID_SRC_ID); +} + int main(int argc, char *argv[]) { tester_init(&argc, &argv); test_sggit(); + test_spe(); return tester_run(); } diff -Nru bluez-5.70/unit/test-micp.c bluez-5.71/unit/test-micp.c --- bluez-5.70/unit/test-micp.c 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/unit/test-micp.c 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,838 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2023 NXP Semiconductors. All rights reserved. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include + + +#include + +#include "lib/bluetooth.h" +#include "lib/uuid.h" +#include "src/shared/util.h" +#include "src/shared/tester.h" +#include "src/shared/queue.h" +#include "src/shared/att.h" +#include "src/shared/gatt-db.h" +#include "src/shared/gatt-server.h" +#include "src/shared/gatt-helpers.h" +#include "src/shared/micp.h" + +struct test_data_mics { + struct gatt_db *db; + struct bt_micp *micp; + struct bt_gatt_server *server; + struct bt_gatt_client *client; + struct queue *ccc_states; + size_t iovcnt; + struct iovec *iov; +}; + +struct test_data_micp { + struct gatt_db *db; + struct bt_micp *micp; + struct bt_gatt_client *client; + size_t iovcnt; + struct iovec *iov; +}; + +struct ccc_state { + uint16_t handle; + uint16_t value; +}; + +struct notify { + uint16_t handle, ccc_handle; + uint8_t *value; + uint16_t len; + bt_gatt_server_conf_func_t conf; + void *user_data; +}; + +#define MICP_GATT_CLIENT_MTU 64 + +#define iov_data(args...) ((const struct iovec[]) { args }) + +#define define_test_mics(name, function, _cfg, args...) \ + do { \ + const struct iovec iov[] = { args }; \ + static struct test_data_mics data; \ + data.iovcnt = ARRAY_SIZE(iov_data(args)); \ + data.iov = util_iov_dup(iov, ARRAY_SIZE(iov_data(args))); \ + tester_add(name, &data, NULL, function, \ + test_teardown_mics); \ + } while (0) + +#define define_test_micp(name, function, _cfg, args...) \ + do { \ + const struct iovec iov[] = { args }; \ + static struct test_data_micp data; \ + data.iovcnt = ARRAY_SIZE(iov_data(args)); \ + data.iov = util_iov_dup(iov, ARRAY_SIZE(iov_data(args))); \ + tester_add(name, &data, test_setup, function, \ + test_teardown_micp); \ + } while (0) + +static void print_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + if (tester_use_debug()) + tester_debug("%s%s", prefix, str); +} + +static void test_teardown_mics(const void *user_data) +{ + struct test_data_mics *data = (void *)user_data; + + bt_micp_unref(data->micp); + bt_gatt_server_unref(data->server); + util_iov_free(data->iov, data->iovcnt); + gatt_db_unref(data->db); + + queue_destroy(data->ccc_states, free); + + tester_teardown_complete(); +} + +static void test_teardown_micp(const void *user_data) +{ + struct test_data_micp *data = (void *)user_data; + + bt_micp_unref(data->micp); + bt_gatt_client_unref(data->client); + util_iov_free(data->iov, data->iovcnt); + gatt_db_unref(data->db); + + tester_teardown_complete(); +} + +static void test_complete_cb(const void *user_data) +{ + tester_test_passed(); +} + +static void client_ready_cb(bool success, uint8_t att_ecode, void *user_data) +{ + + if (!success) + tester_setup_failed(); + else + tester_setup_complete(); +} + +static void micp_write_cb(bool success, uint8_t att_ecode, void *user_data) +{ + if (success) + printf("MICP Write successful\n"); + else + printf("\nWrite failed: 0x%02x\n", att_ecode); +} + +static void micp_write_value(struct bt_micp *micp, void *user_data) +{ + struct bt_mics *mics = micp_get_mics(micp); + uint16_t value_handle; + int ret; + uint16_t value = cpu_to_le16(0x0001); + + gatt_db_attribute_get_char_data(mics->ms, NULL, &value_handle, + NULL, NULL, NULL); + + printf("%s handle: %x\n", __func__, value_handle); + ret = bt_gatt_client_write_value(micp->client, value_handle, + (void *)&value, sizeof(value), micp_write_cb, NULL, NULL); + + if (!ret) + printf("bt_gatt_client_write_value() : Write FAILED"); +} + +static void micp_ready(struct bt_micp *micp, void *user_data) +{ + micp_write_value(micp, user_data); +} + +static void test_client(const void *user_data) +{ + struct test_data_micp *data = (void *)user_data; + struct io *io; + + io = tester_setup_io(data->iov, data->iovcnt); + g_assert(io); + + tester_io_set_complete_func(test_complete_cb); + + data->db = gatt_db_new(); + g_assert(data->db); + + data->micp = bt_micp_new(data->db, bt_gatt_client_get_db(data->client)); + g_assert(data->micp); + + bt_micp_set_debug(data->micp, print_debug, "bt_micp: ", NULL); + + bt_micp_ready_register(data->micp, micp_ready, data, NULL); + + bt_micp_attach(data->micp, data->client); +} + +static bool ccc_state_match(const void *a, const void *b) +{ + const struct ccc_state *ccc = a; + uint16_t handle = PTR_TO_UINT(b); + + return ccc->handle == handle; +} + +static struct ccc_state *find_ccc_state(struct test_data_mics *data, + uint16_t handle) +{ + return queue_find(data->ccc_states, ccc_state_match, + UINT_TO_PTR(handle)); +} + +static struct ccc_state *get_ccc_state(struct test_data_mics *data, + uint16_t handle) +{ + struct ccc_state *ccc; + + ccc = find_ccc_state(data, handle); + if (ccc) + return ccc; + + ccc = new0(struct ccc_state, 1); + ccc->handle = handle; + queue_push_tail(data->ccc_states, ccc); + + return ccc; +} + +static void gatt_notify_cb(struct gatt_db_attribute *attrib, + struct gatt_db_attribute *ccc, + const uint8_t *value, size_t len, + struct bt_att *att, void *user_data) +{ + struct test_data_mics *data = user_data; + struct notify notify; + + memset(¬ify, 0, sizeof(notify)); + + notify.handle = gatt_db_attribute_get_handle(attrib); + notify.ccc_handle = gatt_db_attribute_get_handle(ccc); + notify.value = (void *) value; + notify.len = len; + + printf("%s: notify.value:%d notify->len:%d\n", __func__, + (int)*(notify.value), notify.len); + if (!bt_gatt_server_send_notification(data->server, + notify.handle, notify.value, + notify.len, false)) + printf("%s: Failed to send notification\n", __func__); +} + +static void gatt_ccc_read_cb(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offset, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct test_data_mics *data = user_data; + struct ccc_state *ccc; + uint16_t handle; + uint8_t ecode = 0; + const uint8_t *value = NULL; + size_t len = 0; + + handle = gatt_db_attribute_get_handle(attrib); + + ccc = get_ccc_state(data, handle); + if (!ccc) { + ecode = BT_ATT_ERROR_UNLIKELY; + goto done; + } + + len = sizeof(ccc->value); + value = (void *) &ccc->value; + +done: + gatt_db_attribute_read_result(attrib, id, ecode, value, len); +} + +static void test_server(const void *user_data) +{ + struct test_data_mics *data = (void *)user_data; + struct bt_att *att; + struct io *io; + + io = tester_setup_io(data->iov, data->iovcnt); + g_assert(io); + + tester_io_set_complete_func(test_complete_cb); + + att = bt_att_new(io_get_fd(io), false); + g_assert(att); + + bt_att_set_debug(att, BT_ATT_DEBUG, print_debug, "bt_att:", NULL); + + data->db = gatt_db_new(); + g_assert(data->db); + + gatt_db_ccc_register(data->db, gatt_ccc_read_cb, NULL, + gatt_notify_cb, data); + + data->micp = bt_micp_new(data->db, NULL); + g_assert(data->micp); + + data->server = bt_gatt_server_new(data->db, att, 64, 0); + g_assert(data->server); + + bt_gatt_server_set_debug(data->server, print_debug, "bt_gatt_server:", + NULL); + + data->ccc_states = queue_new(); + + tester_io_send(); + + bt_att_unref(att); +} + +/* + * ATT: Exchange MTU Request (0x02) len 2 + * Client RX MTU: 64 + * + * ATT: Exchange MTU Response (0x03) len 2 + * Server RX MTU: 64 + */ +#define ATT_EXCHANGE_MTU IOV_DATA(0x02, 0x40, 0x00), \ + IOV_DATA(0x03, 0x40, 0x00) + +/* + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0xffff + * Attribute type: Server Supported Features (0x2b3a) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ +#define MICP_READ_SR_FEATURE IOV_DATA(0x08, 0x01, 0x00, 0Xff, 0xff, \ + 0x3a, 0x2b), \ + IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a) + +/* + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Primary Service (0x2800) + * + * ATT: Read By Group Type Response (0x11) len 7 + * Attribute data length: 6 + * Attribute group list: 1 entry + * Handle range: 0x0001-0x0004 + * UUID: Microphone Control (0x184d) + * + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0005-0xffff + * Attribute group type: Primary Service (0x2800) + * + * ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0006 + * Error: Attribute Not Found (0x0a) + */ +#define MICP_READ_GROUP_TYPE \ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \ + IOV_DATA(0x11, 0x06, \ + 0x01, 0x00, 0x04, 0x00, 0x4d, 0x18), \ + IOV_DATA(0x10, 0x05, 0x00, 0xff, 0xff, 0x00, 0x28), \ + IOV_DATA(0x01, 0x10, 0x06, 0x00, 0x0a) + +/* + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Secondary Service (0x2801) + * + * ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ +#define MICP_READ_REQ_SECOND_SERVICE \ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28), \ + IOV_DATA(0x01, 0x10, 0x01, 0x00, 0x0a) + +/* + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0004 + * Attribute type: Include (0x2802) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0001 + * Error: Attribute Not Found (0x0a) + */ +#define MICP_READ_REQ_INCLUDE_SERVICE \ + IOV_DATA(0x08, 0x01, 0x00, 0x04, 0x00, 0x02, 0x28), \ + IOV_DATA(0x01, 0x08, 0x01, 0x00, 0x0a) + +/* ATT: Find Information Request (0x04) len 4 + * Handle range: 0x0004-0x0004 + */ +#define MICP_FIND_INFO_REQ \ + IOV_DATA(0x04, 0x04, 0x00, 0x04, 0x00), \ + IOV_DATA(0x05, 0x01, 0x04, 0x00, 0x02, 0x29) + +/* + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0004 + * Attribute type: Characteristic (0x2803) + * + * ATT: Read By Type Response (0x09) len 8 + * Attribute data length: 7 + * Attribute data list: 1 entry + * Handle: 0x0002 + * Value: 1a0300c32b + * + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0003-0x0004 + * Attribute type: Characteristic (0x2803) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0004 + * Error: Attribute Not Found (0x0a) + */ +#define MICP_READ_REQ_CHAR \ + IOV_DATA(0x08, 0x01, 0x00, 0x04, 0x00, 0x03, 0x28),\ + IOV_DATA(0x09, 0x07, \ + 0x02, 0x00, 0x1a, 0x03, 0x00, 0xc3, 0x2b), \ + IOV_DATA(0x08, 0x03, 0x00, 0x04, 0x00, 0x03, 0x28), \ + IOV_DATA(0x01, 0x08, 0x04, 0x00, 0x0a) +/* + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0003 + * + * ATT: Read Response (0x0b) len 1 + */ +#define MICS_MUTE_READ \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x01) + +/* + * ATT: Write Request (0x12) len 4 + * Handle: 0x0004 + * Data: 0100 + * ATT: Write Response (0x13) len 0 + */ +#define MICS_EN_MUTE_DISCPTR \ + IOV_DATA(0x12, 0x04, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13) + +#define MICS_MUTE_WRITE \ + IOV_DATA(0x12, 0x03, 0x00, 0x01),\ + IOV_DATA(0x13) + +#define MICP_CL_CGGIT_SER_BV_01_C \ + MICS_MUTE_READ, \ + MICS_EN_MUTE_DISCPTR, \ + IOV_DATA(0x12, 0x03, 0x00, 0x01, 0x00), \ + IOV_DATA(0x01, 0x12, 0x03, 0x00, 0x013) + +#define MICP_CL_CGGIT_CHA_BV_01_C \ + MICS_MUTE_READ, \ + MICS_EN_MUTE_DISCPTR, \ + IOV_DATA(0x12, 0x03, 0x00, 0x01, 0x00), \ + IOV_DATA(0x013) + +#define MICP_CL_SPE_BI_01_C \ + MICS_MUTE_READ, \ + MICS_EN_MUTE_DISCPTR, \ + IOV_DATA(0x12, 0x03, 0x00, 0x01, 0x00), \ + IOV_DATA(0x01, 0x12, 0x03, 0x00, 0x80) + +/* GATT Discover All procedure */ +static const struct iovec setup_data[] = { + ATT_EXCHANGE_MTU, + MICP_READ_SR_FEATURE, + MICP_READ_GROUP_TYPE, + MICP_READ_REQ_SECOND_SERVICE, + MICP_READ_REQ_INCLUDE_SERVICE, + MICP_READ_REQ_CHAR, + MICP_FIND_INFO_REQ +}; + +static void test_setup(const void *user_data) +{ + struct test_data_micp *data = (void *)user_data; + struct bt_att *att; + struct gatt_db *db; + struct io *io; + + io = tester_setup_io(setup_data, ARRAY_SIZE(setup_data)); + g_assert(io); + + att = bt_att_new(io_get_fd(io), false); + g_assert(att); + + bt_att_set_debug(att, BT_ATT_DEBUG, print_debug, "bt_att:", NULL); + + db = gatt_db_new(); + g_assert(db); + + data->client = bt_gatt_client_new(db, att, MICP_GATT_CLIENT_MTU, 0); + g_assert(data->client); + + bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:", + NULL); + + bt_gatt_client_ready_register(data->client, client_ready_cb, data, + NULL); + + bt_att_unref(att); + gatt_db_unref(db); +} + +/* + * ATT: Write Request (0x12) len 3 + * Handle: 0x0003 + * Data: 00 + * + * ATT: Write Response (0x13) len 0 + */ +#define MICS_MUTE_WRITE_VAL_00 \ + IOV_DATA(0x12, 0x03, 0x00, 0x00), \ + IOV_DATA(0x13) + +/* + * ATT: Write Request (0x12) len 3 + * Handle: 0x0003 + * Data: 01 + * + * ATT: Write Response (0x13) len 0 + */ +#define MICS_MUTE_WRITE_VAL_01 \ + IOV_DATA(0x12, 0x03, 0x00, 0x01), \ + IOV_DATA(0x13) +/* + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0003 + * + * ATT: Read Response (0x0b) len 1 + */ +#define MICS_MUTE_READ \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x01) + +/* + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Primary Service (0x2800) + * + * ATT: Read By Group Type Response (0x11) len 7 + * Attribute data length: 6 + * Attribute group list: 1 entry + * Handle range: 0x0001-0x0004 + * UUID: Microphone Control (0x184d) + * + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0005-0xffff + * Attribute group type: Primary Service (0x2800) + * + * ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0005 + * Error: Attribute Not Found (0x0a) + */ +#define DISCOVER_PRIM_SERV_NOTIF \ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \ + IOV_DATA(0x11, 0x06, 0x01, 0x00, 0x04, 0x00, 0x4d, 0x18), \ + IOV_DATA(0x10, 0x05, 0x00, 0xff, 0xff, 0x00, 0x28), \ + IOV_DATA(0x01, 0x10, 0x05, 0x00, 0x0a) + +/* + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0005 + * Attribute type: Characteristic (0x2803) + * + * ATT: Read By Type Response (0x09) len 8 + * Attribute data length: 7 + * Attribute data list: 1 entry + * Handle: 0x0002 + * Value: 1a0300c32b + * + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0005-0x0005 + * Attribute type: Characteristic (0x2803) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0005 + * Error: Attribute Not Found (0x0a) + */ +#define DISC_MICS_CHAR_1 \ + IOV_DATA(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28), \ + IOV_DATA(0x09, 0x07, \ + 0x02, 0x00, 0x1a, 0x03, 0x00, 0xc3, 0x2b), \ + IOV_DATA(0x08, 0x05, 0x00, 0x05, 0x00, 0x03, 0x28), \ + IOV_DATA(0x01, 0x08, 0x05, 0x00, 0x0a) + +/* + * ATT: Find By Type Value Request (0x06) len 8 + * Handle range: 0x0001-0xffff + * Attribute type: Primary Service (0x2800) + * UUID: Microphone Control (0x184d) + * + * ATT: Find By Type Value Response (0x07) len 4 + * Handle range: 0x0001-0x0004 + * + * ATT: Find By Type Value Request (0x06) len 8 + * Handle range: 0x0005-0xffff + * Attribute type: Primary Service (0x2800) + * UUID: Microphone Control (0x184d) + * + * ATT: Error Response (0x01) len 4 + * Find By Type Value Request (0x06) + * Handle: 0x0005 + * Error: Attribute Not Found (0x0a) + */ +#define MICS_FIND_BY_TYPE_VALUE \ + IOV_DATA(0x06, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28, 0x4d, 0x18), \ + IOV_DATA(0x07, 0x01, 0x00, 0x04, 0x00), \ + IOV_DATA(0x06, 0x05, 0x00, 0xff, 0xff, 0x00, 0x28, 0x4d, 0x18), \ + IOV_DATA(0x01, 0x06, 0x05, 0x00, 0x0a) + +/* + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x0005 + * Attribute type: Characteristic (0x2803) + * + * ATT: Read By Type Response (0x09) len 8 + * Attribute data length: 7 + * Attribute data list: 1 entry + * Handle: 0x0002 + * Value: 1a0300c32b + * + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0003-0x0005 + * Attribute type: Characteristic (0x2803) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x0003 + * Error: Attribute Not Found (0x0a) + */ +#define DISC_MICS_CHAR_AFTER_TYPE \ + IOV_DATA(0x08, 0x01, 0x00, 0x05, 0x00, 0x03, 0x28), \ + IOV_DATA(0x09, 0x07, \ + 0x02, 0x00, 0x1a, 0x03, 0x00, 0xc3, 0x2b), \ + IOV_DATA(0x08, 0x03, 0x00, 0x05, 0x00, 0x03, 0x28), \ + IOV_DATA(0x01, 0x08, 0x03, 0x00, 0x0a) + +/* + * ATT: Write Request (0x12) len 4 + * Handle: 0x0004 + * Data: 0000 + * + * ATT: Write Response (0x13) len 0 + * + * ATT: Write Request (0x12) len 4 + * Handle: 0x0004 + * Data: 0100 + * + * ATT: Write Response (0x13) len 0 + */ +#define MICS_WRITE_CCD \ + IOV_DATA(0x12, 0x04, 0x00, 0x00, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x12, 0x04, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13) + +/* + * ATT: Find Information Request (0x04) len 4 + * Handle range: 0x0004-0x0005 + * + * ATT: Find Information Response (0x05) len 5 + * Format: UUID-16 (0x01) + * Handle: 0x0004 + * UUID: Client Characteristic Configuration (0x2902) + * + * ATT: Find Information Request (0x04) len 4 + * Handle range: 0x0005-0x0005 + * + * ATT: Error Response (0x01) len 4 + * Find Information Request (0x04) + * Handle: 0x0005 + * Error: Attribute Not Found (0x0a) + */ +#define MICS_FIND_INFO \ + IOV_DATA(0x04, 0x04, 0x00, 0x05, 0x00), \ + IOV_DATA(0x05, 0x01, 0x04, 0x00, 0x02, 0x29), \ + IOV_DATA(0x04, 0x05, 0x00, 0x05, 0x00), \ + IOV_DATA(0x01, 0x04, 0x05, 0x00, 0x0a) + +/* + * 1.reads the characteristic value for the + * Mute characteristic + * 2.update the Mute characteristic to 0 or 1 + * 3.sends a notification containing the updated value + * of the Mute characteristic + * 4.update the Mute characteristic to 0 or 1 which ever + * different than step 2 + * 5.sends a notification containing the updated value of + * the Mute characteristic + */ +#define MICS_SR_SPN_BV_01_C \ + ATT_EXCHANGE_MTU, \ + DISCOVER_PRIM_SERV_NOTIF, \ + DISC_MICS_CHAR_1, \ + MICS_FIND_BY_TYPE_VALUE, \ + DISC_MICS_CHAR_AFTER_TYPE, \ + MICS_FIND_INFO, \ + MICS_WRITE_CCD, \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x01), \ + MICS_MUTE_WRITE_VAL_00, \ + IOV_DATA(0x1b, 0x03, 0x00, 0x00), \ + MICS_MUTE_WRITE_VAL_01, \ + IOV_DATA(0x1b, 0x03, 0x00, 0x01), \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x01) + +#define MICS_SR_SGGIT_SER_BV_01_C \ + ATT_EXCHANGE_MTU, \ + DISCOVER_PRIM_SERV_NOTIF, \ + MICS_FIND_BY_TYPE_VALUE + +#define MICS_SR_SGGIT_CHA_BV_01_C \ + ATT_EXCHANGE_MTU, \ + DISCOVER_PRIM_SERV_NOTIF, \ + MICS_FIND_BY_TYPE_VALUE, \ + DISC_MICS_CHAR_AFTER_TYPE + +/* + * ATT: Write Request (0x12) len 3 + * Handle: 0x0003 + * Data: 02 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0003 + * Error: Value Not Allowed (0x13) + * + * ATT: Write Request (0x12) len 3 + * Handle: 0x0003 + * Data: 05 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0003 + * Error: Value Not Allowed (0x13) + */ +#define MICS_WRITE_MUTE_CHAR_INVALID \ + IOV_DATA(0x12, 0x03, 0x00, 0x02), \ + IOV_DATA(0x01, 0x12, 0x03, 0x00, 0x13), \ + IOV_DATA(0x12, 0x03, 0x00, 0x05), \ + IOV_DATA(0x01, 0x12, 0x03, 0x00, 0x13) + +#define MICS_SR_SPE_BI_1_C \ + ATT_EXCHANGE_MTU, \ + DISCOVER_PRIM_SERV_NOTIF, \ + MICS_FIND_BY_TYPE_VALUE, \ + MICS_WRITE_MUTE_CHAR_INVALID + +/* + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0003 + * + * ATT: Read Response (0x0b) len 1 + */ +#define MICS_MUTE_READ_INVALID \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x02) + +/* + * ATT: Write Request (0x12) len 3 + * Handle: 0x0003 + * Data: 01 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0003 + * Error: Reserved (0x80) + */ +#define MICS_MUTE_WRITE_1 \ + IOV_DATA(0x12, 0x03, 0x00, 0x01), \ + IOV_DATA(0x01, 0x12, 0x03, 0x00, 0x80) + +/* + * ATT: Write Request (0x12) len 3 + * Handle: 0x0003 + * Data: 00 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0003 + * Error: Reserved (0x80) + */ +#define MICS_MUTE_WRITE_0 \ + IOV_DATA(0x12, 0x03, 0x00, 0x00), \ + IOV_DATA(0x01, 0x12, 0x03, 0x00, 0x80) + +#define MICS_SR_SPE_BI_02_C \ + ATT_EXCHANGE_MTU, \ + DISCOVER_PRIM_SERV_NOTIF, \ + MICS_FIND_BY_TYPE_VALUE, \ + MICS_MUTE_READ_INVALID, \ + MICS_MUTE_WRITE_0, \ + MICS_MUTE_WRITE_1 + +int main(int argc, char *argv[]) +{ + + tester_init(&argc, &argv); + + /* MICS Testcases */ + define_test_mics("MICS/SR/SGGIT/SER/BV-01-C", test_server, NULL, + MICS_SR_SGGIT_SER_BV_01_C); + define_test_mics("MICS/SR/SGGIT/CHA/BV-01-C", test_server, NULL, + MICS_SR_SGGIT_CHA_BV_01_C); + define_test_mics("MICS/SR/SPE/BI-01-C", test_server, NULL, + MICS_SR_SPE_BI_1_C); + + /* MICS/SR/SPE/BI-02-C: + * In function *mics_new(struct gatt_db *db)[src/shared/micp.c] + * by default the mics->mute_stat is set to MICS_MUTED[0x01]. + * As per test specs, Testcase MICS/SR/SPE/BI-02-C, Initial + * condition of mute state should be MICS_DISABLED[0x02]. + * To verify this Unit test case we have to modify the initial + * state of mics->mute_stat to MICS_DISABLED in code + * [in func mics_new()], build it and run bluetoothd. Then run + * this unit test case and this test case will Pass. + */ + /* define_test_mics("MICS/SR/SPE/BI-02-C", test_server, NULL, + * MICS_SR_SPE_BI_02_C); + */ + define_test_mics("MICS/SR/SPN/BV-01-C", test_server, NULL, + MICS_SR_SPN_BV_01_C); + + /* MICP Testcases */ + define_test_micp("MICP/CL/CGGIT/SER/BV-01-C", test_client, NULL, + MICP_CL_CGGIT_SER_BV_01_C); + define_test_micp("MICP/CL/CGGIT/CHA/BV-01-C", test_client, NULL, + MICP_CL_CGGIT_CHA_BV_01_C); + define_test_micp("MICP/CL/SPE/BI-01-C", test_client, NULL, + MICP_CL_SPE_BI_01_C); + + return tester_run(); +} diff -Nru bluez-5.70/unit/test-vcp.c bluez-5.71/unit/test-vcp.c --- bluez-5.70/unit/test-vcp.c 1970-01-01 08:00:00.000000000 +0800 +++ bluez-5.71/unit/test-vcp.c 2023-12-14 05:40:27.000000000 +0800 @@ -0,0 +1,1350 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2023 NXP Semiconductors. All rights reserved. + * + * This file contains only VOCS related Unit Test cases. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include + +#include "lib/bluetooth.h" +#include "lib/uuid.h" +#include "src/shared/util.h" +#include "src/shared/tester.h" +#include "src/shared/queue.h" +#include "src/shared/att.h" +#include "src/shared/gatt-db.h" +#include "src/shared/gatt-client.h" +#include "src/shared/gatt-server.h" +#include "src/shared/vcp.h" + +struct test_data { + struct gatt_db *db; + struct bt_vcp *vcp; + struct bt_gatt_server *server; + struct queue *ccc_states; + size_t iovcnt; + struct iovec *iov; +}; + +struct notify { + uint16_t handle, ccc_handle; + uint8_t *value; + uint16_t len; + bt_gatt_server_conf_func_t conf; + void *user_data; +}; + +struct ccc_state { + uint16_t handle; + uint16_t value; +}; + +#define iov_data(args...) ((const struct iovec[]) { args }) + +#define define_test(name, function, _cfg, args...) \ + do { \ + const struct iovec iov[] = { args }; \ + static struct test_data data; \ + data.iovcnt = ARRAY_SIZE(iov_data(args)); \ + data.iov = util_iov_dup(iov, ARRAY_SIZE(iov_data(args))); \ + tester_add(name, &data, NULL, function, \ + test_teardown); \ + } while (0) + +static void test_complete_cb(const void *user_data) +{ + tester_test_passed(); +} + +static void print_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + if (tester_use_debug()) + tester_debug("%s%s", prefix, str); +} + +static void test_teardown(const void *user_data) +{ + struct test_data *data = (void *)user_data; + + bt_vcp_unref(data->vcp); + bt_gatt_server_unref(data->server); + util_iov_free(data->iov, data->iovcnt); + + gatt_db_unref(data->db); + + queue_destroy(data->ccc_states, free); + + tester_teardown_complete(); +} + +static bool ccc_state_match(const void *a, const void *b) +{ + const struct ccc_state *ccc = a; + uint16_t handle = PTR_TO_UINT(b); + + return ccc->handle == handle; +} + +static struct ccc_state *find_ccc_state(struct test_data *data, + uint16_t handle) +{ + return queue_find(data->ccc_states, ccc_state_match, + UINT_TO_PTR(handle)); +} + +static struct ccc_state *get_ccc_state(struct test_data *data, + uint16_t handle) +{ + struct ccc_state *ccc; + + ccc = find_ccc_state(data, handle); + if (ccc) + return ccc; + + ccc = new0(struct ccc_state, 1); + ccc->handle = handle; + queue_push_tail(data->ccc_states, ccc); + + return ccc; +} + +static void gatt_notify_cb(struct gatt_db_attribute *attrib, + struct gatt_db_attribute *ccc, + const uint8_t *value, size_t len, + struct bt_att *att, void *user_data) +{ + struct test_data *data = user_data; + uint16_t handle = gatt_db_attribute_get_handle(attrib); + + if (!bt_gatt_server_send_notification(data->server, + handle, value, len, false)) + printf("%s: Failed to send notification\n", __func__); +} + +static void gatt_ccc_read_cb(struct gatt_db_attribute *attrib, + unsigned int id, uint16_t offest, + uint8_t opcode, struct bt_att *att, + void *user_data) +{ + struct test_data *data = user_data; + struct ccc_state *ccc; + uint16_t handle; + uint8_t ecode = 0; + uint16_t value = 0; + + handle = gatt_db_attribute_get_handle(attrib); + + ccc = get_ccc_state(data, handle); + if (!ccc) { + ecode = BT_ATT_ERROR_UNLIKELY; + goto done; + } + + value = cpu_to_le16(ccc->value); + +done: + gatt_db_attribute_read_result(attrib, id, ecode, (void *)&value, + sizeof(value)); +} + +static void test_server(const void *user_data) +{ + struct test_data *data = (void *)user_data; + struct bt_att *att; + struct io *io; + + io = tester_setup_io(data->iov, data->iovcnt); + g_assert(io); + + tester_io_set_complete_func(test_complete_cb); + + att = bt_att_new(io_get_fd(io), false); + g_assert(att); + + bt_att_set_debug(att, BT_ATT_DEBUG, print_debug, "bt_att:", NULL); + + data->db = gatt_db_new(); + g_assert(data->db); + + gatt_db_ccc_register(data->db, gatt_ccc_read_cb, NULL, + gatt_notify_cb, data); + + data->vcp = bt_vcp_new(data->db, NULL); + g_assert(data->vcp); + + data->server = bt_gatt_server_new(data->db, att, 64, 0); + g_assert(data->server); + + bt_gatt_server_set_debug(data->server, print_debug, "bt_gatt_server", + NULL); + + data->ccc_states = queue_new(); + + tester_io_send(); + + bt_att_unref(att); +} + + /* ATT: Exchange MTU Request (0x02) len 2 + * Client RX MTU: 64 + * ATT: Exchange MTU Response (0x03) len 2 + * Server RX MTU: 64 + */ +#define VOCS_EXCHANGE_MTU \ + IOV_DATA(0x02, 0x40, 0x00), \ + IOV_DATA(0x03, 0x40, 0x00) + + /* ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Primary Service (0x2800) + * + * ATT: Read By Group Type Response (0x11) len 7 + * Attribute data length: 6 + * Attribute group list: 1 entry + * Handle range: 0x000d-0x0016 + * UUID: Volume Control (0x1844) + * + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0017-0xffff + * Attribute group type: Primary Service (0x2800) + * + * ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x0017 + * Error: Attribute Not Found (0x0a) + */ +#define VOCS_PRIMARY_SERVICE_VCS \ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \ + IOV_DATA(0x11, 0x06, 0x0d, 0x00, 0x16, 0x00, 0x44, 0x18), \ + IOV_DATA(0x10, 0x17, 0x00, 0xff, 0xff, 0x00, 0x28), \ + IOV_DATA(0x01, 0x10, 0x17, 0x00, 0x0a) + + /* ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x0001-0xffff + * Attribute group type: Secondary Service (0x2801) + * + * ATT: Read By Group Type Response (0x11) len 7 + * Attribute data length: 6 + * Attribute group list: 1 entry + * Handle range: 0x0001-0x000c + * UUID: Volume Offset Control (0x1845) + * + * ATT: Read By Group Type Request (0x10) len 6 + * Handle range: 0x000d-0xffff + * Attribute group type: Secondary Service (0x2801) + * + * ATT: Error Response (0x01) len 4 + * Read By Group Type Request (0x10) + * Handle: 0x000d + * Error: Attribute Not Found (0x0a) + */ +#define VOCS_SECONDARY_SERVICE_VOCS \ + IOV_DATA(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28), \ + IOV_DATA(0x11, 0x06, 0x01, 0x00, 0x0c, 0x00, 0x45, 0x18), \ + IOV_DATA(0x10, 0x0d, 0x00, 0xff, 0xff, 0x01, 0x28), \ + IOV_DATA(0x01, 0x10, 0x0d, 0x00, 0x0a) + + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0xffff + * Attribute type: Include (0x2802) + * + * ATT: Read By Type Response (0x09) len 9 + * Attribute data length: 8 + * Attribute data list: 1 entry + * Handle: 0x000e + * Value: 01000c004518 + * + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x000f-0xffff + * Attribute type: Include (0x2802) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x000f + * Error: Attribute Not Found (0x0a) + */ +#define VOCS_INCLUDED_SERVICE_VOCS \ + IOV_DATA(0x08, 0x01, 0x00, 0xff, 0xff, 0x02, 0x28), \ + IOV_DATA(0x09, 0x08, \ + 0x0e, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x45, 0x18), \ + IOV_DATA(0x08, 0x0f, 0x00, 0xff, 0xff, 0x02, 0x28), \ + IOV_DATA(0x01, 0x08, 0x0f, 0x00, 0x0a) + + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0001-0x000c + * Attribute type: Characteristic (0x2803) + * + * ATT: Read By Type Response (0x09) len 29 + * Attribute data length: 7 + * Attribute data list: 4 entries + * Handle: 0x0002 + * Value: 120300802b + * Handle: 0x0005 + * Value: 120600812b + * Handle: 0x0008 + * Value: 080900822b + * Handle: 0x000a + * Value: 120b00832b + * + * ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x000b-0x000c + * Attribute type: Characteristic (0x2803) + * + * ATT: Error Response (0x01) len 4 + * Read By Type Request (0x08) + * Handle: 0x000b + * Error: Attribute Not Found (0x0a) + */ +#define VOCS_DISC_CHAR \ + IOV_DATA(0x08, 0x01, 0x00, 0x0c, 0x00, 0x03, 0x28), \ + IOV_DATA(0x09, 0x07, \ + 0x02, 0x00, 0x12, 0x03, 0x00, 0x80, 0x2b, \ + 0x05, 0x00, 0x12, 0x06, 0x00, 0x81, 0x2b, \ + 0x08, 0x00, 0x08, 0x09, 0x00, 0x82, 0x2b, \ + 0x0a, 0x00, 0x12, 0x0b, 0x00, 0x83, 0x2b), \ + IOV_DATA(0x08, 0x0b, 0x00, 0x0c, 0x00, 0x03, 0x28), \ + IOV_DATA(0x01, 0x08, 0x0b, 0x00, 0x0a) + + /* ATT: Find Information Request (0x04) len 4 + * Handle range: 0x0004-0x0004 + * + * ATT: Find Information Response (0x05) len 5 + * Format: UUID-16 (0x01) + * Handle: 0x0004 + * UUID: Client Characteristic Configuration (0x2902) + * + * ATT: Find Information Request (0x04) len 4 + * Handle range: 0x0007-0x0007 + * + * ATT: Find Information Response (0x05) len 5 + * Format: UUID-16 (0x01) + * Handle: 0x0007 + * UUID: Client Characteristic Configuration (0x2902) + * + * ATT: Find Information Request (0x04) len 4 + * Handle range: 0x000c-0x000c + * + * ATT: Find Information Response (0x05) len 5 + * Format: UUID-16 (0x01) + * Handle: 0x000c + * UUID: Client Characteristic Configuration (0x2902) + */ +#define VOCS_DISC_CHAR_DESC \ + IOV_DATA(0x04, 0x04, 0x00, 0x04, 0x00), \ + IOV_DATA(0x05, 0x01, 0x04, 0x00, 0x02, 0x29), \ + IOV_DATA(0x04, 0x07, 0x00, 0x07, 0x00), \ + IOV_DATA(0x05, 0x01, 0x07, 0x00, 0x02, 0x29), \ + IOV_DATA(0x04, 0x0c, 0x00, 0x0c, 0x00), \ + IOV_DATA(0x05, 0x01, 0x0c, 0x00, 0x02, 0x29) + + /* ATT: Read Request (0x0a) len 2 + * Handle: 0x0004 + * + * ATT: Read Response (0x0b) len 2 + * + * ATT: Read Request (0x0a) len 2 + * Handle: 0x0007 + * + * ATT: Read Response (0x0b) len 2 + * + * ATT: Read Request (0x0a) len 2 + * Handle: 0x000c + * + * ATT: Read Request (0x0a) len 2 + * Handle: 0x000c + */ +#define VOCS_READ_CHAR_DESC \ + IOV_DATA(0x0a, 0x04, 0x00), \ + IOV_DATA(0x0b, 0x00, 0x00), \ + IOV_DATA(0x0a, 0x07, 0x00), \ + IOV_DATA(0x0b, 0x00, 0x00), \ + IOV_DATA(0x0a, 0x0c, 0x00), \ + IOV_DATA(0x0b, 0x00, 0x00) + + /* ATT: Read Request (0x0a) len 2 + * Handle: 0x0003 + * + * ATT: Read Response (0x0b) len 3 + */ +#define VOCS_READ_CHAR_VOL_OFFSET \ + IOV_DATA(0x0a, 0x03, 0x00), \ + IOV_DATA(0x0b, 0x00, 0x00, 0x00) + + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0002-0x0003 + * Attribute type: Offset State (0x2b80) + * + * ATT: Read By Type Response (0x09) len 6 + * Attribute data length: 5 + * Attribute data list: 1 entry + * Handle: 0x0003 + * Value: 000000 + */ +#define VOCS_READ_CHAR_VOL_OFFSET_UUID \ + IOV_DATA(0x08, 0x02, 0x00, 0x03, 0x00, 0x80, 0x2b), \ + IOV_DATA(0x09, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00) + + /* ATT: Read Request (0x0a) len 2 + * Handle: 0x0006 + * + * ATT: Read Response (0x0b) len 4 + */ +#define VOCS_READ_CHAR_AUD_LOC \ + IOV_DATA(0x0a, 0x06, 0x00), \ + IOV_DATA(0x0b, 0x02, 0x00, 0x00, 0x00) + + /* ATT: Read By Type Request (0x08) len 6 + * Handle range: 0x0005-0x0006 + * Attribute type: Audio Location (0x2b81) + * + * ATT: Read By Type Response (0x09) len 7 + * Attribute data length: 6 + * Attribute data list: 1 entry + * Handle: 0x0006 + * Value: 02000000 + */ +#define VOCS_READ_CHAR_AUD_LOC_UUID \ + IOV_DATA(0x08, 0x05, 0x00, 0x06, 0x00, 0x81, 0x2b), \ + IOV_DATA(0x09, 0x06, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00) + + /* ATT: Write Request (0x12) len 6 + * Handle: 0x0009 + * Data: 01280a00 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Reserved (0x80) + */ +#define VOCS_CP_INVALID_CHNG_COUNTER \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x28, 0x0a, 0x00),\ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x80) + + /* ATT: Write Request (0x12) len 6 + * Handle: 0x0009 + * Data: 00007800 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Reserved (0x81) + */ +#define VOCS_CP_INVALID_OPCODE \ + IOV_DATA(0x12, 0x09, 0x00, 0x00, 0x00, 0x78, 0x00),\ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x81) + + /* ATT: Write Request (0x12) len 6 + * Handle: 0x0009 + * Data: 01000e01 + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Reserved (0x82) + * + * ATT: Write Request (0x12) len 6 + * Handle: 0x0009 + * Data: 0100f2fe + * + * ATT: Error Response (0x01) len 4 + * Write Request (0x12) + * Handle: 0x0009 + * Error: Reserved (0x82) + */ +#define VOCS_CP_OUT_OF_RANGE_VALUE \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x00, 0x0e, 0x01), \ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x82), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x00, 0xf2, 0xfe),\ + IOV_DATA(0x01, 0x12, 0x09, 0x00, 0x82) + + /* ATT: Write Request (0x12) len 4 + * Handle: 0x0004 + * Data: 0100 + * + * ATT: Write Response (0x13) len 0 + */ +#define VOCS_ENNABLE_VOL_OFFSET_CCD \ + IOV_DATA(0x12, 0x04, 0x00, 0x01, 0x00), \ + IOV_DATA(0x13) + +#define VOCS_SR_SGGIT_CHA_TST_CMDS \ + VOCS_EXCHANGE_MTU, \ + VOCS_PRIMARY_SERVICE_VCS, \ + VOCS_SECONDARY_SERVICE_VOCS, \ + VOCS_INCLUDED_SERVICE_VOCS, \ + VOCS_DISC_CHAR, \ + VOCS_DISC_CHAR_DESC, \ + VOCS_READ_CHAR_DESC + +#define VOCS_SR_SGGIT_SER_BV_01_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS + +#define VOCS_SR_SGGIT_CHA_BV_01_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_READ_CHAR_VOL_OFFSET, \ + VOCS_READ_CHAR_VOL_OFFSET_UUID + +#define VOCS_SR_SGGIT_CHA_BV_02_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_READ_CHAR_AUD_LOC, \ + VOCS_READ_CHAR_AUD_LOC_UUID + +#define VOCS_SR_SGGIT_CHA_BV_03_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS + +#define VOCS_SR_SGGIT_CHA_BV_04_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS + +#define VOCS_SR_SGGIT_CP_BI_01_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_CP_INVALID_CHNG_COUNTER + +#define VOCS_SR_SGGIT_CP_BI_02_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_CP_INVALID_OPCODE + +#define VOCS_SR_SGGIT_CP_BI_03_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_CP_OUT_OF_RANGE_VALUE + +#define VOCS_SR_SPE_BI_01_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_READ_CHAR_AUD_LOC + /* + * VOCS/SR/CP/BV-01-C [Set Volume Offset] + * Do Initial Condition Proedures + * 1. The Lower Tester executes the GATT Read Characteristic + * Value sub-procedure for the Volume Offset State characteristic. + * Repeat steps 2-4 for (255 - Change_Counter value) + 1 times. + * 2. The Lower Tester executes the GATT Write Characteristic Value + * sub-procedure for the Volume + * Offset Control Point characteristic with the Set Volume Offset + * Opcode, with the Volume Offset parameters set to a random value + * different from the last one, and the Change_Counter parameter. + * 3. The Lower Tester receives a Write Response indicating that the IUT + * has accepted the Opcode. + * 4. The Lower Tester receives a GATT Characteristic Value Notification + * for the Volume Offset State characteristic. + */ +#define VOCS_SR_CP_BV_01_C \ + VOCS_SR_SGGIT_CHA_TST_CMDS, \ + VOCS_ENNABLE_VOL_OFFSET_CCD, \ + VOCS_READ_CHAR_VOL_OFFSET, \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x00, 0xde, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xde, 0x00, 0x01), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x01, 0xda, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xda, 0xff, 0x02), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x02, 0x1a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1a, 0x00, 0x03), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x03, 0x49, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x49, 0xff, 0x04), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x04, 0x05, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x05, 0xff, 0x05), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x05, 0xf1, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xf1, 0xff, 0x06), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x06, 0xca, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xca, 0xff, 0x07), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x07, 0x5c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5c, 0x00, 0x08), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x08, 0xaf, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xaf, 0x00, 0x09), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x09, 0x5f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5f, 0x00, 0x0a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x0a, 0x69, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x69, 0xff, 0x0b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x0b, 0x3d, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3d, 0xff, 0x0c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x0c, 0xb6, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xb6, 0xff, 0x0d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x0d, 0xa4, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa4, 0x00, 0x0e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x0e, 0x14, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x14, 0xff, 0x0f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x0f, 0x2a, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x2a, 0xff, 0x10), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x10, 0x51, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x51, 0x00, 0x11), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x011, 0xc4, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xc4, 0xff, 0x12), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x12, 0xe8, 00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xe8, 0x00, 0x13), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x13, 0xca, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xca, 0xff, 0x14), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x14, 0xe6, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xe6, 0xff, 0x15), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x15, 0x62, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x62, 0x00, 0x16), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x16, 0x22, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x22, 0x00, 0x17), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x17, 0xa1, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa1, 0xff, 0x18), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x18, 0xaa, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xaa, 0x00, 0x19), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x19, 0x65, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x65, 0x00, 0x1a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x1a, 0x11, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x11, 0xff, 0x1b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x1b, 0x69, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x69, 0xff, 0x1c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x1c, 0xee, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xee, 0x00, 0x1d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x1d, 0xaa, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xaa, 0xff, 0x1e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x1e, 0x1f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1f, 0xff, 0x1f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x1f, 0xbe, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xbe, 0x00, 0x20), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x20, 0x93, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x93, 0xff, 0x21), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x21, 0x11, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x11, 0xff, 0x22), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x22, 0x83, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x83, 0xff, 0x23), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x23, 0xf8, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xf8, 0x00, 0x24), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x24, 0x90, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x90, 0xff, 0x25), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x25, 0x0c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0c, 0x00, 0x26), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x26, 0xc8, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xc8, 0x00, 0x27), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x27, 0x59, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x59, 0xff, 0x28), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x28, 0x80, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x80, 0xff, 0x29), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x29, 0x0d, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0d, 0xff, 0x2a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x2a, 0x0c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0c, 0x00, 0x2b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x2b, 0x0a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0a, 0x00, 0x2c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x2c, 0x12, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x12, 0x00, 0x2d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x2d, 0x0b, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0b, 0xff, 0x2e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x2e, 0x83, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x83, 0xff, 0x2f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x2f, 0x91, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x91, 0xff, 0x30), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x30, 0x71, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x71, 0xff, 0x31), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x31, 0x72, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x72, 0xff, 0x32), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x32, 0x75, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x75, 0xff, 0x33), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x33, 0x78, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x78, 0xff, 0x34), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x34, 0x61, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x61, 0xff, 0x35), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x35, 0x63, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x63, 0xff, 0x36), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x36, 0x38, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x38, 0xff, 0x37), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x37, 0x21, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x21, 0xff, 0x38), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x38, 0xa4, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa4, 0x00, 0x39), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x39, 0xb4, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xb4, 0x00, 0x3a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x3a, 0xb5, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xb5, 0xff, 0x3b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x3b, 0xac, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xac, 0x00, 0x3c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x3c, 0xab, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xab, 0x00, 0x3d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x3d, 0xad, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xad, 0x00, 0x3e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x3e, 0x83, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x83, 0xff, 0x3f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x3f, 0x84, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x84, 0xff, 0x40), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x40, 0x85, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x85, 0xff, 0x41), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x41, 0x86, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x86, 0xff, 0x42), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x42, 0x87, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x87, 0xff, 0x43), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x43, 0x87, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x87, 0xff, 0x44), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x44, 0x05, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x05, 0x000, 0x45), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x45, 0xce, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xce, 0x00, 0x46), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x46, 0x96, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x96, 0x00, 0x47), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x47, 0x07, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x07, 0x00, 0x48), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x48, 0x08, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x08, 0x00, 0x49), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x49, 0x09, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x09, 0xff, 0x4a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x4a, 0x0a, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0a, 0xff, 0x4b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x4b, 0x11, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x11, 0xff, 0x4c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x4c, 0x22, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x22, 0xff, 0x4d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x4d, 0x33, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x33, 0xff, 0x4e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x4e, 0x09, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x09, 0xff, 0x4f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x4f, 0x19, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x19, 0xff, 0x50), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x50, 0x1a, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1a, 0xff, 0x51), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x51, 0x1b, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1b, 0xff, 0x52), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x52, 0xa1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa1, 0x00, 0x53), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x53, 0xa2, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa2, 0x00, 0x54), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x54, 0xb2, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xb2, 0x00, 0x55), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x55, 0xb3, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xb3, 0x00, 0x56), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x56, 0x68, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x68, 0x00, 0x57), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x57, 0x69, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x69, 0x00, 0x58), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x58, 0x6a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6a, 0x00, 0x59), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x59, 0x7a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7a, 0x00, 0x5a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x5a, 0x7b, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7b, 0x00, 0x5b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x5b, 0x8c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x8c, 0x00, 0x5c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x5c, 0x9c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9c, 0x00, 0x5d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x5d, 0x9b, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9b, 0x00, 0x5e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x5e, 0x9c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9c, 0x00, 0x5f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x5f, 0x9d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9d, 0x00, 0x60), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x60, 0x9e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9e, 0x00, 0x61), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x61, 0x21, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x21, 0x00, 0x62), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x62, 0x23, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x23, 0x00, 0x63), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x63, 0x24, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x24, 0x00, 0x64), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x64, 0x34, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x34, 0x00, 0x65), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x65, 0x44, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x44, 0x00, 0x66), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x66, 0x45, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x45, 0x00, 0x67), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x67, 0x9d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9d, 0x00, 0x68), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x68, 0x9d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9d, 0x00, 0x69), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x69, 0x9d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9d, 0x00, 0x6a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x6a, 0x49, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x49, 0x00, 0x6b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x6b, 0x39, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x39, 0x00, 0x6c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x6c, 0x9d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9d, 0x00, 0x6d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x6d, 0x9e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9e, 0x00, 0x6e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x6e, 0x9f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9f, 0x00, 0x6f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x6f, 0x91, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x91, 0x00, 0x70), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x70, 0x18, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x18, 0x00, 0x71), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x71, 0x34, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x34, 0xff, 0x72), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x72, 0x44, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x44, 0xff, 0x73), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x73, 0x05, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x05, 0xff, 0x74), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x74, 0x06, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x06, 0xff, 0x75), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x75, 0x38, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x38, 0x00, 0x76), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x76, 0x48, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x48, 0x00, 0x77), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x77, 0x58, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x58, 0x00, 0x78), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x78, 0x88, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x88, 0x00, 0x79), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x79, 0x98, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x98, 0x00, 0x7a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x7a, 0x91, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x91, 0x00, 0x7b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x7b, 0x95, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x95, 0x00, 0x7c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x7c, 0x89, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x89, 0x00, 0x7d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x7d, 0x82, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x82, 0x00, 0x7e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x7e, 0x88, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x88, 0x00, 0x7f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x7f, 0x66, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x66, 0x00, 0x80), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x80, 0x55, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x55, 0x00, 0x81), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x81, 0x44, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x44, 0x00, 0x82), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x82, 0x33, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x33, 0x00, 0x83), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x83, 0x22, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x22, 0x00, 0x84), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x84, 0x11, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x11, 0x00, 0x85), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x85, 0x01, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x01, 0x00, 0x86), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x86, 0x3a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3a, 0x00, 0x87), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x87, 0x3b, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3b, 0x00, 0x88), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x88, 0x3c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3c, 0x00, 0x89), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x89, 0x4c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x4c, 0x00, 0x8a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x8a, 0x5c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5c, 0x00, 0x8b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x8b, 0x6c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6c, 0x00, 0x8c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x8c, 0xab, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xab, 0xff, 0x8d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x8d, 0xac, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xac, 0xff, 0x8e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x8e, 0xbc, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xbc, 0x00, 0x8f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x8f, 0xbb, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xbb, 0x00, 0x90), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x90, 0x11, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x11, 0x00, 0x91), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x91, 0x21, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x21, 0x00, 0x92), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x92, 0x31, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x31, 0x00, 0x93), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x93, 0x21, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x21, 0x00, 0x94), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x94, 0x31, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x31, 0x00, 0x95), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x95, 0x41, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x41, 0x00, 0x96), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x96, 0x51, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x51, 0x00, 0x97), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x97, 0x61, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x61, 0x00, 0x98), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x98, 0x81, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x81, 0x00, 0x99), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x99, 0x55, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x55, 0x00, 0x9a), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x9a, 0x59, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x59, 0x00, 0x9b), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x9b, 0x56, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x56, 0x00, 0x9c), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x9c, 0x57, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x57, 0x00, 0x9d), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x9d, 0x58, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x58, 0x00, 0x9e), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x9e, 0x59, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x59, 0x00, 0x9f), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0x9f, 0x60, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x60, 0x00, 0xa0), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa0, 0x0b, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0b, 0xff, 0xa1), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa1, 0x0c, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0c, 0xff, 0xa2), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa2, 0x0c, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0c, 0xff, 0xa3), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa3, 0x0d, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0d, 0xff, 0xa4), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa4, 0x53, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x53, 0xff, 0xa5), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa5, 0x54, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x54, 0xff, 0xa6), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa6, 0x75, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x75, 0xff, 0xa7), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa7, 0x76, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x76, 0xff, 0xa8), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa8, 0x77, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x77, 0xff, 0xa9), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xa9, 0x78, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x78, 0xff, 0xaa), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xaa, 0x76, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x76, 0xff, 0xab), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xab, 0xa1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa1, 0x00, 0xac), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xac, 0xc1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xc1, 0x00, 0xad), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xad, 0xd1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xd1, 0x00, 0xae), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xae, 0xe1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xe1, 0x00, 0xaf), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xaf, 0xf1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xf1, 0x00, 0xb0), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb0, 0xae, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xae, 0x00, 0xb1), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb1, 0xbe, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xbe, 0x00, 0xb2), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb2, 0xdd, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xdd, 0x00, 0xb3), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb3, 0xee, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xee, 0x00, 0xb4), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb4, 0x1d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1d, 0x00, 0xb5), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb5, 0x3a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3a, 0x00, 0xb6), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb6, 0x4a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x4a, 0x00, 0xb7), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb7, 0x5a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5a, 0x00, 0xb8), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb8, 0x7e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7e, 0x00, 0xb9), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xb9, 0x3f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3f, 0x00, 0xba), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xba, 0x3f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3f, 0x00, 0xbb), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xbb, 0xa1, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa1, 0x00, 0xbc), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xbc, 0xa2, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa2, 0x00, 0xbd), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xbd, 0xa3, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa3, 0x00, 0xbe), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xbe, 0xa4, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa4, 0x00, 0xbf), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xbf, 0xa5, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa5, 0x00, 0xc0), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc0, 0xa6, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xa6, 0x00, 0xc1), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc1, 0x1f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1f, 0x00, 0xc2), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc2, 0x2f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x2f, 0x00, 0xc3), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc3, 0x3f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3f, 0x00, 0xc4), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc4, 0x4f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x4f, 0x00, 0xc5), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc5, 0x5f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5f, 0x00, 0xc6), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc6, 0x6f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6f, 0x00, 0xc7), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc7, 0x7f, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7f, 0x00, 0xc8), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc8, 0x1d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1d, 0x00, 0xc9), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xc9, 0xaa, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xaa, 0x00, 0xca), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xca, 0xbb, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xbb, 0x00, 0xcb), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xcb, 0xcd, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xcd, 0x00, 0xcc), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xcc, 0xce, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xce, 0x00, 0xcd), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xcd, 0xde, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xde, 0x00, 0xce), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xce, 0xdf, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xdf, 0x00, 0xcf), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xcf, 0xdb, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xdb, 0x00, 0xd0), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd0, 0x6e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6e, 0x00, 0xd1), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd1, 0x5e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5e, 0x00, 0xd2), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd2, 0x8e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x8e, 0x00, 0xd3), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd3, 0x9e, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x9e, 0x00, 0xd4), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd4, 0xae, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xae, 0x00, 0xd5), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd5, 0xbe, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xbe, 0x00, 0xd6), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd6, 0xee, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xee, 0x00, 0xd7), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd7, 0x1c, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1c, 0x00, 0xd8), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd8, 0x33, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x33, 0x00, 0xd9), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xd9, 0x88, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x88, 0x00, 0xda), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xda, 0x0d, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0d, 0x00, 0xdb), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xdb, 0x88, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x88, 0x00, 0xdc), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xdc, 0x99, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x99, 0x00, 0xdd), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xdd, 0x66, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x66, 0x00, 0xde), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xde, 0x49, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x49, 0x00, 0xdf), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xdf, 0x86, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x86, 0x00, 0xe0), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe0, 0x3a, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3a, 0x00, 0xe1), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe1, 0xd0, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xd0, 0x00, 0xe2), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe2, 0xd2, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xd2, 0x00, 0xe3), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe3, 0xd3, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xd3, 0x00, 0xe4), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe4, 0xd4, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xd4, 0x00, 0xe5), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe5, 0xdf, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xdf, 0x00, 0xe6), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe6, 0xef, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xef, 0x00, 0xe7), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe7, 0xed, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xed, 0x00, 0xe8), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe8, 0xcc, 0x00), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xcc, 0x00, 0xe9), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xe9, 0x1f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x1f, 0xff, 0xea), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xea, 0x2f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x2f, 0xff, 0xeb), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xeb, 0x3f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x3f, 0xff, 0xec), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xec, 0x4f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x4f, 0xff, 0xed), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xed, 0x5f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x5f, 0xff, 0xee), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xee, 0x6f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6f, 0xff, 0xef), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xef, 0x7f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7f, 0xff, 0xf0), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf0, 0xc9, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xc9, 0xff, 0xf1), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf1, 0xb9, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xb9, 0xff, 0xf2), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf2, 0xd9, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xd9, 0xff, 0xf3), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf3, 0xe1, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0xe1, 0xff, 0xf4), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf4, 0x8f, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x8f, 0xff, 0xf5), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf5, 0x7a, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7a, 0xff, 0xf6), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf6, 0x7b, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7b, 0xff, 0xf7), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf7, 0x7c, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7c, 0xff, 0xf8), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf8, 0x7d, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7d, 0xff, 0xf9), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xf9, 0x7e, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7e, 0xff, 0xfa), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xfa, 0x6a, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6a, 0xff, 0xfb), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xfb, 0x6b, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x6b, 0xff, 0xfc), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xfc, 0x7e, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x7e, 0xff, 0xfd), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xfd, 0x0a, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0a, 0xff, 0xfe), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xfe, 0x0b, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0b, 0xff, 0xff), \ + IOV_DATA(0x12, 0x09, 0x00, 0x01, 0xff, 0x0c, 0xff), \ + IOV_DATA(0x13), \ + IOV_DATA(0x1b, 0x03, 0x00, 0x0c, 0xff, 0x00) + +int main(int argc, char *argv[]) +{ + tester_init(&argc, &argv); + + /* VOCS Unit Testcases */ + define_test("VOCS/SR/SGGIT/SER/BV-01-C", test_server, NULL, + VOCS_SR_SGGIT_SER_BV_01_C); + + define_test("VOCS/SR/SGGIT/CHA/BV-01-C", test_server, NULL, + VOCS_SR_SGGIT_CHA_BV_01_C); + define_test("VOCS/SR/SGGIT/CHA/BV-02-C", test_server, NULL, + VOCS_SR_SGGIT_CHA_BV_02_C); + define_test("VOCS/SR/SGGIT/CHA/BV-03-C", test_server, NULL, + VOCS_SR_SGGIT_CHA_BV_03_C); + define_test("VOCS/SR/SGGIT/CHA/BV-04-C", test_server, NULL, + VOCS_SR_SGGIT_CHA_BV_04_C); + + define_test("VOCS/SR/SGGIT/CP/BI-01-C", test_server, NULL, + VOCS_SR_SGGIT_CP_BI_01_C); + define_test("VOCS/SR/SGGIT/CP/BI-02-C", test_server, NULL, + VOCS_SR_SGGIT_CP_BI_02_C); + define_test("VOCS/SR/SGGIT/CP/BI-03-C", test_server, NULL, + VOCS_SR_SGGIT_CP_BI_03_C); + + define_test("VOCS/SR/SPE/BI-01-C", test_server, NULL, + VOCS_SR_SPE_BI_01_C); + + define_test("VOCS/SR/CP/BV-01-C", test_server, NULL, + VOCS_SR_CP_BV_01_C); + + return tester_run(); +} +