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 /* 39 * SocketServer.c 40 * 41 * Handles multiple connections to a single socket without blocking 42 * 43 * Created by Matthias Ringwald on 6/6/09. 44 * 45 */ 46 47 #include "socket_connection.h" 48 49 #include "hci.h" 50 #include "debug.h" 51 52 #include "btstack-config.h" 53 54 #include "btstack.h" 55 #include "btstack_client.h" 56 57 #include <errno.h> 58 #include <fcntl.h> 59 #include <stdio.h> 60 #include <stdint.h> 61 #include <string.h> 62 #include <unistd.h> 63 64 #include <sys/stat.h> 65 66 #ifndef _WIN32 67 #include <arpa/inet.h> 68 #include <netdb.h> 69 #include <sys/socket.h> 70 #include <sys/un.h> 71 #endif 72 73 #ifdef _WIN32 74 #include "Winsock2.h" 75 // define missing types 76 typedef int32_t socklen_t; 77 // 78 #define UNIX_PATH_MAX 108 79 struct sockaddr_un { 80 uint16_t sun_family; 81 char sun_path[UNIX_PATH_MAX]; 82 }; 83 // 84 #define S_IRWXG 0 85 #define S_IRWXO 0 86 #endif 87 88 #ifdef USE_LAUNCHD 89 #include "../port/ios/3rdparty/launch.h" 90 #endif 91 92 #define MAX_PENDING_CONNECTIONS 10 93 94 /** prototypes */ 95 static int socket_connection_hci_process(struct data_source *ds); 96 static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length); 97 98 /** globals */ 99 100 /** packet header used over socket connections, in front of the HCI packet */ 101 typedef struct packet_header { 102 uint16_t type; 103 uint16_t channel; 104 uint16_t length; 105 uint8_t data[0]; 106 } packet_header_t; // 6 107 108 typedef enum { 109 SOCKET_W4_HEADER, 110 SOCKET_W4_DATA 111 } SOCKET_STATE; 112 113 struct connection { 114 data_source_t ds; // used for run loop 115 linked_item_t item; // used for connection list, user_data points to connection_t base 116 SOCKET_STATE state; 117 uint16_t bytes_read; 118 uint16_t bytes_to_read; 119 uint8_t buffer[6+HCI_ACL_BUFFER_SIZE]; // packet_header(6) + max packet: 3-DH5 = header(6) + payload (1021) 120 }; 121 122 /** list of socket connections */ 123 static bk_linked_list_t connections = NULL; 124 static bk_linked_list_t parked = NULL; 125 126 127 /** client packet handler */ 128 129 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; 130 131 static int socket_connection_dummy_handler(connection_t *connection, uint16_t packet_type, uint16_t channel, uint8_t *data, uint16_t length){ 132 return 0; 133 } 134 135 void socket_connection_set_no_sigpipe(int fd){ 136 #ifdef HAVE_SO_NOSIGPIPE 137 int set = 1; 138 setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); 139 #endif 140 } 141 142 void socket_connection_free_connection(connection_t *conn){ 143 // remove from run_loop 144 run_loop_remove_data_source(&conn->ds); 145 146 // and from connection list 147 linked_list_remove(&connections, &conn->item); 148 149 // destroy 150 free(conn); 151 } 152 153 void socket_connection_init_statemachine(connection_t *connection){ 154 // wait for next packet 155 connection->state = SOCKET_W4_HEADER; 156 connection->bytes_read = 0; 157 connection->bytes_to_read = sizeof(packet_header_t); 158 } 159 160 connection_t * socket_connection_register_new_connection(int fd){ 161 // create connection objec 162 connection_t * conn = malloc( sizeof(connection_t)); 163 if (conn == NULL) return 0; 164 linked_item_set_user( &conn->item, conn); 165 conn->ds.fd = fd; 166 conn->ds.process = socket_connection_hci_process; 167 168 // prepare state machine and 169 socket_connection_init_statemachine(conn); 170 171 // add this socket to the run_loop 172 run_loop_add_data_source( &conn->ds ); 173 174 // and the connection list 175 linked_list_add( &connections, &conn->item); 176 177 return conn; 178 } 179 180 void static socket_connection_emit_connection_opened(connection_t *connection){ 181 uint8_t event[1]; 182 event[0] = DAEMON_EVENT_CONNECTION_OPENED; 183 (*socket_connection_packet_callback)(connection, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1); 184 } 185 186 void static socket_connection_emit_connection_closed(connection_t *connection){ 187 uint8_t event[1]; 188 event[0] = DAEMON_EVENT_CONNECTION_CLOSED; 189 (*socket_connection_packet_callback)(connection, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 1); 190 } 191 192 void static socket_connection_emit_nr_connections(void){ 193 linked_item_t *it; 194 uint8_t nr_connections = 0; 195 for (it = (linked_item_t *) connections; it != NULL ; it = it->next, nr_connections++); 196 197 uint8_t event[2]; 198 event[0] = DAEMON_NR_CONNECTIONS_CHANGED; 199 event[1] = nr_connections; 200 (*socket_connection_packet_callback)(NULL, DAEMON_EVENT_PACKET, 0, (uint8_t *) &event, 2); 201 // log_info("Nr connections changed,.. new %u", nr_connections); 202 } 203 204 int socket_connection_hci_process(struct data_source *ds) { 205 connection_t *conn = (connection_t *) ds; 206 207 int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read); 208 if (bytes_read <= 0){ 209 // connection broken (no particular channel, no date yet) 210 socket_connection_emit_connection_closed(conn); 211 212 // free connection 213 socket_connection_free_connection(linked_item_get_user(&conn->item)); 214 215 socket_connection_emit_nr_connections(); 216 return 0; 217 } 218 conn->bytes_read += bytes_read; 219 conn->bytes_to_read -= bytes_read; 220 // hexdump( conn->buffer, conn->bytes_read); 221 if (conn->bytes_to_read > 0) { 222 return 0; 223 } 224 225 int dispatch = 0; 226 switch (conn->state){ 227 case SOCKET_W4_HEADER: 228 conn->state = SOCKET_W4_DATA; 229 conn->bytes_to_read = READ_BT_16( conn->buffer, 4); 230 if (conn->bytes_to_read == 0){ 231 dispatch = 1; 232 } 233 break; 234 case SOCKET_W4_DATA: 235 dispatch = 1; 236 break; 237 default: 238 break; 239 } 240 241 if (dispatch){ 242 // dispatch packet !!! connection, type, channel, data, size 243 int dispatch_err = (*socket_connection_packet_callback)(conn, READ_BT_16( conn->buffer, 0), READ_BT_16( conn->buffer, 2), 244 &conn->buffer[sizeof(packet_header_t)], READ_BT_16( conn->buffer, 4)); 245 246 // reset state machine 247 socket_connection_init_statemachine(conn); 248 249 // "park" if dispatch failed 250 if (dispatch_err) { 251 log_info("socket_connection_hci_process dispatch failed -> park connection"); 252 run_loop_remove_data_source(ds); 253 linked_list_add_tail(&parked, (linked_item_t *) ds); 254 } 255 } 256 return 0; 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 linked_item_t *it = (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 log_info("socket_connection_hci_process retry parked %p", conn); 272 int dispatch_err = (*socket_connection_packet_callback)(conn, READ_BT_16( conn->buffer, 0), READ_BT_16( conn->buffer, 2), 273 &conn->buffer[sizeof(packet_header_t)], READ_BT_16( conn->buffer, 4)); 274 // "un-park" if successful 275 if (!dispatch_err) { 276 log_info("socket_connection_hci_process dispatch succeeded -> un-park connection %p", conn); 277 it->next = it->next->next; 278 run_loop_add_data_source( (data_source_t *) conn); 279 } else { 280 it = it->next; 281 } 282 } 283 } 284 285 int socket_connection_has_parked_connections(void){ 286 return parked != NULL; 287 } 288 289 static int socket_connection_accept(struct data_source *socket_ds) { 290 struct sockaddr_storage ss; 291 socklen_t slen = sizeof(ss); 292 293 /* New connection coming in! */ 294 int fd = accept(socket_ds->fd, (struct sockaddr *)&ss, &slen); 295 if (fd < 0) { 296 perror("accept"); 297 return 0; 298 } 299 300 // no sigpipe 301 socket_connection_set_no_sigpipe(fd); 302 303 log_info("socket_connection_accept new connection %u", fd); 304 305 connection_t * connection = socket_connection_register_new_connection(fd); 306 socket_connection_emit_connection_opened(connection); 307 socket_connection_emit_nr_connections(); 308 309 return 0; 310 } 311 312 /** 313 * create socket data_source for tcp socket 314 * 315 * @return data_source object. If null, check errno 316 */ 317 int socket_connection_create_tcp(int port){ 318 319 // create data_source_t 320 data_source_t *ds = malloc( sizeof(data_source_t)); 321 if (ds == NULL) return -1; 322 ds->fd = 0; 323 ds->process = socket_connection_accept; 324 325 // create tcp socket 326 if ((ds->fd = socket (PF_INET, SOCK_STREAM, 0)) < 0) { 327 log_error("Error creating socket ...(%s)", strerror(errno)); 328 free(ds); 329 return -1; 330 } 331 332 log_info ("Socket created for port %u", port); 333 334 struct sockaddr_in addr; 335 addr.sin_family = AF_INET; 336 addr.sin_port = htons (port); 337 memset (&addr.sin_addr, 0, sizeof (addr.sin_addr)); 338 339 const int y = 1; 340 setsockopt(ds->fd, SOL_SOCKET, SO_REUSEADDR, (void*) &y, sizeof(int)); 341 342 if (bind ( ds->fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { 343 log_error("Error on bind() ...(%s)", strerror(errno)); 344 free(ds); 345 return -1; 346 } 347 348 if (listen (ds->fd, MAX_PENDING_CONNECTIONS)) { 349 log_error("Error on listen() ...(%s)", strerror(errno)); 350 free(ds); 351 return -1; 352 } 353 354 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 data_source_t for fd 375 data_source_t *ds = malloc( sizeof(data_source_t)); 376 if (ds == NULL) return; 377 ds->process = socket_connection_accept; 378 ds->fd = listening_fd; 379 run_loop_add_data_source(ds); 380 } 381 } 382 383 /** 384 * create socket data_source for socket specified by launchd configuration 385 */ 386 int socket_connection_create_launchd(void){ 387 388 launch_data_t sockets_dict, checkin_response; 389 launch_data_t checkin_request; 390 launch_data_t listening_fd_array; 391 392 /* 393 * Register ourselves with launchd. 394 * 395 */ 396 if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) { 397 log_error( "launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string."); 398 return -1; 399 } 400 401 if ((checkin_response = launch_msg(checkin_request)) == NULL) { 402 log_error( "launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %u", errno); 403 return -1; 404 } 405 406 if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) { 407 errno = launch_data_get_errno(checkin_response); 408 log_error( "Check-in failed: %u", errno); 409 return -1; 410 } 411 412 launch_data_t the_label = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL); 413 if (NULL == the_label) { 414 log_error( "No label found"); 415 return -1; 416 } 417 418 /* 419 * Retrieve the dictionary of Socket entries in the config file 420 */ 421 sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS); 422 if (NULL == sockets_dict) { 423 log_error("No sockets found to answer requests on!"); 424 return -1; 425 } 426 427 // if (launch_data_dict_get_count(sockets_dict) > 1) { 428 // log_error("Some sockets will be ignored!"); 429 // } 430 431 /* 432 * Get the dictionary value from the key "Listeners" 433 */ 434 listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners"); 435 if (listening_fd_array) { 436 // log_error("Listeners..."); 437 socket_connection_launchd_register_fd_array( listening_fd_array ); 438 } 439 440 /* 441 * Get the dictionary value from the key "Listeners" 442 */ 443 listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners2"); 444 if (listening_fd_array) { 445 // log_error("Listeners2..."); 446 socket_connection_launchd_register_fd_array( listening_fd_array ); 447 } 448 449 // although used in Apple examples, it creates a malloc warning 450 // launch_data_free(checkin_response); 451 return 0; 452 } 453 #endif 454 455 /** 456 * create socket data_source for unix domain socket 457 */ 458 int socket_connection_create_unix(char *path){ 459 460 // create data_source_t 461 data_source_t *ds = malloc( sizeof(data_source_t)); 462 if (ds == NULL) return -1; 463 ds->fd = 0; 464 ds->process = socket_connection_accept; 465 466 // create unix socket 467 if ((ds->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { 468 log_error( "Error creating socket ...(%s)", strerror(errno)); 469 free(ds); 470 return -1; 471 } 472 473 log_info ("Socket created at %s", path); 474 475 struct sockaddr_un addr; 476 memset(&addr, 0, sizeof(addr)); 477 addr.sun_family = AF_UNIX; 478 strcpy(addr.sun_path, path); 479 unlink(path); 480 481 const int y = 1; 482 setsockopt(ds->fd, SOL_SOCKET, SO_REUSEADDR, (void*) &y, sizeof(int)); 483 484 if (bind ( ds->fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { 485 log_error( "Error on bind() ...(%s)", strerror(errno)); 486 free(ds); 487 return -1; 488 } 489 490 // http://blog.henning.makholm.net/2008/06/unix-domain-socket-woes.html 491 // make socket accept from all clients 492 chmod(path, S_IRWXU | S_IRWXG | S_IRWXO); 493 // 494 495 if (listen (ds->fd, MAX_PENDING_CONNECTIONS)) { 496 log_error( "Error on listen() ...(%s)", strerror(errno)); 497 free(ds); 498 return -1; 499 } 500 501 run_loop_add_data_source(ds); 502 503 log_info ("Server up and running ..."); 504 return 0; 505 } 506 507 /** 508 * set packet handler for all auto-accepted connections 509 */ 510 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) ){ 511 socket_connection_packet_callback = packet_callback; 512 } 513 514 /** 515 * send HCI packet to single connection 516 */ 517 void socket_connection_send_packet(connection_t *conn, uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ 518 uint8_t header[sizeof(packet_header_t)]; 519 bt_store_16(header, 0, type); 520 bt_store_16(header, 2, channel); 521 bt_store_16(header, 4, size); 522 #if defined(HAVE_SO_NOSIGPIPE) || defined (_WIN32) 523 // BSD Variants like Darwin and iOS 524 write(conn->ds.fd, header, 6); 525 write(conn->ds.fd, packet, size); 526 #else 527 // Linux 528 send(conn->ds.fd, header, 6, MSG_NOSIGNAL); 529 send(conn->ds.fd, packet, size, MSG_NOSIGNAL); 530 #endif 531 } 532 533 /** 534 * send HCI packet to all connections 535 */ 536 void socket_connection_send_packet_all(uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ 537 linked_item_t *next; 538 linked_item_t *it; 539 for (it = (linked_item_t *) connections; it ; it = next){ 540 next = it->next; // cache pointer to next connection_t to allow for removal 541 socket_connection_send_packet( (connection_t *) linked_item_get_user(it), type, channel, packet, size); 542 } 543 } 544 545 /** 546 * create socket connection to BTdaemon 547 */ 548 connection_t * socket_connection_open_tcp(const char *address, uint16_t port){ 549 // TCP 550 struct protoent* tcp = getprotobyname("tcp"); 551 552 int btsocket = socket(PF_INET, SOCK_STREAM, tcp->p_proto); 553 if(btsocket == -1){ 554 return NULL; 555 } 556 // localhost 557 struct sockaddr_in btdaemon_address; 558 btdaemon_address.sin_family = AF_INET; 559 btdaemon_address.sin_port = htons(port); 560 struct hostent* localhost = gethostbyname(address); 561 if(!localhost){ 562 return NULL; 563 } 564 // connect 565 char* addr = localhost->h_addr_list[0]; 566 memcpy(&btdaemon_address.sin_addr.s_addr, addr, sizeof (struct in_addr)); 567 if(connect(btsocket, (struct sockaddr*)&btdaemon_address, sizeof (btdaemon_address)) == -1){ 568 return NULL; 569 } 570 571 return socket_connection_register_new_connection(btsocket); 572 } 573 574 575 /** 576 * close socket connection to BTdaemon 577 */ 578 int socket_connection_close_tcp(connection_t * connection){ 579 if (!connection) return -1; 580 #ifdef _WIN32 581 shutdown(connection->ds.fd, SD_BOTH); 582 #else 583 shutdown(connection->ds.fd, SHUT_RDWR); 584 #endif 585 socket_connection_free_connection(connection); 586 return 0; 587 } 588 589 590 /** 591 * create socket connection to BTdaemon 592 */ 593 connection_t * socket_connection_open_unix(void){ 594 595 int btsocket = socket(AF_UNIX, SOCK_STREAM, 0); 596 if(btsocket == -1){ 597 return NULL; 598 } 599 600 struct sockaddr_un server; 601 memset(&server, 0, sizeof(server)); 602 server.sun_family = AF_UNIX; 603 strcpy(server.sun_path, BTSTACK_UNIX); 604 if (connect(btsocket, (struct sockaddr *)&server, sizeof (server)) == -1){ 605 return NULL; 606 }; 607 608 return socket_connection_register_new_connection(btsocket); 609 } 610 611 612 /** 613 * close socket connection to BTdaemon 614 */ 615 int socket_connection_close_unix(connection_t * connection){ 616 if (!connection) return -1; 617 #ifdef _WIN32 618 shutdown(connection->ds.fd, SD_BOTH); 619 #else 620 shutdown(connection->ds.fd, SHUT_RDWR); 621 #endif 622 socket_connection_free_connection(connection); 623 return 0; 624 } 625 626