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