diff options
| author | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
| commit | 80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch) | |
| tree | e3b229aa94e8dcf0590f2317664176e7b8f7607b /src/core/devices/bluetooth/tests | |
| parent | 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff) | |
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/core/devices/bluetooth/tests')
| -rw-r--r-- | src/core/devices/bluetooth/tests/nm-bt-test.c | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/src/core/devices/bluetooth/tests/nm-bt-test.c b/src/core/devices/bluetooth/tests/nm-bt-test.c new file mode 100644 index 00000000..0fc8aa87 --- /dev/null +++ b/src/core/devices/bluetooth/tests/nm-bt-test.c @@ -0,0 +1,223 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "src/core/nm-default-daemon.h" + +#include <glib-unix.h> + +#include "devices/bluetooth/nm-bluez5-dun.h" + +#include "nm-test-utils-core.h" + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_BT +#define _NMLOG(level, ...) \ + nm_log((level), \ + _NMLOG_DOMAIN, \ + NULL, \ + NULL, \ + "bt%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_PRINT_FMT_QUOTED(gl.argv_cmd, "[", gl.argv_cmd, "]", "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/*****************************************************************************/ + +struct { + int argc; + const char *const *argv; + const char * argv_cmd; + GMainLoop * loop; +} gl; + +typedef struct _MainCmdInfo { + const char *name; + int (*main_func)(const struct _MainCmdInfo *main_cmd_info); +} MainCmdInfo; + +/*****************************************************************************/ + +#if WITH_BLUEZ5_DUN + +typedef struct { + NMBluez5DunContext *dun_context; + GCancellable * cancellable; + guint timeout_id; + guint sig_term_id; + guint sig_int_id; +} DunConnectData; + +static void +_dun_connect_cb(NMBluez5DunContext *context, + const char * rfcomm_dev, + GError * error, + gpointer user_data) +{ + DunConnectData *dun_connect_data = user_data; + + g_assert(dun_connect_data); + g_assert(!dun_connect_data->dun_context); + g_assert((!!error) != (!!rfcomm_dev)); + + if (rfcomm_dev && !context) { + _LOGI("dun-connect notifies path \"%s\". Wait longer...", rfcomm_dev); + return; + } + + if (rfcomm_dev) { + g_assert(context); + _LOGI("dun-connect completed with path \"%s\"", rfcomm_dev); + } else { + g_assert(!context); + _LOGI("dun-connect failed with error: %s", error->message); + } + + dun_connect_data->dun_context = context; + + g_main_loop_quit(gl.loop); +} + +static void +_dun_notify_tty_hangup_cb(NMBluez5DunContext *context, gpointer user_data) +{ + _LOGI("dun-connect: notified TTY hangup"); +} + +static gboolean +_timeout_cb(gpointer user_data) +{ + DunConnectData *dun_connect_data = user_data; + + _LOGI("timeout"); + dun_connect_data->timeout_id = 0; + if (dun_connect_data->cancellable) + g_cancellable_cancel(dun_connect_data->cancellable); + return G_SOURCE_REMOVE; +} + +static gboolean +_sig_xxx_cb(DunConnectData *dun_connect_data, int sigid) +{ + _LOGI("signal %s received", sigid == SIGTERM ? "SIGTERM" : "SIGINT"); + g_main_loop_quit(gl.loop); + return G_SOURCE_CONTINUE; +} + +static gboolean +_sig_term_cb(gpointer user_data) +{ + return _sig_xxx_cb(user_data, SIGTERM); +} + +static gboolean +_sig_int_cb(gpointer user_data) +{ + return _sig_xxx_cb(user_data, SIGINT); +} +#endif + +static int +do_dun_connect(const MainCmdInfo *main_cmd_info) +{ +#if WITH_BLUEZ5_DUN + gs_unref_object GCancellable *cancellable = NULL; + gs_free_error GError *error = NULL; + const char * adapter; + const char * remote; + DunConnectData dun_connect_data = {}; + + if (gl.argc < 4) { + _LOGE("missing arguments \"adapter\" and \"remote\""); + return -1; + } + + adapter = gl.argv[2]; + remote = gl.argv[3]; + + cancellable = g_cancellable_new(); + dun_connect_data.cancellable = cancellable; + + if (!nm_bluez5_dun_connect(adapter, + remote, + cancellable, + _dun_connect_cb, + &dun_connect_data, + _dun_notify_tty_hangup_cb, + &dun_connect_data, + &error)) { + _LOGE("connect failed to start: %s", error->message); + return -1; + } + + dun_connect_data.timeout_id = g_timeout_add(60000, _timeout_cb, &dun_connect_data); + + g_main_loop_run(gl.loop); + + nm_clear_g_source(&dun_connect_data.timeout_id); + + if (dun_connect_data.dun_context) { + dun_connect_data.sig_term_id = g_unix_signal_add(SIGTERM, _sig_term_cb, &dun_connect_data); + dun_connect_data.sig_int_id = g_unix_signal_add(SIGINT, _sig_int_cb, &dun_connect_data); + + g_main_loop_run(gl.loop); + + nm_clear_g_source(&dun_connect_data.sig_term_id); + nm_clear_g_source(&dun_connect_data.sig_int_id); + + nm_bluez5_dun_disconnect(g_steal_pointer(&dun_connect_data.dun_context)); + } + + return 0; +#else + _LOGE("compiled without bluetooth DUN support"); + return 1; +#endif +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + static const MainCmdInfo main_cmd_infos[] = { + { + .name = "dun-connect", + .main_func = do_dun_connect, + }, + }; + int exit_code = 0; + guint i; + + if (!g_getenv("G_MESSAGES_DEBUG")) + g_setenv("G_MESSAGES_DEBUG", "all", TRUE); + + nmtst_init_with_logging(&argc, &argv, "DEBUG", "ALL"); + + nm_logging_init(NULL, TRUE); + + gl.argv = (const char *const *) argv; + gl.argc = argc; + gl.loop = g_main_loop_new(NULL, FALSE); + + _LOGI("bluetooth test util start"); + + gl.argv_cmd = argc >= 2 ? argv[1] : NULL; + + for (i = 0; i < G_N_ELEMENTS(main_cmd_infos); i++) { + if (nm_streq0(main_cmd_infos[i].name, gl.argv_cmd)) { + _LOGD("start \"%s\"", gl.argv_cmd); + exit_code = main_cmd_infos[i].main_func(&main_cmd_infos[i]); + _LOGD("completed with %d", exit_code); + break; + } + } + if (gl.argv_cmd && i >= G_N_ELEMENTS(main_cmd_infos)) { + nm_log_err(LOGD_BT, "invalid command \"%s\"", gl.argv_cmd); + exit_code = -1; + } + + nm_clear_pointer(&gl.loop, g_main_loop_unref); + + return exit_code; +} |