diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c
index 475180c..15ef0ae 100644
--- a/obexd/src/bluetooth.c
+++ b/obexd/src/bluetooth.c
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/rfcomm.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
#include <glib.h>
#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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
+<record> \
+ <attribute id=\"0x0001\"> \
+ <sequence> \
+ <uuid value=\"0x1105\"/> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0004\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x0100\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0003\"/> \
+ <uint8 value=\"%u\" name=\"channel\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0008\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0009\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x1105\"/> \
+ <uint16 value=\"0x0100\" name=\"version\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0100\"> \
+ <text value=\"%s\" name=\"name\"/> \
+ </attribute> \
+ \
+ <attribute id=\"0x0303\"> \
+ <sequence> \
+ <uint8 value=\"0x01\"/> \
+ <uint8 value=\"0x01\"/> \
+ <uint8 value=\"0x02\"/> \
+ <uint8 value=\"0x03\"/> \
+ <uint8 value=\"0x04\"/> \
+ <uint8 value=\"0x05\"/> \
+ <uint8 value=\"0x06\"/> \
+ <uint8 value=\"0xff\"/> \
+ </sequence> \
+ </attribute> \
+</record>";
+
+const static gchar *ftp_record = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
+<record> \
+ <attribute id=\"0x0001\"> \
+ <sequence> \
+ <uuid value=\"0x1106\"/> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0004\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x0100\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0003\"/> \
+ <uint8 value=\"%u\" name=\"channel\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0008\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0009\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x1106\"/> \
+ <uint16 value=\"0x0100\" name=\"version\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0100\"> \
+ <text value=\"%s\" name=\"name\"/> \
+ </attribute> \
+</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)
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);
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);
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;
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 bfdac0a..627019f 100644
--- a/obexd/src/dbus.h
+++ b/obexd/src/dbus.h
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 c28e470..40f0099 100644
--- a/obexd/src/main.c
+++ b/obexd/src/main.c
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 791b3c1..4e832e3 100644
--- a/obexd/src/manager.c
+++ b/obexd/src/manager.c
static DBusConnection *connection = NULL;
+static DBusConnection *system_conn = NULL;
+
gboolean manager_init(DBusConnection *conn)
{
DBG("conn %p", 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,
if (agent)
agent_free(agent);
+ if (system_conn)
+ dbus_connection_unref(system_conn);
+
dbus_connection_unref(connection);
}
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 a58bd69..fad8a2d 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
gboolean auto_accept;
gchar *folder;
gchar *capability;
+ guint32 handle;
};
struct obex_session {