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 MATTHIAS 24 * RINGWALD 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 SOCKET_STATE state; 131 uint16_t bytes_read; 132 uint16_t bytes_to_read; 133 uint8_t buffer[6+HCI_ACL_BUFFER_SIZE]; // packet_header(6) + max packet: 3-DH5 = header(6) + payload (1021) 134 }; 135 136 /** list of socket connections */ 137 static btstack_linked_list_t connections = NULL; 138 static btstack_linked_list_t parked = NULL; 139 140 141 /** client packet handler */ 142 143 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; 144 145 static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length){ 146 UNUSED(connection); 147 UNUSED(packet_type); 148 UNUSED(channel); 149 UNUSED(data); 150 UNUSED(length); 151 return 0; 152 } 153 154 static void socket_connection_free_connection(connection_t *conn){ 155 // remove from run_loop 156 btstack_run_loop_remove_data_source(&conn->ds); 157 158 // and from connection list 159 btstack_linked_list_remove(&connections, &conn->linked_connection.item); 160 161 // destroy 162 free(conn); 163 } 164 165 static void socket_connection_init_statemachine(connection_t *connection){ 166 // wait for next packet 167 connection->state = SOCKET_W4_HEADER; 168 connection->bytes_read = 0; 169 connection->bytes_to_read = sizeof(packet_header_t); 170 } 171 172 static connection_t * socket_connection_register_new_connection(int fd){ 173 // create connection objec 174 connection_t * conn = malloc( sizeof(connection_t)); 175 if (conn == NULL) return 0; 176 177 // store reference from linked item to base object 178 conn->linked_connection.connection = conn; 179 180 btstack_run_loop_set_data_source_handler(&conn->ds, &socket_connection_hci_process); 181 btstack_run_loop_set_data_source_fd(&conn->ds, fd); 182 btstack_run_loop_enable_data_source_callbacks(&conn->ds, DATA_SOURCE_CALLBACK_READ); 183 184 // prepare state machine and 185 socket_connection_init_statemachine(conn); 186 187 // add this socket to the run_loop 188 btstack_run_loop_add_data_source( &conn->ds ); 189 190 // and the connection list 191 btstack_linked_list_add( &connections, &conn->linked_connection.item); 192 193 return conn; 194 } 195 196 void static socket_connection_emit_connection_opened(connection_t *connection){ 197 uint8_t event[1]; 198 event[0] = DAEMON_EVENT_CONNECTION_OPENED; 199 (*socket_connection_packet_callback)(connection, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1); 200 } 201 202 void static socket_connection_emit_connection_closed(connection_t *connection){ 203 uint8_t event[1]; 204 event[0] = DAEMON_EVENT_CONNECTION_CLOSED; 205 (*socket_connection_packet_callback)(connection, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1); 206 } 207 208 void socket_connection_hci_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { 209 UNUSED(callback_type); 210 connection_t *conn = (connection_t *) ds; 211 int fd = btstack_run_loop_get_data_source_fd(ds); 212 int bytes_read = read(fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read); 213 if (bytes_read <= 0){ 214 // connection broken (no particular channel, no date yet) 215 socket_connection_emit_connection_closed(conn); 216 217 // free connection 218 socket_connection_free_connection(conn); 219 220 return; 221 } 222 conn->bytes_read += bytes_read; 223 conn->bytes_to_read -= bytes_read; 224 if (conn->bytes_to_read > 0) return; 225 226 int dispatch = 0; 227 switch (conn->state){ 228 case SOCKET_W4_HEADER: 229 conn->state = SOCKET_W4_DATA; 230 conn->bytes_to_read = little_endian_read_16( conn->buffer, 4); 231 if (conn->bytes_to_read == 0){ 232 dispatch = 1; 233 } 234 break; 235 case SOCKET_W4_DATA: 236 dispatch = 1; 237 break; 238 default: 239 break; 240 } 241 242 if (dispatch){ 243 // dispatch packet !!! connection, type, channel, data, size 244 int dispatch_err = (*socket_connection_packet_callback)(conn, little_endian_read_16( conn->buffer, 0), little_endian_read_16( conn->buffer, 2), 245 &conn->buffer[sizeof(packet_header_t)], little_endian_read_16( conn->buffer, 4)); 246 247 // reset state machine 248 socket_connection_init_statemachine(conn); 249 250 // "park" if dispatch failed 251 if (dispatch_err) { 252 log_info("socket_connection_hci_process dispatch failed -> park connection"); 253 btstack_run_loop_remove_data_source(ds); 254 btstack_linked_list_add_tail(&parked, (btstack_linked_item_t *) ds); 255 } 256 } 257 } 258 259 /** 260 * try to dispatch packet for all "parked" connections. 261 * if dispatch is successful, a connection is added again to run loop 262 * pre: connections get parked iff packet was dispatched but could not be sent 263 */ 264 void socket_connection_retry_parked(void){ 265 // log_info("socket_connection_hci_process retry parked"); 266 btstack_linked_item_t *it = (btstack_linked_item_t *) &parked; 267 while (it->next) { 268 connection_t * conn = (connection_t *) it->next; 269 270 // dispatch packet !!! connection, type, channel, data, size 271 uint16_t packet_type = little_endian_read_16( conn->buffer, 0); 272 uint16_t channel = little_endian_read_16( conn->buffer, 2); 273 uint16_t length = little_endian_read_16( conn->buffer, 4); 274 log_info("socket_connection_hci_process retry parked %p (type %u, channel %04x, length %u", conn, packet_type, channel, length); 275 int dispatch_err = (*socket_connection_packet_callback)(conn, packet_type, channel, &conn->buffer[sizeof(packet_header_t)], length); 276 // "un-park" if successful 277 if (!dispatch_err) { 278 log_info("socket_connection_hci_process dispatch succeeded -> un-park connection %p", conn); 279 it->next = it->next->next; 280 btstack_run_loop_add_data_source( (btstack_data_source_t *) conn); 281 } else { 282 it = it->next; 283 } 284 } 285 } 286 287 int socket_connection_has_parked_connections(void){ 288 return parked != NULL; 289 } 290 291 static void socket_connection_accept(btstack_data_source_t *socket_ds, btstack_data_source_callback_type_t callback_type) { 292 UNUSED(callback_type); 293 struct sockaddr_storage ss; 294 socklen_t slen = sizeof(ss); 295 int socket_fd = btstack_run_loop_get_data_source_fd(socket_ds); 296 297 /* New connection coming in! */ 298 int fd = accept(socket_fd, (struct sockaddr *)&ss, &slen); 299 if (fd < 0) { 300 perror("accept"); 301 return; 302 } 303 304 log_info("socket_connection_accept new connection %u", fd); 305 306 connection_t * connection = socket_connection_register_new_connection(fd); 307 socket_connection_emit_connection_opened(connection); 308 } 309 310 /** 311 * create socket data_source for tcp socket 312 * 313 * @return data_source object. If null, check errno 314 */ 315 int socket_connection_create_tcp(int port){ 316 317 // create btstack_data_source_t 318 btstack_data_source_t *ds = calloc(sizeof(btstack_data_source_t), 1); 319 if (ds == NULL) return -1; 320 321 // create tcp socket 322 int fd = socket (PF_INET, SOCK_STREAM, 0); 323 if (fd < 0) { 324 log_error("Error creating socket ...(%s)", strerror(errno)); 325 free(ds); 326 return -1; 327 } 328 329 log_info ("Socket created for port %u", port); 330 331 struct sockaddr_in addr; 332 addr.sin_family = AF_INET; 333 addr.sin_port = htons (port); 334 memset (&addr.sin_addr, 0, sizeof (addr.sin_addr)); 335 336 const int y = 1; 337 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &y, sizeof(int)); 338 339 if (bind ( fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { 340 log_error("Error on bind() ...(%s)", strerror(errno)); 341 free(ds); 342 return -1; 343 } 344 345 if (listen (fd, MAX_PENDING_CONNECTIONS)) { 346 log_error("Error on listen() ...(%s)", strerror(errno)); 347 free(ds); 348 return -1; 349 } 350 351 btstack_run_loop_set_data_source_fd(ds, fd); 352 btstack_run_loop_set_data_source_handler(ds, &socket_connection_accept); 353 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 354 btstack_run_loop_add_data_source(ds); 355 356 log_info ("Server up and running ..."); 357 return 0; 358 } 359 360 #ifdef USE_LAUNCHD 361 362 /* 363 * Register listening sockets with our run loop 364 */ 365 void socket_connection_launchd_register_fd_array(launch_data_t listening_fd_array){ 366 int i; 367 for (i = 0; i < launch_data_array_get_count(listening_fd_array); i++) { 368 // get fd 369 launch_data_t tempi = launch_data_array_get_index (listening_fd_array, i); 370 int listening_fd = launch_data_get_fd(tempi); 371 launch_data_free (tempi); 372 log_info("file descriptor = %u", listening_fd); 373 374 // create btstack_data_source_t for fd 375 btstack_data_source_t *ds = calloc(sizeof(btstack_data_source_t), 1); 376 if (ds == NULL) return; 377 btstack_run_loop_set_data_source_fd(ds, listening_fd); 378 btstack_run_loop_set_data_source_handler(ds, &socket_connection_accept); 379 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 380 btstack_run_loop_add_data_source(ds); 381 } 382 } 383 384 /** 385 * create socket data_source for socket specified by launchd configuration 386 */ 387 int socket_connection_create_launchd(void){ 388 389 launch_data_t sockets_dict, checkin_response; 390 launch_data_t checkin_request; 391 launch_data_t listening_fd_array; 392 393 /* 394 * Register ourselves with launchd. 395 * 396 */ 397 if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { 398 log_error( "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string."); 399 return -1; 400 } 401 402 if ((checkin_response = launch_msg(checkin_request)) == NULL) { 403 log_error( "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %u", errno); 404 return -1; 405 } 406 407 if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { 408 errno = launch_data_get_errno(checkin_response); 409 log_error( "Check-in failed: %u", errno); 410 return -1; 411 } 412 413 launch_data_t the_label = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL); 414 if (NULL == the_label) { 415 log_error( "No label found"); 416 return -1; 417 } 418 419 /* 420 * Retrieve the dictionary of Socket entries in the config file 421 */ 422 sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS); 423 if (NULL == sockets_dict) { 424 log_error("No sockets found to answer requests on!"); 425 return -1; 426 } 427 428 // if (launch_data_dict_get_count(sockets_dict) > 1) { 429 // log_error("Some sockets will be ignored!"); 430 // } 431 432 /* 433 * Get the dictionary value from the key "Listeners" 434 */ 435 listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners"); 436 if (listening_fd_array) { 437 // log_error("Listeners..."); 438 socket_connection_launchd_register_fd_array( listening_fd_array ); 439 } 440 441 /* 442 * Get the dictionary value from the key "Listeners" 443 */ 444 listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners2"); 445 if (listening_fd_array) { 446 // log_error("Listeners2..."); 447 socket_connection_launchd_register_fd_array( listening_fd_array ); 448 } 449 450 // although used in Apple examples, it creates a malloc warning 451 // launch_data_free(checkin_response); 452 return 0; 453 } 454 #endif 455 456 457 /** 458 * set packet handler for all auto-accepted connections 459 */ 460 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) ){ 461 socket_connection_packet_callback = packet_callback; 462 } 463 464 /** 465 * send HCI packet to single connection 466 */ 467 void socket_connection_send_packet(connection_t *conn, uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ 468 uint8_t header[sizeof(packet_header_t)]; 469 little_endian_store_16(header, 0, type); 470 little_endian_store_16(header, 2, channel); 471 little_endian_store_16(header, 4, size); 472 write(conn->ds.source.fd, header, 6); 473 write(conn->ds.source.fd, packet, size); 474 } 475 476 /** 477 * send HCI packet to all connections 478 */ 479 void socket_connection_send_packet_all(uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ 480 btstack_linked_item_t *next; 481 btstack_linked_item_t *it; 482 for (it = (btstack_linked_item_t *) connections; it ; it = next){ 483 next = it->next; // cache pointer to next connection_t to allow for removal 484 linked_connection_t * linked_connection = (linked_connection_t *) it; 485 socket_connection_send_packet( linked_connection->connection, type, channel, packet, size); 486 } 487 } 488 489 /** 490 * create socket connection to BTdaemon 491 */ 492 connection_t * socket_connection_open_tcp(const char *address, uint16_t port){ 493 // TCP 494 struct protoent* tcp = getprotobyname("tcp"); 495 496 int btsocket = socket(PF_INET, SOCK_STREAM, tcp->p_proto); 497 if(btsocket == -1){ 498 return NULL; 499 } 500 // localhost 501 struct sockaddr_in btdaemon_address; 502 btdaemon_address.sin_family = AF_INET; 503 btdaemon_address.sin_port = htons(port); 504 struct hostent* localhost = gethostbyname(address); 505 if(!localhost){ 506 return NULL; 507 } 508 // connect 509 char* addr = localhost->h_addr_list[0]; 510 memcpy(&btdaemon_address.sin_addr.s_addr, addr, sizeof (struct in_addr)); 511 if(connect(btsocket, (struct sockaddr*)&btdaemon_address, sizeof (btdaemon_address)) == -1){ 512 return NULL; 513 } 514 515 return socket_connection_register_new_connection(btsocket); 516 } 517 518 519 /** 520 * close socket connection to BTdaemon 521 */ 522 int socket_connection_close_tcp(connection_t * connection){ 523 if (!connection) return -1; 524 #ifdef _WIN32 525 shutdown(connection->ds.source.fd, SD_BOTH); 526 #else 527 shutdown(connection->ds.source.fd, SHUT_RDWR); 528 #endif 529 socket_connection_free_connection(connection); 530 return 0; 531 } 532 533 #ifdef HAVE_UNIX_SOCKETS 534 535 /** 536 * create socket data_source for unix domain socket 537 */ 538 int socket_connection_create_unix(char *path){ 539 540 // create btstack_data_source_t 541 btstack_data_source_t *ds = calloc(sizeof(btstack_data_source_t), 1); 542 if (ds == NULL) return -1; 543 544 // create unix socket 545 int fd = socket (AF_UNIX, SOCK_STREAM, 0); 546 if (fd < 0) { 547 log_error( "Error creating socket ...(%s)", strerror(errno)); 548 free(ds); 549 return -1; 550 } 551 log_info ("Socket created at %s", path); 552 553 struct sockaddr_un addr; 554 memset(&addr, 0, sizeof(addr)); 555 addr.sun_family = AF_UNIX; 556 strcpy(addr.sun_path, path); 557 unlink(path); 558 559 const int y = 1; 560 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &y, sizeof(int)); 561 562 if (bind (fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { 563 log_error( "Error on bind() ...(%s)", strerror(errno)); 564 free(ds); 565 return -1; 566 } 567 568 // http://blog.henning.makholm.net/2008/06/unix-domain-socket-woes.html 569 // make socket accept from all clients 570 chmod(path, S_IRWXU | S_IRWXG | S_IRWXO); 571 // 572 573 if (listen(fd, MAX_PENDING_CONNECTIONS)) { 574 log_error( "Error on listen() ...(%s)", strerror(errno)); 575 free(ds); 576 return -1; 577 } 578 579 btstack_run_loop_set_data_source_fd(ds, fd); 580 btstack_run_loop_set_data_source_handler(ds, &socket_connection_accept); 581 btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ); 582 btstack_run_loop_add_data_source(ds); 583 584 log_info ("Server up and running ..."); 585 return 0; 586 } 587 588 /** 589 * create socket connection to BTdaemon 590 */ 591 connection_t * socket_connection_open_unix(void){ 592 593 int btsocket = socket(AF_UNIX, SOCK_STREAM, 0); 594 if(btsocket == -1){ 595 return NULL; 596 } 597 598 struct sockaddr_un server; 599 memset(&server, 0, sizeof(server)); 600 server.sun_family = AF_UNIX; 601 strcpy(server.sun_path, BTSTACK_UNIX); 602 if (connect(btsocket, (struct sockaddr *)&server, sizeof (server)) == -1){ 603 return NULL; 604 }; 605 606 return socket_connection_register_new_connection(btsocket); 607 } 608 609 610 /** 611 * close socket connection to BTdaemon 612 */ 613 int socket_connection_close_unix(connection_t * connection){ 614 if (!connection) return -1; 615 #ifdef _WIN32 616 shutdown(connection->ds.source.fd, SD_BOTH); 617 #else 618 shutdown(connection->ds.source.fd, SHUT_RDWR); 619 #endif 620 socket_connection_free_connection(connection); 621 return 0; 622 } 623 624 #endif /* HAVE_UNIX_SOCKETS */ 625 626 /** 627 * Init socket connection module 628 */ 629 void socket_connection_init(void){ 630 // just ignore broken sockets - NO_SO_SIGPIPE 631 #ifndef _WIN32 632 sig_t result = signal(SIGPIPE, SIG_IGN); 633 if (result){ 634 log_error("socket_connection_init: failed to ignore SIGPIPE, error: %s", strerror(errno)); 635 } 636 #endif 637 } 638 639 640