1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /***************************************************************************** 20 * 21 * Filename: uipc.c 22 * 23 * Description: UIPC implementation for bluedroid 24 * 25 *****************************************************************************/ 26 27 #include <stdio.h> 28 #include <string.h> 29 #include <stdlib.h> 30 31 #include <sys/stat.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 35 #include <sys/socket.h> 36 #include <sys/un.h> 37 #include <signal.h> 38 #include <errno.h> 39 #include <pthread.h> 40 #include <sys/select.h> 41 #include <sys/poll.h> 42 #include <sys/mman.h> 43 #include <sys/stat.h> 44 #include <sys/prctl.h> 45 46 47 #include "gki.h" 48 #include "data_types.h" 49 #include "uipc.h" 50 51 #include <cutils/sockets.h> 52 #include "audio_a2dp_hw.h" 53 54 /***************************************************************************** 55 ** Constants & Macros 56 ******************************************************************************/ 57 58 #define PCM_FILENAME "/data/test.pcm" 59 60 #define MAX(a,b) ((a)>(b)?(a):(b)) 61 62 #define CASE_RETURN_STR(const) case const: return #const; 63 64 #define UIPC_DISCONNECTED (-1) 65 66 #define UIPC_LOCK() /*BTIF_TRACE_EVENT1(" %s lock", __FUNCTION__);*/ pthread_mutex_lock(&uipc_main.mutex); 67 #define UIPC_UNLOCK() /*BTIF_TRACE_EVENT1("%s unlock", __FUNCTION__);*/ pthread_mutex_unlock(&uipc_main.mutex); 68 69 /***************************************************************************** 70 ** Local type definitions 71 ******************************************************************************/ 72 73 typedef enum { 74 UIPC_TASK_FLAG_DISCONNECT_CHAN = 0x1, 75 } tUIPC_TASK_FLAGS; 76 77 typedef struct { 78 int srvfd; 79 int fd; 80 int read_poll_tmo_ms; 81 int task_evt_flags; /* event flags pending to be processed in read task */ 82 tUIPC_EVENT cond_flags; 83 pthread_mutex_t cond_mutex; 84 pthread_cond_t cond; 85 tUIPC_RCV_CBACK *cback; 86 } tUIPC_CHAN; 87 88 typedef struct { 89 pthread_t tid; /* main thread id */ 90 int running; 91 pthread_mutex_t mutex; 92 93 fd_set active_set; 94 fd_set read_set; 95 int max_fd; 96 int signal_fds[2]; 97 98 tUIPC_CHAN ch[UIPC_CH_NUM]; 99 } tUIPC_MAIN; 100 101 102 /***************************************************************************** 103 ** Static variables 104 ******************************************************************************/ 105 106 static tUIPC_MAIN uipc_main; 107 108 109 /***************************************************************************** 110 ** Static functions 111 ******************************************************************************/ 112 113 static int uipc_close_ch_locked(tUIPC_CH_ID ch_id); 114 115 /***************************************************************************** 116 ** Externs 117 ******************************************************************************/ 118 119 120 /***************************************************************************** 121 ** Helper functions 122 ******************************************************************************/ 123 124 125 const char* dump_uipc_event(tUIPC_EVENT event) 126 { 127 switch(event) 128 { 129 CASE_RETURN_STR(UIPC_OPEN_EVT) 130 CASE_RETURN_STR(UIPC_CLOSE_EVT) 131 CASE_RETURN_STR(UIPC_RX_DATA_EVT) 132 CASE_RETURN_STR(UIPC_RX_DATA_READY_EVT) 133 CASE_RETURN_STR(UIPC_TX_DATA_READY_EVT) 134 default: 135 return "UNKNOWN MSG ID"; 136 } 137 } 138 139 /***************************************************************************** 140 ** 141 ** Function 142 ** 143 ** Description 144 ** 145 ** Returns 146 ** 147 *******************************************************************************/ 148 149 static void uipc_wait(tUIPC_CH_ID ch_id, tUIPC_EVENT wait_event_flags) 150 { 151 int ret; 152 tUIPC_CHAN *p = &uipc_main.ch[ch_id]; 153 154 //BTIF_TRACE_EVENT2("WAIT UIPC CH %d EVT %x BEGIN", ch_id, wait_event_flags); 155 pthread_mutex_lock(&p->cond_mutex); 156 p->cond_flags |= wait_event_flags; 157 ret = pthread_cond_wait(&p->cond, &p->cond_mutex); 158 pthread_mutex_unlock(&p->cond_mutex); 159 //BTIF_TRACE_EVENT2("WAIT UIPC CH %d EVT %x DONE", ch_id, wait_event_flags); 160 } 161 162 static void uipc_signal(tUIPC_CH_ID ch_id, tUIPC_EVENT event) 163 { 164 int ret; 165 tUIPC_CHAN *p = &uipc_main.ch[ch_id]; 166 167 //BTIF_TRACE_EVENT2("SIGNAL UIPC CH %d EVT %x BEGIN", ch_id, dump_uipc_event(event)); 168 pthread_mutex_lock(&p->cond_mutex); 169 170 if (event & p->cond_flags) 171 { 172 //BTIF_TRACE_EVENT0("UNBLOCK"); 173 ret = pthread_cond_signal(&p->cond); 174 p->cond_flags = 0; 175 } 176 177 pthread_mutex_unlock(&p->cond_mutex); 178 } 179 180 181 182 /***************************************************************************** 183 ** socket helper functions 184 *****************************************************************************/ 185 186 static inline int create_server_socket(const char* name) 187 { 188 int s = socket(AF_LOCAL, SOCK_STREAM, 0); 189 190 BTIF_TRACE_EVENT1("create_server_socket %s", name); 191 192 if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) < 0) 193 { 194 BTIF_TRACE_EVENT1("socket failed to create (%s)", strerror(errno)); 195 return -1; 196 } 197 198 if(listen(s, 5) < 0) 199 { 200 BTIF_TRACE_EVENT1("listen failed", strerror(errno)); 201 close(s); 202 return -1; 203 } 204 205 BTIF_TRACE_EVENT1("created socket fd %d", s); 206 return s; 207 } 208 209 static int accept_server_socket(int sfd) 210 { 211 struct sockaddr_un remote; 212 struct pollfd pfd; 213 int fd; 214 int len = sizeof(struct sockaddr_un); 215 216 BTIF_TRACE_EVENT1("accept fd %d", sfd); 217 218 /* make sure there is data to process */ 219 pfd.fd = sfd; 220 pfd.events = POLLIN; 221 222 if (poll(&pfd, 1, 0) == 0) 223 { 224 BTIF_TRACE_EVENT0("accept poll timeout"); 225 return -1; 226 } 227 228 //BTIF_TRACE_EVENT1("poll revents 0x%x", pfd.revents); 229 230 if ((fd = accept(sfd, (struct sockaddr *)&remote, &len)) == -1) 231 { 232 BTIF_TRACE_ERROR1("sock accept failed (%s)", strerror(errno)); 233 return -1; 234 } 235 236 //BTIF_TRACE_EVENT1("new fd %d", fd); 237 238 return fd; 239 } 240 241 /***************************************************************************** 242 ** 243 ** uipc helper functions 244 ** 245 *****************************************************************************/ 246 247 static int uipc_main_init(void) 248 { 249 int i; 250 const pthread_mutexattr_t attr = PTHREAD_MUTEX_RECURSIVE; 251 pthread_mutex_init(&uipc_main.mutex, &attr); 252 253 BTIF_TRACE_EVENT0("### uipc_main_init ###"); 254 255 /* setup interrupt socket pair */ 256 if (socketpair(AF_UNIX, SOCK_STREAM, 0, uipc_main.signal_fds) < 0) 257 { 258 return -1; 259 } 260 261 FD_SET(uipc_main.signal_fds[0], &uipc_main.active_set); 262 uipc_main.max_fd = MAX(uipc_main.max_fd, uipc_main.signal_fds[0]); 263 264 for (i=0; i< UIPC_CH_NUM; i++) 265 { 266 tUIPC_CHAN *p = &uipc_main.ch[i]; 267 p->srvfd = UIPC_DISCONNECTED; 268 p->fd = UIPC_DISCONNECTED; 269 p->task_evt_flags = 0; 270 pthread_cond_init(&p->cond, NULL); 271 pthread_mutex_init(&p->cond_mutex, NULL); 272 p->cback = NULL; 273 } 274 275 return 0; 276 } 277 278 void uipc_main_cleanup(void) 279 { 280 int i; 281 282 BTIF_TRACE_EVENT0("uipc_main_cleanup"); 283 284 close(uipc_main.signal_fds[0]); 285 close(uipc_main.signal_fds[1]); 286 287 /* close any open channels */ 288 for (i=0; i<UIPC_CH_NUM; i++) 289 uipc_close_ch_locked(i); 290 } 291 292 293 294 /* check pending events in read task */ 295 static void uipc_check_task_flags_locked(void) 296 { 297 int i; 298 299 for (i=0; i<UIPC_CH_NUM; i++) 300 { 301 //BTIF_TRACE_EVENT2("CHECK TASK FLAGS %x %x", uipc_main.ch[i].task_evt_flags, UIPC_TASK_FLAG_DISCONNECT_CHAN); 302 if (uipc_main.ch[i].task_evt_flags & UIPC_TASK_FLAG_DISCONNECT_CHAN) 303 { 304 uipc_main.ch[i].task_evt_flags &= ~UIPC_TASK_FLAG_DISCONNECT_CHAN; 305 uipc_close_ch_locked(i); 306 } 307 308 /* add here */ 309 310 } 311 } 312 313 314 static int uipc_check_fd_locked(tUIPC_CH_ID ch_id) 315 { 316 if (ch_id >= UIPC_CH_NUM) 317 return -1; 318 319 //BTIF_TRACE_EVENT2("CHECK SRVFD %d (ch %d)", uipc_main.ch[ch_id].srvfd, ch_id); 320 321 if (FD_ISSET(uipc_main.ch[ch_id].srvfd, &uipc_main.read_set)) 322 { 323 BTIF_TRACE_EVENT1("INCOMING CONNECTION ON CH %d", ch_id); 324 325 uipc_main.ch[ch_id].fd = accept_server_socket(uipc_main.ch[ch_id].srvfd); 326 327 BTIF_TRACE_EVENT1("NEW FD %d", uipc_main.ch[ch_id].fd); 328 329 if ((uipc_main.ch[ch_id].fd > 0) && uipc_main.ch[ch_id].cback) 330 { 331 /* if we have a callback we should add this fd to the active set 332 and notify user with callback event */ 333 BTIF_TRACE_EVENT1("ADD FD %d TO ACTIVE SET", uipc_main.ch[ch_id].fd); 334 FD_SET(uipc_main.ch[ch_id].fd, &uipc_main.active_set); 335 uipc_main.max_fd = MAX(uipc_main.max_fd, uipc_main.ch[ch_id].fd); 336 } 337 338 if (uipc_main.ch[ch_id].fd < 0) 339 { 340 BTIF_TRACE_ERROR2("FAILED TO ACCEPT CH %d (%s)", ch_id, strerror(errno)); 341 return -1; 342 } 343 344 if (uipc_main.ch[ch_id].cback) 345 uipc_main.ch[ch_id].cback(ch_id, UIPC_OPEN_EVT); 346 } 347 348 //BTIF_TRACE_EVENT2("CHECK FD %d (ch %d)", uipc_main.ch[ch_id].fd, ch_id); 349 350 if (FD_ISSET(uipc_main.ch[ch_id].fd, &uipc_main.read_set)) 351 { 352 //BTIF_TRACE_EVENT1("INCOMING DATA ON CH %d", ch_id); 353 354 if (uipc_main.ch[ch_id].cback) 355 uipc_main.ch[ch_id].cback(ch_id, UIPC_RX_DATA_READY_EVT); 356 } 357 return 0; 358 } 359 360 static void uipc_check_interrupt_locked(void) 361 { 362 if (FD_ISSET(uipc_main.signal_fds[0], &uipc_main.read_set)) 363 { 364 char sig_recv = 0; 365 //BTIF_TRACE_EVENT0("UIPC INTERRUPT"); 366 recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL); 367 } 368 } 369 370 static inline void uipc_wakeup_locked(void) 371 { 372 char sig_on = 1; 373 BTIF_TRACE_EVENT0("UIPC SEND WAKE UP"); 374 send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0); 375 } 376 377 static int uipc_setup_server_locked(tUIPC_CH_ID ch_id, char *name, tUIPC_RCV_CBACK *cback) 378 { 379 int fd; 380 381 BTIF_TRACE_EVENT1("SETUP CHANNEL SERVER %d", ch_id); 382 383 if (ch_id >= UIPC_CH_NUM) 384 return -1; 385 386 UIPC_LOCK(); 387 388 fd = create_server_socket(name); 389 390 if (fd < 0) 391 { 392 BTIF_TRACE_ERROR2("failed to setup %s", name, strerror(errno)); 393 UIPC_UNLOCK(); 394 return -1; 395 } 396 397 BTIF_TRACE_EVENT1("ADD SERVER FD TO ACTIVE SET %d", fd); 398 FD_SET(fd, &uipc_main.active_set); 399 uipc_main.max_fd = MAX(uipc_main.max_fd, fd); 400 401 uipc_main.ch[ch_id].srvfd = fd; 402 uipc_main.ch[ch_id].cback = cback; 403 uipc_main.ch[ch_id].read_poll_tmo_ms = DEFAULT_READ_POLL_TMO_MS; 404 405 /* trigger main thread to update read set */ 406 uipc_wakeup_locked(); 407 408 UIPC_UNLOCK(); 409 410 return 0; 411 } 412 413 static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id) 414 { 415 char buf; 416 struct pollfd pfd; 417 int ret; 418 419 pfd.events = POLLIN|POLLHUP; 420 pfd.fd = uipc_main.ch[ch_id].fd; 421 422 if (uipc_main.ch[ch_id].fd == UIPC_DISCONNECTED) 423 return; 424 425 while (1) 426 { 427 ret = poll(&pfd, 1, 1); 428 BTIF_TRACE_EVENT3("uipc_flush_ch_locked polling : fd %d, rxev %x, ret %d", pfd.fd, pfd.revents, ret); 429 430 if (pfd.revents | (POLLERR|POLLHUP)) 431 return; 432 433 if (ret <= 0) 434 { 435 BTIF_TRACE_EVENT1("uipc_flush_ch_locked : error (%d)", ret); 436 return; 437 } 438 read(pfd.fd, &buf, 1); 439 } 440 } 441 442 443 static void uipc_flush_locked(tUIPC_CH_ID ch_id) 444 { 445 if (ch_id >= UIPC_CH_NUM) 446 return; 447 448 switch(ch_id) 449 { 450 case UIPC_CH_ID_AV_CTRL: 451 uipc_flush_ch_locked(UIPC_CH_ID_AV_CTRL); 452 break; 453 454 case UIPC_CH_ID_AV_AUDIO: 455 uipc_flush_ch_locked(UIPC_CH_ID_AV_AUDIO); 456 break; 457 } 458 } 459 460 461 static int uipc_close_ch_locked(tUIPC_CH_ID ch_id) 462 { 463 int wakeup = 0; 464 465 BTIF_TRACE_EVENT1("CLOSE CHANNEL %d", ch_id); 466 467 if (ch_id >= UIPC_CH_NUM) 468 return -1; 469 470 if (uipc_main.ch[ch_id].srvfd != UIPC_DISCONNECTED) 471 { 472 BTIF_TRACE_EVENT1("CLOSE SERVER (FD %d)", uipc_main.ch[ch_id].srvfd); 473 close(uipc_main.ch[ch_id].srvfd); 474 FD_CLR(uipc_main.ch[ch_id].srvfd, &uipc_main.active_set); 475 uipc_main.ch[ch_id].srvfd = UIPC_DISCONNECTED; 476 wakeup = 1; 477 } 478 479 if (uipc_main.ch[ch_id].fd != UIPC_DISCONNECTED) 480 { 481 BTIF_TRACE_EVENT1("CLOSE CONNECTION (FD %d)", uipc_main.ch[ch_id].fd); 482 close(uipc_main.ch[ch_id].fd); 483 FD_CLR(uipc_main.ch[ch_id].fd, &uipc_main.active_set); 484 uipc_main.ch[ch_id].fd = UIPC_DISCONNECTED; 485 wakeup = 1; 486 } 487 488 /* notify this connection is closed */ 489 if (uipc_main.ch[ch_id].cback) 490 uipc_main.ch[ch_id].cback(ch_id, UIPC_CLOSE_EVT); 491 492 /* trigger main thread update if something was updated */ 493 if (wakeup) 494 uipc_wakeup_locked(); 495 496 return 0; 497 } 498 499 500 void uipc_close_locked(tUIPC_CH_ID ch_id) 501 { 502 if (uipc_main.ch[ch_id].srvfd == UIPC_DISCONNECTED) 503 { 504 BTIF_TRACE_EVENT1("CHANNEL %d ALREADY CLOSED", ch_id); 505 return; 506 } 507 508 /* schedule close on this channel */ 509 uipc_main.ch[ch_id].task_evt_flags |= UIPC_TASK_FLAG_DISCONNECT_CHAN; 510 uipc_wakeup_locked(); 511 } 512 513 514 static void uipc_read_task(void *arg) 515 { 516 int ch_id; 517 int result; 518 519 prctl(PR_SET_NAME, (unsigned long)"uipc-main", 0, 0, 0); 520 521 while (uipc_main.running) 522 { 523 uipc_main.read_set = uipc_main.active_set; 524 525 result = select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL); 526 527 if (result == 0) 528 { 529 BTIF_TRACE_EVENT0("select timeout"); 530 continue; 531 } 532 else if (result < 0) 533 { 534 BTIF_TRACE_EVENT1("select failed %s", strerror(errno)); 535 continue; 536 } 537 538 UIPC_LOCK(); 539 540 /* clear any wakeup interrupt */ 541 uipc_check_interrupt_locked(); 542 543 /* check pending task events */ 544 uipc_check_task_flags_locked(); 545 546 /* make sure we service audio channel first */ 547 uipc_check_fd_locked(UIPC_CH_ID_AV_AUDIO); 548 549 /* check for other connections */ 550 for (ch_id = 0; ch_id < UIPC_CH_NUM; ch_id++) 551 { 552 if (ch_id != UIPC_CH_ID_AV_AUDIO) 553 uipc_check_fd_locked(ch_id); 554 } 555 556 UIPC_UNLOCK(); 557 } 558 559 BTIF_TRACE_EVENT0("UIPC READ THREAD EXITING"); 560 561 uipc_main_cleanup(); 562 563 uipc_main.tid = 0; 564 565 BTIF_TRACE_EVENT0("UIPC READ THREAD DONE"); 566 } 567 568 569 int uipc_start_main_server_thread(void) 570 { 571 uipc_main.running = 1; 572 573 if (pthread_create(&uipc_main.tid, (const pthread_attr_t *) NULL, (void*)uipc_read_task, NULL) < 0) 574 { 575 BTIF_TRACE_ERROR1("uipc_thread_create pthread_create failed:%d", errno); 576 return -1; 577 } 578 579 return 0; 580 } 581 582 /* blocking call */ 583 void uipc_stop_main_server_thread(void) 584 { 585 /* request shutdown of read thread */ 586 UIPC_LOCK(); 587 uipc_main.running = 0; 588 uipc_wakeup_locked(); 589 UIPC_UNLOCK(); 590 591 /* wait until read thread is fully terminated */ 592 if (uipc_main.tid > 0) 593 pthread_join(uipc_main.tid, NULL); 594 } 595 596 /******************************************************************************* 597 ** 598 ** Function UIPC_Init 599 ** 600 ** Description Initialize UIPC module 601 ** 602 ** Returns void 603 ** 604 *******************************************************************************/ 605 606 UDRV_API void UIPC_Init(void *p_data) 607 { 608 BTIF_TRACE_DEBUG0("UIPC_Init"); 609 610 memset(&uipc_main, 0, sizeof(tUIPC_MAIN)); 611 612 uipc_main_init(); 613 614 uipc_start_main_server_thread(); 615 } 616 617 /******************************************************************************* 618 ** 619 ** Function UIPC_Open 620 ** 621 ** Description Open UIPC interface 622 ** 623 ** Returns TRUE in case of success, FALSE in case of failure. 624 ** 625 *******************************************************************************/ 626 UDRV_API BOOLEAN UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback) 627 { 628 BTIF_TRACE_DEBUG2("UIPC_Open : ch_id %d, p_cback %x", ch_id, p_cback); 629 630 UIPC_LOCK(); 631 632 if (ch_id >= UIPC_CH_NUM) 633 { 634 UIPC_UNLOCK(); 635 return FALSE; 636 } 637 638 if (uipc_main.ch[ch_id].srvfd != UIPC_DISCONNECTED) 639 { 640 BTIF_TRACE_EVENT1("CHANNEL %d ALREADY OPEN", ch_id); 641 UIPC_UNLOCK(); 642 return 0; 643 } 644 645 switch(ch_id) 646 { 647 case UIPC_CH_ID_AV_CTRL: 648 uipc_setup_server_locked(ch_id, A2DP_CTRL_PATH, p_cback); 649 break; 650 651 case UIPC_CH_ID_AV_AUDIO: 652 uipc_setup_server_locked(ch_id, A2DP_DATA_PATH, p_cback); 653 break; 654 } 655 656 UIPC_UNLOCK(); 657 658 return TRUE; 659 } 660 661 /******************************************************************************* 662 ** 663 ** Function UIPC_Close 664 ** 665 ** Description Close UIPC interface 666 ** 667 ** Returns void 668 ** 669 *******************************************************************************/ 670 671 UDRV_API void UIPC_Close(tUIPC_CH_ID ch_id) 672 { 673 BTIF_TRACE_DEBUG1("UIPC_Close : ch_id %d", ch_id); 674 675 /* special case handling uipc shutdown */ 676 if (ch_id != UIPC_CH_ID_ALL) 677 { 678 UIPC_LOCK(); 679 uipc_close_locked(ch_id); 680 UIPC_UNLOCK(); 681 } 682 else 683 { 684 BTIF_TRACE_DEBUG0("UIPC_Close : waiting for shutdown to complete"); 685 uipc_stop_main_server_thread(); 686 BTIF_TRACE_DEBUG0("UIPC_Close : shutdown complete"); 687 } 688 } 689 690 /******************************************************************************* 691 ** 692 ** Function UIPC_SendBuf 693 ** 694 ** Description Called to transmit a message over UIPC. 695 ** Message buffer will be freed by UIPC_SendBuf. 696 ** 697 ** Returns TRUE in case of success, FALSE in case of failure. 698 ** 699 *******************************************************************************/ 700 UDRV_API BOOLEAN UIPC_SendBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg) 701 { 702 BTIF_TRACE_DEBUG1("UIPC_SendBuf : ch_id %d NOT IMPLEMENTED", ch_id); 703 704 UIPC_LOCK(); 705 706 /* currently not used */ 707 708 UIPC_UNLOCK(); 709 710 return FALSE; 711 } 712 713 /******************************************************************************* 714 ** 715 ** Function UIPC_Send 716 ** 717 ** Description Called to transmit a message over UIPC. 718 ** 719 ** Returns TRUE in case of success, FALSE in case of failure. 720 ** 721 *******************************************************************************/ 722 UDRV_API BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf, 723 UINT16 msglen) 724 { 725 int n; 726 727 BTIF_TRACE_DEBUG2("UIPC_Send : ch_id:%d %d bytes", ch_id, msglen); 728 729 UIPC_LOCK(); 730 731 if (write(uipc_main.ch[ch_id].fd, p_buf, msglen) < 0) 732 { 733 BTIF_TRACE_ERROR1("failed to write (%s)", strerror(errno)); 734 } 735 736 UIPC_UNLOCK(); 737 738 return FALSE; 739 } 740 741 /******************************************************************************* 742 ** 743 ** Function UIPC_ReadBuf 744 ** 745 ** Description Called to read a message from UIPC. 746 ** 747 ** Returns void 748 ** 749 *******************************************************************************/ 750 UDRV_API void UIPC_ReadBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg) 751 { 752 BTIF_TRACE_DEBUG1("UIPC_ReadBuf : ch_id:%d NOT IMPLEMENTED", ch_id); 753 754 UIPC_LOCK(); 755 UIPC_UNLOCK(); 756 } 757 758 /******************************************************************************* 759 ** 760 ** Function UIPC_Read 761 ** 762 ** Description Called to read a message from UIPC. 763 ** 764 ** Returns return the number of bytes read. 765 ** 766 *******************************************************************************/ 767 768 UDRV_API UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len) 769 { 770 int n; 771 int n_read = 0; 772 int fd = uipc_main.ch[ch_id].fd; 773 struct pollfd pfd; 774 775 if (ch_id >= UIPC_CH_NUM) 776 { 777 BTIF_TRACE_ERROR1("UIPC_Read : invalid ch id %d", ch_id); 778 return 0; 779 } 780 781 if (fd == UIPC_DISCONNECTED) 782 { 783 BTIF_TRACE_ERROR1("UIPC_Read : channel %d closed", ch_id); 784 return 0; 785 } 786 787 //BTIF_TRACE_DEBUG4("UIPC_Read : ch_id %d, len %d, fd %d, polltmo %d", ch_id, len, 788 // fd, uipc_main.ch[ch_id].read_poll_tmo_ms); 789 790 while (n_read < (int)len) 791 { 792 pfd.fd = fd; 793 pfd.events = POLLIN|POLLHUP; 794 795 /* make sure there is data prior to attempting read to avoid blocking 796 a read for more than poll timeout */ 797 if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0) 798 { 799 BTIF_TRACE_EVENT1("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms); 800 return 0; 801 } 802 803 //BTIF_TRACE_EVENT1("poll revents %x", pfd.revents); 804 805 if (pfd.revents & (POLLHUP|POLLNVAL) ) 806 { 807 BTIF_TRACE_EVENT0("poll : channel detached remotely"); 808 UIPC_LOCK(); 809 uipc_close_locked(ch_id); 810 UIPC_UNLOCK(); 811 return 0; 812 } 813 814 n = recv(fd, p_buf+n_read, len-n_read, 0); 815 816 //BTIF_TRACE_EVENT1("read %d bytes", n); 817 818 if (n == 0) 819 { 820 BTIF_TRACE_EVENT0("UIPC_Read : channel detached remotely"); 821 UIPC_LOCK(); 822 uipc_close_locked(ch_id); 823 UIPC_UNLOCK(); 824 return 0; 825 } 826 827 if (n < 0) 828 { 829 BTIF_TRACE_EVENT1("UIPC_Read : read failed (%s)", strerror(errno)); 830 return 0; 831 } 832 833 n_read+=n; 834 835 } 836 837 return n_read; 838 } 839 840 /******************************************************************************* 841 ** 842 ** Function UIPC_Ioctl 843 ** 844 ** Description Called to control UIPC. 845 ** 846 ** Returns void 847 ** 848 *******************************************************************************/ 849 850 UDRV_API extern BOOLEAN UIPC_Ioctl(tUIPC_CH_ID ch_id, UINT32 request, void *param) 851 { 852 BTIF_TRACE_DEBUG2("#### UIPC_Ioctl : ch_id %d, request %d ####", ch_id, request); 853 854 UIPC_LOCK(); 855 856 switch(request) 857 { 858 case UIPC_REQ_RX_FLUSH: 859 uipc_flush_locked(ch_id); 860 break; 861 862 case UIPC_REG_CBACK: 863 //BTIF_TRACE_EVENT3("register callback ch %d srvfd %d, fd %d", ch_id, uipc_main.ch[ch_id].srvfd, uipc_main.ch[ch_id].fd); 864 uipc_main.ch[ch_id].cback = (tUIPC_RCV_CBACK*)param; 865 break; 866 867 case UIPC_REG_REMOVE_ACTIVE_READSET: 868 869 /* user will read data directly and not use select loop */ 870 if (uipc_main.ch[ch_id].fd != UIPC_DISCONNECTED) 871 { 872 /* remove this channel from active set */ 873 FD_CLR(uipc_main.ch[ch_id].fd, &uipc_main.active_set); 874 875 /* refresh active set */ 876 uipc_wakeup_locked(); 877 } 878 break; 879 880 case UIPC_SET_READ_POLL_TMO: 881 uipc_main.ch[ch_id].read_poll_tmo_ms = (int)param; 882 BTIF_TRACE_EVENT2("UIPC_SET_READ_POLL_TMO : CH %d, TMO %d ms", ch_id, uipc_main.ch[ch_id].read_poll_tmo_ms ); 883 break; 884 885 default: 886 BTIF_TRACE_EVENT1("UIPC_Ioctl : request not handled (%d)", request); 887 break; 888 } 889 890 UIPC_UNLOCK(); 891 892 return FALSE; 893 } 894 895