Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

airplay service cannot be discovered #5

Open
CoolBoy119 opened this issue Jan 31, 2024 · 12 comments
Open

airplay service cannot be discovered #5

CoolBoy119 opened this issue Jan 31, 2024 · 12 comments

Comments

@CoolBoy119
Copy link

I use this library to register the airplay service, but it cannot be discovered using a Mac computer. Are there any restrictions?

@CoolBoy119
Copy link
Author

I found that a crash occurs when adding a txt record

@philippe44
Copy link
Owner

Can you share your code?

@CoolBoy119
Copy link
Author

I just do some update in climdnssvc.c,this is my code:
`int main(int argc, char argv[]) {
// const char
* txt = NULL;
struct in_addr host;
char hostname[256],* arg, * identity = NULL, * type = NULL, * addr = NULL;
int port = 0;
bool verbose = false;

// if (argc <= 2) {
// 	print_usage();
// 	exit(0);
// }

#ifdef _WIN32
winsock_init();
#endif

signal(SIGINT, sighandler);
signal(SIGTERM, sighandler);

#if defined(SIGPIPE)
signal(SIGPIPE, SIG_IGN);
#endif
#if defined(SIGQUIT)
signal(SIGQUIT, sighandler);
#endif
#if defined(SIGHUP)
signal(SIGHUP, sighandler);
#endif

// while ((arg = *++argv) != NULL) {
// 	if (!strcasecmp(arg, "-o") || !strcasecmp(arg, "host")) {
// 		addr = *++argv;
// 		argc -= 2;
// 	} else if (!strcasecmp(arg, "-p")) {
// 		port = atoi(*++argv);
// 	} else if (!strcasecmp(arg, "-v")) {
// 		verbose = true;
// 	} else if (!strcasecmp(arg, "-t")) {
// 		(void)! asprintf(&type, "%s.local", *++argv);
// 	} else if (!strcasecmp(arg, "-i")) {
// 		identity = *++argv;
// 	} else {
// 		// nothing let's try to be smart and handle legacy crap		
// 		if (!identity) identity = *argv;
// 		else if (!type) (void) !asprintf(&type, "%s.local", *argv);
// 		else if (!port) port = atoi(*argv);
// 		else {
// 			txt = (const char**) malloc((argc + 1) * sizeof(char**));
// 			memcpy(txt, argv, argc * sizeof(char**));
// 			txt[argc] = NULL;
// 			break;
// 		}
// 		argc--;
// 	}
// }

char* identity_raop="cc3d825f7ed1@mdnslib";
char* type_raop="_raop._tcp.local";
short port_raop=6012;
const char* txt_raop[]= {NULL, "tp=UDP", "sm=false", "sv=false", "ek=1",
				"et=0,1", "md=0,1,2", "cn=0,1", "ch=2",
				"ss=16", "sr=44100", "vn=3", "txtvers=1",
				NULL 
				 };			

gethostname(hostname, sizeof(hostname));
strcat(hostname, ".local");
host = get_interface(addr);

svr = mdnsd_start(host, verbose);
if (svr) {
	printf("host: %s\nidentity: %s\ntype: %s\nip: %s\nport: %u\n", hostname, identity, type, inet_ntoa(host), port);

	mdnsd_set_hostname(svr, hostname, host);
	svc_raop = mdnsd_register_svc(svr, identity_raop, type_raop, port_raop, NULL, txt_raop);
	// mdns_service_destroy(svc);

#ifdef _WIN32
Sleep(INFINITE);
#else
pause();
#endif
mdns_service_remove(svr, svc_raop);
mdnsd_stop(svr);
} else {
printf("Can't start server");
print_usage();
}

free(type);
if (txt_raop) free(txt_raop);

#ifdef _WIN32
winsock_close();
#endif

return 0;

}
`

@CoolBoy119
Copy link
Author

I found it could not create a TXT record in mdnsd_register_svc,it may not enter this branch.
image

@CoolBoy119
Copy link
Author

when I use it with removing the first NULL element in txt, it can enter the branch,but a segfault occurred during runtime.
const char* txt_raop[]= { "tp=UDP", "sm=false", "sv=false", "ek=1",
"et=0,1", "md=0,1,2", "cn=0,1", "ch=2",
"ss=16", "sr=44100", "vn=3", "txtvers=1"
};

@philippe44
Copy link
Owner

philippe44 commented Feb 1, 2024

I think you misunderstood the syntax of TXT. It's an array of pointers and a NULL indicates the last item. If you put NULL first, nothing will be taken into account. If you forget the NULL at the end, the parser will runaway everywhere and crash

@CoolBoy119
Copy link
Author

But it also crashed if I only placed NULL at the end.

@philippe44
Copy link
Owner

philippe44 commented Feb 1, 2024

You either don't set a TXT at all (the txt parameter in the function call is NULL) or it includes at least one element and then finishes by NULL. You can't obviously send an array with just NULL inside, you send a NULL array instead.

@CoolBoy119
Copy link
Author

CoolBoy119 commented Feb 2, 2024

yes,I just update with this,it also crash.
const char* txt_raop[]= {"tp=UDP", "sm=false", "sv=false", "ek=1",
"et=0,1", "md=0,1,2", "cn=0,1", "ch=2",
"ss=16", "sr=44100", "vn=3", "txtvers=1",
NULL
};
if I don't set TXT record,the service may not discover.Can you give me some example?

@philippe44
Copy link
Owner

You can look at my AirConnect project and see how I'm using it

@CoolBoy119
Copy link
Author

I look the libraop project in AirConnect,it show txt code like this:https://github.com/philippe44/libraop/blob/master/src/raop_server.c
I think it register service without txt record.
image

@philippe44
Copy link
Owner

philippe44 commented Feb 3, 2024

No, I do use services w/ TXT, it would not work otherwise, AirPlay would not work. What you probably missed is that the leading NULL is replaced a few lines below by a dynamically generated string.

// set model
(void)!asprintf(&(txt[0]), "am=%s", model);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants