Index: sdptool.c =================================================================== RCS file: /cvsroot/bluez/utils/tools/sdptool.c,v retrieving revision 1.61 diff -u -5 -r1.61 sdptool.c --- sdptool.c 15 Oct 2006 13:07:47 -0000 1.61 +++ sdptool.c 24 Oct 2006 06:43:13 -0000 @@ -43,10 +43,12 @@ #include #include #include +#include "sdp-xml.h" + #ifndef APPLE_AGENT_SVCLASS_ID #define APPLE_AGENT_SVCLASS_ID 0x2112 #endif #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) @@ -65,10 +67,11 @@ } #define DEFAULT_VIEW 0 /* Display only known attribute */ #define TREE_VIEW 1 /* Display full attribute tree */ #define RAW_VIEW 2 /* Display raw tree */ +#define XML_VIEW 3 /* Display xml tree */ /* Pass args to the inquiry/search handler */ struct search_context { char *svc; /* Service */ uuid_t group; /* Browse group */ @@ -3168,10 +3234,78 @@ sdp_close(sess); return ret; } +#define BUFFSIZE 256 + +static int add_xml_service(bdaddr_t *bdaddr, svc_info_t *si) +{ + sdp_session_t *sess; + int ret = -1; + FILE *fp; + char buf[BUFFSIZE]; + sdp_xml_context *context = 0; + sdp_record_t *rec = 0; + + if (!si->name) + return -1; + + fp = fopen(si->name, "r"); + if (!fp) { + fprintf(stderr, "Couldn't open %s\n", si->name); + return -1; + } + + context = sdp_xml_init_context(); + if (!context) { + fprintf(stderr, "Couldn't allocate context\n"); + return -1; + } + + for (;;) { + int done; + int len; + + len = fread(buf, 1, BUFFSIZE, fp); + + if (ferror(fp)) { + return -1; + } + done = feof(fp); + + if (sdp_xml_parse_chunk(context, buf, len, done) != 0) { + return -1; + } + + if (done) + break; + } + + rec = sdp_xml_get_record(context); + sdp_xml_free_context(context); + + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + if (!sess) + return -1; + + rec->handle = si->handle; + /* Remove the record handle attribute so SDP server assigns a new one */ + sdp_attr_remove(rec, 0x0); + + if (sdp_record_register(sess, rec, SDP_RECORD_PERSIST) < 0) + fprintf(stderr, "Registration failed\n"); + +done: + sdp_record_free(rec); + + free(si->name); + sdp_close(sess); + + return ret; +} + static struct option add_options[] = { { "help", 0, 0, 'h' }, { "handle", 1, 0, 'r' }, { "psm", 1, 0, 'p' }, { "channel", 1, 0, 'c' }, @@ -3234,10 +3368,55 @@ si.name = strdup(argv[0]); return add_service(0, &si); } +static struct option addxml_options[] = { + { "help", 0, 0, 'h' }, + { "handle", 1, 0, 'r' }, + { 0, 0, 0, 0 } +}; + +static char *addxml_help = + "Usage:\n" + "\tadd [--handle=RECORD_HANDLE] xmlfile\n"; + +static int cmd_addxml(int argc, char **argv) +{ + svc_info_t si; + int opt; + + memset(&si, 0, sizeof(si)); + si.handle = 0xffffffff; + + for_each_opt(opt, addxml_options, 0) { + switch (opt) { + case 'r': + if (strncasecmp(optarg, "0x", 2)) + si.handle = atoi(optarg); + else + si.handle = strtol(optarg + 2, NULL, 16); + break; + default: + printf(addxml_help); + return -1; + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(add_help); + return -1; + } + + si.name = strdup(argv[0]); + + return add_xml_service(0, &si); +} + /* Delete local service */ static int del_service(bdaddr_t *bdaddr, void *arg) { uint32_t handle, range = 0x0000ffff; sdp_list_t *attr; @@ -3327,10 +3506,15 @@ for (i = 0; i < count; i++) handler(&ii[i].bdaddr, arg); } +static void doprintf(void *data, const char *str) +{ + printf(str); +} + /* * Search for a specific SDP service */ static int do_search(bdaddr_t *bdaddr, struct search_context *context) { @@ -3381,12 +3565,15 @@ case TREE_VIEW: /* Display full tree */ print_tree_attr(rec); printf("\n"); break; + case XML_VIEW: + /* Display raw XML tree */ + convert_sdp_record_to_xml(rec, 0, doprintf); + break; default: - /* Display raw tree */ print_raw_attr(rec); break; } if (sdp_get_group_id(rec, &sub_context.group) != -1) { @@ -3407,10 +3594,11 @@ static struct option browse_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { "uuid", 1, 0, 'u' }, { "l2cap", 0, 0, 'l' }, { 0, 0, 0, 0 } }; @@ -3438,10 +3626,13 @@ context.view = TREE_VIEW; break; case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; case 'u': if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) { printf("Invalid uuid %s\n", optarg); return -1; } @@ -3471,10 +3662,11 @@ static struct option search_options[] = { { "help", 0, 0, 'h' }, { "bdaddr", 1, 0, 'b' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { 0, 0, 0, 0} }; static char *search_help = "Usage:\n" @@ -3512,10 +3704,13 @@ context.view = TREE_VIEW; break; case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; default: printf(search_help); return -1; } } @@ -3608,10 +3803,14 @@ case TREE_VIEW: /* Display full tree */ print_tree_attr(rec); printf("\n"); break; + case XML_VIEW: + /* Display raw XML tree */ + convert_sdp_record_to_xml(rec, 0, doprintf); + break; default: /* Display raw tree */ print_raw_attr(rec); break; } @@ -3622,10 +3821,11 @@ static struct option records_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { 0, 0, 0, 0 } }; static char *records_help = "Usage:\n" @@ -3650,10 +3850,14 @@ context.view = TREE_VIEW; break; case 'r': context.view = RAW_VIEW; break; + + case 'x': + context.view = XML_VIEW; + break; default: printf(records_help); return -1; } } @@ -3684,10 +3888,11 @@ static struct option get_options[] = { { "help", 0, 0, 'h' }, { "bdaddr", 1, 0, 'b' }, { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, + { "xml", 0, 0, 'x' }, { 0, 0, 0, 0 } }; static char *get_help = "Usage:\n" @@ -3716,10 +3921,13 @@ context.view = TREE_VIEW; break; case 'r': context.view = RAW_VIEW; break; + case 'x': + context.view = XML_VIEW; + break; default: printf(get_help); return -1; } } @@ -3749,10 +3957,11 @@ { "add", cmd_add, "Add local service" }, { "del", cmd_del, "Delete local service" }, { "get", cmd_get, "Get local service" }, { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, + { "addxml", cmd_addxml, "Add local service (XML format)" }, { 0, 0, 0 } }; static void usage(void) {