int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm, GIOChannel *io) { struct input_device *idev = find_device(src, dst); struct input_conn *iconn; if (!idev) return -ENOENT; iconn = find_connection(idev->connections, "hid"); if (!iconn) return -ENOENT; switch (psm) { case L2CAP_PSM_HIDP_CTRL: if (iconn->ctrl_io) return -EALREADY; iconn->ctrl_io = g_io_channel_ref(io); break; case L2CAP_PSM_HIDP_INTR: if (iconn->intr_io) return -EALREADY; iconn->intr_io = g_io_channel_ref(io); break; } if (iconn->intr_io && iconn->ctrl_io) input_device_connadd(idev, iconn); return 0; }
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm, GIOChannel *io) { struct input_device *idev = find_device(src, dst); DBG("idev %p psm %d", idev, psm); if (!idev) return -ENOENT; switch (psm) { case L2CAP_PSM_HIDP_CTRL: if (idev->ctrl_io) return -EALREADY; idev->ctrl_io = g_io_channel_ref(io); idev->ctrl_watch = g_io_add_watch(idev->ctrl_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL, ctrl_watch_cb, idev); break; case L2CAP_PSM_HIDP_INTR: if (idev->intr_io) return -EALREADY; idev->intr_io = g_io_channel_ref(io); idev->intr_watch = g_io_add_watch(idev->intr_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL, intr_watch_cb, idev); break; } if (idev->intr_io && idev->ctrl_io) input_device_connadd(idev); return 0; }
static guint g_io_win32_msg_add_watch (GIOChannel *channel, gint priority, GIOCondition condition, GIOFunc func, gpointer user_data, GDestroyNotify notify) { GIOWin32Watch *watch = g_new (GIOWin32Watch, 1); GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; watch->channel = channel; g_io_channel_ref (channel); watch->callback = func; watch->condition = condition; watch->pollfd.fd = G_WIN32_MSG_HANDLE; watch->pollfd.events = condition; g_main_add_poll (&watch->pollfd, priority); return g_source_add (priority, TRUE, &win32_watch_msg_funcs, watch, user_data, notify); }
static void confirm_cb(GIOChannel *io, gpointer user_data) { struct dun_server *server = user_data; struct dun_client *client = &server->client; GError *err = NULL; if (client->io) { error("Rejecting DUN connection since one already exists"); return; } bt_io_get(io, BT_IO_RFCOMM, &err, BT_IO_OPT_DEST_BDADDR, &client->bda, BT_IO_OPT_INVALID); if (err != NULL) { error("Unable to get DUN source and dest address: %s", err->message); g_error_free(err); return; } if (btd_request_authorization(&server->bda, &client->bda, DUN_UUID, auth_cb, user_data) < 0) { error("Requesting DUN authorization failed"); return; } client->io_watch = g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) auth_watch, server); client->io = g_io_channel_ref(io); }
static GSource *channel_create_watch(GIOChannel *channel, GIOCondition condition) { GSource *source; GAtMuxWatch *watch; GAtMuxChannel *dlc = (GAtMuxChannel *) channel; GAtMux *mux = dlc->mux; source = g_source_new(&watch_funcs, sizeof(GAtMuxWatch)); watch = (GAtMuxWatch *) source; watch->channel = channel; g_io_channel_ref(channel); watch->condition = condition; if ((watch->condition & G_IO_OUT) && dlc->throttled == FALSE) wakeup_writer(mux); debug(mux, "creating source: %p, channel: %p, writer: %d, reader: %d", watch, channel, condition & G_IO_OUT, condition & G_IO_IN); dlc->sources = g_slist_prepend(dlc->sources, watch); return source; }
static void mux_setup_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct mux_setup_data *msd = user_data; GIOFlags flags; GIOChannel *channel; GAtMux *mux = NULL; if (!ok) goto error; channel = g_at_chat_get_channel(msd->chat); channel = g_io_channel_ref(channel); g_at_chat_unref(msd->chat); msd->chat = NULL; flags = g_io_channel_get_flags(channel) | G_IO_FLAG_NONBLOCK; g_io_channel_set_flags(channel, flags, NULL); g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_buffered(channel, FALSE); if (msd->mode == 0) mux = g_at_mux_new_gsm0710_basic(channel, msd->frame_size); else mux = g_at_mux_new_gsm0710_advanced(channel, msd->frame_size); g_io_channel_unref(channel); error: msd->func(mux, msd->user); if (msd->destroy) msd->destroy(msd->user); }
static gboolean obtain_send_channel_cb(GIOChannel *channel, GIOCondition condition, G_GNUC_UNUSED gpointer gdata) { #if HAS_SPAWN_LEAVE_STDIN_OPEN if (condition & G_IO_FAILURE) g_io_channel_shutdown(channel, FALSE, NULL); else { g_io_channel_ref(channel); send_channel = channel; create_send_source(); /* for the initialization commands */ } #else if (!(condition & G_IO_FAILURE)) { gint stdin_fd = dup(g_io_channel_unix_get_fd(channel)); #ifdef G_OS_UNIX send_channel = g_io_channel_unix_new(stdin_fd); g_io_channel_set_flags(send_channel, G_IO_FLAG_NONBLOCK, NULL); #else send_channel = g_io_channel_win32_new_fd(stdin_fd); #endif g_io_channel_set_encoding(send_channel, NULL, NULL); g_io_channel_set_buffered(send_channel, FALSE); create_send_source(); /* for the initialization commands */ } #endif return FALSE; }
static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct bt_sco *sco = user_data; DBG(""); /* Lets unref connecting io */ if (sco->io) { g_io_channel_unref(sco->io); sco->io = NULL; } if (err) { error("sco: Audio connect failed (%s)", err->message); /* * Connect_sco_cb is called only when connect_cb is in place * Therefore it is safe to call it */ sco->connect_cb(SCO_STATUS_ERROR, &sco->remote_addr); clear_remote_address(sco); return; } g_io_channel_set_close_on_unref(chan, TRUE); sco->io = g_io_channel_ref(chan); sco->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, disconnect_watch, sco); /* It is safe to call it here */ sco->connect_cb(SCO_STATUS_OK, &sco->remote_addr); }
GAttrib *g_attrib_new(GIOChannel *io) { struct _GAttrib *attrib; uint16_t omtu; g_io_channel_set_encoding(io, NULL, NULL); g_io_channel_set_buffered(io, FALSE); attrib = g_try_new0(struct _GAttrib, 1); if (attrib == NULL) return NULL; attrib->io = g_io_channel_ref(io); attrib->queue = g_queue_new(); attrib->read_watch = g_io_add_watch(attrib->io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, received_data, attrib); if (bt_io_get(attrib->io, BT_IO_L2CAP, NULL, BT_IO_OPT_OMTU, &omtu, BT_IO_OPT_INVALID)) { if (omtu == 0 || omtu > ATT_MAX_MTU) omtu = ATT_MAX_MTU; } else omtu = ATT_DEFAULT_LE_MTU; attrib->buf = g_malloc0(omtu); attrib->buflen = omtu; return g_attrib_ref(attrib); }
static GSource * g_io_unix_create_watch (GIOChannel *channel, GIOCondition condition) { GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; GSource *source; GIOUnixWatch *watch; source = g_source_new (&g_io_watch_funcs, sizeof (GIOUnixWatch)); g_source_set_name (source, "GIOChannel (Unix)"); watch = (GIOUnixWatch *)source; watch->channel = channel; g_io_channel_ref (channel); watch->condition = condition; watch->pollfd.fd = unix_channel->fd; watch->pollfd.events = condition; g_source_add_poll (source, &watch->pollfd); return source; }
int _gpgme_io_dup (int fd) { int newfd; GIOChannel *chan; TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_dup", fd); if (fd < 0 || fd >= MAX_SLAFD || !giochannel_table[fd].used) { errno = EINVAL; return TRACE_SYSRES (-1); } for (newfd = 0; newfd < MAX_SLAFD; newfd++) if (! giochannel_table[newfd].used) break; if (newfd == MAX_SLAFD) { errno = EIO; return TRACE_SYSRES (-1); } chan = giochannel_table[fd].chan; g_io_channel_ref (chan); giochannel_table[newfd].used = 1; giochannel_table[newfd].chan = chan; giochannel_table[newfd].fd = -1; giochannel_table[newfd].socket = INVALID_SOCKET; giochannel_table[newfd].primary = 0; return TRACE_SYSRES (newfd); }
static GSource *g_io_gnutls_create_watch(GIOChannel *channel, GIOCondition condition) { GIOGnuTLSChannel *gnutls_channel = (GIOGnuTLSChannel *) channel; GIOGnuTLSWatch *watch; GSource *source; DBG("channel %p condition %u", channel, condition); source = g_source_new(&gnutls_watch_funcs, sizeof(GIOGnuTLSWatch)); watch = (GIOGnuTLSWatch *) source; watch->channel = channel; g_io_channel_ref(channel); watch->condition = condition; watch->pollfd.fd = gnutls_channel->fd; watch->pollfd.events = condition; g_source_add_poll(source, &watch->pollfd); return source; }
static guint g_io_win32_fd_add_watch (GIOChannel *channel, gint priority, GIOCondition condition, GIOFunc func, gpointer user_data, GDestroyNotify notify) { GIOWin32Watch *watch = g_new (GIOWin32Watch, 1); GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; watch->channel = channel; g_io_channel_ref (channel); watch->callback = func; watch->condition = condition; /* This probably does not work, except for CONIN$. */ watch->pollfd.fd = _get_osfhandle (win32_channel->fd); watch->pollfd.events = condition; g_main_add_poll (&watch->pollfd, priority); return g_source_add (priority, TRUE, &win32_watch_fd_funcs, watch, user_data, notify); }
int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io) { if (!io) return -EINVAL; dev->gateway->rfcomm = g_io_channel_ref(io); return 0; }
static void connect_confirm_cb(GIOChannel *io, gpointer data) { struct sap_server *server = data; struct sap_connection *conn = server->conn; GError *gerr = NULL; bdaddr_t src, dst; char dstaddr[18]; int err; DBG("conn %p io %p", conn, io); if (!io) return; if (conn) { DBG("Another SAP connection already exists."); g_io_channel_shutdown(io, TRUE, NULL); return; } conn = g_try_new0(struct sap_connection, 1); if (!conn) { error("Can't allocate memory for incoming SAP connection."); g_io_channel_shutdown(io, TRUE, NULL); return; } g_io_channel_set_encoding(io, NULL, NULL); g_io_channel_set_buffered(io, FALSE); server->conn = conn; conn->io = g_io_channel_ref(io); conn->state = SAP_STATE_DISCONNECTED; bt_io_get(io, BT_IO_RFCOMM, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_INVALID); if (gerr) { error("%s", gerr->message); g_error_free(gerr); sap_server_remove_conn(server); return; } ba2str(&dst, dstaddr); err = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb, server); if (err < 0) { error("Authorization failure (err %d)", err); sap_server_remove_conn(server); return; } DBG("Authorizing incoming SAP connection from %s", dstaddr); }
static void avctp_confirm_cb(GIOChannel *chan, gpointer data) { struct control *control = NULL; struct audio_device *dev; char address[18]; bdaddr_t src, dst; GError *err = NULL; bt_io_get(chan, BT_IO_L2CAP, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); g_io_channel_shutdown(chan, TRUE, NULL); return; } dev = manager_get_device(&src, &dst, TRUE); if (!dev) { error("Unable to get audio device object for %s", address); goto drop; } if (!dev->control) { btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID); if (!dev->control) goto drop; } control = dev->control; if (control->io) { error("Refusing unexpected connect from %s", address); goto drop; } avctp_set_state(control, AVCTP_STATE_CONNECTING); control->io = g_io_channel_ref(chan); if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID, auth_cb, dev->control) < 0) goto drop; control->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, control_cb, control); return; drop: if (!control || !control->io) g_io_channel_shutdown(chan, TRUE, NULL); if (control) avctp_set_state(control, AVCTP_STATE_DISCONNECTED); }
static void confirm_event(GIOChannel *chan, gpointer user_data) { struct network_adapter *na = user_data; struct network_server *ns; int perr; bdaddr_t src, dst; char address[18]; GError *err = NULL; bt_io_get(chan, BT_IO_L2CAP, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); goto drop; } DBG("BNEP: incoming connect from %s", address); if (na->setup) { error("Refusing connect from %s: setup in progress", address); goto drop; } ns = find_server(na->servers, BNEP_SVC_NAP); if (!ns) goto drop; if (!ns->record_id) goto drop; if (!ns->bridge) goto drop; na->setup = g_new0(struct network_session, 1); bacpy(&na->setup->dst, &dst); na->setup->io = g_io_channel_ref(chan); perr = btd_request_authorization(&src, &dst, BNEP_SVC_UUID, auth_cb, na); if (perr < 0) { error("Refusing connect from %s: %s (%d)", address, strerror(-perr), -perr); setup_destroy(na); goto drop; } return; drop: g_io_channel_shutdown(chan, TRUE, NULL); }
int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io) { if (!io) return -EINVAL; dev->gateway->rfcomm = g_io_channel_ref(io); change_state(dev, GATEWAY_STATE_CONNECTING); return 0; }
static void ctrl_confirm_event_cb(GIOChannel *chan, gpointer user_data) { struct input_server *server = user_data; bdaddr_t src, dst; GError *err = NULL; struct btd_device *device = NULL; DBG(""); bt_io_get(chan, BT_IO_L2CAP, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); goto drop; } device = device_for_connection(&src, &dst); if (!device) { DBG("No device."); goto drop; } if (device_has_service_records(device)) { DBG("Device has service records"); server->pending_accept.chan = chan; if (server_accept(server)) return; DBG("Accept failed"); goto drop; } if (server->pending_accept.timer) { DBG("Accept already pending."); goto drop; } DBG("Device has no service records, pending accept."); server->pending_accept.chan = chan; g_io_channel_ref(server->pending_accept.chan); server->pending_accept.retries = 0; server->pending_accept.src = src; server->pending_accept.dst = dst; server->pending_accept.timer = g_timeout_add_seconds(1, retry_server_accept, server); return; drop: g_io_channel_shutdown(chan, TRUE, NULL); }
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm, GIOChannel *io) { struct input_device *idev = find_device(src, dst); struct input_conn *iconn; char sstr[18], dstr[18]; ba2str(src, sstr); ba2str(dst, dstr); DBG("src %s, dst %s", sstr, dstr); DBG("idev %p", idev); if (!idev) return -ENOENT; iconn = find_connection(idev->connections, HID_UUID); if (!iconn) return -ENOENT; switch (psm) { case L2CAP_PSM_HIDP_CTRL: if (iconn->ctrl_io) return -EALREADY; iconn->ctrl_io = g_io_channel_ref(io); break; case L2CAP_PSM_HIDP_INTR: if (iconn->intr_io) return -EALREADY; iconn->intr_io = g_io_channel_ref(io); break; } if (iconn->intr_io && iconn->ctrl_io) input_device_connadd(idev, iconn); return 0; }
static struct avctp_channel *avctp_channel_create(struct avctp *session, GIOChannel *io, GDestroyNotify destroy) { struct avctp_channel *chan; chan = g_new0(struct avctp_channel, 1); chan->session = session; chan->io = g_io_channel_ref(io); chan->queue = g_queue_new(); chan->destroy = destroy; return chan; }
static void confirm_cb(GIOChannel *io, gpointer user_data) { char addr[18]; struct io_data *data = user_data; GError *err = NULL; if (!bt_io_get(io, &err, BT_IO_OPT_DEST, addr, BT_IO_OPT_INVALID)) { printf("bt_io_get(OPT_DEST): %s\n", err->message); g_clear_error(&err); } else printf("Got confirmation request for %s\n", addr); if (data->accept < 0 && data->reject < 0) return; if (data->reject == 0) { printf("Rejecting connection\n"); g_io_channel_shutdown(io, TRUE, NULL); return; } if (data->voice) { if (!bt_io_set(io, &err, BT_IO_OPT_VOICE, data->voice, BT_IO_OPT_INVALID)) { printf("bt_io_set(OPT_VOICE): %s\n", err->message); g_clear_error(&err); } } data->io = g_io_channel_ref(io); io_data_ref(data); if (data->accept == 0) { if (!bt_io_accept(io, connect_cb, data, (GDestroyNotify) io_data_unref, &err)) { printf("bt_io_accept() failed: %s\n", err->message); g_clear_error(&err); io_data_unref(data); return; } } else { int seconds = (data->reject > 0) ? data->reject : data->accept; g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, seconds, confirm_timeout, data, (GDestroyNotify) io_data_unref); } }
static struct ext_io *create_conn(struct ext_io *server, GIOChannel *io) { struct ext_io *conn; GIOCondition cond; conn = g_new0(struct ext_io, 1); conn->io = g_io_channel_ref(io); conn->proto = server->proto; conn->ext = server->ext; cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL; conn->io_id = g_io_add_watch(io, cond, ext_io_disconnected, conn); return conn; }
int fake_hid_connadd(struct fake_input *fake, GIOChannel *intr_io, struct fake_hid *fake_hid) { if (fake_hid->setup_uinput(fake, fake_hid)) { error("Error setting up uinput"); return ENOMEM; } fake->io = g_io_channel_ref(intr_io); g_io_channel_set_close_on_unref(fake->io, TRUE); g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) fake_hid->event, fake); return 0; }
GAttrib *g_attrib_new(GIOChannel *io, guint16 mtu, bool ext_signed) { gint fd; GAttrib *attr; if (!io) return NULL; fd = g_io_channel_unix_get_fd(io); attr = new0(GAttrib, 1); if (!attr) return NULL; g_io_channel_ref(io); attr->io = io; attr->att = bt_att_new(fd, ext_signed); if (!attr->att) goto fail; bt_att_set_close_on_unref(attr->att, true); g_io_channel_set_close_on_unref(io, FALSE); if (!bt_att_set_mtu(attr->att, mtu)) goto fail; attr->buf = malloc0(mtu); attr->buflen = mtu; if (!attr->buf) goto fail; attr->callbacks = queue_new(); if (!attr->callbacks) goto fail; attr->track_ids = queue_new(); if (!attr->track_ids) goto fail; return g_attrib_ref(attr); fail: free(attr->buf); bt_att_unref(attr->att); g_io_channel_unref(io); free(attr); return NULL; }
static void confirm_event_cb(GIOChannel *chan, gpointer user_data) { struct input_server *server = user_data; bdaddr_t src, dst; GError *err = NULL; char addr[18]; guint ret; DBG(""); bt_io_get(chan, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); goto drop; } ba2str(&dst, addr); if (server->confirm) { error("Refusing connection from %s: setup in progress", addr); goto drop; } if (!input_device_exists(&src, &dst) && !dev_is_sixaxis(&src, &dst)) { error("Refusing connection from %s: unknown device", addr); goto drop; } server->confirm = g_io_channel_ref(chan); ret = btd_request_authorization(&src, &dst, HID_UUID, auth_callback, server); if (ret != 0) return; error("input: authorization for device %s failed", addr); g_io_channel_unref(server->confirm); server->confirm = NULL; drop: input_device_close_channels(&src, &dst); g_io_channel_shutdown(chan, TRUE, NULL); }
int gateway_connect_sco(struct audio_device *dev, GIOChannel *io) { struct gateway *gw = dev->gateway; if (gw->sco) return -EISCONN; gw->sco = g_io_channel_ref(io); gw->sco_id = g_io_add_watch(gw->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) sco_io_cb, dev); change_state(dev, GATEWAY_STATE_PLAYING); return 0; }
static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) { DBusConnection *conn = btd_get_dbus_connection(); struct audio_device *dev = user_data; struct gateway *gw = dev->gateway; DBusMessage *reply; int sk, ret; if (err) { error("connect(): %s", err->message); goto fail; } if (!gw->agent) { error("Handsfree Agent not registered"); goto fail; } sk = g_io_channel_unix_get_fd(chan); if (gw->rfcomm == NULL) gw->rfcomm = g_io_channel_ref(chan); ret = agent_sendfd(gw->agent, sk, newconnection_reply, dev); if (!gw->msg) return; if (ret) reply = dbus_message_new_method_return(gw->msg); else reply = btd_error_failed(gw->msg, "Can't pass file descriptor"); g_dbus_send_message(conn, reply); return; fail: if (gw->msg) { DBusMessage *reply; reply = btd_error_failed(gw->msg, "Connect failed"); g_dbus_send_message(conn, reply); } gateway_close(dev); }
static void confirm_event_cb(GIOChannel *chan, gpointer user_data) { struct input_server *server = user_data; bdaddr_t src, dst; GError *err = NULL; char addr[18]; int ret; bt_io_get(chan, BT_IO_L2CAP, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); goto drop; } if (server->confirm) { char address[18]; ba2str(&dst, address); error("Refusing connection from %s: setup in progress", address); goto drop; } server->confirm = g_io_channel_ref(chan); ret = btd_request_authorization(&src, &dst, HID_UUID, auth_callback, server); if (ret == 0) return; ba2str(&src, addr); error("input: authorization for %s failed: %s (%d)", addr, strerror(-ret), ret); g_io_channel_unref(server->confirm); server->confirm = NULL; drop: input_device_close_channels(&src, &dst); g_io_channel_shutdown(chan, TRUE, NULL); }
static void rfcomm_incoming_cb(GIOChannel *chan, GError *err, gpointer user_data) { struct audio_device *dev = user_data; struct gateway *gw = dev->gateway; uuid_t uuid; gw->incoming = g_io_channel_ref(chan); sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); if (bt_search_service(&dev->src, &dev->dst, &uuid, get_incoming_record_cb, dev, unregister_incoming) == 0) return; unregister_incoming(dev); gateway_close(dev); }