]> git.pld-linux.org Git - packages/asterisk.git/commitdiff
- up to 10.0.1; use explict config as SOURCE12 and 13; bluetooth is back and some... auto/th/asterisk-10_0_1-1
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Fri, 20 Jan 2012 22:50:28 +0000 (22:50 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    asterisk-chan_bluetooth.patch -> 1.2
    asterisk.spec -> 1.202
    external-libedit.patch -> 1.6
    menuselect.makedeps -> 1.1
    menuselect.makeopts -> 1.1

asterisk-chan_bluetooth.patch [deleted file]
asterisk.spec
external-libedit.patch
menuselect.makedeps [new file with mode: 0644]
menuselect.makeopts [new file with mode: 0644]

diff --git a/asterisk-chan_bluetooth.patch b/asterisk-chan_bluetooth.patch
deleted file mode 100644 (file)
index 9c8a44a..0000000
+++ /dev/null
@@ -1,3225 +0,0 @@
-diff -urN asterisk-1.4.0-beta3-o-o/build_tools/menuselect-deps.in asterisk-1.4.0-beta3/build_tools/menuselect-deps.in
---- asterisk-1.4.0-beta3-o-o/build_tools/menuselect-deps.in    2006-09-19 11:07:22.000000000 -0600
-+++ asterisk-1.4.0-beta3/build_tools/menuselect-deps.in        2006-11-06 12:45:04.000000000 -0700
-@@ -1,4 +1,5 @@
- ASOUND=@PBX_ALSA@
-+BLUETOOTH=@PBX_BLUETOOTH@
- CURL=@PBX_CURL@
- FREETDS=@PBX_FREETDS@
- GSM=@PBX_GSM@
-diff -urN asterisk-1.4.0-beta3-o-o/channels/chan_bluetooth.c asterisk-1.4.0-beta3/channels/chan_bluetooth.c
---- asterisk-1.4.0-beta3-o-o/channels/chan_bluetooth.c 1969-12-31 17:00:00.000000000 -0700
-+++ asterisk-1.4.0-beta3/channels/chan_bluetooth.c     2006-11-06 12:44:39.000000000 -0700
-@@ -0,0 +1,3145 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Asterisk Bluetooth Channel
-+ *
-+ * Author: Theo Zourzouvillys <theo@adaptive-it.co.uk>
-+ *
-+ * Adaptive Linux Solutions <http://www.adaptive-it.co.uk>
-+ *
-+ * Copyright (C) 2004 Adaptive Linux Solutions
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ *
-+ * ******************* NOTE NOTE NOTE NOTE NOTE *********************
-+ *
-+ * This code is not at all tested, and only been developed with a
-+ * HBH-200 headset and a Nokia 6310i right now.
-+ *
-+ * Expect it to crash, dial random numbers, and steal all your money.
-+ *
-+ * PLEASE try any headsets and phones, and let me know the results,
-+ * working or not, along with all debug output!
-+ *
-+ * ------------------------------------------------------------------
-+ *
-+ * Asterisk Bluetooth Support
-+ *
-+ * Well, here we go - Attempt to provide Handsfree profile support in
-+ * both AG and HF modes, AG (AudioGateway) mode support for using
-+ * headsets, and HF (Handsfree) mode for utilising mobile/cell phones
-+ *
-+ * It would be nice to also provide Headset support at some time in
-+ * the future, however, a working Handsfree profile is nice for now,
-+ * and as far as I can see, almost all new HS devices also support HF
-+ *
-+ * ------------------------------------------------------------------
-+ * INSTRUCTIONS
-+ *
-+ * You need to have bluez's bluetooth stack, along with user space
-+ * tools (>=v2.10), and running hcid and sdsp.
-+ *
-+ * See bluetooth.conf for configuration details.
-+ *
-+ * - Ensure bluetooth subsystem is up and running.  'hciconfig'
-+ *   should show interface as UP.
-+ *
-+ * - If you're trying to use a headset/HS, start up asterisk, and try
-+ *   to pair it as you normally would.
-+ *
-+ * - If you're trying to use a Phone/AG, just make sure bluetooth is
-+ *   enabled on your phone, and start up asterisk.
-+ *
-+ * - 'bluetooth show peers' will show all bluetooth devices states.
-+ *
-+ * - Send a call out by using Dial(BLT/DevName/0123456).  Call a HS 
-+ *   with Dial(BLT/DevName)
-+ *
-+ * ------------------------------------------------------------------
-+ * BUGS
-+ *
-+ * - What should happen when an AG is paired with asterisk and
-+ *   someone uses the AG dalling a number manually?  My test phone
-+ *   seems to try to open an SCO link.  Perhaps an extension to 
-+ *   route the call to, or maybe drop the RFCOM link all together?
-+ *
-+ * ------------------------------------------------------------------
-+ * COMPATIBILITY
-+ *
-+ * PLEASE email <theo@adaptive-it.co.uk> with the results of ANY
-+ * device not listed in here (working or not), or if the device is
-+ * listed and it doesn't work!  Please also email full debug output
-+ * for any device not working correctly or generating errors in log.
-+ * 
-+ * HandsFree Profile:
-+ *
-+ *  HS (HeadSet):
-+ *   - Ericsson HBH-200
-+ *
-+ *  AG (AudioGateway):
-+ *   - Nokia 6310i
-+ *
-+ * ------------------------------------------------------------------
-+ *
-+ * Questions, bugs, or (preferably) patches to:
-+ *
-+ *  <theo@adaptive-it.co.uk>
-+ *
-+ * ------------------------------------------------------------------
-+ */
-+
-+/*! \file
-+ *
-+ * \brief Channel driver for Bluetooth phones and headsets
-+ *
-+ * \author Theo Zourzouvillys <theo@adaptive-it.co.uk>
-+ *
-+ * \par See also
-+ * \arg \ref Config_bluetooth
-+ *
-+ * \ingroup channel_drivers
-+ */
-+
-+
-+/*** MODULEINFO
-+       <depend>bluetooth</depend>
-+ ***/
-+
-+
-+/* ---------------------------------- */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <asterisk/lock.h>
-+#include <asterisk/utils.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/channel_pvt.h>
-+#include <asterisk/config.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/module.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/sched.h>
-+#include <asterisk/options.h>
-+#include <asterisk/cli.h>
-+#include <asterisk/callerid.h>
-+#include <sys/socket.h>
-+#include <sys/signal.h>
-+#include <sys/time.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <arpa/inet.h>
-+#include <fcntl.h>
-+#include <sys/ioctl.h>
-+#include <ctype.h>
-+
-+#include <bluetooth/bluetooth.h>
-+#include <bluetooth/hci.h>
-+#include <bluetooth/hci_lib.h>
-+#include <bluetooth/sco.h>
-+#include <bluetooth/rfcomm.h>
-+#include <bluetooth/sdp.h>
-+#include <bluetooth/sdp_lib.h>
-+
-+/* --- Data types and definitions --- */
-+
-+#ifndef HANDSFREE_AUDIO_GW_SVCLASS_ID
-+# define HANDSFREE_AUDIO_GW_SVCLASS_ID 0x111f
-+#endif
-+
-+#define BLUETOOTH_FORMAT    AST_FORMAT_SLINEAR
-+#define BLT_CHAN_NAME       "BLT"
-+#define BLT_CONFIG_FILE     "bluetooth.conf"
-+#define BLT_RDBUFF_MAX      1024
-+#define BLT_DEFAULT_HCI_DEV 0
-+#define BLT_SVN_REVISION    "$Rev: 38 $"
-+
-+/* ---------------------------------- */
-+
-+typedef enum {
-+  BLT_ROLE_NONE = 0, // Unknown Device
-+  BLT_ROLE_HS = 1,   // Device is a Headset
-+  BLT_ROLE_AG = 2    // Device is an Audio Gateway
-+} blt_role_t;
-+
-+/* State when we're in HS mode */
-+
-+typedef enum {
-+  BLT_STATE_WANT_R   = 0,
-+  BLT_STATE_WANT_N   = 1,
-+  BLT_STATE_WANT_CMD = 2,
-+  BLT_STATE_WANT_N2  = 3,
-+} blt_state_t;
-+
-+typedef enum {
-+  BLT_STATUS_DOWN,
-+  BLT_STATUS_CONNECTING,
-+  BLT_STATUS_NEGOTIATING,
-+  BLT_STATUS_READY,
-+  BLT_STATUS_RINGING,
-+  BLT_STATUS_IN_CALL,
-+} blt_status_t;
-+
-+/* ---------------------------------- */
-+
-+/* Default config settings */
-+
-+#define BLT_DEFAULT_CHANNEL_AG   5
-+#define BLT_DEFAULT_CHANNEL_HS   6
-+#define BLT_DEFAULT_ROLE         BLT_ROLE_HS
-+#define BLT_OBUF_LEN             (48 * 25)
-+
-+#define BUFLEN 4800
-+
-+/* ---------------------------------- */
-+
-+typedef struct blt_dev blt_dev_t;
-+
-+// XXX:T: Tidy this lot up.
-+struct blt_dev {
-+
-+  blt_status_t status;              /* Device Status */
-+
-+  struct ast_channel * owner;       /* Channel we belong to, possibly NULL */
-+  blt_dev_t * dev;                  /* The bluetooth device channel is for */
-+  struct ast_frame fr;              /* Recieved frame */
-+
-+  /* SCO Handler */
-+  int sco_pipe[2];                   /* SCO alert pipe */
-+  int sco;                           /* SCO fd */
-+  int sco_handle;                    /* SCO Handle */
-+  int sco_mtu;                       /* SCO MTU */
-+  int sco_running;                   /* 1 when sCO thread should be running */
-+  pthread_t sco_thread;              /* SCO thread */
-+  ast_mutex_t sco_lock;              /* SCO lock */
-+  int sco_pos_in;                    /* Reader in position */
-+  int sco_pos_out;                   /* Reader out position */
-+  int sco_sending;                   /* Sending SCO packets */
-+  char buf[1024];                    /* Incoming data buffer */
-+  char sco_buf_out[BUFLEN+1];          /* 24 chunks of 48 */
-+  char sco_buf_in[BUFLEN+1];           /* 24 chunks of 48 */
-+
-+  char dnid[1024];                    /* Outgoi gncall dialed number */
-+  unsigned char * obuf[BLT_OBUF_LEN]; /* Outgoing data buffer */
-+  int obuf_len;                       /* Output Buffer Position */
-+  int obuf_wpos;                      /* Buffer Reader */
-+
-+  // device
-+  int autoconnect;                  /* 1 for autoconnect */
-+  int outgoing_id;                  /* Outgoing connection scheduler id */
-+  char * name;                      /* Devices friendly name */
-+  blt_role_t role;                  /* Device role (HS or AG) */
-+  bdaddr_t bdaddr;                  /* remote address */
-+  int channel;                      /* remote channel */
-+  int rd;                           /* RFCOMM fd */
-+  int tmp_rd;                       /* RFCOMM fd */
-+  int call_cnt;                     /* Number of attempted calls */
-+  ast_mutex_t lock;                 /* RFCOMM socket lock */
-+  char rd_buff[BLT_RDBUFF_MAX];     /* RFCOMM input buffer */
-+  int rd_buff_pos;                  /* RFCOMM input buffer position */
-+  int ready;                        /* 1 When ready */
-+
-+  /* AG mode */
-+  char last_ok_cmd[BLT_RDBUFF_MAX];        /* Runtime[AG]: Last AT command that was OK */
-+  int cind;                                /* Runtime[AG]: Recieved +CIND */  
-+  int call_pos, service_pos, callsetup_pos;  /* Runtime[AG]: Positions in CIND/CMER */
-+  int call, service, callsetup;              /* Runtime[AG]: Values */
-+
-+  /* HS mode */
-+  blt_state_t state;                       /* Runtime: Device state (AG mode only) */
-+  int ring_timer;                          /* Runtime:Ring Timer */
-+  char last_err_cmd[BLT_RDBUFF_MAX];       /* Runtime: Last AT command that was OK */
-+  void (*cb)(blt_dev_t * dev, char * str); /* Runtime: Callback when in HS mode */
-+
-+  int brsf;                                /* Runtime: Bluetooth Retrieve Supported Features */
-+  int bvra;                                /* Runtime: Bluetooth Voice Recognised Activation */
-+  int gain_speaker;                        /* Runtime: Gain Of Speaker */
-+  int clip;                                /* Runtime: Supports CLID */
-+  int colp;                                /* Runtime: Connected Line ID */
-+  int elip;                                /* Runtime: (Ericsson) Supports CLID */
-+  int eolp;                                /* Runtime: (Ericsson) Connected Line ID */
-+  int ringing;                             /* Runtime: Device is ringing */
-+
-+  blt_dev_t * next;                        /* Next in linked list */
-+
-+};
-+
-+typedef struct blt_atcb {
-+
-+  /* The command */
-+  char * str;
-+
-+  /* DTE callbacks: */
-+  int (*set)(blt_dev_t * dev, const char * arg, int len);
-+  int (*read)(blt_dev_t * dev);
-+  int (*execute)(blt_dev_t * dev, const char * data);
-+  int (*test)(blt_dev_t * dev);
-+
-+  /* DCE callbacks: */
-+  int (*unsolicited)(blt_dev_t * dev, const char * value);
-+
-+} blt_atcb_t;
-+
-+/* ---------------------------------- */
-+
-+static void rd_close(blt_dev_t * dev, int reconnect, int err);
-+static int send_atcmd(blt_dev_t * device, const char * fmt, ...);
-+static int sco_connect(blt_dev_t * dev);
-+
-+/* ---------------------------------- */
-+
-+/* RFCOMM channel we listen on*/
-+static int rfcomm_channel_ag = BLT_DEFAULT_CHANNEL_AG;
-+static int rfcomm_channel_hs = BLT_DEFAULT_CHANNEL_HS;
-+
-+/* Address of local bluetooth interface */
-+static int hcidev_id;
-+static bdaddr_t local_bdaddr;
-+
-+/* All the current sockets */
-+AST_MUTEX_DEFINE_STATIC(iface_lock);
-+static blt_dev_t * iface_head;
-+static int ifcount = 0;
-+
-+static int sdp_record_hs = -1;
-+static int sdp_record_ag = -1;
-+
-+/* RFCOMM listen socket */
-+static int rfcomm_sock_ag = -1;
-+static int rfcomm_sock_hs = -1;
-+static int sco_socket = -1;
-+
-+static int monitor_pid = -1;
-+
-+/* The socket monitoring thread */
-+static pthread_t monitor_thread = AST_PTHREADT_NULL;
-+AST_MUTEX_DEFINE_STATIC(monitor_lock);
-+
-+/* Cound how many times this module is currently in use */
-+static int usecnt = 0;
-+AST_MUTEX_DEFINE_STATIC(usecnt_lock);
-+
-+static struct sched_context * sched = NULL;
-+
-+/* ---------------------------------- */
-+
-+static const char *
-+role2str(blt_role_t role)
-+{
-+  switch (role) {
-+    case BLT_ROLE_HS:
-+      return "HS";
-+    case BLT_ROLE_AG:
-+      return "AG";
-+    case BLT_ROLE_NONE:
-+      return "??";
-+  }
-+}
-+
-+static const char *
-+status2str(blt_status_t status)
-+{
-+  switch (status) {
-+    case BLT_STATUS_DOWN:
-+      return "Down";
-+    case BLT_STATUS_CONNECTING:
-+      return "Connecting";
-+    case BLT_STATUS_NEGOTIATING:
-+      return "Negotiating";
-+    case BLT_STATUS_READY:
-+      return "Ready";
-+    case BLT_STATUS_RINGING:
-+      return "Ringing";
-+    case BLT_STATUS_IN_CALL:
-+      return "InCall";
-+  };
-+  return "Unknown";
-+}
-+
-+int sock_err(int fd)
-+{
-+  int ret;
-+  int len = sizeof(ret);
-+  getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &len);
-+  return ret;
-+}
-+
-+/* ---------------------------------- */
-+
-+static const char *
-+parse_cind(const char * str, char * name, int name_len)
-+{
-+  int c = 0;
-+
-+  memset(name, 0, name_len);
-+
-+  while (*str) {
-+    if (*str == '(') {
-+      if (++c == 1 && *(str+1) == '"') {
-+        const char * start = str + 2;
-+        int len = 0;
-+        str += 2;
-+        while (*str && *str != '"') {
-+          len++;
-+          str++;
-+        }
-+        if (len == 0)
-+          return NULL;
-+        strncpy(name, start, (len > name_len) ? name_len : len);
-+      }
-+    } else if (*str == ')')
-+      c--;
-+    else if (c == 0 && *str == ',')
-+      return str + 1;
-+    str++;
-+  }
-+  return NULL;
-+}
-+
-+static void
-+set_cind(blt_dev_t * dev, int indicator, int val)
-+{
-+
-+  ast_log(LOG_DEBUG, "CIND %d set to %d\n", indicator, val);
-+
-+  if (indicator == dev->callsetup_pos) {
-+
-+    // call progress
-+
-+    dev->callsetup = val;
-+
-+    switch (val) {
-+      case 3:
-+        // Outgoign ringing
-+        if (dev->owner && dev->role == BLT_ROLE_AG)
-+          ast_queue_control(dev->owner, AST_CONTROL_RINGING);
-+        break;
-+      case 2:
-+        break;
-+      case 1:
-+        break;
-+      case 0:
-+        if (dev->owner && dev->role == BLT_ROLE_AG && dev->call == 0)
-+          ast_queue_control(dev->owner, AST_CONTROL_CONGESTION);
-+        break;
-+    }
-+
-+  } else if (indicator == dev->service_pos) {
-+
-+    // Signal
-+
-+    if (val == 0)
-+      ast_log(LOG_NOTICE, "Audio Gateway %s lost signal\n", dev->name);
-+    else if (dev->service == 0 && val > 0)
-+      ast_log(LOG_NOTICE, "Audio Gateway %s got signal\n", dev->name);
-+
-+    dev->service = val;
-+
-+  } else if (indicator == dev->call_pos) {
-+
-+    // Call
-+
-+    dev->call = val;
-+
-+    if (dev->owner) {
-+      if (val == 1) {
-+        ast_queue_control(dev->owner, AST_CONTROL_ANSWER);
-+      } else if (val == 0)
-+        ast_queue_control(dev->owner, AST_CONTROL_HANGUP);
-+    }
-+
-+  }
-+
-+
-+}
-+
-+/* ---------------------------------- */
-+
-+int
-+set_buffer(char * ring, char * data, int circular_len, int * pos, int data_len)
-+{
-+  int start_pos = *(pos);
-+  int done = 0;
-+  int copy;
-+
-+  while (data_len) {
-+    // Set can_do to the most we can do in this copy.
-+
-+    copy = MIN(circular_len - start_pos, data_len);
-+    memcpy(ring + start_pos, data + done, copy);
-+
-+    done += copy;
-+    start_pos += copy;
-+    data_len -= copy;
-+
-+    if (start_pos == circular_len)
-+      start_pos = 0;
-+  }
-+  *(pos) = start_pos;
-+  return 0;
-+}
-+
-+int
-+get_buffer(char * dst, char * ring, int ring_size, int * head, int to_copy)
-+{
-+  int copy;
-+
-+  // |1|2|3|4|5|6|7|8|9|
-+  //      |-----|
-+
-+  while (to_copy) {
-+
-+    // Set can_do to the most we can do in this copy.
-+    copy = MIN(ring_size - *head, to_copy);
-+
-+    // ast_log(LOG_DEBUG, "Getting: %d bytes, From pos %d\n", copy, *head);
-+    memcpy(dst, ring + *head, copy);
-+
-+    dst += copy;
-+    *head += copy;
-+    to_copy -= copy;
-+
-+    if (*head == ring_size )
-+      *head = 0;
-+
-+  }
-+
-+  return 0;
-+}
-+
-+/* Handle SCO audio sync.
-+ *
-+ * If we are the MASTER, then we control the timing,
-+ * in 48 byte chunks.  If we're the SLAVE, we send
-+ * as and when we recieve a packet.
-+ *
-+ * Because of packet/timing nessecity, we 
-+ * start up a thread when we're passing audio, so
-+ * that things are timed exactly right.
-+ *
-+ * sco_thread() is the function that handles it.
-+ *
-+ */
-+
-+static void *
-+sco_thread(void * data)
-+{
-+  blt_dev_t * dev = (blt_dev_t*)data;
-+  int res;
-+  struct pollfd pfd[2];
-+  int in_pos = 0;
-+  int out_pos = 0;
-+  char c = 1;
-+  int sending;
-+  char buf[1024];
-+  int len;
-+
-+  // Avoid deadlock in odd circumstances
-+
-+  ast_log(LOG_DEBUG, "SCO thread started on fd %d, pid %d\n", dev->sco, getpid());
-+
-+  // dev->status = BLT_STATUS_IN_CALL;
-+  // ast_queue_control(dev->owner, AST_CONTROL_ANSWER);
-+  // Set buffer to silence, just incase.
-+
-+  ast_mutex_lock(&(dev->sco_lock));
-+
-+  memset(dev->sco_buf_in,  0x7f, BUFLEN);
-+  memset(dev->sco_buf_out, 0x7f, BUFLEN);
-+
-+  dev->sco_pos_in  = 0;
-+  dev->sco_pos_out = 0;
-+
-+  ast_mutex_unlock(&(dev->sco_lock));
-+
-+  while (1) {
-+
-+    ast_mutex_lock(&(dev->sco_lock));
-+
-+    if (dev->sco_running != 1) {
-+      ast_log(LOG_DEBUG, "SCO stopped.\n");
-+      break;
-+    }
-+
-+    pfd[0].fd = dev->sco;
-+    pfd[0].events = POLLIN;
-+
-+    pfd[1].fd = dev->sco_pipe[1];
-+    pfd[1].events = POLLIN;
-+
-+    ast_mutex_unlock(&(dev->sco_lock));
-+
-+    res = poll(pfd, 2, 50);
-+
-+    if (res == -1 && errno != EINTR) {
-+      ast_log(LOG_DEBUG, "SCO poll() error\n");
-+      break;
-+    }
-+
-+    if (res == 0)
-+      continue;
-+
-+    ast_mutex_lock(&(dev->sco_lock));
-+
-+    if (pfd[0].revents & POLLIN) {
-+
-+      len = read(dev->sco, buf, 48);
-+
-+      if (len) {
-+        ast_mutex_lock(&(dev->lock));
-+        set_buffer(dev->sco_buf_in,  buf, BUFLEN, &in_pos,  len);
-+        get_buffer(buf, dev->sco_buf_out, BUFLEN, &out_pos, len);
-+        write(dev->sco, buf, len);
-+        if (dev->owner && dev->owner->_state == AST_STATE_UP)
-+          write(dev->sco_pipe[1], &c, 1);
-+        ast_mutex_unlock(&(dev->lock));
-+      }
-+
-+      ast_mutex_unlock(&(dev->sco_lock));
-+
-+    } else if (pfd[0].revents) {
-+
-+      int e = sock_err(pfd[0].fd);
-+      ast_log(LOG_ERROR, "SCO connection error: %s (errno %d)\n", strerror(e), e);
-+      break;
-+
-+    } else if (pfd[1].revents & POLLIN) {
-+
-+      int len;
-+
-+      len = read(pfd[1].fd, &c, 1);
-+      sending = (sending) ? 0 : 1;
-+
-+      ast_mutex_unlock(&(dev->sco_lock));
-+
-+    } else if (pfd[1].revents) {
-+
-+      int e = sock_err(pfd[1].fd);
-+      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);
-+      break;
-+
-+    } else {
-+      ast_log(LOG_NOTICE, "Unhandled poll output\n");
-+      ast_mutex_unlock(&(dev->sco_lock));
-+    }
-+
-+  }
-+
-+  ast_mutex_lock(&(dev->lock));
-+  close(dev->sco);
-+  dev->sco = -1;
-+  dev->sco_running = -1;
-+  ast_mutex_unlock(&(dev->sco_lock));
-+  if (dev->owner)
-+    ast_queue_control(dev->owner, AST_CONTROL_HANGUP);
-+  ast_mutex_unlock(&(dev->lock));
-+  ast_log(LOG_DEBUG, "SCO thread stopped\n");
-+  return NULL;
-+}
-+
-+/* Start SCO thread.  Must be called with dev->lock */
-+
-+static int
-+sco_start(blt_dev_t * dev, int fd)
-+{
-+
-+  if (dev->sco_pipe[1] <= 0) {
-+    ast_log(LOG_ERROR, "SCO pipe[1] == %d\n", dev->sco_pipe[1]);
-+    return -1;
-+  }
-+
-+  ast_mutex_lock(&(dev->sco_lock));
-+
-+  if (dev->sco_running != -1) {
-+    ast_log(LOG_ERROR, "Tried to start SCO thread while already running\n");
-+    ast_mutex_unlock(&(dev->sco_lock));
-+    return -1;
-+  }
-+
-+  if (dev->sco == -1) {
-+    if (fd > 0) {
-+      dev->sco = fd;
-+    } else if (sco_connect(dev) != 0) {
-+      ast_log(LOG_ERROR, "SCO fd invalid\n");
-+      ast_mutex_unlock(&(dev->sco_lock));
-+      return -1;
-+    }
-+  }
-+
-+  dev->sco_running = 1;
-+
-+  if (ast_pthread_create(&(dev->sco_thread), NULL, sco_thread, dev) < 0) {
-+    ast_log(LOG_ERROR, "Unable to start SCO thread.\n");
-+    dev->sco_running = -1;
-+    ast_mutex_unlock(&(dev->sco_lock));
-+    return -1;
-+  }
-+
-+  ast_mutex_unlock(&(dev->sco_lock));
-+
-+  return 0;
-+}
-+
-+/* Stop SCO thread.  Must be called with dev->lock */
-+
-+static int
-+sco_stop(blt_dev_t * dev)
-+{
-+  ast_mutex_lock(&(dev->sco_lock));
-+  if (dev->sco_running == 1)
-+    dev->sco_running = 0;
-+  else
-+    dev->sco_running = -1;
-+  dev->sco_sending = 0;
-+  ast_mutex_unlock(&(dev->sco_lock));
-+  return 0;
-+}
-+
-+/* ---------------------------------- */
-+
-+/* Answer the call.  Call with lock held on device */
-+
-+static int
-+answer(blt_dev_t * dev)
-+{
-+
-+  if ( (!dev->owner) || (dev->ready != 1) || (dev->status != BLT_STATUS_READY && dev->status != BLT_STATUS_RINGING)) {
-+    ast_log(LOG_ERROR, "Attempt to answer() in invalid state (owner=%p, ready=%d, status=%s)\n", 
-+              dev->owner, dev->ready, status2str(dev->status));
-+    return -1;
-+  }
-+
-+    // dev->sd = sco_connect(&local_bdaddr, &(dev->bdaddr), NULL, NULL, 0);
-+    // dev->status = BLT_STATUS_IN_CALL;
-+    // dev->owner->fds[0] = dev->sd;
-+    //  if we are answering (hitting button):
-+  ast_queue_control(dev->owner, AST_CONTROL_ANSWER);
-+    //  if asterisk signals us to answer:
-+    // ast_setstate(ast, AST_STATE_UP);
-+
-+  /* Start SCO link */
-+  sco_start(dev, -1);
-+  return 0;
-+}
-+
-+/* ---------------------------------- */
-+
-+static int 
-+blt_write(struct ast_channel * ast, struct ast_frame * frame)
-+{
-+  blt_dev_t * dev = ast->pvt->pvt; 
-+
-+  /* Write a frame of (presumably voice) data */
-+
-+  if (frame->frametype != AST_FRAME_VOICE) {
-+    ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
-+    return 0;
-+  }
-+
-+  if (!(frame->subclass & BLUETOOTH_FORMAT)) {
-+    ast_log(LOG_WARNING, "Cannot handle frames in format %d\n", frame->subclass);
-+    return 0;
-+  }
-+
-+  if (ast->_state != AST_STATE_UP) {
-+    return 0;
-+  }
-+
-+  ast_mutex_lock(&(dev->sco_lock));
-+  set_buffer(dev->sco_buf_out, frame->data, BUFLEN, &(dev->sco_pos_out), MIN(frame->datalen, BUFLEN));
-+  ast_mutex_unlock(&(dev->sco_lock));
-+
-+  return 0;
-+
-+}
-+
-+static struct ast_frame *
-+blt_read(struct ast_channel * ast)
-+{
-+  blt_dev_t * dev = ast->pvt->pvt;
-+  char c = 1;
-+  int len;
-+
-+  /* Some nice norms */
-+
-+  dev->fr.datalen = 0;
-+  dev->fr.samples = 0;
-+  dev->fr.data =  NULL;
-+  dev->fr.src = BLT_CHAN_NAME;
-+  dev->fr.offset = 0;
-+  dev->fr.mallocd = 0;
-+  dev->fr.delivery.tv_sec = 0;
-+  dev->fr.delivery.tv_usec = 0;
-+
-+  ast_mutex_lock(&(dev->sco_lock));
-+  dev->sco_sending = 1;
-+  read(dev->sco_pipe[0], &c, 1);
-+  len = get_buffer(dev->buf, dev->sco_buf_in, BUFLEN, &(dev->sco_pos_in), 48);
-+  ast_mutex_unlock(&(dev->sco_lock));
-+
-+  dev->fr.data = dev->buf;
-+  dev->fr.samples = len / 2;
-+  dev->fr.datalen = len;
-+  dev->fr.frametype = AST_FRAME_VOICE;
-+  dev->fr.subclass = BLUETOOTH_FORMAT;
-+  dev->fr.offset = 0;
-+
-+  return &dev->fr;
-+}
-+
-+/* Escape Any '"' in str.  Return malloc()ed string */
-+static char *
-+escape_str(char * str)
-+{
-+  char * ptr = str;
-+  char * pret;
-+  char * ret;
-+  int len = 0;
-+
-+  while (*ptr) {
-+    if (*ptr == '"')
-+      len++;
-+    len++;
-+    ptr++;
-+  }
-+
-+  ret = malloc(len + 1);
-+  pret = memset(ret, 0, len + 1);
-+
-+  ptr = str;
-+  
-+  while (*ptr) {
-+    if (*ptr == '"')
-+      *pret++ = '\\';
-+    *pret++ = *ptr++;
-+  }
-+
-+  return ret;
-+}
-+
-+static int
-+ring_hs(blt_dev_t * dev)
-+{
-+#if (ASTERISK_VERSION_NUM < 010100)
-+  char tmp[AST_MAX_EXTENSION];
-+  char *name, *num;
-+#endif
-+
-+  ast_mutex_lock(&(dev->lock));
-+
-+  if (dev->owner == NULL) {
-+    ast_mutex_unlock(&(dev->lock));
-+    return 0;
-+  } 
-+
-+  dev->ringing = 1;
-+  dev->status = BLT_STATUS_RINGING;
-+
-+  send_atcmd(dev, "RING");
-+
-+  dev->owner->rings++;
-+
-+  // XXX:T: '"' needs to be escaped in ELIP.
-+
-+#if (ASTERISK_VERSION_NUM < 010100)
-+
-+  if (dev->owner->callerid) {
-+
-+    memset(tmp, 0, sizeof(tmp));
-+    strncpy(tmp, dev->owner->callerid, sizeof(tmp)-1);
-+
-+    if (!ast_callerid_parse(tmp, &name, &num)) {
-+
-+      if (dev->clip && num)
-+        send_atcmd(dev, "+CLIP: \"%s\",129", num);
-+
-+      if (dev->elip && name) {
-+        char * esc = escape_str(name);
-+        send_atcmd(dev, "*ELIP: \"%s\"", esc);
-+        free(esc);
-+      }
-+    }
-+  }
-+
-+
-+#else
-+
-+  if (dev->clip && dev->owner->cid.cid_num)
-+    send_atcmd(dev, "+CLIP: \"%s\",129", dev->owner->cid.cid_num);
-+
-+  if (dev->elip && dev->owner->cid.cid_name) {
-+    char * esc = escape_str(dev->owner->cid.cid_name);
-+    send_atcmd(dev, "*ELIP: \"%s\"", esc);
-+    free(esc);
-+  }
-+
-+#endif
-+
-+  ast_mutex_unlock(&(dev->lock));
-+
-+  return 1;
-+}
-+
-+/*
-+ * If the HS is already connected, then just send RING, otherwise, things get a
-+ * little more sticky.  We first have to find the channel for HS using SDP, 
-+ * then intiate the connection.  Once we've done that, we can start the call.
-+ */
-+
-+static int
-+blt_call(struct ast_channel * ast, char * dest, int timeout)
-+{
-+  blt_dev_t * dev = ast->pvt->pvt;
-+
-+  if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
-+    ast_log(LOG_WARNING, "blt_call called on %s, neither down nor reserved\n", ast->name);
-+    return -1;
-+  }
-+
-+  ast_log(LOG_DEBUG, "Calling %s on %s [t: %d]\n", dest, ast->name, timeout);
-+
-+  if (ast_mutex_lock(&iface_lock)) {
-+    ast_log(LOG_ERROR, "Failed to get iface_lock.\n");
-+    return -1;
-+  }
-+
-+//  ast_mutex_lock(&(dev->lock));
-+
-+  if (dev->ready == 0) {
-+    ast_log(LOG_WARNING, "Tried to call a device not ready/connected.\n");
-+    ast_setstate(ast, AST_CONTROL_CONGESTION);
-+//    ast_mutex_unlock(&(dev->lock));
-+    ast_mutex_unlock(&iface_lock);
-+    return 0;
-+  }
-+
-+  if (dev->role == BLT_ROLE_HS) {
-+
-+    send_atcmd(dev, "+CIEV: 3,1");
-+
-+    dev->ring_timer = ast_sched_add(sched, 5000, AST_SCHED_CB(ring_hs), dev);
-+
-+    ring_hs(dev);
-+
-+    ast_setstate(ast, AST_STATE_RINGING);
-+    ast_queue_control(ast, AST_CONTROL_RINGING);
-+
-+  } else if (dev->role == BLT_ROLE_AG) {
-+
-+    send_atcmd(dev, "ATD%s;", dev->dnid);
-+
-+  } else {
-+
-+    ast_setstate(ast, AST_CONTROL_CONGESTION);
-+    ast_log(LOG_ERROR, "Unknown device role\n");
-+
-+  }
-+
-+//  ast_mutex_unlock(&(dev->lock));
-+  ast_mutex_unlock(&iface_lock);
-+
-+  return 0;
-+}
-+
-+static int 
-+blt_hangup(struct ast_channel * ast)
-+{
-+  blt_dev_t * dev = ast->pvt->pvt;
-+
-+  ast_log(LOG_DEBUG, "blt_hangup(%s)\n", ast->name);
-+
-+  if (!ast->pvt->pvt) {
-+    ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
-+    return 0;
-+  }
-+
-+  if (ast_mutex_lock(&iface_lock)) {
-+    ast_log(LOG_ERROR, "Failed to get iface_lock\n");
-+    return 0;
-+  }
-+
-+  ast_mutex_lock(&(dev->lock));
-+
-+  sco_stop(dev);
-+  dev->sco_sending = 0;
-+
-+  if (dev->role == BLT_ROLE_HS) {
-+
-+    if (dev->ringing == 0) {
-+      // Actual call in progress
-+      send_atcmd(dev, "+CIEV: 2,0");
-+    } else {
-+
-+      // Just ringing still
-+
-+      if (dev->role == BLT_ROLE_HS)
-+        send_atcmd(dev, "+CIEV: 3,0");
-+
-+      if (dev->ring_timer >= 0)
-+        ast_sched_del(sched, dev->ring_timer);
-+
-+      dev->ring_timer = -1;
-+      dev->ringing = 0;
-+
-+    }
-+
-+  } else if (dev->role == BLT_ROLE_AG) {
-+
-+    // Cancel call.
-+    send_atcmd(dev, "AT+CHUP");
-+
-+  }
-+
-+  if (dev->status == BLT_STATUS_IN_CALL || dev->status == BLT_STATUS_RINGING)
-+    dev->status = BLT_STATUS_READY;
-+
-+  ast->pvt->pvt = NULL;
-+  dev->owner = NULL;
-+  ast_mutex_unlock(&(dev->lock));
-+  ast_setstate(ast, AST_STATE_DOWN);
-+  ast_mutex_unlock(&(iface_lock));
-+
-+  return 0;
-+}
-+
-+static int 
-+blt_indicate(struct ast_channel * c, int condition)
-+{
-+  ast_log(LOG_DEBUG, "blt_indicate (%d)\n", condition);
-+
-+  switch(condition) {
-+    case AST_CONTROL_RINGING:
-+      return -1;
-+    default:
-+      ast_log(LOG_WARNING, "Don't know how to condition %d\n", condition);
-+      break;
-+  }
-+  return -1;
-+}
-+
-+static int
-+blt_answer(struct ast_channel * ast)
-+{
-+  blt_dev_t * dev = ast->pvt->pvt;
-+
-+  ast_mutex_lock(&dev->lock);
-+
-+  // if (dev->ring_timer >= 0)
-+  //   ast_sched_del(sched, dev->ring_timer);
-+  // dev->ring_timer = -1;
-+
-+  ast_log(LOG_DEBUG, "Answering interface\n");
-+
-+  if (ast->_state != AST_STATE_UP) {
-+    send_atcmd(dev, "+CIEV: 2,1");
-+    send_atcmd(dev, "+CIEV: 3,0");
-+    sco_start(dev, -1);
-+    ast_setstate(ast, AST_STATE_UP);
-+  }
-+
-+  ast_mutex_unlock(&dev->lock);
-+
-+  return 0;
-+}
-+
-+static struct ast_channel *
-+blt_new(blt_dev_t * dev, int state, const char * context, const char * number)
-+{
-+  struct ast_channel * ast;
-+  char c = 0;
-+
-+  if ((ast = ast_channel_alloc(1)) == NULL) {
-+    ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
-+    return NULL;
-+  }
-+
-+  snprintf(ast->name, sizeof(ast->name), "BLT/%s", dev->name);
-+
-+  // ast->fds[0] = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
-+
-+  ast->nativeformats       = BLUETOOTH_FORMAT;
-+  ast->pvt->rawreadformat  = BLUETOOTH_FORMAT;
-+  ast->pvt->rawwriteformat = BLUETOOTH_FORMAT;
-+  ast->writeformat         = BLUETOOTH_FORMAT;
-+  ast->readformat          = BLUETOOTH_FORMAT;
-+
-+  ast_setstate(ast, state);
-+
-+  ast->type = BLT_CHAN_NAME;
-+
-+  ast->pvt->pvt = dev;
-+
-+  ast->pvt->call     = blt_call;
-+  ast->pvt->indicate = blt_indicate;
-+  ast->pvt->hangup   = blt_hangup;
-+  ast->pvt->read     = blt_read;
-+  ast->pvt->write    = blt_write;
-+  ast->pvt->answer   = blt_answer;
-+
-+  strncpy(ast->context, context, sizeof(ast->context)-1);
-+  strncpy(ast->exten,   number,  sizeof(ast->exten) - 1);
-+
-+  ast->language[0] = '\0';
-+
-+  ast->fds[0] = dev->sco_pipe[0];
-+  write(dev->sco_pipe[1], &c, 1);
-+
-+  dev->owner = ast;
-+
-+  ast_mutex_lock(&usecnt_lock);
-+  usecnt++;
-+  ast_mutex_unlock(&usecnt_lock);
-+
-+  ast_update_use_count();
-+
-+  if (state != AST_STATE_DOWN) {
-+    if (ast_pbx_start(ast)) {
-+      ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast->name);
-+      ast_hangup(ast);
-+    }
-+  }
-+
-+  return ast;
-+}
-+
-+static struct ast_channel *
-+#if (ASTERISK_VERSION_NUM < 010100)
-+blt_request(char * type, int format, void * local_data)
-+#else
-+blt_request(const char * type, int format, void * local_data)
-+#endif
-+{
-+  char * data = (char*)local_data;
-+  int oldformat;
-+  blt_dev_t * dev = NULL;
-+  struct ast_channel * ast = NULL;
-+  char * number = data, * dname;
-+
-+  dname = strsep(&number, "/");
-+
-+  oldformat = format;
-+
-+  format &= BLUETOOTH_FORMAT;
-+
-+  if (!format) {
-+    ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
-+    return NULL;
-+  }
-+
-+  ast_log(LOG_DEBUG, "Dialing '%s' via '%s'\n", number, dname);
-+
-+  if (ast_mutex_lock(&iface_lock)) {
-+    ast_log(LOG_ERROR, "Unable to lock iface_list\n");
-+    return NULL;
-+  }
-+
-+  dev = iface_head;
-+
-+  while (dev) {
-+    if (strcmp(dev->name, dname) == 0) {
-+      ast_mutex_lock(&(dev->lock));
-+      if (!dev->ready) {
-+        ast_log(LOG_ERROR, "Device %s is not connected\n", dev->name);
-+        ast_mutex_unlock(&(dev->lock));
-+        ast_mutex_unlock(&iface_lock);
-+        return NULL;
-+      }
-+      break;
-+    }
-+    dev = dev->next;
-+  }
-+
-+  ast_mutex_unlock(&iface_lock);
-+
-+  if (!dev) {
-+    ast_log(LOG_WARNING, "Failed to find device named '%s'\n", dname);
-+    return NULL;
-+  }
-+
-+  if (number && dev->role != BLT_ROLE_AG) {
-+    ast_log(LOG_WARNING, "Tried to send a call out on non AG\n");
-+    ast_mutex_unlock(&(dev->lock));
-+    return NULL;
-+  }
-+
-+  if (dev->role == BLT_ROLE_AG)
-+    strncpy(dev->dnid, number, sizeof(dev->dnid) - 1);
-+
-+  ast = blt_new(dev, AST_STATE_DOWN, "bluetooth", "s");
-+
-+  ast_mutex_unlock(&(dev->lock));
-+
-+  return ast;
-+}
-+
-+/* ---------------------------------- */
-+
-+
-+/* ---- AT COMMAND SOCKET STUFF ---- */
-+
-+static int
-+send_atcmd(blt_dev_t * dev, const char * fmt, ...)
-+{
-+  char buf[1024];
-+  va_list ap;
-+  int len;
-+
-+  va_start(ap, fmt);
-+  len = vsnprintf(buf, 1023, fmt, ap);
-+  va_end(ap);
-+
-+  if (option_verbose)
-+    ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s < %s\n", role2str(dev->role), 10, dev->name, buf);
-+
-+  write(dev->rd, "\r\n", 2);
-+  len = write(dev->rd, buf, len);
-+  write(dev->rd, "\r\n", 2);
-+  return (len) ? 0 : -1;
-+}
-+
-+
-+static int
-+send_atcmd_ok(blt_dev_t * dev, const char * cmd)
-+{
-+  int len;
-+  strncpy(dev->last_ok_cmd, cmd, BLT_RDBUFF_MAX - 1);
-+  if (option_verbose)
-+    ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s < OK\n", role2str(dev->role), 10, dev->name);
-+  len = write(dev->rd, "\r\nOK\r\n", 6);
-+  return (len) ? 0 : -1;
-+}
-+
-+static int
-+send_atcmd_error(blt_dev_t * dev)
-+{
-+  int len;
-+
-+  if (option_verbose)
-+    ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s < ERROR\n", role2str(dev->role), 10, dev->name);
-+
-+//  write(dev->rd, "\r\n", 2);
-+//  len = write(dev->rd, dev->last_ok_cmd, 5);
-+  write(dev->rd, "\r\n", 2);
-+  len = write(dev->rd, "ERROR", 5);
-+  write(dev->rd, "\r\n", 2);
-+
-+  return (len) ? 0 : -1;
-+}
-+
-+
-+/* ---------------------------------- */
-+
-+/* -- Handle negotiation when we're an AG -- */
-+
-+/* Bluetooth Support */
-+
-+static int
-+atcmd_brsf_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  ast_log(LOG_DEBUG, "Device Supports: %s\n", arg);
-+  dev->brsf = atoi(arg);
-+  send_atcmd(dev, "+BRSF: %d", 23);
-+  return 0;
-+}
-+
-+/* Bluetooth Voice Recognition */
-+
-+static int
-+atcmd_bvra_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  ast_log(LOG_WARNING, "+BVRA Not Yet Supported\n");
-+  return -1;
-+#if 0
-+  // XXX:T: Fix voice recognition somehow!
-+  int action = atoi(arg);
-+  ast_log(LOG_DEBUG, "Voice Recognition: %s\n", (a) ? "ACTIVATED" : "DEACTIVATED");
-+  if ((action == 0) & (dev->bvra == 1)) {
-+    /* Disable it */
-+    dev->bvra = 0;
-+    // XXX:T: Shutdown any active bvra channel
-+    ast_log(LOG_DEBUG, "Voice Recognition: DISABLED\n");
-+  } else if ((action == 1) && (dev->bvra == 0)) {
-+    /* Enable it */
-+    dev->bvra = 1;
-+    // XXX:T: Schedule connection to voice recognition extension/application
-+    ast_log(LOG_DEBUG, "Voice Recognition: ENABLED\n");
-+  } else {
-+    ast_log(LOG_ERROR, "+BVRA out of sync (we think %d, but HS wants %d)\n", dev->bvra, action);
-+    return -1;
-+  }
-+  return 0;
-+#endif
-+}
-+
-+/* Clock */
-+
-+static int
-+atcmd_cclk_read(blt_dev_t * dev)
-+{
-+  struct tm t, *tp;
-+  const time_t ti = time(0);
-+  tp = localtime_r(&ti, &t);
-+  send_atcmd(dev, "+CCLK: \"%02d/%02d/%02d,%02d:%02d:%02d+%02d\"", 
-+                  (tp->tm_year % 100), (tp->tm_mon + 1), (tp->tm_mday),
-+                  tp->tm_hour, tp->tm_min, tp->tm_sec, ((tp->tm_gmtoff / 60) / 15));
-+  return 0;
-+}
-+
-+/* CHUP - Hangup Call */
-+
-+static int
-+atcmd_chup_execute(blt_dev_t * dev, const char * data)
-+{
-+  if (!dev->owner) {
-+    ast_log(LOG_ERROR, "Request to hangup call when none in progress\n");
-+    return -1;
-+  }
-+  ast_log(LOG_DEBUG, "Hangup Call\n");
-+  ast_queue_control(dev->owner, AST_CONTROL_HANGUP);
-+  return 0;
-+}
-+
-+/* CIND - Call Indicator */
-+
-+static int
-+atcmd_cind_read(blt_dev_t * dev)
-+{
-+  send_atcmd(dev, "+CIND: 1,0,0");
-+  return 0;
-+}
-+
-+static int
-+atcmd_cind_test(blt_dev_t * dev)
-+{
-+  send_atcmd(dev, "+CIND: (\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0-4))");
-+  return 0;
-+}
-+
-+/* Set Language */
-+
-+static int
-+atcmd_clan_read(blt_dev_t * dev)
-+{
-+  send_atcmd(dev, "+CLAN: \"en\"");
-+  return 0;
-+}
-+
-+/* Caller Id Presentation */
-+
-+static int
-+atcmd_clip_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  dev->clip = atoi(arg);
-+  return 0;
-+}
-+
-+/* Conneced Line Identification Presentation */
-+
-+static int
-+atcmd_colp_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  dev->colp = atoi(arg);
-+  return 0;
-+}
-+
-+/* CMER - Mobile Equipment Event Reporting */
-+
-+static int
-+atcmd_cmer_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  dev->ready = 1;
-+  dev->status = BLT_STATUS_READY;
-+  return 0;
-+}
-+
-+/* PhoneBook Types:
-+ *
-+ *  - FD - SIM Fixed Dialing Phone Book
-+ *  - ME - ME Phone book
-+ *  - SM - SIM Phone Book
-+ *  - DC - ME dialled-calls list
-+ *  - RC - ME recieved-calls lisr
-+ *  - MC - ME missed-calls list
-+ *  - MV - ME Voice Activated Dialing List
-+ *  - HP - Hierachial Phone Book
-+ *  - BC - Own Business Card (PIN2 required)
-+ *
-+ */
-+
-+/* Read Phone Book Entry */
-+
-+static int
-+atcmd_cpbr_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  // XXX:T: Fix the phone book!
-+  // * Maybe add res_phonebook or something? */
-+  send_atcmd(dev, "+CPBR: %d,\"%s\",128,\"%s\"", atoi(arg), arg, arg);
-+  return 0;
-+}
-+
-+/* Select Phone Book */
-+
-+static int
-+atcmd_cpbs_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  // XXX:T: I guess we'll just accept any?
-+  return 0;
-+}
-+
-+static int
-+atcmd_cscs_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  // XXX:T: Language
-+  return 0;
-+}
-+
-+static int
-+atcmd_eips_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  ast_log(LOG_DEBUG, "Identify Presentation Set: %s=%s\n",
-+                         (*(arg) == 49) ? "ELIP" : "EOLP",
-+                         (*(arg+2) == 49) ? "ON" : "OFF");
-+
-+  if (*(arg) == 49)
-+    dev->eolp = (*(arg+2) == 49) ? 1 : 0;
-+  else
-+    dev->elip = (*(arg+2) == 49) ? 1 : 0;
-+
-+  return 0;
-+}
-+
-+/* VGS - Speaker Volume Gain */
-+
-+static int
-+atcmd_vgs_set(blt_dev_t * dev, const char * arg, int len)
-+{
-+  dev->gain_speaker = atoi(arg);
-+  return 0;
-+}
-+
-+/* Dial */
-+static int
-+atcmd_dial_execute(blt_dev_t * dev, const char * data)
-+{
-+  char * number = NULL;
-+
-+  /* Make sure there is a ';' at the end of the line */
-+  if (*(data + (strlen(data) - 1)) != ';') {
-+    ast_log(LOG_WARNING, "Can't dial non-voice right now: %s\n", data);
-+    return -1;
-+  }
-+
-+  number = strndup(data, strlen(data) - 1);
-+  ast_log(LOG_NOTICE, "Dial: [%s]\n", number);
-+
-+  send_atcmd(dev, "+CIEV: 2,1");
-+  send_atcmd(dev, "+CIEV: 3,0");
-+
-+  sco_start(dev, -1);
-+
-+  if (blt_new(dev, AST_STATE_UP, "bluetooth", number) == NULL) {
-+    sco_stop(dev);
-+  }
-+
-+  free(number);
-+
-+  return 0;
-+}
-+
-+/* Answer */
-+
-+static int
-+atcmd_answer_execute(blt_dev_t * dev, const char * data)
-+{
-+
-+  if (!dev->ringing || !dev->owner) {
-+    ast_log(LOG_WARNING, "Can't answer non existant call\n");
-+    return -1;
-+  }
-+
-+  dev->ringing = 0;
-+
-+  if (dev->ring_timer >= 0)
-+    ast_sched_del(sched, dev->ring_timer);
-+
-+  dev->ring_timer = -1;
-+
-+  send_atcmd(dev, "+CIEV: 2,1");
-+  send_atcmd(dev, "+CIEV: 3,0");
-+
-+  return answer(dev);
-+}
-+
-+static int
-+ag_unsol_ciev(blt_dev_t * dev, const char * data)
-+{
-+  const char * orig = data;
-+  int indicator;
-+  int status;
-+
-+  while (*(data) && *(data) == ' ')
-+    data++;
-+
-+  if (*(data) == 0) {
-+    ast_log(LOG_WARNING, "Invalid value[1] for '+CIEV:%s'\n", orig);
-+    return -1;
-+  }
-+
-+  indicator = *(data++) - 48;
-+
-+  if (*(data++) != ',') {
-+    ast_log(LOG_WARNING, "Invalid value[2] for '+CIEV:%s'\n", orig);
-+    return -1;
-+  }
-+
-+  if (*(data) == 0) {
-+    ast_log(LOG_WARNING, "Invalid value[3] for '+CIEV:%s'\n", orig);
-+    return -1;
-+  }
-+
-+  status = *(data) - 48;
-+
-+  set_cind(dev, indicator, status);
-+
-+  return 0;
-+}
-+
-+static int
-+ag_unsol_cind(blt_dev_t * dev, const char * data)
-+{
-+
-+  while (*(data) && *(data) == ' ')
-+    data++;
-+
-+
-+  if (dev->cind == 0)
-+  {
-+    int pos = 1;
-+    char name[1024];
-+
-+    while ((data = parse_cind(data, name, 1023)) != NULL) {
-+      ast_log(LOG_DEBUG, "CIND: %d=%s\n", pos, name);
-+      if (strcmp(name, "call") == 0)
-+        dev->call_pos = pos;
-+      else if (strcmp(name, "service") == 0)
-+        dev->service_pos = pos;
-+      else if (strcmp(name, "call_setup") == 0 || strcmp(name, "callsetup") == 0)
-+        dev->callsetup_pos = pos;
-+      pos++;
-+    }
-+
-+    ast_log(LOG_DEBUG, "CIND: %d=%s\n", pos, name);
-+
-+  } else {
-+
-+    int pos = 1, len = 0;
-+    char val[128];
-+    const char * start = data;
-+
-+    while (*data) {
-+      if (*data == ',') {
-+        memset(val, 0, 128);
-+        strncpy(val, start, len);
-+        set_cind(dev, pos, atoi(val));
-+        pos++;
-+        len = 0;
-+        data++;
-+        start = data;
-+        continue;
-+      }
-+      len++;
-+      data++;
-+    }
-+
-+    memset(val, 0, 128);
-+    strncpy(val, start, len);
-+    ast_log(LOG_DEBUG, "CIND IND %d set to %d [%s]\n", pos, atoi(val), val);
-+
-+
-+  }
-+
-+  return 0;
-+}
-+
-+static blt_atcb_t
-+atcmd_list[] = 
-+{
-+  { "A",     NULL,           NULL,            atcmd_answer_execute, NULL,             NULL },
-+  { "D",     NULL,           NULL,            atcmd_dial_execute,   NULL,             NULL },
-+  { "+BRSF", atcmd_brsf_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+BVRA", atcmd_bvra_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+CCLK", NULL,           atcmd_cclk_read, NULL,                 NULL,             NULL },
-+  { "+CHUP", NULL,           NULL,            atcmd_chup_execute,   NULL,             NULL },
-+  { "+CIEV", NULL,           NULL,            NULL,                 NULL,             ag_unsol_ciev },
-+  { "+CIND", NULL,           atcmd_cind_read, NULL,                 atcmd_cind_test,  ag_unsol_cind },
-+  { "+CLAN", NULL,           atcmd_clan_read, NULL,                 NULL,             NULL },
-+  { "+CLIP", atcmd_clip_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+COLP", atcmd_colp_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+CMER", atcmd_cmer_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+CPBR", atcmd_cpbr_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+CPBS", atcmd_cpbs_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+CSCS", atcmd_cscs_set, NULL,            NULL,                 NULL,             NULL },
-+  { "*EIPS", atcmd_eips_set, NULL,            NULL,                 NULL,             NULL },
-+  { "+VGS",  atcmd_vgs_set,  NULL,            NULL,                 NULL,             NULL },
-+};
-+
-+#define ATCMD_LIST_LEN (sizeof(atcmd_list) / sizeof(blt_atcb_t))
-+
-+/* ---------------------------------- */
-+
-+/* -- Handle negotiation when we're a HS -- */
-+
-+void
-+ag_unknown_response(blt_dev_t * dev, char * cmd)
-+{
-+  ast_log(LOG_DEBUG, "Got UNKN response: %s\n", cmd);
-+
-+  // DELAYED
-+  // NO CARRIER
-+
-+}
-+
-+void
-+ag_cgmi_response(blt_dev_t * dev, char * cmd)
-+{
-+  // CGMM - Phone Model
-+  // CGMR - Phone Revision
-+  // CGSN - IMEI
-+  // AT*
-+  // VTS - send tone
-+  // CREG
-+  // CBC - BATTERY
-+  // CSQ - SIGANL
-+  // CSMS - SMS STUFFS
-+  //  CMGL
-+  //  CMGR
-+  //  CMGS
-+  // CSCA - sms CENTER NUMBER
-+  // CNMI - SMS INDICATION
-+  // ast_log(LOG_DEBUG, "Manufacturer: %s\n", cmd);
-+  dev->cb = ag_unknown_response;
-+}
-+
-+void
-+ag_cgmi_valid_response(blt_dev_t * dev, char * cmd)
-+{
-+  // send_atcmd(dev, "AT+WS46?");
-+  // send_atcmd(dev, "AT+CRC=1");
-+  // send_atcmd(dev, "AT+CNUM");
-+
-+  if (strcmp(cmd, "OK") == 0) {
-+    send_atcmd(dev, "AT+CGMI");
-+    dev->cb = ag_cgmi_response;
-+  } else {
-+    dev->cb = ag_unknown_response;
-+  }
-+}
-+
-+void
-+ag_clip_response(blt_dev_t * dev, char * cmd)
-+{
-+  send_atcmd(dev, "AT+CGMI=?");
-+  dev->cb = ag_cgmi_valid_response;
-+}
-+
-+void
-+ag_cmer_response(blt_dev_t * dev, char * cmd)
-+{
-+  dev->cb = ag_clip_response;
-+  dev->ready = 1;
-+  dev->status = BLT_STATUS_READY;
-+  send_atcmd(dev, "AT+CLIP=1");
-+}
-+
-+void
-+ag_cind_status_response(blt_dev_t * dev, char * cmd)
-+{
-+  // XXX:T: Handle response.
-+  dev->cb = ag_cmer_response;
-+  send_atcmd(dev, "AT+CMER=3,0,0,1");
-+  // Initiase SCO link!
-+}
-+
-+void
-+ag_cind_response(blt_dev_t * dev, char * cmd)
-+{
-+  dev->cb = ag_cind_status_response;
-+  dev->cind = 1;
-+  send_atcmd(dev, "AT+CIND?");
-+}
-+
-+void
-+ag_brsf_response(blt_dev_t * dev, char * cmd)
-+{
-+  dev->cb = ag_cind_response;
-+  ast_log(LOG_DEBUG, "Bluetooth features: %s\n", cmd);
-+  dev->cind = 0;
-+  send_atcmd(dev, "AT+CIND=?");
-+}
-+
-+/* ---------------------------------- */
-+
-+static int
-+sdp_register(sdp_session_t * session)
-+{
-+  // XXX:T: Fix this horrible function so it makes some sense and is extensible!
-+  sdp_list_t *svclass_id, *pfseq, *apseq, *root;
-+  uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid;
-+  sdp_profile_desc_t profile;
-+  sdp_list_t *aproto, *proto[2];
-+  sdp_record_t record;
-+  uint8_t u8 = rfcomm_channel_ag;
-+  uint8_t u8_hs = rfcomm_channel_hs;
-+  sdp_data_t *channel;
-+  int ret = 0;
-+
-+  memset((void *)&record, 0, sizeof(sdp_record_t));
-+  record.handle = 0xffffffff;
-+  sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
-+  root = sdp_list_append(0, &root_uuid);
-+  sdp_set_browse_groups(&record, root);
-+
-+  // Register as an AG
-+
-+  sdp_uuid16_create(&svclass_uuid, HANDSFREE_AUDIO_GW_SVCLASS_ID);
-+  svclass_id = sdp_list_append(0, &svclass_uuid);
-+  sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
-+  svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
-+  sdp_set_service_classes(&record, svclass_id);
-+  sdp_uuid16_create(&profile.uuid, 0x111f);
-+  profile.version = 0x0100;
-+  pfseq = sdp_list_append(0, &profile);
-+
-+  sdp_set_profile_descs(&record, pfseq);
-+
-+  sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
-+  proto[0] = sdp_list_append(0, &l2cap_uuid);
-+  apseq = sdp_list_append(0, proto[0]);
-+
-+  sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
-+  proto[1] = sdp_list_append(0, &rfcomm_uuid);
-+  channel = sdp_data_alloc(SDP_UINT8, &u8);
-+  proto[1] = sdp_list_append(proto[1], channel);
-+  apseq = sdp_list_append(apseq, proto[1]);
-+
-+  aproto = sdp_list_append(0, apseq);
-+  sdp_set_access_protos(&record, aproto);
-+
-+  sdp_set_info_attr(&record, "Voice Gateway", 0, 0);
-+
-+  if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
-+    ast_log(LOG_ERROR, "Service Record registration failed\n");
-+    ret = -1;
-+    goto end;
-+  }
-+
-+  sdp_record_ag = record.handle;
-+
-+  ast_log(LOG_NOTICE, "HeadsetAudioGateway service registered\n");
-+
-+  sdp_data_free(channel);
-+  sdp_list_free(proto[0], 0);
-+  sdp_list_free(proto[1], 0);
-+  sdp_list_free(apseq, 0);
-+  sdp_list_free(aproto, 0);
-+
-+  // -------------
-+
-+  memset((void *)&record, 0, sizeof(sdp_record_t));
-+  record.handle = 0xffffffff;
-+  sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
-+  root = sdp_list_append(0, &root_uuid);
-+  sdp_set_browse_groups(&record, root);
-+
-+  // Register as an HS
-+
-+  sdp_uuid16_create(&svclass_uuid, HANDSFREE_AUDIO_GW_SVCLASS_ID);
-+  svclass_id = sdp_list_append(0, &svclass_uuid);
-+  sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
-+  svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
-+  sdp_set_service_classes(&record, svclass_id);
-+  sdp_uuid16_create(&profile.uuid, 0x111e);
-+  profile.version = 0x0100;
-+  pfseq = sdp_list_append(0, &profile);
-+  sdp_set_profile_descs(&record, pfseq);
-+
-+  sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
-+  proto[0] = sdp_list_append(0, &l2cap_uuid);
-+  apseq = sdp_list_append(0, proto[0]);
-+
-+  sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
-+  proto[1] = sdp_list_append(0, &rfcomm_uuid);
-+  channel = sdp_data_alloc(SDP_UINT8, &u8_hs);
-+  proto[1] = sdp_list_append(proto[1], channel);
-+  apseq = sdp_list_append(apseq, proto[1]);
-+
-+  aproto = sdp_list_append(0, apseq);
-+  sdp_set_access_protos(&record, aproto);
-+  sdp_set_info_attr(&record, "Voice Gateway", 0, 0);
-+
-+  if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) {
-+    ast_log(LOG_ERROR, "Service Record registration failed\n");
-+    ret = -1;
-+    goto end;
-+  }
-+
-+  sdp_record_hs = record.handle;
-+
-+  ast_log(LOG_NOTICE, "HeadsetAudioGateway service registered\n");
-+
-+end:
-+  sdp_data_free(channel);
-+  sdp_list_free(proto[0], 0);
-+  sdp_list_free(proto[1], 0);
-+  sdp_list_free(apseq, 0);
-+  sdp_list_free(aproto, 0);
-+
-+  return ret;
-+}
-+
-+static int
-+rfcomm_listen(bdaddr_t * bdaddr, int channel)
-+{
-+
-+  int sock = -1;
-+  struct sockaddr_rc loc_addr;
-+  int on = 1;
-+
-+  if ((sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
-+    ast_log(LOG_ERROR, "Can't create socket: %s (errno: %d)\n", strerror(errno), errno);
-+    return -1;
-+  }
-+
-+  loc_addr.rc_family = AF_BLUETOOTH;
-+
-+  /* Local Interface Address */
-+  bacpy(&loc_addr.rc_bdaddr, bdaddr);
-+
-+  /* Channel */
-+  loc_addr.rc_channel = channel;
-+
-+  if (bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
-+    ast_log(LOG_ERROR, "Can't bind socket: %s (errno: %d)\n", strerror(errno), errno);
-+    close(sock);
-+    return -1;
-+  }
-+
-+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
-+    ast_log(LOG_ERROR, "Set socket SO_REUSEADDR option on failed: errno %d, %s", errno, strerror(errno));
-+    close(sock);
-+    return -1;
-+  }
-+
-+  if (fcntl(sock, F_SETFL, O_RDWR|O_NONBLOCK) != 0)
-+    ast_log(LOG_ERROR, "Can't set RFCOMM socket to NBIO\n");
-+
-+  if (listen(sock, 10) < 0) {
-+    ast_log(LOG_ERROR,"Can not listen on the socket. %s(%d)\n", strerror(errno), errno);
-+    close(sock);
-+    return -1;
-+  }
-+
-+  ast_log(LOG_NOTICE, "Listening for RFCOMM channel %d connections on FD %d\n", channel, sock);
-+
-+  return sock;
-+}
-+
-+
-+static int
-+sco_listen(bdaddr_t * bdaddr)
-+{
-+  int sock = -1;
-+  int on = 1;
-+  struct sockaddr_sco loc_addr;
-+
-+  memset(&loc_addr, 0, sizeof(loc_addr));
-+
-+  if ((sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) {
-+    ast_log(LOG_ERROR, "Can't create SCO socket: %s (errno: %d)\n", strerror(errno), errno);
-+    return -1;
-+  }
-+
-+  loc_addr.sco_family = AF_BLUETOOTH;
-+  bacpy(&loc_addr.sco_bdaddr, BDADDR_ANY);
-+
-+  if (bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) < 0) {
-+    ast_log(LOG_ERROR, "Can't bind SCO socket: %s (errno: %d)\n", strerror(errno), errno);
-+    close(sock);
-+    return -1;
-+  }
-+
-+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
-+    ast_log(LOG_ERROR, "Set SCO socket SO_REUSEADDR option on failed: errno %d, %s", errno, strerror(errno));
-+    close(sock);
-+    return -1;
-+  }
-+
-+  if (fcntl(sock, F_SETFL, O_RDWR|O_NONBLOCK) != 0)
-+    ast_log(LOG_ERROR, "Can't set SCO socket to NBIO\n");
-+
-+  if (listen(sock, 10) < 0) {
-+    ast_log(LOG_ERROR,"Can not listen on SCO socket: %s(%d)\n", strerror(errno), errno);
-+    close(sock);
-+    return -1;
-+  }
-+
-+  ast_log(LOG_NOTICE, "Listening for SCO connections on FD %d\n", sock);
-+
-+  return sock;
-+}
-+
-+static int
-+rfcomm_connect(bdaddr_t * src, bdaddr_t * dst, int channel, int nbio)
-+{
-+  struct sockaddr_rc addr;
-+  int s;
-+
-+  if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
-+    return -1;
-+  }
-+
-+  memset(&addr, 0, sizeof(addr));
-+  addr.rc_family = AF_BLUETOOTH;
-+  bacpy(&addr.rc_bdaddr, src);
-+  addr.rc_channel = 0;
-+
-+  if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-+    close(s);
-+    return -1;
-+  }
-+
-+  memset(&addr, 0, sizeof(addr));
-+  addr.rc_family = AF_BLUETOOTH;
-+  bacpy(&addr.rc_bdaddr, dst);
-+  addr.rc_channel = channel;
-+
-+  if (nbio) {
-+    if (fcntl(s, F_SETFL, O_RDWR|O_NONBLOCK) != 0)
-+      ast_log(LOG_ERROR, "Can't set RFCOMM socket to NBIO\n");
-+  }
-+
-+  if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 && (nbio != 1 || (errno != EAGAIN))) {
-+    close(s);
-+    return -1;
-+  }
-+
-+  return s;
-+}
-+
-+/* Must be called with dev->lock held */
-+
-+static int
-+sco_connect(blt_dev_t * dev)
-+{
-+  struct sockaddr_sco addr;
-+  // struct sco_conninfo conn;
-+  // struct sco_options opts;
-+  // int size;
-+  // bdaddr_t * src = &local_bdaddr;
-+
-+  int s;
-+  bdaddr_t * dst = &(dev->bdaddr);
-+
-+  if (dev->sco != -1) {
-+    ast_log(LOG_ERROR, "SCO fd already open.\n");
-+    return -1;
-+  }
-+
-+  if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) {
-+    ast_log(LOG_ERROR, "Can't create SCO socket(): %s\n", strerror(errno));
-+    return -1;
-+  }
-+
-+  memset(&addr, 0, sizeof(addr));
-+
-+  addr.sco_family = AF_BLUETOOTH;
-+  bacpy(&addr.sco_bdaddr, BDADDR_ANY);
-+
-+  if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-+    ast_log(LOG_ERROR, "Can't bind() SCO socket: %s\n", strerror(errno));
-+    close(s);
-+    return -1;
-+  }
-+
-+  memset(&addr, 0, sizeof(addr));
-+  addr.sco_family = AF_BLUETOOTH;
-+  bacpy(&addr.sco_bdaddr, dst);
-+
-+  if (fcntl(s, F_SETFL, O_RDWR|O_NONBLOCK) != 0)
-+    ast_log(LOG_ERROR, "Can't set SCO socket to NBIO\n");
-+
-+  if ((connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) && (errno != EAGAIN)) {
-+    ast_log(LOG_ERROR, "Can't connect() SCO socket: %s (errno %d)\n", strerror(errno), errno);
-+    close(s);
-+    return -1;
-+  }
-+
-+  //size = sizeof(conn);
-+
-+
-+/* XXX:T: HERE, fix getting SCO conninfo.
-+
-+  if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &size) < 0) {
-+    ast_log(LOG_ERROR, "Can't getsockopt SCO_CONNINFO on SCO socket: %s\n", strerror(errno));
-+    close(s);
-+    return -1;
-+  }
-+
-+  size = sizeof(opts);
-+
-+  if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &opts, &size) < 0) {
-+    ast_log(LOG_ERROR, "Can't getsockopt SCO_OPTIONS on SCO socket: %s\n", strerror(errno));
-+    close(s);
-+    return -1;
-+  }
-+
-+  dev->sco_handle = conn.hci_handle;
-+  dev->sco_mtu = opts.mtu;
-+
-+*/
-+
-+  ast_log(LOG_DEBUG, "SCO: %d\n", s);
-+
-+  dev->sco = s;
-+
-+  return 0;
-+}
-+
-+
-+/* ---------------------------------- */
-+
-+/* Non blocking (async) outgoing bluetooth connection */
-+
-+static int
-+try_connect(blt_dev_t * dev)
-+{
-+  int fd;
-+  ast_mutex_lock(&(dev->lock));
-+
-+  if (dev->status != BLT_STATUS_CONNECTING && dev->status != BLT_STATUS_DOWN) {
-+    ast_mutex_unlock(&(dev->lock));
-+    return 0;
-+  }
-+
-+  if (dev->rd != -1) {
-+
-+    int ret;
-+    struct pollfd pfd;
-+
-+    if (dev->status != BLT_STATUS_CONNECTING) {
-+      ast_mutex_unlock(&(dev->lock));
-+      dev->outgoing_id = -1;
-+      return 0;
-+    }
-+
-+    // ret = connect(dev->rd, (struct sockaddr *)&(dev->addr), sizeof(struct sockaddr_rc)); // 
-+
-+    pfd.fd = dev->rd;
-+    pfd.events = POLLIN | POLLOUT;
-+
-+    ret = poll(&pfd, 1, 0);
-+
-+    if (ret == -1) {
-+      close(dev->rd);
-+      dev->rd = -1;
-+      dev->status = BLT_STATUS_DOWN;
-+      dev->outgoing_id = ast_sched_add(sched, 10000, AST_SCHED_CB(try_connect), dev);
-+      ast_mutex_unlock(&(dev->lock));
-+      return 0;
-+    }
-+
-+    if (ret > 0) {
-+
-+      int len = sizeof(ret);
-+      getsockopt(dev->rd, SOL_SOCKET, SO_ERROR, &ret, &len);
-+
-+      if (ret == 0) {
-+
-+        ast_log(LOG_NOTICE, "Initialised bluetooth link to device %s\n", dev->name); 
-+
-+#if 0
-+        {
-+          struct hci_conn_info_req * cr;
-+          int dd;
-+          char name[248];
-+
-+          cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
-+          dd = hci_open_dev(hcidev_id);
-+          cr->type = ACL_LINK;
-+          bacpy(&cr->bdaddr, &(dev->bdaddr));
-+
-+          if (ioctl(dd, HCIGETCONNINFO, (unsigned long)cr) < 0) {
-+            ast_log(LOG_ERROR, "Failed to get connection info: %s\n", strerror(errno));
-+          } else {
-+            ast_log(LOG_DEBUG, "HCI Handle: %d\n", cr->conn_info->handle);
-+          }
-+
-+          if (hci_read_remote_name(dd, &(dev->bdaddr), sizeof(name), name, 25000) == 0)
-+            ast_log(LOG_DEBUG, "Remote Name: %s\n", name);
-+          free(cr);
-+        }
-+#endif
-+
-+        dev->status = BLT_STATUS_NEGOTIATING;
-+
-+        /* If this device is a AG, we initiate the negotiation. */
-+
-+        if (dev->role == BLT_ROLE_AG) {
-+          dev->cb = ag_brsf_response;
-+          send_atcmd(dev, "AT+BRSF=23");
-+        }
-+
-+        dev->outgoing_id = -1;
-+        ast_mutex_unlock(&(dev->lock));
-+        return 0;
-+
-+      } else {
-+
-+        if (ret != EHOSTDOWN)
-+          ast_log(LOG_NOTICE, "Connect to device %s failed: %s (errno %d)\n", dev->name, strerror(ret), ret);
-+
-+        close(dev->rd);
-+        dev->rd = -1;
-+        dev->status = BLT_STATUS_DOWN;
-+        dev->outgoing_id = ast_sched_add(sched, (ret == EHOSTDOWN) ? 10000 : 2500, AST_SCHED_CB(try_connect), dev);
-+        ast_mutex_unlock(&(dev->lock));
-+        return 0;
-+
-+      }
-+
-+    }
-+
-+    dev->outgoing_id = ast_sched_add(sched, 100, AST_SCHED_CB(try_connect), dev);
-+    ast_mutex_unlock(&(dev->lock));
-+    return 0;
-+  }
-+
-+  fd = rfcomm_connect(&local_bdaddr, &(dev->bdaddr), dev->channel, 1);
-+
-+  if (fd == -1) {
-+    ast_log(LOG_WARNING, "NBIO connect() to %s returned %d: %s\n", dev->name, errno, strerror(errno));
-+    dev->outgoing_id = ast_sched_add(sched, 5000, AST_SCHED_CB(try_connect), dev);
-+    ast_mutex_unlock(&(dev->lock));
-+    return 0;
-+  }
-+
-+  dev->rd = fd;
-+  dev->status = BLT_STATUS_CONNECTING;
-+  dev->outgoing_id = ast_sched_add(sched, 100, AST_SCHED_CB(try_connect), dev);
-+  ast_mutex_unlock(&(dev->lock));
-+  return 0;
-+}
-+
-+
-+/* Called whenever a new command is recieved while we're the AG */
-+
-+
-+static int
-+process_rfcomm_cmd(blt_dev_t * dev, char * cmd)
-+{
-+  int i;
-+  char * fullcmd = cmd;
-+
-+  if (option_verbose)
-+    ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, cmd);
-+
-+  /* Read the 'AT' from the start of the string */
-+  if (strncmp(cmd, "AT", 2)) {
-+    ast_log(LOG_WARNING, "Unknown command without 'AT': %s\n", cmd);
-+    send_atcmd_error(dev);
-+    return 0;
-+  }
-+
-+  cmd += 2;
-+
-+  // Don't forget 'AT' on it's own is OK.
-+
-+  if (strlen(cmd) == 0) {
-+    send_atcmd_ok(dev, fullcmd);
-+    return 0;
-+  }
-+
-+  for (i = 0 ; i < ATCMD_LIST_LEN ; i++) {
-+    if (strncmp(atcmd_list[i].str, cmd, strlen(atcmd_list[i].str)) == 0) {
-+      char * pos = (cmd + strlen(atcmd_list[i].str));
-+      if ((strncmp(pos, "=?", 2) == 0) && (strlen(pos) == 2)) {
-+        /* TEST command */
-+        if (atcmd_list[i].test) {
-+          if (atcmd_list[i].test(dev) == 0)
-+            send_atcmd_ok(dev, fullcmd);
-+          else
-+            send_atcmd_error(dev);
-+        } else {
-+          send_atcmd_ok(dev, fullcmd);
-+        }
-+      } else if ((strncmp(pos, "?", 1) == 0) && (strlen(pos) == 1)) {
-+        /* READ command */
-+        if (atcmd_list[i].read) {
-+          if (atcmd_list[i].read(dev) == 0)
-+            send_atcmd_ok(dev, fullcmd);
-+          else
-+            send_atcmd_error(dev);
-+        } else {
-+          ast_log(LOG_WARNING, "AT Command: '%s' missing READ function\n", fullcmd);
-+          send_atcmd_error(dev);
-+        }
-+      } else if (strncmp(pos, "=", 1) == 0) {
-+        /* SET command */
-+        if (atcmd_list[i].set) {
-+          if (atcmd_list[i].set(dev, (pos + 1), (*(pos + 1)) ? strlen(pos + 1) : 0) == 0)
-+            send_atcmd_ok(dev, fullcmd);
-+          else
-+            send_atcmd_error(dev);
-+        } else {
-+          ast_log(LOG_WARNING, "AT Command: '%s' missing SET function\n", fullcmd);
-+          send_atcmd_error(dev);
-+        }
-+      } else {
-+        /* EXECUTE command */
-+        if (atcmd_list[i].execute) {
-+          if (atcmd_list[i].execute(dev, cmd + strlen(atcmd_list[i].str)) == 0)
-+            send_atcmd_ok(dev, fullcmd);
-+          else
-+            send_atcmd_error(dev);
-+        } else {
-+          ast_log(LOG_WARNING, "AT Command: '%s' missing EXECUTE function\n", fullcmd);
-+          send_atcmd_error(dev);
-+        }
-+      }
-+      return 0;
-+    }
-+  }
-+
-+  ast_log(LOG_WARNING, "Unknown AT Command: '%s' (%s)\n", fullcmd, cmd);
-+  send_atcmd_error(dev);
-+
-+  return 0;
-+}
-+
-+/* Called when a socket is incoming */
-+
-+static void
-+handle_incoming(int fd, blt_role_t role)
-+{
-+  blt_dev_t * dev;
-+  struct sockaddr_rc addr;
-+  int len = sizeof(addr);
-+
-+  // Got a new incoming socket.
-+  ast_log(LOG_DEBUG, "Incoming RFCOMM socket\n");
-+
-+  ast_mutex_lock(&iface_lock);
-+
-+  fd = accept(fd, (struct sockaddr*)&addr, &len);
-+
-+  dev = iface_head;
-+  while (dev) {
-+    if (bacmp(&(dev->bdaddr), &addr.rc_bdaddr) == 0) {
-+      ast_log(LOG_DEBUG, "Connect from %s\n", dev->name);
-+      ast_mutex_lock(&(dev->lock));
-+      /* Kill any outstanding connect attempt. */
-+      if (dev->outgoing_id > -1) {
-+        ast_sched_del(sched, dev->outgoing_id);
-+        dev->outgoing_id = -1;
-+      }
-+
-+      rd_close(dev, 0, 0);
-+
-+      dev->status = BLT_STATUS_NEGOTIATING;
-+      dev->rd = fd;
-+
-+      if (dev->role == BLT_ROLE_AG) {
-+        dev->cb = ag_brsf_response;
-+        send_atcmd(dev, "AT+BRSF=23");
-+      }
-+
-+      ast_mutex_unlock(&(dev->lock));
-+      break;
-+    }
-+    dev = dev->next;
-+  }
-+
-+  if (dev == NULL) {
-+    ast_log(LOG_WARNING, "Connect from unknown device\n");
-+    close(fd);
-+  }
-+  ast_mutex_unlock(&iface_lock);
-+
-+  return;
-+}
-+
-+static void
-+handle_incoming_sco(int master)
-+{
-+
-+  blt_dev_t * dev;
-+  struct sockaddr_sco addr;
-+  struct sco_conninfo conn;
-+  struct sco_options opts;
-+  int len = sizeof(addr);
-+  int fd;
-+
-+  ast_log(LOG_DEBUG, "Incoming SCO socket\n");
-+
-+  fd = accept(master, (struct sockaddr*)&addr, &len);
-+
-+  if (fcntl(fd, F_SETFL, O_RDWR|O_NONBLOCK) != 0) {
-+    ast_log(LOG_ERROR, "Can't set SCO socket to NBIO\n");
-+    close(fd);
-+    return;
-+  }
-+
-+  len = sizeof(conn);
-+
-+  if (getsockopt(fd, SOL_SCO, SCO_CONNINFO, &conn, &len) < 0) {
-+    ast_log(LOG_ERROR, "Can't getsockopt SCO_CONNINFO on SCO socket: %s\n", strerror(errno));
-+    close(fd);
-+    return;
-+  }
-+
-+  len = sizeof(opts);
-+
-+  if (getsockopt(fd, SOL_SCO, SCO_OPTIONS, &opts, &len) < 0) {
-+    ast_log(LOG_ERROR, "Can't getsockopt SCO_OPTIONS on SCO socket: %s\n", strerror(errno));
-+    close(fd);
-+    return;
-+  }
-+
-+  ast_mutex_lock(&iface_lock);
-+  dev = iface_head;
-+  while (dev) {
-+    if (bacmp(&(dev->bdaddr), &addr.sco_bdaddr) == 0) {
-+      ast_log(LOG_DEBUG, "SCO Connect from %s\n", dev->name);
-+      ast_mutex_lock(&(dev->lock));
-+      if (dev->sco_running != -1) {
-+        ast_log(LOG_ERROR, "Incoming SCO socket, but SCO thread already running.\n");
-+      } else {
-+        sco_start(dev, fd);
-+      }
-+      ast_mutex_unlock(&(dev->lock));
-+      break;
-+    }
-+    dev = dev->next;
-+  }
-+
-+  ast_mutex_unlock(&iface_lock);
-+
-+  if (dev == NULL) {
-+    ast_log(LOG_WARNING, "SCO Connect from unknown device\n");
-+    close(fd);
-+  } else {
-+    // XXX:T: We need to handle the fact we might have an outgoing connection attempt in progress.
-+    ast_log(LOG_DEBUG, "SCO: %d, HCIHandle=%d, MUT=%d\n", fd, conn.hci_handle, opts.mtu);
-+  }
-+
-+
-+
-+  return;
-+}
-+
-+/* Called when there is data waiting on a socket */
-+
-+static int
-+handle_rd_data(blt_dev_t * dev)
-+{
-+  char c;
-+  int ret;
-+
-+  while ((ret = read(dev->rd, &c, 1)) == 1) {
-+
-+    // log_buf[i++] = c;
-+
-+    if (dev->role == BLT_ROLE_HS) {
-+
-+      if (c == '\r') {
-+        ret = process_rfcomm_cmd(dev, dev->rd_buff);
-+        dev->rd_buff_pos = 0;
-+        memset(dev->rd_buff, 0, BLT_RDBUFF_MAX);
-+        return ret;
-+      }
-+
-+      if (dev->rd_buff_pos >= BLT_RDBUFF_MAX)
-+        return 0;
-+
-+      dev->rd_buff[dev->rd_buff_pos++] = c;
-+
-+    } else if (dev->role == BLT_ROLE_AG) {
-+
-+      switch (dev->state) {
-+
-+        case BLT_STATE_WANT_R:
-+          if (c == '\r') {
-+            dev->state = BLT_STATE_WANT_N;
-+          } else if (c == '+') {
-+            dev->state = BLT_STATE_WANT_CMD;
-+            dev->rd_buff[dev->rd_buff_pos++] = '+';
-+          } else {
-+            ast_log(LOG_ERROR, "Device %s: Expected '\\r', got %d. state=BLT_STATE_WANT_R\n", dev->name, c);
-+            return -1;
-+          }
-+          break;
-+
-+        case BLT_STATE_WANT_N:
-+          if (c == '\n')
-+            dev->state = BLT_STATE_WANT_CMD;
-+          else {
-+            ast_log(LOG_ERROR, "Device %s: Expected '\\n', got %d. state=BLT_STATE_WANT_N\n", dev->name, c);
-+            return -1;
-+          }
-+          break;
-+
-+        case BLT_STATE_WANT_CMD:
-+          if (c == '\r')
-+            dev->state = BLT_STATE_WANT_N2;
-+          else {
-+            if (dev->rd_buff_pos >= BLT_RDBUFF_MAX) {
-+              ast_log(LOG_ERROR, "Device %s: Buffer exceeded\n", dev->name);
-+              return -1;
-+            }
-+            dev->rd_buff[dev->rd_buff_pos++] = c;
-+          }
-+          break;
-+
-+        case BLT_STATE_WANT_N2:
-+          if (c == '\n') {
-+
-+            dev->state = BLT_STATE_WANT_R;
-+
-+            if (dev->rd_buff[0] == '+') {
-+              int i;
-+              // find unsolicited
-+              for (i = 0 ; i < ATCMD_LIST_LEN ; i++) {
-+                if (strncmp(atcmd_list[i].str, dev->rd_buff, strlen(atcmd_list[i].str)) == 0) {
-+                  if (atcmd_list[i].unsolicited)
-+                    atcmd_list[i].unsolicited(dev, dev->rd_buff + strlen(atcmd_list[i].str) + 1);
-+                  else
-+                    ast_log(LOG_WARNING, "Device %s: Unhandled Unsolicited: %s\n", dev->name, dev->rd_buff);
-+                  break;
-+                }
-+              }
-+
-+              if (option_verbose)
-+                ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, dev->rd_buff);
-+
-+              if (i == ATCMD_LIST_LEN)
-+                ast_log(LOG_DEBUG, "Device %s: Got unsolicited message: %s\n", dev->name, dev->rd_buff);
-+
-+            } else {
-+
-+              if (
-+                strcmp(dev->rd_buff, "OK") != 0 && 
-+                strcmp(dev->rd_buff, "CONNECT") != 0 &&
-+                strcmp(dev->rd_buff, "RING") != 0 &&
-+                strcmp(dev->rd_buff, "NO CARRIER") != 0 && 
-+                strcmp(dev->rd_buff, "ERROR") != 0 &&
-+                strcmp(dev->rd_buff, "NO DIALTONE") != 0 && 
-+                strcmp(dev->rd_buff, "BUSY") != 0 && 
-+                strcmp(dev->rd_buff, "NO ANSWER") != 0 && 
-+                strcmp(dev->rd_buff, "DELAYED") != 0
-+              ){
-+                // It must be a multiline error
-+                strncpy(dev->last_err_cmd, dev->rd_buff, 1023);
-+                if (option_verbose)
-+                  ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, dev->rd_buff);
-+              } else if (dev->cb) {
-+                if (option_verbose)
-+                  ast_verbose(VERBOSE_PREFIX_1 "[%s] %*s > %s\n", role2str(dev->role), 10, dev->name, dev->rd_buff);
-+                dev->cb(dev, dev->rd_buff);
-+              } else {
-+                ast_log(LOG_ERROR, "Device %s: Data on socket in HS mode, but no callback\n", dev->name);
-+              }
-+
-+            }
-+
-+            dev->rd_buff_pos = 0;
-+            memset(dev->rd_buff, 0, BLT_RDBUFF_MAX);
-+
-+          } else {
-+
-+            ast_log(LOG_ERROR, "Device %s: Expected '\\n' got %d. state = BLT_STATE_WANT_N2:\n", dev->name, c);
-+            return -1;
-+
-+          }
-+
-+          break;
-+
-+        default:
-+          ast_log(LOG_ERROR, "Device %s: Unknown device state %d\n", dev->name, dev->state);
-+          return -1;
-+
-+      }
-+
-+    }
-+
-+  }
-+
-+  return 0;
-+}
-+
-+/* Close the devices RFCOMM socket, and SCO if it exists. Must hold dev->lock */
-+
-+static void
-+rd_close(blt_dev_t * dev, int reconnect, int e)
-+{
-+  dev->ready = 0;
-+
-+  if (dev->rd)
-+    close(dev->rd);
-+
-+  dev->rd = -1;
-+
-+  dev->status = BLT_STATUS_DOWN;
-+
-+  sco_stop(dev);
-+
-+  if (dev->owner) {
-+    ast_setstate(dev->owner, AST_STATE_DOWN);
-+    ast_queue_control(dev->owner, AST_CONTROL_HANGUP);
-+  }
-+
-+  /* Schedule a reconnect */
-+  if (reconnect && dev->autoconnect) {
-+    dev->outgoing_id = ast_sched_add(sched, 5000, AST_SCHED_CB(try_connect), dev);
-+
-+    if (monitor_thread == pthread_self()) {
-+      // Because we're not the monitor thread, we needd to inturrupt poll().
-+      pthread_kill(monitor_thread, SIGURG);
-+    }
-+
-+    if (e)
-+      ast_log(LOG_NOTICE, "Device %s disconnected, scheduled reconnect in 5 seconds: %s (errno %d)\n", dev->name, strerror(e), e);
-+  } else if (e) {
-+    ast_log(LOG_NOTICE, "Device %s disconnected: %s (errno %d)\n", dev->name, strerror(e), e);
-+  }
-+
-+  return;
-+}
-+
-+/*
-+ * Remember that we can only add to the scheduler from
-+ * the do_monitor thread, as it calculates time to next one from
-+ * this loop.
-+ */
-+
-+static void *
-+do_monitor(void * data)
-+{
-+#define SRV_SOCK_CNT 3
-+
-+  int res = 0;
-+  blt_dev_t * dev;
-+  struct pollfd * pfds = malloc(sizeof(struct pollfd) * (ifcount + SRV_SOCK_CNT));
-+
-+  /* -- We start off by trying to connect all of our devices (non blocking) -- */
-+
-+  monitor_pid = getpid();
-+
-+  if (ast_mutex_lock(&iface_lock)) {
-+    ast_log(LOG_ERROR, "Failed to get iface_lock.\n");
-+    return NULL;
-+  }
-+
-+  dev = iface_head;
-+  while (dev) {
-+
-+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, dev->sco_pipe) != 0) {
-+      ast_log(LOG_ERROR, "Failed to create socket pair: %s (errno %d)\n", strerror(errno), errno);
-+      ast_mutex_unlock(&iface_lock);
-+      return NULL;
-+    }
-+
-+    if (dev->autoconnect && dev->status == BLT_STATUS_DOWN)
-+      dev->outgoing_id = ast_sched_add(sched, 1500, AST_SCHED_CB(try_connect), dev);
-+    dev = dev->next;
-+  }
-+  ast_mutex_unlock(&iface_lock);
-+
-+  /* -- Now, Scan all sockets, and service scheduler -- */
-+
-+  pfds[0].fd = rfcomm_sock_ag;
-+  pfds[0].events = POLLIN;
-+
-+  pfds[1].fd = rfcomm_sock_hs;
-+  pfds[1].events = POLLIN;
-+
-+  pfds[2].fd = sco_socket;
-+  pfds[2].events = POLLIN;
-+
-+  while (1) {
-+    int cnt = SRV_SOCK_CNT;
-+    int i;
-+
-+    /* -- Build pfds -- */
-+
-+    if (ast_mutex_lock(&iface_lock)) {
-+      ast_log(LOG_ERROR, "Failed to get iface_lock.\n");
-+      return NULL;
-+    }
-+    dev = iface_head;
-+    while (dev) {
-+      ast_mutex_lock(&(dev->lock));
-+      if (dev->rd > 0 && ((dev->status != BLT_STATUS_DOWN) && (dev->status != BLT_STATUS_CONNECTING))) {
-+        pfds[cnt].fd = dev->rd;
-+        pfds[cnt].events = POLLIN;
-+        cnt++;
-+      }
-+      ast_mutex_unlock(&(dev->lock));
-+      dev = dev->next;
-+    }
-+    ast_mutex_unlock(&iface_lock);
-+
-+    /* -- End Build pfds -- */
-+
-+    res = ast_sched_wait(sched);
-+    res = poll(pfds, cnt, MAX(100, MIN(100, res)));
-+
-+    if (res == 0)
-+      ast_sched_runq(sched);
-+
-+    if (pfds[0].revents) {
-+      handle_incoming(rfcomm_sock_ag, BLT_ROLE_AG);
-+      res--;
-+    }
-+
-+    if (pfds[1].revents) {
-+      handle_incoming(rfcomm_sock_hs, BLT_ROLE_HS);
-+      res--;
-+    }
-+
-+    if (pfds[2].revents) {
-+      handle_incoming_sco(sco_socket);
-+      res--;
-+    }
-+
-+    if (res == 0)
-+      continue;
-+
-+    for (i = SRV_SOCK_CNT ; i < cnt ; i++) {
-+
-+      /* Optimise a little bit */
-+      if (res == 0)
-+        break;
-+      else if (pfds[i].revents == 0)
-+        continue;
-+
-+      /* -- Find the socket that has activity -- */
-+
-+      if (ast_mutex_lock(&iface_lock)) {
-+        ast_log(LOG_ERROR, "Failed to get iface_lock.\n");
-+        return NULL;
-+      }
-+
-+      dev = iface_head;
-+
-+      while (dev) {
-+        if (pfds[i].fd == dev->rd) {
-+          ast_mutex_lock(&(dev->lock));
-+          if (pfds[i].revents & POLLIN) {
-+            if (handle_rd_data(dev) == -1) {
-+              rd_close(dev, 0, 0);
-+            }
-+          } else {
-+            rd_close(dev, 1, sock_err(dev->rd));
-+          }
-+          ast_mutex_unlock(&(dev->lock));
-+          res--;
-+          break;
-+        }
-+        dev = dev->next;
-+      }
-+
-+      if (dev == NULL) {
-+        ast_log(LOG_ERROR, "Unhandled fd from poll()\n");
-+        close(pfds[i].fd);
-+      }
-+
-+      ast_mutex_unlock(&iface_lock);
-+
-+      /* -- End find socket with activity -- */
-+
-+    }
-+
-+  }
-+
-+  return NULL;
-+}
-+
-+static int
-+restart_monitor(void)
-+{
-+
-+  if (monitor_thread == AST_PTHREADT_STOP)
-+    return 0;
-+
-+  if (ast_mutex_lock(&monitor_lock)) {
-+    ast_log(LOG_WARNING, "Unable to lock monitor\n");
-+    return -1;
-+  }
-+
-+  if (monitor_thread == pthread_self()) {
-+    ast_mutex_unlock(&monitor_lock);
-+    ast_log(LOG_WARNING, "Cannot kill myself\n");
-+    return -1;
-+  }
-+
-+  if (monitor_thread != AST_PTHREADT_NULL) {
-+
-+    /* Just signal it to be sure it wakes up */
-+    pthread_cancel(monitor_thread);
-+    pthread_kill(monitor_thread, SIGURG);
-+    ast_log(LOG_DEBUG, "Waiting for monitor thread to join...\n");
-+    pthread_join(monitor_thread, NULL);
-+    ast_log(LOG_DEBUG, "joined\n");
-+
-+  } else {
-+
-+    /* Start a new monitor */
-+    if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
-+      ast_mutex_unlock(&monitor_lock);
-+      ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
-+      return -1;
-+    }
-+
-+  }
-+
-+  ast_mutex_unlock(&monitor_lock);
-+  return 0;
-+}
-+
-+static int
-+blt_parse_config(void)
-+{
-+  struct ast_config * cfg;
-+  struct ast_variable * v;
-+  char * cat;
-+
-+  cfg = ast_load(BLT_CONFIG_FILE);
-+
-+  if (!cfg) {
-+    ast_log(LOG_NOTICE, "Unable to load Bluetooth config: %s.  Bluetooth disabled\n", BLT_CONFIG_FILE);
-+    return -1;
-+  }
-+
-+  v = ast_variable_browse(cfg, "general");
-+
-+  while (v) {
-+    if (!strcasecmp(v->name, "rfchannel_ag")) {
-+      rfcomm_channel_ag = atoi(v->value);
-+    } else if (!strcasecmp(v->name, "rfchannel_hs")) {
-+      rfcomm_channel_hs = atoi(v->value);
-+    } else if (!strcasecmp(v->name, "interface")) {
-+      hcidev_id = atoi(v->value);
-+    } else {
-+      ast_log(LOG_WARNING, "Unknown config key '%s' in section [general]\n", v->name);
-+    }
-+    v = v->next;
-+  }
-+  cat = ast_category_browse(cfg, NULL);
-+
-+  while(cat) {
-+
-+    char * str;
-+
-+    if (strcasecmp(cat, "general")) {
-+      blt_dev_t * device = malloc(sizeof(blt_dev_t));
-+      memset(device, 0, sizeof(blt_dev_t));
-+      device->sco_running = -1;
-+      device->sco = -1;
-+      device->rd = -1;
-+      device->outgoing_id = -1;
-+      device->status = BLT_STATUS_DOWN;
-+      str2ba(cat, &(device->bdaddr));
-+      device->name = ast_variable_retrieve(cfg, cat, "name");
-+
-+      str = ast_variable_retrieve(cfg, cat, "type");
-+
-+      if (str == NULL) {
-+        ast_log(LOG_ERROR, "Device [%s] has no role.  Specify type=<HS/AG>\n", cat);
-+        return -1;
-+      } else if (strcasecmp(str, "HS") == 0)
-+        device->role = BLT_ROLE_HS;
-+      else if (strcasecmp(str, "AG") == 0) {
-+        device->role = BLT_ROLE_AG;
-+      } else {
-+        ast_log(LOG_ERROR, "Device [%s] has invalid role '%s'\n", cat, str);
-+        return -1;
-+      }
-+
-+      /* XXX:T: Find channel to use using SDP.
-+       *        However, this needs to be non blocking, and I can't see
-+       *        anything in sdp_lib.h that will allow non blocking calls.
-+       */
-+
-+      device->channel = 1;
-+
-+      if ((str = ast_variable_retrieve(cfg, cat, "channel")) != NULL)
-+        device->channel = atoi(str);
-+
-+      if ((str = ast_variable_retrieve(cfg, cat, "autoconnect")) != NULL)
-+        device->autoconnect = (strcasecmp(str, "yes") == 0 || strcmp(str, "1") == 0) ? 1 : 0;
-+
-+      device->next = iface_head;
-+      iface_head = device;
-+      ifcount++;
-+    }
-+
-+    cat = ast_category_browse(cfg, cat);
-+  }
-+  return 0;
-+}
-+
-+
-+static int
-+blt_show_peers(int fd, int argc, char *argv[])
-+{
-+  blt_dev_t * dev;
-+
-+  if (ast_mutex_lock(&iface_lock)) {
-+    ast_log(LOG_ERROR, "Failed to get Iface lock\n");
-+    ast_cli(fd, "Failed to get iface lock\n");
-+    return RESULT_FAILURE;
-+  }
-+
-+  dev = iface_head;
-+
-+  ast_cli(fd, "BDAddr            Name       Role Status      A/C SCOCon/Fd/Th Sig\n");
-+  ast_cli(fd, "----------------- ---------- ---- ----------- --- ------------ ---\n");
-+
-+  while (dev) {
-+    char b1[18];
-+    ba2str(&(dev->bdaddr), b1);
-+    ast_cli(fd, "%s %-10s %-4s %-11s %-3s %2d/%02d/%-6ld %s\n",
-+                b1, dev->name, (dev->role == BLT_ROLE_HS) ? "HS" : "AG", status2str(dev->status),
-+                (dev->autoconnect) ? "Yes" : "No",
-+                dev->sco_running,
-+                dev->sco,
-+                dev->sco_thread,
-+                (dev->role == BLT_ROLE_AG) ? (dev->service) ? "Yes" : "No" : "N/A"
-+            );
-+    dev = dev->next;
-+  }
-+
-+  ast_mutex_unlock(&iface_lock);
-+  return RESULT_SUCCESS;
-+}
-+
-+static int
-+blt_show_information(int fd, int argc, char *argv[])
-+{
-+  char b1[18];
-+  ba2str(&local_bdaddr, b1);
-+  ast_cli(fd, "-------------------------------------------\n");
-+  ast_cli(fd, "       Version : %s\n", BLT_SVN_REVISION);
-+  ast_cli(fd, "   Monitor PID : %d\n", monitor_pid);
-+  ast_cli(fd, "     RFCOMM AG : Channel %d, FD %d\n", rfcomm_channel_ag, rfcomm_sock_ag);
-+  ast_cli(fd, "     RFCOMM HS : Channel %d, FD %d\n", rfcomm_channel_hs, rfcomm_sock_hs);
-+  ast_cli(fd, "        Device : hci%d, MAC Address %s\n", hcidev_id, b1);
-+  ast_cli(fd, "-------------------------------------------\n");
-+  return RESULT_SUCCESS;
-+}
-+
-+static int
-+blt_ag_sendcmd(int fd, int argc, char *argv[])
-+{
-+  blt_dev_t * dev;
-+
-+  if (argc != 4)
-+    return RESULT_SHOWUSAGE;
-+
-+  ast_mutex_lock(&iface_lock);
-+  dev = iface_head;
-+  while (dev) {
-+    if (!strcasecmp(argv[2], dev->name))
-+      break;
-+    dev = dev->next;
-+  }
-+  ast_mutex_unlock(&iface_lock);
-+
-+  if (!dev) {
-+    ast_cli(fd, "Device '%s' does not exist\n", argv[2]);
-+    return RESULT_FAILURE;
-+  }
-+
-+  if (dev->role != BLT_ROLE_AG) {
-+    ast_cli(fd, "Device '%s' is not an AudioGateway\n", argv[2]);
-+    return RESULT_FAILURE;
-+  }
-+
-+  if (dev->status == BLT_STATUS_DOWN || dev->status == BLT_STATUS_NEGOTIATING) {
-+    ast_cli(fd, "Device '%s' is not connected\n", argv[2]);
-+    return RESULT_FAILURE;
-+  }
-+
-+  if (*(argv[3] + strlen(argv[3]) - 1) == '.')
-+    *(argv[3] + strlen(argv[3]) - 1) = '?';
-+
-+  ast_cli(fd, "Sending AT command to %s: %s\n", dev->name, argv[3]);
-+
-+  ast_mutex_lock(&(dev->lock));
-+  send_atcmd(dev, argv[3]);
-+  ast_mutex_unlock(&(dev->lock));
-+
-+  return RESULT_SUCCESS;
-+}
-+
-+static char *
-+complete_device(char * line, char * word, int pos, int state, int rpos, blt_role_t role)
-+{
-+  blt_dev_t * dev;
-+  int which = 0;
-+  char *ret;
-+
-+  if (pos != rpos)
-+    return NULL;
-+
-+  ast_mutex_lock(&iface_lock);
-+
-+  dev = iface_head;
-+
-+  while (dev) {
-+
-+    if ((dev->role == role) && (!strncasecmp(word, dev->name, strlen(word)))) {
-+      if (++which > state)
-+        break;
-+    }
-+
-+    dev = dev->next;
-+  }
-+
-+  if (dev)
-+    ret = strdup(dev->name);
-+  else
-+    ret = NULL;
-+
-+  ast_mutex_unlock(&iface_lock);
-+
-+  return ret;
-+}
-+
-+static char *
-+complete_device_2_ag(char * line, char * word, int pos, int state)
-+{
-+  return complete_device(line, word, pos, state, 2, BLT_ROLE_AG);
-+}
-+
-+static char show_peers_usage[] =
-+"Usage: bluetooth show peers\n"
-+"       List all bluetooth peers and their status\n";
-+
-+static struct ast_cli_entry
-+cli_show_peers =
-+    { { "bluetooth", "show", "peers", NULL }, blt_show_peers, "List Bluetooth Peers", show_peers_usage };
-+
-+
-+static char ag_sendcmd[] =
-+"Usage: bluetooth ag <device> sendcmd <cmd>\n"
-+"       Sends a AT cmd over the RFCOMM link, and print result (AG only)\n";
-+
-+static struct ast_cli_entry
-+cli_ag_sendcmd =
-+    { { "bluetooth", "sendcmd", NULL }, blt_ag_sendcmd, "Send AG an AT command", ag_sendcmd, complete_device_2_ag };
-+
-+static char show_information[] =
-+"Usage: bluetooth show information\n"
-+"       Lists information about the bluetooth subsystem\n";
-+
-+static struct ast_cli_entry
-+cli_show_information =
-+    { { "bluetooth", "show", "information", NULL }, blt_show_information, "List Bluetooth Info", show_information };
-+
-+void
-+remove_sdp_records(void)
-+{
-+
-+  sdp_session_t * sdp;
-+  sdp_list_t * attr;
-+  sdp_record_t * rec;
-+  int res = -1;
-+  uint32_t range = 0x0000ffff;
-+
-+  if (sdp_record_ag == -1 || sdp_record_hs == -1)
-+    return;
-+
-+  ast_log(LOG_DEBUG, "Removing SDP records\n");
-+
-+  sdp = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
-+
-+  if (!sdp)
-+    return;
-+
-+  attr = sdp_list_append(0, &range);
-+  rec = sdp_service_attr_req(sdp, sdp_record_ag, SDP_ATTR_REQ_RANGE, attr);
-+  sdp_list_free(attr, 0);
-+
-+  if (rec)
-+    if (sdp_record_unregister(sdp, rec) == 0)
-+      res = 0;
-+
-+  attr = sdp_list_append(0, &range);
-+  rec = sdp_service_attr_req(sdp, sdp_record_hs, SDP_ATTR_REQ_RANGE, attr);
-+  sdp_list_free(attr, 0);
-+
-+  if (rec)
-+    if (sdp_record_unregister(sdp, rec) == 0)
-+      res = 0;
-+
-+  sdp_close(sdp);
-+
-+  if (res == 0)
-+    ast_log(LOG_NOTICE, "Removed SDP records\n");
-+  else
-+    ast_log(LOG_ERROR, "Failed to remove SDP records\n");
-+
-+}
-+
-+static int
-+__unload_module(void)
-+{
-+
-+  ast_channel_unregister(BLT_CHAN_NAME);
-+
-+  if (monitor_thread != AST_PTHREADT_NULL) {
-+
-+    if (ast_mutex_lock(&monitor_lock)) {
-+
-+      if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
-+        pthread_cancel(monitor_thread);
-+        pthread_kill(monitor_thread, SIGURG);
-+        fprintf(stderr, "Waiting for monitor thread to join...\n");
-+        pthread_join(monitor_thread, NULL);
-+        fprintf(stderr, "joined\n");
-+      }
-+      monitor_thread = AST_PTHREADT_STOP;
-+      ast_mutex_unlock(&monitor_lock);
-+
-+    } else {
-+
-+      ast_log(LOG_WARNING, "Unable to lock the monitor\n");
-+      return -1;
-+
-+    }
-+
-+  }
-+
-+  ast_unregister_atexit(remove_sdp_records);
-+  remove_sdp_records();
-+  return 0;
-+}
-+
-+int
-+load_module()
-+{
-+  sdp_session_t * sess;
-+  int dd;
-+  uint16_t vs;
-+
-+  hcidev_id = BLT_DEFAULT_HCI_DEV;
-+
-+  if (blt_parse_config() != 0) {
-+    ast_log(LOG_ERROR, "Bluetooth configuration error.  Bluetooth Disabled\n");
-+    return unload_module();
-+  }
-+
-+  dd  = hci_open_dev(hcidev_id);
-+  if (dd == -1) {
-+    ast_log(LOG_ERROR, "Unable to open interface hci%d: %s.\n", hcidev_id, strerror(errno));
-+    return -1;
-+  }
-+
-+  hci_read_voice_setting(dd, &vs, 1000);
-+  vs = htobs(vs);
-+  close(dd);
-+
-+  if (vs != 0x0060) {
-+    ast_log(LOG_ERROR, "Bluetooth voice setting must be 0x0060, not 0x%04x\n", vs);
-+    unload_module();
-+    return 0;
-+  }
-+
-+  if ((sched = sched_context_create()) == NULL) {
-+    ast_log(LOG_WARNING, "Unable to create schedule context\n");
-+    return -1;
-+  }
-+
-+  memset(&local_bdaddr, 0, sizeof(local_bdaddr));
-+
-+  hci_devba(hcidev_id, &local_bdaddr);
-+
-+  /* --- Add SDP record --- */
-+
-+  sess = sdp_connect(&local_bdaddr, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
-+
-+  if ((rfcomm_sock_ag = rfcomm_listen(&local_bdaddr, rfcomm_channel_ag)) < 0) {
-+    return -1;
-+  }
-+
-+  if ((rfcomm_sock_hs = rfcomm_listen(&local_bdaddr, rfcomm_channel_hs)) < 0)
-+    return -1;
-+
-+  if ((sco_socket = sco_listen(&local_bdaddr)) < 0)
-+    return -1;
-+
-+  if (!sess) {
-+    ast_log(LOG_ERROR, "Failed to connect to SDP server: %s\n", strerror(errno));
-+    return -1;
-+  }
-+
-+  if (sdp_register(sess) != 0) {
-+    ast_log(LOG_ERROR, "Failed to register HeadsetAudioGateway in SDP\n");
-+    return -1;
-+  }
-+
-+  sdp_close(sess);
-+
-+  if (restart_monitor() != 0)
-+    return -1;
-+
-+  if (ast_channel_register(BLT_CHAN_NAME, "Bluetooth Driver", BLUETOOTH_FORMAT, blt_request)) {
-+    ast_log(LOG_ERROR, "Unable to register channel class BTL\n");
-+    __unload_module();
-+    return -1;
-+  }
-+
-+  ast_cli_register(&cli_show_information);
-+  ast_cli_register(&cli_show_peers);
-+  ast_cli_register(&cli_ag_sendcmd);
-+
-+  ast_register_atexit(remove_sdp_records);
-+
-+  ast_log(LOG_NOTICE, "Loaded Bluetooth support, %s\n", BLT_SVN_REVISION + 1);
-+
-+  return 0;
-+}
-+
-+int
-+unload_module(void)
-+{
-+  ast_cli_unregister(&cli_ag_sendcmd);
-+  ast_cli_unregister(&cli_show_peers);
-+  ast_cli_unregister(&cli_show_information);
-+  return __unload_module();
-+}
-+
-+int
-+usecount()
-+{
-+  int res;
-+  ast_mutex_lock(&usecnt_lock);
-+  res = usecnt;
-+  ast_mutex_unlock(&usecnt_lock);
-+  return res;
-+}
-+
-+char *description()
-+{
-+  return "Bluetooth Channel Driver";
-+}
-+
-+char *
-+key()
-+{
-+  return ASTERISK_GPL_KEY;
-+}
-+
-+
-diff -urN asterisk-1.4.0-beta3-o-o/configs/bluetooth.conf.sample asterisk-1.4.0-beta3/configs/bluetooth.conf.sample
---- asterisk-1.4.0-beta3-o-o/configs/bluetooth.conf.sample     1969-12-31 17:00:00.000000000 -0700
-+++ asterisk-1.4.0-beta3/configs/bluetooth.conf.sample 2006-11-06 12:44:39.000000000 -0700
-@@ -0,0 +1,33 @@
-+[general]
-+; Channel we listen on as a HS (Headset)
-+rfchannel_hs = 2
-+; Channel we listen on as an AG (AudioGateway)
-+rfchannel_ag = 3
-+; hci interface to use (number - e.g '0')
-+interface = 0
-+
-+;; A HBH-500 Handsfree Kit
-+[00:0A:D9:A1:AA:D2]
-+; Any name to use, this is what we use to send calls to (BLT/<name>).
-+name        = HBH-500
-+; IS this a HS or AG?
-+type        = HS
-+;
-+;
-+; RFCOMM channel to connect to.  For a HandsSet:
-+;    sdptool search --bdaddr xx:xx:xx:xx:xx:xx 0x111E
-+; or,for an AudioGateway (Phone):
-+;    sdptool search --bdaddr xx:xx:xx:xx:xx:xx 0x111F
-+;
-+; Find the 'channel' value under RFCOMM.
-+;
-+channel     = 2
-+; Automatically conenct?
-+autoconnect = yes
-+
-+;; A Nokia 6310i
-+[00:60:57:1C:00:99]
-+name        = Neil
-+type        = AG
-+channel     = 13
-+autoconnect = yes
-diff -urN asterisk-1.4.0-beta3-o-o/configure.ac asterisk-1.4.0-beta3/configure.ac
---- asterisk-1.4.0-beta3-o-o/configure.ac      2006-10-13 09:41:14.000000000 -0600
-+++ asterisk-1.4.0-beta3/configure.ac  2006-11-06 12:44:39.000000000 -0700
-@@ -152,6 +152,7 @@
- # by the --with option name, to make things easier for the users :-)
- AST_EXT_LIB_SETUP([ALSA], [Advanced Linux Sound Architecture], [asound])
-+AST_EXT_LIB_SETUP([BLUETOOTH], [Bluetooth], [bluetooth])
- AST_EXT_LIB_SETUP([CURL], [cURL], [curl])
- AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
- AST_EXT_LIB_SETUP([GNUTLS], [GNU TLS support (used for iksemel only)], [gnutls])
-@@ -314,6 +315,8 @@
- AST_EXT_LIB_CHECK([ALSA], [asound], [snd_spcm_init], [alsa/asoundlib.h], [-lm -ldl])
-+AST_EXT_LIB_CHECK([BLUETOOTH], [bluetooth], [bt_malloc], [bluetooth/bluetooth.h])
-+
- AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h])
- GSM_INTERNAL="yes"
-diff -urN asterisk-1.4.0-beta3-o-o/makeopts.in asterisk-1.4.0-beta3/makeopts.in
---- asterisk-1.4.0-beta3-o-o/makeopts.in       2006-09-19 08:04:15.000000000 -0600
-+++ asterisk-1.4.0-beta3/makeopts.in   2006-11-06 12:44:39.000000000 -0700
-@@ -157,3 +157,6 @@
- SUPPSERV_INCLUDE=@SUPPSERV_INCLUDE@
- SUPPSERV_LIB=@SUPPSERV_LIB@
-+
-+BLUETOOTH_INCLUDE=@BLUETOOTH_INCLUDE@
-+BLUETOOTH_LIB=@BLUETOOTH_LIB@
index dac28673fa46fc636c39e5457d31d35e9f0a5964..f0bb9c86514c4980f8ba6015891034486183ad0c 100644 (file)
@@ -2,7 +2,6 @@
 # - cgi-bin package - separate, because of suid-root
 # - use shared versions of LIBILBC:=ilbc/libilbc.a (ilbc not enabled currently)
 # - CFLAGS passing
-# - fix bluetooth patch
 # - make package for moh sound files
 # - likely odbc and imap broken (identical code, some #define not working, etc):
 #   *** WARNING: identical binaries are copied, not linked:
@@ -24,7 +23,6 @@
 #
 # Conditional build:
 %bcond_with    rxfax           # without rx (also tx:-D) fax
-%bcond_with    bluetooth       # without bluetooth support (NFT)
 %bcond_with    zhone           # zhone hack
 %bcond_with    zhone_hack      # huge hack workarounding broken zhone channel banks which start randomly
                                # issuing pulse-dialled calls to weird numbers
 %bcond_without verbose         # verbose build
 
 %define                spandsp_version 0.0.2pre26
-%define                rel     1       
+%define                rel     1
 Summary:       Asterisk PBX
 Summary(pl.UTF-8):     Centralka (PBX) Asterisk
 Name:          asterisk
-Version:       1.8.7.2
+Version:       10.0.1
 Release:       %{rel}%{?with_bristuff:.bristuff}
 License:       GPL v2
 Group:         Applications/System
 Source0:       http://downloads.digium.com/pub/asterisk/releases/%{name}-%{version}.tar.gz
-# Source0-md5: 27ab62d75be35e623e4798d58a0959fc
+# Source0-md5: b8eaff7832fe46fc764030ed46df617c
 Source1:       %{name}.init
 Source2:       %{name}.sysconfig
 Source5:       %{name}.logrotate
 Source10:      app_txfax.c
 Source11:      app_rxfax.c
+# menuselect.* -> make menuconfig; choose options; copy resulting files here
+Source12:      menuselect.makedeps
+Source13:      menuselect.makeopts
 Patch0:                mxml-system.patch
 Patch1:                lua51-path.patch
 Patch2:                %{name}-no_k6_on_sparc.patch
@@ -62,7 +63,6 @@ Patch8:               libedit-history.patch
 Patch9:                pld-banner.patch
 # http://soft-switch.org/downloads/spandsp/spandsp-%{spandsp_version}/asterisk-1.2.x/apps_Makefile.patch
 Patch10:       %{name}-txfax-Makefile.patch
-Patch11:       %{name}-chan_bluetooth.patch
 Patch12:       %{name}-zhone.patch
 # http://svn.debian.org/wsvn/pkg-voip/asterisk/trunk/debian/patches/bristuff
 Patch13:       %{name}-bristuff.patch
@@ -78,7 +78,7 @@ BuildRequires:        alsa-lib-devel
 BuildRequires: autoconf
 BuildRequires: automake
 BuildRequires: bison
-%{?with_bluetooth:BuildRequires: bluez-devel}
+BuildRequires: bluez-libs-devel
 BuildRequires: curl-devel
 BuildRequires: dahdi-linux-devel
 BuildRequires: dahdi-tools-devel >= 2.0.0
@@ -557,7 +557,6 @@ cd apps
 cp %{SOURCE10} .
 cp %{SOURCE11} .
 %endif
-%{?with_bluetooth:%patch11 -p1}
 %{?with_zhonehack:%patch12 -p1}
 %if %{with bristuff}
 %patch13 -p1
@@ -575,6 +574,13 @@ cp %{SOURCE11} .
 # avoid using these
 rm -rf imap menuselect/mxml main/editline codecs/gsm codecs/lpc10
 
+install %{SOURCE12} .
+install %{SOURCE13} .
+
+%if %{without h323}
+sed -i -e 's#\(MENUSELECT_ADDONS=.*\)#\1 chan_ooh323#g' menuselect.makeopts
+%endif
+
 %build
 rm -f pbx/.depend
 
@@ -612,12 +618,6 @@ cd ..
 
 cp -f .cleancount .lastclean
 
-%if %{with h323}
-# included conditionally, so make sure its there first
-%{__make} -C channels/h323 Makefile.ast \
-       %{?with_verbose:NOISY_BUILD=yes} \
-%endif
-
 %{__make} DEBUG= \
        OPTIMIZE= \
        ASTVARRUNDIR=%{_localstatedir}/run/asterisk \
@@ -671,27 +671,6 @@ touch apps/app_voicemail.so apps/app_directory.so
        %{?with_verbose:NOISY_BUILD=yes} \
 %endif
 
-%{__make} \
-       DEBUG= \
-       OPTIMIZE= \
-       ASTVARRUNDIR=%{_localstatedir}/run/asterisk \
-       ASTDATADIR=%{_datadir}/asterisk \
-       ASTVARLIBDIR=%{_datadir}/asterisk \
-       ASTDBDIR=%{_localstatedir}/spool/asterisk \
-       %{?with_verbose:NOISY_BUILD=yes} \
-       CHANNEL_LIBS+=chan_bluetooth.so || :
-
-# rerun needed; asterisk wants that
-%{__make} \
-       DEBUG= \
-       OPTIMIZE= \
-       ASTVARRUNDIR=%{_localstatedir}/run/asterisk \
-       ASTDATADIR=%{_datadir}/asterisk \
-       ASTVARLIBDIR=%{_datadir}/asterisk \
-       ASTDBDIR=%{_localstatedir}/spool/asterisk \
-       %{?with_verbose:NOISY_BUILD=yes} \
-       CHANNEL_LIBS+=chan_bluetooth.so
-
 # safe checks
 %{?with_bristuff:objdump -p channels/chan_zap.so | grep -qE 'NEEDED +libgsmat\.so' || exit 1}
 
@@ -768,7 +747,7 @@ find doc/api/html -name '*.map' -size 0 -delete
 %endif
 
 #fixme
-rm  $RPM_BUILD_ROOT/etc/asterisk/{app_mysql,cdr_mysql,chan_mobile,chan_ooh323,misdn%{!?with_h323:,h323},res_config_mysql,res_pktccops}.conf
+rm  $RPM_BUILD_ROOT/etc/asterisk/{app_mysql,cdr_mysql,chan_mobile,misdn%{!?with_h323:,chan_ooh323},res_pktccops,h323}.conf
 
 rm -fr $RPM_BUILD_ROOT/usr/include/asterisk/doxygen
 
@@ -810,6 +789,8 @@ chown -R asterisk:asterisk /var/lib/asterisk
 
 #%attr(755,root,root) %{_sbindir}/aelparse
 %attr(755,root,root) %{_sbindir}/astcanary
+%attr(755,root,root) %{_sbindir}/astdb2bdb
+%attr(755,root,root) %{_sbindir}/astdb2sqlite3
 %attr(755,root,root) %{_sbindir}/asterisk
 %attr(755,root,root) %{_sbindir}/astgenkey
 %attr(755,root,root) %{_sbindir}/autosupport
@@ -848,6 +829,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/cli_aliases.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/cli_permissions.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/codecs.conf
+%attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/confbridge.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/dnsmgr.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/dsp.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/dundi.conf
@@ -870,6 +852,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/phoneprov.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/queuerules.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/queues.conf
+%attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/res_config_mysql.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/res_stun_monitor.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/rpt.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/rtp.conf
@@ -923,12 +906,10 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_queue.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_read.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_readexten.so
-%attr(755,root,root) %{_libdir}/asterisk/modules/app_readfile.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_record.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_sayunixtime.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_senddtmf.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_sendtext.so
-%attr(755,root,root) %{_libdir}/asterisk/modules/app_setcallerid.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_sms.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_softhangup.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_speech_utils.so
@@ -960,6 +941,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(755,root,root) %{_libdir}/asterisk/modules/chan_bridge.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/chan_iax2.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/chan_local.so
+%attr(755,root,root) %{_libdir}/asterisk/modules/chan_mobile.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/chan_mgcp.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/chan_multicast_rtp.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/chan_phone.so
@@ -982,7 +964,6 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(755,root,root) %{_libdir}/asterisk/modules/format_siren14.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/format_siren7.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/format_sln.so
-%attr(755,root,root) %{_libdir}/asterisk/modules/format_sln16.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/format_vox.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/format_wav.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_aes.so
@@ -1006,6 +987,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_global.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_groupcount.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_iconv.so
+%attr(755,root,root) %{_libdir}/asterisk/modules/func_jitterbuffer.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_lock.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_logic.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/func_math.so
@@ -1038,10 +1020,13 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_calendar_ews.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_calendar_exchange.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_calendar_icalendar.so
+%attr(755,root,root) %{_libdir}/asterisk/modules/res_config_mysql.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_clialiases.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_clioriginate.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_convert.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_crypto.so
+%attr(755,root,root) %{_libdir}/asterisk/modules/res_format_attr_celt.so
+%attr(755,root,root) %{_libdir}/asterisk/modules/res_format_attr_silk.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_limit.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_monitor.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_mutestream.so
@@ -1133,7 +1118,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %defattr(644,root,root,755)
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/meetme.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/chan_dahdi.conf
-%attr(755,root,root) %{_libdir}/asterisk/modules/app_dahdibarge.so
+#%attr(755,root,root) %{_libdir}/asterisk/modules/app_dahdibarge.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_dahdiras.so
 #%attr(755,root,root) %{_libdir}/asterisk/modules/app_dahdiscan.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/app_flash.so
@@ -1168,8 +1153,8 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %if %{with h323}
 %files h323
 %defattr(644,root,root,755)
-%attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/h323.conf
-%attr(755,root,root) %{_libdir}/asterisk/modules/chan_h323.so
+%attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/chan_ooh323.conf
+%attr(755,root,root) %{_libdir}/asterisk/modules/chan_ooh323.so
 %endif
 
 %files http
@@ -1298,7 +1283,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/cel_sqlite3_custom.conf
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/res_config_sqlite.conf
 %attr(755,root,root) %{_libdir}/asterisk/modules/cdr_sqlite3_custom.so
-%attr(755,root,root) %{_libdir}/asterisk/modules/cdr_sqlite.so
+#%attr(755,root,root) %{_libdir}/asterisk/modules/cdr_sqlite.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/cel_sqlite3_custom.so
 %attr(755,root,root) %{_libdir}/asterisk/modules/res_config_sqlite.so
 
@@ -1317,7 +1302,7 @@ chown -R asterisk:asterisk /var/lib/asterisk
 %files usbradio
 %defattr(644,root,root,755)
 %attr(640,root,asterisk) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/asterisk/usbradio.conf
-#%attr(755,root,root) %{_libdir}/asterisk/modules/chan_usbradio.so
+%attr(755,root,root) %{_libdir}/asterisk/modules/chan_usbradio.so
 
 %files voicemail
 %defattr(644,root,root,755)
index 174382bf342b93100668589987d221b242a7f35b..c70a7a5b66c8f282a22b5712f166562ce2e536ff 100644 (file)
@@ -77,17 +77,17 @@ Index: configure.ac
  
  $(OBJS): _ASTCFLAGS+=-DAST_MODULE=\"core\"
  
--$(MAIN_TGT): $(OBJS) editline/libedit.a db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS)
-+$(MAIN_TGT): $(OBJS) $(LIBEDIT_OBJ) db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS)
+-$(MAIN_TGT): $(OBJS) editline/libedit.a $(AST_EMBED_LDSCRIPTS)
++$(MAIN_TGT): $(OBJS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS)
        @$(CC) -c -o buildinfo.o $(_ASTCFLAGS) buildinfo.c $(ASTCFLAGS)
--      $(ECHO_PREFIX) echo "   [LD] $(OBJS) editline/libedit.a db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) -> $@"
-+      $(ECHO_PREFIX) echo "   [LD] $(OBJS) $(LIBEDIT_OBJ) db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) -> $@"
+-      $(ECHO_PREFIX) echo "   [LD] $(OBJS) editline/libedit.a $(AST_EMBED_LDSCRIPTS) -> $@"
++      $(ECHO_PREFIX) echo "   [LD] $(OBJS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS) -> $@"
  ifneq ($(findstring chan_h323,$(MENUSELECT_CHANNELS)),)
--      $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(OBJS) editline/libedit.a db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(GMIMELDFLAGS)
-+      $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(OBJS) $(LIBEDIT_OBJ) db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(GMIMELDFLAGS) $(LIBEDIT_LIB)
+-      $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(OBJS) editline/libedit.a $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(GMIMELDFLAGS)
++      $(CMD_PREFIX) $(CC) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(OBJS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(GMIMELDFLAGS) $(LIBEDIT_LIB)
  else
--      $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $(OBJS) editline/libedit.a db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS) $(GMIMELDFLAGS)
-+      $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $(OBJS) $(LIBEDIT_OBJ) db1-ast/libdb1.a $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS) $(GMIMELDFLAGS) $(LIBEDIT_LIB)
+-      $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $(OBJS) editline/libedit.a $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS) $(GMIMELDFLAGS)
++      $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(ASTLINK) $(AST_EMBED_LDFLAGS) $(_ASTLDFLAGS) $(ASTLDFLAGS) $(H323LDFLAGS) $(OBJS) $(LIBEDIT_OBJ) $(AST_EMBED_LDSCRIPTS) buildinfo.o $(AST_LIBS) $(AST_EMBED_LIBS) $(H323LDLIBS) $(GMIMELDFLAGS) $(LIBEDIT_LIB)
  endif
  
  ifeq ($(GNU_LD),1)
diff --git a/menuselect.makedeps b/menuselect.makedeps
new file mode 100644 (file)
index 0000000..c8dfc89
--- /dev/null
@@ -0,0 +1,114 @@
+MENUSELECT_DEPENDS_chan_mobile=BLUETOOTH 
+MENUSELECT_DEPENDS_res_config_mysql=MYSQLCLIENT 
+MENUSELECT_DEPENDS_app_mysql=MYSQLCLIENT 
+MENUSELECT_DEPENDS_cdr_mysql=MYSQLCLIENT 
+MENUSELECT_DEPENDS_app_flash=DAHDI 
+MENUSELECT_DEPENDS_app_page=DAHDI 
+MENUSELECT_DEPENDS_app_dahdiras=DAHDI 
+MENUSELECT_DEPENDS_app_fax=SPANDSP 
+MENUSELECT_DEPENDS_app_jack=JACK RESAMPLE 
+MENUSELECT_DEPENDS_app_osplookup=OSPTK OPENSSL 
+MENUSELECT_DEPENDS_app_rpt=DAHDI TONEZONE 
+MENUSELECT_DEPENDS_app_dahdibarge=DAHDI 
+MENUSELECT_DEPENDS_app_meetme=DAHDI 
+MENUSELECT_DEPENDS_cdr_syslog=SYSLOG 
+MENUSELECT_DEPENDS_cdr_pgsql=PGSQL 
+MENUSELECT_DEPENDS_cdr_radius=RADIUS 
+MENUSELECT_DEPENDS_cdr_sqlite3_custom=SQLITE3 
+MENUSELECT_DEPENDS_cdr_tds=FREETDS 
+MENUSELECT_DEPENDS_cdr_sqlite=SQLITE 
+MENUSELECT_DEPENDS_cel_pgsql=PGSQL 
+MENUSELECT_DEPENDS_cel_radius=RADIUS 
+MENUSELECT_DEPENDS_cel_sqlite3_custom=SQLITE3 
+MENUSELECT_DEPENDS_cel_tds=FREETDS 
+MENUSELECT_DEPENDS_chan_dahdi=DAHDI TONEZONE PRI SS7 OPENR2 
+MENUSELECT_DEPENDS_chan_iax2=CRYPTO 
+MENUSELECT_DEPENDS_chan_alsa=ALSA 
+MENUSELECT_DEPENDS_chan_console=PORTAUDIO 
+MENUSELECT_DEPENDS_chan_gtalk=IKSEMEL OPENSSL 
+MENUSELECT_DEPENDS_chan_jingle=IKSEMEL OPENSSL 
+MENUSELECT_DEPENDS_chan_misdn=ISDNNET MISDN SUPPSERV 
+MENUSELECT_DEPENDS_chan_nbs=NBS 
+MENUSELECT_DEPENDS_chan_oss=OSS 
+MENUSELECT_DEPENDS_chan_phone=IXJUSER 
+MENUSELECT_DEPENDS_chan_usbradio=OSS ALSA USB 
+MENUSELECT_DEPENDS_chan_vpb=VPB 
+MENUSELECT_DEPENDS_chan_h323=OPENH323 
+MENUSELECT_DEPENDS_codec_dahdi=DAHDI 
+MENUSELECT_DEPENDS_codec_gsm=GSM 
+MENUSELECT_DEPENDS_codec_speex=SPEEX SPEEX_PREPROCESS SPEEXDSP 
+MENUSELECT_DEPENDS_codec_lpc10=LPC10 
+MENUSELECT_DEPENDS_format_ogg_vorbis=VORBIS OGG 
+MENUSELECT_DEPENDS_func_aes=CRYPTO 
+MENUSELECT_DEPENDS_func_curl=CURL 
+MENUSELECT_DEPENDS_func_iconv=ICONV 
+MENUSELECT_DEPENDS_func_speex=SPEEX SPEEX_PREPROCESS SPEEXDSP 
+MENUSELECT_DEPENDS_pbx_dundi=ZLIB CRYPTO 
+MENUSELECT_DEPENDS_pbx_lua=LUA 
+MENUSELECT_DEPENDS_res_calendar_caldav=NEON ICAL LIBXML2 
+MENUSELECT_DEPENDS_res_calendar_ews=NEON29 
+MENUSELECT_DEPENDS_res_calendar_exchange=NEON ICAL IKSEMEL 
+MENUSELECT_DEPENDS_res_calendar_icalendar=NEON ICAL 
+MENUSELECT_DEPENDS_res_config_curl=CURL 
+MENUSELECT_DEPENDS_res_crypto=OPENSSL 
+MENUSELECT_DEPENDS_res_curl=CURL 
+MENUSELECT_DEPENDS_res_http_post=GMIME 
+MENUSELECT_DEPENDS_res_odbc=GENERIC_ODBC LTDL 
+MENUSELECT_DEPENDS_res_srtp=SRTP 
+MENUSELECT_DEPENDS_res_timing_dahdi=DAHDI 
+MENUSELECT_DEPENDS_res_timing_timerfd=TIMERFD 
+MENUSELECT_DEPENDS_res_ais=AIS 
+MENUSELECT_DEPENDS_res_config_ldap=LDAP 
+MENUSELECT_DEPENDS_res_config_pgsql=PGSQL 
+MENUSELECT_DEPENDS_res_config_sqlite=SQLITE 
+MENUSELECT_DEPENDS_res_fax_spandsp=SPANDSP 
+MENUSELECT_DEPENDS_res_jabber=IKSEMEL OPENSSL 
+MENUSELECT_DEPENDS_res_snmp=NETSNMP 
+MENUSELECT_DEPENDS_res_timing_kqueue=KQUEUE 
+MENUSELECT_DEPENDS_test_acl=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_amihooks=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_aoc=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_app=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_ast_format_str_reduce=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_astobj2=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_db=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_devicestate=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_dlinklists=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_event=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_expr=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_format_api=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_func_file=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_gosub=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_heap=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_linkedlists=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_locale=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_logger=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_netsock2=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_pbx=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_poll=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_sched=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_security_events=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_skel=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_stringfields=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_strings=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_substitution=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_time=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_test_utils=TEST_FRAMEWORK 
+MENUSELECT_DEPENDS_REBUILD_PARSERS=BISON FLEX 
+MENUSELECT_DEPENDS_BETTER_BACKTRACES=BFD DLADDR 
+MENUSELECT_DEPENDS_USE_HOARD_ALLOCATOR=HOARD 
+MENUSELECT_DEPENDS_ODBC_STORAGE=GENERIC_ODBC LTDL 
+MENUSELECT_DEPENDS_IMAP_STORAGE=IMAP_TK OPENSSL 
+MENUSELECT_DEPENDS_astman=NEWT 
+MENUSELECT_DEPENDS_smsq=POPT 
+MENUSELECT_DEPENDS_EMBED_ADDONS=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_APPS=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_BRIDGES=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_CDR=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_CHANNELS=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_CODECS=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_FORMATS=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_FUNCS=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_PBX=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_RES=GNU_LD 
+MENUSELECT_DEPENDS_EMBED_TEST=GNU_LD 
diff --git a/menuselect.makeopts b/menuselect.makeopts
new file mode 100644 (file)
index 0000000..671b74d
--- /dev/null
@@ -0,0 +1,53 @@
+MENUSELECT_ADDONS=format_mp3 app_mysql app_saycountpl cdr_mysql 
+MENUSELECT_APPS=app_skel app_fax app_ivrdemo app_rpt app_saycounted app_dahdibarge app_readfile app_setcallerid 
+MENUSELECT_BRIDGES=
+MENUSELECT_CDR=cdr_sqlite 
+MENUSELECT_CEL=
+MENUSELECT_CHANNELS=chan_misdn chan_nbs chan_vpb chan_h323 
+MENUSELECT_CODECS=codec_ilbc 
+MENUSELECT_FORMATS=
+MENUSELECT_FUNCS=
+MENUSELECT_PBX=
+MENUSELECT_RES=res_pktccops res_timing_kqueue 
+MENUSELECT_TESTS=test_acl test_amihooks test_aoc test_app test_ast_format_str_reduce test_astobj2 test_db test_devicestate test_dlinklists test_event test_expr test_format_api test_func_file test_gosub test_heap test_linkedlists test_locale test_logger test_netsock2 test_pbx test_poll test_sched test_security_events test_skel test_stringfields test_strings test_substitution test_time test_utils 
+MENUSELECT_CFLAGS=LOADABLE_MODULES 
+MENUSELECT_OPTS_app_voicemail=FILE_STORAGE 
+MENUSELECT_UTILS=astcanary astdb2sqlite3 astdb2bdb 
+MENUSELECT_AGIS=
+MENUSELECT_EMBED=
+MENUSELECT_CORE_SOUNDS=CORE-SOUNDS-EN-GSM 
+MENUSELECT_MOH=MOH-OPSOUND-WAV 
+MENUSELECT_EXTRA_SOUNDS=
+MENUSELECT_BUILD_DEPS=chan_local app_voicemail app_meetme res_monitor res_agi res_adsi res_smdi res_odbc res_crypto res_jabber res_ael_share res_fax G711_NEW_ALGORITHM chan_usbradio 
+MENUSELECT_DEPSFAILED=MENUSELECT_CHANNELS=chan_misdn
+MENUSELECT_DEPSFAILED=MENUSELECT_CHANNELS=chan_nbs
+MENUSELECT_DEPSFAILED=MENUSELECT_RES=res_timing_kqueue
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_acl
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_amihooks
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_aoc
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_app
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_ast_format_str_reduce
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_astobj2
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_db
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_devicestate
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_dlinklists
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_event
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_expr
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_format_api
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_func_file
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_gosub
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_heap
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_linkedlists
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_locale
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_logger
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_netsock2
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_pbx
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_poll
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_sched
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_security_events
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_skel
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_stringfields
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_strings
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_substitution
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_time
+MENUSELECT_DEPSFAILED=MENUSELECT_TESTS=test_utils
This page took 0.220271 seconds and 4 git commands to generate.