mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-26 21:54:33 +08:00
isotest: Add support for creating/synchronizing to multiple BISes
This adds an additional command line option for the Broadcast exercise, so that the user can indicate the number of BISes to create as part of a BIG (Broadcast Source), or the number of BISes to synchronize to (Broadcast Sink). For the Broadcast Source exercise, issue the following command, in order to create a BIG with handle 0x01, associated with the advertising handle 0x01, with 2 BISes: tools/isotest -i hci0 -s 00:00:00:00:00:00 -N 2 -G 1 -T 1 The isotest and btmon logs will look something like this: isotest[7178]: mgmt socket: fd 3 isotest[7178]: mgmt_set_le: err 0 isotest[7178]: mgmt_set_experimental: err 0 isotest[7179]: Exit isotest[7178]: Connecting 00:00:00:00:00:00 ... isotest[7178]: Connected [00:00:00:00:00:00] isotest[7178]: QoS [BIG 0x01 BIS 0x01 Packing 0x00 Framing 0x00 Encryption 0x00] isotest[7178]: Input QoS [Interval 10000 us Latency 10 ms SDU 0 PHY 0x00 RTN 2] isotest[7178]: Output QoS [Interval 10000 us Latency 10 ms SDU 40 PHY 0x02 RTN 2] isotest[7178]: Connecting 00:00:00:00:00:00 ... isotest[7178]: Connected [00:00:00:00:00:00] isotest[7178]: QoS [BIG 0x01 BIS 0x01 Packing 0x00 Framing 0x00 Encryption 0x00] isotest[7178]: Input QoS [Interval 10000 us Latency 10 ms SDU 0 PHY 0x00 RTN 2] isotest[7178]: Output QoS [Interval 10000 us Latency 10 ms SDU 40 PHY 0x02 RTN 2] isotest[7183]: Sending ... isotest[7183]: Number of packets: 1 isotest[7183]: Socket jitter buffer: 80 buffer isotest[7183]: [seq 0] 40 bytes buffered 92 (3712 bytes) isotest[7184]: Sending ... isotest[7184]: Number of packets: 1 isotest[7184]: Socket jitter buffer: 80 buffer isotest[7184]: [seq 0] 40 bytes buffered 92 (3712 bytes) isotest[7178]: Exit < HCI Command: LE Create Broadcast Isochronous Group (0x08|0x0068) plen 31 Handle: 0x01 Advertising Handle: 0x01 Number of BIS: 2 SDU Interval: 10000 us (0x002710) Maximum SDU size: 40 Maximum Latency: 10 ms (0x000a) RTN: 0x02 PHY: LE 2M (0x02) Packing: Sequential (0x00) Framing: Unframed (0x00) Encryption: 0x00 Broadcast Code: 00000000000000000000000000000000 > HCI Event: Command Status (0x0f) plen 4 LE Create Broadcast Isochronous Group (0x08|0x0068) ncmd 1 Status: Success (0x00) > HCI Event: LE Meta Event (0x3e) plen 23 LE Broadcast Isochronous Group Complete (0x1b) Status: Success (0x00) Handle: 0x01 BIG Synchronization Delay: 1974 us (0x0007b6) Transport Latency: 1974 us (0x0007b6) PHY: LE 2M (0x02) NSE: 3 BN: 1 PTO: 1 IRC: 3 Maximum PDU: 40 ISO Interval: 10.00 msec (0x0008) Connection Handle #0: 10 Connection Handle #1: 11 < HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13 Handle: 10 Data Path Direction: Input (Host to Controller) (0x00) Data Path: HCI (0x00) Coding Format: Transparent (0x03) Company Codec ID: Ericsson Technology Licensing (0) Vendor Codec ID: 0 Controller Delay: 0 us (0x000000) Codec Configuration Length: 0 Codec Configuration: > HCI Event: Command Complete (0x0e) plen 6 LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1 Status: Success (0x00) Handle: 10 < HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13 Handle: 11 Data Path Direction: Input (Host to Controller) (0x00) Data Path: HCI (0x00) Coding Format: Transparent (0x03) Company Codec ID: Ericsson Technology Licensing (0) Vendor Codec ID: 0 Controller Delay: 0 us (0x000000) Codec Configuration Length: 0 Codec Configuration: > HCI Event: Command Complete (0x0e) plen 6 LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1 Status: Success (0x00) Handle: 11 < ISO Data TX: Handle 10 flags 0x02 dlen 44 < ISO Data TX: Handle 11 flags 0x02 dlen 44 > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 10 Count: 1 > HCI Event: Number of Completed Packets (0x13) plen 5 Num handles: 1 Handle: 11 Count: 1 For the Broadcast Sink exercise, issue the following command, in order to synchronize to the BISes created by the source: tools/isotest -i hci1 -r 36:13:00:E1:1B:F0 -V le_random -N 2 -G 1 The flow is shown by the isotest log and the filtered btmon snippet below: isotest[4033]: mgmt socket: fd 3 isotest[4034]: Exit isotest[4033]: mgmt_set_le: err 0 isotest[4033]: mgmt_set_experimental: err 0 isotest[4033]: Waiting for connection 36:13:00:E1:1B:F0... isotest[4036]: Connected [36:13:00:E1:1B:F0] isotest[4036]: QoS [BIG 0x01 BIS 0x00 Packing 0x00 Framing 0x00 Encryption 0x00] isotest[4036]: Input QoS [Interval 1974 us Latency 10 ms SDU 40 PHY 0x00 RTN 0] isotest[4036]: Output QoS [Interval 0 us Latency 0 ms SDU 0 PHY 0x00 RTN 0] isotest[4036]: Receiving ... isotest[4037]: Connected [36:13:00:E1:1B:F0] isotest[4037]: QoS [BIG 0x01 BIS 0x00 Packing 0x00 Framing 0x00 Encryption 0x00] isotest[4037]: Input QoS [Interval 1974 us Latency 10 ms SDU 40 PHY 0x00 RTN 0] isotest[4037]: Output QoS [Interval 0 us Latency 0 ms SDU 0 PHY 0x00 RTN 0] isotest[4037]: Receiving ... isotest[4037]: [seq 0] 280 bytes in 6.48 sec speed 0.34 kb/s isotest[4036]: [seq 0] 280 bytes in 6.54 sec speed 0.33 kb/s isotest[4037]: [seq 1] 280 bytes in 7.01 sec speed 0.31 kb/s isotest[4036]: [seq 1] 280 bytes in 7.02 sec speed 0.31 kb/s isotest[4037]: [seq 2] 280 bytes in 7.06 sec speed 0.31 kb/s isotest[4036]: [seq 2] 280 bytes in 7.04 sec speed 0.31 kb/s < HCI Command: LE Periodic Advertising Create Sync (0x08|0x0044) plen 14 Options: 0x0000 Use advertising SID, Advertiser Address Type and address Reporting initially enabled SID: 0x00 Adv address type: Random (0x01) Adv address: 36:13:00:E1:1B:F0 (Non-Resolvable) Skip: 0x0000 Sync timeout: 163840 msec (0x4000) Sync CTE type: 0x0000 > HCI Event: Command Status (0x0f) plen 4 LE Periodic Advertising Create Sync (0x08|0x0044) ncmd 1 Status: Success (0x00) < HCI Command: LE Set Extended Scan Parameters (0x08|0x0041) plen 13 Own address type: Public (0x00) Filter policy: Ignore not in accept list (0x01) PHYs: 0x05 Entry 0: LE 1M Type: Passive (0x00) Interval: 60.000 msec (0x0060) Window: 30.000 msec (0x0030) Entry 1: LE Coded Type: Passive (0x00) Interval: 60.000 msec (0x0060) Window: 30.000 msec (0x0030) > HCI Event: Command Complete (0x0e) plen 4 LE Set Extended Scan Parameters (0x08|0x0041) ncmd 1 Status: Success (0x00) < HCI Command: LE Set Extended Scan Enable (0x08|0x0042) plen 6 Extended scan: Enabled (0x01) Filter duplicates: Enabled (0x01) Duration: 0 msec (0x0000) Period: 0.00 sec (0x0000) > HCI Event: Command Complete (0x0e) plen 4 LE Set Extended Scan Enable (0x08|0x0042) ncmd 1 Status: Success (0x00) > HCI Event: LE Meta Event (0x3e) plen 16 LE Periodic Advertising Sync Established (0x0e) Status: Success (0x00) Sync handle: 0 Advertising SID: 0x00 Advertiser address type: Random (0x01) Advertiser address: 36:13:00:E1:1B:F0 (Non-Resolvable) Advertiser PHY: LE 2M (0x02) Periodic advertising interval: 10.00 msec (0x0008) Advertiser clock accuracy: 0x00 > HCI Event: LE Meta Event (0x3e) plen 8 LE Periodic Advertising Report (0x0f) Sync handle: 0 TX power: 127 dbm (0x7f) RSSI: -47 dBm (0xd1) CTE Type: No Constant Tone Extension (0xff) Data status: Complete Data length: 0x00 > HCI Event: LE Meta Event (0x3e) plen 20 LE Broadcast Isochronous Group Info Advertising Report (0x22) Sync Handle: 0x0000 Number BIS: 2 NSE: 3 ISO Interval: 10.00 msec (0x0008) BN: 1 PTO: 1 IRC: 3 Maximum PDU: 40 SDU Interval: 10000 us (0x002710) Maximum SDU: 40 PHY: LE 2M (0x02) Framing: Unframed (0x00) Encryption: 0x00 < HCI Command: LE Broadcast Isochronous Group Create Sync (0x08|0x006b) plen 26 BIG Handle: 0x01 BIG Sync Handle: 0x0000 Encryption: Unencrypted (0x00) Broadcast Code: 00000000000000000000000000000000 Maximum Number Subevents: 0x00 Timeout: 163840 ms (0x4000) Number of BIS: 2 BIS ID: 0x01 BIS ID: 0x02 > HCI Event: LE Meta Event (0x3e) plen 19 LE Broadcast Isochronous Group Sync Estabilished (0x1d) Status: Success (0x00) BIG Handle: 0x01 Transport Latency: 1974 us (0x0007b6) NSE: 3 BN: 1 PTO: 1 IRC: 3 Maximum PDU: 40 ISO Interval: 10.00 msec (0x0008) Connection Handle #0: 10 Connection Handle #1: 11 < HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13 Handle: 10 Data Path Direction: Output (Controller to Host) (0x01) Data Path: HCI (0x00) Coding Format: Transparent (0x03) Company Codec ID: Ericsson Technology Licensing (0) Vendor Codec ID: 0 Controller Delay: 0 us (0x000000) Codec Configuration Length: 0 Codec Configuration: > HCI Event: Command Complete (0x0e) plen 6 LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1 Status: Success (0x00) Handle: 10 < HCI Command: LE Setup Isochronous Data Path (0x08|0x006e) plen 13 Handle: 11 Data Path Direction: Output (Controller to Host) (0x01) Data Path: HCI (0x00) Coding Format: Transparent (0x03) Company Codec ID: Ericsson Technology Licensing (0) Vendor Codec ID: 0 Controller Delay: 0 us (0x000000) Codec Configuration Length: 0 Codec Configuration: > HCI Event: Command Complete (0x0e) plen 6 LE Setup Isochronous Data Path (0x08|0x006e) ncmd 1 Status: Success (0x00) Handle: 11 > ISO Data RX: Handle 10 flags 0x06 dlen 48 > ISO Data RX: Handle 11 flags 0x06 dlen 48
This commit is contained in:
parent
15eb57049b
commit
8ff103f993
304
tools/isotest.c
304
tools/isotest.c
@ -32,6 +32,7 @@
|
||||
#include <linux/sockios.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "lib/bluetooth.h"
|
||||
#include "lib/hci.h"
|
||||
@ -45,6 +46,9 @@
|
||||
#define SEC_USEC(_t) (_t * 1000000L)
|
||||
#define TS_USEC(_ts) (SEC_USEC((_ts)->tv_sec) + NSEC_USEC((_ts)->tv_nsec))
|
||||
|
||||
#define DEFAULT_BIG_ID 0x01
|
||||
#define DEFAULT_BIS_ID 0x01
|
||||
|
||||
/* Test modes */
|
||||
enum {
|
||||
SEND,
|
||||
@ -72,6 +76,8 @@ static bool quiet;
|
||||
struct bt_iso_qos *iso_qos;
|
||||
static bool inout;
|
||||
|
||||
static uint8_t num_bis = 1;
|
||||
|
||||
struct lookup_table {
|
||||
const char *name;
|
||||
int flag;
|
||||
@ -316,8 +322,6 @@ static int do_connect(char *peer)
|
||||
struct sockaddr_iso addr;
|
||||
int sk;
|
||||
|
||||
mgmt_set_experimental();
|
||||
|
||||
/* Create socket */
|
||||
sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_ISO);
|
||||
if (sk < 0) {
|
||||
@ -390,6 +394,45 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int *bcast_do_connect_mbis(uint8_t count, char *peer)
|
||||
{
|
||||
int *sk;
|
||||
uint8_t sk_cnt = 0;
|
||||
|
||||
sk = malloc(count * sizeof(*sk));
|
||||
if (!sk) {
|
||||
syslog(LOG_ERR, "Can't allocate socket array");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
defer_setup = 1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i == count - 1)
|
||||
defer_setup = 0;
|
||||
|
||||
sk[i] = do_connect(peer);
|
||||
if (sk[i] < 0) {
|
||||
syslog(LOG_ERR, "Can't create socket: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
sk_cnt++;
|
||||
}
|
||||
|
||||
return sk;
|
||||
|
||||
error:
|
||||
for (int i = 0; i < sk_cnt; i++)
|
||||
close(sk[i]);
|
||||
|
||||
free(sk);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static void do_listen(char *filename, void (*handler)(int fd, int sk),
|
||||
char *peer)
|
||||
{
|
||||
@ -431,8 +474,11 @@ static void do_listen(char *filename, void (*handler)(int fd, int sk),
|
||||
if (peer) {
|
||||
str2ba(peer, &addr->iso_bc->bc_bdaddr);
|
||||
addr->iso_bc->bc_bdaddr_type = bdaddr_type;
|
||||
addr->iso_bc->bc_num_bis = 1;
|
||||
addr->iso_bc->bc_bis[0] = 1;
|
||||
addr->iso_bc->bc_num_bis = num_bis;
|
||||
|
||||
for (int i = 0; i < num_bis; i++)
|
||||
addr->iso_bc->bc_bis[i] = i + 1;
|
||||
|
||||
optlen += sizeof(*addr->iso_bc);
|
||||
}
|
||||
|
||||
@ -584,6 +630,7 @@ static void recv_mode(int fd, int sk)
|
||||
strerror(errno), errno);
|
||||
if (errno != ENOTCONN)
|
||||
return;
|
||||
|
||||
r = 0;
|
||||
}
|
||||
|
||||
@ -704,84 +751,16 @@ static int read_file(int fd, ssize_t count, bool rewind)
|
||||
return len;
|
||||
}
|
||||
|
||||
static void do_send(int sk, int fd, struct bt_iso_io_qos *out, uint32_t num,
|
||||
bool repeat)
|
||||
static void do_send(int sk, int fd, char *peer, bool repeat)
|
||||
{
|
||||
uint32_t seq;
|
||||
struct timespec t_start;
|
||||
int len, used;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &t_start) < 0) {
|
||||
perror("clock_gettime");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (seq = 0; ; seq++) {
|
||||
if (fd >= 0) {
|
||||
len = read_file(fd, out->sdu, repeat);
|
||||
if (len < 0) {
|
||||
syslog(LOG_ERR, "read failed: %s (%d)",
|
||||
strerror(-len), -len);
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
len = out->sdu;
|
||||
|
||||
len = send(sk, buf, len, 0);
|
||||
if (len <= 0) {
|
||||
syslog(LOG_ERR, "send failed: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ioctl(sk, TIOCOUTQ, &used);
|
||||
|
||||
if (!quiet)
|
||||
syslog(LOG_INFO,
|
||||
"[seq %d] %d bytes buffered %d (%d bytes)",
|
||||
seq, len, used / len, used);
|
||||
|
||||
if (seq && !((seq + 1) % num))
|
||||
send_wait(&t_start, num * out->interval);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_mode(char *filename, char *peer, int i, bool repeat)
|
||||
{
|
||||
struct bt_iso_qos qos;
|
||||
int send_len, used;
|
||||
socklen_t len;
|
||||
int sk, fd = -1;
|
||||
struct bt_iso_qos qos;
|
||||
uint32_t num;
|
||||
struct bt_iso_io_qos *out;
|
||||
|
||||
if (filename) {
|
||||
char altername[PATH_MAX];
|
||||
struct stat st;
|
||||
int err;
|
||||
|
||||
snprintf(altername, PATH_MAX, "%s.%u", filename, i);
|
||||
|
||||
err = stat(altername, &st);
|
||||
if (!err)
|
||||
fd = open_file(altername);
|
||||
|
||||
if (fd <= 0)
|
||||
fd = open_file(filename);
|
||||
}
|
||||
|
||||
sk = do_connect(peer);
|
||||
if (sk < 0) {
|
||||
syslog(LOG_ERR, "Can't connect to the server: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (defer_setup) {
|
||||
syslog(LOG_INFO, "Waiting for %d seconds",
|
||||
abs(defer_setup) - 1);
|
||||
sleep(abs(defer_setup) - 1);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "Sending ...");
|
||||
|
||||
/* Read QoS */
|
||||
@ -830,14 +809,114 @@ static void send_mode(char *filename, char *peer, int i, bool repeat)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 6; i < out->sdu; i++)
|
||||
for (int i = 6; i < out->sdu; i++)
|
||||
buf[i] = 0x7f;
|
||||
|
||||
do_send(sk, fd, out, num, repeat);
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &t_start) < 0) {
|
||||
perror("clock_gettime");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (seq = 0; ; seq++) {
|
||||
if (fd >= 0) {
|
||||
send_len = read_file(fd, out->sdu, repeat);
|
||||
if (send_len < 0) {
|
||||
syslog(LOG_ERR, "read failed: %s (%d)",
|
||||
strerror(-send_len), -send_len);
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
send_len = out->sdu;
|
||||
|
||||
send_len = send(sk, buf, send_len, 0);
|
||||
if (send_len <= 0) {
|
||||
syslog(LOG_ERR, "send failed: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ioctl(sk, TIOCOUTQ, &used);
|
||||
|
||||
if (!quiet)
|
||||
syslog(LOG_INFO,
|
||||
"[seq %d] %d bytes buffered %d (%d bytes)",
|
||||
seq, send_len, used / send_len, used);
|
||||
|
||||
if (seq && !((seq + 1) % num))
|
||||
send_wait(&t_start, num * out->interval);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_mode(char *filename, char *peer, int i, bool repeat)
|
||||
{
|
||||
int sk, fd = -1;
|
||||
int *sk_arr;
|
||||
uint8_t nconn = strcmp(peer, "00:00:00:00:00:00") ? 1 : num_bis;
|
||||
|
||||
mgmt_set_experimental();
|
||||
|
||||
if (filename) {
|
||||
char altername[PATH_MAX];
|
||||
struct stat st;
|
||||
int err;
|
||||
|
||||
snprintf(altername, PATH_MAX, "%s.%u", filename, i);
|
||||
|
||||
err = stat(altername, &st);
|
||||
if (!err)
|
||||
fd = open_file(altername);
|
||||
|
||||
if (fd <= 0)
|
||||
fd = open_file(filename);
|
||||
}
|
||||
|
||||
if (nconn > 1) {
|
||||
sk_arr = bcast_do_connect_mbis(nconn, peer);
|
||||
if (!sk_arr)
|
||||
exit(1);
|
||||
|
||||
for (int i = 0; i < nconn; i++) {
|
||||
if (fork()) {
|
||||
/* Parent */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Child */
|
||||
do_send(sk_arr[i], fd, peer, repeat);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Wait for children to exit */
|
||||
while (wait(NULL) > 0)
|
||||
;
|
||||
|
||||
for (int i = 0; i < nconn; i++)
|
||||
close(sk_arr[i]);
|
||||
|
||||
free(sk_arr);
|
||||
return;
|
||||
}
|
||||
|
||||
sk = do_connect(peer);
|
||||
if (sk < 0) {
|
||||
syslog(LOG_ERR, "Can't connect to the server: %s (%d)",
|
||||
strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (defer_setup) {
|
||||
syslog(LOG_INFO, "Waiting for %d seconds",
|
||||
abs(defer_setup) - 1);
|
||||
sleep(abs(defer_setup) - 1);
|
||||
}
|
||||
|
||||
do_send(sk, fd, peer, repeat);
|
||||
}
|
||||
|
||||
static void reconnect_mode(char *peer)
|
||||
{
|
||||
mgmt_set_experimental();
|
||||
|
||||
while (1) {
|
||||
int sk;
|
||||
|
||||
@ -856,6 +935,8 @@ static void reconnect_mode(char *peer)
|
||||
|
||||
static void multy_connect_mode(char *peer)
|
||||
{
|
||||
mgmt_set_experimental();
|
||||
|
||||
while (1) {
|
||||
int i, sk;
|
||||
|
||||
@ -989,7 +1070,8 @@ static void usage(void)
|
||||
"\t[-B, --preset <value>]\n"
|
||||
"\t[-G, --CIG/BIG <value>]\n"
|
||||
"\t[-T, --CIS/BIS <value>]\n"
|
||||
"\t[-V, --type <value>] address type (help for list)\n");
|
||||
"\t[-V, --type <value>] address type (help for list)\n"
|
||||
"\t[-N, --nbis <value>] Number of BISes to create/synchronize to\n");
|
||||
}
|
||||
|
||||
static const struct option main_options[] = {
|
||||
@ -1019,6 +1101,7 @@ static const struct option main_options[] = {
|
||||
{ "CIG/BIG", required_argument, NULL, 'G'},
|
||||
{ "CIS/BIS", required_argument, NULL, 'T'},
|
||||
{ "type", required_argument, NULL, 'V'},
|
||||
{ "nbis", required_argument, NULL, 'N'},
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1048,6 +1131,8 @@ int main(int argc, char *argv[])
|
||||
char *filename = NULL;
|
||||
bool repeat = false;
|
||||
unsigned int i;
|
||||
uint8_t nconn = 1;
|
||||
char *peer;
|
||||
|
||||
iso_qos = malloc(sizeof(*iso_qos));
|
||||
/* Default to 16_2_1 */
|
||||
@ -1058,7 +1143,7 @@ int main(int argc, char *argv[])
|
||||
int opt;
|
||||
|
||||
opt = getopt_long(argc, argv,
|
||||
"d::cmr::s::nb:i:j:hqt:CV:W:M:S:P:F:I:L:Y:R:B:G:T:e:k:",
|
||||
"d::cmr::s::nb:i:j:hqt:CV:W:M:S:P:F:I:L:Y:R:B:G:T:e:k:N:",
|
||||
main_options, NULL);
|
||||
if (opt < 0)
|
||||
break;
|
||||
@ -1224,6 +1309,23 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
if (optarg)
|
||||
num_bis = atoi(optarg);
|
||||
|
||||
if (num_bis > 1) {
|
||||
/* If the user requested multiple BISes,
|
||||
* make sure that all BISes are bound
|
||||
* for the same BIG and advertising set
|
||||
*/
|
||||
if (iso_qos->bcast.big == BT_ISO_QOS_BIG_UNSET)
|
||||
iso_qos->bcast.big = DEFAULT_BIG_ID;
|
||||
|
||||
if (iso_qos->bcast.bis == BT_ISO_QOS_BIS_UNSET)
|
||||
iso_qos->bcast.bis = DEFAULT_BIS_ID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* fall through */
|
||||
default:
|
||||
usage();
|
||||
@ -1297,10 +1399,46 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case CONNECT:
|
||||
sk = do_connect(argv[optind + i]);
|
||||
if (sk < 0)
|
||||
exit(1);
|
||||
dump_mode(-1, sk);
|
||||
peer = argv[optind + i];
|
||||
|
||||
mgmt_set_experimental();
|
||||
|
||||
if (!strcmp(peer, "00:00:00:00:00:00"))
|
||||
nconn = num_bis;
|
||||
|
||||
if (nconn > 1) {
|
||||
int *sk_arr = bcast_do_connect_mbis(nconn,
|
||||
peer);
|
||||
|
||||
if (!sk_arr)
|
||||
exit(1);
|
||||
|
||||
for (int i = 0; i < nconn; i++) {
|
||||
if (fork()) {
|
||||
/* Parent */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Child */
|
||||
dump_mode(-1, sk_arr[i]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Wait for children to exit */
|
||||
while (wait(NULL) > 0)
|
||||
;
|
||||
|
||||
for (int i = 0; i < nconn; i++)
|
||||
close(sk_arr[i]);
|
||||
|
||||
free(sk_arr);
|
||||
} else {
|
||||
sk = do_connect(argv[optind + i]);
|
||||
if (sk < 0)
|
||||
exit(1);
|
||||
dump_mode(-1, sk);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case RECV:
|
||||
|
@ -172,6 +172,10 @@ OPTIONS
|
||||
|
||||
-k, --bcode=<BCODE> Socket QoS Broadcast Code
|
||||
|
||||
-N, --nbis=<NBIS> Number of BISes to create as part of a
|
||||
BIG (BIS broadcaster) or to synchronize
|
||||
to (BIS broadcast receiver)
|
||||
|
||||
EXAMPLES
|
||||
========
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user