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