SCO(7)

NAME
sco - SCO transport

SYNOPSIS

            #include <sys/socket.h>
            #include <bluetooth/bluetooth.h>
            #include <bluetooth/sco.h>

            sco_socket = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);

DESCRIPTION

The SCO logical transport, is a symmetric, point-to-point transport between the Central and a specific Peripheral. The SCO logical transport reserves slots and can therefore be considered as a circuit-switched connection between the Central and the Peripheral.

In addition to the reserved slots, when eSCO is supported, a retransmission window follows immediately after. Together, the reserved slots and the retransmission window form the complete eSCO window.

SOCKET ADDRESS

            struct sockaddr_sco {
                sa_family_t     sco_family;
                bdaddr_t        sco_bdaddr;
            };

Example:

            struct sockaddr_sco addr;

            memset(&addr, 0, sizeof(addr));
            addr.sco_family = AF_BLUETOOTH;
            bacpy(&addr.sco_bdaddr, bdaddr);

SOCKET OPTIONS

The socket options listed below can be set by using setsockopt(2) and read with getsockopt(2) with the socket level set to SOL_BLUETOOTH.

  BT_SECURITY (since Linux 2.6.30)

Channel security level, possible values:
Value | Security Level | Link Key Type | Encryption
BT_SECURITY_SDP | 0 (SDP Only) | None | Not required
BT_SECURITY_LOW | 1 (Low) | Unauthenticated | Not required
BT_SECURITY_MEDIUM | 2 (Medium - default) | Unauthenticated | Desired
BT_SECURITY_HIGH | 3 (High) | Authenticated | Required
BT_SECURITY_FIPS (since Linux 3.15) | 4 (Secure Only) | Authenticated (P-256 based Secure Simple Pairing and Secure Authentication) | Required

Example:

            int level = BT_SECURITY_HIGH;
            int err = setsockopt(sco_socket, SOL_BLUETOOTH, BT_SECURITY, &level,
                                 sizeof(level));
            if (err == -1) {
                perror("setsockopt");
                return 1;
            }

  BT_DEFER_SETUP (since Linux 2.6.30)

Channel defer connection setup, this control if the connection procedure needs to be authorized by userspace before responding which allows authorization at profile level, possible values:
Value | Description | Authorization
0 | Disable (default) | Not required
1 | Enable | Required

Example:

            int defer_setup = 1;
            int err = setsockopt(sco_socket, SOL_BLUETOOTH, BT_DEFER_SETUP,
                                 &defer_setup, sizeof(defer_setup));
            if (err == -1) {
                perror("setsockopt");
                return err;
            }

            err = listen(sco_socket, 5);
            if (err) {
                perror("listen");
                return err;
            }

            struct sockaddr_sco remote_addr = {0};
            socklen_t addr_len = sizeof(remote_addr);
            int new_socket = accept(sco_socket, (struct sockaddr*)&remote_addr,
                                    &addr_len);
            if (new_socket < 0) {
                perror("accept");
                return new_socket;
            }

            /* To complete the connection setup of new_socket read 1 byte */
            char c;
            struct pollfd pfd;

            memset(&pfd, 0, sizeof(pfd));
            pfd.fd = new_socket;
            pfd.events = POLLOUT;

            err = poll(&pfd, 1, 0);
            if (err) {
                perror("poll");
                return err;
            }

            if (!(pfd.revents & POLLOUT)) {
                err = read(sk, &c, 1);
                if (err < 0) {
                    perror("read");
                    return err;
                }
            }

  BT_VOICE (since Linux 3.11)

Transport voice settings, possible values:

            struct bt_voice {
                uint16_t setting;
            };
Define | Value | Description
BT_VOICE_TRANSPARENT | 0x0003 | Transparent output
BT_VOICE_CVSD_16BIT | 0x0060 | C-VSD output PCM 16-bit input
BT_VOICE_TRANSPARENT_16BIT | 0x0063 | Transparent output PCM 16-bit input

Example:

            struct bt_voice voice;

            memset(&voice, 0, sizeof(voice));
            voice.setting = BT_VOICE_TRANSPARENT;
            int err = setsockopt(sco_socket, SOL_BLUETOOTH, BT_VOICE, &voice,
                                 sizeof(voice));
            if (err == -1) {
                perror("setsockopt");
                return 1;
            }

  BT_PHY (since Linux 5.10)

Transport supported PHY(s), possible values:
Define | Value | Description
BT_PHY_BR_1M_1SLOT | BIT 0 | BR 1Mbps 1SLOT
BT_PHY_BR_1M_3SLOT | BIT 1 | BR 1Mbps 3SLOT
BT_PHY_BR_2M_1SLOT | BIT 3 | EDR 2Mbps 1SLOT
BT_PHY_BR_2M_3SLOT | BIT 4 | EDR 2Mbps 3SLOT
BT_PHY_BR_3M_1SLOT | BIT 6 | EDR 3Mbps 1SLOT
BT_PHY_BR_3M_3SLOT | BIT 7 | EDR 3Mbps 3SLOT

  BT_CODEC (since Linux 5.14)

Transport codec offload, possible values:

            struct bt_codec {
                uint8_t id;
                uint16_t cid;
                uint16_t vid;
                uint8_t data_path_id;
                uint8_t num_caps;
                struct codec_caps {
                    uint8_t len;
                    uint8_t data[];
                } caps[];
            } __attribute__((packed));

            struct bt_codecs {
                uint8_t num_codecs;
                struct bt_codec codecs[];
            } __attribute__((packed));

Example:

            char buffer[sizeof(struct bt_codecs) + sizeof(struct bt_codec)];
            struct bt_codec *codecs = (void *)buffer;

            memset(codecs, 0, sizeof(codecs));
            codec->num_codecs = 1;
            codecs->codecs[0].id = 0x05;
            codecs->codecs[0].data_path_id = 1;

            int err = setsockopt(sco_socket, SOL_BLUETOOTH, BT_CODEC, codecs,
                                 sizeof(buffer));
            if (err == -1) {
                perror("setsockopt");
                return 1;
            }

RESOURCES

 <http://www.bluez.org>

REPORTING BUGS

 <linux-bluetooth@vger.kernel.org>

SEE ALSO

socket(7), scotest(1)

COPYRIGHT
Free use of this software is granted under the terms of the GNU Lesser General Public Licenses (LGPL).