📄 sdptool.c
字号:
memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = 0xffffffff; 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 (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { 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_opush(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; sdp_record_t record; uint8_t chan = si->channel? si->channel: 4; sdp_data_t *channel; uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; //uint8_t formats[] = { 0xff }; void *dtds[sizeof(formats)], *values[sizeof(formats)]; int i; uint8_t dtd = SDP_UINT8; sdp_data_t *sflist; int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = 0xffffffff; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID); svclass_id = sdp_list_append(0, &opush_uuid); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID); profile[0].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, &chan); proto[1] = sdp_list_append(proto[1], channel); apseq = sdp_list_append(apseq, proto[1]); sdp_uuid16_create(&obex_uuid, OBEX_UUID); proto[2] = sdp_list_append(0, &obex_uuid); apseq = sdp_list_append(apseq, proto[2]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); for (i = 0; i < sizeof(formats); i++) { dtds[i] = &dtd; values[i] = &formats[i]; } sflist = sdp_seq_alloc(dtds, values, sizeof(formats)); sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist); sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("OBEX Object Push service registered\n");end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(proto[2], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); return ret;}static int add_file_trans(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; sdp_record_t record; uint8_t u8 = si->channel? si->channel: 4; sdp_data_t *channel; int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = 0xffffffff; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&ftrn_uuid, OBEX_FILETRANS_SVCLASS_ID); svclass_id = sdp_list_append(0, &ftrn_uuid); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile[0].uuid, OBEX_FILETRANS_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(0, &profile[0]); 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]); sdp_uuid16_create(&obex_uuid, OBEX_UUID); proto[2] = sdp_list_append(0, &obex_uuid); apseq = sdp_list_append(apseq, proto[2]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("OBEX File Transfer service registered\n");end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(proto[2], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); return ret;}static int add_nap(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint16_t lp = 0x000f, ver = 0x0100; sdp_data_t *psm, *version; int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = 0xffffffff; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&ftrn_uuid, NAP_SVCLASS_ID); svclass_id = sdp_list_append(0, &ftrn_uuid); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(0, &profile[0]); sdp_set_profile_descs(&record, pfseq); sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap_uuid); psm = sdp_data_alloc(SDP_UINT16, &lp); proto[0] = sdp_list_append(proto[0], psm); apseq = sdp_list_append(0, proto[0]); sdp_uuid16_create(&bnep_uuid, BNEP_UUID); proto[1] = sdp_list_append(0, &bnep_uuid); version = sdp_data_alloc(SDP_UINT16, &ver); proto[1] = sdp_list_append(proto[1], version); { uint16_t ptype[4] = { 0x0010, 0x0020, 0x0030, 0x0040 }; sdp_data_t *head, *pseq; int p; for (p = 0, head = NULL; p < 4; p++) { sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); head = sdp_seq_append(head, data); } pseq = sdp_data_alloc(SDP_SEQ16, head); proto[1] = sdp_list_append(proto[1], pseq); } apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("NAP service registered\n");end: sdp_data_free(version); sdp_data_free(psm); 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_gn(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint16_t lp = 0x000f, ver = 0x0100; sdp_data_t *psm, *version; int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = 0xffffffff; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&ftrn_uuid, GN_SVCLASS_ID); svclass_id = sdp_list_append(0, &ftrn_uuid); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(0, &profile[0]); sdp_set_profile_descs(&record, pfseq); sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); proto[0] = sdp_list_append(0, &l2cap_uuid); psm = sdp_data_alloc(SDP_UINT16, &lp); proto[0] = sdp_list_append(proto[0], psm); apseq = sdp_list_append(0, proto[0]); sdp_uuid16_create(&bnep_uuid, BNEP_UUID); proto[1] = sdp_list_append(0, &bnep_uuid); version = sdp_data_alloc(SDP_UINT16, &ver); proto[1] = sdp_list_append(proto[1], version); apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); sdp_set_info_attr(&record, "Group Network Service", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("GN service registered\n");end: sdp_data_free(version); sdp_data_free(psm); 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_hid(sdp_session_t *sess, svc_info_t *si){ return -1;}static int add_cip(sdp_session_t *sess, svc_info_t *si){ return -1;}static int add_ctp(sdp_session_t *session, svc_info_t *si){ sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, tcsbin, ctp; sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[2]; sdp_record_t record; uint8_t netid = 0x02; // 0x01-0x07 cf. p120 profile document sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); record.handle = 0xffffffff; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); sdp_uuid16_create(&ctp, CORDLESS_TELEPHONY_SVCLASS_ID); svclass_id = sdp_list_append(0, &ctp); sdp_set_service_classes(&record, svclass_id); sdp_uuid16_create(&profile[0].uuid, CORDLESS_TELEPHONY_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(0, &profile[0]); 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(&tcsbin, TCS_BIN_UUID); proto[1] = sdp_list_append(0, &tcsbin); apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); sdp_attr_add(&record, SDP_EXTERNAL_NETWORK, network); sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); ret = -1; goto end; } printf("CTP service registered\n");end: sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); sdp_data_free(network); return ret;}struct { char *name; uint16_t class; int (*add)(sdp_session_t *sess, svc_info_t *si);} service[] = { { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, { "HSET", HEADSET_SVCLASS_ID, add_headset }, { "FAX", FAX_SVCLASS_ID, add_fax }, { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, { "NAP", NAP_SVCLASS_ID, add_nap }, { "GN", GN_SVCLASS_ID, add_gn }, { "HID", HID_SVCLASS_ID, add_hid }, { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, { 0 }};/* Add local service */int add_service(bdaddr_t *bdaddr, svc_info_t *si){ int i; sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); if (!sess) return -1; if (si->name) for (i=0; service[i].name; i++) if (!strcasecmp(service[i].name, si->name)) { int ret = service[i].add(sess, si); free(si->name); sdp_close(sess); return ret; } printf("Unknown service name: %s\n", si->name); free(si->name); sdp_close(sess); return -1;}static struct option add_options[] = { {"help", 0,0, 'h'}, {"channel", 1,0, 'c'}, {0, 0, 0, 0}};static char *add_help = "Usage:\n" "\tadd [--channel=CHAN] service\n";int cmd_add(int argc, char **argv){ svc_info_t si; int opt; memset(&si, 0, sizeof(si)); for_each_opt(opt, add_options, 0) { switch(opt) { case 'c': si.channel = atoi(optarg); break; default: printf(add_help); return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -