Lines Matching refs:mcl
55 struct mcap_mcl *mcl; /* MCL for this operation */
75 static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
76 static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
77 static void proc_req_active(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
79 static void (*proc_req[])(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len) = {
85 static void mcap_cache_mcl(struct mcap_mcl *mcl);
107 static uint8_t default_mdl_conn_req_cb(struct mcap_mcl *mcl,
124 static void set_default_cb(struct mcap_mcl *mcl)
126 if (!mcl->cb)
127 mcl->cb = g_new0(struct mcap_mdl_cb, 1);
129 mcl->cb->mdl_connected = default_mdl_connected_cb;
130 mcl->cb->mdl_closed = default_mdl_closed_cb;
131 mcl->cb->mdl_deleted = default_mdl_deleted_cb;
132 mcl->cb->mdl_aborted = default_mdl_aborted_cb;
133 mcl->cb->mdl_conn_req = default_mdl_conn_req_cb;
134 mcl->cb->mdl_reconn_req = default_mdl_reconn_req_cb;
169 static gboolean mcap_send_std_opcode(struct mcap_mcl *mcl, void *cmd,
172 if (mcl->state == MCL_IDLE) {
174 "MCL is not connected");
178 if (mcl->req != MCL_AVAILABLE) {
184 if (!(mcl->ctrl & MCAP_CTRL_STD_OP)) {
190 if (mcl->state == MCL_PENDING) {
196 if (mcap_send_data(g_io_channel_unix_get_fd(mcl->cc), cmd, size) < 0) {
202 mcl->lcmd = cmd;
203 mcl->req = MCL_WAITING_RSP;
208 static void update_mcl_state(struct mcap_mcl *mcl)
213 if (mcl->state == MCL_PENDING)
216 for (l = mcl->mdls; l; l = l->next) {
220 mcl->state = MCL_ACTIVE;
225 mcl->state = MCL_CONNECTED;
249 mcap_mcl_unref(mdl->mcl);
277 static void free_mcl_priv_data(struct mcap_mcl *mcl)
279 free_mcap_mdl_op(mcl->priv_data);
280 mcl->priv_data = NULL;
283 static void mcap_notify_error(struct mcap_mcl *mcl, GError *err)
285 struct mcap_mdl_op_cb *con = mcl->priv_data;
290 if (!con || !mcl->lcmd)
293 switch (mcl->lcmd[0]) {
296 l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
298 mcl->mdls = g_slist_remove(mcl->mdls, mdl);
300 update_mcl_state(mcl);
305 l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
307 update_mcl_state(mcl);
311 for (l = mcl->mdls; l; l = l->next) {
317 update_mcl_state(mcl);
322 l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
324 update_mcl_state(mcl);
329 free_mcl_priv_data(mcl);
330 g_free(mcl->lcmd);
331 mcl->lcmd = NULL;
349 static int mcap_send_cmd(struct mcap_mcl *mcl, uint8_t oc, uint8_t rc,
355 if (mcl->cc == NULL)
358 sock = g_io_channel_unix_get_fd(mcl->cc);
374 static struct mcap_mdl *get_mdl(struct mcap_mcl *mcl, uint16_t mdlid)
379 for (l = mcl->mdls; l; l = l->next) {
388 static uint16_t generate_mdlid(struct mcap_mcl *mcl)
390 uint16_t mdlid = mcl->next_mdl;
394 mdl = get_mdl(mcl, mdlid);
396 mcl->next_mdl = (mdlid % MCAP_MDLID_FINAL) + 1;
400 } while (mdlid != mcl->next_mdl);
448 struct mcap_mcl *mcl = data;
452 RELEASE_TIMER(mcl);
457 mcap_notify_error(mcl, gerr);
460 mcl->mi->mcl_disconnected_cb(mcl, mcl->mi->user_data);
461 mcap_cache_mcl(mcl);
466 gboolean mcap_create_mdl(struct mcap_mcl *mcl,
479 id = generate_mdlid(mcl);
487 mdl->mcl = mcap_mcl_ref(mcl);
499 if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_create_mdl_req),
507 mcl->state = MCL_ACTIVE;
508 mcl->priv_data = con;
510 mcl->mdls = g_slist_insert_sorted(mcl->mdls, mcap_mdl_ref(mdl),
512 mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
513 mcl);
524 struct mcap_mcl *mcl = mdl->mcl;
534 if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
547 mcl->state = MCL_ACTIVE;
548 mcl->priv_data = con;
550 mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
551 mcl);
555 static gboolean send_delete_req(struct mcap_mcl *mcl,
563 if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
568 mcl->priv_data = con;
570 mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
571 mcl);
575 gboolean mcap_delete_all_mdls(struct mcap_mcl *mcl,
585 DBG("MCL in state: %d", mcl->state);
586 if (!mcl->mdls) {
592 for (l = mcl->mdls; l; l = l->next) {
605 if (!send_delete_req(mcl, con, MCAP_ALL_MDLIDS, err)) {
618 struct mcap_mcl *mcl= mdl->mcl;
622 l = g_slist_find(mcl->mdls, mdl);
644 if (!send_delete_req(mcl, con, mdl->mdlid, err)) {
659 struct mcap_mcl *mcl = mdl->mcl;
669 if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
680 mcl->priv_data = con;
681 mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
682 mcl);
688 struct mcap_mcl *mcl;
691 mcl = list->data;
693 if (!bacmp(&mcl->addr, addr))
694 return mcl;
716 static void close_mcl(struct mcap_mcl *mcl, gboolean cache_requested)
718 gboolean save = ((!(mcl->ctrl & MCAP_CTRL_FREE)) && cache_requested);
720 RELEASE_TIMER(mcl);
722 if (mcl->cc) {
723 g_io_channel_shutdown(mcl->cc, TRUE, NULL);
724 g_io_channel_unref(mcl->cc);
725 mcl->cc = NULL;
728 if (mcl->wid) {
729 g_source_remove(mcl->wid);
730 mcl->wid = 0;
733 if (mcl->lcmd) {
734 mcl->lcmd);
735 mcl->lcmd = NULL;
738 if (mcl->priv_data)
739 free_mcl_priv_data(mcl);
741 g_slist_foreach(mcl->mdls, (GFunc) shutdown_mdl, NULL);
743 mcap_sync_stop(mcl);
745 mcl->state = MCL_IDLE;
750 g_slist_foreach(mcl->mdls, (GFunc) mcap_mdl_unref, NULL);
751 g_slist_free(mcl->mdls);
752 mcl->mdls = NULL;
755 static void mcap_mcl_shutdown(struct mcap_mcl *mcl)
757 close_mcl(mcl, TRUE);
760 static void mcap_mcl_release(struct mcap_mcl *mcl)
762 close_mcl(mcl, FALSE);
765 static void mcap_cache_mcl(struct mcap_mcl *mcl)
771 if (mcl->ctrl & MCAP_CTRL_CACHED)
774 mcl->mi->mcls = g_slist_remove(mcl->mi->mcls, mcl);
776 if (mcl->ctrl & MCAP_CTRL_NOCACHE) {
777 mcl->mi->cached = g_slist_remove(mcl->mi->cached, mcl);
778 mcap_mcl_release(mcl);
779 mcap_mcl_unref(mcl);
783 DBG("Caching MCL");
785 len = g_slist_length(mcl->mi->cached);
787 /* Remove the latest cached mcl */
788 l = g_slist_last(mcl->mi->cached);
790 mcl->mi->cached = g_slist_remove(mcl->mi->cached, last);
793 /* We have to release this MCL if */
803 mcl->mi->cached = g_slist_prepend(mcl->mi->cached, mcl);
804 mcl->ctrl |= MCAP_CTRL_CACHED;
805 mcap_mcl_shutdown(mcl);
808 static void mcap_uncache_mcl(struct mcap_mcl *mcl)
810 if (!(mcl->ctrl & MCAP_CTRL_CACHED))
813 DBG("Got MCL from cache");
815 mcl->mi->cached = g_slist_remove(mcl->mi->cached, mcl);
816 mcl->mi->mcls = g_slist_prepend(mcl->mi->mcls, mcl);
817 mcl->ctrl &= ~MCAP_CTRL_CACHED;
818 mcl->ctrl &= ~MCAP_CTRL_FREE;
821 void mcap_close_mcl(struct mcap_mcl *mcl, gboolean cache)
823 if (!mcl)
826 if (mcl->ctrl & MCAP_CTRL_FREE) {
827 mcap_mcl_release(mcl);
832 mcl->ctrl |= MCAP_CTRL_NOCACHE;
834 if (mcl->cc) {
835 g_io_channel_shutdown(mcl->cc, TRUE, NULL);
836 g_io_channel_unref(mcl->cc);
837 mcl->cc = NULL;
838 mcl->state = MCL_IDLE;
839 } else if ((mcl->ctrl & MCAP_CTRL_CACHED) &&
840 (mcl->ctrl & MCAP_CTRL_NOCACHE)) {
841 mcl->ctrl &= ~MCAP_CTRL_CACHED;
842 mcl->mi->cached = g_slist_remove(mcl->mi->cached, mcl);
843 mcap_mcl_release(mcl);
844 mcap_mcl_unref(mcl);
848 struct mcap_mcl *mcap_mcl_ref(struct mcap_mcl *mcl)
850 mcl->ref++;
852 DBG("mcap_mcl_ref(%p): ref=%d", mcl, mcl->ref);
854 return mcl;
857 void mcap_mcl_unref(struct mcap_mcl *mcl)
859 mcl->ref--;
861 DBG("mcap_mcl_unref(%p): ref=%d", mcl, mcl->ref);
863 if (mcl->ref > 0)
866 mcap_mcl_release(mcl);
867 mcap_instance_unref(mcl->mi);
868 g_free(mcl->cb);
869 g_free(mcl);
929 gboolean mcap_mcl_set_cb(struct mcap_mcl *mcl, gpointer user_data,
936 ret = parse_set_opts(mcl->cb, gerr, cb1, args);
942 mcl->cb->user_data = user_data;
946 void mcap_mcl_get_addr(struct mcap_mcl *mcl, bdaddr_t *addr)
948 bacpy(addr, &mcl->addr);
958 mdl->mcl->cb->mdl_deleted(mdl, mdl->mcl->cb->user_data);
963 static gboolean check_cmd_req_length(struct mcap_mcl *mcl, void *cmd,
977 mcap_send_cmd(mcl, rspcod, MCAP_INVALID_PARAM_VALUE, mdl_id,
984 static void process_md_create_mdl_req(struct mcap_mcl *mcl, void *cmd,
994 if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_create_mdl_req),
1001 mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_INVALID_MDL,
1008 mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_INVALID_MDEP,
1013 mdl = get_mdl(mcl, mdl_id);
1017 mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_MDL_BUSY,
1024 rsp = mcl->cb->mdl_conn_req(mcl, mdep_id, mdl_id, &conf,
1025 mcl->cb->user_data);
1026 if (mcl->state == MCL_IDLE) {
1027 /* MCL has been closed int the callback */
1033 /* has changed it. Protocol Error: force closing the MCL by */
1035 mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP,
1040 mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, rsp, mdl_id,
1047 mdl->mcl = mcap_mcl_ref(mcl);
1049 mcl->mdls = g_slist_insert_sorted(mcl->mdls, mcap_mdl_ref(mdl),
1052 /* MCAP specification says that we should close the MCL if
1060 mcl->state = MCL_PENDING;
1061 mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_SUCCESS, mdl_id,
1065 static void process_md_reconnect_mdl_req(struct mcap_mcl *mcl, void *cmd,
1073 if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
1080 mdl = get_mdl(mcl, mdl_id);
1082 mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_INVALID_MDL,
1088 mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_MDL_BUSY,
1094 rsp = mcl->cb->mdl_reconn_req(mdl, mcl->cb->user_data);
1095 if (mcl->state == MCL_IDLE)
1099 mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, rsp, mdl_id,
1108 mcl->state = MCL_PENDING;
1109 mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_SUCCESS, mdl_id,
1113 static void process_md_abort_mdl_req(struct mcap_mcl *mcl, void *cmd,
1121 if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
1127 mcl->state = MCL_CONNECTED;
1129 for (l = mcl->mdls; l; l = l->next) {
1133 if (mcl->state != MCL_CONNECTED)
1137 if (mdl->state == MDL_CONNECTED && mcl->state != MCL_ACTIVE)
1138 mcl->state = MCL_ACTIVE;
1140 if (abrt && mcl->state == MCL_ACTIVE)
1145 mcap_send_cmd(mcl, MCAP_MD_ABORT_MDL_RSP, MCAP_INVALID_MDL,
1150 mcl->cb->mdl_aborted(abrt, mcl->cb->user_data);
1152 mcap_send_cmd(mcl, MCAP_MD_ABORT_MDL_RSP, MCAP_SUCCESS, mdl_id,
1156 static void process_md_delete_mdl_req(struct mcap_mcl *mcl, void *cmd,
1165 if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
1173 g_slist_foreach(mcl->mdls, mcap_del_mdl, ¬ify);
1174 g_slist_free(mcl->mdls);
1175 mcl->mdls = NULL;
1176 mcl->state = MCL_CONNECTED;
1178 mcl->cb->mdl_deleted(NULL, mcl->cb->user_data);
1183 mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_INVALID_MDL,
1188 for (l = mcl->mdls, mdl = NULL; l; l = l->next) {
1197 mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_INVALID_MDL,
1202 mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1203 update_mcl_state(mcl);
1208 mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_SUCCESS, mdlid,
1212 static void invalid_req_state(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1217 mcl->state);
1222 mcap_send_cmd(mcl, cmd[0]+1, MCAP_INVALID_OPERATION, mdlr, NULL, 0);
1225 /* Function used to process commands depending of MCL state */
1226 static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1230 process_md_create_mdl_req(mcl, cmd, len);
1233 process_md_reconnect_mdl_req(mcl, cmd, len);
1236 process_md_delete_mdl_req(mcl, cmd, len);
1239 invalid_req_state(mcl, cmd, len);
1243 static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1246 process_md_abort_mdl_req(mcl, cmd, len);
1248 invalid_req_state(mcl, cmd, len);
1251 static void proc_req_active(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1255 process_md_create_mdl_req(mcl, cmd, len);
1258 process_md_reconnect_mdl_req(mcl, cmd, len);
1261 process_md_delete_mdl_req(mcl, cmd, len);
1264 invalid_req_state(mcl, cmd, len);
1269 static gboolean check_err_rsp(struct mcap_mcl *mcl, mcap_rsp *rsp,
1272 mcap_md_req *cmdlast = (mcap_md_req *) mcl->lcmd;
1284 if (rlen < sizeof(mcap_rsp) || (mcl->lcmd[0] + 1) != rsp->op) {
1304 mcl->ctrl &= ~MCAP_CTRL_STD_OP;
1327 static gboolean process_md_create_mdl_rsp(struct mcap_mcl *mcl,
1330 mcap_md_create_mdl_req *cmdlast = (mcap_md_create_mdl_req *) mcl->lcmd;
1331 struct mcap_mdl_op_cb *conn = mcl->priv_data;
1339 close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp) + 1, &gerr);
1340 g_free(mcl->lcmd);
1341 mcl->lcmd = NULL;
1342 mcl->req = MCL_AVAILABLE;
1360 mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1363 update_mcl_state(mcl);
1367 static gboolean process_md_reconnect_mdl_rsp(struct mcap_mcl *mcl,
1370 struct mcap_mdl_op_cb *reconn = mcl->priv_data;
1377 close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);
1379 g_free(mcl->lcmd);
1380 mcl->lcmd = NULL;
1381 mcl->req = MCL_AVAILABLE;
1389 update_mcl_state(mcl);
1395 mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1396 mcl->cb->mdl_deleted(mdl, mcl->cb->user_data);
1402 static gboolean process_md_abort_mdl_rsp(struct mcap_mcl *mcl,
1405 struct mcap_mdl_op_cb *abrt = mcl->priv_data;
1412 close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);
1414 g_free(mcl->lcmd);
1415 mcl->lcmd = NULL;
1416 mcl->req = MCL_AVAILABLE;
1422 mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1423 mcl->cb->mdl_deleted(mdl, mcl->cb->user_data);
1430 update_mcl_state(mcl);
1445 mdl->mcl->cb->mdl_closed(mdl, mdl->mcl->cb->user_data);
1456 mdl->mcl->mdls = g_slist_remove(mdl->mcl->mdls, mdl);
1460 static gboolean process_md_delete_mdl_rsp(struct mcap_mcl *mcl, mcap_rsp *rsp,
1463 struct mcap_mdl_op_cb *del = mcl->priv_data;
1467 mcap_md_req *cmdlast = (mcap_md_req *) mcl->lcmd;
1473 close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);
1475 g_free(mcl->lcmd);
1476 mcl->lcmd = NULL;
1477 mcl->req = MCL_AVAILABLE;
1483 g_slist_foreach(mcl->mdls, restore_mdl, NULL);
1490 g_slist_foreach(mcl->mdls, mcap_del_mdl, ¬ify);
1491 g_slist_free(mcl->mdls);
1492 mcl->mdls = NULL;
1493 mcl->state = MCL_CONNECTED;
1495 mcl->mdls = g_slist_remove(mcl->mdls, mdl);
1496 update_mcl_state(mcl);
1505 static void post_process_rsp(struct mcap_mcl *mcl, struct mcap_mdl_op_cb *op)
1507 if (mcl->priv_data != op) {
1509 /* We should not delete the mcl private data */
1513 /* delete the mcl private data here. */
1514 free_mcl_priv_data(mcl);
1518 static void proc_response(struct mcap_mcl *mcl, void *buf, uint32_t len)
1520 struct mcap_mdl_op_cb *op = mcl->priv_data;
1524 RELEASE_TIMER(mcl);
1526 switch (mcl->lcmd[0] + 1) {
1528 close = process_md_create_mdl_rsp(mcl, rsp, len);
1529 post_process_rsp(mcl, op);
1532 close = process_md_reconnect_mdl_rsp(mcl, rsp, len);
1533 post_process_rsp(mcl, op);
1536 close = process_md_abort_mdl_rsp(mcl, rsp, len);
1537 post_process_rsp(mcl, op);
1540 close = process_md_delete_mdl_rsp(mcl, rsp, len);
1541 post_process_rsp(mcl, op);
1550 mcl->mi->mcl_disconnected_cb(mcl, mcl->mi->user_data);
1551 mcap_cache_mcl(mcl);
1555 static void proc_cmd(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
1563 mcap_send_cmd(mcl, MCAP_ERROR_RSP, MCAP_INVALID_OP_CODE,
1570 proc_sync_cmd(mcl, cmd, len);
1574 if (!(mcl->ctrl & MCAP_CTRL_STD_OP)) {
1580 if (mcl->req == MCL_WAITING_RSP) {
1583 if (mcl->role == MCL_INITIATOR)
1587 RELEASE_TIMER(mcl);
1588 mcl->req = MCL_AVAILABLE;
1591 mcap_notify_error(mcl, gerr);
1592 proc_req[mcl->state](mcl, cmd, len);
1595 proc_response(mcl, cmd, len);
1597 proc_req[mcl->state](mcl, cmd, len);
1611 update_mcl_state(mdl->mcl);
1615 mdl->mcl->cb->mdl_closed(mdl, mdl->mcl->cb->user_data);
1679 BT_IO_OPT_SOURCE_BDADDR, &mdl->mcl->mi->src,
1680 BT_IO_OPT_DEST_BDADDR, &mdl->mcl->addr,
1683 BT_IO_OPT_SEC_LEVEL, mdl->mcl->mi->sec,
1701 struct mcap_mcl *mcl = data;
1713 proc_cmd(mcl, buf, (uint32_t) len);
1717 if (mcl->state != MCL_IDLE) {
1718 if (mcl->req == MCL_WAITING_RSP) {
1721 "MCL closed");
1722 mcap_notify_error(mcl, gerr);
1725 mcl->mi->mcl_disconnected_cb(mcl, mcl->mi->user_data);
1727 mcap_cache_mcl(mcl);
1736 struct mcap_mcl *aux, *mcl = con->mcl;
1741 mcl->ctrl &= ~MCAP_CTRL_CONN;
1744 if (mcl->ctrl & MCAP_CTRL_FREE) {
1745 mcap_mcl_release(mcl);
1746 mcl->mi->mcl_uncached_cb(mcl, mcl->mi->user_data);
1752 ba2str(&mcl->addr, dstaddr);
1754 aux = find_mcl(mcl->mi->mcls, &mcl->addr);
1756 /* Double MCL connection case */
1757 error("MCL error: Device %s is already connected", dstaddr);
1759 "MCL %s is already connected", dstaddr);
1765 mcl->state = MCL_CONNECTED;
1766 mcl->role = MCL_INITIATOR;
1767 mcl->req = MCL_AVAILABLE;
1768 mcl->ctrl |= MCAP_CTRL_STD_OP;
1770 mcap_sync_init(mcl);
1772 if (mcl->ctrl & MCAP_CTRL_CACHED)
1773 mcap_uncache_mcl(mcl);
1775 mcl->ctrl &= ~MCAP_CTRL_FREE;
1776 mcl->mi->mcls = g_slist_prepend(mcl->mi->mcls,
1777 mcap_mcl_ref(mcl));
1780 mcl->wid = g_io_add_watch_full(mcl->cc, G_PRIORITY_DEFAULT,
1783 mcap_mcl_ref(mcl),
1785 connect_cb(mcl, gerr, data);
1790 struct mcap_mcl *mcl = mdl->mcl;
1800 mcl->state = MCL_ACTIVE;
1801 mcl->cb->mdl_connected(mdl, mcl->cb->user_data);
1808 mcap_mcl_unref(con->mcl);
1822 struct mcap_mcl *mcl;
1825 mcl = find_mcl(mi->mcls, addr);
1826 if (mcl) {
1828 "MCL is already connected.");
1832 mcl = find_mcl(mi->cached, addr);
1833 if (!mcl) {
1834 mcl = g_new0(struct mcap_mcl, 1);
1835 mcl->mi = mcap_instance_ref(mi);
1836 mcl->state = MCL_IDLE;
1837 bacpy(&mcl->addr, addr);
1838 set_default_cb(mcl);
1839 mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
1842 mcl->ctrl |= MCAP_CTRL_CONN;
1845 con->mcl = mcap_mcl_ref(mcl);
1850 mcl->cc = bt_io_connect(BT_IO_L2CAP, mcap_connect_mcl_cb, con,
1859 if (!mcl->cc) {
1860 mcl->ctrl &= ~MCAP_CTRL_CONN;
1861 if (mcl->ctrl & MCAP_CTRL_FREE) {
1862 mcap_mcl_release(mcl);
1863 mcl->mi->mcl_uncached_cb(mcl, mcl->mi->user_data);
1865 mcap_mcl_unref(con->mcl);
1877 struct mcap_mcl *mcl;
1895 mcl = find_mcl(mi->mcls, &dst);
1896 if (!mcl || mcl->state != MCL_PENDING)
1899 for (l = mcl->mdls; l; l = l->next) {
1911 static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl)
1915 mcl->state = MCL_CONNECTED;
1916 mcl->role = MCL_ACCEPTOR;
1917 mcl->req = MCL_AVAILABLE;
1918 mcl->cc = g_io_channel_ref(chan);
1919 mcl->ctrl |= MCAP_CTRL_STD_OP;
1921 mcap_sync_init(mcl);
1923 reconn = (mcl->ctrl & MCAP_CTRL_CACHED);
1925 mcap_uncache_mcl(mcl);
1927 mcl->mi->mcls = g_slist_prepend(mcl->mi->mcls,
1928 mcap_mcl_ref(mcl));
1930 mcl->wid = g_io_add_watch_full(mcl->cc, G_PRIORITY_DEFAULT,
1933 mcap_mcl_ref(mcl),
1936 /* Callback to report new MCL */
1938 mcl->mi->mcl_reconnected_cb(mcl, mcl->mi->user_data);
1940 mcl->mi->mcl_connected_cb(mcl, mcl->mi->user_data);
1947 struct mcap_mcl *mcl;
1966 mcl = find_mcl(mi->mcls, &dst);
1967 if (mcl) {
1973 mcl = find_mcl(mi->cached, &dst);
1974 if (!mcl) {
1975 mcl = g_new0(struct mcap_mcl, 1);
1976 mcl->mi = mcap_instance_ref(mi);
1977 bacpy(&mcl->addr, &dst);
1978 set_default_cb(mcl);
1979 mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
1982 set_mcl_conf(chan, mcl);