|
Packit |
5756e2 |
// SPDX-License-Identifier: LGPL-2.1+
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-default.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include <glib-unix.h>
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "devices/bluetooth/nm-bluez5-dun.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-test-utils-core.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#define _NMLOG_DOMAIN LOGD_BT
|
|
Packit |
5756e2 |
#define _NMLOG(level, ...) \
|
|
Packit |
5756e2 |
nm_log ((level), _NMLOG_DOMAIN, \
|
|
Packit |
5756e2 |
NULL, NULL, \
|
|
Packit |
5756e2 |
"bt%s%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
|
Packit |
5756e2 |
NM_PRINT_FMT_QUOTED (gl.argv_cmd, "[", gl.argv_cmd, "]", "") \
|
|
Packit |
5756e2 |
_NM_UTILS_MACRO_REST (__VA_ARGS__))
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
struct {
|
|
Packit |
5756e2 |
int argc;
|
|
Packit |
5756e2 |
const char *const*argv;
|
|
Packit |
5756e2 |
const char *argv_cmd;
|
|
Packit |
5756e2 |
GMainLoop *loop;
|
|
Packit |
5756e2 |
} gl;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct _MainCmdInfo {
|
|
Packit |
5756e2 |
const char *name;
|
|
Packit |
5756e2 |
int (*main_func) (const struct _MainCmdInfo *main_cmd_info);
|
|
Packit |
5756e2 |
} MainCmdInfo;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#if WITH_BLUEZ5_DUN
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit |
5756e2 |
NMBluez5DunContext *dun_context;
|
|
Packit |
5756e2 |
GCancellable *cancellable;
|
|
Packit |
5756e2 |
guint timeout_id;
|
|
Packit |
5756e2 |
guint sig_term_id;
|
|
Packit |
5756e2 |
guint sig_int_id;
|
|
Packit |
5756e2 |
} DunConnectData;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit |
5756e2 |
_dun_connect_cb (NMBluez5DunContext *context,
|
|
Packit |
5756e2 |
const char *rfcomm_dev,
|
|
Packit |
5756e2 |
GError *error,
|
|
Packit |
5756e2 |
gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
DunConnectData *dun_connect_data = user_data;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
g_assert (dun_connect_data);
|
|
Packit |
5756e2 |
g_assert (!dun_connect_data->dun_context);
|
|
Packit |
5756e2 |
g_assert ((!!error) != (!!rfcomm_dev));
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
if (rfcomm_dev && !context) {
|
|
Packit |
5756e2 |
_LOGI ("dun-connect notifies path \"%s\". Wait longer...", rfcomm_dev);
|
|
Packit |
5756e2 |
return;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
if (rfcomm_dev) {
|
|
Packit |
5756e2 |
g_assert (context);
|
|
Packit |
5756e2 |
_LOGI ("dun-connect completed with path \"%s\"", rfcomm_dev);
|
|
Packit |
5756e2 |
} else {
|
|
Packit |
5756e2 |
g_assert (!context);
|
|
Packit |
5756e2 |
_LOGI ("dun-connect failed with error: %s", error->message);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
dun_connect_data->dun_context = context;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
g_main_loop_quit (gl.loop);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit |
5756e2 |
_dun_notify_tty_hangup_cb (NMBluez5DunContext *context,
|
|
Packit |
5756e2 |
gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
_LOGI ("dun-connect: notified TTY hangup");
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit |
5756e2 |
_timeout_cb (gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
DunConnectData *dun_connect_data = user_data;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
_LOGI ("timeout");
|
|
Packit |
5756e2 |
dun_connect_data->timeout_id = 0;
|
|
Packit |
5756e2 |
if (dun_connect_data->cancellable)
|
|
Packit |
5756e2 |
g_cancellable_cancel (dun_connect_data->cancellable);
|
|
Packit |
5756e2 |
return G_SOURCE_REMOVE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit |
5756e2 |
_sig_xxx_cb (DunConnectData *dun_connect_data, int sigid)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
_LOGI ("signal %s received", sigid == SIGTERM ? "SIGTERM" : "SIGINT");
|
|
Packit |
5756e2 |
g_main_loop_quit (gl.loop);
|
|
Packit |
5756e2 |
return G_SOURCE_CONTINUE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit |
5756e2 |
_sig_term_cb (gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
return _sig_xxx_cb (user_data, SIGTERM);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit |
5756e2 |
_sig_int_cb (gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
return _sig_xxx_cb (user_data, SIGINT);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
#endif
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static int
|
|
Packit |
5756e2 |
do_dun_connect (const MainCmdInfo *main_cmd_info)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
#if WITH_BLUEZ5_DUN
|
|
Packit |
5756e2 |
gs_unref_object GCancellable *cancellable = NULL;
|
|
Packit |
5756e2 |
gs_free_error GError *error = NULL;
|
|
Packit |
5756e2 |
const char *adapter;
|
|
Packit |
5756e2 |
const char *remote;
|
|
Packit |
5756e2 |
DunConnectData dun_connect_data = { };
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
if (gl.argc < 4) {
|
|
Packit |
5756e2 |
_LOGE ("missing arguments \"adapter\" and \"remote\"");
|
|
Packit |
5756e2 |
return -1;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
adapter = gl.argv[2];
|
|
Packit |
5756e2 |
remote = gl.argv[3];
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
cancellable = g_cancellable_new ();
|
|
Packit |
5756e2 |
dun_connect_data.cancellable = cancellable;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
if (!nm_bluez5_dun_connect (adapter,
|
|
Packit |
5756e2 |
remote,
|
|
Packit |
5756e2 |
cancellable,
|
|
Packit |
5756e2 |
_dun_connect_cb,
|
|
Packit |
5756e2 |
&dun_connect_data,
|
|
Packit |
5756e2 |
_dun_notify_tty_hangup_cb,
|
|
Packit |
5756e2 |
&dun_connect_data,
|
|
Packit |
5756e2 |
&error)) {
|
|
Packit |
5756e2 |
_LOGE ("connect failed to start: %s", error->message);
|
|
Packit |
5756e2 |
return -1;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
dun_connect_data.timeout_id = g_timeout_add (60000, _timeout_cb, &dun_connect_data);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
g_main_loop_run (gl.loop);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
nm_clear_g_source (&dun_connect_data.timeout_id);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
if (dun_connect_data.dun_context) {
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
dun_connect_data.sig_term_id = g_unix_signal_add (SIGTERM, _sig_term_cb, &dun_connect_data);
|
|
Packit |
5756e2 |
dun_connect_data.sig_int_id = g_unix_signal_add (SIGINT, _sig_int_cb, &dun_connect_data);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
g_main_loop_run (gl.loop);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
nm_clear_g_source (&dun_connect_data.sig_term_id);
|
|
Packit |
5756e2 |
nm_clear_g_source (&dun_connect_data.sig_int_id);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
nm_bluez5_dun_disconnect (g_steal_pointer (&dun_connect_data.dun_context));
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
return 0;
|
|
Packit |
5756e2 |
#else
|
|
Packit |
5756e2 |
_LOGE ("compiled without bluetooth DUN support");
|
|
Packit |
5756e2 |
return 1;
|
|
Packit |
5756e2 |
#endif
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/*****************************************************************************/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
NMTST_DEFINE ();
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
int
|
|
Packit |
5756e2 |
main (int argc, char **argv)
|
|
Packit |
5756e2 |
{
|
|
Packit |
5756e2 |
static const MainCmdInfo main_cmd_infos[] = {
|
|
Packit |
5756e2 |
{ .name = "dun-connect", .main_func = do_dun_connect, },
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
int exit_code = 0;
|
|
Packit |
5756e2 |
guint i;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
if (!g_getenv ("G_MESSAGES_DEBUG"))
|
|
Packit |
5756e2 |
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
nmtst_init_with_logging (&argc, &argv, "DEBUG", "ALL");
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
nm_logging_init (NULL, TRUE);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gl.argv = (const char *const*) argv;
|
|
Packit |
5756e2 |
gl.argc = argc;
|
|
Packit |
5756e2 |
gl.loop = g_main_loop_new (NULL, FALSE);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
_LOGI ("bluetooth test util start");
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
gl.argv_cmd = argc >= 2 ? argv[1] : NULL;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
for (i = 0; i < G_N_ELEMENTS (main_cmd_infos); i++) {
|
|
Packit |
5756e2 |
if (nm_streq0 (main_cmd_infos[i].name, gl.argv_cmd)) {
|
|
Packit |
5756e2 |
_LOGD ("start \"%s\"", gl.argv_cmd);
|
|
Packit |
5756e2 |
exit_code = main_cmd_infos[i].main_func (&main_cmd_infos[i]);
|
|
Packit |
5756e2 |
_LOGD ("completed with %d", exit_code);
|
|
Packit |
5756e2 |
break;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
if (gl.argv_cmd && i >= G_N_ELEMENTS (main_cmd_infos)) {
|
|
Packit |
5756e2 |
nm_log_err (LOGD_BT, "invalid command \"%s\"", gl.argv_cmd);
|
|
Packit |
5756e2 |
exit_code = -1;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
nm_clear_pointer (&gl.loop, g_main_loop_unref);
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
return exit_code;
|
|
Packit |
5756e2 |
}
|