summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-11-21 11:45:59 +0000
committerMarcel Holtmann <marcel@holtmann.org>2006-11-21 11:45:59 +0000
commit253ba836f00b17a4da1436520f3735593ba9493d (patch)
treee7bd3fc5ce506c89faea293ad70800223a0df395
parentbeb22838a0859410bb62f1c6a1fde1a4a13cab8c (diff)
Add support for XML based service records
-rw-r--r--hcid/service-agent.c129
1 files changed, 96 insertions, 33 deletions
diff --git a/hcid/service-agent.c b/hcid/service-agent.c
index a7e3a870..9c46dd1f 100644
--- a/hcid/service-agent.c
+++ b/hcid/service-agent.c
@@ -27,11 +27,14 @@
#include <stdio.h>
#include <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
#include <dbus/dbus.h>
@@ -39,6 +42,7 @@
static char *name = NULL;
static char *description = NULL;
+static char *filename = NULL;
static volatile sig_atomic_t __io_canceled = 0;
static volatile sig_atomic_t __io_terminated = 0;
@@ -180,11 +184,12 @@ static const DBusObjectPathVTable service_table = {
.message_function = service_message,
};
-static int add_record(DBusConnection *conn, const char *service_path)
+static int append_record_from_blob(DBusMessage *msg)
{
- DBusMessage *msg, *reply;
DBusMessageIter iter, array_iter;
- DBusError err;
+ dbus_message_iter_init_append(msg, &iter);
+ int i;
+
unsigned char record[] = {
0x35, 0x59, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19,
0x11, 0x01, 0x09, 0x00, 0x04, 0x35, 0x0c, 0x35,
@@ -199,10 +204,60 @@ static int add_record(DBusConnection *conn, const char *service_path)
0x01, 0x25, 0x08, 0x43, 0x4f, 0x4d, 0x20, 0x50,
0x6f, 0x72, 0x74 };
- int i;
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_BYTE_AS_STRING, &array_iter);
+
+ for (i = 0; i < sizeof(record); i++)
+ dbus_message_iter_append_basic(&array_iter,
+ DBUS_TYPE_BYTE, &record[i]);
+
+ dbus_message_iter_close_container(&iter, &array_iter);
+
+ return 0;
+}
+
+static int append_record_from_file(DBusMessage *msg)
+{
+ struct stat st;
+ char *record;
+ int fd;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return -1;
+ }
+
+ record = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (!record || record == MAP_FAILED) {
+ close(fd);
+ return -1;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &record,
+ DBUS_TYPE_INVALID);
+
+ munmap(record, st.st_size);
+
+ close(fd);
+
+ return 0;
+}
+
+static int add_record(DBusConnection *conn, const char *service_path)
+{
+ DBusMessage *msg, *reply;
+ DBusError error;
+ const char *method;
+ int err;
+ method = filename ? "AddServiceRecordAsXML" : "AddServiceRecord";
+
msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
- INTERFACE, "AddServiceRecord");
+ INTERFACE, method);
if (!msg) {
fprintf(stderr, "Can't allocate new method call\n");
return -1;
@@ -211,28 +266,28 @@ static int add_record(DBusConnection *conn, const char *service_path)
dbus_message_append_args(msg, DBUS_TYPE_STRING, &service_path,
DBUS_TYPE_INVALID);
- dbus_message_iter_init_append(msg, &iter);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_BYTE_AS_STRING, &array_iter);
-
- for (i = 0; i < sizeof(record); i++)
- dbus_message_iter_append_basic(&array_iter,
- DBUS_TYPE_BYTE, &record[i]);
+ if (filename)
+ err = append_record_from_file(msg);
+ else
+ err = append_record_from_blob(msg);
- dbus_message_iter_close_container(&iter, &array_iter);
+ if (err < 0) {
+ fprintf(stderr, "Can't create service record\n");
+ dbus_message_unref(msg);
+ return -1;
+ }
- dbus_error_init(&err);
+ dbus_error_init(&error);
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error);
dbus_message_unref(msg);
if (!reply) {
fprintf(stderr, "Can't register service record\n");
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "%s\n", err.message);
- dbus_error_free(&err);
+ if (dbus_error_is_set(&error)) {
+ fprintf(stderr, "%s\n", error.message);
+ dbus_error_free(&error);
}
return -1;
}
@@ -247,7 +302,7 @@ static int add_record(DBusConnection *conn, const char *service_path)
static int register_service(DBusConnection *conn, const char *service_path)
{
DBusMessage *msg, *reply;
- DBusError err;
+ DBusError error;
if (!dbus_connection_register_object_path(conn, service_path,
&service_table, NULL)) {
@@ -267,17 +322,17 @@ static int register_service(DBusConnection *conn, const char *service_path)
DBUS_TYPE_STRING, &description,
DBUS_TYPE_INVALID);
- dbus_error_init(&err);
+ dbus_error_init(&error);
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error);
dbus_message_unref(msg);
if (!reply) {
fprintf(stderr, "Can't register service agent\n");
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "%s\n", err.message);
- dbus_error_free(&err);
+ if (dbus_error_is_set(&error)) {
+ fprintf(stderr, "%s\n", error.message);
+ dbus_error_free(&error);
}
return -1;
}
@@ -292,7 +347,7 @@ static int register_service(DBusConnection *conn, const char *service_path)
static int unregister_service(DBusConnection *conn, const char *service_path)
{
DBusMessage *msg, *reply;
- DBusError err;
+ DBusError error;
msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
INTERFACE, "UnregisterService");
@@ -305,17 +360,17 @@ static int unregister_service(DBusConnection *conn, const char *service_path)
dbus_message_append_args(msg, DBUS_TYPE_STRING, &service_path,
DBUS_TYPE_INVALID);
- dbus_error_init(&err);
+ dbus_error_init(&error);
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error);
dbus_message_unref(msg);
if (!reply) {
fprintf(stderr, "Can't unregister service agent\n");
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "%s\n", err.message);
- dbus_error_free(&err);
+ if (dbus_error_is_set(&error)) {
+ fprintf(stderr, "%s\n", error.message);
+ dbus_error_free(&error);
}
return -1;
}
@@ -336,7 +391,8 @@ static void usage(void)
printf("Usage:\n"
"\tservice-agent [--name service-name]"
" [--description service-description]"
- " [--path service-path]\n"
+ " [--path service-path]"
+ " [--file service-record]\n"
"\n");
}
@@ -344,6 +400,7 @@ static struct option main_options[] = {
{ "name", 1, 0, 'n' },
{ "description", 1, 0, 'd' },
{ "path", 1, 0, 'p' },
+ { "file", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
};
@@ -358,7 +415,7 @@ int main(int argc, char *argv[])
snprintf(default_path, sizeof(default_path),
"/org/bluez/service_agent_%d", getpid());
- while ((opt = getopt_long(argc, argv, "+n:d:p:h", main_options, NULL)) != EOF) {
+ while ((opt = getopt_long(argc, argv, "+n:d:p:f:h", main_options, NULL)) != EOF) {
switch(opt) {
case 'n':
name = strdup(optarg);
@@ -373,6 +430,9 @@ int main(int argc, char *argv[])
}
service_path = strdup(optarg);
break;
+ case 'f':
+ filename = strdup(optarg);
+ break;
case 'h':
usage();
exit(0);
@@ -434,6 +494,9 @@ int main(int argc, char *argv[])
if (description)
free(description);
+ if (filename);
+ free(filename);
+
dbus_connection_unref(conn);
return 0;