|
Lines 31-36
Link Here
|
| 31 |
#include "shairport.h" |
31 |
#include "shairport.h" |
| 32 |
#include "hairtunes.h" |
32 |
#include "hairtunes.h" |
| 33 |
|
33 |
|
|
|
34 |
static struct printfPtr g_printf={NULL}; |
| 35 |
|
| 36 |
int xprintf(const char *format, ...) |
| 37 |
{ |
| 38 |
char dbg[2048]; |
| 39 |
va_list args; |
| 40 |
va_start(args, format); |
| 41 |
vsnprintf(dbg, sizeof(dbg), format, args); |
| 42 |
va_end(args); |
| 43 |
if(g_printf.extprintf) |
| 44 |
{ |
| 45 |
g_printf.extprintf(dbg, sizeof(dbg)); |
| 46 |
} |
| 47 |
else |
| 48 |
{ |
| 49 |
printf(dbg); |
| 50 |
} |
| 51 |
|
| 52 |
return 1; |
| 53 |
} |
| 54 |
|
| 34 |
#ifndef TRUE |
55 |
#ifndef TRUE |
| 35 |
#define TRUE (-1) |
56 |
#define TRUE (-1) |
| 36 |
#endif |
57 |
#endif |
|
Lines 98-103
Link Here
|
| 98 |
{ |
119 |
{ |
| 99 |
g_ao=*ao; |
120 |
g_ao=*ao; |
| 100 |
} |
121 |
} |
|
|
122 |
|
| 123 |
void shairport_set_printf(struct printfPtr *funcPtr) |
| 124 |
{ |
| 125 |
g_printf = *funcPtr; |
| 126 |
} |
| 101 |
#endif |
127 |
#endif |
| 102 |
|
128 |
|
| 103 |
#ifndef XBMC |
129 |
#ifndef XBMC |
|
Lines 106-112
Link Here
|
| 106 |
int shairport_main(int argc, char **argv) |
132 |
int shairport_main(int argc, char **argv) |
| 107 |
#endif |
133 |
#endif |
| 108 |
{ |
134 |
{ |
| 109 |
printf("initializing shairport\n"); |
135 |
xprintf("initializing shairport\n",NULL); |
| 110 |
char tHWID_Hex[HWID_SIZE * 2 + 1]; |
136 |
char tHWID_Hex[HWID_SIZE * 2 + 1]; |
| 111 |
char tKnownHwid[32]; |
137 |
char tKnownHwid[32]; |
| 112 |
|
138 |
|
|
Lines 185-206
Link Here
|
| 185 |
} |
211 |
} |
| 186 |
else if(!strcmp(arg, "-h") || !strcmp(arg, "--help")) |
212 |
else if(!strcmp(arg, "-h") || !strcmp(arg, "--help")) |
| 187 |
{ |
213 |
{ |
| 188 |
slog(LOG_INFO, "ShairPort version 0.05 C port - Airport Express emulator\n"); |
214 |
xprintf("ShairPort version 0.05 C port - Airport Express emulator\n"); |
| 189 |
slog(LOG_INFO, "Usage:\nshairport [OPTION...]\n\nOptions:\n"); |
215 |
xprintf("Usage:\nshairport [OPTION...]\n\nOptions:\n"); |
| 190 |
slog(LOG_INFO, " -a, --apname=AirPort Sets Airport name\n"); |
216 |
xprintf(" -a, --apname=AirPort Sets Airport name\n"); |
| 191 |
slog(LOG_INFO, " -p, --password=secret Sets Password (not working)\n"); |
217 |
xprintf(" -p, --password=secret Sets Password (not working)\n"); |
| 192 |
slog(LOG_INFO, " -o, --server_port=5000 Sets Port for Avahi/dns-sd\n"); |
218 |
xprintf(" -o, --server_port=5000 Sets Port for Avahi/dns-sd\n"); |
| 193 |
slog(LOG_INFO, " -b, --buffer=282 Sets Number of frames to buffer before beginning playback\n"); |
219 |
xprintf(" -b, --buffer=282 Sets Number of frames to buffer before beginning playback\n"); |
| 194 |
slog(LOG_INFO, " -d Daemon mode\n"); |
220 |
xprintf(" -d Daemon mode\n"); |
| 195 |
slog(LOG_INFO, " -q, --quiet Supresses all output.\n"); |
221 |
xprintf(" -q, --quiet Supresses all output.\n"); |
| 196 |
slog(LOG_INFO, " -v,-v2,-v3,-vv Various debugging levels\n"); |
222 |
xprintf(" -v,-v2,-v3,-vv Various debugging levels\n"); |
| 197 |
slog(LOG_INFO, "\n"); |
223 |
xprintf("\n"); |
| 198 |
return 0; |
224 |
return 0; |
| 199 |
} |
225 |
} |
| 200 |
} |
226 |
} |
| 201 |
|
227 |
|
| 202 |
if ( buffer_start_fill < 30 || buffer_start_fill > BUFFER_FRAMES ) { |
228 |
if ( buffer_start_fill < 30 || buffer_start_fill > BUFFER_FRAMES ) { |
| 203 |
fprintf(stderr, "buffer value must be > 30 and < %d\n", BUFFER_FRAMES); |
229 |
xprintf("buffer value must be > 30 and < %d\n", BUFFER_FRAMES); |
| 204 |
return(0); |
230 |
return(0); |
| 205 |
} |
231 |
} |
| 206 |
|
232 |
|
|
Lines 209-219
Link Here
|
| 209 |
int tPid = fork(); |
235 |
int tPid = fork(); |
| 210 |
if(tPid < 0) |
236 |
if(tPid < 0) |
| 211 |
{ |
237 |
{ |
| 212 |
exit(1); // Error on fork |
238 |
//exit(1); // Error on fork |
| 213 |
} |
239 |
} |
| 214 |
else if(tPid > 0) |
240 |
else if(tPid > 0) |
| 215 |
{ |
241 |
{ |
| 216 |
exit(0); |
242 |
//exit(0); |
| 217 |
} |
243 |
} |
| 218 |
else |
244 |
else |
| 219 |
{ |
245 |
{ |
|
Lines 254-263
Link Here
|
| 254 |
sscanf(tHWID_Hex, "%02X%02X%02X%02X%02X%02X", &tHWID[0], &tHWID[1], &tHWID[2], &tHWID[3], &tHWID[4], &tHWID[5]); |
280 |
sscanf(tHWID_Hex, "%02X%02X%02X%02X%02X%02X", &tHWID[0], &tHWID[1], &tHWID[2], &tHWID[3], &tHWID[4], &tHWID[5]); |
| 255 |
} |
281 |
} |
| 256 |
|
282 |
|
| 257 |
slog(LOG_INFO, "LogLevel: %d\n", kCurrentLogLevel); |
283 |
xprintf("LogLevel: %d\n", kCurrentLogLevel); |
| 258 |
slog(LOG_INFO, "AirName: %s\n", tServerName); |
284 |
xprintf("AirName: %s\n", tServerName); |
| 259 |
slog(LOG_INFO, "HWID: %.*s\n", HWID_SIZE, tHWID+1); |
285 |
xprintf("HWID: %.*s\n", HWID_SIZE, tHWID+1); |
| 260 |
slog(LOG_INFO, "HWID_Hex(%d): %s\n", strlen(tHWID_Hex), tHWID_Hex); |
286 |
xprintf("HWID_Hex(%d): %s\n", strlen(tHWID_Hex), tHWID_Hex); |
| 261 |
|
287 |
|
| 262 |
if(tSimLevel >= 1) |
288 |
if(tSimLevel >= 1) |
| 263 |
{ |
289 |
{ |
|
Lines 271-282
Link Here
|
| 271 |
#ifndef XBMC |
297 |
#ifndef XBMC |
| 272 |
startAvahi(tHWID_Hex, tServerName, tPort); |
298 |
startAvahi(tHWID_Hex, tServerName, tPort); |
| 273 |
#endif |
299 |
#endif |
| 274 |
slog(LOG_DEBUG_V, "Starting connection server: specified server port: %d\n", tPort); |
300 |
xprintf("Starting connection server: specified server port: %d\n", tPort); |
| 275 |
tServerSock = setupListenServer(&tAddrInfo, tPort); |
301 |
tServerSock = setupListenServer(&tAddrInfo, tPort); |
| 276 |
if(tServerSock < 0) |
302 |
if(tServerSock < 0) |
| 277 |
{ |
303 |
{ |
| 278 |
freeaddrinfo(tAddrInfo); |
304 |
freeaddrinfo(tAddrInfo); |
| 279 |
slog(LOG_INFO, "Error setting up server socket on port %d, try specifying a different port\n", tPort); |
305 |
xprintf("Error setting up server socket on port %d, try specifying a different port\n", tPort); |
| 280 |
return 0; |
306 |
return 0; |
| 281 |
} |
307 |
} |
| 282 |
|
308 |
|
|
Lines 303-309
Link Here
|
| 303 |
|
329 |
|
| 304 |
int readsock; |
330 |
int readsock; |
| 305 |
|
331 |
|
| 306 |
slog(LOG_DEBUG_V, "Waiting for clients to connect\n"); |
332 |
xprintf("Waiting for clients to connect\n"); |
| 307 |
|
333 |
|
| 308 |
while(m_running) |
334 |
while(m_running) |
| 309 |
{ |
335 |
{ |
|
Lines 335-341
Link Here
|
| 335 |
{ |
361 |
{ |
| 336 |
freeaddrinfo(tAddrInfo); |
362 |
freeaddrinfo(tAddrInfo); |
| 337 |
tAddrInfo = NULL; |
363 |
tAddrInfo = NULL; |
| 338 |
slog(LOG_DEBUG, "...Accepted Client Connection..\n"); |
364 |
xprintf("...Accepted Client Connection..\n"); |
| 339 |
close(tServerSock); |
365 |
close(tServerSock); |
| 340 |
handleClient(tClientSock, tPassword, tHWID); |
366 |
handleClient(tClientSock, tPassword, tHWID); |
| 341 |
//close(tClientSock); |
367 |
//close(tClientSock); |
|
Lines 343-353
Link Here
|
| 343 |
} |
369 |
} |
| 344 |
else |
370 |
else |
| 345 |
{ |
371 |
{ |
| 346 |
slog(LOG_DEBUG_VV, "Child now busy handling new client\n"); |
372 |
xprintf("Child now busy handling new client\n"); |
| 347 |
close(tClientSock); |
373 |
close(tClientSock); |
| 348 |
} |
374 |
} |
| 349 |
#else |
375 |
#else |
| 350 |
slog(LOG_DEBUG, "...Accepted Client Connection..\n"); |
376 |
xprintf("...Accepted Client Connection..\n"); |
| 351 |
handleClient(tClientSock, tPassword, tHWID); |
377 |
handleClient(tClientSock, tPassword, tHWID); |
| 352 |
#endif |
378 |
#endif |
| 353 |
} |
379 |
} |
|
Lines 357-363
Link Here
|
| 357 |
} |
383 |
} |
| 358 |
} |
384 |
} |
| 359 |
|
385 |
|
| 360 |
slog(LOG_DEBUG_VV, "Finished\n"); |
386 |
xprintf("Finished\n"); |
| 361 |
if(tAddrInfo != NULL) |
387 |
if(tAddrInfo != NULL) |
| 362 |
{ |
388 |
{ |
| 363 |
freeaddrinfo(tAddrInfo); |
389 |
freeaddrinfo(tAddrInfo); |
|
Lines 416-422
Link Here
|
| 416 |
|
442 |
|
| 417 |
void handleClient(int pSock, char *pPassword, char *pHWADDR) |
443 |
void handleClient(int pSock, char *pPassword, char *pHWADDR) |
| 418 |
{ |
444 |
{ |
| 419 |
slog(LOG_DEBUG_VV, "In Handle Client\n"); |
445 |
xprintf("In Handle Client\n"); |
| 420 |
fflush(stdout); |
446 |
fflush(stdout); |
| 421 |
|
447 |
|
| 422 |
socklen_t len; |
448 |
socklen_t len; |
|
Lines 435-441
Link Here
|
| 435 |
|
461 |
|
| 436 |
// deal with both IPv4 and IPv6: |
462 |
// deal with both IPv4 and IPv6: |
| 437 |
if (addr.ss_family == AF_INET) { |
463 |
if (addr.ss_family == AF_INET) { |
| 438 |
slog(LOG_DEBUG_V, "Constructing ipv4 address\n"); |
464 |
xprintf("Constructing ipv4 address\n"); |
| 439 |
struct sockaddr_in *s = (struct sockaddr_in *)&addr; |
465 |
struct sockaddr_in *s = (struct sockaddr_in *)&addr; |
| 440 |
port = ntohs(s->sin_port); |
466 |
port = ntohs(s->sin_port); |
| 441 |
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); |
467 |
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); |
|
Lines 455-474
Link Here
|
| 455 |
if(memcmp(&addr.bin[0], "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\xff\xff", 12) == 0) |
481 |
if(memcmp(&addr.bin[0], "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\xff\xff", 12) == 0) |
| 456 |
{ |
482 |
{ |
| 457 |
// its ipv4... |
483 |
// its ipv4... |
| 458 |
slog(LOG_DEBUG_V, "Constructing ipv4 from ipv6 address\n"); |
484 |
xprintf("Constructing ipv4 from ipv6 address\n"); |
| 459 |
memcpy(ipbin, &addr.bin[12], 4); |
485 |
memcpy(ipbin, &addr.bin[12], 4); |
| 460 |
ipbinlen = 4; |
486 |
ipbinlen = 4; |
| 461 |
} |
487 |
} |
| 462 |
else |
488 |
else |
| 463 |
{ |
489 |
{ |
| 464 |
slog(LOG_DEBUG_V, "Constructing ipv6 address\n"); |
490 |
xprintf("Constructing ipv6 address\n"); |
| 465 |
memcpy(ipbin, &s->sin6_addr, 16); |
491 |
memcpy(ipbin, &s->sin6_addr, 16); |
| 466 |
ipbinlen = 16; |
492 |
ipbinlen = 16; |
| 467 |
} |
493 |
} |
| 468 |
} |
494 |
} |
| 469 |
|
495 |
|
| 470 |
slog(LOG_DEBUG_V, "Peer IP address: %s\n", ipstr); |
496 |
xprintf("Peer IP address: %s\n", ipstr); |
| 471 |
slog(LOG_DEBUG_V, "Peer port : %d\n", port); |
497 |
xprintf("Peer port : %d\n", port); |
| 472 |
|
498 |
|
| 473 |
int tMoreDataNeeded = 1; |
499 |
int tMoreDataNeeded = 1; |
| 474 |
struct keyring tKeys; |
500 |
struct keyring tKeys; |
|
Lines 489-504
Link Here
|
| 489 |
tError = readDataFromClient(pSock, &(tConn.recv)); |
515 |
tError = readDataFromClient(pSock, &(tConn.recv)); |
| 490 |
if(!tError && strlen(tConn.recv.data) > 0) |
516 |
if(!tError && strlen(tConn.recv.data) > 0) |
| 491 |
{ |
517 |
{ |
| 492 |
slog(LOG_DEBUG_VV, "Finished Reading some data from client\n"); |
518 |
xprintf("Finished Reading some data from client\n"); |
| 493 |
// parse client request |
519 |
// parse client request |
| 494 |
tMoreDataNeeded = parseMessage(&tConn, ipbin, ipbinlen, pHWADDR); |
520 |
tMoreDataNeeded = parseMessage(&tConn, ipbin, ipbinlen, pHWADDR); |
| 495 |
if(1 == tMoreDataNeeded) |
521 |
if(1 == tMoreDataNeeded) |
| 496 |
{ |
522 |
{ |
| 497 |
slog(LOG_DEBUG_VV, "\n\nNeed to read more data\n"); |
523 |
xprintf("\n\nNeed to read more data\n"); |
| 498 |
} |
524 |
} |
| 499 |
else if(-1 == tMoreDataNeeded) // Forked process down below ended. |
525 |
else if(-1 == tMoreDataNeeded) // Forked process down below ended. |
| 500 |
{ |
526 |
{ |
| 501 |
slog(LOG_DEBUG_V, "Forked Process ended...cleaning up\n"); |
527 |
xprintf("Forked Process ended...cleaning up\n"); |
| 502 |
cleanup(&tConn); |
528 |
cleanup(&tConn); |
| 503 |
// pSock was already closed |
529 |
// pSock was already closed |
| 504 |
return; |
530 |
return; |
|
Lines 507-519
Link Here
|
| 507 |
} |
533 |
} |
| 508 |
else |
534 |
else |
| 509 |
{ |
535 |
{ |
| 510 |
slog(LOG_DEBUG, "Error reading from socket, closing client\n"); |
536 |
xprintf("Error reading from socket, closing client\n"); |
| 511 |
// Error reading data....quit. |
537 |
// Error reading data....quit. |
| 512 |
cleanup(&tConn); |
538 |
cleanup(&tConn); |
| 513 |
return; |
539 |
return; |
| 514 |
} |
540 |
} |
| 515 |
} |
541 |
} |
| 516 |
slog(LOG_DEBUG_VV, "Writing: %d chars to socket\n", tConn.resp.current); |
542 |
xprintf("Writing: %d chars to socket\n", tConn.resp.current); |
| 517 |
//tConn->resp.data[tConn->resp.current-1] = '\0'; |
543 |
//tConn->resp.data[tConn->resp.current-1] = '\0'; |
| 518 |
writeDataToClient(pSock, &(tConn.resp)); |
544 |
writeDataToClient(pSock, &(tConn.resp)); |
| 519 |
// Finished reading one message... |
545 |
// Finished reading one message... |
|
Lines 526-534
Link Here
|
| 526 |
|
552 |
|
| 527 |
void writeDataToClient(int pSock, struct shairbuffer *pResponse) |
553 |
void writeDataToClient(int pSock, struct shairbuffer *pResponse) |
| 528 |
{ |
554 |
{ |
| 529 |
slog(LOG_DEBUG_VV, "\n----Beg Send Response Header----\n%.*s\n", pResponse->current, pResponse->data); |
555 |
xprintf("\n----Beg Send Response Header----\n%.*s\n", pResponse->current, pResponse->data); |
| 530 |
send(pSock, pResponse->data, pResponse->current,0); |
556 |
send(pSock, pResponse->data, pResponse->current,0); |
| 531 |
slog(LOG_DEBUG_VV, "----Send Response Header----\n"); |
557 |
xprintf("----Send Response Header----\n"); |
| 532 |
} |
558 |
} |
| 533 |
|
559 |
|
| 534 |
int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer) |
560 |
int readDataFromClient(int pSock, struct shairbuffer *pClientBuffer) |
|
Lines 541-547
Link Here
|
| 541 |
while(tRetval > 0 && tEnd < 0) |
567 |
while(tRetval > 0 && tEnd < 0) |
| 542 |
{ |
568 |
{ |
| 543 |
// Read from socket until \n\n, \r\n\r\n, or \r\r is found |
569 |
// Read from socket until \n\n, \r\n\r\n, or \r\r is found |
| 544 |
slog(LOG_DEBUG_V, "Waiting To Read...\n"); |
570 |
xprintf("Waiting To Read...\n"); |
| 545 |
fflush(stdout); |
571 |
fflush(stdout); |
| 546 |
tRetval = read(pSock, tReadBuf, MAX_SIZE); |
572 |
tRetval = read(pSock, tReadBuf, MAX_SIZE); |
| 547 |
// if new buffer contains the end of request string, only copy partial buffer? |
573 |
// if new buffer contains the end of request string, only copy partial buffer? |
|
Lines 552-591
Link Here
|
| 552 |
{ |
578 |
{ |
| 553 |
pClientBuffer->marker = tEnd+1; // Marks start of content |
579 |
pClientBuffer->marker = tEnd+1; // Marks start of content |
| 554 |
} |
580 |
} |
| 555 |
slog(SOCKET_LOG_LEVEL, "Found end of http request at: %d\n", tEnd); |
581 |
xprintf("Found end of http request at: %d\n", tEnd); |
| 556 |
fflush(stdout); |
582 |
fflush(stdout); |
| 557 |
} |
583 |
} |
| 558 |
else |
584 |
else |
| 559 |
{ |
585 |
{ |
| 560 |
tEnd = MAX_SIZE; |
586 |
tEnd = MAX_SIZE; |
| 561 |
slog(SOCKET_LOG_LEVEL, "Read %d of data so far\n%s\n", tRetval, tReadBuf); |
587 |
xprintf("Read %d of data so far\n%s\n", tRetval, tReadBuf); |
| 562 |
fflush(stdout); |
588 |
fflush(stdout); |
| 563 |
} |
589 |
} |
| 564 |
if(tRetval > 0) |
590 |
if(tRetval > 0) |
| 565 |
{ |
591 |
{ |
| 566 |
// Copy read data into tReceive; |
592 |
// Copy read data into tReceive; |
| 567 |
slog(SOCKET_LOG_LEVEL, "Read %d data, using %d of it\n", tRetval, tEnd); |
593 |
xprintf("Read %d data, using %d of it\n", tRetval, tEnd); |
| 568 |
addNToShairBuffer(pClientBuffer, tReadBuf, tRetval); |
594 |
addNToShairBuffer(pClientBuffer, tReadBuf, tRetval); |
| 569 |
slog(LOG_DEBUG_VV, "Finished copying data\n"); |
595 |
xprintf("Finished copying data\n"); |
| 570 |
} |
596 |
} |
| 571 |
else |
597 |
else |
| 572 |
{ |
598 |
{ |
| 573 |
slog(LOG_DEBUG, "Error reading data from socket, got: %d bytes", tRetval); |
599 |
xprintf("Error reading data from socket, got: %d bytes", tRetval); |
| 574 |
return tRetval; |
600 |
return tRetval; |
| 575 |
} |
601 |
} |
| 576 |
} |
602 |
} |
| 577 |
if(tEnd + 1 != tRetval) |
603 |
if(tEnd + 1 != tRetval) |
| 578 |
{ |
604 |
{ |
| 579 |
slog(SOCKET_LOG_LEVEL, "Read more data after end of http request. %d instead of %d\n", tRetval, tEnd+1); |
605 |
xprintf("Read more data after end of http request. %d instead of %d\n", tRetval, tEnd+1); |
| 580 |
} |
606 |
} |
| 581 |
slog(SOCKET_LOG_LEVEL, "Finished Reading Data:\n%s\nEndOfData\n", pClientBuffer->data); |
607 |
xprintf("Finished Reading Data:\n%s\nEndOfData\n", pClientBuffer->data); |
| 582 |
fflush(stdout); |
608 |
fflush(stdout); |
| 583 |
return 0; |
609 |
return 0; |
| 584 |
} |
610 |
} |
| 585 |
|
611 |
|
| 586 |
char *getFromBuffer(char *pBufferPtr, const char *pField, int pLenAfterField, int *pReturnSize, char *pDelims) |
612 |
char *getFromBuffer(char *pBufferPtr, const char *pField, int pLenAfterField, int *pReturnSize, char *pDelims) |
| 587 |
{ |
613 |
{ |
| 588 |
slog(LOG_DEBUG_V, "GettingFromBuffer: %s\n", pField); |
614 |
xprintf("GettingFromBuffer: %s\n", pField); |
| 589 |
char* tFound = strstr(pBufferPtr, pField); |
615 |
char* tFound = strstr(pBufferPtr, pField); |
| 590 |
int tSize = 0; |
616 |
int tSize = 0; |
| 591 |
if(tFound != NULL) |
617 |
if(tFound != NULL) |
|
Lines 606-612
Link Here
|
| 606 |
} |
632 |
} |
| 607 |
|
633 |
|
| 608 |
tSize = (int) (tShortest - tFound); |
634 |
tSize = (int) (tShortest - tFound); |
| 609 |
slog(LOG_DEBUG_VV, "Found %.*s length: %d\n", tSize, tFound, tSize); |
635 |
xprintf("Found %.*s length: %d\n", tSize, tFound, tSize); |
| 610 |
if(pReturnSize != NULL) |
636 |
if(pReturnSize != NULL) |
| 611 |
{ |
637 |
{ |
| 612 |
*pReturnSize = tSize; |
638 |
*pReturnSize = tSize; |
|
Lines 614-620
Link Here
|
| 614 |
} |
640 |
} |
| 615 |
else |
641 |
else |
| 616 |
{ |
642 |
{ |
| 617 |
slog(LOG_DEBUG_V, "Not Found\n"); |
643 |
xprintf("Not Found\n"); |
| 618 |
} |
644 |
} |
| 619 |
return tFound; |
645 |
return tFound; |
| 620 |
} |
646 |
} |
|
Lines 648-657
Link Here
|
| 648 |
{ |
674 |
{ |
| 649 |
char tTrim[tFoundSize + 2]; |
675 |
char tTrim[tFoundSize + 2]; |
| 650 |
getTrimmed(tFound, tFoundSize, TRUE, TRUE, tTrim); |
676 |
getTrimmed(tFound, tFoundSize, TRUE, TRUE, tTrim); |
| 651 |
slog(LOG_DEBUG_VV, "HeaderChallenge: [%s] len: %d sizeFound: %d\n", tTrim, strlen(tTrim), tFoundSize); |
677 |
xprintf("HeaderChallenge: [%s] len: %d sizeFound: %d\n", tTrim, strlen(tTrim), tFoundSize); |
| 652 |
int tChallengeDecodeSize = 16; |
678 |
int tChallengeDecodeSize = 16; |
| 653 |
char *tChallenge = decode_base64((unsigned char *)tTrim, tFoundSize, &tChallengeDecodeSize); |
679 |
char *tChallenge = decode_base64((unsigned char *)tTrim, tFoundSize, &tChallengeDecodeSize); |
| 654 |
slog(LOG_DEBUG_VV, "Challenge Decode size: %d expected 16\n", tChallengeDecodeSize); |
680 |
xprintf("Challenge Decode size: %d expected 16\n", tChallengeDecodeSize); |
| 655 |
|
681 |
|
| 656 |
int tCurSize = 0; |
682 |
int tCurSize = 0; |
| 657 |
unsigned char tChalResp[38]; |
683 |
unsigned char tChalResp[38]; |
|
Lines 673-679
Link Here
|
| 673 |
} |
699 |
} |
| 674 |
|
700 |
|
| 675 |
char *tTmp = encode_base64((unsigned char *)tChalResp, tCurSize); |
701 |
char *tTmp = encode_base64((unsigned char *)tChalResp, tCurSize); |
| 676 |
slog(LOG_DEBUG_VV, "Full sig: %s\n", tTmp); |
702 |
xprintf("Full sig: %s\n", tTmp); |
| 677 |
free(tTmp); |
703 |
free(tTmp); |
| 678 |
|
704 |
|
| 679 |
// RSA Encrypt |
705 |
// RSA Encrypt |
|
Lines 722-731
Link Here
|
| 722 |
{ |
748 |
{ |
| 723 |
if(isLogEnabledFor(HEADER_LOG_LEVEL)) |
749 |
if(isLogEnabledFor(HEADER_LOG_LEVEL)) |
| 724 |
{ |
750 |
{ |
| 725 |
slog(HEADER_LOG_LEVEL, "Content-Length: %s value -> %d\n", tContent, tContentSize); |
751 |
xprintf("Content-Length: %s value -> %d\n", tContent, tContentSize); |
| 726 |
if(pConn->recv.marker != 0) |
752 |
if(pConn->recv.marker != 0) |
| 727 |
{ |
753 |
{ |
| 728 |
slog(HEADER_LOG_LEVEL, "ContentPtr has %d, but needs %d\n", |
754 |
xprintf("ContentPtr has %d, but needs %d\n", |
| 729 |
strlen(pConn->recv.data+pConn->recv.marker), tContentSize); |
755 |
strlen(pConn->recv.data+pConn->recv.marker), tContentSize); |
| 730 |
} |
756 |
} |
| 731 |
} |
757 |
} |
|
Lines 735-741
Link Here
|
| 735 |
} |
761 |
} |
| 736 |
else |
762 |
else |
| 737 |
{ |
763 |
{ |
| 738 |
slog(LOG_DEBUG_VV, "No content, header only\n"); |
764 |
xprintf("No content, header only\n"); |
| 739 |
} |
765 |
} |
| 740 |
|
766 |
|
| 741 |
// "Creates" a new Response Header for our response message |
767 |
// "Creates" a new Response Header for our response message |
|
Lines 748-754
Link Here
|
| 748 |
{ |
774 |
{ |
| 749 |
tLen = 20; |
775 |
tLen = 20; |
| 750 |
} |
776 |
} |
| 751 |
slog(LOG_INFO, "********** RECV %.*s **********\n", tLen, pConn->recv.data); |
777 |
xprintf("********** RECV %.*s **********\n", tLen, pConn->recv.data); |
| 752 |
} |
778 |
} |
| 753 |
|
779 |
|
| 754 |
if(pConn->password != NULL) |
780 |
if(pConn->password != NULL) |
|
Lines 758-764
Link Here
|
| 758 |
|
784 |
|
| 759 |
if(buildAppleResponse(pConn, pIpBin, pIpBinLen, pHWID)) // need to free sig |
785 |
if(buildAppleResponse(pConn, pIpBin, pIpBinLen, pHWID)) // need to free sig |
| 760 |
{ |
786 |
{ |
| 761 |
slog(LOG_DEBUG_V, "Added AppleResponse to Apple-Challenge request\n"); |
787 |
xprintf("Added AppleResponse to Apple-Challenge request\n"); |
| 762 |
} |
788 |
} |
| 763 |
|
789 |
|
| 764 |
// Find option, then based on option, do different actions. |
790 |
// Find option, then based on option, do different actions. |
|
Lines 778-791
Link Here
|
| 778 |
int tKeySize = 0; |
804 |
int tKeySize = 0; |
| 779 |
char tEncodedAesIV[tSize + 2]; |
805 |
char tEncodedAesIV[tSize + 2]; |
| 780 |
getTrimmed(tHeaderVal, tSize, TRUE, TRUE, tEncodedAesIV); |
806 |
getTrimmed(tHeaderVal, tSize, TRUE, TRUE, tEncodedAesIV); |
| 781 |
slog(LOG_DEBUG_VV, "AESIV: [%.*s] Size: %d Strlen: %d\n", tSize, tEncodedAesIV, tSize, strlen(tEncodedAesIV)); |
807 |
xprintf("AESIV: [%.*s] Size: %d Strlen: %d\n", tSize, tEncodedAesIV, tSize, strlen(tEncodedAesIV)); |
| 782 |
char *tDecodedIV = decode_base64((unsigned char*) tEncodedAesIV, tSize, &tSize); |
808 |
char *tDecodedIV = decode_base64((unsigned char*) tEncodedAesIV, tSize, &tSize); |
| 783 |
|
809 |
|
| 784 |
// grab the key, copy it out of the receive buffer |
810 |
// grab the key, copy it out of the receive buffer |
| 785 |
tHeaderVal = getFromContent(tContent, "a=rsaaeskey", &tKeySize); |
811 |
tHeaderVal = getFromContent(tContent, "a=rsaaeskey", &tKeySize); |
| 786 |
char tEncodedAesKey[tKeySize + 2]; // +1 for nl, +1 for \0 |
812 |
char tEncodedAesKey[tKeySize + 2]; // +1 for nl, +1 for \0 |
| 787 |
getTrimmed(tHeaderVal, tKeySize, TRUE, TRUE, tEncodedAesKey); |
813 |
getTrimmed(tHeaderVal, tKeySize, TRUE, TRUE, tEncodedAesKey); |
| 788 |
slog(LOG_DEBUG_VV, "AES KEY: [%s] Size: %d Strlen: %d\n", tEncodedAesKey, tKeySize, strlen(tEncodedAesKey)); |
814 |
xprintf("AES KEY: [%s] Size: %d Strlen: %d\n", tEncodedAesKey, tKeySize, strlen(tEncodedAesKey)); |
| 789 |
// remove base64 coding from key |
815 |
// remove base64 coding from key |
| 790 |
char *tDecodedAesKey = decode_base64((unsigned char*) tEncodedAesKey, |
816 |
char *tDecodedAesKey = decode_base64((unsigned char*) tEncodedAesKey, |
| 791 |
tKeySize, &tKeySize); // Need to free DecodedAesKey |
817 |
tKeySize, &tKeySize); // Need to free DecodedAesKey |
|
Lines 794-800
Link Here
|
| 794 |
int tFmtpSize = 0; |
820 |
int tFmtpSize = 0; |
| 795 |
char *tFmtp = getFromContent(tContent, "a=fmtp", &tFmtpSize); // Don't need to free |
821 |
char *tFmtp = getFromContent(tContent, "a=fmtp", &tFmtpSize); // Don't need to free |
| 796 |
tFmtp = getTrimmedMalloc(tFmtp, tFmtpSize, TRUE, FALSE); // will need to free |
822 |
tFmtp = getTrimmedMalloc(tFmtp, tFmtpSize, TRUE, FALSE); // will need to free |
| 797 |
slog(LOG_DEBUG_VV, "Format: %s\n", tFmtp); |
823 |
xprintf("Format: %s\n", tFmtp); |
| 798 |
|
824 |
|
| 799 |
RSA *rsa = loadKey(); |
825 |
RSA *rsa = loadKey(); |
| 800 |
// Decrypt the binary aes key |
826 |
// Decrypt the binary aes key |
|
Lines 803-813
Link Here
|
| 803 |
if(RSA_private_decrypt(tKeySize, (unsigned char *)tDecodedAesKey, |
829 |
if(RSA_private_decrypt(tKeySize, (unsigned char *)tDecodedAesKey, |
| 804 |
(unsigned char*) tDecryptedKey, rsa, RSA_PKCS1_OAEP_PADDING) >= 0) |
830 |
(unsigned char*) tDecryptedKey, rsa, RSA_PKCS1_OAEP_PADDING) >= 0) |
| 805 |
{ |
831 |
{ |
| 806 |
slog(LOG_DEBUG, "Decrypted AES key from RSA Successfully\n"); |
832 |
xprintf("Decrypted AES key from RSA Successfully\n"); |
| 807 |
} |
833 |
} |
| 808 |
else |
834 |
else |
| 809 |
{ |
835 |
{ |
| 810 |
slog(LOG_INFO, "Error Decrypting AES key from RSA\n"); |
836 |
xprintf("Error Decrypting AES key from RSA\n"); |
| 811 |
} |
837 |
} |
| 812 |
free(tDecodedAesKey); |
838 |
free(tDecodedAesKey); |
| 813 |
RSA_free(rsa); |
839 |
RSA_free(rsa); |
|
Lines 823-835
Link Here
|
| 823 |
// struct comms *tComms = pConn->hairtunes; |
849 |
// struct comms *tComms = pConn->hairtunes; |
| 824 |
// if (! (pipe(tComms->in) == 0 && pipe(tComms->out) == 0)) |
850 |
// if (! (pipe(tComms->in) == 0 && pipe(tComms->out) == 0)) |
| 825 |
// { |
851 |
// { |
| 826 |
// slog(LOG_INFO, "Error setting up hairtunes communications...some things probably wont work very well.\n"); |
852 |
// xprintf("Error setting up hairtunes communications...some things probably wont work very well.\n"); |
| 827 |
// } |
853 |
// } |
| 828 |
|
854 |
|
| 829 |
// Setup fork |
855 |
// Setup fork |
| 830 |
char tPort[8] = "6000"; // get this from dup()'d stdout of child pid |
856 |
char tPort[8] = "6000"; // get this from dup()'d stdout of child pid |
| 831 |
|
857 |
|
| 832 |
printf("******** SETUP!!!!!\n"); |
858 |
xprintf("******** SETUP!!!!!\n",NULL); |
| 833 |
#ifndef XBMC |
859 |
#ifndef XBMC |
| 834 |
int tPid = fork(); |
860 |
int tPid = fork(); |
| 835 |
if(tPid == 0) |
861 |
if(tPid == 0) |
|
Lines 845-855
Link Here
|
| 845 |
tFound = getFromSetup(pConn->recv.data, "timing_port", &tSize); |
871 |
tFound = getFromSetup(pConn->recv.data, "timing_port", &tSize); |
| 846 |
getTrimmed(tFound, tSize, 1, 0, tTPortStr); |
872 |
getTrimmed(tFound, tSize, 1, 0, tTPortStr); |
| 847 |
|
873 |
|
| 848 |
slog(LOG_DEBUG_VV, "converting %s and %s from str->int\n", tCPortStr, tTPortStr); |
874 |
xprintf("converting %s and %s from str->int\n", tCPortStr, tTPortStr); |
| 849 |
int tControlport = atoi(tCPortStr); |
875 |
int tControlport = atoi(tCPortStr); |
| 850 |
int tTimingport = atoi(tTPortStr); |
876 |
int tTimingport = atoi(tTPortStr); |
| 851 |
|
877 |
|
| 852 |
slog(LOG_DEBUG_V, "Got %d for CPort and %d for TPort\n", tControlport, tTimingport); |
878 |
xprintf("Got %d for CPort and %d for TPort\n", tControlport, tTimingport); |
| 853 |
char *tRtp = NULL; |
879 |
char *tRtp = NULL; |
| 854 |
char *tPipe = NULL; |
880 |
char *tPipe = NULL; |
| 855 |
char *tAoDriver = NULL; |
881 |
char *tAoDriver = NULL; |
|
Lines 884-890
Link Here
|
| 884 |
tDataport, tRtp, tPipe, tAoDriver, tAoDeviceName, tAoDeviceId); |
910 |
tDataport, tRtp, tPipe, tAoDriver, tAoDeviceName, tAoDeviceId); |
| 885 |
#ifndef XBMC |
911 |
#ifndef XBMC |
| 886 |
// Quit when finished. |
912 |
// Quit when finished. |
| 887 |
slog(LOG_DEBUG, "Returned from hairtunes init....returning -1, should close out this whole side of the fork\n"); |
913 |
xprintf("Returned from hairtunes init....returning -1, should close out this whole side of the fork\n"); |
| 888 |
return -1; |
914 |
return -1; |
| 889 |
} |
915 |
} |
| 890 |
else if(tPid >0) |
916 |
else if(tPid >0) |
|
Lines 897-903
Link Here
|
| 897 |
int tRead = read(tComms->out[0], tFromHairtunes, 80); |
923 |
int tRead = read(tComms->out[0], tFromHairtunes, 80); |
| 898 |
if(tRead <= 0) |
924 |
if(tRead <= 0) |
| 899 |
{ |
925 |
{ |
| 900 |
slog(LOG_INFO, "Error reading port from hairtunes function, assuming default port: %d\n", tPort); |
926 |
xprintf("Error reading port from hairtunes function, assuming default port: %d\n", tPort); |
| 901 |
} |
927 |
} |
| 902 |
else |
928 |
else |
| 903 |
{ |
929 |
{ |
|
Lines 909-915
Link Here
|
| 909 |
} |
935 |
} |
| 910 |
else |
936 |
else |
| 911 |
{ |
937 |
{ |
| 912 |
slog(LOG_INFO, "Read %d bytes, Error translating %s into a port\n", tRead, tFromHairtunes); |
938 |
xprintf("Read %d bytes, Error translating %s into a port\n", tRead, tFromHairtunes); |
| 913 |
} |
939 |
} |
| 914 |
} |
940 |
} |
| 915 |
|
941 |
|
|
Lines 930-936
Link Here
|
| 930 |
} |
956 |
} |
| 931 |
else |
957 |
else |
| 932 |
{ |
958 |
{ |
| 933 |
slog(LOG_INFO, "Error forking process....dere' be errors round here.\n"); |
959 |
xprintf("Error forking process....dere' be errors round here.\n"); |
| 934 |
return -1; |
960 |
return -1; |
| 935 |
} |
961 |
} |
| 936 |
#endif |
962 |
#endif |
|
Lines 942-948
Link Here
|
| 942 |
propogateCSeq(pConn); |
968 |
propogateCSeq(pConn); |
| 943 |
#ifndef XBMC |
969 |
#ifndef XBMC |
| 944 |
close(pConn->hairtunes->in[1]); |
970 |
close(pConn->hairtunes->in[1]); |
| 945 |
slog(LOG_DEBUG, "Tearing down connection, closing pipes\n"); |
971 |
xprintf("Tearing down connection, closing pipes\n"); |
| 946 |
#else |
972 |
#else |
| 947 |
hairtunes_cleanup(); |
973 |
hairtunes_cleanup(); |
| 948 |
#endif |
974 |
#endif |
|
Lines 964-970
Link Here
|
| 964 |
propogateCSeq(pConn); |
990 |
propogateCSeq(pConn); |
| 965 |
int tSize = 0; |
991 |
int tSize = 0; |
| 966 |
char *tVol = getFromHeader(pConn->recv.data, "volume", &tSize); |
992 |
char *tVol = getFromHeader(pConn->recv.data, "volume", &tSize); |
| 967 |
slog(LOG_DEBUG_VV, "About to write [vol: %.*s] data to hairtunes\n", tSize, tVol); |
993 |
xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol); |
| 968 |
// TBD VOLUME |
994 |
// TBD VOLUME |
| 969 |
#ifndef XBMC |
995 |
#ifndef XBMC |
| 970 |
write(pConn->hairtunes->in[1], "vol: ", 5); |
996 |
write(pConn->hairtunes->in[1], "vol: ", 5); |
|
Lines 973-983
Link Here
|
| 973 |
#else |
999 |
#else |
| 974 |
hairtunes_setvolume(atof(tVol)); |
1000 |
hairtunes_setvolume(atof(tVol)); |
| 975 |
#endif |
1001 |
#endif |
| 976 |
slog(LOG_DEBUG_VV, "Finished writing data write data to hairtunes\n"); |
1002 |
xprintf("Finished writing data write data to hairtunes\n"); |
| 977 |
} |
1003 |
} |
| 978 |
else |
1004 |
else |
| 979 |
{ |
1005 |
{ |
| 980 |
slog(LOG_DEBUG, "\n\nUn-Handled recv: %s\n", pConn->recv.data); |
1006 |
xprintf("\n\nUn-Handled recv: %s\n", pConn->recv.data); |
| 981 |
propogateCSeq(pConn); |
1007 |
propogateCSeq(pConn); |
| 982 |
} |
1008 |
} |
| 983 |
addToShairBuffer(&(pConn->resp), "\r\n"); |
1009 |
addToShairBuffer(&(pConn->resp), "\r\n"); |
|
Lines 1056-1062
Link Here
|
| 1056 |
char tName[100 + HWID_SIZE + 3]; |
1082 |
char tName[100 + HWID_SIZE + 3]; |
| 1057 |
if(strlen(pServerName) > tMaxServerName) |
1083 |
if(strlen(pServerName) > tMaxServerName) |
| 1058 |
{ |
1084 |
{ |
| 1059 |
slog(LOG_INFO,"Hey dog, we see you like long server names, " |
1085 |
xprintf("Hey dog, we see you like long server names, " |
| 1060 |
"so we put a strncat in our command so we don't buffer overflow, while you listen to your flow.\n" |
1086 |
"so we put a strncat in our command so we don't buffer overflow, while you listen to your flow.\n" |
| 1061 |
"We just used the first %d characters. Pick something shorter if you want\n", tMaxServerName); |
1087 |
"We just used the first %d characters. Pick something shorter if you want\n", tMaxServerName); |
| 1062 |
} |
1088 |
} |
|
Lines 1067-1073
Link Here
|
| 1067 |
strcat(tName, pHWStr); |
1093 |
strcat(tName, pHWStr); |
| 1068 |
strcat(tName, "@"); |
1094 |
strcat(tName, "@"); |
| 1069 |
strncat(tName, pServerName, tMaxServerName); |
1095 |
strncat(tName, pServerName, tMaxServerName); |
| 1070 |
slog(AVAHI_LOG_LEVEL, "Avahi/DNS-SD Name: %s\n", tName); |
1096 |
xprintf("Avahi/DNS-SD Name: %s\n", tName); |
| 1071 |
|
1097 |
|
| 1072 |
execlp("avahi-publish-service", "avahi-publish-service", tName, |
1098 |
execlp("avahi-publish-service", "avahi-publish-service", tName, |
| 1073 |
"_raop._tcp", tPort, "tp=UDP","sm=false","sv=false","ek=1","et=0,1", |
1099 |
"_raop._tcp", tPort, "tp=UDP","sm=false","sv=false","ek=1","et=0,1", |
|
Lines 1079-1090
Link Here
|
| 1079 |
perror("error"); |
1105 |
perror("error"); |
| 1080 |
} |
1106 |
} |
| 1081 |
|
1107 |
|
| 1082 |
slog(LOG_INFO, "Bad error... couldn't find or failed to run: avahi-publish-service OR dns-sd\n"); |
1108 |
xprintf("Bad error... couldn't find or failed to run: avahi-publish-service OR dns-sd\n"); |
| 1083 |
exit(1); |
1109 |
//exit(1); |
| 1084 |
} |
1110 |
} |
| 1085 |
else |
1111 |
else |
| 1086 |
{ |
1112 |
{ |
| 1087 |
slog(LOG_DEBUG_VV, "Avahi/DNS-SD started on PID: %d\n", tPid); |
1113 |
xprintf("Avahi/DNS-SD started on PID: %d\n", tPid); |
| 1088 |
} |
1114 |
} |
| 1089 |
return tPid; |
1115 |
return tPid; |
| 1090 |
} |
1116 |
} |
|
Lines 1092-1098
Link Here
|
| 1092 |
|
1118 |
|
| 1093 |
void printBufferInfo(struct shairbuffer *pBuf, int pLevel) |
1119 |
void printBufferInfo(struct shairbuffer *pBuf, int pLevel) |
| 1094 |
{ |
1120 |
{ |
| 1095 |
slog(pLevel, "Buffer: [%s] size: %d maxchars:%d\n", pBuf->data, pBuf->current, pBuf->maxsize/sizeof(char)); |
1121 |
xprintf("Buffer: [%s] size: %d maxchars:%d\n", pBuf->data, pBuf->current, pBuf->maxsize/sizeof(char)); |
| 1096 |
} |
1122 |
} |
| 1097 |
|
1123 |
|
| 1098 |
int getAvailChars(struct shairbuffer *pBuf) |
1124 |
int getAvailChars(struct shairbuffer *pBuf) |
|
Lines 1173-1179
Link Here
|
| 1173 |
{ |
1199 |
{ |
| 1174 |
va_list argp; |
1200 |
va_list argp; |
| 1175 |
va_start(argp, pFormat); |
1201 |
va_start(argp, pFormat); |
| 1176 |
vprintf(pFormat, argp); |
1202 |
xprintf(pFormat, argp); |
|
|
1203 |
//vprintf(pFormat, argp); |
| 1177 |
va_end(argp); |
1204 |
va_end(argp); |
| 1178 |
} |
1205 |
} |
| 1179 |
//#endif |
1206 |
//#endif |
|
Lines 1227-1235
Link Here
|
| 1227 |
{ |
1254 |
{ |
| 1228 |
if(pBuf->data != NULL) |
1255 |
if(pBuf->data != NULL) |
| 1229 |
{ |
1256 |
{ |
| 1230 |
slog(LOG_DEBUG_VV, "Hrm, buffer wasn't cleaned up....trying to free\n"); |
1257 |
xprintf("Hrm, buffer wasn't cleaned up....trying to free\n"); |
| 1231 |
free(pBuf->data); |
1258 |
free(pBuf->data); |
| 1232 |
slog(LOG_DEBUG_VV, "Free didn't seem to seg fault....huzzah\n"); |
1259 |
xprintf("Free didn't seem to seg fault....huzzah\n"); |
| 1233 |
} |
1260 |
} |
| 1234 |
pBuf->current = 0; |
1261 |
pBuf->current = 0; |
| 1235 |
pBuf->marker = 0; |
1262 |
pBuf->marker = 0; |
|
Lines 1287-1292
Link Here
|
| 1287 |
BIO *tBio = BIO_new_mem_buf(AIRPORT_PRIVATE_KEY, -1); |
1314 |
BIO *tBio = BIO_new_mem_buf(AIRPORT_PRIVATE_KEY, -1); |
| 1288 |
RSA *rsa = PEM_read_bio_RSAPrivateKey(tBio, NULL, NULL, NULL); //NULL, NULL, NULL); |
1315 |
RSA *rsa = PEM_read_bio_RSAPrivateKey(tBio, NULL, NULL, NULL); //NULL, NULL, NULL); |
| 1289 |
BIO_free(tBio); |
1316 |
BIO_free(tBio); |
| 1290 |
slog(RSA_LOG_LEVEL, "RSA Key: %d\n", RSA_check_key(rsa)); |
1317 |
xprintf("RSA Key: %d\n", RSA_check_key(rsa)); |
| 1291 |
return rsa; |
1318 |
return rsa; |
| 1292 |
} |
1319 |
} |