sco-tester.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2013 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdlib.h>
  14. #include <unistd.h>
  15. #include <errno.h>
  16. #include <stdbool.h>
  17. #include <glib.h>
  18. #include "lib/bluetooth.h"
  19. #include "lib/sco.h"
  20. #include "lib/mgmt.h"
  21. #include "monitor/bt.h"
  22. #include "emulator/bthost.h"
  23. #include "emulator/hciemu.h"
  24. #include "src/shared/tester.h"
  25. #include "src/shared/mgmt.h"
  26. struct test_data {
  27. const void *test_data;
  28. struct mgmt *mgmt;
  29. uint16_t mgmt_index;
  30. struct hciemu *hciemu;
  31. enum hciemu_type hciemu_type;
  32. unsigned int io_id;
  33. bool disable_esco;
  34. bool enable_codecs;
  35. };
  36. struct sco_client_data {
  37. int expect_err;
  38. const uint8_t *send_data;
  39. uint16_t data_len;
  40. };
  41. static void print_debug(const char *str, void *user_data)
  42. {
  43. const char *prefix = user_data;
  44. tester_print("%s%s", prefix, str);
  45. }
  46. static void read_info_callback(uint8_t status, uint16_t length,
  47. const void *param, void *user_data)
  48. {
  49. struct test_data *data = tester_get_data();
  50. const struct mgmt_rp_read_info *rp = param;
  51. char addr[18];
  52. uint16_t manufacturer;
  53. uint32_t supported_settings, current_settings;
  54. tester_print("Read Info callback");
  55. tester_print(" Status: 0x%02x", status);
  56. if (status || !param) {
  57. tester_pre_setup_failed();
  58. return;
  59. }
  60. ba2str(&rp->bdaddr, addr);
  61. manufacturer = btohs(rp->manufacturer);
  62. supported_settings = btohl(rp->supported_settings);
  63. current_settings = btohl(rp->current_settings);
  64. tester_print(" Address: %s", addr);
  65. tester_print(" Version: 0x%02x", rp->version);
  66. tester_print(" Manufacturer: 0x%04x", manufacturer);
  67. tester_print(" Supported settings: 0x%08x", supported_settings);
  68. tester_print(" Current settings: 0x%08x", current_settings);
  69. tester_print(" Class: 0x%02x%02x%02x",
  70. rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
  71. tester_print(" Name: %s", rp->name);
  72. tester_print(" Short name: %s", rp->short_name);
  73. if (strcmp(hciemu_get_address(data->hciemu), addr)) {
  74. tester_pre_setup_failed();
  75. return;
  76. }
  77. tester_pre_setup_complete();
  78. }
  79. static void index_added_callback(uint16_t index, uint16_t length,
  80. const void *param, void *user_data)
  81. {
  82. struct test_data *data = tester_get_data();
  83. tester_print("Index Added callback");
  84. tester_print(" Index: 0x%04x", index);
  85. data->mgmt_index = index;
  86. mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL,
  87. read_info_callback, NULL, NULL);
  88. }
  89. static void index_removed_callback(uint16_t index, uint16_t length,
  90. const void *param, void *user_data)
  91. {
  92. struct test_data *data = tester_get_data();
  93. tester_print("Index Removed callback");
  94. tester_print(" Index: 0x%04x", index);
  95. if (index != data->mgmt_index)
  96. return;
  97. mgmt_unregister_index(data->mgmt, data->mgmt_index);
  98. mgmt_unref(data->mgmt);
  99. data->mgmt = NULL;
  100. tester_post_teardown_complete();
  101. }
  102. static void enable_codec_callback(uint8_t status, uint16_t length,
  103. const void *param, void *user_data)
  104. {
  105. if (status != MGMT_STATUS_SUCCESS) {
  106. tester_warn("Failed to enable codecs");
  107. tester_setup_failed();
  108. return;
  109. }
  110. tester_print("Enabled codecs");
  111. }
  112. static void read_index_list_callback(uint8_t status, uint16_t length,
  113. const void *param, void *user_data)
  114. {
  115. struct test_data *data = tester_get_data();
  116. tester_print("Read Index List callback");
  117. tester_print(" Status: 0x%02x", status);
  118. if (status || !param) {
  119. tester_pre_setup_failed();
  120. return;
  121. }
  122. mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
  123. index_added_callback, NULL, NULL);
  124. mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
  125. index_removed_callback, NULL, NULL);
  126. data->hciemu = hciemu_new(HCIEMU_TYPE_BREDRLE);
  127. if (!data->hciemu) {
  128. tester_warn("Failed to setup HCI emulation");
  129. tester_pre_setup_failed();
  130. return;
  131. }
  132. if (tester_use_debug())
  133. hciemu_set_debug(data->hciemu, print_debug, "hciemu: ", NULL);
  134. tester_print("New hciemu instance created");
  135. if (data->disable_esco) {
  136. uint8_t *features;
  137. tester_print("Disabling eSCO packet type support");
  138. features = hciemu_get_features(data->hciemu);
  139. if (features)
  140. features[3] &= ~0x80;
  141. }
  142. }
  143. static void test_pre_setup(const void *test_data)
  144. {
  145. struct test_data *data = tester_get_data();
  146. data->mgmt = mgmt_new_default();
  147. if (!data->mgmt) {
  148. tester_warn("Failed to setup management interface");
  149. tester_pre_setup_failed();
  150. return;
  151. }
  152. if (tester_use_debug())
  153. mgmt_set_debug(data->mgmt, print_debug, "mgmt: ", NULL);
  154. mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, NULL,
  155. read_index_list_callback, NULL, NULL);
  156. }
  157. static void test_post_teardown(const void *test_data)
  158. {
  159. struct test_data *data = tester_get_data();
  160. hciemu_unref(data->hciemu);
  161. data->hciemu = NULL;
  162. }
  163. static void test_data_free(void *test_data)
  164. {
  165. struct test_data *data = test_data;
  166. if (data->io_id > 0)
  167. g_source_remove(data->io_id);
  168. free(data);
  169. }
  170. #define test_sco_full(name, data, setup, func, _disable_esco, _enable_codecs) \
  171. do { \
  172. struct test_data *user; \
  173. user = malloc(sizeof(struct test_data)); \
  174. if (!user) \
  175. break; \
  176. user->hciemu_type = HCIEMU_TYPE_BREDRLE; \
  177. user->io_id = 0; \
  178. user->test_data = data; \
  179. user->disable_esco = _disable_esco; \
  180. user->enable_codecs = _enable_codecs; \
  181. tester_add_full(name, data, \
  182. test_pre_setup, setup, func, NULL, \
  183. test_post_teardown, 2, user, test_data_free); \
  184. } while (0)
  185. #define test_sco(name, data, setup, func) \
  186. test_sco_full(name, data, setup, func, false, false)
  187. #define test_sco_11(name, data, setup, func) \
  188. test_sco_full(name, data, setup, func, true, false)
  189. #define test_offload_sco(name, data, setup, func) \
  190. test_sco_full(name, data, setup, func, false, true)
  191. static const struct sco_client_data connect_success = {
  192. .expect_err = 0
  193. };
  194. static const struct sco_client_data connect_failure = {
  195. .expect_err = EOPNOTSUPP
  196. };
  197. const uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
  198. static const struct sco_client_data connect_send_success = {
  199. .expect_err = 0,
  200. .data_len = sizeof(data),
  201. .send_data = data
  202. };
  203. static void client_connectable_complete(uint16_t opcode, uint8_t status,
  204. const void *param, uint8_t len,
  205. void *user_data)
  206. {
  207. if (opcode != BT_HCI_CMD_WRITE_SCAN_ENABLE)
  208. return;
  209. tester_print("Client set connectable status 0x%02x", status);
  210. if (status)
  211. tester_setup_failed();
  212. else
  213. tester_setup_complete();
  214. }
  215. static void setup_powered_callback(uint8_t status, uint16_t length,
  216. const void *param, void *user_data)
  217. {
  218. struct test_data *data = tester_get_data();
  219. struct bthost *bthost;
  220. if (status != MGMT_STATUS_SUCCESS) {
  221. tester_setup_failed();
  222. return;
  223. }
  224. tester_print("Controller powered on");
  225. bthost = hciemu_client_get_host(data->hciemu);
  226. bthost_set_cmd_complete_cb(bthost, client_connectable_complete, data);
  227. bthost_write_scan_enable(bthost, 0x03);
  228. }
  229. static void setup_powered(const void *test_data)
  230. {
  231. struct test_data *data = tester_get_data();
  232. unsigned char param[] = { 0x01 };
  233. tester_print("Powering on controller");
  234. mgmt_send(data->mgmt, MGMT_OP_SET_CONNECTABLE, data->mgmt_index,
  235. sizeof(param), param,
  236. NULL, NULL, NULL);
  237. mgmt_send(data->mgmt, MGMT_OP_SET_SSP, data->mgmt_index,
  238. sizeof(param), param, NULL, NULL, NULL);
  239. mgmt_send(data->mgmt, MGMT_OP_SET_LE, data->mgmt_index,
  240. sizeof(param), param, NULL, NULL, NULL);
  241. if (data->enable_codecs) {
  242. /* a6695ace-ee7f-4fb9-881a-5fac66c629af */
  243. static const uint8_t uuid[16] = {
  244. 0xaf, 0x29, 0xc6, 0x66, 0xac, 0x5f, 0x1a, 0x88,
  245. 0xb9, 0x4f, 0x7f, 0xee, 0xce, 0x5a, 0x69, 0xa6,
  246. };
  247. struct mgmt_cp_set_exp_feature cp;
  248. memset(&cp, 0, sizeof(cp));
  249. memcpy(cp.uuid, uuid, 16);
  250. cp.action = 1;
  251. tester_print("Enabling codecs");
  252. mgmt_send(data->mgmt, MGMT_OP_SET_EXP_FEATURE, data->mgmt_index,
  253. sizeof(cp), &cp, enable_codec_callback, NULL, NULL);
  254. }
  255. mgmt_send(data->mgmt, MGMT_OP_SET_POWERED, data->mgmt_index,
  256. sizeof(param), param,
  257. setup_powered_callback, NULL, NULL);
  258. }
  259. static void test_framework(const void *test_data)
  260. {
  261. tester_test_passed();
  262. }
  263. static void test_socket(const void *test_data)
  264. {
  265. int sk;
  266. sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
  267. if (sk < 0) {
  268. tester_warn("Can't create socket: %s (%d)", strerror(errno),
  269. errno);
  270. tester_test_failed();
  271. return;
  272. }
  273. close(sk);
  274. tester_test_passed();
  275. }
  276. static void test_codecs_getsockopt(const void *test_data)
  277. {
  278. int sk, err;
  279. socklen_t len;
  280. char buffer[255];
  281. sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
  282. if (sk < 0) {
  283. tester_warn("Can't create socket: %s (%d)", strerror(errno),
  284. errno);
  285. tester_test_failed();
  286. return;
  287. }
  288. len = sizeof(buffer);
  289. memset(buffer, 0, len);
  290. err = getsockopt(sk, SOL_BLUETOOTH, BT_CODEC, buffer, &len);
  291. if (err < 0) {
  292. tester_warn("Can't get socket option : %s (%d)",
  293. strerror(errno), errno);
  294. tester_test_failed();
  295. goto end;
  296. }
  297. tester_test_passed();
  298. end:
  299. close(sk);
  300. }
  301. static void test_codecs_setsockopt(const void *test_data)
  302. {
  303. int sk, err;
  304. char buffer[255];
  305. struct bt_codecs *codecs;
  306. sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
  307. if (sk < 0) {
  308. tester_warn("Can't create socket: %s (%d)", strerror(errno),
  309. errno);
  310. tester_test_failed();
  311. return;
  312. }
  313. memset(buffer, 0, sizeof(buffer));
  314. codecs = (void *)buffer;
  315. codecs->codecs[0].id = 0x05;
  316. codecs->num_codecs = 1;
  317. codecs->codecs[0].data_path_id = 1;
  318. codecs->codecs[0].num_caps = 0x00;
  319. err = setsockopt(sk, SOL_BLUETOOTH, BT_CODEC, codecs, sizeof(buffer));
  320. if (err < 0) {
  321. tester_warn("Can't set socket option : %s (%d)",
  322. strerror(errno), errno);
  323. tester_test_failed();
  324. goto end;
  325. }
  326. tester_test_passed();
  327. end:
  328. close(sk);
  329. }
  330. static void test_getsockopt(const void *test_data)
  331. {
  332. int sk, err;
  333. socklen_t len;
  334. struct bt_voice voice;
  335. sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
  336. if (sk < 0) {
  337. tester_warn("Can't create socket: %s (%d)", strerror(errno),
  338. errno);
  339. tester_test_failed();
  340. return;
  341. }
  342. len = sizeof(voice);
  343. memset(&voice, 0, len);
  344. err = getsockopt(sk, SOL_BLUETOOTH, BT_VOICE, &voice, &len);
  345. if (err < 0) {
  346. tester_warn("Can't get socket option : %s (%d)",
  347. strerror(errno), errno);
  348. tester_test_failed();
  349. goto end;
  350. }
  351. if (voice.setting != BT_VOICE_CVSD_16BIT) {
  352. tester_warn("Invalid voice setting");
  353. tester_test_failed();
  354. goto end;
  355. }
  356. tester_test_passed();
  357. end:
  358. close(sk);
  359. }
  360. static void test_setsockopt(const void *test_data)
  361. {
  362. int sk, err;
  363. socklen_t len;
  364. struct bt_voice voice;
  365. sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
  366. if (sk < 0) {
  367. tester_warn("Can't create socket: %s (%d)", strerror(errno),
  368. errno);
  369. tester_test_failed();
  370. goto end;
  371. }
  372. len = sizeof(voice);
  373. memset(&voice, 0, len);
  374. err = getsockopt(sk, SOL_BLUETOOTH, BT_VOICE, &voice, &len);
  375. if (err < 0) {
  376. tester_warn("Can't get socket option : %s (%d)",
  377. strerror(errno), errno);
  378. tester_test_failed();
  379. goto end;
  380. }
  381. if (voice.setting != BT_VOICE_CVSD_16BIT) {
  382. tester_warn("Invalid voice setting");
  383. tester_test_failed();
  384. goto end;
  385. }
  386. memset(&voice, 0, sizeof(voice));
  387. voice.setting = BT_VOICE_TRANSPARENT;
  388. err = setsockopt(sk, SOL_BLUETOOTH, BT_VOICE, &voice, sizeof(voice));
  389. if (err < 0) {
  390. tester_warn("Can't set socket option : %s (%d)",
  391. strerror(errno), errno);
  392. tester_test_failed();
  393. goto end;
  394. }
  395. len = sizeof(voice);
  396. memset(&voice, 0, len);
  397. err = getsockopt(sk, SOL_BLUETOOTH, BT_VOICE, &voice, &len);
  398. if (err < 0) {
  399. tester_warn("Can't get socket option : %s (%d)",
  400. strerror(errno), errno);
  401. tester_test_failed();
  402. goto end;
  403. }
  404. if (voice.setting != BT_VOICE_TRANSPARENT) {
  405. tester_warn("Invalid voice setting");
  406. tester_test_failed();
  407. goto end;
  408. }
  409. tester_test_passed();
  410. end:
  411. close(sk);
  412. }
  413. static int create_sco_sock(struct test_data *data)
  414. {
  415. const uint8_t *central_bdaddr;
  416. struct sockaddr_sco addr;
  417. int sk, err;
  418. sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK,
  419. BTPROTO_SCO);
  420. if (sk < 0) {
  421. err = -errno;
  422. tester_warn("Can't create socket: %s (%d)", strerror(errno),
  423. errno);
  424. return err;
  425. }
  426. central_bdaddr = hciemu_get_central_bdaddr(data->hciemu);
  427. if (!central_bdaddr) {
  428. tester_warn("No central bdaddr");
  429. return -ENODEV;
  430. }
  431. memset(&addr, 0, sizeof(addr));
  432. addr.sco_family = AF_BLUETOOTH;
  433. bacpy(&addr.sco_bdaddr, (void *) central_bdaddr);
  434. if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  435. err = -errno;
  436. tester_warn("Can't bind socket: %s (%d)", strerror(errno),
  437. errno);
  438. close(sk);
  439. return err;
  440. }
  441. return sk;
  442. }
  443. static int connect_sco_sock(struct test_data *data, int sk)
  444. {
  445. const uint8_t *client_bdaddr;
  446. struct sockaddr_sco addr;
  447. int err;
  448. client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
  449. if (!client_bdaddr) {
  450. tester_warn("No client bdaddr");
  451. return -ENODEV;
  452. }
  453. memset(&addr, 0, sizeof(addr));
  454. addr.sco_family = AF_BLUETOOTH;
  455. bacpy(&addr.sco_bdaddr, (void *) client_bdaddr);
  456. err = connect(sk, (struct sockaddr *) &addr, sizeof(addr));
  457. if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
  458. err = -errno;
  459. tester_warn("Can't connect socket: %s (%d)", strerror(errno),
  460. errno);
  461. return err;
  462. }
  463. return 0;
  464. }
  465. static gboolean sco_connect_cb(GIOChannel *io, GIOCondition cond,
  466. gpointer user_data)
  467. {
  468. struct test_data *data = tester_get_data();
  469. const struct sco_client_data *scodata = data->test_data;
  470. int err, sk_err, sk;
  471. socklen_t len = sizeof(sk_err);
  472. data->io_id = 0;
  473. sk = g_io_channel_unix_get_fd(io);
  474. if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &sk_err, &len) < 0)
  475. err = -errno;
  476. else
  477. err = -sk_err;
  478. if (err < 0)
  479. tester_warn("Connect failed: %s (%d)", strerror(-err), -err);
  480. else
  481. tester_print("Successfully connected");
  482. if (scodata->send_data) {
  483. ssize_t ret;
  484. tester_print("Writing %u bytes of data", scodata->data_len);
  485. ret = write(sk, scodata->send_data, scodata->data_len);
  486. if (scodata->data_len != ret) {
  487. tester_warn("Failed to write %u bytes: %zu %s (%d)",
  488. scodata->data_len, ret, strerror(errno),
  489. errno);
  490. err = -errno;
  491. }
  492. }
  493. if (-err != scodata->expect_err)
  494. tester_test_failed();
  495. else
  496. tester_test_passed();
  497. return FALSE;
  498. }
  499. static void test_connect(const void *test_data)
  500. {
  501. struct test_data *data = tester_get_data();
  502. GIOChannel *io;
  503. int sk;
  504. sk = create_sco_sock(data);
  505. if (sk < 0) {
  506. tester_test_failed();
  507. return;
  508. }
  509. if (connect_sco_sock(data, sk) < 0) {
  510. close(sk);
  511. tester_test_failed();
  512. return;
  513. }
  514. io = g_io_channel_unix_new(sk);
  515. g_io_channel_set_close_on_unref(io, TRUE);
  516. data->io_id = g_io_add_watch(io, G_IO_OUT, sco_connect_cb, NULL);
  517. g_io_channel_unref(io);
  518. tester_print("Connect in progress");
  519. }
  520. static void test_connect_transp(const void *test_data)
  521. {
  522. struct test_data *data = tester_get_data();
  523. const struct sco_client_data *scodata = data->test_data;
  524. int sk, err;
  525. struct bt_voice voice;
  526. sk = create_sco_sock(data);
  527. if (sk < 0) {
  528. tester_test_failed();
  529. return;
  530. }
  531. memset(&voice, 0, sizeof(voice));
  532. voice.setting = BT_VOICE_TRANSPARENT;
  533. err = setsockopt(sk, SOL_BLUETOOTH, BT_VOICE, &voice, sizeof(voice));
  534. if (err < 0) {
  535. tester_warn("Can't set socket option : %s (%d)",
  536. strerror(errno), errno);
  537. tester_test_failed();
  538. goto end;
  539. }
  540. err = connect_sco_sock(data, sk);
  541. tester_warn("Connect returned %s (%d), expected %s (%d)",
  542. strerror(-err), -err,
  543. strerror(scodata->expect_err), scodata->expect_err);
  544. if (-err != scodata->expect_err)
  545. tester_test_failed();
  546. else
  547. tester_test_passed();
  548. end:
  549. close(sk);
  550. }
  551. static void test_connect_offload_msbc(const void *test_data)
  552. {
  553. struct test_data *data = tester_get_data();
  554. const struct sco_client_data *scodata = data->test_data;
  555. int sk, err;
  556. int len;
  557. char buffer[255];
  558. struct bt_codecs *codecs;
  559. sk = create_sco_sock(data);
  560. if (sk < 0) {
  561. tester_test_failed();
  562. return;
  563. }
  564. len = sizeof(buffer);
  565. memset(buffer, 0, len);
  566. codecs = (void *)buffer;
  567. codecs->codecs[0].id = 0x05;
  568. codecs->num_codecs = 1;
  569. codecs->codecs[0].data_path_id = 1;
  570. codecs->codecs[0].num_caps = 0x00;
  571. err = setsockopt(sk, SOL_BLUETOOTH, BT_CODEC, codecs, sizeof(buffer));
  572. if (err < 0) {
  573. tester_warn("Can't set socket option : %s (%d)",
  574. strerror(errno), errno);
  575. tester_test_failed();
  576. goto end;
  577. }
  578. err = connect_sco_sock(data, sk);
  579. tester_warn("Connect returned %s (%d), expected %s (%d)",
  580. strerror(-err), -err,
  581. strerror(scodata->expect_err), scodata->expect_err);
  582. if (-err != scodata->expect_err)
  583. tester_test_failed();
  584. else
  585. tester_test_passed();
  586. end:
  587. close(sk);
  588. }
  589. int main(int argc, char *argv[])
  590. {
  591. tester_init(&argc, &argv);
  592. test_sco("Basic Framework - Success", NULL, setup_powered,
  593. test_framework);
  594. test_sco("Basic SCO Socket - Success", NULL, setup_powered,
  595. test_socket);
  596. test_sco("Basic SCO Get Socket Option - Success", NULL, setup_powered,
  597. test_getsockopt);
  598. test_sco("Basic SCO Set Socket Option - Success", NULL, setup_powered,
  599. test_setsockopt);
  600. test_sco("eSCO CVSD - Success", &connect_success, setup_powered,
  601. test_connect);
  602. test_sco("eSCO mSBC - Success", &connect_success, setup_powered,
  603. test_connect_transp);
  604. test_sco_11("SCO CVSD 1.1 - Success", &connect_success, setup_powered,
  605. test_connect);
  606. test_sco_11("SCO mSBC 1.1 - Failure", &connect_failure, setup_powered,
  607. test_connect_transp);
  608. test_sco("SCO CVSD Send - Success", &connect_send_success,
  609. setup_powered, test_connect);
  610. test_offload_sco("Basic SCO Get Socket Option - Offload - Success",
  611. NULL, setup_powered, test_codecs_getsockopt);
  612. test_offload_sco("Basic SCO Set Socket Option - Offload - Success",
  613. NULL, setup_powered, test_codecs_setsockopt);
  614. test_offload_sco("eSCO mSBC - Offload - Success",
  615. &connect_success, setup_powered, test_connect_offload_msbc);
  616. return tester_run();
  617. }