1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "socket_connection.c" 39 40 /* 41 * SocketServer.c 42 * 43 * Handles multiple connections to a single socket without blocking 44 * 45 * Created by Matthias Ringwald on 6/6/09. 46 * 47 */ 48 49 #include "socket_connection.h" 50 51 #include "hci.h" 52 #include "btstack_debug.h" 53 54 #include "btstack_config.h" 55 56 #include "btstack.h" 57 #include "btstack_client.h" 58 59 #include <errno.h> 60 #include <fcntl.h> 61 #include <signal.h> 62 #include <stdint.h> 63 #include <stdio.h> 64 #include <string.h> 65 #include <unistd.h> 66 67 #include <sys/stat.h> 68 69 #ifndef _WIN32 70 #include <arpa/inet.h> 71 #include <netdb.h> 72 #include <sys/socket.h> 73 #include <sys/un.h> 74 #endif 75 76 #ifdef _WIN32 77 #include "Winsock2.h" 78 // define missing types 79 typedef int32_t socklen_t; 80 // 81 #define UNIX_PATH_MAX 108 82 struct sockaddr_un { 83 uint16_t sun_family; 84 char sun_path[UNIX_PATH_MAX]; 85 }; 86 // 87 #endif 88 89 // has been missing on mingw32 in the past 90 #ifndef S_IRWXG 91 #define S_IRWXG 0 92 #endif 93 #ifndef S_IRWXO 94 #define S_IRWXO 0 95 #endif 96 97 #ifdef USE_LAUNCHD 98 #include "../port/ios/3rdparty/launch.h" 99 #endif 100 101 #define MAX_PENDING_CONNECTIONS 10 102 103 /** prototypes */ 104 static void socket_connection_hci_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type); 105 static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length); 106 107 /** globals */ 108 109 /** packet header used over socket connections, in front of the HCI packet */ 110 typedef struct packet_header { 111 uint16_t type; 112 uint16_t channel; 113 uint16_t length; 114 uint8_t data[0]; 115 } packet_header_t; // 6 116 117 typedef enum { 118 SOCKET_W4_HEADER, 119 SOCKET_W4_DATA 120 } SOCKET_STATE; 121 122 typedef struct linked_connection { 123 btstack_linked_item_t item; 124 connection_t * connection; 125 } linked_connection_t; 126 127 struct connection { 128 btstack_data_source_t ds; // used for run loop 129 linked_connection_t linked_connection; // used for connection list 130 int socket_fd; // ds only stores event handle in win32 131 SOCKET_STATE state; 132 uint16_t bytes_read; 133 uint16_t bytes_to_read; 134 uint8_t buffer[6+HCI_ACL_BUFFER_SIZE]; // packet_header(6) + max packet: 3-DH5 = header(6) + payload (1021) 135 }; 136 137 /** list of socket connections */ 138 static btstack_linked_list_t connections = NULL; 139 static btstack_linked_list_t parked = NULL; 140 141 #ifdef _WIN32 142 // workaround as btstack_data_source_t only stores windows event (instead of fd) 143 static int tcp_socket_fd; 144 #endif 145 146 /** client packet handler */ 147 148 static int (*socket_connection_packet_callback)(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length) = socket_connection_dummy_handler; 149 150 static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length){ 151 UNUSED(connection); 152 UNUSED(packet_type); 153 UNUSED(channel); 154 UNUSED(data); 155 UNUSED(length); 156 return 0; 157 } 158 159 static void socket_connection_free_connection(connection_t *conn){ 160 // remove from run_loop 161 btstack_run_loop_remove_data_source(&conn->ds); 162 163 // and from connection list 164 btstack_linked_list_remove(&connections, &conn->linked_connection.item); 165 166 #ifdef _WIN32 167 if (conn->ds.source.handle){ 168 WSACloseEvent(conn->ds.source.handle); 169 } 170 #endif 171 172 // destroy 173 free(conn); 174 } 175 176 static void socket_connection_init_statemachine(connection_t *connection){ 177 // wait for next packet 178 connection->state = SOCKET_W4_HEADER; 179 connection->bytes_read = 0; 180 connection->bytes_to_read = sizeof(packet_header_t); 181 } 182 183 static connection_t * socket_connection_register_new_connection(int fd){ 184 // create connection objec 185 connection_t * conn = malloc( sizeof(connection_t)); 186 if (conn == NULL) return NULL; 187 memset(conn, 0, sizeof(connection_t)); 188 // store reference from linked item to base object 189 conn->linked_connection.connection = conn; 190 191 // keep fd around 192 conn->socket_fd = fd; 193 194 #ifdef _WIN32 195 // wrap fd in windows event and configure for accept and close 196 WSAEVENT event = WSACreateEvent(); 197 if (!event){ 198 log_error("Error creating WSAEvent for socket"); 199 return NULL; 200 } 201 int res = WSAEventSelect(fd, event, FD_READ | FD_WRITE | FD_CLOSE); 202 if (res == SOCKET_ERROR){ 203 log_error("WSAEventSelect() error: %d\n" , WSAGetLastError()); 204 free(conn); 205 return NULL; 206 } 207 #endif 208 209 btstack_run_loop_set_data_source_handler(&conn->ds, &socket_connection_hci_process); 210 #ifdef _WIN32 211 conn->ds.source.handle = event; 212 #else 213 btstack_run_loop_set_data_source_fd(&conn->ds, fd); 214 #endif 215 btstack_run_loop_enable_data_source_callbacks(&conn->ds, DATA_SOURCE_CALLBACK_READ); 216 217 // prepare state machine and 218 socket_connection_init_statemachine(conn); 219 220 // add this socket to the run_loop 221 btstack_run_loop_add_data_source( &conn->ds ); 222 223 // and the connection list 224 btstack_linked_list_add( &connections, &conn->linked_connection.item); 225 226 return conn; 227 } 228 229 void static socket_connection_emit_connection_opened(connection_t *connection){ 230 uint8_t event[1]; 231 event[0] = DAEMON_EVENT_CONNECTION_OPENED; 232 (*socket_connection_packet_callback)(connection, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1); 233 } 234 235 void static socket_connection_emit_connection_closed(connection_t *connection){ 236 uint8_t event[1]; 237 event[0] = DAEMON_EVENT_CONNECTION_CLOSED; 238 (*socket_connection_packet_callback)(connection, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1); 239 } 240 241 void socket_connection_hci_process(btstack_data_source_t *socket_ds, btstack_data_source_callback_type_t callback_type) { 242 UNUSED(callback_type); 243 connection_t *conn = (connection_t *) socket_ds; 244 245 log_debug("socket_connection_hci_process, callback %x", callback_type); 246 247 // get socket_fd 248 int socket_fd = conn->socket_fd; 249 250 #ifdef _WIN32 251 // sync state 252 WSANETWORKEVENTS network_events; 253 if (WSAEnumNetworkEvents(socket_fd, socket_ds->source.handle, &network_events) == SOCKET_ERROR){ 254 log_error("WSAEnumNetworkEvents() failed with error %d\n", WSAGetLastError()); 255 return; 256 } 257 // check if read possible 258 if ((network_events.lNetworkEvents & FD_READ) == 0) return; 259 #endif 260 261 // read from socket 262 #ifdef _WIN32 263 int flags = 0; 264 int bytes_read = recv(socket_fd, (char*) &conn->buffer[conn->bytes_read], conn->bytes_to_read, flags); 265 #else 266 int bytes_read = read(socket_fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read); 267 #endif 268 269 log_debug("socket_connection_hci_process fd %x, bytes read %d", socket_fd, bytes_read); 270 if (bytes_read <= 0){ 271 // connection broken (no particular channel, no date yet) 272 socket_connection_emit_connection_closed(conn); 273 274 // free connection 275 socket_connection_free_connection(conn); 276 277 return; 278 } 279 conn->bytes_read += bytes_read; 280 conn->bytes_to_read -= bytes_read; 281 if (conn->bytes_to_read > 0) return; 282 283 int dispatch = 0; 284 switch (conn->state){ 285 case SOCKET_W4_HEADER: 286 conn->state = SOCKET_W4_DATA; 287 conn->bytes_to_read = little_endian_read_16( conn->buffer, 4); 288 if (conn->bytes_to_read == 0){ 289 dispatch = 1; 290 } 291 break; 292 case SOCKET_W4_DATA: 293 dispatch = 1; 294 break; 295 default: 296 break; 297 } 298 299 if (dispatch){ 300 // dispatch packet !!! connection, type, channel, data, size 301 int dispatch_err = (*socket_connection_packet_callback)(conn, little_endian_read_16( conn->buffer, 0), little_endian_read_16( conn->buffer, 2), 302 &conn->buffer[sizeof(packet_header_t)], little_endian_read_16( conn->buffer, 4)); 303 304 // reset state machine 305 socket_connection_init_statemachine(conn); 306 307 // "park" if dispatch failed 308 if (dispatch_err) { 309 log_info("socket_connection_hci_process dispatch failed -> park connection"); 310 btstack_run_loop_remove_data_source(socket_ds); 311 btstack_linked_list_add_tail(&parked, (btstack_linked_item_t *) socket_ds); 312 } 313 } 314 } 315 316 /** 317 * try to dispatch packet for all "parked" connections. 318 * if dispatch is successful, a connection is added again to run loop 319 * pre: connections get parked iff packet was dispatched but could not be sent 320 */ 321 void socket_connection_retry_parked(void){ 322 // log_info("socket_connection_hci_process retry parked"); 323 btstack_linked_item_t *it = (btstack_linked_item_t *) &parked; 324 while (it->next) { 325 connection_t * conn = (connection_t *) it->next; 326 327 // dispatch packet !!! connection, type, channel, data, size 328 uint16_t packet_type = little_endian_read_16( conn->buffer, 0); 329 uint16_t channel = little_endian_read_16( conn->buffer, 2); 330 uint16_t length = little_endian_read_16( conn->buffer, 4); 331 log_info("socket_connection_hci_process retry parked %p (type %u, channel %04x, length %u", conn, packet_type, channel, length); 332 int dispatch_err = (*socket_connection_packet_callback)(conn, packet_type, channel, &conn->buffer[sizeof(packet_header_t)], length); 333 // "un-park" if successful 334 if (!dispatch_err) { 335 log_info("socket_connection_hci_process dispatch succeeded -> un-park connection %p", conn); 336 it->next = it->next->next; 337 btstack_run_loop_add_data_source( (btstack_data_source_t *) conn); 338 } else { 339 it = it->next; 340 } 341 } 342 } 343 344 int socket_connection_has_parked_connections(void){ 345 return parked != NULL; 346 } 347 348 static void socket_connection_accept(btstack_data_source_t *socket_ds, btstack_data_source_callback_type_t callback_type) { 349 UNUSED(callback_type); 350 struct sockaddr_storage ss; 351 socklen_t slen = sizeof(ss); 352 353 // get socket_fd 354 #ifdef _WIN32 355 int socket_fd = tcp_socket_fd; 356 #else 357 int socket_fd = btstack_run_loop_get_data_source_fd(socket_ds); 358 #endif 359 360 #ifdef _WIN32 361 // sync state 362 WSANETWORKEVENTS network_events; 363 if (WSAEnumNetworkEvents(socket_fd, socket_ds->source.handle, &network_events) == SOCKET_ERROR){ 364 log_error("WSAEnumNetworkEvents() failed with error %d\n", WSAGetLastError()); 365 return; 366 } 367 #endif 368 369 /* New connection coming in! */ 370 int fd = accept(socket_fd, (struct sockaddr *)&ss, &slen); 371 if (fd < 0) { 372 perror("accept"); 373 return; 374 } 375 376 log_info("socket_connection_accept new connection %u", fd); 377 378 connection_t * connection = socket_connection_register_new_connection(fd); 379 socket_connection_emit_connection_opened(connection); 380 } 381 382 /** 383 * create socket data_source for tcp socket 384 * 385 * @return data_source object. If null, check errno 386 */ 387 int socket_connection_create_tcp(int port){ 388 389 // create btstack_data_source_t 390 btstack_data_source_t *ds = calloc(sizeof(btstack_data_source_t), 1); 391 if (ds == NULL) return -1; 392 393 // create tcp socket 394 int fd = socket (PF_INET, SOCK_STREAM, 0); 395 if (fd < 0) { 396 log_error("Error creating socket ...(%s)", strerror(errno)); 397 free(ds); 398 return -1; 399 } 400 401 log_info ("Socket created for port %u", port); 402 403 #ifdef _WIN32 404 // wrap fd in windows event and configure for accept and close 405 WSAEVENT event = WSACreateEvent(); 406 if (!event){ 407 log_error("Error creating WSAEvent for socket"); 408 free(ds); 409 return -1; 410 } 411 int res = WSAEventSelect(fd, event, FD_ACCEPT | FD_CLOSE); 412 if (res == SOCKET_ERROR){ 413 log_error("WSAEventSelect() error: %d\n" , WSAGetLastError()); 414 free(ds); 415 return -1; 416 } 417 // keep fd around 418 tcp_socket_fd = fd; 419 #endif 420 421 struct sockaddr_in addr; 422 addr.sin_family = AF_INET; 423 addr.sin_port = htons (port); 424 memset (&addr.sin_addr, 0, sizeof (addr.sin_addr)); 425 426 const int y = 1; 427 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &y, sizeof(int)); 428 429 if (bind ( fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { 430 log_error("Error on bind() ...(%s)", strerror(errno)); 431 free(ds); 432 return -1; 433 } 434 435 if (listen (fd, MAX_PENDING_CONNECTIONS)) { 436 log_error("Error on listen() ...(%s)", strerror(errno)); 437 free(ds); 438 return -1; 439 } 440 441 #ifdef _WIN32 442 ds->source.handle = event; 443 #else 444 btstack_run_loop_set_data_source_fd(ds, fd); 445 #endif 446 btstack_run_loop_set_data_source_handler(ds, &socket_connection_accept); 447 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 448 btstack_run_loop_add_data_source(ds); 449 450 log_info ("Server up and running ..."); 451 return 0; 452 } 453 454 #ifdef USE_LAUNCHD 455 456 /* 457 * Register listening sockets with our run loop 458 */ 459 void socket_connection_launchd_register_fd_array(launch_data_t listening_fd_array){ 460 int i; 461 for (i = 0; i < launch_data_array_get_count(listening_fd_array); i++) { 462 // get fd 463 launch_data_t tempi = launch_data_array_get_index (listening_fd_array, i); 464 int listening_fd = launch_data_get_fd(tempi); 465 launch_data_free (tempi); 466 log_info("file descriptor = %u", listening_fd); 467 468 // create btstack_data_source_t for fd 469 btstack_data_source_t *ds = calloc(sizeof(btstack_data_source_t), 1); 470 if (ds == NULL) return; 471 btstack_run_loop_set_data_source_fd(ds, listening_fd); 472 btstack_run_loop_set_data_source_handler(ds, &socket_connection_accept); 473 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 474 btstack_run_loop_add_data_source(ds); 475 } 476 } 477 478 /** 479 * create socket data_source for socket specified by launchd configuration 480 */ 481 int socket_connection_create_launchd(void){ 482 483 launch_data_t sockets_dict, checkin_response; 484 launch_data_t checkin_request; 485 launch_data_t listening_fd_array; 486 487 /* 488 * Register ourselves with launchd. 489 * 490 */ 491 if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { 492 log_error( "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string."); 493 return -1; 494 } 495 496 if ((checkin_response = launch_msg(checkin_request)) == NULL) { 497 log_error( "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %u", errno); 498 return -1; 499 } 500 501 if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { 502 errno = launch_data_get_errno(checkin_response); 503 log_error( "Check-in failed: %u", errno); 504 return -1; 505 } 506 507 launch_data_t the_label = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL); 508 if (NULL == the_label) { 509 log_error( "No label found"); 510 return -1; 511 } 512 513 /* 514 * Retrieve the dictionary of Socket entries in the config file 515 */ 516 sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS); 517 if (NULL == sockets_dict) { 518 log_error("No sockets found to answer requests on!"); 519 return -1; 520 } 521 522 // if (launch_data_dict_get_count(sockets_dict) > 1) { 523 // log_error("Some sockets will be ignored!"); 524 // } 525 526 /* 527 * Get the dictionary value from the key "Listeners" 528 */ 529 listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners"); 530 if (listening_fd_array) { 531 // log_error("Listeners..."); 532 socket_connection_launchd_register_fd_array( listening_fd_array ); 533 } 534 535 /* 536 * Get the dictionary value from the key "Listeners" 537 */ 538 listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners2"); 539 if (listening_fd_array) { 540 // log_error("Listeners2..."); 541 socket_connection_launchd_register_fd_array( listening_fd_array ); 542 } 543 544 // although used in Apple examples, it creates a malloc warning 545 // launch_data_free(checkin_response); 546 return 0; 547 } 548 #endif 549 550 551 /** 552 * set packet handler for all auto-accepted connections 553 */ 554 void socket_connection_register_packet_callback( int (*packet_callback)(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length) ){ 555 socket_connection_packet_callback = packet_callback; 556 } 557 558 /** 559 * send HCI packet to single connection 560 */ 561 void socket_connection_send_packet(connection_t *conn, uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ 562 uint8_t header[sizeof(packet_header_t)]; 563 little_endian_store_16(header, 0, type); 564 little_endian_store_16(header, 2, channel); 565 little_endian_store_16(header, 4, size); 566 // avoid -Wunused-result 567 int res; 568 #ifdef _WIN32 569 int flags = 0; 570 res = send(conn->socket_fd, (const char *) header, 6, flags); 571 res = send(conn->socket_fd, (const char *) packet, size, flags); 572 #else 573 res = write(conn->socket_fd, header, 6); 574 res = write(conn->socket_fd, packet, size); 575 #endif 576 UNUSED(res); 577 } 578 579 /** 580 * send HCI packet to all connections 581 */ 582 void socket_connection_send_packet_all(uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ 583 btstack_linked_item_t *next; 584 btstack_linked_item_t *it; 585 for (it = (btstack_linked_item_t *) connections; it ; it = next){ 586 next = it->next; // cache pointer to next connection_t to allow for removal 587 linked_connection_t * linked_connection = (linked_connection_t *) it; 588 socket_connection_send_packet( linked_connection->connection, type, channel, packet, size); 589 } 590 } 591 592 /** 593 * create socket connection to BTdaemon 594 */ 595 connection_t * socket_connection_open_tcp(const char *address, uint16_t port){ 596 // TCP 597 struct protoent* tcp = getprotobyname("tcp"); 598 599 int btsocket = socket(PF_INET, SOCK_STREAM, tcp->p_proto); 600 if(btsocket == -1){ 601 return NULL; 602 } 603 // localhost 604 struct sockaddr_in btdaemon_address; 605 btdaemon_address.sin_family = AF_INET; 606 btdaemon_address.sin_port = htons(port); 607 struct hostent* localhost = gethostbyname(address); 608 if(!localhost){ 609 return NULL; 610 } 611 // connect 612 char* addr = localhost->h_addr_list[0]; 613 memcpy(&btdaemon_address.sin_addr.s_addr, addr, sizeof (struct in_addr)); 614 if(connect(btsocket, (struct sockaddr*)&btdaemon_address, sizeof (btdaemon_address)) == -1){ 615 return NULL; 616 } 617 618 return socket_connection_register_new_connection(btsocket); 619 } 620 621 622 /** 623 * close socket connection to BTdaemon 624 */ 625 int socket_connection_close_tcp(connection_t * connection){ 626 if (!connection) return -1; 627 #ifdef _WIN32 628 shutdown(connection->ds.source.fd, SD_BOTH); 629 #else 630 shutdown(connection->ds.source.fd, SHUT_RDWR); 631 #endif 632 socket_connection_free_connection(connection); 633 return 0; 634 } 635 636 #ifdef HAVE_UNIX_SOCKETS 637 638 /** 639 * create socket data_source for unix domain socket 640 */ 641 int socket_connection_create_unix(char *path){ 642 643 // create btstack_data_source_t 644 btstack_data_source_t *ds = calloc(sizeof(btstack_data_source_t), 1); 645 if (ds == NULL) return -1; 646 647 // create unix socket 648 int fd = socket (AF_UNIX, SOCK_STREAM, 0); 649 if (fd < 0) { 650 log_error( "Error creating socket ...(%s)", strerror(errno)); 651 free(ds); 652 return -1; 653 } 654 log_info ("Socket created at %s", path); 655 656 struct sockaddr_un addr; 657 memset(&addr, 0, sizeof(addr)); 658 addr.sun_family = AF_UNIX; 659 strcpy(addr.sun_path, path); 660 unlink(path); 661 662 const int y = 1; 663 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &y, sizeof(int)); 664 665 if (bind (fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { 666 log_error( "Error on bind() ...(%s)", strerror(errno)); 667 free(ds); 668 return -1; 669 } 670 671 // http://blog.henning.makholm.net/2008/06/unix-domain-socket-woes.html 672 // make socket accept from all clients 673 chmod(path, S_IRWXU | S_IRWXG | S_IRWXO); 674 // 675 676 if (listen(fd, MAX_PENDING_CONNECTIONS)) { 677 log_error( "Error on listen() ...(%s)", strerror(errno)); 678 free(ds); 679 return -1; 680 } 681 682 btstack_run_loop_set_data_source_fd(ds, fd); 683 btstack_run_loop_set_data_source_handler(ds, &socket_connection_accept); 684 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 685 btstack_run_loop_add_data_source(ds); 686 687 log_info ("Server up and running ..."); 688 return 0; 689 } 690 691 /** 692 * create socket connection to BTdaemon 693 */ 694 connection_t * socket_connection_open_unix(void){ 695 696 int btsocket = socket(AF_UNIX, SOCK_STREAM, 0); 697 if(btsocket == -1){ 698 return NULL; 699 } 700 701 struct sockaddr_un server; 702 memset(&server, 0, sizeof(server)); 703 server.sun_family = AF_UNIX; 704 strcpy(server.sun_path, BTSTACK_UNIX); 705 if (connect(btsocket, (struct sockaddr *)&server, sizeof (server)) == -1){ 706 return NULL; 707 }; 708 709 return socket_connection_register_new_connection(btsocket); 710 } 711 712 713 /** 714 * close socket connection to BTdaemon 715 */ 716 int socket_connection_close_unix(connection_t * connection){ 717 if (!connection) return -1; 718 #ifdef _WIN32 719 shutdown(connection->ds.source.fd, SD_BOTH); 720 #else 721 shutdown(connection->ds.source.fd, SHUT_RDWR); 722 #endif 723 socket_connection_free_connection(connection); 724 return 0; 725 } 726 727 #endif /* HAVE_UNIX_SOCKETS */ 728 729 /** 730 * Init socket connection module 731 */ 732 void socket_connection_init(void){ 733 734 // just ignore broken sockets - NO_SO_SIGPIPE 735 #ifndef _WIN32 736 sig_t result = signal(SIGPIPE, SIG_IGN); 737 if (result){ 738 log_error("socket_connection_init: failed to ignore SIGPIPE, error: %s", strerror(errno)); 739 } 740 #endif 741 742 #ifdef _WIN32 743 // TODO: call WSACleanup with wsa data on shutdown 744 WSADATA wsa; 745 int res = WSAStartup(MAKEWORD(2, 2), &wsa); 746 log_info("WSAStartup(v2.2) = %x", res); 747 if (res){ 748 log_error("WSAStartup error: %d", WSAGetLastError()); 749 return; 750 } 751 #endif 752 } 753 754 755