void threaded_listener::process_item(queue_item_type &item) { try { if (!item.notify_guard) { notify_disconnected(item.to); } else if (item.for_open) { if (item.notify_guard->open()) { // open once try { notify_connection_opened(item.to, item.id); item.notify_guard->commit(); // allow notify close for next event } catch (...) { item.notify_guard->cancel(); // disallow notify close for next event data_.notify_connection_opened_failed(item.to, item.id); } } } else if (item.notify_guard->close()) { // close once (if not canceled) notify_connection_closed(item.to, item.id); } } catch (...) { } }
void threaded_listener::thread_func() { queue_item_type item; while (items_.pop(item)) { data_type const &dt = item.first; if (item.second) { notify_connection_opened(dt.first, dt.second); } else if (dt.second) { notify_connection_closed(dt.first, dt.second); } else { notify_disconnected(dt.first); } } }
void on_nble_gap_disconnect_evt(const struct nble_gap_disconnect_evt *ev) { struct bt_conn *conn; conn = bt_conn_lookup_handle(ev->conn_handle); if (!conn) { BT_ERR("Unable to find conn for handle %u", ev->conn_handle); return; } BT_DBG("conn %p handle %u", conn, ev->conn_handle); conn->state = BT_CONN_DISCONNECTED; notify_disconnected(conn); /* Drop the reference given by lookup_handle() */ bt_conn_unref(conn); /* Drop the initial reference from conn_new() */ bt_conn_unref(conn); }
void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) { bt_conn_state_t old_state; BT_DBG("%s -> %s", state2str(conn->state), state2str(state)); if (conn->state == state) { BT_WARN("no transition"); return; } old_state = conn->state; conn->state = state; /* Actions needed for exiting the old state */ switch (old_state) { case BT_CONN_DISCONNECTED: /* Take a reference for the first state transition after * bt_conn_add_le() and keep it until reaching DISCONNECTED * again. */ bt_conn_ref(conn); break; case BT_CONN_CONNECT: if (conn->timeout) { fiber_delayed_start_cancel(conn->timeout); conn->timeout = NULL; /* Drop the reference taken by timeout fiber */ bt_conn_unref(conn); } break; default: break; } /* Actions needed for entering the new state */ switch (conn->state) { case BT_CONN_CONNECTED: nano_fifo_init(&conn->tx_queue); fiber_start(conn->stack, sizeof(conn->stack), conn_tx_fiber, (int)bt_conn_ref(conn), 0, 7, 0); bt_l2cap_connected(conn); notify_connected(conn); break; case BT_CONN_DISCONNECTED: /* Notify disconnection and queue a dummy buffer to wake * up and stop the tx fiber for states where it was * running. */ if (old_state == BT_CONN_CONNECTED || old_state == BT_CONN_DISCONNECT) { bt_l2cap_disconnected(conn); notify_disconnected(conn); nano_fifo_put(&conn->tx_queue, net_buf_get(&dummy, 0)); } else if (old_state == BT_CONN_CONNECT) { /* conn->err will be set in this case */ notify_connected(conn); } else if (old_state == BT_CONN_CONNECT_SCAN && conn->err) { /* this indicate LE Create Connection failed */ notify_connected(conn); } /* Release the reference we took for the very first * state transition. */ bt_conn_unref(conn); break; case BT_CONN_CONNECT_SCAN: break; case BT_CONN_CONNECT: /* * Timer is needed only for LE. For other link types controller * will handle connection timeout. */ if (conn->type != BT_CONN_TYPE_LE) { break; } /* Add LE Create Connection timeout */ conn->timeout = fiber_delayed_start(conn->stack, sizeof(conn->stack), timeout_fiber, (int)bt_conn_ref(conn), 0, 7, 0, CONN_TIMEOUT); break; case BT_CONN_DISCONNECT: break; default: BT_WARN("no valid (%u) state was set", state); break; } }