From e77fbdfaed30fd2e2be9e9b2554ebdd00ca37703 Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Thu, 2 Oct 2008 16:54:46 -0300 Subject: [PATCH] obexd: Makes use of the BlueZ Service plugin to add services records --- obexd/src/bluetooth.c | 221 +++++++++++++++++++----------------------- obexd/src/dbus.h | 2 + obexd/src/main.c | 16 +-- obexd/src/manager.c | 58 +++++++++++ obexd/src/obex.h | 1 + 5 files changed, 171 insertions(+), 127 deletions(-) diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c index 475180c40..15ef0ae72 100644 --- a/obexd/src/bluetooth.c +++ b/obexd/src/bluetooth.c @@ -36,8 +36,6 @@ #include #include #include -#include -#include #include @@ -46,108 +44,116 @@ #include "logging.h" #include "obex.h" - -static GSList *handles = NULL; -static sdp_session_t *session = NULL; - -static void add_lang_attr(sdp_record_t *r) -{ - sdp_lang_attr_t base_lang; - sdp_list_t *langs = 0; - - /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */ - base_lang.code_ISO639 = (0x65 << 8) | 0x6e; - base_lang.encoding = 106; - base_lang.base_offset = SDP_PRIMARY_LANG_BASE; - langs = sdp_list_append(0, &base_lang); - sdp_set_lang_attr(r, langs); - sdp_list_free(langs, 0); -} +#include "dbus.h" + +const static gchar *opp_record = " \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +"; + +const static gchar *ftp_record = " \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +"; static uint32_t register_record(const gchar *name, guint16 service, guint8 channel) { - uuid_t root_uuid, uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; - sdp_list_t *root, *svclass_id, *apseq, *profiles, *aproto, *proto[3]; - sdp_data_t *sdp_data; - sdp_profile_desc_t profile; - sdp_record_t record; - uint8_t formats = 0xFF; - int ret; + gchar *record; + gint handle; switch (service) { case OBEX_OPUSH: - sdp_uuid16_create(&uuid, OBEX_OBJPUSH_SVCLASS_ID); - sdp_uuid16_create(&profile.uuid, OBEX_OBJPUSH_PROFILE_ID); + record = g_markup_printf_escaped(opp_record, channel, name); break; case OBEX_FTP: - sdp_uuid16_create(&uuid, OBEX_FILETRANS_SVCLASS_ID); - sdp_uuid16_create(&profile.uuid, OBEX_FILETRANS_PROFILE_ID); + record = g_markup_printf_escaped(ftp_record, channel, name); break; default: return 0; } - /* Browse Groups */ - memset(&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(&record, root); - sdp_list_free(root, NULL); - - /* Service Class */ - svclass_id = sdp_list_append(NULL, &uuid); - sdp_set_service_classes(&record, svclass_id); - sdp_list_free(svclass_id, NULL); - - /* Profile Descriptor */ - profile.version = 0x0100; - profiles = sdp_list_append(NULL, &profile); - sdp_set_profile_descs(&record, profiles); - sdp_list_free(profiles, NULL); - - /* Protocol Descriptor */ - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap_uuid); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(NULL, &rfcomm_uuid); - sdp_data = sdp_data_alloc(SDP_UINT8, &channel); - proto[1] = sdp_list_append(proto[1], sdp_data); - apseq = sdp_list_append(apseq, proto[1]); - - sdp_uuid16_create(&obex_uuid, OBEX_UUID); - proto[2] = sdp_list_append(NULL, &obex_uuid); - apseq = sdp_list_append(apseq, proto[2]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(&record, aproto); - - sdp_data_free(sdp_data); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(proto[2], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(aproto, NULL); - - /* Suported Repositories */ - if (service == OBEX_OPUSH) - sdp_attr_add_new(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, - SDP_UINT8, &formats); - - /* Service Name */ - sdp_set_info_attr(&record, name, NULL, NULL); - - add_lang_attr(&record); - - ret = sdp_record_register(session, &record, SDP_RECORD_PERSIST); - - sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); - sdp_list_free(record.pattern, free); - - return (ret < 0 ? 0 : record.handle); + handle = add_record(record); + g_free(record); + + return handle; } static gboolean connect_event(GIOChannel *io, GIOCondition cond, gpointer user_data) @@ -199,7 +205,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel, struct sockaddr_rc laddr; GIOChannel *io; struct server *server; - uint32_t *handle; + uint32_t handle; int err, sk, arg; sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); @@ -245,21 +251,18 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel, goto failed; } - handle = malloc(sizeof(uint32_t)); - *handle = register_record(name, service, channel); - if (*handle == 0) { - g_free(handle); + handle = register_record(name, service, channel); + if (handle == 0) { err = EIO; goto failed; } - handles = g_slist_prepend(handles, handle); - server = g_malloc0(sizeof(struct server)); server->service = service; server->folder = g_strdup(folder); server->auto_accept = auto_accept; server->capability = g_strdup(capability); + server->handle = handle; io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(io, TRUE); @@ -268,7 +271,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel, connect_event, server, server_destroyed); g_io_channel_unref(io); - debug("Registered: %s, record handle: 0x%x, folder: %s", name, *handle, folder); + debug("Registered: %s, record handle: 0x%x, folder: %s", name, handle, folder); return 0; @@ -283,31 +286,11 @@ gint bluetooth_init(guint service, const gchar *name, const gchar *folder, guint8 channel, gboolean secure, gboolean auto_accept, const gchar *capability) { - if (!session) { - session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); - if (!session) { - gint err = errno; - error("sdp_connect(): %s(%d)", strerror(err), err); - return -err; - } - } - return server_register(service, name, channel, folder, secure, auto_accept, capability); } -static void unregister_record(gpointer rec_handle, gpointer user_data) -{ - uint32_t *handle = rec_handle; - - sdp_device_record_unregister_binary(session, BDADDR_ANY, *handle); - g_free(handle); -} - void bluetooth_exit(void) { - g_slist_foreach(handles, unregister_record, NULL); - g_slist_free(handles); - - sdp_close(session); + return; } diff --git a/obexd/src/dbus.h b/obexd/src/dbus.h index bfdac0a19..627019fa2 100644 --- a/obexd/src/dbus.h +++ b/obexd/src/dbus.h @@ -39,6 +39,8 @@ void register_transfer(guint32 id, struct obex_session *os); void unregister_transfer(guint32 id); +gint add_record(gchar *record); + void register_session(guint32 id, struct obex_session *os); void unregister_session(guint32 id); diff --git a/obexd/src/main.c b/obexd/src/main.c index c28e470b1..40f0099e7 100644 --- a/obexd/src/main.c +++ b/obexd/src/main.c @@ -252,20 +252,20 @@ int main(int argc, char *argv[]) plugin_init(); - if (opush) - server_start(OBEX_OPUSH, root_path, auto_accept, - NULL, devnode); - - if (ftp) - server_start(OBEX_FTP, root_path, auto_accept, - capability, devnode); - if (!manager_init(conn)) { error("manager_init failed"); plugin_cleanup(); exit(EXIT_FAILURE); } + if (opush) + server_start(OBEX_OPUSH, root_path, auto_accept, + NULL, devnode); + + if (ftp) + server_start(OBEX_FTP, root_path, auto_accept, + capability, devnode); + memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_term; sigaction(SIGINT, &sa, NULL); diff --git a/obexd/src/manager.c b/obexd/src/manager.c index 791b3c1a0..4e832e33a 100644 --- a/obexd/src/manager.c +++ b/obexd/src/manager.c @@ -314,6 +314,8 @@ static GDBusMethodTable session_methods[] = { static DBusConnection *connection = NULL; +static DBusConnection *system_conn = NULL; + gboolean manager_init(DBusConnection *conn) { DBG("conn %p", conn); @@ -322,6 +324,10 @@ gboolean manager_init(DBusConnection *conn) if (connection == NULL) return FALSE; + system_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL); + if (system_conn == NULL) + return FALSE; + return g_dbus_register_interface(connection, OPENOBEX_MANAGER_PATH, OPENOBEX_MANAGER_INTERFACE, manager_methods, manager_signals, NULL, @@ -340,6 +346,9 @@ void manager_cleanup(void) if (agent) agent_free(agent); + if (system_conn) + dbus_connection_unref(system_conn); + dbus_connection_unref(connection); } @@ -572,6 +581,55 @@ int request_authorization(gint32 cid, int fd, const gchar *filename, return 0; } +gint add_record(gchar *record) +{ + DBusMessage *msg, *reply; + const gchar *adapter_path; + guint32 handle; + + if (system_conn == NULL) + return 0; + + msg = dbus_message_new_method_call("org.bluez", "/", + "org.bluez.Manager", "DefaultAdapter"); + + reply = dbus_connection_send_with_reply_and_block(system_conn, msg, + -1, NULL); + if (reply == NULL) { + dbus_message_unref(msg); + return 0; + } + + dbus_message_unref(msg); + + dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &adapter_path, + DBUS_TYPE_INVALID); + + dbus_message_unref(reply); + + msg = dbus_message_new_method_call("org.bluez", adapter_path, + "org.bluez.Service", "AddRecord"); + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &record, + DBUS_TYPE_INVALID); + + reply = dbus_connection_send_with_reply_and_block(system_conn, msg, + -1, NULL); + if (reply == NULL) { + dbus_message_unref(msg); + return 0; + } + + dbus_message_unref(msg); + + dbus_message_get_args(reply, NULL, DBUS_TYPE_UINT32, &handle, + DBUS_TYPE_INVALID); + + dbus_message_unref(reply); + + return handle; +} + void register_session(guint32 id, struct obex_session *os) { gchar *path = g_strdup_printf("/session%u", id); diff --git a/obexd/src/obex.h b/obexd/src/obex.h index a58bd6956..fad8a2d69 100644 --- a/obexd/src/obex.h +++ b/obexd/src/obex.h @@ -47,6 +47,7 @@ struct server { gboolean auto_accept; gchar *folder; gchar *capability; + guint32 handle; }; struct obex_session { -- 2.47.3