⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdptool.c

📁 蓝牙的各种编程接口和各种按理介绍,还有一些例子和说明
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	}	argc -= optind;	argv += optind;	if (argc < 1) {		printf(add_help);		return -1;	}	si.name = strdup(argv[0]);	return add_service(0, &si);}/* Delete local service */int del_service(bdaddr_t *bdaddr, void *arg) {	uint32_t handle, range = 0x0000ffff;	sdp_list_t *attr;	sdp_session_t *sess;	sdp_record_t *rec;	if (!arg) { 		printf("Record handle was not specified.\n");		return -1;	}	sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);	if (!sess) {		printf("No local SDP server!\n");		return -1;	}	handle = strtoul((char *)arg, 0, 16);	attr = sdp_list_append(0, &range);	rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr);	sdp_list_free(attr, 0);	if (!rec) {		printf("Service Record not found.\n");		sdp_close(sess);		return -1;	}	if (sdp_record_unregister(sess, rec)) {		printf("Failed to unregister service record: %s\n", strerror(errno));		sdp_close(sess);		return -1;	}	printf("Service Record deleted.\n");	sdp_close(sess);	return 0;}static struct option del_options[] = {	{"help",    0,0, 'h'},	{0, 0, 0, 0}};static char *del_help = 	"Usage:\n"	"\tdel record_handle\n";int cmd_del(int argc, char **argv){	int opt;	for_each_opt(opt, del_options, 0) {		switch(opt) {		default:			printf(del_help);			return -1;		}	}	argc -= optind;	argv += optind;	if (argc < 1) {		printf(del_help);		return -1;	}	return del_service(0, argv[0]);}/* * Perform an inquiry and search/browse all peer found. */static void inquiry(handler_t handler, void *arg){	inquiry_info ii[20];	uint8_t count = 0;	int i;	printf("Inquiring ...\n");	if (sdp_general_inquiry(ii, 20, 8, &count) < 0) {		printf("Inquiry failed\n");		return;	}	for (i=0; i<count; i++)		handler(&ii[i].bdaddr, arg);}/* * Search for a specific SDP service */int do_search(bdaddr_t *bdaddr, struct search_context *context){	sdp_list_t *attrid, *search, *seq, *next;	uint32_t range = 0x0000ffff;	char str[20];	sdp_session_t *sess;	if (!bdaddr) {		inquiry(do_search, context);		return 0;	}	sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY);	ba2str(bdaddr, str);	if (!sess) {		printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno));		return -1;	}	if (context->svc)		printf("Searching for %s on %s ...\n", context->svc, str);	else		printf("Browsing %s ...\n", str);	attrid = sdp_list_append(0, &range);	search = sdp_list_append(0, &context->group);	if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) {		printf("Service Search failed: %s\n", strerror(errno));		sdp_close(sess);		return -1;	}	sdp_list_free(attrid, 0);	sdp_list_free(search, 0);	for (; seq; seq = next) {		sdp_record_t *rec = (sdp_record_t *) seq->data;		struct search_context sub_context;		if (context->tree) {			/* Display full tree */			sdp_printf_service_attr(rec);		} else {			/* Display user friendly form */			print_service_attr(rec);		}		printf("\n");				if (sdp_get_group_id(rec, &sub_context.group) != -1) {			/* Set the subcontext for browsing the sub tree */			memcpy(&sub_context, context, sizeof(struct search_context));			/* Browse the next level down if not done */			if (sub_context.group.value.uuid16 != context->group.value.uuid16)				do_search(bdaddr, &sub_context);		}		next = seq->next;		free(seq);		sdp_record_free(rec);	}	sdp_close(sess);	return 0;}static struct option browse_options[] = {	{"help",    0,0, 'h'},	{"tree",    0,0, 't'},	{0, 0, 0, 0}};static char *browse_help = 	"Usage:\n"	"\tbrowse [--tree] [bdaddr]\n";/* * Browse the full SDP database (i.e. list all services starting from the * root/top-level). */int cmd_browse(int argc, char **argv){	struct search_context context;	int opt;	/* Initialise context */	memset(&context, '\0', sizeof(struct search_context));	/* We want to browse the top-level/root */	sdp_uuid16_create(&(context.group), PUBLIC_BROWSE_GROUP);	for_each_opt(opt, browse_options, 0) {		switch(opt) {		case 't':			context.tree = 1;			break;		default:			printf(browse_help);			return -1;		}	}	argc -= optind;	argv += optind;	if (argc >= 1) {		bdaddr_t bdaddr;		estr2ba(argv[0], &bdaddr);		return do_search(&bdaddr, &context);	}	return do_search(0, &context);}static struct option search_options[] = {	{"help",    0,0, 'h'},	{"bdaddr",  1,0, 'b'},	{"tree",    0,0, 't'},	{0, 0, 0, 0}};static char *search_help = 	"Usage:\n"	"\tsearch [--bdaddr bdaddr] [--tree] SERVICE\n"	"SERVICE is a name (string) or UUID (0x1002)\n";/* * Search for a specific SDP service * * Note : we should support multiple services on the command line : *	sdptool search 0x0100 0x000f 0x1002 * (this would search a service supporting both L2CAP and BNEP directly in * the top level browse group) */int cmd_search(int argc, char **argv){	struct search_context context;	uint16_t class = 0;	bdaddr_t bdaddr;	int has_addr = 0;	int i;	int opt;	/* Initialise context */	memset(&context, '\0', sizeof(struct search_context));	for_each_opt(opt, search_options, 0) {		switch(opt) {		case 'b':			estr2ba(optarg, &bdaddr);			has_addr = 1;			break;		case 't':			context.tree = 1;			break;		default:			printf(search_help);			return -1;		}	}	argc -= optind;	argv += optind;	if (argc < 1) {		printf(search_help);		return -1;	}	/* Note : we need to find a way to support search combining	 * multiple services - Jean II */	context.svc = strdup(argv[0]);	if (!strncasecmp(context.svc, "0x", 2)) {		int num;		/* This is a UUID16, just convert to int */		sscanf(context.svc + 2, "%X", &num);		class = num;		printf("Class 0x%X\n", class);	} else {		/* Convert class name to an UUID */		for (i=0; service[i].name; i++)			if (strcasecmp(context.svc, service[i].name) == 0) {				class = service[i].class;				break;			}		if (!class) {			printf("Unknown service %s\n", context.svc);			return -1;		}	}		sdp_uuid16_create(&context.group, class);	if (has_addr)		return do_search(&bdaddr, &context);	return do_search(0, &context);}/* * Show how to get a specific SDP record by its handle. * Not really useful to the user, just show how it can be done... * Jean II */int get_service(bdaddr_t *bdaddr, struct search_context *context) {	sdp_list_t *attrid;	uint32_t range = 0x0000ffff;	sdp_record_t *rec;	sdp_session_t *session = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY);	if (!session) {		char str[20];		ba2str(bdaddr, str);		printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno));		return -1;	}	attrid = sdp_list_append(0, &range);	rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid);	sdp_list_free(attrid, 0);	sdp_close(session);	if (!rec) {		printf("Service get request failed.\n");		return -1;	}	if (context->tree) {		/* Display full tree */		sdp_printf_service_attr(rec);	} else {		/* Display user friendly form */		print_service_attr(rec);	}	printf("\n");	sdp_record_free(rec);	return 0;}static struct option get_options[] = {	{"help",    0,0, 'h'},	{"bdaddr",  1,0, 'b'},	{"tree",    0,0, 't'},	{0, 0, 0, 0}};static char *get_help = 	"Usage:\n"	"\tget [--tree] [--bdaddr bdaddr] record_handle\n";/* * Get a specific SDP record on the local SDP server */int cmd_get(int argc, char **argv){	struct search_context context;	bdaddr_t bdaddr;	int has_addr = 0;	int opt;	/* Initialise context */	memset(&context, '\0', sizeof(struct search_context));	for_each_opt(opt, get_options, 0) {		switch(opt) {		case 'b':			estr2ba(optarg, &bdaddr);			has_addr = 1;			break;		case 't':			context.tree = 1;			break;		default:			printf(get_help);			return -1;		}	}	argc -= optind;	argv += optind;	if (argc < 1) {		printf(get_help);		return -1;	}	/* Convert command line parameters */	context.handle = strtoul(argv[0], 0, 16);	return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context);}struct {	char *cmd;	int (*func)(int argc, char **argv);	char *doc;} command[] = {	{ "search",  cmd_search,      "Search for a service"          },	{ "browse",  cmd_browse,      "Browse all available services" },	{ "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" },	{ 0, 0, 0}};static void usage(void){	int i;	printf("sdptool - SDP Tool v%s\n", VERSION);	printf("Usage:\n"		"\tsdptool [options] <command> [command parameters]\n");	printf("Options:\n"		"\t--help\t\tDisplay help\n"		"\t--source\tSpecify source interface\n");	printf("Commands:\n");	for (i=0; command[i].cmd; i++)		printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc);	printf("\nServices:\n\t");	for (i=0; service[i].name; i++)		printf("%s ", service[i].name);	printf("\n");}static struct option main_options[] = {	{"help",   0, 0, 'h'},	{"source", 1, 0, 'S'},	{0, 0, 0, 0}};int main(int argc, char **argv){	int opt, i;	bacpy(&interface, BDADDR_ANY);	while ((opt=getopt_long(argc, argv, "+hS:", main_options, 0)) != -1) {		switch(opt) {		case 'S':			str2ba(optarg, &interface);			break;		case 'h':		default:			usage();			return -1;		}	}	argc -= optind;	argv += optind;	optind = 0;	if (argc < 1) {		usage();		return -1;	}	for (i=0; command[i].cmd; i++)		if (strncmp(command[i].cmd, argv[0], 4) == 0)			return command[i].func(argc, argv);	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -