📄 sdptool.c
字号:
/* Add this sequence to the attrib list */ pSequenceHolder = sdp_seq_alloc(dtdArray, valueArray, argc); if (pSequenceHolder) { sdp_attr_replace(rec, attrib, pSequenceHolder); /* Update on the server */ ret = sdp_device_record_update(session, &interface, rec); if (ret < 0) printf("Service Record update failed (%d).\n", errno); } else printf("Failed to create pSequenceHolder\n"); /* Cleanup */ for (i = 0; i < argc; i++) free(allocArray[i]); free(dtdArray); free(valueArray); free(allocArray); sdp_record_free(rec); return ret;}static struct option seq_options[] = { { "help", 0, 0, 'h' }, { 0, 0, 0, 0 }};static char *seq_help = "Usage:\n" "\tget record_handle attrib_id attrib_values\n";/* * Add an attribute sequence to an existing SDP record * on the local SDP server */static int cmd_setseq(int argc, char **argv){ int opt, status; uint32_t handle; uint16_t attrib; sdp_session_t *sess; for_each_opt(opt, seq_options, NULL) { switch(opt) { default: printf(seq_help); return -1; } } argc -= optind; argv += optind; if (argc < 3) { printf(seq_help); return -1; } /* Convert command line args */ handle = strtoul(argv[0], NULL, 16); attrib = strtoul(argv[1], NULL, 16); argc -= 2; argv += 2; /* Do it */ sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!sess) return -1; status = set_attribseq(sess, handle, attrib, argc, argv); sdp_close(sess); return status;}static void print_service_class(void *value, void *userData){ char ServiceClassUUID_str[MAX_LEN_SERVICECLASS_UUID_STR]; uuid_t *uuid = (uuid_t *)value; sdp_uuid2strn(uuid, UUID_str, MAX_LEN_UUID_STR); sdp_svclass_uuid2strn(uuid, ServiceClassUUID_str, MAX_LEN_SERVICECLASS_UUID_STR); if (uuid->type != SDP_UUID128) printf(" \"%s\" (0x%s)\n", ServiceClassUUID_str, UUID_str); else printf(" UUID 128: %s\n", UUID_str);}static void print_service_desc(void *value, void *user){ char str[MAX_LEN_PROTOCOL_UUID_STR]; sdp_data_t *p = (sdp_data_t *)value, *s; int i = 0, proto = 0; for (; p; p = p->next, i++) { switch (p->dtd) { case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: sdp_uuid2strn(&p->val.uuid, UUID_str, MAX_LEN_UUID_STR); sdp_proto_uuid2strn(&p->val.uuid, str, sizeof(str)); proto = sdp_uuid_to_proto(&p->val.uuid); printf(" \"%s\" (0x%s)\n", str, UUID_str); break; case SDP_UINT8: if (proto == RFCOMM_UUID) printf(" Channel: %d\n", p->val.uint8); else printf(" uint8: 0x%x\n", p->val.uint8); break; case SDP_UINT16: if (proto == L2CAP_UUID) { if (i == 1) printf(" PSM: %d\n", p->val.uint16); else printf(" Version: 0x%04x\n", p->val.uint16); } else if (proto == BNEP_UUID) if (i == 1) printf(" Version: 0x%04x\n", p->val.uint16); else printf(" uint16: 0x%x\n", p->val.uint16); else printf(" uint16: 0x%x\n", p->val.uint16); break; case SDP_SEQ16: printf(" SEQ16:"); for (s = p->val.dataseq; s; s = s->next) printf(" %x", s->val.uint16); printf("\n"); break; case SDP_SEQ8: printf(" SEQ8:"); for (s = p->val.dataseq; s; s = s->next) printf(" %x", s->val.uint8); printf("\n"); break; default: printf(" FIXME: dtd=0%x\n", p->dtd); break; } }}static void print_lang_attr(void *value, void *user){ sdp_lang_attr_t *lang = (sdp_lang_attr_t *)value; printf(" code_ISO639: 0x%02x\n", lang->code_ISO639); printf(" encoding: 0x%02x\n", lang->encoding); printf(" base_offset: 0x%02x\n", lang->base_offset);}static void print_access_protos(void *value, void *userData){ sdp_list_t *protDescSeq = (sdp_list_t *)value; sdp_list_foreach(protDescSeq, print_service_desc, 0);}static void print_profile_desc(void *value, void *userData){ sdp_profile_desc_t *desc = (sdp_profile_desc_t *)value; char str[MAX_LEN_PROFILEDESCRIPTOR_UUID_STR]; sdp_uuid2strn(&desc->uuid, UUID_str, MAX_LEN_UUID_STR); sdp_profile_uuid2strn(&desc->uuid, str, MAX_LEN_PROFILEDESCRIPTOR_UUID_STR); printf(" \"%s\" (0x%s)\n", str, UUID_str); if (desc->version) printf(" Version: 0x%04x\n", desc->version);}/* * Parse a SDP record in user friendly form. */static void print_service_attr(sdp_record_t *rec){ sdp_list_t *list = 0, *proto = 0; sdp_record_print(rec); printf("Service RecHandle: 0x%x\n", rec->handle); if (sdp_get_service_classes(rec, &list) == 0) { printf("Service Class ID List:\n"); sdp_list_foreach(list, print_service_class, 0); sdp_list_free(list, free); } if (sdp_get_access_protos(rec, &proto) == 0) { printf("Protocol Descriptor List:\n"); sdp_list_foreach(proto, print_access_protos, 0); sdp_list_foreach(proto, (sdp_list_func_t)sdp_list_free, 0); sdp_list_free(proto, 0); } if (sdp_get_lang_attr(rec, &list) == 0) { printf("Language Base Attr List:\n"); sdp_list_foreach(list, print_lang_attr, 0); sdp_list_free(list, free); } if (sdp_get_profile_descs(rec, &list) == 0) { printf("Profile Descriptor List:\n"); sdp_list_foreach(list, print_profile_desc, 0); sdp_list_free(list, free); }}/* * Support for Service (de)registration */typedef struct { uint32_t handle; char *name; char *provider; char *desc; unsigned int class; unsigned int profile; uint16_t psm; uint8_t channel; uint8_t network;} svc_info_t;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);}static int add_sp(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto; uuid_t root_uuid, sp_uuid, l2cap, rfcomm; sdp_profile_desc_t profile; sdp_record_t record; uint8_t u8 = si->channel ? si->channel : 1; sdp_data_t *channel; int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_list_free(root, 0); sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID); svclass_id = sdp_list_append(0, &sp_uuid); sdp_set_service_classes(&record, svclass_id); sdp_list_free(svclass_id, 0); sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID); profile.version = 0x0100; profiles = sdp_list_append(0, &profile); sdp_set_profile_descs(&record, profiles); sdp_list_free(profiles, 0); sdp_uuid16_create(&l2cap, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap); apseq = sdp_list_append(0, proto[0]); sdp_uuid16_create(&rfcomm, RFCOMM_UUID); proto[1] = sdp_list_append(0, &rfcomm); channel = sdp_data_alloc(SDP_UINT8, &u8); proto[1] = sdp_list_append(proto[1], channel); apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); add_lang_attr(&record); sdp_set_info_attr(&record, "Serial Port", "BlueZ", "COM Port"); sdp_set_url_attr(&record, "http://www.bluez.org/", "http://www.bluez.org/", "http://www.bluez.org/"); sdp_set_service_id(&record, sp_uuid); sdp_set_service_ttl(&record, 0xffff); sdp_set_service_avail(&record, 0xff); sdp_set_record_state(&record, 0x00001234); if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("Serial Port service registered\n");end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); return ret;}static int add_dun(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root, *aproto; uuid_t rootu, dun, gn, l2cap, rfcomm; sdp_profile_desc_t profile; sdp_list_t *proto[2]; sdp_record_t record; uint8_t u8 = si->channel ? si->channel : 2; sdp_data_t *channel; int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &rootu); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID); svclass_id = sdp_list_append(0, &dun); sdp_uuid16_create(&gn, GENERIC_NETWORKING_SVCLASS_ID); svclass_id = sdp_list_append(svclass_id, &gn); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID); profile.version = 0x0100; pfseq = sdp_list_append(0, &profile); sdp_set_profile_descs(&record, pfseq); sdp_uuid16_create(&l2cap, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap); apseq = sdp_list_append(0, proto[0]); sdp_uuid16_create(&rfcomm, RFCOMM_UUID); proto[1] = sdp_list_append(0, &rfcomm); channel = sdp_data_alloc(SDP_UINT8, &u8); proto[1] = sdp_list_append(proto[1], channel); apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("Dial-Up Networking service registered\n");end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); return ret;}static int add_fax(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint8_t u8 = si->channel? si->channel : 3; sdp_data_t *channel; int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); svclass_id = sdp_list_append(0, &fax_uuid); sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); svclass_id = sdp_list_append(svclass_id, &tel_uuid); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); profile.version = 0x0100; pfseq = sdp_list_append(0, &profile); sdp_set_profile_descs(&record, pfseq); sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap_uuid); apseq = sdp_list_append(0, proto[0]); sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); proto[1] = sdp_list_append(0, &rfcomm_uuid); channel = sdp_data_alloc(SDP_UINT8, &u8); proto[1] = sdp_list_append(proto[1], channel); apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); sdp_set_info_attr(&record, "Fax", 0, 0); if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("Fax service registered\n");end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); return ret;}static int add_lan(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint8_t u8 = si->channel ? si->channel : 4; sdp_data_t *channel; int ret = 0; memset(&record, 0, sizeof(sdp_record_t)); record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&svclass_uuid, LAN_ACCESS_SVCLASS_ID); svclass_id = sdp_list_append(0, &svclass_uuid); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile.uuid, LAN_ACCESS_PROFILE_ID); profile.version = 0x0100; pfseq = sdp_list_append(0, &profile); sdp_set_profile_descs(&record, pfseq); sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap_uuid); apseq = sdp_list_append(0, proto[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -