409
437
dbus_message_unref(reply);
440
static void get_adapter_properties(const char *path, const char *handle,
443
bluetooth_send_with_reply(path, BLUEZ_ADAPTER_INTERFACE,
444
"GetProperties", adapter_properties_cb,
445
g_strdup(path), g_free, -1, DBUS_TYPE_INVALID);
448
static void remove_record(struct server *server)
452
if (server->handle == 0)
455
msg = dbus_message_new_method_call(BLUEZ_SERVICE, adapter_any_path,
456
BLUEZ_SERVICE_INTERFACE,
459
ofono_error("Unable to allocate D-Bus RemoveRecord message");
463
dbus_message_append_args(msg, DBUS_TYPE_UINT32, &server->handle,
465
g_dbus_send_message(connection, msg);
467
ofono_info("Unregistered handle for channel %d: 0x%x",
468
server->channel, server->handle);
471
static void cb_data_destroy(gpointer data)
473
struct cb_data *cb_data = data;
475
if (cb_data->source != 0)
476
g_source_remove(cb_data->source);
478
g_free(cb_data->path);
482
static void cancel_authorization(struct cb_data *user_data)
486
msg = dbus_message_new_method_call(BLUEZ_SERVICE, user_data->path,
487
BLUEZ_SERVICE_INTERFACE,
488
"CancelAuthorization");
491
ofono_error("Unable to allocate D-Bus CancelAuthorization"
496
g_dbus_send_message(connection, msg);
499
static gboolean client_event(GIOChannel *chan, GIOCondition cond, gpointer data)
501
struct cb_data *cb_data = data;
503
cancel_authorization(cb_data);
509
static void auth_cb(DBusPendingCall *call, gpointer user_data)
511
struct cb_data *cb_data = user_data;
512
struct server *server = cb_data->server;
513
DBusMessage *reply = dbus_pending_call_steal_reply(call);
517
dbus_error_init(&derr);
519
if (dbus_set_error_from_message(&derr, reply)) {
520
ofono_error("RequestAuthorization error: %s, %s",
521
derr.name, derr.message);
523
if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY))
524
cancel_authorization(cb_data);
526
dbus_error_free(&derr);
528
ofono_info("RequestAuthorization succeeded");
530
if (!bt_io_accept(cb_data->io, server->connect_cb,
531
server->user_data, NULL, &err)) {
532
ofono_error("%s", err->message);
537
dbus_message_unref(reply);
540
static void new_connection(GIOChannel *io, gpointer user_data)
542
struct server *server = user_data;
546
char laddress[18], raddress[18];
552
bt_io_get(io, BT_IO_RFCOMM, &err, BT_IO_OPT_SOURCE, laddress,
553
BT_IO_OPT_DEST, raddress,
554
BT_IO_OPT_CHANNEL, &channel,
557
ofono_error("%s", err->message);
562
ofono_info("New connection for %s on channel %u from: %s,", laddress,
566
g_hash_table_iter_init(&iter, adapter_address_hash);
568
while (g_hash_table_iter_next(&iter, &key, &value)) {
569
if (g_str_equal(laddress, value) == TRUE) {
578
cbd = g_try_new0(struct cb_data, 1);
580
ofono_error("Unable to allocate client cb_data structure");
584
cbd->path = g_strdup(path);
585
cbd->server = server;
590
if (bluetooth_send_with_reply(path, BLUEZ_SERVICE_INTERFACE,
591
"RequestAuthorization",
592
auth_cb, cbd, cb_data_destroy,
593
TIMEOUT, DBUS_TYPE_STRING, &addr,
594
DBUS_TYPE_UINT32, &server->handle,
595
DBUS_TYPE_INVALID) < 0) {
596
ofono_error("Request Bluetooth authorization failed");
600
ofono_info("RequestAuthorization(%s, 0x%x)", raddress, server->handle);
602
cbd->source = g_io_add_watch(io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
606
static void remove_service_handle(gpointer data, gpointer user_data)
608
struct server *server = data;
613
static void add_record_cb(DBusPendingCall *call, gpointer user_data)
615
struct server *server = user_data;
616
DBusMessage *reply = dbus_pending_call_steal_reply(call);
619
dbus_error_init(&derr);
621
if (dbus_set_error_from_message(&derr, reply)) {
622
ofono_error("Replied with an error: %s, %s",
623
derr.name, derr.message);
624
dbus_error_free(&derr);
628
dbus_message_get_args(reply, NULL, DBUS_TYPE_UINT32, &server->handle,
631
ofono_info("Registered handle for channel %d: 0x%x",
632
server->channel, server->handle);
635
dbus_message_unref(reply);
638
static void add_record(gpointer data, gpointer user_data)
640
struct server *server = data;
642
if (server->sdp_record == NULL)
645
bluetooth_send_with_reply(adapter_any_path,
646
BLUEZ_SERVICE_INTERFACE, "AddRecord",
647
add_record_cb, server, NULL, -1,
648
DBUS_TYPE_STRING, &server->sdp_record,
652
static void find_adapter_cb(DBusPendingCall *call, gpointer user_data)
654
DBusMessage *reply = dbus_pending_call_steal_reply(call);
658
dbus_error_init(&derr);
660
if (dbus_set_error_from_message(&derr, reply)) {
661
ofono_error("Replied with an error: %s, %s",
662
derr.name, derr.message);
663
dbus_error_free(&derr);
667
dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
670
adapter_any_path = g_strdup(path);
672
g_slist_foreach(server_list, (GFunc) add_record, NULL);
675
dbus_message_unref(reply);
412
678
static gboolean adapter_added(DBusConnection *connection, DBusMessage *message,
590
875
bluetooth_unref();
878
struct server *bluetooth_register_server(guint8 channel, const char *sdp_record,
879
ConnectFunc cb, gpointer user_data)
881
struct server *server;
884
server = g_try_new0(struct server, 1);
888
server->channel = channel;
890
server->io = bt_io_listen(BT_IO_RFCOMM, NULL, new_connection,
892
BT_IO_OPT_CHANNEL, server->channel,
893
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
895
if (server->io == NULL) {
903
if (sdp_record != NULL)
904
server->sdp_record = g_strdup(sdp_record);
906
server->connect_cb = cb;
907
server->user_data = user_data;
909
server_list = g_slist_prepend(server_list, server);
911
if (adapter_any_path != NULL)
912
add_record(server, NULL);
917
void bluetooth_unregister_server(struct server *server)
919
server_list = g_slist_remove(server_list, server);
921
remove_record(server);
923
if (server->io != NULL) {
924
g_io_channel_shutdown(server->io, TRUE, NULL);
925
g_io_channel_unref(server->io);
929
g_free(server->sdp_record);
593
935
OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION,
594
936
OFONO_PLUGIN_PRIORITY_DEFAULT, NULL, NULL)