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