source:
freewrt/package/asterisk/patches/asterisk-1.0.9-chan_bluetooth.patch@
428f140
| Last change on this file since 428f140 was 475ad56, checked in by , 20 years ago | |
|---|---|
|
|
| File size: 96.5 KB | |
-
channels/Makefile
diff -ruN asterisk-1.0.9-old/channels/Makefile asterisk-1.0.9-new/channels/Makefile
old new 202 202 chan_h323.so: chan_h323.o h323/libchanh323.a 203 203 $(CC) $(SOLINK) -o $@ $< h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat 204 204 205 # 206 # Asterisk Bluetooth Support 207 # http://www.crazygreek.co.uk/content/chan_bluetooth 208 # 209 chan_bluetooth.so: chan_bluetooth.o 210 $(CC) $(SOLINK) -o $@ $< $(EXTRA_LDFLAGS) -lbluetooth 211 205 212 206 213 #chan_modem.so : chan_modem.o 207 214 # $(CC) -rdynamic -shared -Xlinker -x -o $@ $< -
channels/chan_bluetooth.c
diff -ruN asterisk-1.0.9-old/channels/chan_bluetooth.c asterisk-1.0.9-new/channels/chan_bluetooth.c
old new 1 /* 2 * Asterisk -- A telephony toolkit for Linux. 3 * 4 * Asterisk Bluetooth Channel 5 * 6 * Author: Theo Zourzouvillys <theo@adaptive-it.co.uk> 7 * 8 * Adaptive Linux Solutions <http://www.adaptive-it.co.uk> 9 * 10 * Copyright (C) 2004 Adaptive Linux Solutions 11 * 12 * This program is free software, distributed under the terms of 13 * the GNU General Public License 14 * 15 * ******************* NOTE NOTE NOTE NOTE NOTE ********************* 16 * 17 * This code is not at all tested, and only been developed with a 18 * HBH-200 headset and a Nokia 6310i right now. 19 * 20 * Expect it to crash, dial random numbers, and steal all your money. 21 * 22 * PLEASE try any headsets and phones, and let me know the results, 23 * working or not, along with all debug output! 24 * 25 * ------------------------------------------------------------------ 26 * 27 * Asterisk Bluetooth Support 28 * 29 * Well, here we go - Attempt to provide Handsfree profile support in 30 * both AG and HF modes, AG (AudioGateway) mode support for using 31 * headsets, and HF (Handsfree) mode for utilising mobile/cell phones 32 * 33 * It would be nice to also provide Headset support at some time in 34 * the future, however, a working Handsfree profile is nice for now, 35 * and as far as I can see, almost all new HS devices also support HF 36 * 37 * ------------------------------------------------------------------ 38 * INSTRUCTIONS 39 * 40 * You need to have bluez's bluetooth stack, along with user space 41 * tools (>=v2.10), and running hcid and sdsp. 42 * 43 * See bluetooth.conf for configuration details. 44 * 45 * - Ensure bluetooth subsystem is up and running. 'hciconfig' 46 * should show interface as UP. 47 * 48 * - If you're trying to use a headset/HS, start up asterisk, and try 49 * to pair it as you normally would. 50 * 51 * - If you're trying to use a Phone/AG, just make sure bluetooth is 52 * enabled on your phone, and start up asterisk. 53 * 54 * - 'bluetooth show peers' will show all bluetooth devices states. 55 * 56 * - Send a call out by using Dial(BLT/DevName/0123456). Call a HS 57 * with Dial(BLT/DevName) 58 * 59 * ------------------------------------------------------------------ 60 * BUGS 61 * 62 * - What should happen when an AG is paired with asterisk and 63 * someone uses the AG dalling a number manually? My test phone 64 * seems to try to open an SCO link. Perhaps an extension to 65 * route the call to, or maybe drop the RFCOM link all together? 66 * 67 * ------------------------------------------------------------------ 68 * COMPATIBILITY 69 * 70 * PLEASE email <theo@adaptive-it.co.uk> with the results of ANY 71 * device not listed in here (working or not), or if the device is 72 * listed and it doesn't work! Please also email full debug output 73 * for any device not working correctly or generating errors in log. 74 * 75 * HandsFree Profile: 76 * 77 * HS (HeadSet): 78 * - Ericsson HBH-200 79 * 80 * AG (AudioGateway): 81 * - Nokia 6310i 82 * 83 * ------------------------------------------------------------------ 84 * 85 * Questions, bugs, or (preferably) patches to: 86 * 87 * <theo@adaptive-it.co.uk> 88 * 89 * ------------------------------------------------------------------ 90 */ 91 92 /* ---------------------------------- */ 93 94 #include <stdio.h> 95 #include <string.h> 96 #include <asterisk/lock.h> 97 #include <asterisk/utils.h> 98 #include <asterisk/channel.h> 99 #include <asterisk/config.h> 100 #include <asterisk/logger.h> 101 #include <asterisk/module.h> 102 #include <asterisk/pbx.h> 103 #include <asterisk/sched.h> 104 #include <asterisk/options.h> 105 #include <asterisk/cli.h> 106 #include <asterisk/callerid.h> 107 #include <sys/socket.h> 108 #include <sys/signal.h> 109 #include <sys/time.h> 110 #include <errno.h> 111 #include <unistd.h> 112 #include <stdlib.h> 113 #include <arpa/inet.h> 114 #include <fcntl.h> 115 #include <sys/ioctl.h> 116 #include <ctype.h> 117 #include <endian.h> 118 119 #include <bluetooth/bluetooth.h> 120 #include <bluetooth/hci.h> 121 #include <bluetooth/hci_lib.h> 122 #include <bluetooth/sco.h> 123 #include <bluetooth/rfcomm.h> 124 #include <bluetooth/sdp.h> 125 #include <bluetooth/sdp_lib.h> 126 127 /* --- Data types and definitions --- */ 128 129 #ifndef HANDSFREE_AUDIO_GW_SVCLASS_ID 130 # define HANDSFREE_AUDIO_GW_SVCLASS_ID 0x111f 131 #endif 132 #define BLUETOOTH_FORMAT AST_FORMAT_SLINEAR 133 #define BLT_CHAN_NAME "BLT" 134 #define BLT_CONFIG_FILE "bluetooth.conf" 135 #define BLT_RDBUFF_MAX 1024 136 #define BLT_DEFAULT_HCI_DEV 0 137 #define BLT_SVN_REVISION "$Rev: 3737 $" 138 139 /* ---------------------------------- */ 140 141 typedef enum { 142 BLT_ROLE_NONE = 0, // Unknown Device 143 BLT_ROLE_HS = 1, // Device is a Headset 144 BLT_ROLE_AG = 2, // Device is an Audio Gateway 145 BLT_ROLE_GUI = 3 // Device is used as an GUI 146 } blt_role_t; 147 148 /* State when we're in HS mode */ 149 150 typedef enum { 151 BLT_STATE_WANT_R = 0, 152 BLT_STATE_WANT_N = 1, 153 BLT_STATE_WANT_CMD = 2, 154 BLT_STATE_WANT_N2 = 3, 155 } blt_state_t; 156 157 typedef enum { 158 BLT_STATUS_DOWN, 159 BLT_STATUS_CONNECTING, 160 BLT_STATUS_NEGOTIATING, 161 BLT_STATUS_READY, 162 BLT_STATUS_RINGING, 163 BLT_STATUS_IN_CALL, 164 } blt_status_t; 165 166 /* ---------------------------------- */ 167 168 /* Default config settings */ 169 170 #define BLT_DEFAULT_CHANNEL_AG 5 171 #define BLT_DEFAULT_CHANNEL_HS 6 172 #define BLT_DEFAULT_CHANNEL_GUI 1 173 #define BLT_DEFAULT_ROLE BLT_ROLE_HS 174 #define BLT_OBUF_LEN (48 * 25) 175 176 #define BUFLEN (4800) 177 178 /* ---------------------------------- */ 179 180 typedef struct blt_dev blt_dev_t; 181 182 void ag_cgmi_response(blt_dev_t * dev, char * cmd); 183 void ag_unknown_response(blt_dev_t * dev, char * cmd); 184 void ag_cgmi_valid_response(blt_dev_t * dev, char * cmd); 185 void ag_clip_response(blt_dev_t * dev, char * cmd); 186 void ag_cmer_response(blt_dev_t * dev, char * cmd); 187 void ag_cind_status_response(blt_dev_t * dev, char * cmd); 188 void ag_cind_response(blt_dev_t * dev, char * cmd); 189 void ag_brsf_response(blt_dev_t * dev, char * cmd); 190 void remove_sdp_records(void); 191 192 void gui_easm_response(blt_dev_t * dev, char * cmd); 193 194 int sock_err(int fd); 195 int parse_clip(const char * str, char *number, int number_len, char * name, int name_len, int *type); 196 int set_buffer(char * ring, char * data, int circular_len, int * pos, int data_len); 197 int get_buffer(char * dst, char * ring, int ring_size, int * head, int to_copy); 198 void gui_eaid_response(blt_dev_t * dev, char * cmd); 199 200 201 202 struct blt_ring { 203 unsigned char buf[BUFLEN]; 204 }; 205 // XXX:T: Tidy this lot up. 206 struct blt_dev { 207 208 blt_status_t status; /* Device Status */ 209 210 struct ast_channel * owner; /* Channel we belong to, possibly NULL */ 211 blt_dev_t * dev; /* The bluetooth device channel is for */ 212 struct ast_frame fr; /* Recieved frame */ 213 214 /* SCO Handler */ 215 int sco_pipe[2]; /* SCO alert pipe */ 216 int sco; /* SCO fd */ 217 int sco_handle; /* SCO Handle */ 218 int sco_mtu; /* SCO MTU */ 219 int sco_running; /* 1 when sCO thread should be running */ 220 pthread_t sco_thread; /* SCO thread */ 221 ast_mutex_t sco_lock; /* SCO lock */ 222 int sco_pos_in; /* Reader in position (drain)*/ 223 int sco_pos_inrcv; /* Reader in position (fill) */ 224 int wakeread; /* blt_read() needs to be woken */ 225 int sco_pos_out; /* Reader out position */ 226 int sco_sending; /* Sending SCO packets */ 227 char buf[1200]; /* Incoming data buffer */ 228 int bufpos; 229 char sco_buf_out[BUFLEN]; /* 24 chunks of 48 */ 230 char sco_buf_in[BUFLEN]; /* 24 chunks of 48 */ 231 232 char dnid[1024]; /* Outgoi gncall dialed number */ 233 unsigned char * obuf[BLT_OBUF_LEN]; /* Outgoing data buffer */ 234 int obuf_len; /* Output Buffer Position */ 235 int obuf_wpos; /* Buffer Reader */ 236 237 // device 238 int autoconnect; /* 1 for autoconnect */ 239 int outgoing_id; /* Outgoing connection scheduler id */ 240 char * name; /* Devices friendly name */ 241 blt_role_t role; /* Device role (HS or AG) */ 242 bdaddr_t bdaddr; /* remote address */ 243 int channel; /* remote channel */ 244 int rd; /* RFCOMM fd */ 245 int tmp_rd; /* RFCOMM fd */ 246 int call_cnt; /* Number of attempted calls */ 247 ast_mutex_t lock; /* RFCOMM socket lock */ 248 char rd_buff[BLT_RDBUFF_MAX]; /* RFCOMM input buffer */ 249 int rd_buff_pos; /* RFCOMM input buffer position */ 250 int ready; /* 1 When ready */ 251 char *context; 252 253 /* AG mode */ 254 char last_ok_cmd[BLT_RDBUFF_MAX]; /* Runtime[AG]: Last AT command that was OK */ 255 int cind; /* Runtime[AG]: Recieved +CIND */ 256 int call_pos, service_pos, callsetup_pos; /* Runtime[AG]: Positions in CIND/CMER */ 257 int call, service, callsetup; /* Runtime[AG]: Values */ 258 char cid_num[AST_MAX_EXTENSION]; 259 char cid_name[AST_MAX_EXTENSION]; 260 261 /* HS mode */ 262 blt_state_t state; /* Runtime: Device state (AG mode only) */ 263 int ring_timer; /* Runtime:Ring Timer */ 264 char last_err_cmd[BLT_RDBUFF_MAX]; /* Runtime: Last AT command that was OK */ 265 void (*cb)(blt_dev_t * dev, char * str); /* Runtime: Callback when in HS mode */ 266 267 int brsf; /* Runtime: Bluetooth Retrieve Supported Features */ 268 int bvra; /* Runtime: Bluetooth Voice Recognised Activation */ 269 int gain_speaker; /* Runtime: Gain Of Speaker */ 270 int clip; /* Runtime: Supports CLID */ 271 int colp; /* Runtime: Connected Line ID */ 272 int elip; /* Runtime: (Ericsson) Supports CLID */ 273 int eolp; /* Runtime: (Ericsson) Connected Line ID */ 274 int ringing; /* Runtime: Device is ringing */ 275 276 blt_dev_t * next; /* Next in linked list */ 277 278 }; 279 280 typedef struct blt_atcb { 281 282 /* The command */ 283 char * str; 284 285 /* DTE callbacks: */ 286 int (*set)(blt_dev_t * dev, const char * arg, int len); 287 int (*read)(blt_dev_t * dev); 288 int (*execute)(blt_dev_t * dev, const char * data); 289 int (*test)(blt_dev_t * dev); 290 291 /* DCE callbacks: */ 292 int (*unsolicited)(blt_dev_t * dev, const char * value); 293 294 } blt_atcb_t; 295 296 /* ---------------------------------- */ 297 298 static void rd_close(blt_dev_t * dev, int reconnect, int err); 299 static int send_atcmd(blt_dev_t * device, const char * fmt, ...); 300 static int sco_connect(blt_dev_t * dev); 301 static int sco_start(blt_dev_t * dev, int fd); 302 303 /* ---------------------------------- */ 304 305 /* RFCOMM channel we listen on*/ 306 static int rfcomm_channel_ag = BLT_DEFAULT_CHANNEL_AG; 307 static int rfcomm_channel_hs = BLT_DEFAULT_CHANNEL_HS; 308 static int rfcomm_channel_gui = BLT_DEFAULT_CHANNEL_GUI; 309 310 static char* gui_default_sip_number = ""; 311 static char* gui_default_sip_address = ""; 312 313 /* Address of local bluetooth interface */ 314 static int hcidev_id; 315 static bdaddr_t local_bdaddr; 316 317 /* All the current sockets */ 318 AST_MUTEX_DEFINE_STATIC(iface_lock); 319 static blt_dev_t * iface_head; 320 static int ifcount = 0; 321 322 static int sdp_record_hs = -1; 323 static int sdp_record_ag = -1; 324 static int sdp_record_gui = -1; 325 326 /* RFCOMM listen socket */ 327 static int rfcomm_sock_ag = -1; 328 static int rfcomm_sock_hs = -1; 329 static int rfcomm_sock_gui = -1; 330 331 static int sco_socket = -1; 332 333 static int monitor_pid = -1; 334 335 /* The socket monitoring thread */ 336 static pthread_t monitor_thread = AST_PTHREADT_NULL; 337 AST_MUTEX_DEFINE_STATIC(monitor_lock); 338 339 /* Count how many times this module is currently in use */ 340 static int usecnt = 0; 341 AST_MUTEX_DEFINE_STATIC(usecnt_lock); 342 343 static struct sched_context * sched = NULL; 344 345 /* ---------------------------------- */ 346 347 #if ASTERISK_VERSION_NUM <= 010107 348 #include <asterisk/channel_pvt.h> 349 #define tech_pvt pvt->pvt 350 #else /* CVS. FIXME: Version number */ 351 static struct ast_channel *blt_request(const char *type, int format, void *data, int *cause); 352 static int blt_hangup(struct ast_channel *c); 353 static int blt_answer(struct ast_channel *c); 354 static struct ast_frame *blt_read(struct ast_channel *chan); 355 static int blt_call(struct ast_channel *c, char *dest, int timeout); 356 static int blt_write(struct ast_channel *chan, struct ast_frame *f); 357 static int blt_indicate(struct ast_channel *chan, int cond); 358 359 static const struct ast_channel_tech blt_tech = { 360 .type = BLT_CHAN_NAME, 361 .description = "Bluetooth Channel Driver", 362 .capabilities = BLUETOOTH_FORMAT, 363 .requester = blt_request, 364 .hangup = blt_hangup, 365 .answer = blt_answer, 366 .read = blt_read, 367 .call = blt_call, 368 .write = blt_write, 369 .indicate = blt_indicate, 370 }; 371 #endif 372 /* ---------------------------------- */ 373 374 static const char * 375 role2str(blt_role_t role) 376 { 377 switch (role) { 378 case BLT_ROLE_HS: 379 return "HS"; 380 case BLT_ROLE_AG: 381 return "AG"; 382 case BLT_ROLE_GUI: 383 return "GUI"; 384 case BLT_ROLE_NONE: 385 default: 386 return "??"; 387 } 388 } 389 390 static const char * 391 status2str(blt_status_t status) 392 { 393 switch (status) { 394 case BLT_STATUS_DOWN: 395 return "Down"; 396 case BLT_STATUS_CONNECTING: 397 return "Connecting"; 398 case BLT_STATUS_NEGOTIATING: 399 return "Negotiating"; 400 case BLT_STATUS_READY: 401 return "Ready"; 402 case BLT_STATUS_RINGING: 403 return "Ringing"; 404 case BLT_STATUS_IN_CALL: 405 return "InCall"; 406 }; 407 return "Unknown"; 408 } 409 410 int sock_err(int fd) 411 { 412 int ret; 413 int len = sizeof(ret); 414 getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &len); 415 return ret; 416 } 417 418 /* ---------------------------------- */ 419 int parse_clip(const char * str, char *number, int number_len, char * name, int name_len, int *type) 420 { 421 const char *c = str; 422 const char *start; 423 int length; 424 char typestr[256]; 425 426 memset(number, 0, number_len); 427 memset(name, 0, name_len); 428 *type = 0; 429 430 number[0] = '\0'; 431 name[0] = '\0'; 432 while(*c && *c != '"') 433 c++; 434 c++; 435 start = c; 436 while(*c && *c != '"') 437 c++; 438 length = c - start < number_len ? c - start : number_len; 439 strncpy(number, start, length); 440 number[length] = '\0'; 441 c++; 442 while(*c && *c != ',') 443 c++; 444 c++; 445 start = c; 446 while(*c && *c != ',') 447 c++; 448 length = c - start < number_len ? c - start : number_len; 449 strncpy(typestr, start, length); 450 typestr[length] = '\0'; 451 *type = atoi(typestr); 452 c++; 453 while(*c && *c != ',') 454 c++; 455 c++; 456 while(*c && *c != ',') 457 c++; 458 c++; 459 while(*c && *c != '"') 460 c++; 461 c++; 462 start = c; 463 while(*c && *c != '"') 464 c++; 465 length = c - start < number_len ? c - start : number_len; 466 strncpy(name, start, length); 467 name[length] = '\0'; 468 469 return(1); 470 } 471 472 473 static const char * 474 parse_cind(const char * str, char * name, int name_len) 475 { 476 int c = 0; 477 478 memset(name, 0, name_len); 479 480 while (*str) { 481 if (*str == '(') { 482 if (++c == 1 && *(str+1) == '"') { 483 const char * start = str + 2; 484 int len = 0; 485 str += 2; 486 while (*str && *str != '"') { 487 len++; 488 str++; 489 } 490 if (len == 0) 491 return NULL; 492 strncpy(name, start, (len > name_len) ? name_len : len); 493 } 494 } else if (*str == ')') 495 c--; 496 else if (c == 0 && *str == ',') 497 return str + 1; 498 str++; 499 } 500 return NULL; 501 } 502 503 static void 504 set_cind(blt_dev_t * dev, int indicator, int val) 505 { 506 507 ast_log(LOG_DEBUG, "CIND %d set to %d\n", indicator, val); 508 509 if (indicator == dev->callsetup_pos) { 510 511 // call progress 512 513 dev->callsetup = val; 514 515 switch (val) { 516 case 3: 517 // Outgoing ringing 518 if ((dev->owner && dev->role == BLT_ROLE_AG) || 519 (dev->owner && dev->role == BLT_ROLE_GUI)) 520 ast_queue_control(dev->owner, AST_CONTROL_RINGING); 521 break; 522 case 2: 523 break; 524 case 1: 525 break; 526 case 0: 527 if ((dev->owner && dev->role == BLT_ROLE_AG && dev->call == 0) || 528 (dev->owner && dev->role == BLT_ROLE_AG && dev->call == 0)) 529 ast_queue_control(dev->owner, AST_CONTROL_CONGESTION); 530 break; 531 } 532 533 } else if (indicator == dev->service_pos) { 534 535 // Signal 536 537 if (val == 0) 538 ast_log(LOG_NOTICE, "Audio Gateway %s lost signal\n", dev->name); 539 else if (dev->service == 0 && val > 0) 540 ast_log(LOG_NOTICE, "Audio Gateway %s got signal\n", dev->name); 541 542 dev->service = val; 543 544 } else if (indicator == dev->call_pos) { 545 546 // Call 547 548 dev->call = val; 549 550 if (dev->owner) { 551 if (val == 1) { 552 sco_start(dev, -1); 553 ast_queue_control(dev->owner, AST_CONTROL_ANSWER); 554 } else if (val == 0) 555 ast_queue_control(dev->owner, AST_CONTROL_HANGUP); 556 } 557 558 } 559 560 561 } 562 563 /* ---------------------------------- */ 564 565 int 566 set_buffer(char * ring, char * data, int circular_len, int * pos, int data_len) 567 { 568 int start_pos = *(pos); 569 int done = 0; 570 int copy; 571 572 while (data_len) { 573 // Set can_do to the most we can do in this copy. 574 575 copy = MIN(circular_len - start_pos, data_len); 576 memcpy(ring + start_pos, data + done, copy); 577 done += copy; 578 start_pos += copy; 579 data_len -= copy; 580 581 if (start_pos == circular_len) { 582 start_pos = 0; 583 } 584 } 585 *(pos) = start_pos; 586 return 0; 587 } 588 589 int 590 get_buffer(char * dst, char * ring, int ring_size, int * head, int to_copy) 591 { 592 int copy; 593 594 // |1|2|3|4|5|6|7|8|9| 595 // |-----| 596 597 while (to_copy) { 598 599 // Set can_do to the most we can do in this copy. 600 copy = MIN(ring_size - *head, to_copy); 601 602 // ast_log(LOG_DEBUG, "Getting: %d bytes, From pos %d\n", copy, *head); 603 #if __BYTE_ORDER == __LITTLE_ENDIAN 604 memcpy(dst, ring + *head, copy); 605 #else 606 // memcpy(dst, ring + *head, copy); 607 ast_swapcopy_samples(dst, ring+*head, copy/2); 608 #endif 609 memset(ring+*head, 0, copy); 610 dst += copy; 611 *head += copy; 612 to_copy -= copy; 613 614 if (*head == ring_size ) { 615 *head = 0; 616 } 617 618 } 619 620 return 0; 621 } 622 623 /* Handle SCO audio sync. 624 * 625 * If we are the MASTER, then we control the timing, 626 * in 48 byte chunks. If we're the SLAVE, we send 627 * as and when we recieve a packet. 628 * 629 * Because of packet/timing nessecity, we 630 * start up a thread when we're passing audio, so 631 * that things are timed exactly right. 632 * 633 * sco_thread() is the function that handles it. 634 * 635 */ 636 637 static void * 638 sco_thread(void * data) 639 { 640 blt_dev_t * dev = (blt_dev_t*)data; 641 int res; 642 struct pollfd pfd[2]; 643 int in_pos = 0; 644 int out_pos = 0; 645 char c = 1; 646 int sending; 647 char buf[1024]; 648 int len; 649 650 // Avoid deadlock in odd circumstances 651 652 ast_log(LOG_WARNING, "SCO thread started on fd %d, pid %d\n", dev->sco, getpid()); 653 654 if (fcntl(dev->sco_pipe[1], F_SETFL, O_RDWR|O_NONBLOCK)) { 655 ast_log(LOG_WARNING, "fcntl failed on sco_pipe\n"); 656 } 657 658 // dev->status = BLT_STATUS_IN_CALL; 659 // ast_queue_control(dev->owner, AST_CONTROL_ANSWER); 660 // Set buffer to silence, just incase. 661 662 ast_mutex_lock(&(dev->sco_lock)); 663 664 memset(dev->sco_buf_in, 0, BUFLEN); 665 memset(dev->sco_buf_out, 0, BUFLEN); 666 667 dev->sco_pos_in = 0; 668 dev->sco_pos_out = 0; 669 dev->sco_pos_inrcv = 0; 670 dev->wakeread = 1; 671 672 ast_mutex_unlock(&(dev->sco_lock)); 673 674 while (1) { 675 676 ast_mutex_lock(&(dev->sco_lock)); 677 678 if (dev->sco_running != 1) { 679 ast_log(LOG_DEBUG, "SCO stopped.\n"); 680 break; 681 } 682 683 pfd[0].fd = dev->sco; 684 pfd[0].events = POLLIN; 685 686 pfd[1].fd = dev->sco_pipe[1]; 687 pfd[1].events = POLLIN; 688 689 ast_mutex_unlock(&(dev->sco_lock)); 690 691 res = poll(pfd, 2, 50); 692 693 if (res == -1 && errno != EINTR) { 694 ast_log(LOG_DEBUG, "SCO poll() error\n"); 695 break; 696 } 697 698 if (res == 0) 699 continue; 700 701 702 if (pfd[0].revents & POLLIN) { 703 704 len = read(dev->sco, buf, 48); 705 706 if (len) { 707 ast_mutex_lock(&(dev->lock)); 708 709 if (dev->owner && dev->owner->_state == AST_STATE_UP) { 710 ast_mutex_lock(&(dev->sco_lock)); 711 set_buffer(dev->sco_buf_in, buf, BUFLEN, &in_pos, len); 712 dev->sco_pos_inrcv = in_pos; 713 714 get_buffer(buf, dev->sco_buf_out, BUFLEN, &out_pos, len); 715 if (write(dev->sco, buf, len) != len) 716 ast_log(LOG_WARNING, "Wrote <48 to sco\n"); 717 718 if (dev->wakeread) { 719 /* blt_read has caught up. Kick it */ 720 dev->wakeread = 0; 721 if(write(dev->sco_pipe[1], &c, 1) != 1) 722 ast_log(LOG_WARNING, "write to kick sco_pipe failed\n"); 723 } 724 ast_mutex_unlock(&(dev->sco_lock)); 725 } 726 ast_mutex_unlock(&(dev->lock)); 727 } 728 729 } else if (pfd[0].revents) { 730 731 int e = sock_err(pfd[0].fd); 732 ast_log(LOG_ERROR, "SCO connection error: %s (errno %d)\n", strerror(e), e); 733 break; 734 735 } else if (pfd[1].revents & POLLIN) { 736 737 int len; 738 739 len = read(pfd[1].fd, &c, 1); 740 sending = (sending) ? 0 : 1; 741 742 ast_mutex_unlock(&(dev->sco_lock)); 743 744 } else if (pfd[1].revents) { 745 746 int e = sock_err(pfd[1].fd); 747 ast_log(LOG_ERROR, "SCO pipe connection event %d on pipe[1]=%d: %s (errno %d)\n", pfd[1].revents, pfd[1].fd, strerror(e), e); 748 break; 749 750 } else { 751 ast_log(LOG_NOTICE, "Unhandled poll output\n"); 752 ast_mutex_unlock(&(dev->sco_lock)); 753 } 754 755 } 756 757 ast_mutex_lock(&(dev->lock)); 758 close(dev->sco); 759 dev->sco = -1; 760 dev->sco_running = -1; 761 762 memset(dev->sco_buf_in, 0, BUFLEN); 763 memset(dev->sco_buf_out, 0, BUFLEN); 764 765 dev->sco_pos_in = 0; 766 dev->sco_pos_out = 0; 767 dev->sco_pos_inrcv = 0; 768 769 ast_mutex_unlock(&(dev->sco_lock)); 770 if (dev->owner) 771 ast_queue_control(dev->owner, AST_CONTROL_HANGUP); 772 ast_mutex_unlock(&(dev->lock)); 773 ast_log(LOG_DEBUG, "SCO thread stopped\n"); 774 return NULL; 775 } 776 777 /* Start SCO thread. Must be called with dev->lock */ 778 779 static int 780 sco_start(blt_dev_t * dev, int fd) 781 { 782 783 if (dev->sco_pipe[1] <= 0) { 784 ast_log(LOG_ERROR, "SCO pipe[1] == %d\n", dev->sco_pipe[1]); 785 return -1; 786 } 787 788 ast_mutex_lock(&(dev->sco_lock)); 789 790 if (dev->sco_running != -1) { 791 ast_log(LOG_ERROR, "Tried to start SCO thread while already running\n"); 792 ast_mutex_unlock(&(dev->sco_lock)); 793 return -1; 794 } 795 796 if (dev->sco == -1) { 797 if (fd > 0) { 798 dev->sco = fd; 799 } else if (sco_connect(dev) != 0) { 800 ast_log(LOG_ERROR, "SCO fd invalid\n"); 801 ast_mutex_unlock(&(dev->sco_lock)); 802 return -1; 803 } 804 } 805 806 dev->sco_running = 1; 807 808 if (ast_pthread_create(&(dev->sco_thread), NULL, sco_thread, dev) < 0) { 809 ast_log(LOG_ERROR, "Unable to start SCO thread.\n"); 810 dev->sco_running = -1; 811 ast_mutex_unlock(&(dev->sco_lock)); 812 return -1; 813 } 814 815 ast_mutex_unlock(&(dev->sco_lock)); 816 817 return 0; 818 } 819 820 /* Stop SCO thread. Must be called with dev->lock */ 821 822 static int 823 sco_stop(blt_dev_t * dev) 824 { 825 ast_mutex_lock(&(dev->sco_lock)); 826 if (dev->sco_running == 1) 827 dev->sco_running = 0; 828 else 829 dev->sco_running = -1; 830 dev->sco_sending = 0; 831 ast_mutex_unlock(&(dev->sco_lock)); 832 return 0; 833 } 834 835 /* ---------------------------------- */ 836 837 /* Answer the call. Call with lock held on device */ 838 839 static int 840 answer(blt_dev_t * dev) 841 { 842 843 if ( (!dev->owner) || (dev->ready != 1) || (dev->status != BLT_STATUS_READY && dev->status != BLT_STATUS_RINGING)) { 844 ast_log(LOG_ERROR, "Attempt to answer() in invalid state (owner=%p, ready=%d, status=%s)\n", 845 dev->owner, dev->ready, status2str(dev->status)); 846 return -1; 847 } 848 849 // dev->sd = sco_connect(&local_bdaddr, &(dev->bdaddr), NULL, NULL, 0); 850 // dev->status = BLT_STATUS_IN_CALL; 851 // dev->owner->fds[0] = dev->sd; 852 // if we are answering (hitting button): 853 ast_queue_control(dev->owner, AST_CONTROL_ANSWER); 854 // if asterisk signals us to answer: 855 // ast_setstate(ast, AST_STATE_UP); 856 857 /* Start SCO link */ 858 sco_start(dev, -1); 859 return 0; 860 } 861 862 /* ---------------------------------- */ 863 864 static int 865 blt_write(struct ast_channel * ast, struct ast_frame * frame) 866 { 867 blt_dev_t * dev = ast->tech_pvt; 868 869 /* Write a frame of (presumably voice) data */ 870 871 if (frame->frametype != AST_FRAME_VOICE) { 872 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype); 873 return 0; 874 } 875 876 if (!(frame->subclass & BLUETOOTH_FORMAT)) { 877 static int fish = 5; 878 if (fish) { 879 ast_log(LOG_WARNING, "Cannot handle frames in format %d\n", frame->subclass); 880 fish--; 881 } 882 return 0; 883 } 884 885 if (ast->_state != AST_STATE_UP) { 886 return 0; 887 } 888 889 ast_mutex_lock(&(dev->sco_lock)); 890 set_buffer(dev->sco_buf_out, frame->data, BUFLEN, &(dev->sco_pos_out), MIN(frame->datalen, BUFLEN)); 891 ast_mutex_unlock(&(dev->sco_lock)); 892 893 return 0; 894 895 } 896 897 static struct ast_frame * 898 blt_read(struct ast_channel * ast) 899 { 900 blt_dev_t * dev = ast->tech_pvt; 901 char c = 1; 902 int len; 903 static int fish = 0; 904 /* Some nice norms */ 905 906 dev->fr.datalen = 0; 907 dev->fr.samples = 0; 908 dev->fr.data = NULL; 909 dev->fr.src = BLT_CHAN_NAME; 910 dev->fr.offset = 0; 911 dev->fr.mallocd = AST_MALLOCD_DATA; 912 dev->fr.delivery.tv_sec = 0; 913 dev->fr.delivery.tv_usec = 0; 914 read(dev->sco_pipe[0], &c, 1); 915 ast_mutex_lock(&(dev->sco_lock)); 916 dev->sco_sending = 1; 917 918 if (dev->sco_pos_inrcv < dev->sco_pos_in) { 919 /* Buffer wrapped. Read only till the end */ 920 len = BUFLEN - dev->sco_pos_in + dev->sco_pos_inrcv; 921 } else { 922 len = dev->sco_pos_inrcv - dev->sco_pos_in; 923 } 924 dev->fr.data = malloc(AST_FRIENDLY_OFFSET+len) + AST_FRIENDLY_OFFSET; 925 926 get_buffer(dev->fr.data, dev->sco_buf_in, BUFLEN, &(dev->sco_pos_in), len); 927 dev->wakeread = 1; 928 ast_mutex_unlock(&(dev->sco_lock)); 929 if (fish) { 930 unsigned char *x = dev->fr.data; 931 ast_log(LOG_WARNING, "blt_read %d: %02x %02x %02x %02x %02x %02x\n", 932 dev->fr.datalen, x[0], x[1], x[2], x[3], x[4], x[5]); 933 fish--; 934 } 935 936 dev->fr.samples = len / 2; 937 dev->fr.datalen = len; 938 dev->fr.frametype = AST_FRAME_VOICE; 939 dev->fr.subclass = BLUETOOTH_FORMAT; 940 dev->fr.offset = AST_FRIENDLY_OFFSET; 941 return &dev->fr; 942 } 943 944 /* Escape Any '"' in str. Return malloc()ed string */ 945 static char * 946 escape_str(char * str) 947 { 948 char * ptr = str; 949 char * pret; 950 char * ret; 951 int len = 0; 952 953 while (*ptr) { 954 if (*ptr == '"') 955 len++; 956 len++; 957 ptr++; 958 } 959 960 ret = malloc(len + 1); 961 pret = memset(ret, 0, len + 1); 962 963 ptr = str; 964 965 while (*ptr) { 966 if (*ptr == '"') 967 *pret++ = '\\'; 968 *pret++ = *ptr++; 969 } 970 971 return ret; 972 } 973 974 static int 975 ring_hs(blt_dev_t * dev) 976 { 977 #if (ASTERISK_VERSION_NUM < 010100) 978 char tmp[AST_MAX_EXTENSION]; 979 char *name, *num; 980 #endif 981 982 ast_mutex_lock(&(dev->lock)); 983 984 if (dev->owner == NULL) { 985 ast_mutex_unlock(&(dev->lock)); 986 return 0; 987 } 988 989 dev->ringing = 1; 990 dev->status = BLT_STATUS_RINGING; 991 992 send_atcmd(dev, "RING"); 993 994 dev->owner->rings++; 995 996 // XXX:T: '"' needs to be escaped in ELIP. 997 998 #if (ASTERISK_VERSION_NUM < 010100) 999 1000 if (dev->owner->callerid) { 1001 1002 memset(tmp, 0, sizeof(tmp)); 1003 strncpy(tmp, dev->owner->callerid, sizeof(tmp)-1); 1004 1005 if (!ast_callerid_parse(tmp, &name, &num)) { 1006 1007 if (dev->clip && num) 1008 send_atcmd(dev, "+CLIP: \"%s\",129", num); 1009 1010 if (dev->elip && name) { 1011 char * esc = escape_str(name); 1012 send_atcmd(dev, "*ELIP: \"%s\"", esc); 1013 free(esc); 1014 } 1015 } 1016 } 1017 1018 1019 #else 1020 1021 if (dev->clip && dev->owner->cid.cid_num) 1022 send_atcmd(dev, "+CLIP: \"%s\",129", dev->owner->cid.cid_num); 1023 1024 if (dev->elip && dev->owner->cid.cid_name) { 1025 char * esc = escape_str(dev->owner->cid.cid_name); 1026 send_atcmd(dev, "*ELIP: \"%s\"", esc); 1027 free(esc); 1028 } 1029 1030 #endif 1031 1032 ast_mutex_unlock(&(dev->lock)); 1033 1034 return 1; 1035 } 1036 1037 /* 1038 * If the HS is already connected, then just send RING, otherwise, things get a 1039 * little more sticky. We first have to find the channel for HS using SDP, 1040 * then initiate the connection. Once we've done that, we can start the call. 1041 */ 1042 1043 static int 1044 blt_call(struct ast_channel * ast, char * dest, int timeout) 1045 { 1046 blt_dev_t * dev = ast->tech_pvt; 1047 1048 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 1049 ast_log(LOG_WARNING, "blt_call called on %s, neither down nor reserved\n", ast->name); 1050 return -1; 1051 } 1052 1053 ast_log(LOG_DEBUG, "Calling %s on %s [t: %d]\n", dest, ast->name, timeout); 1054 1055 if (ast_mutex_lock(&iface_lock)) { 1056 ast_log(LOG_ERROR, "Failed to get iface_lock.\n"); 1057 return -1; 1058 } 1059 1060 // ast_mutex_lock(&(dev->lock)); 1061 1062 if (dev->ready == 0) { 1063 ast_log(LOG_WARNING, "Tried to call a device not ready/connected.\n"); 1064 ast_setstate(ast, AST_CONTROL_CONGESTION); 1065 // ast_mutex_unlock(&(dev->lock)); 1066 ast_mutex_unlock(&iface_lock); 1067 return 0; 1068 } 1069 1070 if (dev->role == BLT_ROLE_HS) { 1071 1072 send_atcmd(dev, "+CIEV: 3,1"); 1073 1074 dev->ring_timer = ast_sched_add(sched, 5000, AST_SCHED_CB(ring_hs), dev); 1075 1076 ring_hs(dev); 1077 1078 ast_setstate(ast, AST_STATE_RINGING); 1079 ast_queue_control(ast, AST_CONTROL_RINGING); 1080 1081 } else if (dev->role == BLT_ROLE_AG) { 1082 1083 send_atcmd(dev, "ATD%s;", dev->dnid); 1084 // it does not seem like we should start the audio until the call is connected 1085 // sco_start(dev, -1); 1086 } else if (dev->role == BLT_ROLE_GUI) { 1087 1088 send_atcmd(dev, "ATD%s;", dev->dnid); 1089 1090 } else { 1091 1092 ast_setstate(ast, AST_CONTROL_CONGESTION); 1093 ast_log(LOG_ERROR, "Unknown device role\n"); 1094 1095 } 1096 1097 // ast_mutex_unlock(&(dev->lock)); 1098 ast_mutex_unlock(&iface_lock); 1099 1100 return 0; 1101 } 1102 1103 static int 1104 blt_hangup(struct ast_channel * ast) 1105 { 1106 blt_dev_t * dev = ast->tech_pvt; 1107 1108 ast_log(LOG_DEBUG, "blt_hangup(%s)\n", ast->name); 1109 1110 if (!ast->tech_pvt) { 1111 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 1112 return 0; 1113 } 1114 1115 if (ast_mutex_lock(&iface_lock)) { 1116 ast_log(LOG_ERROR, "Failed to get iface_lock\n"); 1117 return 0; 1118 } 1119 1120 ast_mutex_lock(&(dev->lock)); 1121 1122 sco_stop(dev); 1123 dev->sco_sending = 0; 1124 1125 if (dev->role == BLT_ROLE_HS) { 1126 1127 if (dev->ringing == 0) { 1128 // Actual call in progress 1129 send_atcmd(dev, "+CIEV: 2,0"); 1130 } else { 1131 1132 // Just ringing still 1133 1134 if (dev->role == BLT_ROLE_HS) 1135 send_atcmd(dev, "+CIEV: 3,0"); 1136 1137 if (dev->ring_timer >= 0) 1138 ast_sched_del(sched, dev->ring_timer); 1139 1140 dev->ring_timer = -1; 1141 dev->ringing = 0; 1142 1143 } 1144 1145 } else if (dev->role == BLT_ROLE_AG) { 1146 1147 // Cancel call. 1148 send_atcmd(dev, "ATH"); 1149 send_atcmd(dev, "AT+CHUP"); 1150 1151 } 1152 1153 if (dev->status == BLT_STATUS_IN_CALL || dev->status == BLT_STATUS_RINGING) 1154 dev->status = BLT_STATUS_READY; 1155 1156 ast->tech_pvt = NULL; 1157 dev->owner = NULL; 1158 ast_mutex_unlock(&(dev->lock)); 1159 ast_setstate(ast, AST_STATE_DOWN); 1160 ast_mutex_unlock(&(iface_lock)); 1161 1162 return 0; 1163 } 1164 1165 static int 1166 blt_indicate(struct ast_channel * c, int condition) 1167 { 1168 ast_log(LOG_DEBUG, "blt_indicate (%d)\n", condition); 1169 1170 switch(condition) { 1171 case AST_CONTROL_RINGING: 1172 return -1; 1173 default: 1174 ast_log(LOG_WARNING, "Don't know how to condition %d\n", condition); 1175 break; 1176 } 1177 return -1; 1178 } 1179 1180 static int 1181 blt_answer(struct ast_channel * ast) 1182 { 1183 blt_dev_t * dev = ast->tech_pvt; 1184 1185 ast_mutex_lock(&dev->lock); 1186 1187 // if (dev->ring_timer >= 0) 1188 // ast_sched_del(sched, dev->ring_timer); 1189 // dev->ring_timer = -1; 1190 1191 ast_log(LOG_DEBUG, "Answering interface\n"); 1192 1193 if (ast->_state != AST_STATE_UP) { 1194 send_atcmd(dev, "+CIEV: 2,1"); 1195 send_atcmd(dev, "+CIEV: 3,0"); 1196 sco_start(dev, -1); 1197 ast_setstate(ast, AST_STATE_UP); 1198 } 1199 1200 ast_mutex_unlock(&dev->lock); 1201 1202 return 0; 1203 } 1204 1205 static struct ast_channel * 1206 blt_new(blt_dev_t * dev, int state, const char * context, const char * number) 1207 { 1208 struct ast_channel * ast; 1209 char c = 0; 1210 1211 if ((ast = ast_channel_alloc(1)) == NULL) { 1212 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 1213 return NULL; 1214 } 1215 1216 snprintf(ast->name, sizeof(ast->name), "BLT/%s", dev->name); 1217 1218 // ast->fds[0] = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); 1219 1220 ast->nativeformats = BLUETOOTH_FORMAT; 1221 //ast->rawreadformat = BLUETOOTH_FORMAT; 1222 //ast->rawwriteformat = BLUETOOTH_FORMAT; 1223 ast->writeformat = BLUETOOTH_FORMAT; 1224 ast->readformat = BLUETOOTH_FORMAT; 1225 1226 ast_setstate(ast, state); 1227 1228 ast->type = BLT_CHAN_NAME; 1229 1230 ast->tech_pvt = dev; 1231 #if ASTERISK_VERSION_NUM > 010107 1232 ast->tech = &blt_tech; 1233 #else 1234 ast->pvt->call = blt_call; 1235 ast->pvt->indicate = blt_indicate; 1236 ast->pvt->hangup = blt_hangup; 1237 ast->pvt->read = blt_read; 1238 ast->pvt->write = blt_write; 1239 ast->pvt->answer = blt_answer; 1240 #endif 1241 strncpy(ast->context, context, sizeof(ast->context)-1); 1242 strncpy(ast->exten, number, sizeof(ast->exten) - 1); 1243 if(0 == strcmp(number, "s")) 1244 { 1245 //ast_set_callerid(ast, dev->cid_num, dev->cid_name, dev->cid_num); 1246 } 1247 1248 ast->language[0] = '\0'; 1249 1250 ast->fds[0] = dev->sco_pipe[0]; 1251 write(dev->sco_pipe[1], &c, 1); 1252 1253 dev->owner = ast; 1254 1255 ast_mutex_lock(&usecnt_lock); 1256 usecnt++; 1257 ast_mutex_unlock(&usecnt_lock); 1258 1259 ast_update_use_count(); 1260 1261 if (state != AST_STATE_DOWN) { 1262 if (ast_pbx_start(ast)) { 1263 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast->name); 1264 ast_hangup(ast); 1265 } 1266 } 1267 1268 return ast; 1269 } 1270 1271 static struct ast_channel * 1272 #if (ASTERISK_VERSION_NUM < 010100) 1273 blt_request(char * type, int format, void * local_data) 1274 #elif (ASTERISK_VERSION_NUM <= 010107) 1275 blt_request(const char * type, int format, void * local_data) 1276 #else 1277 blt_request(const char * type, int format, void * local_data, int *cause) 1278 #endif 1279 { 1280 char * data = (char*)local_data; 1281 int oldformat; 1282 blt_dev_t * dev = NULL; 1283 struct ast_channel * ast = NULL; 1284 char * number = data, * dname; 1285 1286 dname = strsep(&number, "/"); 1287 1288 oldformat = format; 1289 1290 format &= BLUETOOTH_FORMAT; 1291 1292 if (!format) { 1293 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat); 1294 return NULL; 1295 } 1296 1297 ast_log(LOG_DEBUG, "Dialing '%s' via '%s'\n", number, dname); 1298 1299 if (ast_mutex_lock(&iface_lock)) { 1300 ast_log(LOG_ERROR, "Unable to lock iface_list\n"); 1301 return NULL; 1302 } 1303 1304 dev = iface_head; 1305 1306 while (dev) { 1307 if (strcmp(dev->name, dname) == 0) { 1308 ast_mutex_lock(&(dev->lock)); 1309 if (!dev->ready) { 1310 ast_log(LOG_ERROR, "Device %s is not connected\n", dev->name); 1311 ast_mutex_unlock(&(dev->lock)); 1312 ast_mutex_unlock(&iface_lock); 1313 return NULL; 1314 } 1315 break; 1316 } 1317 dev = dev->next; 1318 } 1319 1320 ast_mutex_unlock(&iface_lock); 1321 1322 if (!dev) { 1323 ast_log(LOG_WARNING, "Failed to find device named '%s'\n", dname); 1324 return NULL; 1325 } 1326 1327 if (number && dev->role != BLT_ROLE_AG) { 1328 ast_log(LOG_WARNING, "Tried to send a call out on non AG\n"); 1329 ast_mutex_unlock(&(dev->lock)); 1330 return NULL; 1331 } 1332 1333 if (dev->role == BLT_ROLE_AG) 1334 strncpy(dev->dnid, number, sizeof(dev->dnid) - 1); 1335 1336 ast = blt_new(dev, AST_STATE_DOWN, dev->context, "s"); 1337 1338 ast_mutex_unlock(&(dev->lock)); 1339 1340 return ast; 1341 } 1342 1343 /* ---------------------------------- */ 1344 1345 1346 /* ---- AT COMMAND SOCKET STUFF ---- */ 1347 1348 static int 1349 send_atcmd(blt_dev_t * dev, const char * fmt, ...) 1350 { 1351 char buf[1024]; 1352 va_list ap; 1353 int len; 1354 1355 va_start(ap, fmt); 1356 len = vsnprintf(buf, 1023, fmt, ap); 1357 va_end(ap); 1358 1359 if (option_verbose) 1360 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s < %s\n", role2str(dev->role), 10, dev->name, buf); 1361 1362 write(dev->rd, "\r\n", 2); 1363 len = write(dev->rd, buf, len); 1364 write(dev->rd, "\r\n", 2); 1365 return (len) ? 0 : -1; 1366 } 1367 1368 1369 static int 1370 send_atcmd_ok(blt_dev_t * dev, const char * cmd) 1371 { 1372 int len; 1373 strncpy(dev->last_ok_cmd, cmd, BLT_RDBUFF_MAX - 1); 1374 if (option_verbose) 1375 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s < OK\n", role2str(dev->role), 10, dev->name); 1376 len = write(dev->rd, "\r\nOK\r\n", 6); 1377 return (len) ? 0 : -1; 1378 } 1379 1380 static int 1381 send_atcmd_error(blt_dev_t * dev) 1382 { 1383 int len; 1384 1385 if (option_verbose) 1386 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s < ERROR\n", role2str(dev->role), 10, dev->name); 1387 1388 // write(dev->rd, "\r\n", 2); 1389 // len = write(dev->rd, dev->last_ok_cmd, 5); 1390 write(dev->rd, "\r\n", 2); 1391 len = write(dev->rd, "ERROR", 5); 1392 write(dev->rd, "\r\n", 2); 1393 1394 return (len) ? 0 : -1; 1395 } 1396 1397 1398 /* ---------------------------------- */ 1399 1400 /* -- Handle negotiation when we're an AG -- */ 1401 1402 /* Bluetooth Support */ 1403 1404 static int 1405 atcmd_brsf_set(blt_dev_t * dev, const char * arg, int len) 1406 { 1407 ast_log(LOG_DEBUG, "Device Supports: %s\n", arg); 1408 dev->brsf = atoi(arg); 1409 send_atcmd(dev, "+BRSF: %d", 23); 1410 return 0; 1411 } 1412 1413 /* Bluetooth Voice Recognition */ 1414 1415 static int 1416 atcmd_bvra_set(blt_dev_t * dev, const char * arg, int len) 1417 { 1418 ast_log(LOG_WARNING, "+BVRA Not Yet Supported\n"); 1419 return -1; 1420 #if 0 1421 // XXX:T: Fix voice recognition somehow! 1422 int action = atoi(arg); 1423 ast_log(LOG_DEBUG, "Voice Recognition: %s\n", (a) ? "ACTIVATED" : "DEACTIVATED"); 1424 if ((action == 0) & (dev->bvra == 1)) { 1425 /* Disable it */ 1426 dev->bvra = 0; 1427 // XXX:T: Shutdown any active bvra channel 1428 ast_log(LOG_DEBUG, "Voice Recognition: DISABLED\n"); 1429 } else if ((action == 1) && (dev->bvra == 0)) { 1430 /* Enable it */ 1431 dev->bvra = 1; 1432 // XXX:T: Schedule connection to voice recognition extension/application 1433 ast_log(LOG_DEBUG, "Voice Recognition: ENABLED\n"); 1434 } else { 1435 ast_log(LOG_ERROR, "+BVRA out of sync (we think %d, but HS wants %d)\n", dev->bvra, action); 1436 return -1; 1437 } 1438 return 0; 1439 #endif 1440 } 1441 1442 /* Clock */ 1443 1444 static int 1445 atcmd_cclk_read(blt_dev_t * dev) 1446 { 1447 struct tm t, *tp; 1448 const time_t ti = time(0); 1449 tp = localtime_r(&ti, &t); 1450 send_atcmd(dev, "+CCLK: \"%02d/%02d/%02d,%02d:%02d:%02d+%02d\"", 1451 (tp->tm_year % 100), (tp->tm_mon + 1), (tp->tm_mday), 1452 tp->tm_hour, tp->tm_min, tp->tm_sec, ((tp->tm_gmtoff / 60) / 15)); 1453 return 0; 1454 } 1455 1456 /* CHUP - Hangup Call */ 1457 1458 static int 1459 atcmd_chup_execute(blt_dev_t * dev, const char * data) 1460 { 1461 if (!dev->owner) { 1462 ast_log(LOG_ERROR, "Request to hangup call when none in progress\n"); 1463 return -1; 1464 } 1465 ast_log(LOG_DEBUG, "Hangup Call\n"); 1466 ast_queue_control(dev->owner, AST_CONTROL_HANGUP); 1467 return 0; 1468 } 1469 1470 /* CIND - Call Indicator */ 1471 1472 static int 1473 atcmd_cind_read(blt_dev_t * dev) 1474 { 1475 send_atcmd(dev, "+CIND: 1,0,0"); 1476 return 0; 1477 } 1478 1479 static int 1480 atcmd_cind_test(blt_dev_t * dev) 1481 { 1482 send_atcmd(dev, "+CIND: (\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0-4))"); 1483 return 0; 1484 } 1485 1486 /* Set Language */ 1487 1488 static int 1489 atcmd_clan_read(blt_dev_t * dev) 1490 { 1491 send_atcmd(dev, "+CLAN: \"en\""); 1492 return 0; 1493 } 1494 1495 /* Caller Id Presentation */ 1496 1497 static int 1498 atcmd_clip_set(blt_dev_t * dev, const char * arg, int len) 1499 { 1500 dev->clip = atoi(arg); 1501 return 0; 1502 } 1503 1504 /* Connected Line Identification Presentation */ 1505 1506 static int 1507 atcmd_colp_set(blt_dev_t * dev, const char * arg, int len) 1508 { 1509 dev->colp = atoi(arg); 1510 return 0; 1511 } 1512 1513 /* CMER - Mobile Equipment Event Reporting */ 1514 1515 static int 1516 atcmd_cmer_set(blt_dev_t * dev, const char * arg, int len) 1517 { 1518 dev->ready = 1; 1519 dev->status = BLT_STATUS_READY; 1520 return 0; 1521 } 1522 1523 /* PhoneBook Types: 1524 * 1525 * - FD - SIM Fixed Dialing Phone Book 1526 * - ME - ME Phone book 1527 * - SM - SIM Phone Book 1528 * - DC - ME dialled-calls list 1529 * - RC - ME recieved-calls lisr 1530 * - MC - ME missed-calls list 1531 * - MV - ME Voice Activated Dialing List 1532 * - HP - Hierachial Phone Book 1533 * - BC - Own Business Card (PIN2 required) 1534 * 1535 */ 1536 1537 /* Read Phone Book Entry */ 1538 1539 static int 1540 atcmd_cpbr_set(blt_dev_t * dev, const char * arg, int len) 1541 { 1542 // XXX:T: Fix the phone book! 1543 // * Maybe add res_phonebook or something? */ 1544 send_atcmd(dev, "+CPBR: %d,\"%s\",128,\"%s\"", atoi(arg), arg, arg); 1545 return 0; 1546 } 1547 1548 /* Select Phone Book */ 1549 1550 static int 1551 atcmd_cpbs_set(blt_dev_t * dev, const char * arg, int len) 1552 { 1553 // XXX:T: I guess we'll just accept any? 1554 return 0; 1555 } 1556 1557 static int 1558 atcmd_cscs_set(blt_dev_t * dev, const char * arg, int len) 1559 { 1560 // XXX:T: Language 1561 return 0; 1562 } 1563 1564 static int 1565 atcmd_eips_set(blt_dev_t * dev, const char * arg, int len) 1566 { 1567 ast_log(LOG_DEBUG, "Identify Presentation Set: %s=%s\n", 1568 (*(arg) == 49) ? "ELIP" : "EOLP", 1569 (*(arg+2) == 49) ? "ON" : "OFF"); 1570 1571 if (*(arg) == 49) 1572 dev->eolp = (*(arg+2) == 49) ? 1 : 0; 1573 else 1574 dev->elip = (*(arg+2) == 49) ? 1 : 0; 1575 1576 return 0; 1577 } 1578 1579 /* VGS - Speaker Volume Gain */ 1580 1581 static int 1582 atcmd_vgs_set(blt_dev_t * dev, const char * arg, int len) 1583 { 1584 dev->gain_speaker = atoi(arg); 1585 return 0; 1586 } 1587 1588 void 1589 gui_eaid_response(blt_dev_t * dev, char * cmd) 1590 { 1591 ast_log(LOG_NOTICE, "Submenu displayed.\n"); 1592 } 1593 1594 static int 1595 atcmd_eami_execute(blt_dev_t * dev, const char * data) 1596 { 1597 char * number = NULL; 1598 1599 number = strndup(data, strlen(data)); 1600 int menuitem = atoi(number); 1601 1602 ast_log(LOG_NOTICE, "Menu Item '%d'.\n", menuitem); 1603 1604 dev->cb = gui_eaid_response; 1605 1606 if (menuitem == 1) { 1607 char command[1024] = ""; 1608 const char* c1 = "AT*EAID=8,1,\"Make a SIP call\",\"Number\",\""; 1609 const char* c2 = "\""; 1610 1611 (void)strncat(command, c1, sizeof(command) - strlen(command) - 1); 1612 (void)strncat(command, gui_default_sip_number, sizeof(command) - strlen(command) - 1); 1613 (void)strncat(command, c2, sizeof(command) - strlen(command) - 1); 1614 1615 //strcat(command, "AT*EAID=8,1,\"Make a SIP call\",\"Number\",\""); 1616 //strcat(command, gui_default_sip_number); 1617 //strcat(command, "\""); 1618 send_atcmd(dev, command); 1619 } else if (menuitem == 2) { 1620 char command[1024] = ""; 1621 const char* c1 = "AT*EAID=11,1,\"Make a SIP call\",\"SIP Address\",100,\""; 1622 const char* c2 = "\""; 1623 1624 (void)strncat(command, c1, sizeof(command) - strlen(command) - 1); 1625 (void)strncat(command, gui_default_sip_address, sizeof(command) - strlen(command) - 1); 1626 (void)strncat(command, c2, sizeof(command) - strlen(command) - 1); 1627 1628 //strcat(command, "AT*EAID=11,1,\"Make a SIP call\",\"SIP Address\",100,\""); 1629 //strcat(command, gui_default_sip_address); 1630 //strcat(command, "\""); 1631 send_atcmd(dev, command); 1632 } else if (menuitem == 0) { 1633 dev->cb = gui_easm_response; 1634 // send_atcmd(dev,"AT*EASM=\"SIP Menu\",1,1,3,\"Call Number\",\"Call Address\",\"More Options\",1"); 1635 send_atcmd(dev,"AT*EASM=\"SIP Menu\",1,1,2,\"Call Number\",\"Call Address\",1"); 1636 } else { 1637 ast_log(LOG_ERROR, "Menu item not implementented.\n"); 1638 } 1639 return 0; 1640 } 1641 1642 static int 1643 atcmd_eaii_execute(blt_dev_t * dev, const char * data) 1644 { 1645 int pos = 1, len = 0; 1646 char type[128]; 1647 char val[128]; 1648 const char * start = data; 1649 struct sockaddr_in addr; 1650 1651 while (*data) { 1652 if (*data == ',') { 1653 memset(type, 0, 128); 1654 strncpy(type, start, len); 1655 1656 ast_log(LOG_NOTICE, "Number(8)/Address(11): '%s'.\n", type); 1657 1658 pos++; 1659 len = 0; 1660 data++; 1661 start = data; 1662 continue; 1663 } 1664 len++; 1665 data++; 1666 } 1667 1668 memset(val, 0, 128); 1669 strncpy(val, start, len); 1670 1671 char del[]= "\""; 1672 char* address; 1673 address = strtok(val, del); 1674 int type_int = atoi(type); 1675 1676 if (strcmp(address, " 0") == 0) { 1677 ast_log(LOG_NOTICE, "Spurious EAII:\n"); 1678 ast_log(LOG_NOTICE, data); 1679 return 0; 1680 } 1681 1682 if (type_int == 8) { 1683 (void)strncat(address, "@sipgate.de", sizeof(address) - strlen(address) - 1); 1684 } 1685 1686 ast_log(LOG_NOTICE, "SIP number/address: '%i','%s'.\n", type_int, address); 1687 1688 if (type_int == 8 || type_int == 11) { 1689 1690 char messagebox[1024] = ""; 1691 const char* mb1 = "AT*EAID=1,1,\"Setting up SIP call to "; 1692 const char* mb2 = "\",30"; 1693 1694 (void)strncat(messagebox, mb1, sizeof(messagebox) - strlen(messagebox) - 1); 1695 (void)strncat(messagebox, address, sizeof(messagebox) - strlen(messagebox) - 1); 1696 (void)strncat(messagebox, mb2, sizeof(messagebox) - strlen(messagebox) - 1); 1697 1698 //strcat(messagebox, "AT*EAID=1,1,\"Setting up SIP call to "); 1699 //strcat(messagebox, address); 1700 //strcat(messagebox, "\",30"); 1701 send_atcmd(dev, messagebox); 1702 1703 send_atcmd(dev, "AT*ESKS=2"); 1704 send_atcmd(dev, "AT*EKSP"); 1705 send_atcmd(dev, "AT*ESKS=0"); 1706 1707 //Create manager connection to create call 1708 int s = socket(AF_INET,SOCK_STREAM,0); 1709 if (s < 0) { 1710 ast_log(LOG_ERROR, "Manager connection failed."); 1711 1712 dev->cb = ag_cgmi_response; 1713 send_atcmd(dev, "AT*EAID=1,1,\"Call failed\""); 1714 return -1; 1715 } 1716 addr.sin_family = AF_INET; 1717 addr.sin_port = htons(5038); 1718 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 1719 memset(&(addr.sin_zero), '\0', 8); 1720 1721 if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 1722 ast_log(LOG_ERROR, "Manager connection failed. (2)"); 1723 dev->cb = ag_cgmi_response; 1724 send_atcmd(dev, "AT*EAID=1,1,\"Call failed\""); 1725 return -1; 1726 } 1727 char* command = "Action: login\r\nUsername: markus\r\nSecret: supAEr\r\n\r\n"; 1728 if (write(s,command,strlen(command)) < 0) { 1729 ast_log(LOG_ERROR, "Manager connection failed. (3)"); 1730 dev->cb = ag_cgmi_response; 1731 send_atcmd(dev, "AT*EAID=1,1,\"Call failed\""); 1732 return -1; 1733 } 1734 1735 char command3[1024] = ""; 1736 const char* action = "Action: Originate\r\nChannel: SIP/"; 1737 const char* action2 = "\r\nExten: 1235\r\nPriority: 1\r\nContext: sipgate.de\r\n\r\nAction: logoff\r\n\r\n"; 1738 1739 (void)strncat(command3, action, sizeof(command3) - strlen(command3) - 1); 1740 (void)strncat(command3, address, sizeof(command3) - strlen(command3) - 1); 1741 (void)strncat(command3, action2, sizeof(command3) - strlen(command3) - 1); 1742 1743 //strcat(command3, "Action: Originate\r\nChannel: SIP/"); 1744 //strcat(command3, address); 1745 //strcat(command3, "\r\nExten: 1235\r\nPriority: 1\r\nContext: sipgate.de\r\n\r\n"); 1746 ast_log(LOG_NOTICE, command3); 1747 1748 if (write(s,command3,strlen(command3)) < 0) { 1749 ast_log(LOG_ERROR, "Manager connection failed. (5)"); 1750 return -1; 1751 } 1752 } 1753 //dev->cb = ag_cgmi_response; 1754 return 0; 1755 } 1756 1757 /* Dial */ 1758 static int 1759 atcmd_dial_execute(blt_dev_t * dev, const char * data) 1760 { 1761 char * number = NULL; 1762 1763 /* Make sure there is a ';' at the end of the line */ 1764 if (*(data + (strlen(data) - 1)) != ';') { 1765 ast_log(LOG_WARNING, "Can't dial non-voice right now: %s\n", data); 1766 return -1; 1767 } 1768 1769 number = strndup(data, strlen(data) - 1); 1770 ast_log(LOG_NOTICE, "Dial: [%s]\n", number); 1771 1772 send_atcmd(dev, "+CIEV: 2,1"); 1773 send_atcmd(dev, "+CIEV: 3,0"); 1774 1775 sco_start(dev, -1); 1776 1777 if (blt_new(dev, AST_STATE_UP, dev->context, number) == NULL) { 1778 sco_stop(dev); 1779 } 1780 1781 free(number); 1782 1783 return 0; 1784 } 1785 1786 static int atcmd_bldn_execute(blt_dev_t * dev, const char *data) 1787 { 1788 return atcmd_dial_execute(dev, "bldn;"); 1789 } 1790 1791 /* Answer */ 1792 1793 static int 1794 atcmd_answer_execute(blt_dev_t * dev, const char * data) 1795 { 1796 1797 if (!dev->ringing || !dev->owner) { 1798 ast_log(LOG_WARNING, "Can't answer non existant call\n"); 1799 return -1; 1800 } 1801 1802 dev->ringing = 0; 1803 1804 if (dev->ring_timer >= 0) 1805 ast_sched_del(sched, dev->ring_timer); 1806 1807 dev->ring_timer = -1; 1808 1809 send_atcmd(dev, "+CIEV: 2,1"); 1810 send_atcmd(dev, "+CIEV: 3,0"); 1811 1812 return answer(dev); 1813 } 1814 1815 static int 1816 ag_unsol_ciev(blt_dev_t * dev, const char * data) 1817 { 1818 const char * orig = data; 1819 int indicator; 1820 int status; 1821 1822 while (*(data) && *(data) == ' ') 1823 data++; 1824 1825 if (*(data) == 0) { 1826 ast_log(LOG_WARNING, "Invalid value[1] for '+CIEV:%s'\n", orig); 1827 return -1; 1828 } 1829 1830 indicator = *(data++) - 48; 1831 1832 if (*(data++) != ',') { 1833 ast_log(LOG_WARNING, "Invalid value[2] for '+CIEV:%s'\n", orig); 1834 return -1; 1835 } 1836 1837 if (*(data) == 0) { 1838 ast_log(LOG_WARNING, "Invalid value[3] for '+CIEV:%s'\n", orig); 1839 return -1; 1840 } 1841 1842 status = *(data) - 48; 1843 1844 set_cind(dev, indicator, status); 1845 1846 return 0; 1847 } 1848 1849 static int 1850 ag_unsol_cind(blt_dev_t * dev, const char * data) 1851 { 1852 1853 while (*(data) && *(data) == ' ') 1854 data++; 1855 1856 1857 if (dev->cind == 0) 1858 { 1859 int pos = 1; 1860 char name[1024]; 1861 1862 while ((data = parse_cind(data, name, 1023)) != NULL) { 1863 ast_log(LOG_DEBUG, "CIND: %d=%s\n", pos, name); 1864 if (strcmp(name, "call") == 0) 1865 dev->call_pos = pos; 1866 else if (strcmp(name, "service") == 0) 1867 dev->service_pos = pos; 1868 else if (strcmp(name, "call_setup") == 0 || strcmp(name, "callsetup") == 0) 1869 dev->callsetup_pos = pos; 1870 pos++; 1871 } 1872 1873 ast_log(LOG_DEBUG, "CIND: %d=%s\n", pos, name); 1874 1875 } else { 1876 1877 int pos = 1, len = 0; 1878 char val[128]; 1879 const char * start = data; 1880 1881 while (*data) { 1882 if (*data == ',') { 1883 memset(val, 0, 128); 1884 strncpy(val, start, len); 1885 set_cind(dev, pos, atoi(val)); 1886 pos++; 1887 len = 0; 1888 data++; 1889 start = data; 1890 continue; 1891 } 1892 len++; 1893 data++; 1894 } 1895 1896 memset(val, 0, 128); 1897 strncpy(val, start, len); 1898 ast_log(LOG_DEBUG, "CIND IND %d set to %d [%s]\n", pos, atoi(val), val); 1899 1900 1901 } 1902 1903 return 0; 1904 } 1905 1906 /* 1907 * handle an incoming call 1908 */ 1909 static int 1910 ag_unsol_clip(blt_dev_t * dev, const char * data) 1911 { 1912 const char * orig = data; 1913 char name[256]; 1914 char number[64]; 1915 int type; 1916 1917 while (*(data) && *(data) == ' ') 1918 data++; 1919 1920 if (*(data) == 0) { 1921 ast_log(LOG_WARNING, "Invalid value[1] for '+CLIP:%s'\n", orig); 1922 return -1; 1923 } 1924 1925 parse_clip(data, number, sizeof(number)-1, name, sizeof(name)-1, &type); 1926 ast_log(LOG_NOTICE, "Parsed '+CLIP: %s' number='%s' type='%d' name='%s'\n", data, number, type, name); 1927 1928 blt_new(dev, AST_STATE_RING, dev->context, "s"); 1929 1930 return 0; 1931 } 1932 1933 1934 1935 static blt_atcb_t 1936 atcmd_list[] = 1937 { 1938 { "A", NULL, NULL, atcmd_answer_execute, NULL, NULL }, 1939 { "D", NULL, NULL, atcmd_dial_execute, NULL, NULL }, 1940 { "+BRSF", atcmd_brsf_set, NULL, NULL, NULL, NULL }, 1941 { "+BVRA", atcmd_bvra_set, NULL, NULL, NULL, NULL }, 1942 { "+CCLK", NULL, atcmd_cclk_read, NULL, NULL, NULL }, 1943 { "+CHUP", NULL, NULL, atcmd_chup_execute, NULL, NULL }, 1944 { "+CIEV", NULL, NULL, NULL, NULL, ag_unsol_ciev }, 1945 { "+CIND", NULL, atcmd_cind_read, NULL, atcmd_cind_test, ag_unsol_cind }, 1946 { "*EAMI", NULL, NULL, atcmd_eami_execute, NULL, NULL}, 1947 { "*EAII", NULL, NULL, atcmd_eaii_execute, NULL, NULL}, 1948 1949 { "+CLAN", NULL, atcmd_clan_read, NULL, NULL, NULL }, 1950 { "+CLIP", atcmd_clip_set, NULL, NULL, NULL, ag_unsol_clip }, 1951 { "+COLP", atcmd_colp_set, NULL, NULL, NULL, NULL }, 1952 { "+CMER", atcmd_cmer_set, NULL, NULL, NULL, NULL }, 1953 { "+CPBR", atcmd_cpbr_set, NULL, NULL, NULL, NULL }, 1954 { "+CPBS", atcmd_cpbs_set, NULL, NULL, NULL, NULL }, 1955 { "+CSCS", atcmd_cscs_set, NULL, NULL, NULL, NULL }, 1956 { "*EIPS", atcmd_eips_set, NULL, NULL, NULL, NULL }, 1957 { "+VGS", atcmd_vgs_set, NULL, NULL, NULL, NULL }, 1958 { "+BLDN", NULL, NULL, atcmd_bldn_execute, NULL, NULL }, 1959 }; 1960 1961 #define ATCMD_LIST_LEN (sizeof(atcmd_list) / sizeof(blt_atcb_t)) 1962 1963 /* ---------------------------------- */ 1964 1965 /* -- Handle negotiation when we're a HS -- */ 1966 1967 void 1968 ag_unknown_response(blt_dev_t * dev, char * cmd) 1969 { 1970 ast_log(LOG_DEBUG, "Got UNKN response: %s\n", cmd); 1971 1972 // DELAYED 1973 // NO CARRIER 1974 1975 } 1976 1977 void 1978 gui_easm_response(blt_dev_t * dev, char * cmd) 1979 { 1980 ast_log(LOG_NOTICE, "Menu displayed.\n"); 1981 } 1982 1983 void 1984 ag_cgmi_response(blt_dev_t * dev, char * cmd) 1985 { 1986 // CGMM - Phone Model 1987 // CGMR - Phone Revision 1988 // CGSN - IMEI 1989 // AT* 1990 // VTS - send tone 1991 // CREG 1992 // CBC - BATTERY 1993 // CSQ - SIGANL 1994 // CSMS - SMS STUFFS 1995 // CMGL 1996 // CMGR 1997 // CMGS 1998 // CSCA - sms CENTER NUMBER 1999 // CNMI - SMS INDICATION 2000 // ast_log(LOG_DEBUG, "Manufacturer: %s\n", cmd); 2001 2002 if (dev->role == BLT_ROLE_GUI) { 2003 ast_log(LOG_NOTICE, "Displaying Menu.\n"); 2004 dev->cb = gui_easm_response; 2005 // send_atcmd(dev,"AT*EASM=\"SIP Menu\",1,1,3,\"Call Number\",\"Call Address\",\"More Options\",1"); 2006 send_atcmd(dev,"AT*EASM=\"SIP Menu\",1,1,2,\"Call Number\",\"Call Address\",1"); 2007 } else { 2008 dev->cb = ag_unknown_response; 2009 } 2010 } 2011 2012 void 2013 ag_cgmi_valid_response(blt_dev_t * dev, char * cmd) 2014 { 2015 // send_atcmd(dev, "AT+WS46?"); 2016 // send_atcmd(dev, "AT+CRC=1"); 2017 // send_atcmd(dev, "AT+CNUM"); 2018 2019 if (strcmp(cmd, "OK") == 0) { 2020 send_atcmd(dev, "AT+CGMI"); 2021 dev->cb = ag_cgmi_response; 2022 } else { 2023 dev->cb = ag_unknown_response; 2024 } 2025 } 2026 2027 void 2028 ag_clip_response(blt_dev_t * dev, char * cmd) 2029 { 2030 send_atcmd(dev, "AT+CGMI=?"); 2031 dev->cb = ag_cgmi_valid_response; 2032 } 2033 2034 void 2035 ag_cmer_response(blt_dev_t * dev, char * cmd) 2036 { 2037 dev->cb = ag_clip_response; 2038 dev->ready = 1; 2039 dev->status = BLT_STATUS_READY; 2040 send_atcmd(dev, "AT+CLIP=1"); 2041 } 2042 2043 void 2044 ag_cind_status_response(blt_dev_t * dev, char * cmd) 2045 { 2046 // XXX:T: Handle response. 2047 dev->cb = ag_cmer_response; 2048 send_atcmd(dev, "AT+CMER=3,0,0,1"); 2049 // Initiliase SCO link! 2050 } 2051 2052 void 2053 ag_cind_response(blt_dev_t * dev, char * cmd) 2054 { 2055 dev->cb = ag_cind_status_response; 2056 dev->cind = 1; 2057 send_atcmd(dev, "AT+CIND?"); 2058 } 2059 2060 void 2061 ag_brsf_response(blt_dev_t * dev, char * cmd) 2062 { 2063 dev->cb = ag_cind_response; 2064 ast_log(LOG_DEBUG, "Bluetooth features: %s\n", cmd); 2065 dev->cind = 0; 2066 send_atcmd(dev, "AT+CIND=?"); 2067 } 2068 2069 /* ---------------------------------- */ 2070 2071 static int 2072 sdp_register(sdp_session_t * session) 2073 { 2074 // XXX:T: Fix this horrible function so it makes some sense and is extensible! 2075 sdp_list_t *svclass_id, *pfseq, *apseq, *root; 2076 uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; 2077 sdp_profile_desc_t profile; 2078 sdp_list_t *aproto, *proto[2]; 2079 sdp_record_t record; 2080 uint8_t u8 = rfcomm_channel_ag; 2081 uint8_t u8_hs = rfcomm_channel_hs; 2082 sdp_data_t *channel; 2083 int ret = 0; 2084 2085 memset((void *)&record, 0, sizeof(sdp_record_t)); 2086 record.handle = 0xffffffff; 2087 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 2088 root = sdp_list_append(0, &root_uuid); 2089 sdp_set_browse_groups(&record, root); 2090 2091 // Register as an AG 2092 2093 sdp_uuid16_create(&svclass_uuid, HANDSFREE_AUDIO_GW_SVCLASS_ID); 2094 svclass_id = sdp_list_append(0, &svclass_uuid); 2095 sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); 2096 svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); 2097 sdp_set_service_classes(&record, svclass_id); 2098 sdp_uuid16_create(&profile.uuid, 0x111f); 2099 profile.version = 0x0100; 2100 pfseq = sdp_list_append(0, &profile); 2101 2102 sdp_set_profile_descs(&record, pfseq); 2103 2104 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); 2105 proto[0] = sdp_list_append(0, &l2cap_uuid); 2106 apseq = sdp_list_append(0, proto[0]); 2107 2108 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); 2109 proto[1] = sdp_list_append(0, &rfcomm_uuid); 2110 channel = sdp_data_alloc(SDP_UINT8, &u8); 2111 proto[1] = sdp_list_append(proto[1], channel); 2112 apseq = sdp_list_append(apseq, proto[1]); 2113 2114 aproto = sdp_list_append(0, apseq); 2115 sdp_set_access_protos(&record, aproto); 2116 2117 sdp_set_info_attr(&record, "Voice Gateway", 0, 0); 2118 2119 if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { 2120 ast_log(LOG_ERROR, "Service Record registration failed\n"); 2121 ret = -1; 2122 goto end; 2123 } 2124 2125 sdp_record_ag = record.handle; 2126 sdp_record_gui = record.handle; 2127 2128 ast_log(LOG_NOTICE, "HeadsetAudioGateway service registered\n"); 2129 2130 sdp_data_free(channel); 2131 sdp_list_free(proto[0], 0); 2132 sdp_list_free(proto[1], 0); 2133 sdp_list_free(apseq, 0); 2134 sdp_list_free(aproto, 0); 2135 2136 // ------------- 2137 2138 memset((void *)&record, 0, sizeof(sdp_record_t)); 2139 record.handle = 0xffffffff; 2140 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 2141 root = sdp_list_append(0, &root_uuid); 2142 sdp_set_browse_groups(&record, root); 2143 2144 // Register as an HS 2145 2146 sdp_uuid16_create(&svclass_uuid, HANDSFREE_AUDIO_GW_SVCLASS_ID); 2147 svclass_id = sdp_list_append(0, &svclass_uuid); 2148 sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); 2149 svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); 2150 sdp_set_service_classes(&record, svclass_id); 2151 sdp_uuid16_create(&profile.uuid, 0x111e); 2152 profile.version = 0x0100; 2153 pfseq = sdp_list_append(0, &profile); 2154 sdp_set_profile_descs(&record, pfseq); 2155 2156 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); 2157 proto[0] = sdp_list_append(0, &l2cap_uuid); 2158 apseq = sdp_list_append(0, proto[0]); 2159 2160 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); 2161 proto[1] = sdp_list_append(0, &rfcomm_uuid); 2162 channel = sdp_data_alloc(SDP_UINT8, &u8_hs); 2163 proto[1] = sdp_list_append(proto[1], channel); 2164 apseq = sdp_list_append(apseq, proto[1]); 2165 2166 aproto = sdp_list_append(0, apseq); 2167 sdp_set_access_protos(&record, aproto); 2168 sdp_set_info_attr(&record, "Voice Gateway", 0, 0); 2169 2170 if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { 2171 ast_log(LOG_ERROR, "Service Record registration failed\n"); 2172 ret = -1; 2173 goto end; 2174 } 2175 2176 sdp_record_hs = record.handle; 2177 2178 ast_log(LOG_NOTICE, "HeadsetAudioGateway service registered\n"); 2179 2180 end: 2181 sdp_data_free(channel); 2182 sdp_list_free(proto[0], 0); 2183 sdp_list_free(proto[1], 0); 2184 sdp_list_free(apseq, 0); 2185 sdp_list_free(aproto, 0); 2186 2187 return ret; 2188 } 2189 2190 static int 2191 rfcomm_listen(bdaddr_t * bdaddr, int channel) 2192 { 2193 2194 int sock = -1; 2195 struct sockaddr_rc loc_addr; 2196 int on = 1; 2197 2198 if ((sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { 2199 ast_log(LOG_ERROR, "Can't create socket: %s (errno: %d)\n", strerror(errno), errno); 2200 return -1; 2201 } 2202 2203 loc_addr.rc_family = AF_BLUETOOTH; 2204 2205 /* Local Interface Address */ 2206 bacpy(&loc_addr.rc_bdaddr, bdaddr); 2207 2208 /* Channel */ 2209 loc_addr.rc_channel = channel; 2210 2211 if (bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) { 2212 ast_log(LOG_ERROR, "Can't bind socket: %s (errno: %d)\n", strerror(errno), errno); 2213 close(sock); 2214 return -1; 2215 } 2216 2217 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 2218 ast_log(LOG_ERROR, "Set socket SO_REUSEADDR option on failed: errno %d, %s", errno, strerror(errno)); 2219 close(sock); 2220 return -1; 2221 } 2222 2223 if (fcntl(sock, F_SETFL, O_RDWR|O_NONBLOCK) != 0) 2224 ast_log(LOG_ERROR, "Can't set RFCOMM socket to NBIO\n"); 2225 2226 if (listen(sock, 10) < 0) { 2227 ast_log(LOG_ERROR,"Can not listen on the socket. %s(%d)\n", strerror(errno), errno); 2228 close(sock); 2229 return -1; 2230 } 2231 2232 ast_log(LOG_NOTICE, "Listening for RFCOMM channel %d connections on FD %d\n", channel, sock); 2233 2234 return sock; 2235 } 2236 2237 2238 static int 2239 sco_listen(bdaddr_t * bdaddr) 2240 { 2241 int sock = -1; 2242 int on = 1; 2243 struct sockaddr_sco loc_addr; 2244 2245 memset(&loc_addr, 0, sizeof(loc_addr)); 2246 2247 if ((sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { 2248 ast_log(LOG_ERROR, "Can't create SCO socket: %s (errno: %d)\n", strerror(errno), errno); 2249 return -1; 2250 } 2251 2252 loc_addr.sco_family = AF_BLUETOOTH; 2253 bacpy(&loc_addr.sco_bdaddr, BDADDR_ANY); 2254 2255 if (bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) { 2256 ast_log(LOG_ERROR, "Can't bind SCO socket: %s (errno: %d)\n", strerror(errno), errno); 2257 close(sock); 2258 return -1; 2259 } 2260 2261 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { 2262 ast_log(LOG_ERROR, "Set SCO socket SO_REUSEADDR option on failed: errno %d, %s", errno, strerror(errno)); 2263 close(sock); 2264 return -1; 2265 } 2266 2267 if (fcntl(sock, F_SETFL, O_RDWR|O_NONBLOCK) != 0) 2268 ast_log(LOG_ERROR, "Can't set SCO socket to NBIO\n"); 2269 2270 if (listen(sock, 10) < 0) { 2271 ast_log(LOG_ERROR,"Can not listen on SCO socket: %s(%d)\n", strerror(errno), errno); 2272 close(sock); 2273 return -1; 2274 } 2275 2276 ast_log(LOG_NOTICE, "Listening for SCO connections on FD %d\n", sock); 2277 2278 return sock; 2279 } 2280 2281 static int 2282 rfcomm_connect(bdaddr_t * src, bdaddr_t * dst, int channel, int nbio) 2283 { 2284 struct sockaddr_rc addr; 2285 int s; 2286 2287 if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { 2288 return -1; 2289 } 2290 2291 memset(&addr, 0, sizeof(addr)); 2292 addr.rc_family = AF_BLUETOOTH; 2293 bacpy(&addr.rc_bdaddr, src); 2294 addr.rc_channel = 0; 2295 2296 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 2297 close(s); 2298 return -1; 2299 } 2300 2301 memset(&addr, 0, sizeof(addr)); 2302 addr.rc_family = AF_BLUETOOTH; 2303 bacpy(&addr.rc_bdaddr, dst); 2304 addr.rc_channel = channel; 2305 2306 if (nbio) { 2307 if (fcntl(s, F_SETFL, O_RDWR|O_NONBLOCK) != 0) 2308 ast_log(LOG_ERROR, "Can't set RFCOMM socket to NBIO\n"); 2309 } 2310 2311 if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 && (nbio != 1 || (errno != EAGAIN))) { 2312 close(s); 2313 return -1; 2314 } 2315 2316 return s; 2317 } 2318 2319 /* Must be called with dev->lock held */ 2320 2321 static int 2322 sco_connect(blt_dev_t * dev) 2323 { 2324 struct sockaddr_sco addr; 2325 // struct sco_conninfo conn; 2326 // struct sco_options opts; 2327 // int size; 2328 // bdaddr_t * src = &local_bdaddr; 2329 2330 int s; 2331 bdaddr_t * dst = &(dev->bdaddr); 2332 2333 if (dev->sco != -1) { 2334 ast_log(LOG_ERROR, "SCO fd already open.\n"); 2335 return -1; 2336 } 2337 2338 if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { 2339 ast_log(LOG_ERROR, "Can't create SCO socket(): %s\n", strerror(errno)); 2340 return -1; 2341 } 2342 2343 memset(&addr, 0, sizeof(addr)); 2344 2345 addr.sco_family = AF_BLUETOOTH; 2346 bacpy(&addr.sco_bdaddr, BDADDR_ANY); 2347 2348 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 2349 ast_log(LOG_ERROR, "Can't bind() SCO socket: %s\n", strerror(errno)); 2350 close(s); 2351 return -1; 2352 } 2353 2354 memset(&addr, 0, sizeof(addr)); 2355 addr.sco_family = AF_BLUETOOTH; 2356 bacpy(&addr.sco_bdaddr, dst); 2357 2358 if (fcntl(s, F_SETFL, O_RDWR|O_NONBLOCK) != 0) 2359 ast_log(LOG_ERROR, "Can't set SCO socket to NBIO\n"); 2360 2361 if ((connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) && (errno != EAGAIN)) { 2362 ast_log(LOG_ERROR, "Can't connect() SCO socket: %s (errno %d)\n", strerror(errno), errno); 2363 close(s); 2364 return -1; 2365 } 2366 2367 //size = sizeof(conn); 2368 2369 2370 /* XXX:T: HERE, fix getting SCO conninfo. 2371 2372 if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &size) < 0) { 2373 ast_log(LOG_ERROR, "Can't getsockopt SCO_CONNINFO on SCO socket: %s\n", strerror(errno)); 2374 close(s); 2375 return -1; 2376 } 2377 2378 size = sizeof(opts); 2379 2380 if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &opts, &size) < 0) { 2381 ast_log(LOG_ERROR, "Can't getsockopt SCO_OPTIONS on SCO socket: %s\n", strerror(errno)); 2382 close(s); 2383 return -1; 2384 } 2385 2386 dev->sco_handle = conn.hci_handle; 2387 dev->sco_mtu = opts.mtu; 2388 2389 */ 2390 2391 ast_log(LOG_DEBUG, "SCO: %d\n", s); 2392 2393 dev->sco = s; 2394 2395 return 0; 2396 } 2397 2398 2399 /* ---------------------------------- */ 2400 2401 /* Non blocking (async) outgoing bluetooth connection */ 2402 2403 static int 2404 try_connect(blt_dev_t * dev) 2405 { 2406 int fd; 2407 ast_mutex_lock(&(dev->lock)); 2408 2409 if (dev->status != BLT_STATUS_CONNECTING && dev->status != BLT_STATUS_DOWN) { 2410 ast_mutex_unlock(&(dev->lock)); 2411 return 0; 2412 } 2413 2414 if (dev->rd != -1) { 2415 2416 int ret; 2417 struct pollfd pfd; 2418 2419 if (dev->status != BLT_STATUS_CONNECTING) { 2420 ast_mutex_unlock(&(dev->lock)); 2421 dev->outgoing_id = -1; 2422 return 0; 2423 } 2424 2425 // ret = connect(dev->rd, (struct sockaddr *)&(dev->addr), sizeof(struct sockaddr_rc)); // 2426 2427 pfd.fd = dev->rd; 2428 pfd.events = POLLIN | POLLOUT; 2429 2430 ret = poll(&pfd, 1, 0); 2431 2432 if (ret == -1) { 2433 close(dev->rd); 2434 dev->rd = -1; 2435 dev->status = BLT_STATUS_DOWN; 2436 dev->outgoing_id = ast_sched_add(sched, 10000, AST_SCHED_CB(try_connect), dev); 2437 ast_mutex_unlock(&(dev->lock)); 2438 return 0; 2439 } 2440 2441 if (ret > 0) { 2442 2443 int len = sizeof(ret); 2444 getsockopt(dev->rd, SOL_SOCKET, SO_ERROR, &ret, &len); 2445 2446 if (ret == 0) { 2447 2448 ast_log(LOG_NOTICE, "Initialised bluetooth link to device %s\n", dev->name); 2449 2450 #if 0 2451 { 2452 struct hci_conn_info_req * cr; 2453 int dd; 2454 char name[248]; 2455 2456 cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); 2457 dd = hci_open_dev(hcidev_id); 2458 cr->type = ACL_LINK; 2459 bacpy(&cr->bdaddr, &(dev->bdaddr)); 2460 2461 if (ioctl(dd, HCIGETCONNINFO, (unsigned long)cr) < 0) { 2462 ast_log(LOG_ERROR, "Failed to get connection info: %s\n", strerror(errno)); 2463 } else { 2464 ast_log(LOG_DEBUG, "HCI Handle: %d\n", cr->conn_info->handle); 2465 } 2466 2467 if (hci_read_remote_name(dd, &(dev->bdaddr), sizeof(name), name, 25000) == 0) 2468 ast_log(LOG_DEBUG, "Remote Name: %s\n", name); 2469 free(cr); 2470 } 2471 #endif 2472 2473 dev->status = BLT_STATUS_NEGOTIATING; 2474 2475 /* If this device is an AG/GUI, we initiate the negotiation. */ 2476 2477 if (dev->role == BLT_ROLE_AG || 2478 dev->role == BLT_ROLE_GUI) { 2479 dev->cb = ag_brsf_response; 2480 send_atcmd(dev, "AT+BRSF=23"); 2481 } 2482 2483 dev->outgoing_id = -1; 2484 ast_mutex_unlock(&(dev->lock)); 2485 return 0; 2486 2487 } else { 2488 2489 if (ret != EHOSTDOWN) 2490 ast_log(LOG_NOTICE, "Connect to device %s failed: %s (errno %d)\n", dev->name, strerror(ret), ret); 2491 2492 close(dev->rd); 2493 dev->rd = -1; 2494 dev->status = BLT_STATUS_DOWN; 2495 dev->outgoing_id = ast_sched_add(sched, (ret == EHOSTDOWN) ? 10000 : 2500, AST_SCHED_CB(try_connect), dev); 2496 ast_mutex_unlock(&(dev->lock)); 2497 return 0; 2498 2499 } 2500 2501 } 2502 2503 dev->outgoing_id = ast_sched_add(sched, 100, AST_SCHED_CB(try_connect), dev); 2504 ast_mutex_unlock(&(dev->lock)); 2505 return 0; 2506 } 2507 2508 ast_log(LOG_NOTICE, "RFCOMM connect start.\n"); 2509 fd = rfcomm_connect(&local_bdaddr, &(dev->bdaddr), dev->channel, 1); 2510 ast_log(LOG_NOTICE, "RFCOMM connect done.\n"); 2511 2512 if (fd == -1) { 2513 ast_log(LOG_WARNING, "NBIO connect() to %s returned %d: %s\n", dev->name, errno, strerror(errno)); 2514 dev->outgoing_id = ast_sched_add(sched, 5000, AST_SCHED_CB(try_connect), dev); 2515 ast_mutex_unlock(&(dev->lock)); 2516 return 0; 2517 } 2518 2519 dev->rd = fd; 2520 dev->status = BLT_STATUS_CONNECTING; 2521 dev->outgoing_id = ast_sched_add(sched, 100, AST_SCHED_CB(try_connect), dev); 2522 ast_mutex_unlock(&(dev->lock)); 2523 return 0; 2524 } 2525 2526 2527 /* Called whenever a new command is received while we're the AG */ 2528 2529 2530 static int 2531 process_rfcomm_cmd(blt_dev_t * dev, char * cmd) 2532 { 2533 int i; 2534 char * fullcmd = cmd; 2535 2536 if (option_verbose) 2537 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, cmd); 2538 2539 /* Read the 'AT' from the start of the string */ 2540 if (strncmp(cmd, "AT", 2)) { 2541 ast_log(LOG_WARNING, "Unknown command without 'AT': %s\n", cmd); 2542 send_atcmd_error(dev); 2543 return 0; 2544 } 2545 2546 cmd += 2; 2547 2548 // Don't forget 'AT' on its own is OK. 2549 2550 if (strlen(cmd) == 0) { 2551 send_atcmd_ok(dev, fullcmd); 2552 return 0; 2553 } 2554 2555 for (i = 0 ; i < ATCMD_LIST_LEN ; i++) { 2556 if (strncmp(atcmd_list[i].str, cmd, strlen(atcmd_list[i].str)) == 0) { 2557 char * pos = (cmd + strlen(atcmd_list[i].str)); 2558 if ((strncmp(pos, "=?", 2) == 0) && (strlen(pos) == 2)) { 2559 /* TEST command */ 2560 if (atcmd_list[i].test) { 2561 if (atcmd_list[i].test(dev) == 0) 2562 send_atcmd_ok(dev, fullcmd); 2563 else 2564 send_atcmd_error(dev); 2565 } else { 2566 send_atcmd_ok(dev, fullcmd); 2567 } 2568 } else if ((strncmp(pos, "?", 1) == 0) && (strlen(pos) == 1)) { 2569 /* READ command */ 2570 if (atcmd_list[i].read) { 2571 if (atcmd_list[i].read(dev) == 0) 2572 send_atcmd_ok(dev, fullcmd); 2573 else 2574 send_atcmd_error(dev); 2575 } else { 2576 ast_log(LOG_WARNING, "AT Command: '%s' missing READ function\n", fullcmd); 2577 send_atcmd_error(dev); 2578 } 2579 } else if (strncmp(pos, "=", 1) == 0) { 2580 /* SET command */ 2581 if (atcmd_list[i].set) { 2582 if (atcmd_list[i].set(dev, (pos + 1), (*(pos + 1)) ? strlen(pos + 1) : 0) == 0) 2583 send_atcmd_ok(dev, fullcmd); 2584 else 2585 send_atcmd_error(dev); 2586 } else { 2587 ast_log(LOG_WARNING, "AT Command: '%s' missing SET function\n", fullcmd); 2588 send_atcmd_error(dev); 2589 } 2590 } else { 2591 /* EXECUTE command */ 2592 if (atcmd_list[i].execute) { 2593 if (atcmd_list[i].execute(dev, cmd + strlen(atcmd_list[i].str)) == 0) 2594 send_atcmd_ok(dev, fullcmd); 2595 else 2596 send_atcmd_error(dev); 2597 } else { 2598 ast_log(LOG_WARNING, "AT Command: '%s' missing EXECUTE function\n", fullcmd); 2599 send_atcmd_error(dev); 2600 } 2601 } 2602 return 0; 2603 } 2604 } 2605 2606 ast_log(LOG_NOTICE, "Unknown AT Command: '%s' (%s)\n", fullcmd, cmd); 2607 send_atcmd_error(dev); 2608 2609 return 0; 2610 } 2611 2612 /* Called when a socket is incoming */ 2613 2614 static void 2615 handle_incoming(int fd, blt_role_t role) 2616 { 2617 blt_dev_t * dev; 2618 struct sockaddr_rc addr; 2619 int len = sizeof(addr); 2620 2621 // Got a new incoming socket. 2622 ast_log(LOG_DEBUG, "Incoming RFCOMM socket\n"); 2623 2624 ast_mutex_lock(&iface_lock); 2625 2626 fd = accept(fd, (struct sockaddr*)&addr, &len); 2627 2628 dev = iface_head; 2629 while (dev) { 2630 if (bacmp(&(dev->bdaddr), &addr.rc_bdaddr) == 0) { 2631 ast_log(LOG_DEBUG, "Connect from %s\n", dev->name); 2632 ast_mutex_lock(&(dev->lock)); 2633 /* Kill any outstanding connect attempt. */ 2634 if (dev->outgoing_id > -1) { 2635 ast_sched_del(sched, dev->outgoing_id); 2636 dev->outgoing_id = -1; 2637 } 2638 2639 rd_close(dev, 0, 0); 2640 2641 dev->status = BLT_STATUS_NEGOTIATING; 2642 dev->rd = fd; 2643 2644 if (dev->role == BLT_ROLE_AG || 2645 dev->role == BLT_ROLE_GUI) { 2646 dev->cb = ag_brsf_response; 2647 send_atcmd(dev, "AT+BRSF=23"); 2648 } 2649 ast_mutex_unlock(&(dev->lock)); 2650 break; 2651 } 2652 dev = dev->next; 2653 } 2654 2655 if (dev == NULL) { 2656 ast_log(LOG_WARNING, "Connect from unknown device\n"); 2657 close(fd); 2658 } 2659 ast_mutex_unlock(&iface_lock); 2660 2661 return; 2662 } 2663 2664 static void 2665 handle_incoming_sco(int master) 2666 { 2667 2668 blt_dev_t * dev; 2669 struct sockaddr_sco addr; 2670 struct sco_conninfo conn; 2671 struct sco_options opts; 2672 int len = sizeof(addr); 2673 int fd; 2674 2675 ast_log(LOG_DEBUG, "Incoming SCO socket\n"); 2676 2677 fd = accept(master, (struct sockaddr*)&addr, &len); 2678 2679 if (fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK) != 0) { 2680 ast_log(LOG_ERROR, "Can't set SCO socket to NBIO\n"); 2681 close(fd); 2682 return; 2683 } 2684 2685 len = sizeof(conn); 2686 2687 if (getsockopt(fd, SOL_SCO, SCO_CONNINFO, &conn, &len) < 0) { 2688 ast_log(LOG_ERROR, "Can't getsockopt SCO_CONNINFO on SCO socket: %s\n", strerror(errno)); 2689 close(fd); 2690 return; 2691 } 2692 2693 len = sizeof(opts); 2694 2695 if (getsockopt(fd, SOL_SCO, SCO_OPTIONS, &opts, &len) < 0) { 2696 ast_log(LOG_ERROR, "Can't getsockopt SCO_OPTIONS on SCO socket: %s\n", strerror(errno)); 2697 close(fd); 2698 return; 2699 } 2700 2701 ast_mutex_lock(&iface_lock); 2702 dev = iface_head; 2703 while (dev) { 2704 if (bacmp(&(dev->bdaddr), &addr.sco_bdaddr) == 0) { 2705 ast_log(LOG_DEBUG, "SCO Connect from %s\n", dev->name); 2706 ast_mutex_lock(&(dev->lock)); 2707 if (dev->sco_running != -1) { 2708 ast_log(LOG_ERROR, "Incoming SCO socket, but SCO thread already running.\n"); 2709 } else { 2710 sco_start(dev, fd); 2711 } 2712 ast_mutex_unlock(&(dev->lock)); 2713 break; 2714 } 2715 dev = dev->next; 2716 } 2717 2718 ast_mutex_unlock(&iface_lock); 2719 2720 if (dev == NULL) { 2721 ast_log(LOG_WARNING, "SCO Connect from unknown device\n"); 2722 close(fd); 2723 } else { 2724 // XXX:T: We need to handle the fact we might have an outgoing connection attempt in progress. 2725 ast_log(LOG_DEBUG, "SCO: %d, HCIHandle=%d, MUT=%d\n", fd, conn.hci_handle, opts.mtu); 2726 } 2727 2728 2729 2730 return; 2731 } 2732 2733 /* Called when there is data waiting on a socket */ 2734 2735 static int 2736 handle_rd_data(blt_dev_t * dev) 2737 { 2738 char c; 2739 int ret; 2740 2741 while ((ret = read(dev->rd, &c, 1)) == 1) { 2742 2743 // log_buf[i++] = c; 2744 2745 if (dev->role == BLT_ROLE_HS) { 2746 2747 if (c == '\r') { 2748 ret = process_rfcomm_cmd(dev, dev->rd_buff); 2749 dev->rd_buff_pos = 0; 2750 memset(dev->rd_buff, 0, BLT_RDBUFF_MAX); 2751 return ret; 2752 } 2753 2754 if (dev->rd_buff_pos >= BLT_RDBUFF_MAX) 2755 return 0; 2756 2757 dev->rd_buff[dev->rd_buff_pos++] = c; 2758 2759 } else if (dev->role == BLT_ROLE_AG || 2760 dev->role == BLT_ROLE_GUI) { 2761 2762 //ast_log(LOG_ERROR, "%s: %c\n", dev->name, c); 2763 2764 switch (dev->state) { 2765 case BLT_STATE_WANT_R: 2766 if (c == '\r' || c == 10) { 2767 dev->state = BLT_STATE_WANT_N; 2768 } else if (c == '+') { 2769 dev->state = BLT_STATE_WANT_CMD; 2770 dev->rd_buff[dev->rd_buff_pos++] = '+'; 2771 } else { 2772 ast_log(LOG_ERROR, "Device %s: Expected '\\r', got %d. state=BLT_STATE_WANT_R\n", dev->name, c); 2773 return -1; 2774 } 2775 break; 2776 2777 case BLT_STATE_WANT_N: 2778 if (c == '\n' || c == 13) 2779 dev->state = BLT_STATE_WANT_CMD; 2780 else { 2781 ast_log(LOG_ERROR, "Device %s: Expected '\\n', got %d. state=BLT_STATE_WANT_N\n", dev->name, c); 2782 return -1; 2783 } 2784 break; 2785 2786 case BLT_STATE_WANT_CMD: 2787 if (c == '\r' || c == 10) 2788 dev->state = BLT_STATE_WANT_N2; 2789 else { 2790 if (dev->rd_buff_pos >= BLT_RDBUFF_MAX) { 2791 ast_log(LOG_ERROR, "Device %s: Buffer exceeded\n", dev->name); 2792 return -1; 2793 } 2794 dev->rd_buff[dev->rd_buff_pos++] = c; 2795 } 2796 break; 2797 2798 case BLT_STATE_WANT_N2: 2799 if (c == '\n' || c == 13) { 2800 2801 dev->state = BLT_STATE_WANT_R; 2802 2803 if (dev->rd_buff[0] == '+') { 2804 int i; 2805 // find unsolicited 2806 for (i = 0 ; i < ATCMD_LIST_LEN ; i++) { 2807 if (strncmp(atcmd_list[i].str, dev->rd_buff, strlen(atcmd_list[i].str)) == 0) { 2808 if (atcmd_list[i].unsolicited) 2809 atcmd_list[i].unsolicited(dev, dev->rd_buff + strlen(atcmd_list[i].str) + 1); 2810 else 2811 ast_log(LOG_WARNING, "Device %s: Unhandled Unsolicited: %s\n", dev->name, dev->rd_buff); 2812 break; 2813 } 2814 } 2815 2816 if (option_verbose) 2817 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, dev->rd_buff); 2818 2819 if (i == ATCMD_LIST_LEN) 2820 ast_log(LOG_NOTICE, "Device %s: Got unsolicited message: %s\n", dev->name, dev->rd_buff); 2821 2822 } else if (dev->rd_buff[0] == '*') { 2823 if (option_verbose) 2824 ast_verbose(VERBOSE_PREFIX_1 "[%s]* %*s > %s\n", role2str(dev->role), 9, dev->name, dev->rd_buff); 2825 2826 int i; 2827 // find execute 2828 for (i = 0 ; i < ATCMD_LIST_LEN ; i++) { 2829 if (strncmp(atcmd_list[i].str, dev->rd_buff, strlen(atcmd_list[i].str)) == 0) { 2830 if (atcmd_list[i].execute) 2831 atcmd_list[i].execute(dev, dev->rd_buff + strlen(atcmd_list[i].str) + 1); 2832 else 2833 ast_log(LOG_ERROR, "Device %s: Unhandled Execute: %s\n", dev->name, dev->rd_buff); 2834 break; 2835 } 2836 } 2837 2838 2839 } else { 2840 2841 if ( 2842 strcmp(dev->rd_buff, "OK") != 0 && 2843 strcmp(dev->rd_buff, "CONNECT") != 0 && 2844 strcmp(dev->rd_buff, "RING") != 0 && 2845 strcmp(dev->rd_buff, "NO CARRIER") != 0 && 2846 strcmp(dev->rd_buff, "ERROR") != 0 && 2847 strcmp(dev->rd_buff, "NO DIALTONE") != 0 && 2848 strcmp(dev->rd_buff, "BUSY") != 0 && 2849 strcmp(dev->rd_buff, "NO ANSWER") != 0 && 2850 strcmp(dev->rd_buff, "DELAYED") != 0 2851 ){ 2852 // It must be a multiline error 2853 strncpy(dev->last_err_cmd, dev->rd_buff, 1023); 2854 if (option_verbose) 2855 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, dev->rd_buff); 2856 } else if (dev->cb) { 2857 if (option_verbose) 2858 ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, dev->rd_buff); 2859 dev->cb(dev, dev->rd_buff); 2860 } else { 2861 ast_log(LOG_ERROR, "Device %s: Data on socket in HS mode, but no callback\n", dev->name); 2862 } 2863 2864 } 2865 2866 dev->rd_buff_pos = 0; 2867 memset(dev->rd_buff, 0, BLT_RDBUFF_MAX); 2868 } else { 2869 2870 ast_log(LOG_ERROR, "Device %s: Expected '\\n' got %d. state = BLT_STATE_WANT_N2:\n", dev->name, c); 2871 return -1; 2872 2873 } 2874 2875 break; 2876 2877 default: 2878 ast_log(LOG_ERROR, "Device %s: Unknown device state %d\n", dev->name, dev->state); 2879 return -1; 2880 2881 } 2882 2883 } 2884 2885 } 2886 2887 return 0; 2888 } 2889 2890 /* Close the devices RFCOMM socket, and SCO if it exists. Must hold dev->lock */ 2891 2892 static void 2893 rd_close(blt_dev_t * dev, int reconnect, int e) 2894 { 2895 dev->ready = 0; 2896 2897 if (dev->rd) 2898 close(dev->rd); 2899 2900 dev->rd = -1; 2901 2902 dev->status = BLT_STATUS_DOWN; 2903 2904 sco_stop(dev); 2905 2906 if (dev->owner) { 2907 ast_setstate(dev->owner, AST_STATE_DOWN); 2908 ast_queue_control(dev->owner, AST_CONTROL_HANGUP); 2909 } 2910 2911 /* Schedule a reconnect */ 2912 if (reconnect && dev->autoconnect) { 2913 dev->outgoing_id = ast_sched_add(sched, 5000, AST_SCHED_CB(try_connect), dev); 2914 2915 if (monitor_thread == pthread_self()) { 2916 // Because we're not the monitor thread, we needd to inturrupt poll(). 2917 pthread_kill(monitor_thread, SIGURG); 2918 } 2919 2920 if (e) 2921 ast_log(LOG_NOTICE, "Device %s disconnected, scheduled reconnect in 5 seconds: %s (errno %d)\n", dev->name, strerror(e), e); 2922 } else if (e) { 2923 ast_log(LOG_NOTICE, "Device %s disconnected: %s (errno %d)\n", dev->name, strerror(e), e); 2924 } 2925 2926 return; 2927 } 2928 2929 /* 2930 * Remember that we can only add to the scheduler from 2931 * the do_monitor thread, as it calculates time to next one from 2932 * this loop. 2933 */ 2934 2935 static void * 2936 do_monitor(void * data) 2937 { 2938 #define SRV_SOCK_CNT 4 2939 2940 int res = 0; 2941 blt_dev_t * dev; 2942 struct pollfd * pfds = malloc(sizeof(struct pollfd) * (ifcount + SRV_SOCK_CNT)); 2943 2944 /* -- We start off by trying to connect all of our devices (non blocking) -- */ 2945 2946 monitor_pid = getpid(); 2947 2948 if (ast_mutex_lock(&iface_lock)) { 2949 ast_log(LOG_ERROR, "Failed to get iface_lock.\n"); 2950 return NULL; 2951 } 2952 2953 dev = iface_head; 2954 while (dev) { 2955 2956 if (socketpair(PF_UNIX, SOCK_STREAM, 0, dev->sco_pipe) != 0) { 2957 ast_log(LOG_ERROR, "Failed to create socket pair: %s (errno %d)\n", strerror(errno), errno); 2958 ast_mutex_unlock(&iface_lock); 2959 return NULL; 2960 } 2961 2962 if (dev->autoconnect && dev->status == BLT_STATUS_DOWN) 2963 dev->outgoing_id = ast_sched_add(sched, 1500, AST_SCHED_CB(try_connect), dev); 2964 dev = dev->next; 2965 } 2966 ast_mutex_unlock(&iface_lock); 2967 2968 /* -- Now, Scan all sockets, and service scheduler -- */ 2969 2970 pfds[0].fd = rfcomm_sock_ag; 2971 pfds[0].events = POLLIN; 2972 2973 pfds[1].fd = rfcomm_sock_hs; 2974 pfds[1].events = POLLIN; 2975 2976 pfds[2].fd = rfcomm_sock_gui; 2977 pfds[2].events = POLLIN; 2978 2979 pfds[3].fd = sco_socket; 2980 pfds[3].events = POLLIN; 2981 2982 while (1) { 2983 int cnt = SRV_SOCK_CNT; 2984 int i; 2985 2986 /* -- Build pfds -- */ 2987 2988 if (ast_mutex_lock(&iface_lock)) { 2989 ast_log(LOG_ERROR, "Failed to get iface_lock.\n"); 2990 return NULL; 2991 } 2992 dev = iface_head; 2993 while (dev) { 2994 ast_mutex_lock(&(dev->lock)); 2995 if (dev->rd > 0 && ((dev->status != BLT_STATUS_DOWN) && (dev->status != BLT_STATUS_CONNECTING))) { 2996 pfds[cnt].fd = dev->rd; 2997 pfds[cnt].events = POLLIN; 2998 cnt++; 2999 } 3000 ast_mutex_unlock(&(dev->lock)); 3001 dev = dev->next; 3002 } 3003 ast_mutex_unlock(&iface_lock); 3004 3005 /* -- End Build pfds -- */ 3006 3007 res = ast_sched_wait(sched); 3008 res = poll(pfds, cnt, MAX(100, MIN(100, res))); 3009 3010 if (res == 0) 3011 ast_sched_runq(sched); 3012 3013 if (pfds[0].revents) { 3014 handle_incoming(rfcomm_sock_ag, BLT_ROLE_AG); 3015 res--; 3016 } 3017 3018 if (pfds[1].revents) { 3019 handle_incoming(rfcomm_sock_hs, BLT_ROLE_HS); 3020 res--; 3021 } 3022 3023 if (pfds[2].revents) { 3024 handle_incoming(rfcomm_sock_gui, BLT_ROLE_GUI); 3025 res--; 3026 } 3027 3028 if (pfds[3].revents) { 3029 handle_incoming_sco(sco_socket); 3030 res--; 3031 } 3032 3033 if (res == 0) 3034 continue; 3035 3036 for (i = SRV_SOCK_CNT ; i < cnt ; i++) { 3037 3038 /* Optimise a little bit */ 3039 if (res == 0) 3040 break; 3041 else if (pfds[i].revents == 0) 3042 continue; 3043 3044 /* -- Find the socket that has activity -- */ 3045 3046 if (ast_mutex_lock(&iface_lock)) { 3047 ast_log(LOG_ERROR, "Failed to get iface_lock.\n"); 3048 return NULL; 3049 } 3050 3051 dev = iface_head; 3052 3053 while (dev) { 3054 if (pfds[i].fd == dev->rd) { 3055 ast_mutex_lock(&(dev->lock)); 3056 if (pfds[i].revents & POLLIN) { 3057 if (handle_rd_data(dev) == -1) { 3058 rd_close(dev, 0, 0); 3059 } 3060 } else { 3061 rd_close(dev, 1, sock_err(dev->rd)); 3062 } 3063 ast_mutex_unlock(&(dev->lock)); 3064 res--; 3065 break; 3066 } 3067 dev = dev->next; 3068 } 3069 3070 if (dev == NULL) { 3071 ast_log(LOG_ERROR, "Unhandled fd from poll()\n"); 3072 close(pfds[i].fd); 3073 } 3074 3075 ast_mutex_unlock(&iface_lock); 3076 3077 /* -- End find socket with activity -- */ 3078 3079 } 3080 3081 } 3082 3083 return NULL; 3084 } 3085 3086 static int 3087 restart_monitor(void) 3088 { 3089 3090 if (monitor_thread == AST_PTHREADT_STOP) 3091 return 0; 3092 3093 if (ast_mutex_lock(&monitor_lock)) { 3094 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 3095 return -1; 3096 } 3097 3098 if (monitor_thread == pthread_self()) { 3099 ast_mutex_unlock(&monitor_lock); 3100 ast_log(LOG_WARNING, "Cannot kill myself\n"); 3101 return -1; 3102 } 3103 3104 if (monitor_thread != AST_PTHREADT_NULL) { 3105 3106 /* Just signal it to be sure it wakes up */ 3107 pthread_cancel(monitor_thread); 3108 pthread_kill(monitor_thread, SIGURG); 3109 ast_log(LOG_DEBUG, "Waiting for monitor thread to join...\n"); 3110 pthread_join(monitor_thread, NULL); 3111 ast_log(LOG_DEBUG, "joined\n"); 3112 3113 } else { 3114 3115 /* Start a new monitor */ 3116 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 3117 ast_mutex_unlock(&monitor_lock); 3118 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 3119 return -1; 3120 } 3121 3122 } 3123 3124 ast_mutex_unlock(&monitor_lock); 3125 return 0; 3126 } 3127 3128 static int 3129 blt_parse_config(void) 3130 { 3131 struct ast_config * cfg; 3132 struct ast_variable * v; 3133 char * cat; 3134 3135 cfg = ast_load(BLT_CONFIG_FILE); 3136 3137 if (!cfg) { 3138 ast_log(LOG_NOTICE, "Unable to load Bluetooth config: %s. Bluetooth disabled\n", BLT_CONFIG_FILE); 3139 return -1; 3140 } 3141 3142 v = ast_variable_browse(cfg, "general"); 3143 3144 while (v) { 3145 if (!strcasecmp(v->name, "rfchannel_ag")) { 3146 rfcomm_channel_ag = atoi(v->value); 3147 } else if (!strcasecmp(v->name, "rfchannel_hs")) { 3148 rfcomm_channel_hs = atoi(v->value); 3149 } else if (!strcasecmp(v->name, "rfchannel_gui")) { 3150 rfcomm_channel_gui = atoi(v->value); 3151 } else if (!strcasecmp(v->name, "interface")) { 3152 hcidev_id = atoi(v->value); 3153 } else if (!strcasecmp(v->name, "gui_default_sip_number")) { 3154 gui_default_sip_number = v->value; 3155 } else if (!strcasecmp(v->name, "gui_default_sip_address")) { 3156 gui_default_sip_address = v->value; 3157 } else { 3158 ast_log(LOG_WARNING, "Unknown config key '%s' in section [general]\n", v->name); 3159 } 3160 v = v->next; 3161 } 3162 cat = ast_category_browse(cfg, NULL); 3163 3164 while(cat) { 3165 3166 char * str; 3167 3168 if (strcasecmp(cat, "general")) { 3169 blt_dev_t * device = malloc(sizeof(blt_dev_t)); 3170 memset(device, 0, sizeof(blt_dev_t)); 3171 device->sco_running = -1; 3172 device->sco = -1; 3173 device->rd = -1; 3174 device->outgoing_id = -1; 3175 device->status = BLT_STATUS_DOWN; 3176 str2ba(cat, &(device->bdaddr)); 3177 device->name = ast_variable_retrieve(cfg, cat, "name"); 3178 3179 str = ast_variable_retrieve(cfg, cat, "type"); 3180 3181 if (str == NULL) { 3182 ast_log(LOG_ERROR, "Device [%s] has no role. Specify type=<HS/AG>\n", cat); 3183 return -1; 3184 } else if (strcasecmp(str, "HS") == 0) { 3185 device->role = BLT_ROLE_HS; 3186 } else if (strcasecmp(str, "AG") == 0) { 3187 device->role = BLT_ROLE_AG; 3188 } else if (strcasecmp(str, "GUI") == 0) { 3189 device->role = BLT_ROLE_GUI; 3190 } else { 3191 ast_log(LOG_ERROR, "Device [%s] has invalid role '%s'\n", cat, str); 3192 return -1; 3193 } 3194 3195 /* XXX:T: Find channel to use using SDP. 3196 * However, this needs to be non blocking, and I can't see 3197 * anything in sdp_lib.h that will allow non blocking calls. 3198 */ 3199 3200 device->channel = 1; 3201 3202 if ((str = ast_variable_retrieve(cfg, cat, "channel")) != NULL) 3203 device->channel = atoi(str); 3204 3205 if ((str = ast_variable_retrieve(cfg, cat, "autoconnect")) != NULL) 3206 device->autoconnect = (strcasecmp(str, "yes") == 0 || strcmp(str, "1") == 0) ? 1 : 0; 3207 3208 if ((str = ast_variable_retrieve(cfg, cat, "context")) != NULL) 3209 device->context = str; 3210 else 3211 device->context = "bluetooth"; 3212 3213 device->next = iface_head; 3214 iface_head = device; 3215 ifcount++; 3216 } 3217 3218 cat = ast_category_browse(cfg, cat); 3219 } 3220 return 0; 3221 } 3222 3223 3224 static int 3225 blt_show_peers(int fd, int argc, char *argv[]) 3226 { 3227 blt_dev_t * dev; 3228 3229 if (ast_mutex_lock(&iface_lock)) { 3230 ast_log(LOG_ERROR, "Failed to get Iface lock\n"); 3231 ast_cli(fd, "Failed to get iface lock\n"); 3232 return RESULT_FAILURE; 3233 } 3234 3235 dev = iface_head; 3236 3237 ast_cli(fd, "BDAddr Name Role Status A/C SCOCon/Fd/Th Sig\n"); 3238 ast_cli(fd, "----------------- ---------- ---- ----------- --- ------------ ---\n"); 3239 3240 while (dev) { 3241 char b1[18]; 3242 ba2str(&(dev->bdaddr), b1); 3243 ast_cli(fd, "%s %-10s %-4s %-11s %-3s %2d/%02d/%-6ld %s\n", 3244 b1, dev->name, 3245 // (dev->role == BLT_ROLE_HS) ? "HS" : "AG", 3246 (dev->role == BLT_ROLE_HS) ? "HS" : (dev->role == BLT_ROLE_AG) ? "AG" : "GUI", 3247 status2str(dev->status), 3248 (dev->autoconnect) ? "Yes" : "No", 3249 dev->sco_running, 3250 dev->sco, 3251 dev->sco_thread, 3252 (dev->role == BLT_ROLE_AG) ? (dev->service) ? "Yes" : "No" : "N/A" 3253 ); 3254 dev = dev->next; 3255 } 3256 3257 ast_mutex_unlock(&iface_lock); 3258 return RESULT_SUCCESS; 3259 } 3260 3261 static int 3262 blt_show_information(int fd, int argc, char *argv[]) 3263 { 3264 char b1[18]; 3265 ba2str(&local_bdaddr, b1); 3266 ast_cli(fd, "-------------------------------------------\n"); 3267 ast_cli(fd, " Version : %s\n", BLT_SVN_REVISION); 3268 ast_cli(fd, " Monitor PID : %d\n", monitor_pid); 3269 ast_cli(fd, " RFCOMM AG : Channel %d, FD %d\n", rfcomm_channel_ag, rfcomm_sock_ag); 3270 ast_cli(fd, " RFCOMM HS : Channel %d, FD %d\n", rfcomm_channel_hs, rfcomm_sock_hs); 3271 ast_cli(fd, " RFCOMM GUI : Channel %d, FD %d\n", rfcomm_channel_gui, rfcomm_sock_gui); 3272 ast_cli(fd, " Device : hci%d, MAC Address %s\n", hcidev_id, b1); 3273 ast_cli(fd, "-------------------------------------------\n"); 3274 return RESULT_SUCCESS; 3275 } 3276 3277 static int 3278 blt_ag_sendcmd(int fd, int argc, char *argv[]) 3279 { 3280 blt_dev_t * dev; 3281 3282 if (argc != 4) 3283 return RESULT_SHOWUSAGE; 3284 3285 ast_mutex_lock(&iface_lock); 3286 dev = iface_head; 3287 while (dev) { 3288 if (!strcasecmp(argv[2], dev->name)) 3289 break; 3290 dev = dev->next; 3291 } 3292 ast_mutex_unlock(&iface_lock); 3293 3294 if (!dev) { 3295 ast_cli(fd, "Device '%s' does not exist\n", argv[2]); 3296 return RESULT_FAILURE; 3297 } 3298 3299 if ((dev->role != BLT_ROLE_AG) && (dev->role != BLT_ROLE_GUI)) { 3300 ast_cli(fd, "Device '%s' is not an AG or GUI\n", argv[2]); 3301 return RESULT_FAILURE; 3302 } 3303 3304 if (dev->status == BLT_STATUS_DOWN || dev->status == BLT_STATUS_NEGOTIATING) { 3305 ast_cli(fd, "Device '%s' is not connected\n", argv[2]); 3306 return RESULT_FAILURE; 3307 } 3308 3309 if (*(argv[3] + strlen(argv[3]) - 1) == '.') 3310 *(argv[3] + strlen(argv[3]) - 1) = '?'; 3311 3312 ast_cli(fd, "Sending AT command to %s: %s\n", dev->name, argv[3]); 3313 3314 ast_mutex_lock(&(dev->lock)); 3315 send_atcmd(dev, argv[3]); 3316 ast_mutex_unlock(&(dev->lock)); 3317 3318 return RESULT_SUCCESS; 3319 } 3320 3321 static char * 3322 complete_device(char * line, char * word, int pos, int state, int rpos, blt_role_t role) 3323 { 3324 blt_dev_t * dev; 3325 int which = 0; 3326 char *ret; 3327 3328 if (pos != rpos) 3329 return NULL; 3330 3331 ast_mutex_lock(&iface_lock); 3332 3333 dev = iface_head; 3334 3335 while (dev) { 3336 3337 if ((dev->role == role) && (!strncasecmp(word, dev->name, strlen(word)))) { 3338 if (++which > state) 3339 break; 3340 } 3341 3342 dev = dev->next; 3343 } 3344 3345 if (dev) 3346 ret = strdup(dev->name); 3347 else 3348 ret = NULL; 3349 3350 ast_mutex_unlock(&iface_lock); 3351 3352 return ret; 3353 } 3354 3355 static char * 3356 complete_device_2_ag_gui(char * line, char * word, int pos, int state) 3357 { 3358 return complete_device(line, word, pos, state, 2, BLT_ROLE_AG); 3359 } 3360 3361 static char show_peers_usage[] = 3362 "Usage: bluetooth show peers\n" 3363 " List all bluetooth peers and their status\n"; 3364 3365 static struct ast_cli_entry 3366 cli_show_peers = 3367 { { "bluetooth", "show", "peers", NULL }, blt_show_peers, "List Bluetooth Peers", show_peers_usage }; 3368 3369 3370 static char ag_sendcmd[] = 3371 "Usage: bluetooth <device> sendcmd <cmd>\n" 3372 " Sends a AT cmd over the RFCOMM link, and print result (AG only)\n"; 3373 3374 static struct ast_cli_entry 3375 cli_ag_sendcmd = 3376 { { "bluetooth", "sendcmd", NULL }, blt_ag_sendcmd, "Send AG/GUI an AT command", ag_sendcmd, complete_device_2_ag_gui }; 3377 3378 static char show_information[] = 3379 "Usage: bluetooth show information\n" 3380 " Lists information about the bluetooth subsystem\n"; 3381 3382 static struct ast_cli_entry 3383 cli_show_information = 3384 { { "bluetooth", "show", "information", NULL }, blt_show_information, "List Bluetooth Info", show_information }; 3385 3386 void 3387 remove_sdp_records(void) 3388 { 3389 3390 sdp_session_t * sdp; 3391 sdp_list_t * attr; 3392 sdp_record_t * rec; 3393 int res = -1; 3394 uint32_t range = 0x0000ffff; 3395 3396 if (sdp_record_ag == -1 || sdp_record_gui == -1 || sdp_record_hs == -1) 3397 return; 3398 3399 ast_log(LOG_DEBUG, "Removing SDP records\n"); 3400 3401 sdp = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); 3402 3403 if (!sdp) 3404 return; 3405 3406 attr = sdp_list_append(0, &range); 3407 rec = sdp_service_attr_req(sdp, sdp_record_ag, SDP_ATTR_REQ_RANGE, attr); 3408 sdp_list_free(attr, 0); 3409 3410 if (rec) 3411 if (sdp_record_unregister(sdp, rec) == 0) 3412 res = 0; 3413 3414 rec = sdp_service_attr_req(sdp, sdp_record_gui, SDP_ATTR_REQ_RANGE, attr); 3415 sdp_list_free(attr, 0); 3416 3417 if (rec) 3418 if (sdp_record_unregister(sdp, rec) == 0) 3419 res = 0; 3420 3421 attr = sdp_list_append(0, &range); 3422 rec = sdp_service_attr_req(sdp, sdp_record_hs, SDP_ATTR_REQ_RANGE, attr); 3423 sdp_list_free(attr, 0); 3424 3425 if (rec) 3426 if (sdp_record_unregister(sdp, rec) == 0) 3427 res = 0; 3428 3429 sdp_close(sdp); 3430 3431 if (res == 0) 3432 ast_log(LOG_NOTICE, "Removed SDP records\n"); 3433 else 3434 ast_log(LOG_ERROR, "Failed to remove SDP records\n"); 3435 3436 } 3437 3438 static int 3439 __unload_module(void) 3440 { 3441 3442 #if ASTERISK_VERSION_NUM <= 010107 3443 ast_channel_unregister(BLT_CHAN_NAME); 3444 #else 3445 ast_channel_unregister(&blt_tech); 3446 #endif 3447 3448 if (monitor_thread != AST_PTHREADT_NULL) { 3449 3450 if (ast_mutex_lock(&monitor_lock)) { 3451 3452 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 3453 pthread_cancel(monitor_thread); 3454 pthread_kill(monitor_thread, SIGURG); 3455 fprintf(stderr, "Waiting for monitor thread to join...\n"); 3456 pthread_join(monitor_thread, NULL); 3457 fprintf(stderr, "joined\n"); 3458 } 3459 monitor_thread = AST_PTHREADT_STOP; 3460 ast_mutex_unlock(&monitor_lock); 3461 3462 } else { 3463 3464 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 3465 return -1; 3466 3467 } 3468 3469 } 3470 3471 ast_unregister_atexit(remove_sdp_records); 3472 remove_sdp_records(); 3473 return 0; 3474 } 3475 3476 int 3477 load_module() 3478 { 3479 sdp_session_t * sess; 3480 int dd; 3481 uint16_t vs; 3482 3483 hcidev_id = BLT_DEFAULT_HCI_DEV; 3484 3485 if (blt_parse_config() != 0) { 3486 ast_log(LOG_ERROR, "Bluetooth configuration error. Bluetooth Disabled\n"); 3487 return unload_module(); 3488 } 3489 3490 dd = hci_open_dev(hcidev_id); 3491 if (dd == -1) { 3492 ast_log(LOG_ERROR, "Unable to open interface hci%d: %s.\n", hcidev_id, strerror(errno)); 3493 return -1; 3494 } 3495 3496 hci_read_voice_setting(dd, &vs, 1000); 3497 vs = htobs(vs); 3498 close(dd); 3499 3500 if (vs != 0x0060) { 3501 ast_log(LOG_ERROR, "Bluetooth voice setting must be 0x0060, not 0x%04x\n", vs); 3502 unload_module(); 3503 return 0; 3504 } 3505 3506 if ((sched = sched_context_create()) == NULL) { 3507 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 3508 return -1; 3509 } 3510 3511 memset(&local_bdaddr, 0, sizeof(local_bdaddr)); 3512 3513 hci_devba(hcidev_id, &local_bdaddr); 3514 3515 /* --- Add SDP record --- */ 3516 3517 sess = sdp_connect(&local_bdaddr, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); 3518 3519 if ((rfcomm_sock_ag = rfcomm_listen(&local_bdaddr, rfcomm_channel_ag)) < 0) { 3520 return -1; 3521 } 3522 3523 if ((rfcomm_sock_hs = rfcomm_listen(&local_bdaddr, rfcomm_channel_hs)) < 0) 3524 return -1; 3525 3526 if ((rfcomm_sock_gui = rfcomm_listen(&local_bdaddr, rfcomm_channel_gui)) < 0) 3527 return -1; 3528 3529 if ((sco_socket = sco_listen(&local_bdaddr)) < 0) 3530 return -1; 3531 3532 if (!sess) { 3533 ast_log(LOG_ERROR, "Failed to connect to SDP server: %s\n", strerror(errno)); 3534 return -1; 3535 } 3536 3537 if (sdp_register(sess) != 0) { 3538 ast_log(LOG_ERROR, "Failed to register HeadsetAudioGateway in SDP\n"); 3539 return -1; 3540 } 3541 3542 sdp_close(sess); 3543 3544 if (restart_monitor() != 0) 3545 return -1; 3546 3547 #if ASTERISK_VERSION_NUM <= 010107 3548 if (ast_channel_register(BLT_CHAN_NAME, "Bluetooth Driver", BLUETOOTH_FORMAT, blt_request)) { 3549 #else 3550 if (ast_channel_register(&blt_tech)) { 3551 #endif 3552 ast_log(LOG_ERROR, "Unable to register channel class BTL\n"); 3553 __unload_module(); 3554 return -1; 3555 } 3556 3557 ast_cli_register(&cli_show_information); 3558 ast_cli_register(&cli_show_peers); 3559 ast_cli_register(&cli_ag_sendcmd); 3560 3561 ast_register_atexit(remove_sdp_records); 3562 3563 ast_log(LOG_NOTICE, "Loaded Bluetooth support, %s\n", BLT_SVN_REVISION + 1); 3564 3565 return 0; 3566 } 3567 3568 int 3569 unload_module(void) 3570 { 3571 ast_cli_unregister(&cli_ag_sendcmd); 3572 ast_cli_unregister(&cli_show_peers); 3573 ast_cli_unregister(&cli_show_information); 3574 return __unload_module(); 3575 } 3576 3577 int 3578 usecount() 3579 { 3580 int res; 3581 ast_mutex_lock(&usecnt_lock); 3582 res = usecnt; 3583 ast_mutex_unlock(&usecnt_lock); 3584 return res; 3585 } 3586 3587 char *description() 3588 { 3589 return "Bluetooth Channel Driver"; 3590 } 3591 3592 char * 3593 key() 3594 { 3595 return ASTERISK_GPL_KEY; 3596 } 3597 3598 -
configs/bluetooth.conf
diff -ruN asterisk-1.0.9-old/configs/bluetooth.conf asterisk-1.0.9-new/configs/bluetooth.conf
old new 1 [general] 2 ; Channel we listen on as a HS (Headset) 3 rfchannel_hs = 2 4 ; Channel we listen on as an AG (AudioGateway) 5 rfchannel_ag = 3 6 ; Channel we listen on as GUI 7 rfchannel_gui = 4 8 ; hci interface to use (number - e.g '0') 9 interface = 0 10 11 ; RFCOMM channel to connect to. For a HandsSet: 12 ; sdptool search --bdaddr xx:xx:xx:xx:xx:xx 0x111E 13 ; or,for an AudioGateway (Phone): 14 ; sdptool search --bdaddr xx:xx:xx:xx:xx:xx 0x111F 15 ; 16 ; Find the 'channel' value under RFCOMM. 17 ; 18 ;channel = 6 19 ; Automatically connect? 20 ;autoconnect = yes 21 22 ;example for a SonyEricsson mobile as a GUI device 23 [00:0F:DE:6E:77:6B] 24 name = T610 25 type = GUI 26 channel = 6 27 ;channel = 1 28 autoconnect = yes 29 30 ;[00:0E:6D:1A:3D:86] 31 ;name = Nokia 32 ;type = AG 33 ;channel = 13 34 ;autoconnect = yes 35 36 [00:0E:A1:01:49:AE] 37 name = AutoBlue 38 type = HS 39 channel = 2 40 autoconnect = yes 41 42 ;[00:0A:D9:EB:FD:D8] 43 ;name = P900 44 ;type = AG 45 ;channel = 8 46 ;autoconnect = no
Note:
See TracBrowser
for help on using the repository browser.
