policy.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  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.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <unistd.h>
  16. #include <time.h>
  17. #include <glib.h>
  18. #include "lib/bluetooth.h"
  19. #include "lib/sdp.h"
  20. #include "lib/uuid.h"
  21. #include "lib/mgmt.h"
  22. #include "src/log.h"
  23. #include "src/plugin.h"
  24. #include "src/adapter.h"
  25. #include "src/device.h"
  26. #include "src/service.h"
  27. #include "src/profile.h"
  28. #include "src/btd.h"
  29. #include "src/shared/timeout.h"
  30. #define CONTROL_CONNECT_TIMEOUT 2
  31. #define SOURCE_RETRY_TIMEOUT 2
  32. #define SINK_RETRY_TIMEOUT SOURCE_RETRY_TIMEOUT
  33. #define CT_RETRY_TIMEOUT 1
  34. #define TG_RETRY_TIMEOUT CT_RETRY_TIMEOUT
  35. #define SOURCE_RETRIES 1
  36. #define SINK_RETRIES SOURCE_RETRIES
  37. #define CT_RETRIES 1
  38. #define TG_RETRIES CT_RETRIES
  39. struct reconnect_data {
  40. struct btd_device *dev;
  41. bool reconnect;
  42. GSList *services;
  43. unsigned int timer;
  44. bool active;
  45. unsigned int attempt;
  46. bool on_resume;
  47. };
  48. static const char *default_reconnect[] = {
  49. HSP_AG_UUID, HFP_AG_UUID, A2DP_SOURCE_UUID,
  50. A2DP_SINK_UUID, NULL };
  51. static char **reconnect_uuids = NULL;
  52. static const size_t default_attempts = 1;
  53. static size_t reconnect_attempts = 0;
  54. static const int default_intervals[] = { 1, 2, 4, 8, 16, 32, 64 };
  55. static int *reconnect_intervals = NULL;
  56. static size_t reconnect_intervals_len = 0;
  57. static const int default_resume_delay = 2;
  58. static int resume_delay;
  59. static GSList *reconnects = NULL;
  60. static unsigned int service_id = 0;
  61. static GSList *devices = NULL;
  62. static bool auto_enable = true;
  63. struct policy_data {
  64. struct btd_device *dev;
  65. unsigned int source_timer;
  66. uint8_t source_retries;
  67. unsigned int sink_timer;
  68. uint8_t sink_retries;
  69. unsigned int ct_timer;
  70. uint8_t ct_retries;
  71. unsigned int tg_timer;
  72. uint8_t tg_retries;
  73. };
  74. static struct reconnect_data *reconnect_find(struct btd_device *dev)
  75. {
  76. GSList *l;
  77. for (l = reconnects; l; l = g_slist_next(l)) {
  78. struct reconnect_data *reconnect = l->data;
  79. if (reconnect->dev == dev)
  80. return reconnect;
  81. }
  82. return NULL;
  83. }
  84. static void policy_connect(struct policy_data *data,
  85. struct btd_service *service)
  86. {
  87. struct btd_profile *profile = btd_service_get_profile(service);
  88. struct reconnect_data *reconnect;
  89. reconnect = reconnect_find(btd_service_get_device(service));
  90. if (reconnect && reconnect->active)
  91. return;
  92. DBG("%s profile %s", device_get_path(data->dev), profile->name);
  93. btd_service_connect(service);
  94. }
  95. static void policy_disconnect(struct policy_data *data,
  96. struct btd_service *service)
  97. {
  98. struct btd_profile *profile = btd_service_get_profile(service);
  99. DBG("%s profile %s", device_get_path(data->dev), profile->name);
  100. btd_service_disconnect(service);
  101. }
  102. static bool policy_connect_ct(gpointer user_data)
  103. {
  104. struct policy_data *data = user_data;
  105. struct btd_service *service;
  106. data->ct_timer = 0;
  107. data->ct_retries++;
  108. service = btd_device_get_service(data->dev, AVRCP_REMOTE_UUID);
  109. if (service != NULL)
  110. policy_connect(data, service);
  111. return FALSE;
  112. }
  113. static void policy_set_ct_timer(struct policy_data *data, int timeout)
  114. {
  115. if (data->ct_timer > 0)
  116. timeout_remove(data->ct_timer);
  117. data->ct_timer = timeout_add_seconds(timeout, policy_connect_ct,
  118. data, NULL);
  119. }
  120. static struct policy_data *find_data(struct btd_device *dev)
  121. {
  122. GSList *l;
  123. for (l = devices; l; l = l->next) {
  124. struct policy_data *data = l->data;
  125. if (data->dev == dev)
  126. return data;
  127. }
  128. return NULL;
  129. }
  130. static void policy_remove(void *user_data)
  131. {
  132. struct policy_data *data = user_data;
  133. if (data->source_timer > 0)
  134. timeout_remove(data->source_timer);
  135. if (data->sink_timer > 0)
  136. timeout_remove(data->sink_timer);
  137. if (data->ct_timer > 0)
  138. timeout_remove(data->ct_timer);
  139. if (data->tg_timer > 0)
  140. timeout_remove(data->tg_timer);
  141. g_free(data);
  142. }
  143. static struct policy_data *policy_get_data(struct btd_device *dev)
  144. {
  145. struct policy_data *data;
  146. data = find_data(dev);
  147. if (data != NULL)
  148. return data;
  149. data = g_new0(struct policy_data, 1);
  150. data->dev = dev;
  151. devices = g_slist_prepend(devices, data);
  152. return data;
  153. }
  154. static bool policy_connect_sink(gpointer user_data)
  155. {
  156. struct policy_data *data = user_data;
  157. struct btd_service *service;
  158. data->sink_timer = 0;
  159. data->sink_retries++;
  160. service = btd_device_get_service(data->dev, A2DP_SINK_UUID);
  161. if (service != NULL)
  162. policy_connect(data, service);
  163. return FALSE;
  164. }
  165. static void policy_set_sink_timer(struct policy_data *data)
  166. {
  167. if (data->sink_timer > 0)
  168. timeout_remove(data->sink_timer);
  169. data->sink_timer = timeout_add_seconds(SINK_RETRY_TIMEOUT,
  170. policy_connect_sink,
  171. data, NULL);
  172. }
  173. static void sink_cb(struct btd_service *service, btd_service_state_t old_state,
  174. btd_service_state_t new_state)
  175. {
  176. struct btd_device *dev = btd_service_get_device(service);
  177. struct policy_data *data;
  178. struct btd_service *controller;
  179. controller = btd_device_get_service(dev, AVRCP_REMOTE_UUID);
  180. if (controller == NULL)
  181. return;
  182. data = policy_get_data(dev);
  183. switch (new_state) {
  184. case BTD_SERVICE_STATE_UNAVAILABLE:
  185. if (data->sink_timer > 0) {
  186. timeout_remove(data->sink_timer);
  187. data->sink_timer = 0;
  188. }
  189. break;
  190. case BTD_SERVICE_STATE_DISCONNECTED:
  191. if (old_state == BTD_SERVICE_STATE_CONNECTING) {
  192. int err = btd_service_get_error(service);
  193. if (err == -EAGAIN) {
  194. if (data->sink_retries < SINK_RETRIES)
  195. policy_set_sink_timer(data);
  196. else
  197. data->sink_retries = 0;
  198. break;
  199. } else if (data->sink_timer > 0) {
  200. timeout_remove(data->sink_timer);
  201. data->sink_timer = 0;
  202. }
  203. }
  204. if (data->ct_timer > 0) {
  205. timeout_remove(data->ct_timer);
  206. data->ct_timer = 0;
  207. } else if (btd_service_get_state(controller) !=
  208. BTD_SERVICE_STATE_DISCONNECTED)
  209. policy_disconnect(data, controller);
  210. break;
  211. case BTD_SERVICE_STATE_CONNECTING:
  212. break;
  213. case BTD_SERVICE_STATE_CONNECTED:
  214. if (data->sink_timer > 0) {
  215. timeout_remove(data->sink_timer);
  216. data->sink_timer = 0;
  217. }
  218. /* Check if service initiate the connection then proceed
  219. * immediatelly otherwise set timer
  220. */
  221. if (btd_service_is_initiator(service))
  222. policy_connect(data, controller);
  223. else if (btd_service_get_state(controller) !=
  224. BTD_SERVICE_STATE_CONNECTED)
  225. policy_set_ct_timer(data, CONTROL_CONNECT_TIMEOUT);
  226. break;
  227. case BTD_SERVICE_STATE_DISCONNECTING:
  228. break;
  229. }
  230. }
  231. static void hs_cb(struct btd_service *service, btd_service_state_t old_state,
  232. btd_service_state_t new_state)
  233. {
  234. struct btd_device *dev = btd_service_get_device(service);
  235. struct policy_data *data;
  236. struct btd_service *sink;
  237. /* If the device supports Sink set a timer to connect it as well */
  238. sink = btd_device_get_service(dev, A2DP_SINK_UUID);
  239. if (sink == NULL)
  240. return;
  241. data = policy_get_data(dev);
  242. switch (new_state) {
  243. case BTD_SERVICE_STATE_UNAVAILABLE:
  244. break;
  245. case BTD_SERVICE_STATE_DISCONNECTED:
  246. break;
  247. case BTD_SERVICE_STATE_CONNECTING:
  248. break;
  249. case BTD_SERVICE_STATE_CONNECTED:
  250. /* Check if service initiate the connection then proceed
  251. * immediately otherwise set timer
  252. */
  253. if (btd_service_is_initiator(service))
  254. policy_connect(data, sink);
  255. else if (btd_service_get_state(sink) !=
  256. BTD_SERVICE_STATE_CONNECTED)
  257. policy_set_sink_timer(data);
  258. break;
  259. case BTD_SERVICE_STATE_DISCONNECTING:
  260. break;
  261. }
  262. }
  263. static bool policy_connect_tg(gpointer user_data)
  264. {
  265. struct policy_data *data = user_data;
  266. struct btd_service *service;
  267. data->tg_timer = 0;
  268. data->tg_retries++;
  269. service = btd_device_get_service(data->dev, AVRCP_TARGET_UUID);
  270. if (service != NULL)
  271. policy_connect(data, service);
  272. return FALSE;
  273. }
  274. static void policy_set_tg_timer(struct policy_data *data, int timeout)
  275. {
  276. if (data->tg_timer > 0)
  277. timeout_remove(data->tg_timer);
  278. data->tg_timer = timeout_add_seconds(timeout, policy_connect_tg,
  279. data, NULL);
  280. }
  281. static bool policy_connect_source(gpointer user_data)
  282. {
  283. struct policy_data *data = user_data;
  284. struct btd_service *service;
  285. data->source_timer = 0;
  286. data->source_retries++;
  287. service = btd_device_get_service(data->dev, A2DP_SOURCE_UUID);
  288. if (service != NULL)
  289. policy_connect(data, service);
  290. return FALSE;
  291. }
  292. static void policy_set_source_timer(struct policy_data *data)
  293. {
  294. if (data->source_timer > 0)
  295. timeout_remove(data->source_timer);
  296. data->source_timer = timeout_add_seconds(SOURCE_RETRY_TIMEOUT,
  297. policy_connect_source,
  298. data, NULL);
  299. }
  300. static void source_cb(struct btd_service *service,
  301. btd_service_state_t old_state,
  302. btd_service_state_t new_state)
  303. {
  304. struct btd_device *dev = btd_service_get_device(service);
  305. struct policy_data *data;
  306. struct btd_service *target;
  307. target = btd_device_get_service(dev, AVRCP_TARGET_UUID);
  308. if (target == NULL)
  309. return;
  310. data = policy_get_data(dev);
  311. switch (new_state) {
  312. case BTD_SERVICE_STATE_UNAVAILABLE:
  313. if (data->source_timer > 0) {
  314. timeout_remove(data->source_timer);
  315. data->source_timer = 0;
  316. }
  317. break;
  318. case BTD_SERVICE_STATE_DISCONNECTED:
  319. if (old_state == BTD_SERVICE_STATE_CONNECTING) {
  320. int err = btd_service_get_error(service);
  321. if (err == -EAGAIN) {
  322. if (data->source_retries < SOURCE_RETRIES)
  323. policy_set_source_timer(data);
  324. else
  325. data->source_retries = 0;
  326. break;
  327. } else if (data->source_timer > 0) {
  328. timeout_remove(data->source_timer);
  329. data->source_timer = 0;
  330. }
  331. }
  332. if (data->tg_timer > 0) {
  333. timeout_remove(data->tg_timer);
  334. data->tg_timer = 0;
  335. } else if (btd_service_get_state(target) !=
  336. BTD_SERVICE_STATE_DISCONNECTED)
  337. policy_disconnect(data, target);
  338. break;
  339. case BTD_SERVICE_STATE_CONNECTING:
  340. break;
  341. case BTD_SERVICE_STATE_CONNECTED:
  342. if (data->source_timer > 0) {
  343. timeout_remove(data->source_timer);
  344. data->source_timer = 0;
  345. }
  346. /* Check if service initiate the connection then proceed
  347. * immediatelly otherwise set timer
  348. */
  349. if (btd_service_is_initiator(service))
  350. policy_connect(data, target);
  351. else if (btd_service_get_state(target) !=
  352. BTD_SERVICE_STATE_CONNECTED)
  353. policy_set_tg_timer(data, CONTROL_CONNECT_TIMEOUT);
  354. break;
  355. case BTD_SERVICE_STATE_DISCONNECTING:
  356. break;
  357. }
  358. }
  359. static void controller_cb(struct btd_service *service,
  360. btd_service_state_t old_state,
  361. btd_service_state_t new_state)
  362. {
  363. struct btd_device *dev = btd_service_get_device(service);
  364. struct policy_data *data;
  365. data = find_data(dev);
  366. if (data == NULL)
  367. return;
  368. switch (new_state) {
  369. case BTD_SERVICE_STATE_UNAVAILABLE:
  370. if (data->ct_timer > 0) {
  371. timeout_remove(data->ct_timer);
  372. data->ct_timer = 0;
  373. }
  374. break;
  375. case BTD_SERVICE_STATE_DISCONNECTED:
  376. if (old_state == BTD_SERVICE_STATE_CONNECTING) {
  377. int err = btd_service_get_error(service);
  378. if (err == -EAGAIN) {
  379. if (data->ct_retries < CT_RETRIES)
  380. policy_set_ct_timer(data,
  381. CT_RETRY_TIMEOUT);
  382. else
  383. data->ct_retries = 0;
  384. break;
  385. } else if (data->ct_timer > 0) {
  386. timeout_remove(data->ct_timer);
  387. data->ct_timer = 0;
  388. }
  389. } else if (old_state == BTD_SERVICE_STATE_CONNECTED) {
  390. data->ct_retries = 0;
  391. }
  392. break;
  393. case BTD_SERVICE_STATE_CONNECTING:
  394. break;
  395. case BTD_SERVICE_STATE_CONNECTED:
  396. if (data->ct_timer > 0) {
  397. timeout_remove(data->ct_timer);
  398. data->ct_timer = 0;
  399. }
  400. break;
  401. case BTD_SERVICE_STATE_DISCONNECTING:
  402. break;
  403. }
  404. }
  405. static void target_cb(struct btd_service *service,
  406. btd_service_state_t old_state,
  407. btd_service_state_t new_state)
  408. {
  409. struct btd_device *dev = btd_service_get_device(service);
  410. struct policy_data *data;
  411. data = find_data(dev);
  412. if (data == NULL)
  413. return;
  414. switch (new_state) {
  415. case BTD_SERVICE_STATE_UNAVAILABLE:
  416. if (data->tg_timer > 0) {
  417. timeout_remove(data->tg_timer);
  418. data->tg_timer = 0;
  419. }
  420. break;
  421. case BTD_SERVICE_STATE_DISCONNECTED:
  422. if (old_state == BTD_SERVICE_STATE_CONNECTING) {
  423. int err = btd_service_get_error(service);
  424. if (err == -EAGAIN) {
  425. if (data->tg_retries < TG_RETRIES)
  426. policy_set_tg_timer(data,
  427. TG_RETRY_TIMEOUT);
  428. else
  429. data->tg_retries = 0;
  430. break;
  431. } else if (data->tg_timer > 0) {
  432. timeout_remove(data->tg_timer);
  433. data->tg_timer = 0;
  434. }
  435. } else if (old_state == BTD_SERVICE_STATE_CONNECTED) {
  436. data->tg_retries = 0;
  437. }
  438. break;
  439. case BTD_SERVICE_STATE_CONNECTING:
  440. break;
  441. case BTD_SERVICE_STATE_CONNECTED:
  442. if (data->tg_timer > 0) {
  443. timeout_remove(data->tg_timer);
  444. data->tg_timer = 0;
  445. }
  446. break;
  447. case BTD_SERVICE_STATE_DISCONNECTING:
  448. break;
  449. }
  450. }
  451. static void reconnect_reset(struct reconnect_data *reconnect)
  452. {
  453. reconnect->attempt = 0;
  454. reconnect->active = false;
  455. if (reconnect->timer > 0) {
  456. timeout_remove(reconnect->timer);
  457. reconnect->timer = 0;
  458. }
  459. }
  460. static bool reconnect_match(const char *uuid)
  461. {
  462. char **str;
  463. if (!reconnect_uuids)
  464. return false;
  465. for (str = reconnect_uuids; *str; str++) {
  466. if (!bt_uuid_strcmp(uuid, *str))
  467. return true;
  468. }
  469. return false;
  470. }
  471. static struct reconnect_data *reconnect_add(struct btd_service *service)
  472. {
  473. struct btd_device *dev = btd_service_get_device(service);
  474. struct reconnect_data *reconnect;
  475. reconnect = reconnect_find(dev);
  476. if (!reconnect) {
  477. reconnect = g_new0(struct reconnect_data, 1);
  478. reconnect->dev = dev;
  479. reconnects = g_slist_append(reconnects, reconnect);
  480. }
  481. if (g_slist_find(reconnect->services, service))
  482. return reconnect;
  483. reconnect->services = g_slist_append(reconnect->services,
  484. btd_service_ref(service));
  485. return reconnect;
  486. }
  487. static void reconnect_destroy(gpointer data)
  488. {
  489. struct reconnect_data *reconnect = data;
  490. if (reconnect->timer > 0)
  491. timeout_remove(reconnect->timer);
  492. g_slist_free_full(reconnect->services,
  493. (GDestroyNotify) btd_service_unref);
  494. g_free(reconnect);
  495. }
  496. static void reconnect_remove(struct btd_service *service)
  497. {
  498. struct btd_device *dev = btd_service_get_device(service);
  499. struct reconnect_data *reconnect;
  500. GSList *l;
  501. reconnect = reconnect_find(dev);
  502. if (!reconnect)
  503. return;
  504. l = g_slist_find(reconnect->services, service);
  505. if (!l)
  506. return;
  507. reconnect->services = g_slist_delete_link(reconnect->services, l);
  508. btd_service_unref(service);
  509. if (reconnect->services)
  510. return;
  511. reconnects = g_slist_remove(reconnects, reconnect);
  512. if (reconnect->timer > 0)
  513. timeout_remove(reconnect->timer);
  514. g_free(reconnect);
  515. }
  516. static void service_cb(struct btd_service *service,
  517. btd_service_state_t old_state,
  518. btd_service_state_t new_state,
  519. void *user_data)
  520. {
  521. struct btd_profile *profile = btd_service_get_profile(service);
  522. struct reconnect_data *reconnect;
  523. if (g_str_equal(profile->remote_uuid, A2DP_SINK_UUID))
  524. sink_cb(service, old_state, new_state);
  525. else if (g_str_equal(profile->remote_uuid, A2DP_SOURCE_UUID))
  526. source_cb(service, old_state, new_state);
  527. else if (g_str_equal(profile->remote_uuid, AVRCP_REMOTE_UUID))
  528. controller_cb(service, old_state, new_state);
  529. else if (g_str_equal(profile->remote_uuid, AVRCP_TARGET_UUID))
  530. target_cb(service, old_state, new_state);
  531. else if (g_str_equal(profile->remote_uuid, HFP_HS_UUID) ||
  532. g_str_equal(profile->remote_uuid, HSP_HS_UUID))
  533. hs_cb(service, old_state, new_state);
  534. /*
  535. * Return if the reconnection feature is not enabled (all
  536. * subsequent code in this function is about that).
  537. */
  538. if (!reconnect_uuids || !reconnect_uuids[0])
  539. return;
  540. /*
  541. * We're only interested in reconnecting profiles which have set
  542. * auto_connect to true.
  543. */
  544. if (!profile->auto_connect)
  545. return;
  546. /*
  547. * If the service went away remove it from the reconnection
  548. * tracking. The function will remove the entire tracking data
  549. * if this was the last service for the device.
  550. */
  551. if (new_state == BTD_SERVICE_STATE_UNAVAILABLE) {
  552. reconnect_remove(service);
  553. return;
  554. }
  555. if (new_state != BTD_SERVICE_STATE_CONNECTED)
  556. return;
  557. /*
  558. * Add an entry to track reconnections. The function will return
  559. * an existing entry if there is one.
  560. */
  561. reconnect = reconnect_add(service);
  562. reconnect->active = false;
  563. /*
  564. * Should this device be reconnected? A matching UUID might not
  565. * be the first profile that's connected so we might have an
  566. * entry but with the reconnect flag set to false.
  567. */
  568. if (!reconnect->reconnect)
  569. reconnect->reconnect = reconnect_match(profile->remote_uuid);
  570. DBG("Added %s reconnect %u", profile->name, reconnect->reconnect);
  571. }
  572. static bool reconnect_timeout(gpointer data)
  573. {
  574. struct reconnect_data *reconnect = data;
  575. int err;
  576. DBG("Reconnecting profiles");
  577. /* Mark the GSource as invalid */
  578. reconnect->timer = 0;
  579. /* Mark any reconnect on resume as handled */
  580. reconnect->on_resume = false;
  581. err = btd_device_connect_services(reconnect->dev, reconnect->services);
  582. if (err < 0) {
  583. error("Reconnecting services failed: %s (%d)",
  584. strerror(-err), -err);
  585. reconnect_reset(reconnect);
  586. return FALSE;
  587. }
  588. reconnect->attempt++;
  589. return FALSE;
  590. }
  591. static void reconnect_set_timer(struct reconnect_data *reconnect, int timeout)
  592. {
  593. static int interval_timeout = 0;
  594. reconnect->active = true;
  595. if (reconnect->attempt < reconnect_intervals_len)
  596. interval_timeout = reconnect_intervals[reconnect->attempt];
  597. if (timeout < 0)
  598. timeout = interval_timeout;
  599. DBG("attempt %u/%zu %d seconds", reconnect->attempt + 1,
  600. reconnect_attempts, timeout);
  601. reconnect->timer = timeout_add_seconds(timeout, reconnect_timeout,
  602. reconnect, NULL);
  603. }
  604. static void disconnect_cb(struct btd_device *dev, uint8_t reason)
  605. {
  606. struct reconnect_data *reconnect;
  607. DBG("reason %u", reason);
  608. /* Only attempt reconnect for the following reasons */
  609. if (reason != MGMT_DEV_DISCONN_TIMEOUT &&
  610. reason != MGMT_DEV_DISCONN_LOCAL_HOST_SUSPEND)
  611. return;
  612. reconnect = reconnect_find(dev);
  613. if (!reconnect || !reconnect->reconnect)
  614. return;
  615. reconnect_reset(reconnect);
  616. DBG("Device %s identified for auto-reconnection", device_get_path(dev));
  617. switch (reason) {
  618. case MGMT_DEV_DISCONN_LOCAL_HOST_SUSPEND:
  619. if (btd_device_get_service(dev, A2DP_SINK_UUID)) {
  620. DBG("%s configured to reconnect on resume",
  621. device_get_path(dev));
  622. reconnect->on_resume = true;
  623. /* If the kernel supports resume events, it is
  624. * preferable to set the reconnect timer there as it is
  625. * a more predictable delay.
  626. */
  627. if (!btd_has_kernel_features(KERNEL_HAS_RESUME_EVT))
  628. reconnect_set_timer(reconnect, resume_delay);
  629. }
  630. break;
  631. case MGMT_DEV_DISCONN_TIMEOUT:
  632. reconnect_set_timer(reconnect, -1);
  633. break;
  634. default:
  635. DBG("Developer error. Reason = %d", reason);
  636. break;
  637. }
  638. }
  639. static void policy_adapter_resume(struct btd_adapter *adapter)
  640. {
  641. GSList *l;
  642. /* Check if devices on this adapter need to be reconnected on resume */
  643. for (l = reconnects; l; l = g_slist_next(l)) {
  644. struct reconnect_data *reconnect = l->data;
  645. if (reconnect->on_resume &&
  646. device_get_adapter(reconnect->dev) == adapter) {
  647. reconnect_set_timer(reconnect, resume_delay);
  648. }
  649. }
  650. }
  651. static void conn_fail_cb(struct btd_device *dev, uint8_t status)
  652. {
  653. struct reconnect_data *reconnect;
  654. DBG("status %u", status);
  655. reconnect = reconnect_find(dev);
  656. if (!reconnect || !reconnect->reconnect)
  657. return;
  658. if (!reconnect->active)
  659. return;
  660. /* Give up if we were powered off */
  661. if (status == MGMT_STATUS_NOT_POWERED) {
  662. reconnect_reset(reconnect);
  663. return;
  664. }
  665. /* Reset if ReconnectAttempts was reached */
  666. if (reconnect->attempt == reconnect_attempts) {
  667. reconnect_reset(reconnect);
  668. return;
  669. }
  670. reconnect_set_timer(reconnect, -1);
  671. }
  672. static int policy_adapter_probe(struct btd_adapter *adapter)
  673. {
  674. DBG("");
  675. if (auto_enable)
  676. btd_adapter_restore_powered(adapter);
  677. return 0;
  678. }
  679. static struct btd_adapter_driver policy_driver = {
  680. .name = "policy",
  681. .probe = policy_adapter_probe,
  682. .resume = policy_adapter_resume,
  683. };
  684. static int policy_init(void)
  685. {
  686. GError *gerr = NULL;
  687. GKeyFile *conf;
  688. service_id = btd_service_add_state_cb(service_cb, NULL);
  689. conf = btd_get_main_conf();
  690. if (!conf) {
  691. reconnect_uuids = g_strdupv((char **) default_reconnect);
  692. reconnect_attempts = default_attempts;
  693. reconnect_intervals_len = sizeof(default_intervals) /
  694. sizeof(*reconnect_intervals);
  695. reconnect_intervals = g_memdup(default_intervals,
  696. sizeof(default_intervals));
  697. goto done;
  698. }
  699. g_key_file_set_list_separator(conf, ',');
  700. reconnect_uuids = g_key_file_get_string_list(conf, "Policy",
  701. "ReconnectUUIDs",
  702. NULL, &gerr);
  703. if (gerr) {
  704. g_clear_error(&gerr);
  705. reconnect_uuids = g_strdupv((char **) default_reconnect);
  706. }
  707. reconnect_attempts = g_key_file_get_integer(conf, "Policy",
  708. "ReconnectAttempts",
  709. &gerr);
  710. if (gerr) {
  711. g_clear_error(&gerr);
  712. reconnect_attempts = default_attempts;
  713. }
  714. reconnect_intervals = g_key_file_get_integer_list(conf, "Policy",
  715. "ReconnectIntervals",
  716. (size_t *) &reconnect_intervals_len,
  717. &gerr);
  718. if (gerr) {
  719. g_clear_error(&gerr);
  720. reconnect_intervals_len = sizeof(default_intervals) /
  721. sizeof(*reconnect_intervals);
  722. reconnect_intervals = g_memdup(default_intervals,
  723. sizeof(default_intervals));
  724. }
  725. auto_enable = g_key_file_get_boolean(conf, "Policy", "AutoEnable",
  726. NULL);
  727. resume_delay = g_key_file_get_integer(
  728. conf, "Policy", "ResumeDelay", &gerr);
  729. if (gerr) {
  730. g_clear_error(&gerr);
  731. resume_delay = default_resume_delay;
  732. }
  733. done:
  734. if (reconnect_uuids && reconnect_uuids[0] && reconnect_attempts) {
  735. btd_add_disconnect_cb(disconnect_cb);
  736. btd_add_conn_fail_cb(conn_fail_cb);
  737. }
  738. btd_register_adapter_driver(&policy_driver);
  739. return 0;
  740. }
  741. static void policy_exit(void)
  742. {
  743. btd_remove_disconnect_cb(disconnect_cb);
  744. btd_remove_conn_fail_cb(conn_fail_cb);
  745. if (reconnect_uuids)
  746. g_strfreev(reconnect_uuids);
  747. g_free(reconnect_intervals);
  748. g_slist_free_full(reconnects, reconnect_destroy);
  749. g_slist_free_full(devices, policy_remove);
  750. btd_service_remove_state_cb(service_id);
  751. btd_unregister_adapter_driver(&policy_driver);
  752. }
  753. BLUETOOTH_PLUGIN_DEFINE(policy, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
  754. policy_init, policy_exit)