diff options
| author | Sebastien Bacher <seb128@ubuntu.com> | 2021-01-11 18:07:03 +0100 |
|---|---|---|
| committer | Sebastien Bacher <seb128@ubuntu.com> | 2021-01-11 18:15:57 +0100 |
| commit | 2567f558da3eb9911678227d4aeb15162e707d89 (patch) | |
| tree | 13c80b0e091c8ba585b14b966cda998f95f1936d /src/devices/bluetooth/nm-bluez5-dun.c | |
| parent | 02d99ffd62ede29cffcb45fcbe33d044b7406d3a (diff) | |
| parent | f54032b30e1ddd84f10a339e0caf493772e049a7 (diff) | |
Merge branch 'debian/master' into ubuntu/master
Diffstat (limited to 'src/devices/bluetooth/nm-bluez5-dun.c')
| -rw-r--r-- | src/devices/bluetooth/nm-bluez5-dun.c | 1368 |
1 files changed, 680 insertions, 688 deletions
diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c index c253d4e2..422c8516 100644 --- a/src/devices/bluetooth/nm-bluez5-dun.c +++ b/src/devices/bluetooth/nm-bluez5-dun.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Red Hat, Inc. */ @@ -23,843 +23,835 @@ /*****************************************************************************/ typedef struct { - GCancellable *cancellable; - NMBluez5DunConnectCb callback; - gpointer callback_user_data; + GCancellable * cancellable; + NMBluez5DunConnectCb callback; + gpointer callback_user_data; - sdp_session_t *sdp_session; + sdp_session_t *sdp_session; - GError *rfcomm_sdp_search_error; + GError *rfcomm_sdp_search_error; - GSource *source; + GSource *source; - gint64 connect_open_tty_started_at; + gint64 connect_open_tty_started_at; - gulong cancelled_id; + gulong cancelled_id; - guint8 sdp_session_try_count; + guint8 sdp_session_try_count; } ConnectData; struct _NMBluez5DunContext { - const char *dst_str; + const char *dst_str; - ConnectData *cdat; + ConnectData *cdat; - NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb; - gpointer notify_tty_hangup_user_data; + NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb; + gpointer notify_tty_hangup_user_data; - char *rfcomm_tty_path; + char *rfcomm_tty_path; - GSource *rfcomm_tty_poll_source; + GSource *rfcomm_tty_poll_source; - int rfcomm_sock_fd; - int rfcomm_tty_fd; - int rfcomm_tty_no; - int rfcomm_channel; + int rfcomm_sock_fd; + int rfcomm_tty_fd; + int rfcomm_tty_no; + int rfcomm_channel; - bdaddr_t src; - bdaddr_t dst; + bdaddr_t src; + bdaddr_t dst; - char src_str[]; + char src_str[]; }; /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_BT #define _NMLOG_PREFIX_NAME "bluez" -#define _NMLOG(level, context, ...) \ - G_STMT_START { \ - if (nm_logging_enabled ((level), (_NMLOG_DOMAIN))) { \ - const NMBluez5DunContext *const _context = (context); \ - \ - _nm_log ((level), (_NMLOG_DOMAIN), 0, NULL, NULL, \ - "%s: DUN[%s] " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - _context->src_str \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG(level, context, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \ + const NMBluez5DunContext *const _context = (context); \ + \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + "%s: DUN[%s] " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + _context->src_str _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ -static void _context_invoke_callback_success (NMBluez5DunContext *context); -static void _context_invoke_callback_fail_and_free (NMBluez5DunContext *context, - GError *error); -static void _context_free (NMBluez5DunContext *context); -static int _connect_open_tty (NMBluez5DunContext *context); -static gboolean _connect_sdp_session_start (NMBluez5DunContext *context, - GError **error); +static void _context_invoke_callback_success(NMBluez5DunContext *context); +static void _context_invoke_callback_fail_and_free(NMBluez5DunContext *context, GError *error); +static void _context_free(NMBluez5DunContext *context); +static int _connect_open_tty(NMBluez5DunContext *context); +static gboolean _connect_sdp_session_start(NMBluez5DunContext *context, GError **error); /*****************************************************************************/ -NM_AUTO_DEFINE_FCN0 (NMBluez5DunContext *, _nm_auto_free_context, _context_free) +NM_AUTO_DEFINE_FCN0(NMBluez5DunContext *, _nm_auto_free_context, _context_free); #define nm_auto_free_context nm_auto(_nm_auto_free_context) /*****************************************************************************/ const char * -nm_bluez5_dun_context_get_adapter (const NMBluez5DunContext *context) +nm_bluez5_dun_context_get_adapter(const NMBluez5DunContext *context) { - return context->src_str; + return context->src_str; } const char * -nm_bluez5_dun_context_get_remote (const NMBluez5DunContext *context) +nm_bluez5_dun_context_get_remote(const NMBluez5DunContext *context) { - return context->dst_str; + return context->dst_str; } const char * -nm_bluez5_dun_context_get_rfcomm_dev (const NMBluez5DunContext *context) +nm_bluez5_dun_context_get_rfcomm_dev(const NMBluez5DunContext *context) { - return context->rfcomm_tty_path; + return context->rfcomm_tty_path; } /*****************************************************************************/ static gboolean -_rfcomm_tty_poll_cb (int fd, - GIOCondition condition, - gpointer user_data) +_rfcomm_tty_poll_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; + NMBluez5DunContext *context = user_data; - _LOGD (context, "receive %s%s%s signal on rfcomm file descriptor", - NM_FLAGS_HAS (condition, G_IO_ERR) ? "ERR" : "", - NM_FLAGS_ALL (condition, G_IO_HUP | G_IO_ERR) ? "," : "", - NM_FLAGS_HAS (condition, G_IO_HUP) ? "HUP" : ""); + _LOGD(context, + "receive %s%s%s signal on rfcomm file descriptor", + NM_FLAGS_HAS(condition, G_IO_ERR) ? "ERR" : "", + NM_FLAGS_ALL(condition, G_IO_HUP | G_IO_ERR) ? "," : "", + NM_FLAGS_HAS(condition, G_IO_HUP) ? "HUP" : ""); - nm_clear_g_source_inst (&context->rfcomm_tty_poll_source); - context->notify_tty_hangup_cb (context, - context->notify_tty_hangup_user_data); - return G_SOURCE_REMOVE; + nm_clear_g_source_inst(&context->rfcomm_tty_poll_source); + context->notify_tty_hangup_cb(context, context->notify_tty_hangup_user_data); + return G_SOURCE_REMOVE; } static gboolean -_connect_open_tty_retry_cb (gpointer user_data) +_connect_open_tty_retry_cb(gpointer user_data) { - NMBluez5DunContext *context = user_data; - int r; - - r = _connect_open_tty (context); - if (r >= 0) - return G_SOURCE_REMOVE; - - if (nm_utils_get_monotonic_timestamp_nsec () > context->cdat->connect_open_tty_started_at + (30 * 100 * NM_UTILS_NSEC_PER_MSEC)) { - gs_free_error GError *error = NULL; - - nm_clear_g_source_inst (&context->cdat->source); - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "give up waiting to open %s device: %s (%d)", - context->rfcomm_tty_path, - nm_strerror_native (r), - -r); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - return G_SOURCE_CONTINUE; + NMBluez5DunContext *context = user_data; + int r; + + r = _connect_open_tty(context); + if (r >= 0) + return G_SOURCE_REMOVE; + + if (nm_utils_get_monotonic_timestamp_nsec() + > context->cdat->connect_open_tty_started_at + (30 * 100 * NM_UTILS_NSEC_PER_MSEC)) { + gs_free_error GError *error = NULL; + + nm_clear_g_source_inst(&context->cdat->source); + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "give up waiting to open %s device: %s (%d)", + context->rfcomm_tty_path, + nm_strerror_native(r), + -r); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + return G_SOURCE_CONTINUE; } static int -_connect_open_tty (NMBluez5DunContext *context) +_connect_open_tty(NMBluez5DunContext *context) { - int fd; - int errsv; - - fd = open (context->rfcomm_tty_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); - if (fd < 0) { - errsv = NM_ERRNO_NATIVE (errno); - - if (!context->cdat->source) { - _LOGD (context, "failed opening tty "RFCOMM_FMT": %s (%d). Start polling...", - context->rfcomm_tty_no, - nm_strerror_native (errsv), - errsv); - context->cdat->connect_open_tty_started_at = nm_utils_get_monotonic_timestamp_nsec (); - context->cdat->source = nm_g_timeout_source_new (100, - G_PRIORITY_DEFAULT, - _connect_open_tty_retry_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - } - return -errsv; - } - - context->rfcomm_tty_fd = fd; - - context->rfcomm_tty_poll_source = nm_g_unix_fd_source_new (context->rfcomm_tty_fd, - G_IO_ERR | G_IO_HUP, - G_PRIORITY_DEFAULT, - _rfcomm_tty_poll_cb, - context, - NULL); - g_source_attach (context->rfcomm_tty_poll_source, NULL); - - _context_invoke_callback_success (context); - return 0; + int fd; + int errsv; + + fd = open(context->rfcomm_tty_path, O_RDONLY | O_NOCTTY | O_CLOEXEC); + if (fd < 0) { + errsv = NM_ERRNO_NATIVE(errno); + + if (!context->cdat->source) { + _LOGD(context, + "failed opening tty " RFCOMM_FMT ": %s (%d). Start polling...", + context->rfcomm_tty_no, + nm_strerror_native(errsv), + errsv); + context->cdat->connect_open_tty_started_at = nm_utils_get_monotonic_timestamp_nsec(); + context->cdat->source = nm_g_timeout_source_new(100, + G_PRIORITY_DEFAULT, + _connect_open_tty_retry_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + } + return -errsv; + } + + context->rfcomm_tty_fd = fd; + + context->rfcomm_tty_poll_source = nm_g_unix_fd_source_new(context->rfcomm_tty_fd, + G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + _rfcomm_tty_poll_cb, + context, + NULL); + g_source_attach(context->rfcomm_tty_poll_source, NULL); + + _context_invoke_callback_success(context); + return 0; } static void -_connect_create_rfcomm (NMBluez5DunContext *context) +_connect_create_rfcomm(NMBluez5DunContext *context) { - gs_free_error GError *error = NULL; - struct rfcomm_dev_req req; - int devid; - int errsv; - int r; - - _LOGD (context, "connected to %s on channel %d", - context->dst_str, context->rfcomm_channel); - - /* Create an RFCOMM kernel device for the DUN channel */ - memset (&req, 0, sizeof (req)); - req.dev_id = -1; - req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); - req.channel = context->rfcomm_channel; - memcpy (&req.src, &context->src, ETH_ALEN); - memcpy (&req.dst, &context->dst, ETH_ALEN); - devid = ioctl (context->rfcomm_sock_fd, RFCOMMCREATEDEV, &req); - if (devid < 0) { - errsv = NM_ERRNO_NATIVE (errno); - if (errsv == EBADFD) { - /* hm. We use a non-blocking socket to connect. Above getsockopt(SOL_SOCKET,SO_ERROR) indicated - * success, but still now we fail with EBADFD. I think that is a bug and we should get the - * failure during connect(). - * - * Anyway, craft a less confusing error message than - * "failed to create rfcomm device: File descriptor in bad state (77)". */ - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "unknown failure to connect to DUN device"); - } else { - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to create rfcomm device: %s (%d)", - nm_strerror_native (errsv), errsv); - } - _context_invoke_callback_fail_and_free (context, error); - return; - } - - context->rfcomm_tty_no = devid; - context->rfcomm_tty_path = g_strdup_printf (RFCOMM_FMT, devid); - - r = _connect_open_tty (context); - if (r < 0) { - /* we created the rfcomm device, but cannot yet open it. That means, we are - * not yet fully connected. However, we notify the caller about "what we learned - * so far". Note that this happens synchronously. - * - * The purpose is that once we proceed synchrnously, modem-manager races with - * the detection of the modem. We want to notify the caller first about the - * device name. */ - context->cdat->callback (NULL, - context->rfcomm_tty_path, - NULL, - context->cdat->callback_user_data); - } + gs_free_error GError *error = NULL; + struct rfcomm_dev_req req; + int devid; + int errsv; + int r; + + _LOGD(context, "connected to %s on channel %d", context->dst_str, context->rfcomm_channel); + + /* Create an RFCOMM kernel device for the DUN channel */ + memset(&req, 0, sizeof(req)); + req.dev_id = -1; + req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); + req.channel = context->rfcomm_channel; + memcpy(&req.src, &context->src, ETH_ALEN); + memcpy(&req.dst, &context->dst, ETH_ALEN); + devid = ioctl(context->rfcomm_sock_fd, RFCOMMCREATEDEV, &req); + if (devid < 0) { + errsv = NM_ERRNO_NATIVE(errno); + if (errsv == EBADFD) { + /* hm. We use a non-blocking socket to connect. Above getsockopt(SOL_SOCKET,SO_ERROR) indicated + * success, but still now we fail with EBADFD. I think that is a bug and we should get the + * failure during connect(). + * + * Anyway, craft a less confusing error message than + * "failed to create rfcomm device: File descriptor in bad state (77)". */ + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "unknown failure to connect to DUN device"); + } else { + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to create rfcomm device: %s (%d)", + nm_strerror_native(errsv), + errsv); + } + _context_invoke_callback_fail_and_free(context, error); + return; + } + + context->rfcomm_tty_no = devid; + context->rfcomm_tty_path = g_strdup_printf(RFCOMM_FMT, devid); + + r = _connect_open_tty(context); + if (r < 0) { + /* we created the rfcomm device, but cannot yet open it. That means, we are + * not yet fully connected. However, we notify the caller about "what we learned + * so far". Note that this happens synchronously. + * + * The purpose is that once we proceed synchronously, modem-manager races with + * the detection of the modem. We want to notify the caller first about the + * device name. */ + context->cdat->callback(NULL, + context->rfcomm_tty_path, + NULL, + context->cdat->callback_user_data); + } } static gboolean -_connect_socket_connect_cb (int fd, - GIOCondition condition, - gpointer user_data) +_connect_socket_connect_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; - gs_free_error GError *error = NULL; - int errsv = 0; - socklen_t slen = sizeof(errsv); - int r; - - nm_clear_g_source_inst (&context->cdat->source); - - r = getsockopt (context->rfcomm_sock_fd, SOL_SOCKET, SO_ERROR, &errsv, &slen); - - if (r < 0) { - errsv = errno; - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to complete connecting RFCOMM socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - if (errsv != 0) { - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to connect RFCOMM socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - _connect_create_rfcomm (context); - return G_SOURCE_REMOVE; + NMBluez5DunContext *context = user_data; + gs_free_error GError *error = NULL; + int errsv = 0; + socklen_t slen = sizeof(errsv); + int r; + + nm_clear_g_source_inst(&context->cdat->source); + + r = getsockopt(context->rfcomm_sock_fd, SOL_SOCKET, SO_ERROR, &errsv, &slen); + + if (r < 0) { + errsv = errno; + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to complete connecting RFCOMM socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + if (errsv != 0) { + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to connect RFCOMM socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + _connect_create_rfcomm(context); + return G_SOURCE_REMOVE; } static void -_connect_socket_connect (NMBluez5DunContext *context) +_connect_socket_connect(NMBluez5DunContext *context) { - gs_free_error GError *error = NULL; - struct sockaddr_rc sa; - int errsv; - - context->rfcomm_sock_fd = socket (AF_BLUETOOTH, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_RFCOMM); - if (context->rfcomm_sock_fd < 0) { - errsv = errno; - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to create RFCOMM socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return; - } - - /* Connect to the remote device */ - memset (&sa, 0, sizeof (sa)); - sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = 0; - memcpy (&sa.rc_bdaddr, &context->src, ETH_ALEN); - if (bind (context->rfcomm_sock_fd, - (struct sockaddr *) &sa, - sizeof(sa)) != 0) { - errsv = errno; - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to bind socket: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return; - } - - memset (&sa, 0, sizeof (sa)); - sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = context->rfcomm_channel; - memcpy (&sa.rc_bdaddr, &context->dst, ETH_ALEN); - if (connect (context->rfcomm_sock_fd, - (struct sockaddr *) &sa, - sizeof (sa)) != 0) { - - errsv = errno; - if (errsv != EINPROGRESS) { - g_set_error (&error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to connect to remote device: %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return; - } - - _LOGD (context, "connecting to %s on channel %d...", - context->dst_str, - context->rfcomm_channel); - - context->cdat->source = nm_g_unix_fd_source_new (context->rfcomm_sock_fd, - G_IO_OUT, - G_PRIORITY_DEFAULT, - _connect_socket_connect_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - return; - } - - _connect_create_rfcomm (context); + gs_free_error GError *error = NULL; + struct sockaddr_rc sa; + int errsv; + + context->rfcomm_sock_fd = + socket(AF_BLUETOOTH, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_RFCOMM); + if (context->rfcomm_sock_fd < 0) { + errsv = errno; + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to create RFCOMM socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return; + } + + /* Connect to the remote device */ + memset(&sa, 0, sizeof(sa)); + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = 0; + memcpy(&sa.rc_bdaddr, &context->src, ETH_ALEN); + if (bind(context->rfcomm_sock_fd, (struct sockaddr *) &sa, sizeof(sa)) != 0) { + errsv = errno; + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to bind socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return; + } + + memset(&sa, 0, sizeof(sa)); + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = context->rfcomm_channel; + memcpy(&sa.rc_bdaddr, &context->dst, ETH_ALEN); + if (connect(context->rfcomm_sock_fd, (struct sockaddr *) &sa, sizeof(sa)) != 0) { + errsv = errno; + if (errsv != EINPROGRESS) { + g_set_error(&error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to connect to remote device: %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return; + } + + _LOGD(context, + "connecting to %s on channel %d...", + context->dst_str, + context->rfcomm_channel); + + context->cdat->source = nm_g_unix_fd_source_new(context->rfcomm_sock_fd, + G_IO_OUT, + G_PRIORITY_DEFAULT, + _connect_socket_connect_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + return; + } + + _connect_create_rfcomm(context); } static void -_connect_sdp_search_cb (uint8_t type, - uint16_t status, - uint8_t *rsp, - size_t size, - void *user_data) +_connect_sdp_search_cb(uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *user_data) { - NMBluez5DunContext *context = user_data; - int scanned; - int seqlen = 0; - int bytesleft = size; - uint8_t dataType; - int channel = -1; - - if ( context->cdat->rfcomm_sdp_search_error - || context->rfcomm_channel >= 0) - return; - - _LOGD (context, "SDP search finished with type=%d status=%d", - status, type); - - /* SDP response received */ - if ( status - || type != SDP_SVC_SEARCH_ATTR_RSP) { - g_set_error (&context->cdat->rfcomm_sdp_search_error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "did not get a Service Discovery response"); - return; - } - - scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); - - _LOGD (context, "SDP sequence type scanned=%d length=%d", - scanned, seqlen); - - scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); - if ( !scanned - || !seqlen) { - /* Short read or unknown sequence type */ - g_set_error (&context->cdat->rfcomm_sdp_search_error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "improper Service Discovery response"); - return; - } - - rsp += scanned; - bytesleft -= scanned; - do { - sdp_record_t *rec; - int recsize = 0; - sdp_list_t *protos; - - rec = sdp_extract_pdu (rsp, bytesleft, &recsize); - if (!rec) - break; - - if (!recsize) { - sdp_record_free (rec); - break; - } - - if (sdp_get_access_protos (rec, &protos) == 0) { - /* Extract the DUN channel number */ - channel = sdp_get_proto_port (protos, RFCOMM_UUID); - sdp_list_free (protos, NULL); - - _LOGD (context, "SDP channel=%d", - channel); - } - sdp_record_free (rec); - - scanned += recsize; - rsp += recsize; - bytesleft -= recsize; - } while ( scanned < (ssize_t) size - && bytesleft > 0 - && channel < 0); - - if (channel == -1) { - g_set_error (&context->cdat->rfcomm_sdp_search_error, - NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "did not receive rfcomm-channel"); - return; - } - - context->rfcomm_channel = channel; + NMBluez5DunContext *context = user_data; + int scanned; + int seqlen = 0; + int bytesleft = size; + uint8_t dataType; + int channel = -1; + + if (context->cdat->rfcomm_sdp_search_error || context->rfcomm_channel >= 0) + return; + + _LOGD(context, "SDP search finished with type=%d status=%d", status, type); + + /* SDP response received */ + if (status || type != SDP_SVC_SEARCH_ATTR_RSP) { + g_set_error(&context->cdat->rfcomm_sdp_search_error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "did not get a Service Discovery response"); + return; + } + + scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen); + + _LOGD(context, "SDP sequence type scanned=%d length=%d", scanned, seqlen); + + scanned = sdp_extract_seqtype(rsp, bytesleft, &dataType, &seqlen); + if (!scanned || !seqlen) { + /* Short read or unknown sequence type */ + g_set_error(&context->cdat->rfcomm_sdp_search_error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "improper Service Discovery response"); + return; + } + + rsp += scanned; + bytesleft -= scanned; + do { + sdp_record_t *rec; + int recsize = 0; + sdp_list_t * protos; + + rec = sdp_extract_pdu(rsp, bytesleft, &recsize); + if (!rec) + break; + + if (!recsize) { + sdp_record_free(rec); + break; + } + + if (sdp_get_access_protos(rec, &protos) == 0) { + /* Extract the DUN channel number */ + channel = sdp_get_proto_port(protos, RFCOMM_UUID); + sdp_list_free(protos, NULL); + + _LOGD(context, "SDP channel=%d", channel); + } + sdp_record_free(rec); + + scanned += recsize; + rsp += recsize; + bytesleft -= recsize; + } while (scanned < (ssize_t) size && bytesleft > 0 && channel < 0); + + if (channel == -1) { + g_set_error(&context->cdat->rfcomm_sdp_search_error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "did not receive rfcomm-channel"); + return; + } + + context->rfcomm_channel = channel; } static gboolean -_connect_sdp_search_io_cb (int fd, - GIOCondition condition, - gpointer user_data) +_connect_sdp_search_io_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; - gs_free_error GError *error = NULL; - int errsv; - - if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { - _LOGD (context, "SDP search returned with invalid IO condition 0x%x", - (guint) condition); - error = g_error_new (NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "Service Discovery interrupted"); - nm_clear_g_source_inst (&context->cdat->source); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - if (sdp_process (context->cdat->sdp_session) == 0) { - _LOGD (context, "SDP search still not finished"); - return G_SOURCE_CONTINUE; - } - - nm_clear_g_source_inst (&context->cdat->source); - - if ( context->rfcomm_channel < 0 - && !context->cdat->rfcomm_sdp_search_error) { - errsv = sdp_get_error (context->cdat->sdp_session); - _LOGD (context, "SDP search failed: %s (%d)", - nm_strerror_native (errsv), errsv); - error = g_error_new (NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "Service Discovery failed with %s (%d)", - nm_strerror_native (errsv), errsv); - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; - } - - if (context->cdat->rfcomm_sdp_search_error) { - _LOGD (context, "SDP search failed to complete: %s", context->cdat->rfcomm_sdp_search_error->message); - _context_invoke_callback_fail_and_free (context, context->cdat->rfcomm_sdp_search_error); - return G_SOURCE_REMOVE; - } - - nm_clear_pointer (&context->cdat->sdp_session, sdp_close); - - _connect_socket_connect (context); - - return G_SOURCE_REMOVE; + NMBluez5DunContext *context = user_data; + gs_free_error GError *error = NULL; + int errsv; + + if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { + _LOGD(context, "SDP search returned with invalid IO condition 0x%x", (guint) condition); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Service Discovery interrupted"); + nm_clear_g_source_inst(&context->cdat->source); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + if (sdp_process(context->cdat->sdp_session) == 0) { + _LOGD(context, "SDP search still not finished"); + return G_SOURCE_CONTINUE; + } + + nm_clear_g_source_inst(&context->cdat->source); + + if (context->rfcomm_channel < 0 && !context->cdat->rfcomm_sdp_search_error) { + errsv = sdp_get_error(context->cdat->sdp_session); + _LOGD(context, "SDP search failed: %s (%d)", nm_strerror_native(errsv), errsv); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Service Discovery failed with %s (%d)", + nm_strerror_native(errsv), + errsv); + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; + } + + if (context->cdat->rfcomm_sdp_search_error) { + _LOGD(context, + "SDP search failed to complete: %s", + context->cdat->rfcomm_sdp_search_error->message); + _context_invoke_callback_fail_and_free(context, context->cdat->rfcomm_sdp_search_error); + return G_SOURCE_REMOVE; + } + + nm_clear_pointer(&context->cdat->sdp_session, sdp_close); + + _connect_socket_connect(context); + + return G_SOURCE_REMOVE; } static gboolean -_connect_sdp_session_start_on_idle_cb (gpointer user_data) +_connect_sdp_session_start_on_idle_cb(gpointer user_data) { - NMBluez5DunContext *context = user_data; - gs_free_error GError *error = NULL; + NMBluez5DunContext *context = user_data; + gs_free_error GError *error = NULL; - nm_clear_g_source_inst (&context->cdat->source); + nm_clear_g_source_inst(&context->cdat->source); - _LOGD (context, "retry starting sdp-session..."); + _LOGD(context, "retry starting sdp-session..."); - if (!_connect_sdp_session_start (context, &error)) - _context_invoke_callback_fail_and_free (context, error); + if (!_connect_sdp_session_start(context, &error)) + _context_invoke_callback_fail_and_free(context, error); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static gboolean -_connect_sdp_io_cb (int fd, - GIOCondition condition, - gpointer user_data) +_connect_sdp_io_cb(int fd, GIOCondition condition, gpointer user_data) { - NMBluez5DunContext *context = user_data; - sdp_list_t *search; - sdp_list_t *attrs; - uuid_t svclass; - uint16_t attr; - int errsv; - int fd_err = 0; - int r; - socklen_t len = sizeof (fd_err); - gs_free_error GError *error = NULL; - - nm_clear_g_source_inst (&context->cdat->source); - - _LOGD (context, "sdp-session ready to connect with fd=%d", fd); - - if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) { - errsv = NM_ERRNO_NATIVE (errno); - error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "error for getsockopt on Service Discovery socket: %s (%d)", - nm_strerror_native (errsv), errsv); - goto done; - } - - if (fd_err != 0) { - errsv = nm_errno_native (fd_err); - - if ( NM_IN_SET (errsv, ECONNREFUSED, EHOSTDOWN) - && --context->cdat->sdp_session_try_count > 0) { - /* *sigh* */ - _LOGD (context, "sdp-session failed with %s (%d). Retry in a bit", nm_strerror_native (errsv), errsv); - nm_clear_g_source_inst (&context->cdat->source); - context->cdat->source = nm_g_timeout_source_new (1000, - G_PRIORITY_DEFAULT, - _connect_sdp_session_start_on_idle_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - return G_SOURCE_REMOVE; - } - - error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "error on Service Discovery socket: %s (%d)", - nm_strerror_native (errsv), errsv); - goto done; - } - - if (sdp_set_notify (context->cdat->sdp_session, _connect_sdp_search_cb, context) < 0) { - /* Should not be reached, only can fail if we passed bad sdp_session. */ - error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "could not set Service Discovery notification"); - goto done; - } - - sdp_uuid16_create (&svclass, DIALUP_NET_SVCLASS_ID); - search = sdp_list_append (NULL, &svclass); - attr = SDP_ATTR_PROTO_DESC_LIST; - attrs = sdp_list_append (NULL, &attr); - - r = sdp_service_search_attr_async (context->cdat->sdp_session, - search, - SDP_ATTR_REQ_INDIVIDUAL, - attrs); - - sdp_list_free (attrs, NULL); - sdp_list_free (search, NULL); - - if (r < 0) { - errsv = nm_errno_native (sdp_get_error (context->cdat->sdp_session)); - error = g_error_new (NM_BT_ERROR, - NM_BT_ERROR_DUN_CONNECT_FAILED, - "error starting Service Discovery: %s (%d)", - nm_strerror_native (errsv), errsv); - goto done; - } - - /* Set callback responsible for update the internal SDP transaction */ - context->cdat->source = nm_g_unix_fd_source_new (fd, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - G_PRIORITY_DEFAULT, - _connect_sdp_search_io_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); + NMBluez5DunContext *context = user_data; + sdp_list_t * search; + sdp_list_t * attrs; + uuid_t svclass; + uint16_t attr; + int errsv; + int fd_err = 0; + int r; + socklen_t len = sizeof(fd_err); + gs_free_error GError *error = NULL; + + nm_clear_g_source_inst(&context->cdat->source); + + _LOGD(context, "sdp-session ready to connect with fd=%d", fd); + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) { + errsv = NM_ERRNO_NATIVE(errno); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "error for getsockopt on Service Discovery socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + goto done; + } + + if (fd_err != 0) { + errsv = nm_errno_native(fd_err); + + if (NM_IN_SET(errsv, ECONNREFUSED, EHOSTDOWN) + && --context->cdat->sdp_session_try_count > 0) { + /* *sigh* */ + _LOGD(context, + "sdp-session failed with %s (%d). Retry in a bit", + nm_strerror_native(errsv), + errsv); + nm_clear_g_source_inst(&context->cdat->source); + context->cdat->source = nm_g_timeout_source_new(1000, + G_PRIORITY_DEFAULT, + _connect_sdp_session_start_on_idle_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + return G_SOURCE_REMOVE; + } + + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "error on Service Discovery socket: %s (%d)", + nm_strerror_native(errsv), + errsv); + goto done; + } + + if (sdp_set_notify(context->cdat->sdp_session, _connect_sdp_search_cb, context) < 0) { + /* Should not be reached, only can fail if we passed bad sdp_session. */ + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "could not set Service Discovery notification"); + goto done; + } + + sdp_uuid16_create(&svclass, DIALUP_NET_SVCLASS_ID); + search = sdp_list_append(NULL, &svclass); + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr); + + r = sdp_service_search_attr_async(context->cdat->sdp_session, + search, + SDP_ATTR_REQ_INDIVIDUAL, + attrs); + + sdp_list_free(attrs, NULL); + sdp_list_free(search, NULL); + + if (r < 0) { + errsv = nm_errno_native(sdp_get_error(context->cdat->sdp_session)); + error = g_error_new(NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "error starting Service Discovery: %s (%d)", + nm_strerror_native(errsv), + errsv); + goto done; + } + + /* Set callback responsible for update the internal SDP transaction */ + context->cdat->source = nm_g_unix_fd_source_new(fd, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + G_PRIORITY_DEFAULT, + _connect_sdp_search_io_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); done: - if (error) - _context_invoke_callback_fail_and_free (context, error); - return G_SOURCE_REMOVE; + if (error) + _context_invoke_callback_fail_and_free(context, error); + return G_SOURCE_REMOVE; } /*****************************************************************************/ static void -_connect_cancelled_cb (GCancellable *cancellable, - NMBluez5DunContext *context) +_connect_cancelled_cb(GCancellable *cancellable, NMBluez5DunContext *context) { - gs_free_error GError *error = NULL; + gs_free_error GError *error = NULL; - if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) - g_return_if_reached (); + if (!g_cancellable_set_error_if_cancelled(cancellable, &error)) + g_return_if_reached(); - _context_invoke_callback_fail_and_free (context, error); + _context_invoke_callback_fail_and_free(context, error); } static gboolean -_connect_sdp_session_start (NMBluez5DunContext *context, - GError **error) +_connect_sdp_session_start(NMBluez5DunContext *context, GError **error) { - nm_assert (context->cdat); - - nm_clear_g_source_inst (&context->cdat->source); - nm_clear_pointer (&context->cdat->sdp_session, sdp_close); - - context->cdat->sdp_session = sdp_connect (&context->src, &context->dst, SDP_NON_BLOCKING); - if (!context->cdat->sdp_session) { - int errsv = nm_errno_native (errno); - - g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "failed to connect to the SDP server: %s (%d)", - nm_strerror_native (errsv), errsv); - return FALSE; - } - - context->cdat->source = nm_g_unix_fd_source_new (sdp_get_socket (context->cdat->sdp_session), - G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - G_PRIORITY_DEFAULT, - _connect_sdp_io_cb, - context, - NULL); - g_source_attach (context->cdat->source, NULL); - return TRUE; + nm_assert(context->cdat); + + nm_clear_g_source_inst(&context->cdat->source); + nm_clear_pointer(&context->cdat->sdp_session, sdp_close); + + context->cdat->sdp_session = sdp_connect(&context->src, &context->dst, SDP_NON_BLOCKING); + if (!context->cdat->sdp_session) { + int errsv = nm_errno_native(errno); + + g_set_error(error, + NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "failed to connect to the SDP server: %s (%d)", + nm_strerror_native(errsv), + errsv); + return FALSE; + } + + context->cdat->source = nm_g_unix_fd_source_new(sdp_get_socket(context->cdat->sdp_session), + G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + G_PRIORITY_DEFAULT, + _connect_sdp_io_cb, + context, + NULL); + g_source_attach(context->cdat->source, NULL); + return TRUE; } /*****************************************************************************/ gboolean -nm_bluez5_dun_connect (const char *adapter, - const char *remote, - GCancellable *cancellable, - NMBluez5DunConnectCb callback, - gpointer callback_user_data, - NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb, - gpointer notify_tty_hangup_user_data, - GError **error) +nm_bluez5_dun_connect(const char * adapter, + const char * remote, + GCancellable * cancellable, + NMBluez5DunConnectCb callback, + gpointer callback_user_data, + NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb, + gpointer notify_tty_hangup_user_data, + GError ** error) { - nm_auto_free_context NMBluez5DunContext *context = NULL; - ConnectData *cdat; - gsize src_l; - gsize dst_l; - - g_return_val_if_fail (adapter, FALSE); - g_return_val_if_fail (remote, FALSE); - g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (callback, FALSE); - g_return_val_if_fail (notify_tty_hangup_cb, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); - nm_assert (!g_cancellable_is_cancelled (cancellable)); - - src_l = strlen (adapter) + 1; - dst_l = strlen (remote) + 1; - - cdat = g_slice_new (ConnectData); - *cdat = (ConnectData) { - .callback = callback, - .callback_user_data = callback_user_data, - .cancellable = g_object_ref (cancellable), - .sdp_session_try_count = 5, - }; - - context = g_malloc (sizeof (NMBluez5DunContext) + src_l + dst_l); - *context = (NMBluez5DunContext) { - .cdat = cdat, - .notify_tty_hangup_cb = notify_tty_hangup_cb, - .notify_tty_hangup_user_data = notify_tty_hangup_user_data, - .rfcomm_tty_no = -1, - .rfcomm_sock_fd = -1, - .rfcomm_tty_fd = -1, - .rfcomm_channel = -1, - }; - memcpy (&context->src_str[0], adapter, src_l); - context->dst_str = &context->src_str[src_l]; - memcpy ((char *) context->dst_str, remote, dst_l); - - if (str2ba (adapter, &context->src) < 0) { - g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "invalid source"); - return FALSE; - } - - if (str2ba (remote, &context->dst) < 0) { - g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, - "invalid remote"); - return FALSE; - } - - context->cdat->cancelled_id = g_signal_connect (context->cdat->cancellable, - "cancelled", - G_CALLBACK (_connect_cancelled_cb), - context); - - if (!_connect_sdp_session_start (context, error)) - return FALSE; - - _LOGD (context, "starting channel number discovery for device %s", - context->dst_str); - - g_steal_pointer (&context); - return TRUE; + nm_auto_free_context NMBluez5DunContext *context = NULL; + ConnectData * cdat; + gsize src_l; + gsize dst_l; + + g_return_val_if_fail(adapter, FALSE); + g_return_val_if_fail(remote, FALSE); + g_return_val_if_fail(G_IS_CANCELLABLE(cancellable), FALSE); + g_return_val_if_fail(callback, FALSE); + g_return_val_if_fail(notify_tty_hangup_cb, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + nm_assert(!g_cancellable_is_cancelled(cancellable)); + + src_l = strlen(adapter) + 1; + dst_l = strlen(remote) + 1; + + cdat = g_slice_new(ConnectData); + *cdat = (ConnectData){ + .callback = callback, + .callback_user_data = callback_user_data, + .cancellable = g_object_ref(cancellable), + .sdp_session_try_count = 5, + }; + + context = g_malloc(sizeof(NMBluez5DunContext) + src_l + dst_l); + *context = (NMBluez5DunContext){ + .cdat = cdat, + .notify_tty_hangup_cb = notify_tty_hangup_cb, + .notify_tty_hangup_user_data = notify_tty_hangup_user_data, + .rfcomm_tty_no = -1, + .rfcomm_sock_fd = -1, + .rfcomm_tty_fd = -1, + .rfcomm_channel = -1, + }; + memcpy(&context->src_str[0], adapter, src_l); + context->dst_str = &context->src_str[src_l]; + memcpy((char *) context->dst_str, remote, dst_l); + + if (str2ba(adapter, &context->src) < 0) { + g_set_error(error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, "invalid source"); + return FALSE; + } + + if (str2ba(remote, &context->dst) < 0) { + g_set_error(error, NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, "invalid remote"); + return FALSE; + } + + context->cdat->cancelled_id = g_signal_connect(context->cdat->cancellable, + "cancelled", + G_CALLBACK(_connect_cancelled_cb), + context); + + if (!_connect_sdp_session_start(context, error)) + return FALSE; + + _LOGD(context, "starting channel number discovery for device %s", context->dst_str); + + g_steal_pointer(&context); + return TRUE; } /*****************************************************************************/ void -nm_bluez5_dun_disconnect (NMBluez5DunContext *context) +nm_bluez5_dun_disconnect(NMBluez5DunContext *context) { - nm_assert (context); - nm_assert (!context->cdat); + nm_assert(context); + nm_assert(!context->cdat); - _LOGD (context, "disconnecting DUN connection"); + _LOGD(context, "disconnecting DUN connection"); - _context_free (context); + _context_free(context); } /*****************************************************************************/ static void -_context_cleanup_connect_data (NMBluez5DunContext *context) +_context_cleanup_connect_data(NMBluez5DunContext *context) { - ConnectData *cdat; + ConnectData *cdat; - cdat = g_steal_pointer (&context->cdat); - if (!cdat) - return; + cdat = g_steal_pointer(&context->cdat); + if (!cdat) + return; - nm_clear_g_signal_handler (cdat->cancellable, &cdat->cancelled_id); + nm_clear_g_signal_handler(cdat->cancellable, &cdat->cancelled_id); - nm_clear_g_source_inst (&cdat->source); + nm_clear_g_source_inst(&cdat->source); - nm_clear_pointer (&cdat->sdp_session, sdp_close); + nm_clear_pointer(&cdat->sdp_session, sdp_close); - g_clear_object (&cdat->cancellable); + g_clear_object(&cdat->cancellable); - g_clear_error (&cdat->rfcomm_sdp_search_error); + g_clear_error(&cdat->rfcomm_sdp_search_error); - nm_g_slice_free (cdat); + nm_g_slice_free(cdat); } static void -_context_invoke_callback (NMBluez5DunContext *context, - GError *error) +_context_invoke_callback(NMBluez5DunContext *context, GError *error) { - NMBluez5DunConnectCb callback; - gpointer callback_user_data; - - nm_assert (context); - nm_assert (context->cdat); - nm_assert (context->cdat->callback); - nm_assert (error || context->rfcomm_tty_path); - - if (!error) - _LOGD (context, "connected via \"%s\"", context->rfcomm_tty_path); - else if (nm_utils_error_is_cancelled (error)) - _LOGD (context, "cancelled"); - else - _LOGD (context, "failed to connect: %s", error->message); - - callback = context->cdat->callback; - callback_user_data = context->cdat->callback_user_data; - - _context_cleanup_connect_data (context); - - callback (error ? NULL : context, - error ? NULL : context->rfcomm_tty_path, - error, - callback_user_data); + NMBluez5DunConnectCb callback; + gpointer callback_user_data; + + nm_assert(context); + nm_assert(context->cdat); + nm_assert(context->cdat->callback); + nm_assert(error || context->rfcomm_tty_path); + + if (!error) + _LOGD(context, "connected via \"%s\"", context->rfcomm_tty_path); + else if (nm_utils_error_is_cancelled(error)) + _LOGD(context, "cancelled"); + else + _LOGD(context, "failed to connect: %s", error->message); + + callback = context->cdat->callback; + callback_user_data = context->cdat->callback_user_data; + + _context_cleanup_connect_data(context); + + callback(error ? NULL : context, + error ? NULL : context->rfcomm_tty_path, + error, + callback_user_data); } static void -_context_invoke_callback_success (NMBluez5DunContext *context) +_context_invoke_callback_success(NMBluez5DunContext *context) { - nm_assert (context->rfcomm_tty_path); - _context_invoke_callback (context, NULL); + nm_assert(context->rfcomm_tty_path); + _context_invoke_callback(context, NULL); } static void -_context_invoke_callback_fail_and_free (NMBluez5DunContext *context, - GError *error) +_context_invoke_callback_fail_and_free(NMBluez5DunContext *context, GError *error) { - nm_assert (error); - _context_invoke_callback (context, error); - _context_free (context); + nm_assert(error); + _context_invoke_callback(context, error); + _context_free(context); } static void -_context_free (NMBluez5DunContext *context) +_context_free(NMBluez5DunContext *context) { - nm_assert (context); + nm_assert(context); - _context_cleanup_connect_data (context); + _context_cleanup_connect_data(context); - nm_clear_g_source_inst (&context->rfcomm_tty_poll_source); + nm_clear_g_source_inst(&context->rfcomm_tty_poll_source); - if (context->rfcomm_sock_fd >= 0) { - if (context->rfcomm_tty_no >= 0) { - struct rfcomm_dev_req req; + if (context->rfcomm_sock_fd >= 0) { + if (context->rfcomm_tty_no >= 0) { + struct rfcomm_dev_req req; - memset (&req, 0, sizeof (struct rfcomm_dev_req)); - req.dev_id = context->rfcomm_tty_no; - context->rfcomm_tty_no = -1; - (void) ioctl (context->rfcomm_sock_fd, RFCOMMRELEASEDEV, &req); - } - nm_close (nm_steal_fd (&context->rfcomm_sock_fd)); - } + memset(&req, 0, sizeof(struct rfcomm_dev_req)); + req.dev_id = context->rfcomm_tty_no; + context->rfcomm_tty_no = -1; + (void) ioctl(context->rfcomm_sock_fd, RFCOMMRELEASEDEV, &req); + } + nm_close(nm_steal_fd(&context->rfcomm_sock_fd)); + } - if (context->rfcomm_tty_fd >= 0) - nm_close (nm_steal_fd (&context->rfcomm_tty_fd)); - nm_clear_g_free (&context->rfcomm_tty_path); - g_free (context); + if (context->rfcomm_tty_fd >= 0) + nm_close(nm_steal_fd(&context->rfcomm_tty_fd)); + nm_clear_g_free(&context->rfcomm_tty_path); + g_free(context); } |