source: freewrt/package/asterisk/patches/asterisk-1.0.9-chan_bluetooth.patch@ 428f140

freewrt_1_0 freewrt_2_0
Last change on this file since 428f140 was 475ad56, checked in by Waldemar Brodkorb <wbx@…>, 20 years ago

add OpenWrt trunk revision 3830.

git-svn-id: svn://www.freewrt.org/trunk/freewrt@1 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100644
File size: 96.5 KB
  • channels/Makefile

    diff -ruN asterisk-1.0.9-old/channels/Makefile asterisk-1.0.9-new/channels/Makefile
    old new  
    202202chan_h323.so: chan_h323.o h323/libchanh323.a
    203203        $(CC) $(SOLINK) -o $@ $< h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat
    204204
     205#
     206# Asterisk Bluetooth Support
     207# http://www.crazygreek.co.uk/content/chan_bluetooth
     208#
     209chan_bluetooth.so: chan_bluetooth.o
     210        $(CC) $(SOLINK) -o $@ $< $(EXTRA_LDFLAGS) -lbluetooth
     211
    205212
    206213#chan_modem.so : chan_modem.o
    207214#       $(CC) -rdynamic -shared -Xlinker -x -o $@ $<
  • channels/chan_bluetooth.c

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

    diff -ruN asterisk-1.0.9-old/configs/bluetooth.conf asterisk-1.0.9-new/configs/bluetooth.conf
    old new  
     1[general]
     2; Channel we listen on as a HS (Headset)
     3rfchannel_hs = 2
     4; Channel we listen on as an AG (AudioGateway)
     5rfchannel_ag = 3
     6; Channel we listen on as GUI
     7rfchannel_gui = 4
     8; hci interface to use (number - e.g '0')
     9interface = 0
     10
     11; RFCOMM channel to connect to.  For a HandsSet:
     12;    sdptool search --bdaddr xx:xx:xx:xx:xx:xx 0x111E
     13; or,for an AudioGateway (Phone):
     14;    sdptool search --bdaddr xx:xx:xx:xx:xx:xx 0x111F
     15;
     16; Find the 'channel' value under RFCOMM.
     17;
     18;channel     = 6
     19; Automatically connect?
     20;autoconnect = yes
     21
     22;example for a SonyEricsson mobile as a GUI device
     23[00:0F:DE:6E:77:6B]
     24name    = T610
     25type    = GUI
     26channel = 6
     27;channel = 1
     28autoconnect     = yes
     29
     30;[00:0E:6D:1A:3D:86]
     31;name   = Nokia
     32;type   = AG
     33;channel = 13
     34;autoconnect    = yes
     35
     36[00:0E:A1:01:49:AE]
     37name    = AutoBlue
     38type    = HS
     39channel = 2
     40autoconnect = yes
     41
     42;[00:0A:D9:EB:FD:D8]
     43;name    = P900
     44;type    = AG
     45;channel = 8
     46;autoconnect = no
Note: See TracBrowser for help on using the repository browser.