[Asterisk-Dev] chan_bluetooth

David Woodhouse dwmw2 at infradead.org
Wed Nov 23 02:58:25 MST 2005


On Wed, 2005-11-23 at 06:23 +0000, Theo Zourzouvillys wrote:
> On Tuesday 22 November 2005 21:40, Brent Priddy wrote:
> > are you keeping the stable version and David is keeping the CVS-HEAD
> > version? is there a difference between your chan_bluetooth and
> > David's?

Nothing so organised. I just threw it into a CVS tree for my own
purposes when I couldn't get much response out of Theo, and then have
pointed a few people at it since then when they've been having trouble.
I haven't really had time to 'maintain' it, although I do use it with a
Bluetooth headset so I've been making sure it works for that.

I'm pleased to see that Theo has returned :)

> If david provides me with a diff, i'll happily merge them!, or provide
> svn access for him.

I believe my initial import into CVS was your then-latest version, so
the patch from that is below. The current chan_bluetooth.c is at
http://david.woodhou.se/chan_bluetooth.c, and the RCS file in case you
want the history or intermediate diffs is at
http://david.woodhou.se/chan_bluetooth.c,v

You're welcome to a CVS account too, of course, but I assume you'll want
to continue in SVN and we'll stop using the CVS version.

Index: chan_bluetooth.c
===================================================================
RCS file: /home/cvs/chan_bluetooth/chan_bluetooth.c,v
retrieving revision 1.1
retrieving revision 1.7
diff -u -p -r1.1 -r1.7
--- chan_bluetooth.c	13 May 2005 16:39:50 -0000	1.1
+++ chan_bluetooth.c	6 Nov 2005 14:38:19 -0000	1.7
@@ -96,7 +96,6 @@
 #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>
@@ -105,6 +104,8 @@
 #include <asterisk/options.h>
 #include <asterisk/cli.h>
 #include <asterisk/callerid.h>
+#include <asterisk/version.h>
+
 #include <sys/socket.h>
 #include <sys/signal.h>
 #include <sys/time.h>
@@ -115,6 +116,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <ctype.h>
+#include <endian.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -129,7 +131,6 @@
 #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"
@@ -172,12 +173,15 @@ typedef enum {
 #define BLT_DEFAULT_ROLE         BLT_ROLE_HS
 #define BLT_OBUF_LEN             (48 * 25)
 
-#define BUFLEN 4800
+#define BUFLEN (4800)
 
 /* ---------------------------------- */
 
 typedef struct blt_dev blt_dev_t;
 
+struct blt_ring {
+	unsigned char buf[BUFLEN];
+};
 // XXX:T: Tidy this lot up.
 struct blt_dev {
 
@@ -195,12 +199,15 @@ struct blt_dev {
   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_in;                    /* Reader in position (drain)*/
+  int sco_pos_inrcv;                 /* Reader in position (fill) */
+	int wakeread; /* blt_read() needs to be woken */
   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 buf[1200];                    /* Incoming data buffer */
+  int bufpos;
+  char sco_buf_out[BUFLEN];          /* 24 chunks of 48 */
+  char sco_buf_in[BUFLEN];           /* 24 chunks of 48 */
 
   char dnid[1024];                    /* Outgoi gncall dialed number */
   unsigned char * obuf[BLT_OBUF_LEN]; /* Outgoing data buffer */
@@ -221,12 +228,15 @@ struct blt_dev {
   char rd_buff[BLT_RDBUFF_MAX];     /* RFCOMM input buffer */
   int rd_buff_pos;                  /* RFCOMM input buffer position */
   int ready;                        /* 1 When ready */
+  char *context;
 
   /* 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 */
+  char cid_num[AST_MAX_EXTENSION];
+  char cid_name[AST_MAX_EXTENSION];
 
   /* HS mode */
   blt_state_t state;                       /* Runtime: Device state (AG mode only) */
@@ -268,6 +278,7 @@ typedef struct blt_atcb {
 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);
+static int sco_start(blt_dev_t * dev, int fd);
 
 /* ---------------------------------- */
 
@@ -306,6 +317,34 @@ static struct sched_context * sched = NU
 
 /* ---------------------------------- */
 
+#if ASTERISK_VERSION_NUM <= 010107
+#include <asterisk/channel_pvt.h>
+#define tech_pvt pvt->pvt
+#define ast_config_load ast_load
+#else /* CVS. FIXME: Version number */
+static struct ast_channel *blt_request(const char *type, int format, void *data, int *cause);
+static int blt_hangup(struct ast_channel *c);
+static int blt_answer(struct ast_channel *c);
+static struct ast_frame *blt_read(struct ast_channel *chan);
+static int blt_call(struct ast_channel *c, char *dest, int timeout);
+static int blt_write(struct ast_channel *chan, struct ast_frame *f);
+static int blt_indicate(struct ast_channel *chan, int cond);
+
+static const struct ast_channel_tech blt_tech = {
+	.type = BLT_CHAN_NAME,
+	.description = "Bluetooth Channel Driver",
+	.capabilities = BLUETOOTH_FORMAT,
+	.requester = blt_request,
+	.hangup = blt_hangup,
+	.answer = blt_answer,
+	.read = blt_read,
+	.call = blt_call,
+	.write = blt_write,
+	.indicate = blt_indicate,
+};
+#endif
+/* ---------------------------------- */
+
 static const char *
 role2str(blt_role_t role)
 {
@@ -348,6 +387,59 @@ int sock_err(int fd)
 }
 
 /* ---------------------------------- */
+int parse_clip(const char * str, char *number, int number_len, char * name, int name_len, int *type)
+{
+  const char *c = str;
+  const char *start;
+  int length;
+  char typestr[256];
+
+  memset(number, 0, number_len);
+  memset(name, 0, name_len);
+  *type = 0;
+
+  number[0] = '\0';
+  name[0] = '\0';
+  while(*c && *c != '"')
+    c++;
+  c++;
+  start = c;
+  while(*c && *c != '"')
+    c++;
+  length = c - start < number_len ? c - start : number_len;
+  strncpy(number, start, length);
+  number[length] = '\0';
+  c++;
+  while(*c && *c != ',')
+    c++;
+  c++;
+  start = c;
+  while(*c && *c != ',')
+    c++;
+  length = c - start < number_len ? c - start : number_len;
+  strncpy(typestr, start, length);
+  typestr[length] = '\0';
+  *type = atoi(typestr);
+  c++;
+  while(*c && *c != ',')
+    c++;
+  c++;
+  while(*c && *c != ',')
+    c++;
+  c++;
+  while(*c && *c != '"')
+    c++;
+  c++;
+  start = c;
+  while(*c && *c != '"')
+    c++;
+  length = c - start < number_len ? c - start : number_len;
+  strncpy(name, start, length);
+  name[length] = '\0';
+
+  return(1);
+}
+
 
 static const char *
 parse_cind(const char * str, char * name, int name_len)
@@ -426,6 +518,7 @@ set_cind(blt_dev_t * dev, int indicator,
 
     if (dev->owner) {
       if (val == 1) {
+      	sco_start(dev, -1);
         ast_queue_control(dev->owner, AST_CONTROL_ANSWER);
       } else if (val == 0)
         ast_queue_control(dev->owner, AST_CONTROL_HANGUP);
@@ -450,13 +543,13 @@ set_buffer(char * ring, char * data, int
 
     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)
+    if (start_pos == circular_len) {
       start_pos = 0;
+    }
   }
   *(pos) = start_pos;
   return 0;
@@ -476,14 +569,20 @@ get_buffer(char * dst, char * ring, int 
     copy = MIN(ring_size - *head, to_copy);
 
     // ast_log(LOG_DEBUG, "Getting: %d bytes, From pos %d\n", copy, *head);
+#if __BYTE_ORDER == __LITTLE_ENDIAN
     memcpy(dst, ring + *head, copy);
-
+#else
+    //    memcpy(dst, ring + *head, copy);
+    ast_swapcopy_samples(dst, ring+*head, copy/2);
+#endif
+    memset(ring+*head, 0, copy);
     dst += copy;
     *head += copy;
     to_copy -= copy;
 
-    if (*head == ring_size )
-      *head = 0;
+    if (*head == ring_size ) {
+	    *head = 0;
+    }
 
   }
 
@@ -519,7 +618,11 @@ sco_thread(void * data)
 
   // Avoid deadlock in odd circumstances
 
-  ast_log(LOG_DEBUG, "SCO thread started on fd %d, pid %d\n", dev->sco, getpid());
+  ast_log(LOG_WARNING, "SCO thread started on fd %d, pid %d\n", dev->sco, getpid());
+
+  if (fcntl(dev->sco_pipe[1], F_SETFL, O_RDWR|O_NONBLOCK)) {
+	  ast_log(LOG_WARNING, "fcntl failed on sco_pipe\n");
+  }
 
   // dev->status = BLT_STATUS_IN_CALL;
   // ast_queue_control(dev->owner, AST_CONTROL_ANSWER);
@@ -527,11 +630,13 @@ sco_thread(void * data)
 
   ast_mutex_lock(&(dev->sco_lock));
 
-  memset(dev->sco_buf_in,  0x7f, BUFLEN);
-  memset(dev->sco_buf_out, 0x7f, BUFLEN);
+  memset(dev->sco_buf_in, 0, BUFLEN);
+  memset(dev->sco_buf_out, 0, BUFLEN);
 
   dev->sco_pos_in  = 0;
   dev->sco_pos_out = 0;
+  dev->sco_pos_inrcv = 0;
+  dev->wakeread = 1;
 
   ast_mutex_unlock(&(dev->sco_lock));
 
@@ -562,7 +667,6 @@ sco_thread(void * data)
     if (res == 0)
       continue;
 
-    ast_mutex_lock(&(dev->sco_lock));
 
     if (pfd[0].revents & POLLIN) {
 
@@ -570,16 +674,27 @@ sco_thread(void * data)
 
       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);
+
+        if (dev->owner && dev->owner->_state == AST_STATE_UP) {
+		ast_mutex_lock(&(dev->sco_lock));
+		set_buffer(dev->sco_buf_in,  buf, BUFLEN, &in_pos,  len);
+		dev->sco_pos_inrcv = in_pos;
+
+		get_buffer(buf, dev->sco_buf_out, BUFLEN, &out_pos, len);
+		if (write(dev->sco, buf, len) != len)
+			ast_log(LOG_WARNING, "Wrote <48 to sco\n");
+
+		if (dev->wakeread) {
+			/* blt_read has caught up. Kick it */
+			dev->wakeread = 0;
+			if(write(dev->sco_pipe[1], &c, 1) != 1)
+				ast_log(LOG_WARNING, "write to kick sco_pipe failed\n");
+		}
+		ast_mutex_unlock(&(dev->sco_lock));
+	}
         ast_mutex_unlock(&(dev->lock));
       }
 
-      ast_mutex_unlock(&(dev->sco_lock));
-
     } else if (pfd[0].revents) {
 
       int e = sock_err(pfd[0].fd);
@@ -612,6 +727,14 @@ sco_thread(void * data)
   close(dev->sco);
   dev->sco = -1;
   dev->sco_running = -1;
+  
+  memset(dev->sco_buf_in, 0, BUFLEN);
+  memset(dev->sco_buf_out, 0, BUFLEN);
+
+  dev->sco_pos_in  = 0;
+  dev->sco_pos_out = 0;
+  dev->sco_pos_inrcv = 0;
+  
   ast_mutex_unlock(&(dev->sco_lock));
   if (dev->owner)
     ast_queue_control(dev->owner, AST_CONTROL_HANGUP);
@@ -710,7 +833,7 @@ answer(blt_dev_t * dev)
 static int 
 blt_write(struct ast_channel * ast, struct ast_frame * frame)
 {
-  blt_dev_t * dev = ast->pvt->pvt; 
+  blt_dev_t * dev = ast->tech_pvt; 
 
   /* Write a frame of (presumably voice) data */
 
@@ -720,7 +843,11 @@ blt_write(struct ast_channel * ast, stru
   }
 
   if (!(frame->subclass & BLUETOOTH_FORMAT)) {
-    ast_log(LOG_WARNING, "Cannot handle frames in format %d\n", frame->subclass);
+	  static int fish = 5;
+	  if (fish) {
+		  ast_log(LOG_WARNING, "Cannot handle frames in format %d\n", frame->subclass);
+		  fish--;
+	  }
     return 0;
   }
 
@@ -739,10 +866,10 @@ blt_write(struct ast_channel * ast, stru
 static struct ast_frame *
 blt_read(struct ast_channel * ast)
 {
-  blt_dev_t * dev = ast->pvt->pvt;
+  blt_dev_t * dev = ast->tech_pvt;
   char c = 1;
   int len;
-
+  static int fish = 0;
   /* Some nice norms */
 
   dev->fr.datalen = 0;
@@ -750,23 +877,36 @@ blt_read(struct ast_channel * ast)
   dev->fr.data =  NULL;
   dev->fr.src = BLT_CHAN_NAME;
   dev->fr.offset = 0;
-  dev->fr.mallocd = 0;
+  dev->fr.mallocd = AST_MALLOCD_DATA;
   dev->fr.delivery.tv_sec = 0;
   dev->fr.delivery.tv_usec = 0;
-
+  read(dev->sco_pipe[0], &c, 1);
   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);
+
+  if (dev->sco_pos_inrcv < dev->sco_pos_in) {
+	  /* Buffer wrapped. Read only till the end */
+	  len = BUFLEN - dev->sco_pos_in + dev->sco_pos_inrcv;
+  } else {
+	  len = dev->sco_pos_inrcv - dev->sco_pos_in;
+  }
+  dev->fr.data = malloc(AST_FRIENDLY_OFFSET+len) + AST_FRIENDLY_OFFSET;
+
+  get_buffer(dev->fr.data, dev->sco_buf_in, BUFLEN, &(dev->sco_pos_in), len);
+  dev->wakeread = 1;
   ast_mutex_unlock(&(dev->sco_lock));
+  if (fish) {
+	  unsigned char *x = dev->fr.data;
+	  ast_log(LOG_WARNING, "blt_read  %d: %02x %02x %02x %02x %02x %02x\n",
+		  dev->fr.datalen, x[0], x[1], x[2], x[3], x[4], x[5]);
+	  fish--;
+  }
 
-  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;
-
+  dev->fr.offset = AST_FRIENDLY_OFFSET;
   return &dev->fr;
 }
 
@@ -872,7 +1012,7 @@ ring_hs(blt_dev_t * dev)
 static int
 blt_call(struct ast_channel * ast, char * dest, int timeout)
 {
-  blt_dev_t * dev = ast->pvt->pvt;
+  blt_dev_t * dev = ast->tech_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);
@@ -910,7 +1050,8 @@ blt_call(struct ast_channel * ast, char 
   } else if (dev->role == BLT_ROLE_AG) {
 
     send_atcmd(dev, "ATD%s;", dev->dnid);
-
+// it does not seem like we should start the audio untill the coall is connected
+//    sco_start(dev, -1);
   } else {
 
     ast_setstate(ast, AST_CONTROL_CONGESTION);
@@ -927,11 +1068,11 @@ blt_call(struct ast_channel * ast, char 
 static int 
 blt_hangup(struct ast_channel * ast)
 {
-  blt_dev_t * dev = ast->pvt->pvt;
+  blt_dev_t * dev = ast->tech_pvt;
 
   ast_log(LOG_DEBUG, "blt_hangup(%s)\n", ast->name);
 
-  if (!ast->pvt->pvt) {
+  if (!ast->tech_pvt) {
     ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
     return 0;
   }
@@ -969,6 +1110,7 @@ blt_hangup(struct ast_channel * ast)
   } else if (dev->role == BLT_ROLE_AG) {
 
     // Cancel call.
+    send_atcmd(dev, "ATH");
     send_atcmd(dev, "AT+CHUP");
 
   }
@@ -976,7 +1118,7 @@ blt_hangup(struct ast_channel * ast)
   if (dev->status == BLT_STATUS_IN_CALL || dev->status == BLT_STATUS_RINGING)
     dev->status = BLT_STATUS_READY;
 
-  ast->pvt->pvt = NULL;
+  ast->tech_pvt = NULL;
   dev->owner = NULL;
   ast_mutex_unlock(&(dev->lock));
   ast_setstate(ast, AST_STATE_DOWN);
@@ -1003,7 +1145,7 @@ blt_indicate(struct ast_channel * c, int
 static int
 blt_answer(struct ast_channel * ast)
 {
-  blt_dev_t * dev = ast->pvt->pvt;
+  blt_dev_t * dev = ast->tech_pvt;
 
   ast_mutex_lock(&dev->lock);
 
@@ -1041,8 +1183,8 @@ blt_new(blt_dev_t * dev, int state, cons
   // 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->rawreadformat  = BLUETOOTH_FORMAT;
+  ast->rawwriteformat = BLUETOOTH_FORMAT;
   ast->writeformat         = BLUETOOTH_FORMAT;
   ast->readformat          = BLUETOOTH_FORMAT;
 
@@ -1050,17 +1192,23 @@ blt_new(blt_dev_t * dev, int state, cons
 
   ast->type = BLT_CHAN_NAME;
 
-  ast->pvt->pvt = dev;
-
+  ast->tech_pvt = dev;
+#if ASTERISK_VERSION_NUM > 010107
+  ast->tech = &blt_tech;
+#else
   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;
-
+#endif
   strncpy(ast->context, context, sizeof(ast->context)-1);
   strncpy(ast->exten,   number,  sizeof(ast->exten) - 1);
+  if(0 == strcmp(number, "s"))
+  {
+    ast_set_callerid(ast, dev->cid_num, dev->cid_name, dev->cid_num);
+  }
 
   ast->language[0] = '\0';
 
@@ -1088,8 +1236,10 @@ blt_new(blt_dev_t * dev, int state, cons
 static struct ast_channel *
 #if (ASTERISK_VERSION_NUM < 010100)
 blt_request(char * type, int format, void * local_data)
-#else
+#elif (ASTERISK_VERSION_NUM <= 010107)
 blt_request(const char * type, int format, void * local_data)
+#else
+blt_request(const char * type, int format, void * local_data, int *cause)
 #endif
 {
   char * data = (char*)local_data;
@@ -1148,7 +1298,7 @@ blt_request(const char * type, int forma
   if (dev->role == BLT_ROLE_AG)
     strncpy(dev->dnid, number, sizeof(dev->dnid) - 1);
 
-  ast = blt_new(dev, AST_STATE_DOWN, "bluetooth", "s");
+  ast = blt_new(dev, AST_STATE_DOWN, dev->context, "s");
 
   ast_mutex_unlock(&(dev->lock));
 
@@ -1420,7 +1570,7 @@ atcmd_dial_execute(blt_dev_t * dev, cons
 
   sco_start(dev, -1);
 
-  if (blt_new(dev, AST_STATE_UP, "bluetooth", number) == NULL) {
+  if (blt_new(dev, AST_STATE_UP, dev->context, number) == NULL) {
     sco_stop(dev);
   }
 
@@ -1429,6 +1579,11 @@ atcmd_dial_execute(blt_dev_t * dev, cons
   return 0;
 }
 
+static int atcmd_bldn_execute(blt_dev_t * dev, const char *data)
+{
+	return atcmd_dial_execute(dev, "bldn;");
+}
+
 /* Answer */
 
 static int
@@ -1544,6 +1699,35 @@ ag_unsol_cind(blt_dev_t * dev, const cha
   return 0;
 }
 
+/*
+ * handle an incoming call
+ */
+static int
+ag_unsol_clip(blt_dev_t * dev, const char * data)
+{
+  const char * orig = data;
+  char name[256];
+  char number[64];
+  int type;
+
+  while (*(data) && *(data) == ' ')
+    data++;
+
+  if (*(data) == 0) {
+    ast_log(LOG_WARNING, "Invalid value[1] for '+CLIP:%s'\n", orig);
+    return -1;
+  }
+
+  parse_clip(data, number, sizeof(number)-1, name, sizeof(name)-1, &type);
+  ast_log(LOG_NOTICE, "Parsed '+CLIP: %s' number='%s' type='%d' name='%s'\n", data, number, type, name);
+
+  blt_new(dev, AST_STATE_RING, dev->context, "s");
+
+  return 0;
+}
+
+
+
 static blt_atcb_t
 atcmd_list[] = 
 {
@@ -1556,7 +1740,7 @@ atcmd_list[] = 
   { "+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 },
+  { "+CLIP", atcmd_clip_set, NULL,            NULL,                 NULL,             ag_unsol_clip },
   { "+COLP", atcmd_colp_set, NULL,            NULL,                 NULL,             NULL },
   { "+CMER", atcmd_cmer_set, NULL,            NULL,                 NULL,             NULL },
   { "+CPBR", atcmd_cpbr_set, NULL,            NULL,                 NULL,             NULL },
@@ -1564,6 +1748,7 @@ atcmd_list[] = 
   { "+CSCS", atcmd_cscs_set, NULL,            NULL,                 NULL,             NULL },
   { "*EIPS", atcmd_eips_set, NULL,            NULL,                 NULL,             NULL },
   { "+VGS",  atcmd_vgs_set,  NULL,            NULL,                 NULL,             NULL },
+  { "+BLDN", NULL,           NULL,            atcmd_bldn_execute,   NULL,             NULL },
 };
 
 #define ATCMD_LIST_LEN (sizeof(atcmd_list) / sizeof(blt_atcb_t))
@@ -2135,7 +2320,7 @@ process_rfcomm_cmd(blt_dev_t * dev, char
 
   cmd += 2;
 
-  // Don't forget 'AT' on it's own is OK.
+  // Don't forget 'AT' on its own is OK.
 
   if (strlen(cmd) == 0) {
     send_atcmd_ok(dev, fullcmd);
@@ -2696,7 +2881,7 @@ blt_parse_config(void)
   struct ast_variable * v;
   char * cat;
 
-  cfg = ast_load(BLT_CONFIG_FILE);
+  cfg = ast_config_load(BLT_CONFIG_FILE);
 
   if (!cfg) {
     ast_log(LOG_NOTICE, "Unable to load Bluetooth config: %s.  Bluetooth disabled\n", BLT_CONFIG_FILE);
@@ -2761,6 +2946,11 @@ blt_parse_config(void)
       if ((str = ast_variable_retrieve(cfg, cat, "autoconnect")) != NULL)
         device->autoconnect = (strcasecmp(str, "yes") == 0 || strcmp(str, "1") == 0) ? 1 : 0;
 
+      if ((str = ast_variable_retrieve(cfg, cat, "context")) != NULL)
+	device->context = str;
+      else
+	device->context = "bluetooth";
+
       device->next = iface_head;
       iface_head = device;
       ifcount++;
@@ -2979,7 +3169,11 @@ static int
 __unload_module(void)
 {
 
+#if ASTERISK_VERSION_NUM <= 010107
   ast_channel_unregister(BLT_CHAN_NAME);
+#else
+  ast_channel_unregister(&blt_tech);
+#endif
 
   if (monitor_thread != AST_PTHREADT_NULL) {
 
@@ -3077,7 +3271,11 @@ load_module()
   if (restart_monitor() != 0)
     return -1;
 
+#if ASTERISK_VERSION_NUM <= 010107
   if (ast_channel_register(BLT_CHAN_NAME, "Bluetooth Driver", BLUETOOTH_FORMAT, blt_request)) {
+#else
+  if (ast_channel_register(&blt_tech)) {
+#endif
     ast_log(LOG_ERROR, "Unable to register channel class BTL\n");
     __unload_module();
     return -1;



-- 
dwmw2





More information about the asterisk-dev mailing list