Asterisk - The Open Source Telephony Project  21.4.1
chan_mobile.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \brief Bluetooth Mobile Device channel driver
22  *
23  * \author Dave Bowerman <david.bowerman@gmail.com>
24  *
25  * \ingroup channel_drivers
26  */
27 
28 /*! \li \ref chan_mobile.c uses the configuration file \ref chan_mobile.conf
29  * \addtogroup configuration_file Configuration Files
30  */
31 
32 /*!
33  * \page chan_mobile.conf chan_mobile.conf
34  * \verbinclude chan_mobile.conf.sample
35  */
36 
37 /*** MODULEINFO
38  <depend>bluetooth</depend>
39  <defaultenabled>no</defaultenabled>
40  <support_level>extended</support_level>
41  ***/
42 
43 #include "asterisk.h"
44 
45 #include <pthread.h>
46 #include <signal.h>
47 
48 #include <bluetooth/bluetooth.h>
49 #include <bluetooth/hci.h>
50 #include <bluetooth/hci_lib.h>
51 #include <bluetooth/sdp.h>
52 #include <bluetooth/sdp_lib.h>
53 #include <bluetooth/rfcomm.h>
54 #include <bluetooth/sco.h>
55 #include <bluetooth/l2cap.h>
56 
57 #include "asterisk/compat.h"
58 #include "asterisk/lock.h"
59 #include "asterisk/callerid.h"
60 #include "asterisk/channel.h"
61 #include "asterisk/config.h"
62 #include "asterisk/logger.h"
63 #include "asterisk/module.h"
64 #include "asterisk/pbx.h"
65 #include "asterisk/options.h"
66 #include "asterisk/utils.h"
67 #include "asterisk/linkedlists.h"
68 #include "asterisk/cli.h"
69 #include "asterisk/devicestate.h"
70 #include "asterisk/causes.h"
71 #include "asterisk/dsp.h"
72 #include "asterisk/app.h"
73 #include "asterisk/manager.h"
74 #include "asterisk/io.h"
75 #include "asterisk/smoother.h"
76 #include "asterisk/format_cache.h"
77 
78 #define MBL_CONFIG "chan_mobile.conf"
79 #define MBL_CONFIG_OLD "mobile.conf"
80 
81 #define DEVICE_FRAME_SIZE 48
82 #define DEVICE_FRAME_FORMAT ast_format_slin
83 #define CHANNEL_FRAME_SIZE 320
84 
85 static int discovery_interval = 60; /* The device discovery interval, default 60 seconds. */
86 static pthread_t discovery_thread = AST_PTHREADT_NULL; /* The discovery thread */
87 static sdp_session_t *sdp_session;
88 
89 AST_MUTEX_DEFINE_STATIC(unload_mutex);
90 static int unloading_flag = 0;
91 static inline int check_unloading(void);
92 static inline void set_unloading(void);
93 
94 enum mbl_type {
95  MBL_TYPE_PHONE,
96  MBL_TYPE_HEADSET
97 };
98 
99 struct adapter_pvt {
100  int dev_id; /* device id */
101  int hci_socket; /* device descriptor */
102  char id[31]; /* the 'name' from mobile.conf */
103  bdaddr_t addr; /* adddress of adapter */
104  unsigned int inuse:1; /* are we in use ? */
105  unsigned int alignment_detection:1; /* do alignment detection on this adapter? */
106  struct io_context *io; /*!< io context for audio connections */
107  struct io_context *accept_io; /*!< io context for sco listener */
108  int *sco_id; /*!< the io context id of the sco listener socket */
109  int sco_socket; /*!< sco listener socket */
110  pthread_t sco_listener_thread; /*!< sco listener thread */
112 };
113 
115 
116 struct msg_queue_entry;
117 struct hfp_pvt;
118 struct mbl_pvt {
119  struct ast_channel *owner; /* Channel we belong to, possibly NULL */
120  struct ast_frame fr; /* "null" frame */
121  ast_mutex_t lock; /*!< pvt lock */
122  /*! queue for messages we are expecting */
124  enum mbl_type type; /* Phone or Headset */
125  char id[31]; /* The id from mobile.conf */
126  int group; /* group number for group dialling */
127  bdaddr_t addr; /* address of device */
128  struct adapter_pvt *adapter; /* the adapter we use */
129  char context[AST_MAX_CONTEXT]; /* the context for incoming calls */
130  struct hfp_pvt *hfp; /*!< hfp pvt */
131  int rfcomm_port; /* rfcomm port number */
132  int rfcomm_socket; /* rfcomm socket descriptor */
133  char rfcomm_buf[256];
134  char io_buf[CHANNEL_FRAME_SIZE + AST_FRIENDLY_OFFSET];
135  struct ast_smoother *bt_out_smoother; /* our bt_out_smoother, for making 48 byte frames */
136  struct ast_smoother *bt_in_smoother; /* our smoother, for making "normal" CHANNEL_FRAME_SIZEed byte frames */
137  int sco_socket; /* sco socket descriptor */
138  pthread_t monitor_thread; /* monitor thread handle */
139  int timeout; /*!< used to set the timeout for rfcomm data (may be used in the future) */
140  unsigned int no_callsetup:1;
141  unsigned int has_sms:1;
142  unsigned int do_alignment_detection:1;
143  unsigned int alignment_detection_triggered:1;
144  unsigned int blackberry:1;
145  short alignment_samples[4];
146  int alignment_count;
147  int ring_sched_id;
148  struct ast_dsp *dsp;
149  struct ast_sched_context *sched;
150  int hangupcause;
151 
152  /* flags */
153  unsigned int outgoing:1; /*!< outgoing call */
154  unsigned int incoming:1; /*!< incoming call */
155  unsigned int outgoing_sms:1; /*!< outgoing sms */
156  unsigned int incoming_sms:1; /*!< outgoing sms */
157  unsigned int needcallerid:1; /*!< we need callerid */
158  unsigned int needchup:1; /*!< we need to send a chup */
159  unsigned int needring:1; /*!< we need to send a RING */
160  unsigned int answered:1; /*!< we sent/received an answer */
161  unsigned int connected:1; /*!< do we have an rfcomm connection to a device */
162 
163  AST_LIST_ENTRY(mbl_pvt) entry;
164 };
165 
166 /*! Structure used by hfp_parse_clip to return two items */
167 struct cidinfo {
168  char *cnum;
169  char *cnam;
170 };
171 
173 
174 static int handle_response_ok(struct mbl_pvt *pvt, char *buf);
175 static int handle_response_error(struct mbl_pvt *pvt, char *buf);
176 static int handle_response_ciev(struct mbl_pvt *pvt, char *buf);
177 static int handle_response_clip(struct mbl_pvt *pvt, char *buf);
178 static int handle_response_ring(struct mbl_pvt *pvt, char *buf);
179 static int handle_response_cmti(struct mbl_pvt *pvt, char *buf);
180 static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf);
181 static int handle_response_cusd(struct mbl_pvt *pvt, char *buf);
182 static int handle_response_busy(struct mbl_pvt *pvt);
183 static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf);
184 static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf);
185 static int handle_sms_prompt(struct mbl_pvt *pvt, char *buf);
186 
187 /* CLI stuff */
188 static char *handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
189 static char *handle_cli_mobile_search(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
190 static char *handle_cli_mobile_rfcomm(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
191 static char *handle_cli_mobile_cusd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
192 
193 static struct ast_cli_entry mbl_cli[] = {
194  AST_CLI_DEFINE(handle_cli_mobile_show_devices, "Show Bluetooth Cell / Mobile devices"),
195  AST_CLI_DEFINE(handle_cli_mobile_search, "Search for Bluetooth Cell / Mobile devices"),
196  AST_CLI_DEFINE(handle_cli_mobile_rfcomm, "Send commands to the rfcomm port for debugging"),
197  AST_CLI_DEFINE(handle_cli_mobile_cusd, "Send CUSD commands to the mobile"),
198 };
199 
200 /* App stuff */
201 static char *app_mblstatus = "MobileStatus";
202 static char *mblstatus_synopsis = "MobileStatus(Device,Variable)";
203 static char *mblstatus_desc =
204 "MobileStatus(Device,Variable)\n"
205 " Device - Id of mobile device from mobile.conf\n"
206 " Variable - Variable to store status in will be 1-3.\n"
207 " In order, Disconnected, Connected & Free, Connected & Busy.\n";
208 
209 static char *app_mblsendsms = "MobileSendSMS";
210 static char *mblsendsms_synopsis = "MobileSendSMS(Device,Dest,Message)";
211 static char *mblsendsms_desc =
212 "MobileSendSms(Device,Dest,Message)\n"
213 " Device - Id of device from mobile.conf\n"
214 " Dest - destination\n"
215 " Message - text of the message\n";
216 
217 static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, struct cidinfo *cidinfo,
218  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor);
219 static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
220  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
221 static int mbl_call(struct ast_channel *ast, const char *dest, int timeout);
222 static int mbl_hangup(struct ast_channel *ast);
223 static int mbl_answer(struct ast_channel *ast);
224 static int mbl_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
225 static struct ast_frame *mbl_read(struct ast_channel *ast);
226 static int mbl_write(struct ast_channel *ast, struct ast_frame *frame);
227 static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
228 static int mbl_devicestate(const char *data);
229 
230 static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen);
231 
232 static int mbl_queue_control(struct mbl_pvt *pvt, enum ast_control_frame_type control);
233 static int mbl_queue_hangup(struct mbl_pvt *pvt);
234 static int mbl_ast_hangup(struct mbl_pvt *pvt);
235 static int mbl_has_service(struct mbl_pvt *pvt);
236 
237 static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel);
238 static int rfcomm_write(int rsock, char *buf);
239 static int rfcomm_write_full(int rsock, char *buf, size_t count);
240 static int rfcomm_wait(int rsock, int *ms);
241 static ssize_t rfcomm_read(int rsock, char *buf, size_t count);
242 
243 static int sco_connect(bdaddr_t src, bdaddr_t dst);
244 static int sco_write(int s, char *buf, int len);
245 static int sco_accept(int *id, int fd, short events, void *data);
246 static int sco_bind(struct adapter_pvt *adapter);
247 
248 static void *do_sco_listen(void *data);
249 static int sdp_search(char *addr, int profile);
250 
251 static int headset_send_ring(const void *data);
252 
253 /*
254  * bluetooth handsfree profile helpers
255  */
256 
257 #define HFP_HF_ECNR (1 << 0)
258 #define HFP_HF_CW (1 << 1)
259 #define HFP_HF_CID (1 << 2)
260 #define HFP_HF_VOICE (1 << 3)
261 #define HFP_HF_VOLUME (1 << 4)
262 #define HFP_HF_STATUS (1 << 5)
263 #define HFP_HF_CONTROL (1 << 6)
264 
265 #define HFP_AG_CW (1 << 0)
266 #define HFP_AG_ECNR (1 << 1)
267 #define HFP_AG_VOICE (1 << 2)
268 #define HFP_AG_RING (1 << 3)
269 #define HFP_AG_TAG (1 << 4)
270 #define HFP_AG_REJECT (1 << 5)
271 #define HFP_AG_STATUS (1 << 6)
272 #define HFP_AG_CONTROL (1 << 7)
273 #define HFP_AG_ERRORS (1 << 8)
274 
275 #define HFP_CIND_UNKNOWN -1
276 #define HFP_CIND_NONE 0
277 #define HFP_CIND_SERVICE 1
278 #define HFP_CIND_CALL 2
279 #define HFP_CIND_CALLSETUP 3
280 #define HFP_CIND_CALLHELD 4
281 #define HFP_CIND_SIGNAL 5
282 #define HFP_CIND_ROAM 6
283 #define HFP_CIND_BATTCHG 7
284 
285 /* call indicator values */
286 #define HFP_CIND_CALL_NONE 0
287 #define HFP_CIND_CALL_ACTIVE 1
288 
289 /* callsetup indicator values */
290 #define HFP_CIND_CALLSETUP_NONE 0
291 #define HFP_CIND_CALLSETUP_INCOMING 1
292 #define HFP_CIND_CALLSETUP_OUTGOING 2
293 #define HFP_CIND_CALLSETUP_ALERTING 3
294 
295 /* service indicator values */
296 #define HFP_CIND_SERVICE_NONE 0
297 #define HFP_CIND_SERVICE_AVAILABLE 1
298 
299 /*!
300  * \brief This struct holds HFP features that we support.
301  */
302 struct hfp_hf {
303  int ecnr:1; /*!< echo-cancel/noise reduction */
304  int cw:1; /*!< call waiting and three way calling */
305  int cid:1; /*!< cli presentation (callier id) */
306  int voice:1; /*!< voice recognition activation */
307  int volume:1; /*!< remote volume control */
308  int status:1; /*!< enhanced call status */
309  int control:1; /*!< enhanced call control*/
310 };
311 
312 /*!
313  * \brief This struct holds HFP features the AG supports.
314  */
315 struct hfp_ag {
316  int cw:1; /*!< three way calling */
317  int ecnr:1; /*!< echo-cancel/noise reduction */
318  int voice:1; /*!< voice recognition */
319  int ring:1; /*!< in band ring tone capability */
320  int tag:1; /*!< attach a number to a voice tag */
321  int reject:1; /*!< ability to reject a call */
322  int status:1; /*!< enhanced call status */
323  int control:1; /*!< enhanced call control*/
324  int errors:1; /*!< extended error result codes*/
325 };
326 
327 /*!
328  * \brief This struct holds mappings for indications.
329  */
330 struct hfp_cind {
331  int service; /*!< whether we have service or not */
332  int call; /*!< call state */
333  int callsetup; /*!< bluetooth call setup indications */
334  int callheld; /*!< bluetooth call hold indications */
335  int signal; /*!< signal strength */
336  int roam; /*!< roaming indicator */
337  int battchg; /*!< battery charge indicator */
338 };
339 
340 
341 /*!
342  * \brief This struct holds state information about the current hfp connection.
343  */
344 struct hfp_pvt {
345  struct mbl_pvt *owner; /*!< the mbl_pvt struct that owns this struct */
346  int initialized:1; /*!< whether a service level connection exists or not */
347  int nocallsetup:1; /*!< whether we detected a callsetup indicator */
348  struct hfp_ag brsf; /*!< the supported feature set of the AG */
349  int cind_index[16]; /*!< the cind/ciev index to name mapping for this AG */
350  int cind_state[16]; /*!< the cind/ciev state for this AG */
351  struct hfp_cind cind_map; /*!< the cind name to index mapping for this AG */
352  int rsock; /*!< our rfcomm socket */
353  int rport; /*!< our rfcomm port */
354  int sent_alerting; /*!< have we sent alerting? */
355 };
356 
357 
358 /* Our supported features.
359  * we only support caller id
360  */
361 static struct hfp_hf hfp_our_brsf = {
362  .ecnr = 0,
363  .cw = 0,
364  .cid = 1,
365  .voice = 0,
366  .volume = 0,
367  .status = 0,
368  .control = 0,
369 };
370 
371 
372 static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value);
373 static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf);
374 static int parse_next_token(char string[], const int start, const char delim);
375 static int hfp_parse_cmti(struct hfp_pvt *hfp, char *buf);
376 static int hfp_parse_cmgr(struct hfp_pvt *hfp, char *buf, char **from_number, char **text);
377 static int hfp_parse_brsf(struct hfp_pvt *hfp, const char *buf);
378 static int hfp_parse_cind(struct hfp_pvt *hfp, char *buf);
379 static int hfp_parse_cind_test(struct hfp_pvt *hfp, char *buf);
380 static char *hfp_parse_cusd(struct hfp_pvt *hfp, char *buf);
381 
382 static int hfp_brsf2int(struct hfp_hf *hf);
383 static struct hfp_ag *hfp_int2brsf(int brsf, struct hfp_ag *ag);
384 
385 static int hfp_send_brsf(struct hfp_pvt *hfp, struct hfp_hf *brsf);
386 static int hfp_send_cind(struct hfp_pvt *hfp);
387 static int hfp_send_cind_test(struct hfp_pvt *hfp);
388 static int hfp_send_cmer(struct hfp_pvt *hfp, int status);
389 static int hfp_send_clip(struct hfp_pvt *hfp, int status);
390 static int hfp_send_vgs(struct hfp_pvt *hfp, int value);
391 
392 #if 0
393 static int hfp_send_vgm(struct hfp_pvt *hfp, int value);
394 #endif
395 static int hfp_send_dtmf(struct hfp_pvt *hfp, char digit);
396 static int hfp_send_cmgf(struct hfp_pvt *hfp, int mode);
397 static int hfp_send_cnmi(struct hfp_pvt *hfp);
398 static int hfp_send_cmgr(struct hfp_pvt *hfp, int index);
399 static int hfp_send_cmgs(struct hfp_pvt *hfp, const char *number);
400 static int hfp_send_sms_text(struct hfp_pvt *hfp, const char *message);
401 static int hfp_send_chup(struct hfp_pvt *hfp);
402 static int hfp_send_atd(struct hfp_pvt *hfp, const char *number);
403 static int hfp_send_ata(struct hfp_pvt *hfp);
404 static int hfp_send_cusd(struct hfp_pvt *hfp, const char *code);
405 
406 /*
407  * bluetooth headset profile helpers
408  */
409 static int hsp_send_ok(int rsock);
410 static int hsp_send_error(int rsock);
411 static int hsp_send_vgs(int rsock, int gain);
412 static int hsp_send_vgm(int rsock, int gain);
413 static int hsp_send_ring(int rsock);
414 
415 
416 /*
417  * Hayes AT command helpers
418  */
419 typedef enum {
420  /* errors */
421  AT_PARSE_ERROR = -2,
422  AT_READ_ERROR = -1,
423  AT_UNKNOWN = 0,
424  /* at responses */
425  AT_OK,
426  AT_ERROR,
427  AT_RING,
428  AT_BRSF,
429  AT_CIND,
430  AT_CIEV,
431  AT_CLIP,
432  AT_CMTI,
433  AT_CMGR,
434  AT_SMS_PROMPT,
435  AT_CMS_ERROR,
436  /* at commands */
437  AT_A,
438  AT_D,
439  AT_CHUP,
440  AT_CKPD,
441  AT_CMGS,
442  AT_VGM,
443  AT_VGS,
444  AT_VTS,
445  AT_CMGF,
446  AT_CNMI,
447  AT_CMER,
448  AT_CIND_TEST,
449  AT_CUSD,
450  AT_BUSY,
451  AT_NO_DIALTONE,
452  AT_NO_CARRIER,
453  AT_ECAM,
454 } at_message_t;
455 
456 static int at_match_prefix(char *buf, char *prefix);
457 static at_message_t at_read_full(int rsock, char *buf, size_t count);
458 static inline const char *at_msg2str(at_message_t msg);
459 
460 struct msg_queue_entry {
461  at_message_t expected;
462  at_message_t response_to;
463  void *data;
464 
465  AST_LIST_ENTRY(msg_queue_entry) entry;
466 };
467 
468 static int msg_queue_push(struct mbl_pvt *pvt, at_message_t expect, at_message_t response_to);
469 static int msg_queue_push_data(struct mbl_pvt *pvt, at_message_t expect, at_message_t response_to, void *data);
470 static struct msg_queue_entry *msg_queue_pop(struct mbl_pvt *pvt);
471 static void msg_queue_free_and_pop(struct mbl_pvt *pvt);
472 static void msg_queue_flush(struct mbl_pvt *pvt);
473 static struct msg_queue_entry *msg_queue_head(struct mbl_pvt *pvt);
474 
475 /*
476  * channel stuff
477  */
478 
479 static struct ast_channel_tech mbl_tech = {
480  .type = "Mobile",
481  .description = "Bluetooth Mobile Device Channel Driver",
482  .requester = mbl_request,
483  .call = mbl_call,
484  .hangup = mbl_hangup,
485  .answer = mbl_answer,
486  .send_digit_end = mbl_digit_end,
487  .read = mbl_read,
488  .write = mbl_write,
489  .fixup = mbl_fixup,
490  .devicestate = mbl_devicestate
491 };
492 
493 /* CLI Commands implementation */
494 
495 static char *handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
496 {
497  struct mbl_pvt *pvt;
498  char bdaddr[18];
499  char group[6];
500 
501 #define FORMAT1 "%-15.15s %-17.17s %-5.5s %-15.15s %-9.9s %-10.10s %-3.3s\n"
502 
503  switch (cmd) {
504  case CLI_INIT:
505  e->command = "mobile show devices";
506  e->usage =
507  "Usage: mobile show devices\n"
508  " Shows the state of Bluetooth Cell / Mobile devices.\n";
509  return NULL;
510  case CLI_GENERATE:
511  return NULL;
512  }
513 
514  if (a->argc != 3)
515  return CLI_SHOWUSAGE;
516 
517  ast_cli(a->fd, FORMAT1, "ID", "Address", "Group", "Adapter", "Connected", "State", "SMS");
519  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
520  ast_mutex_lock(&pvt->lock);
521  ba2str(&pvt->addr, bdaddr);
522  snprintf(group, sizeof(group), "%d", pvt->group);
523  ast_cli(a->fd, FORMAT1,
524  pvt->id,
525  bdaddr,
526  group,
527  pvt->adapter->id,
528  pvt->connected ? "Yes" : "No",
529  (!pvt->connected) ? "None" : (pvt->owner) ? "Busy" : (pvt->outgoing_sms || pvt->incoming_sms) ? "SMS" : (mbl_has_service(pvt)) ? "Free" : "No Service",
530  (pvt->has_sms) ? "Yes" : "No"
531  );
532  ast_mutex_unlock(&pvt->lock);
533  }
535 
536 #undef FORMAT1
537 
538  return CLI_SUCCESS;
539 }
540 
541 static char *handle_cli_mobile_search(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
542 {
543  struct adapter_pvt *adapter;
544  inquiry_info *ii = NULL;
545  int max_rsp, num_rsp;
546  int len, flags;
547  int i, phport, hsport;
548  char addr[19] = {0};
549  char name[31] = {0};
550 
551 #define FORMAT1 "%-17.17s %-30.30s %-6.6s %-7.7s %-4.4s\n"
552 #define FORMAT2 "%-17.17s %-30.30s %-6.6s %-7.7s %d\n"
553 
554  switch (cmd) {
555  case CLI_INIT:
556  e->command = "mobile search";
557  e->usage =
558  "Usage: mobile search\n"
559  " Searches for Bluetooth Cell / Mobile devices in range.\n";
560  return NULL;
561  case CLI_GENERATE:
562  return NULL;
563  }
564 
565  if (a->argc != 2)
566  return CLI_SHOWUSAGE;
567 
568  /* find a free adapter */
569  AST_RWLIST_RDLOCK(&adapters);
570  AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
571  if (!adapter->inuse)
572  break;
573  }
574  AST_RWLIST_UNLOCK(&adapters);
575 
576  if (!adapter) {
577  ast_cli(a->fd, "All Bluetooth adapters are in use at this time.\n");
578  return CLI_SUCCESS;
579  }
580 
581  len = 8;
582  max_rsp = 255;
583  flags = IREQ_CACHE_FLUSH;
584 
585  ii = ast_alloca(max_rsp * sizeof(inquiry_info));
586  num_rsp = hci_inquiry(adapter->dev_id, len, max_rsp, NULL, &ii, flags);
587  if (num_rsp > 0) {
588  ast_cli(a->fd, FORMAT1, "Address", "Name", "Usable", "Type", "Port");
589  for (i = 0; i < num_rsp; i++) {
590  ba2str(&(ii + i)->bdaddr, addr);
591  name[0] = 0x00;
592  if (hci_read_remote_name(adapter->hci_socket, &(ii + i)->bdaddr, sizeof(name) - 1, name, 0) < 0)
593  strcpy(name, "[unknown]");
594  phport = sdp_search(addr, HANDSFREE_AGW_PROFILE_ID);
595  if (!phport)
596  hsport = sdp_search(addr, HEADSET_PROFILE_ID);
597  else
598  hsport = 0;
599  ast_cli(a->fd, FORMAT2, addr, name, (phport > 0 || hsport > 0) ? "Yes" : "No",
600  (phport > 0) ? "Phone" : "Headset", (phport > 0) ? phport : hsport);
601  }
602  } else
603  ast_cli(a->fd, "No Bluetooth Cell / Mobile devices found.\n");
604 
605 #undef FORMAT1
606 #undef FORMAT2
607 
608  return CLI_SUCCESS;
609 }
610 
611 static char *handle_cli_mobile_rfcomm(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
612 {
613  char buf[128];
614  struct mbl_pvt *pvt = NULL;
615 
616  switch (cmd) {
617  case CLI_INIT:
618  e->command = "mobile rfcomm";
619  e->usage =
620  "Usage: mobile rfcomm <device ID> <command>\n"
621  " Send <command> to the rfcomm port on the device\n"
622  " with the specified <device ID>.\n";
623  return NULL;
624  case CLI_GENERATE:
625  return NULL;
626  }
627 
628  if (a->argc != 4)
629  return CLI_SHOWUSAGE;
630 
632  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
633  if (!strcmp(pvt->id, a->argv[2]))
634  break;
635  }
637 
638  if (!pvt) {
639  ast_cli(a->fd, "Device %s not found.\n", a->argv[2]);
640  goto e_return;
641  }
642 
643  ast_mutex_lock(&pvt->lock);
644  if (!pvt->connected) {
645  ast_cli(a->fd, "Device %s not connected.\n", a->argv[2]);
646  goto e_unlock_pvt;
647  }
648 
649  snprintf(buf, sizeof(buf), "%s\r", a->argv[3]);
650  rfcomm_write(pvt->rfcomm_socket, buf);
651  msg_queue_push(pvt, AT_OK, AT_UNKNOWN);
652 
653 e_unlock_pvt:
654  ast_mutex_unlock(&pvt->lock);
655 e_return:
656  return CLI_SUCCESS;
657 }
658 
659 static char *handle_cli_mobile_cusd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
660 {
661  char buf[128];
662  struct mbl_pvt *pvt = NULL;
663 
664  switch (cmd) {
665  case CLI_INIT:
666  e->command = "mobile cusd";
667  e->usage =
668  "Usage: mobile cusd <device ID> <command>\n"
669  " Send cusd <command> to the rfcomm port on the device\n"
670  " with the specified <device ID>.\n";
671  return NULL;
672  case CLI_GENERATE:
673  return NULL;
674  }
675 
676  if (a->argc != 4)
677  return CLI_SHOWUSAGE;
678 
680  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
681  if (!strcmp(pvt->id, a->argv[2]))
682  break;
683  }
685 
686  if (!pvt) {
687  ast_cli(a->fd, "Device %s not found.\n", a->argv[2]);
688  goto e_return;
689  }
690 
691  ast_mutex_lock(&pvt->lock);
692  if (!pvt->connected) {
693  ast_cli(a->fd, "Device %s not connected.\n", a->argv[2]);
694  goto e_unlock_pvt;
695  }
696 
697  snprintf(buf, sizeof(buf), "%s", a->argv[3]);
698  if (hfp_send_cusd(pvt->hfp, buf) || msg_queue_push(pvt, AT_OK, AT_CUSD)) {
699  ast_cli(a->fd, "[%s] error sending CUSD\n", pvt->id);
700  goto e_unlock_pvt;
701  }
702 
703 e_unlock_pvt:
704  ast_mutex_unlock(&pvt->lock);
705 e_return:
706  return CLI_SUCCESS;
707 }
708 
709 /*
710 
711  Dialplan applications implementation
712 
713 */
714 
715 static int mbl_status_exec(struct ast_channel *ast, const char *data)
716 {
717 
718  struct mbl_pvt *pvt;
719  char *parse;
720  int stat;
721  char status[2];
722 
724  AST_APP_ARG(device);
725  AST_APP_ARG(variable);
726  );
727 
728  if (ast_strlen_zero(data))
729  return -1;
730 
731  parse = ast_strdupa(data);
732 
733  AST_STANDARD_APP_ARGS(args, parse);
734 
735  if (ast_strlen_zero(args.device) || ast_strlen_zero(args.variable))
736  return -1;
737 
738  stat = 1;
739 
741  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
742  if (!strcmp(pvt->id, args.device))
743  break;
744  }
746 
747  if (pvt) {
748  ast_mutex_lock(&pvt->lock);
749  if (pvt->connected)
750  stat = 2;
751  if (pvt->owner)
752  stat = 3;
753  ast_mutex_unlock(&pvt->lock);
754  }
755 
756  snprintf(status, sizeof(status), "%d", stat);
757  pbx_builtin_setvar_helper(ast, args.variable, status);
758 
759  return 0;
760 
761 }
762 
763 static int mbl_sendsms_exec(struct ast_channel *ast, const char *data)
764 {
765 
766  struct mbl_pvt *pvt;
767  char *parse, *message;
768 
770  AST_APP_ARG(device);
771  AST_APP_ARG(dest);
772  AST_APP_ARG(message);
773  );
774 
775  if (ast_strlen_zero(data))
776  return -1;
777 
778  parse = ast_strdupa(data);
779 
780  AST_STANDARD_APP_ARGS(args, parse);
781 
782  if (ast_strlen_zero(args.device)) {
783  ast_log(LOG_ERROR,"NULL device for message -- SMS will not be sent.\n");
784  return -1;
785  }
786 
787  if (ast_strlen_zero(args.dest)) {
788  ast_log(LOG_ERROR,"NULL destination for message -- SMS will not be sent.\n");
789  return -1;
790  }
791 
792  if (ast_strlen_zero(args.message)) {
793  ast_log(LOG_ERROR,"NULL Message to be sent -- SMS will not be sent.\n");
794  return -1;
795  }
796 
798  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
799  if (!strcmp(pvt->id, args.device))
800  break;
801  }
803 
804  if (!pvt) {
805  ast_log(LOG_ERROR,"Bluetooth device %s wasn't found in the list -- SMS will not be sent.\n", args.device);
806  goto e_return;
807  }
808 
809  ast_mutex_lock(&pvt->lock);
810  if (!pvt->connected) {
811  ast_log(LOG_ERROR,"Bluetooth device %s wasn't connected -- SMS will not be sent.\n", args.device);
812  goto e_unlock_pvt;
813  }
814 
815  if (!pvt->has_sms) {
816  ast_log(LOG_ERROR,"Bluetooth device %s doesn't handle SMS -- SMS will not be sent.\n", args.device);
817  goto e_unlock_pvt;
818  }
819 
820  message = ast_strdup(args.message);
821 
822  if (hfp_send_cmgs(pvt->hfp, args.dest)
823  || msg_queue_push_data(pvt, AT_SMS_PROMPT, AT_CMGS, message)) {
824 
825  ast_log(LOG_ERROR, "[%s] problem sending SMS message\n", pvt->id);
826  goto e_free_message;
827  }
828 
829  ast_mutex_unlock(&pvt->lock);
830 
831  return 0;
832 
833 e_free_message:
834  ast_free(message);
835 e_unlock_pvt:
836  ast_mutex_unlock(&pvt->lock);
837 e_return:
838  return -1;
839 }
840 
841 /*
842 
843  Channel Driver callbacks
844 
845 */
846 
847 static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, struct cidinfo *cidinfo,
848  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
849 {
850  struct ast_channel *chn;
851 
852  pvt->answered = 0;
853  pvt->alignment_count = 0;
854  pvt->alignment_detection_triggered = 0;
855  if (pvt->adapter->alignment_detection)
856  pvt->do_alignment_detection = 1;
857  else
858  pvt->do_alignment_detection = 0;
859 
860  ast_smoother_reset(pvt->bt_out_smoother, DEVICE_FRAME_SIZE);
861  ast_smoother_reset(pvt->bt_in_smoother, CHANNEL_FRAME_SIZE);
862  ast_dsp_digitreset(pvt->dsp);
863 
864  chn = ast_channel_alloc(1, state,
865  cidinfo ? cidinfo->cnum : NULL,
866  cidinfo ? cidinfo->cnam : NULL,
867  0, 0, pvt->context, assignedids, requestor, 0,
868  "Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff);
869  if (!chn) {
870  goto e_return;
871  }
872 
873  ast_channel_tech_set(chn, &mbl_tech);
874  ast_channel_nativeformats_set(chn, mbl_tech.capabilities);
875  ast_channel_set_rawreadformat(chn, DEVICE_FRAME_FORMAT);
876  ast_channel_set_rawwriteformat(chn, DEVICE_FRAME_FORMAT);
877  ast_channel_set_writeformat(chn, DEVICE_FRAME_FORMAT);
878  ast_channel_set_readformat(chn, DEVICE_FRAME_FORMAT);
879  ast_channel_tech_pvt_set(chn, pvt);
880 
881  if (state == AST_STATE_RING)
882  ast_channel_rings_set(chn, 1);
883 
884  ast_channel_language_set(chn, "en");
885  pvt->owner = chn;
886 
887  if (pvt->sco_socket != -1) {
888  ast_channel_set_fd(chn, 0, pvt->sco_socket);
889  }
890  ast_channel_unlock(chn);
891 
892  return chn;
893 
894 e_return:
895  return NULL;
896 }
897 
898 static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
899  const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
900 {
901 
902  struct ast_channel *chn = NULL;
903  struct mbl_pvt *pvt;
904  char *dest_dev = NULL;
905  char *dest_num = NULL;
906  int group = -1;
907 
908  if (!data) {
909  ast_log(LOG_WARNING, "Channel requested with no data\n");
910  *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
911  return NULL;
912  }
913 
914  if (ast_format_cap_iscompatible_format(cap, DEVICE_FRAME_FORMAT) == AST_FORMAT_CMP_NOT_EQUAL) {
915  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
916  ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
917  *cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
918  return NULL;
919  }
920 
921  dest_dev = ast_strdupa(data);
922 
923  dest_num = strchr(dest_dev, '/');
924  if (dest_num)
925  *dest_num++ = 0x00;
926 
927  if (((dest_dev[0] == 'g') || (dest_dev[0] == 'G')) && ((dest_dev[1] >= '0') && (dest_dev[1] <= '9'))) {
928  group = atoi(&dest_dev[1]);
929  }
930 
931  /* Find requested device and make sure it's connected. */
933  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
934  if (group > -1 && pvt->group == group && pvt->connected && !pvt->owner) {
935  if (!mbl_has_service(pvt)) {
936  continue;
937  }
938 
939  break;
940  } else if (!strcmp(pvt->id, dest_dev)) {
941  break;
942  }
943  }
945  if (!pvt || !pvt->connected || pvt->owner) {
946  ast_log(LOG_WARNING, "Request to call on device %s which is not connected / already in use.\n", dest_dev);
947  *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
948  return NULL;
949  }
950 
951  if ((pvt->type == MBL_TYPE_PHONE) && !dest_num) {
952  ast_log(LOG_WARNING, "Can't determine destination number.\n");
953  *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
954  return NULL;
955  }
956 
957  ast_mutex_lock(&pvt->lock);
958  chn = mbl_new(AST_STATE_DOWN, pvt, NULL, assignedids, requestor);
959  ast_mutex_unlock(&pvt->lock);
960  if (!chn) {
961  ast_log(LOG_WARNING, "Unable to allocate channel structure.\n");
962  *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
963  return NULL;
964  }
965 
966  return chn;
967 
968 }
969 
970 static int mbl_call(struct ast_channel *ast, const char *dest, int timeout)
971 {
972  struct mbl_pvt *pvt;
973  char *dest_dev;
974  char *dest_num = NULL;
975 
976  dest_dev = ast_strdupa(dest);
977 
978  pvt = ast_channel_tech_pvt(ast);
979 
980  if (pvt->type == MBL_TYPE_PHONE) {
981  dest_num = strchr(dest_dev, '/');
982  if (!dest_num) {
983  ast_log(LOG_WARNING, "Cant determine destination number.\n");
984  return -1;
985  }
986  *dest_num++ = 0x00;
987  }
988 
990  ast_log(LOG_WARNING, "mbl_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
991  return -1;
992  }
993 
994  ast_debug(1, "Calling %s on %s\n", dest, ast_channel_name(ast));
995 
996  ast_mutex_lock(&pvt->lock);
997  if (pvt->type == MBL_TYPE_PHONE) {
998  if (hfp_send_atd(pvt->hfp, dest_num)) {
999  ast_mutex_unlock(&pvt->lock);
1000  ast_log(LOG_ERROR, "error sending ATD command on %s\n", pvt->id);
1001  return -1;
1002  }
1003  pvt->hangupcause = 0;
1004  pvt->needchup = 1;
1005  msg_queue_push(pvt, AT_OK, AT_D);
1006  } else {
1007  if (hsp_send_ring(pvt->rfcomm_socket)) {
1008  ast_log(LOG_ERROR, "[%s] error ringing device\n", pvt->id);
1009  ast_mutex_unlock(&pvt->lock);
1010  return -1;
1011  }
1012 
1013  if ((pvt->ring_sched_id = ast_sched_add(pvt->sched, 6000, headset_send_ring, pvt)) == -1) {
1014  ast_log(LOG_ERROR, "[%s] error ringing device\n", pvt->id);
1015  ast_mutex_unlock(&pvt->lock);
1016  return -1;
1017  }
1018 
1019  pvt->outgoing = 1;
1020  pvt->needring = 1;
1021  }
1022  ast_mutex_unlock(&pvt->lock);
1023 
1024  return 0;
1025 
1026 }
1027 
1028 static int mbl_hangup(struct ast_channel *ast)
1029 {
1030 
1031  struct mbl_pvt *pvt;
1032 
1033  if (!ast_channel_tech_pvt(ast)) {
1034  ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
1035  return 0;
1036  }
1037  pvt = ast_channel_tech_pvt(ast);
1038 
1039  ast_debug(1, "[%s] hanging up device\n", pvt->id);
1040 
1041  ast_mutex_lock(&pvt->lock);
1042  ast_channel_set_fd(ast, 0, -1);
1043  close(pvt->sco_socket);
1044  pvt->sco_socket = -1;
1045 
1046  if (pvt->needchup) {
1047  hfp_send_chup(pvt->hfp);
1048  msg_queue_push(pvt, AT_OK, AT_CHUP);
1049  pvt->needchup = 0;
1050  }
1051 
1052  pvt->outgoing = 0;
1053  pvt->incoming = 0;
1054  pvt->needring = 0;
1055  pvt->owner = NULL;
1056  ast_channel_tech_pvt_set(ast, NULL);
1057 
1058  ast_mutex_unlock(&pvt->lock);
1059 
1061 
1062  return 0;
1063 
1064 }
1065 
1066 static int mbl_answer(struct ast_channel *ast)
1067 {
1068 
1069  struct mbl_pvt *pvt;
1070 
1071  pvt = ast_channel_tech_pvt(ast);
1072 
1073  if (pvt->type == MBL_TYPE_HEADSET)
1074  return 0;
1075 
1076  ast_mutex_lock(&pvt->lock);
1077  if (pvt->incoming) {
1078  hfp_send_ata(pvt->hfp);
1079  msg_queue_push(pvt, AT_OK, AT_A);
1080  pvt->answered = 1;
1081  }
1082  ast_mutex_unlock(&pvt->lock);
1083 
1084  return 0;
1085 
1086 }
1087 
1088 static int mbl_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
1089 {
1090  struct mbl_pvt *pvt = ast_channel_tech_pvt(ast);
1091 
1092  if (pvt->type == MBL_TYPE_HEADSET)
1093  return 0;
1094 
1095  ast_mutex_lock(&pvt->lock);
1096  if (hfp_send_dtmf(pvt->hfp, digit)) {
1097  ast_mutex_unlock(&pvt->lock);
1098  ast_debug(1, "[%s] error sending digit %c\n", pvt->id, digit);
1099  return -1;
1100  }
1101  msg_queue_push(pvt, AT_OK, AT_VTS);
1102  ast_mutex_unlock(&pvt->lock);
1103 
1104  ast_debug(1, "[%s] dialed %c\n", pvt->id, digit);
1105 
1106  return 0;
1107 }
1108 
1109 static struct ast_frame *mbl_read(struct ast_channel *ast)
1110 {
1111 
1112  struct mbl_pvt *pvt = ast_channel_tech_pvt(ast);
1113  struct ast_frame *fr = &ast_null_frame;
1114  int r;
1115 
1116  ast_debug(3, "*** mbl_read()\n");
1117 
1118  while (ast_mutex_trylock(&pvt->lock)) {
1119  CHANNEL_DEADLOCK_AVOIDANCE(ast);
1120  }
1121 
1122  if (!pvt->owner || pvt->sco_socket == -1) {
1123  goto e_return;
1124  }
1125 
1126  memset(&pvt->fr, 0x00, sizeof(struct ast_frame));
1127  pvt->fr.frametype = AST_FRAME_VOICE;
1128  pvt->fr.subclass.format = DEVICE_FRAME_FORMAT;
1129  pvt->fr.src = "Mobile";
1130  pvt->fr.offset = AST_FRIENDLY_OFFSET;
1131  pvt->fr.mallocd = 0;
1132  pvt->fr.delivery.tv_sec = 0;
1133  pvt->fr.delivery.tv_usec = 0;
1134  pvt->fr.data.ptr = pvt->io_buf + AST_FRIENDLY_OFFSET;
1135 
1136  do {
1137  if ((r = read(pvt->sco_socket, pvt->fr.data.ptr, DEVICE_FRAME_SIZE)) == -1) {
1138  if (errno != EAGAIN && errno != EINTR) {
1139  ast_debug(1, "[%s] read error %d, going to wait for new connection\n", pvt->id, errno);
1140  close(pvt->sco_socket);
1141  pvt->sco_socket = -1;
1142  ast_channel_set_fd(ast, 0, -1);
1143  }
1144  goto e_return;
1145  }
1146 
1147  pvt->fr.datalen = r;
1148  pvt->fr.samples = r / 2;
1149 
1150  if (pvt->do_alignment_detection)
1151  do_alignment_detection(pvt, pvt->fr.data.ptr, r);
1152 
1153  ast_smoother_feed(pvt->bt_in_smoother, &pvt->fr);
1154  fr = ast_smoother_read(pvt->bt_in_smoother);
1155  } while (fr == NULL);
1156  fr = ast_dsp_process(ast, pvt->dsp, fr);
1157 
1158  ast_mutex_unlock(&pvt->lock);
1159 
1160  return fr;
1161 
1162 e_return:
1163  ast_mutex_unlock(&pvt->lock);
1164  return fr;
1165 }
1166 
1167 static int mbl_write(struct ast_channel *ast, struct ast_frame *frame)
1168 {
1169 
1170  struct mbl_pvt *pvt = ast_channel_tech_pvt(ast);
1171  struct ast_frame *f;
1172 
1173  ast_debug(3, "*** mbl_write\n");
1174 
1175  if (frame->frametype != AST_FRAME_VOICE) {
1176  return 0;
1177  }
1178 
1179  while (ast_mutex_trylock(&pvt->lock)) {
1180  CHANNEL_DEADLOCK_AVOIDANCE(ast);
1181  }
1182 
1183  ast_smoother_feed(pvt->bt_out_smoother, frame);
1184 
1185  while ((f = ast_smoother_read(pvt->bt_out_smoother))) {
1186  sco_write(pvt->sco_socket, f->data.ptr, f->datalen);
1187  }
1188 
1189  ast_mutex_unlock(&pvt->lock);
1190 
1191  return 0;
1192 
1193 }
1194 
1195 static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1196 {
1197 
1198  struct mbl_pvt *pvt = ast_channel_tech_pvt(newchan);
1199 
1200  if (!pvt) {
1201  ast_debug(1, "fixup failed, no pvt on newchan\n");
1202  return -1;
1203  }
1204 
1205  ast_mutex_lock(&pvt->lock);
1206  if (pvt->owner == oldchan)
1207  pvt->owner = newchan;
1208  ast_mutex_unlock(&pvt->lock);
1209 
1210  return 0;
1211 
1212 }
1213 
1214 static int mbl_devicestate(const char *data)
1215 {
1216 
1217  char *device;
1218  int res = AST_DEVICE_INVALID;
1219  struct mbl_pvt *pvt;
1220 
1221  device = ast_strdupa(S_OR(data, ""));
1222 
1223  ast_debug(1, "Checking device state for device %s\n", device);
1224 
1226  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
1227  if (!strcmp(pvt->id, device))
1228  break;
1229  }
1231 
1232  if (!pvt)
1233  return res;
1234 
1235  ast_mutex_lock(&pvt->lock);
1236  if (pvt->connected) {
1237  if (pvt->owner)
1238  res = AST_DEVICE_INUSE;
1239  else
1240  res = AST_DEVICE_NOT_INUSE;
1241 
1242  if (!mbl_has_service(pvt))
1243  res = AST_DEVICE_UNAVAILABLE;
1244  }
1245  ast_mutex_unlock(&pvt->lock);
1246 
1247  return res;
1248 
1249 }
1250 
1251 /*
1252 
1253  Callback helpers
1254 
1255 */
1256 
1257 /*
1258 
1259  do_alignment_detection()
1260 
1261  This routine attempts to detect where we get misaligned sco audio data from the bluetooth adaptor.
1262 
1263  Its enabled by alignmentdetect=yes under the adapter entry in mobile.conf
1264 
1265  Some adapters suffer a problem where occasionally they will byte shift the audio stream one byte to the right.
1266  The result is static or white noise on the inbound (from the adapter) leg of the call.
1267  This is characterised by a sudden jump in magnitude of the value of the 16 bit samples.
1268 
1269  Here we look at the first 4 48 byte frames. We average the absolute values of each sample in the frame,
1270  then average the sum of the averages of frames 1, 2, and 3.
1271  Frame zero is usually zero.
1272  If the end result > 100, and it usually is if we have the problem, set a flag and compensate by shifting the bytes
1273  for each subsequent frame during the call.
1274 
1275  If the result is <= 100 then clear the flag so we don't come back in here...
1276 
1277  This seems to work OK....
1278 
1279 */
1280 
1281 static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen)
1282 {
1283 
1284  int i;
1285  short a, *s;
1286  char *p;
1287 
1288  if (pvt->alignment_detection_triggered) {
1289  for (i=buflen, p=buf+buflen-1; i>0; i--, p--)
1290  *p = *(p-1);
1291  *(p+1) = 0;
1292  return;
1293  }
1294 
1295  if (pvt->alignment_count < 4) {
1296  s = (short *)buf;
1297  for (i=0, a=0; i<buflen/2; i++) {
1298  a += *s++;
1299  a /= i+1;
1300  }
1301  pvt->alignment_samples[pvt->alignment_count++] = a;
1302  return;
1303  }
1304 
1305  ast_debug(1, "Alignment Detection result is [%-d %-d %-d %-d]\n", pvt->alignment_samples[0], pvt->alignment_samples[1], pvt->alignment_samples[2], pvt->alignment_samples[3]);
1306 
1307  a = abs(pvt->alignment_samples[1]) + abs(pvt->alignment_samples[2]) + abs(pvt->alignment_samples[3]);
1308  a /= 3;
1309  if (a > 100) {
1310  pvt->alignment_detection_triggered = 1;
1311  ast_debug(1, "Alignment Detection Triggered.\n");
1312  } else
1313  pvt->do_alignment_detection = 0;
1314 
1315 }
1316 
1317 static int mbl_queue_control(struct mbl_pvt *pvt, enum ast_control_frame_type control)
1318 {
1319  for (;;) {
1320  if (pvt->owner) {
1321  if (ast_channel_trylock(pvt->owner)) {
1322  DEADLOCK_AVOIDANCE(&pvt->lock);
1323  } else {
1324  ast_queue_control(pvt->owner, control);
1325  ast_channel_unlock(pvt->owner);
1326  break;
1327  }
1328  } else
1329  break;
1330  }
1331  return 0;
1332 }
1333 
1334 static int mbl_queue_hangup(struct mbl_pvt *pvt)
1335 {
1336  for (;;) {
1337  if (pvt->owner) {
1338  if (ast_channel_trylock(pvt->owner)) {
1339  DEADLOCK_AVOIDANCE(&pvt->lock);
1340  } else {
1341  if (pvt->hangupcause != 0) {
1342  ast_channel_hangupcause_set(pvt->owner, pvt->hangupcause);
1343  }
1344  ast_queue_hangup(pvt->owner);
1345  ast_channel_unlock(pvt->owner);
1346  break;
1347  }
1348  } else
1349  break;
1350  }
1351  return 0;
1352 }
1353 
1354 static int mbl_ast_hangup(struct mbl_pvt *pvt)
1355 {
1356  ast_hangup(pvt->owner);
1357  return 0;
1358 }
1359 
1360 /*!
1361  * \brief Check if a mobile device has service.
1362  * \param pvt a mbl_pvt struct
1363  * \retval 1 this device has service
1364  * \retval 0 no service
1365  *
1366  * \note This function will always indicate that service is available if the
1367  * given device does not support service indication.
1368  */
1369 static int mbl_has_service(struct mbl_pvt *pvt)
1370 {
1371 
1372  if (pvt->type != MBL_TYPE_PHONE)
1373  return 1;
1374 
1375  if (!pvt->hfp->cind_map.service)
1376  return 1;
1377 
1378  if (pvt->hfp->cind_state[pvt->hfp->cind_map.service] == HFP_CIND_SERVICE_AVAILABLE)
1379  return 1;
1380 
1381  return 0;
1382 }
1383 
1384 /*
1385 
1386  rfcomm helpers
1387 
1388 */
1389 
1390 static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel)
1391 {
1392 
1393  struct sockaddr_rc addr;
1394  int s;
1395 
1396  if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
1397  ast_debug(1, "socket() failed (%d).\n", errno);
1398  return -1;
1399  }
1400 
1401  memset(&addr, 0, sizeof(addr));
1402  addr.rc_family = AF_BLUETOOTH;
1403  bacpy(&addr.rc_bdaddr, &src);
1404  addr.rc_channel = (uint8_t) 0;
1405  if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1406  ast_debug(1, "bind() failed (%d).\n", errno);
1407  close(s);
1408  return -1;
1409  }
1410 
1411  memset(&addr, 0, sizeof(addr));
1412  addr.rc_family = AF_BLUETOOTH;
1413  bacpy(&addr.rc_bdaddr, &dst);
1414  addr.rc_channel = remote_channel;
1415  if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1416  ast_debug(1, "connect() failed (%d).\n", errno);
1417  close(s);
1418  return -1;
1419  }
1420 
1421  return s;
1422 
1423 }
1424 
1425 /*!
1426  * \brief Write to an rfcomm socket.
1427  * \param rsock the socket to write to
1428  * \param buf the null terminated buffer to write
1429  *
1430  * This function will write characters from buf. The buffer must be null
1431  * terminated.
1432  *
1433  * \retval -1 error
1434  * \retval 0 success
1435  */
1436 static int rfcomm_write(int rsock, char *buf)
1437 {
1438  return rfcomm_write_full(rsock, buf, strlen(buf));
1439 }
1440 
1441 
1442 /*!
1443  * \brief Write to an rfcomm socket.
1444  * \param rsock the socket to write to
1445  * \param buf the buffer to write
1446  * \param count the number of characters from the buffer to write
1447  *
1448  * This function will write count characters from buf. It will always write
1449  * count chars unless it encounters an error.
1450  *
1451  * \retval -1 error
1452  * \retval 0 success
1453  */
1454 static int rfcomm_write_full(int rsock, char *buf, size_t count)
1455 {
1456  char *p = buf;
1457  ssize_t out_count;
1458 
1459  ast_debug(1, "rfcomm_write() (%d) [%.*s]\n", rsock, (int) count, buf);
1460  while (count > 0) {
1461  if ((out_count = write(rsock, p, count)) == -1) {
1462  ast_debug(1, "rfcomm_write() error [%d]\n", errno);
1463  return -1;
1464  }
1465  count -= out_count;
1466  p += out_count;
1467  }
1468 
1469  return 0;
1470 }
1471 
1472 /*!
1473  * \brief Wait for activity on an rfcomm socket.
1474  * \param rsock the socket to watch
1475  * \param ms a pointer to an int containing a timeout in ms
1476  * \return zero on timeout and the socket fd (non-zero) otherwise
1477  * \retval 0 timeout
1478  */
1479 static int rfcomm_wait(int rsock, int *ms)
1480 {
1481  int exception, outfd;
1482  outfd = ast_waitfor_n_fd(&rsock, 1, ms, &exception);
1483  if (outfd < 0)
1484  outfd = 0;
1485 
1486  return outfd;
1487 }
1488 
1489 #ifdef RFCOMM_READ_DEBUG
1490 #define rfcomm_read_debug(c) __rfcomm_read_debug(c)
1491 static void __rfcomm_read_debug(char c)
1492 {
1493  if (c == '\r')
1494  ast_debug(2, "rfcomm_read: \\r\n");
1495  else if (c == '\n')
1496  ast_debug(2, "rfcomm_read: \\n\n");
1497  else
1498  ast_debug(2, "rfcomm_read: %c\n", c);
1499 }
1500 #else
1501 #define rfcomm_read_debug(c)
1502 #endif
1503 
1504 /*!
1505  * \brief Append the given character to the given buffer and increase the
1506  * in_count.
1507  */
1508 static void inline rfcomm_append_buf(char **buf, size_t count, size_t *in_count, char c)
1509 {
1510  if (*in_count < count) {
1511  (*in_count)++;
1512  *(*buf)++ = c;
1513  }
1514 }
1515 
1516 /*!
1517  * \brief Read a character from the given stream and check if it matches what
1518  * we expected.
1519  */
1520 static int rfcomm_read_and_expect_char(int rsock, char *result, char expected)
1521 {
1522  int res;
1523  char c;
1524 
1525  if (!result)
1526  result = &c;
1527 
1528  if ((res = read(rsock, result, 1)) < 1) {
1529  return res;
1530  }
1531  rfcomm_read_debug(*result);
1532 
1533  if (*result != expected) {
1534  return -2;
1535  }
1536 
1537  return 1;
1538 }
1539 
1540 /*!
1541  * \brief Read a character from the given stream and append it to the given
1542  * buffer if it matches the expected character.
1543  */
1544 static int rfcomm_read_and_append_char(int rsock, char **buf, size_t count, size_t *in_count, char *result, char expected)
1545 {
1546  int res;
1547  char c;
1548 
1549  if (!result)
1550  result = &c;
1551 
1552  if ((res = rfcomm_read_and_expect_char(rsock, result, expected)) < 1) {
1553  return res;
1554  }
1555 
1556  rfcomm_append_buf(buf, count, in_count, *result);
1557  return 1;
1558 }
1559 
1560 /*!
1561  * \brief Read until \verbatim '\r\n'. \endverbatim
1562  * This function consumes the \verbatim'\r\n'\endverbatim but does not add it to buf.
1563  */
1564 static int rfcomm_read_until_crlf(int rsock, char **buf, size_t count, size_t *in_count)
1565 {
1566  int res;
1567  char c;
1568 
1569  while ((res = read(rsock, &c, 1)) == 1) {
1570  rfcomm_read_debug(c);
1571  if (c == '\r') {
1572  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\n')) == 1) {
1573  break;
1574  } else if (res == -2) {
1575  rfcomm_append_buf(buf, count, in_count, '\r');
1576  } else {
1577  rfcomm_append_buf(buf, count, in_count, '\r');
1578  break;
1579  }
1580  }
1581 
1582  rfcomm_append_buf(buf, count, in_count, c);
1583  }
1584  return res;
1585 }
1586 
1587 /*!
1588  * \brief Read the remainder of an AT SMS prompt.
1589  * \note the entire parsed string is \verbatim '\r\n> ' \endverbatim
1590  *
1591  * By the time this function is executed, only a ' ' is left to read.
1592  */
1593 static int rfcomm_read_sms_prompt(int rsock, char **buf, size_t count, size_t *in_count)
1594 {
1595  int res;
1596  if ((res = rfcomm_read_and_append_char(rsock, buf, count, in_count, NULL, ' ')) < 1)
1597  goto e_return;
1598 
1599  return 1;
1600 
1601 e_return:
1602  ast_log(LOG_ERROR, "error parsing SMS prompt on rfcomm socket\n");
1603  return res;
1604 }
1605 
1606 /*!
1607  * \brief Read until a \verbatim \r\nOK\r\n \endverbatim message.
1608  */
1609 static int rfcomm_read_until_ok(int rsock, char **buf, size_t count, size_t *in_count)
1610 {
1611  int res;
1612  char c;
1613 
1614  /* here, we read until finding a \r\n, then we read one character at a
1615  * time looking for the string '\r\nOK\r\n'. If we only find a partial
1616  * match, we place that in the buffer and try again. */
1617 
1618  for (;;) {
1619  if ((res = rfcomm_read_until_crlf(rsock, buf, count, in_count)) != 1) {
1620  break;
1621  }
1622 
1623  rfcomm_append_buf(buf, count, in_count, '\r');
1624  rfcomm_append_buf(buf, count, in_count, '\n');
1625 
1626  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\r')) != 1) {
1627  if (res != -2) {
1628  break;
1629  }
1630 
1631  rfcomm_append_buf(buf, count, in_count, c);
1632  continue;
1633  }
1634 
1635  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\n')) != 1) {
1636  if (res != -2) {
1637  break;
1638  }
1639 
1640  rfcomm_append_buf(buf, count, in_count, '\r');
1641  rfcomm_append_buf(buf, count, in_count, c);
1642  continue;
1643  }
1644  if ((res = rfcomm_read_and_expect_char(rsock, &c, 'O')) != 1) {
1645  if (res != -2) {
1646  break;
1647  }
1648 
1649  rfcomm_append_buf(buf, count, in_count, '\r');
1650  rfcomm_append_buf(buf, count, in_count, '\n');
1651  rfcomm_append_buf(buf, count, in_count, c);
1652  continue;
1653  }
1654 
1655  if ((res = rfcomm_read_and_expect_char(rsock, &c, 'K')) != 1) {
1656  if (res != -2) {
1657  break;
1658  }
1659 
1660  rfcomm_append_buf(buf, count, in_count, '\r');
1661  rfcomm_append_buf(buf, count, in_count, '\n');
1662  rfcomm_append_buf(buf, count, in_count, 'O');
1663  rfcomm_append_buf(buf, count, in_count, c);
1664  continue;
1665  }
1666 
1667  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\r')) != 1) {
1668  if (res != -2) {
1669  break;
1670  }
1671 
1672  rfcomm_append_buf(buf, count, in_count, '\r');
1673  rfcomm_append_buf(buf, count, in_count, '\n');
1674  rfcomm_append_buf(buf, count, in_count, 'O');
1675  rfcomm_append_buf(buf, count, in_count, 'K');
1676  rfcomm_append_buf(buf, count, in_count, c);
1677  continue;
1678  }
1679 
1680  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\n')) != 1) {
1681  if (res != -2) {
1682  break;
1683  }
1684 
1685  rfcomm_append_buf(buf, count, in_count, '\r');
1686  rfcomm_append_buf(buf, count, in_count, '\n');
1687  rfcomm_append_buf(buf, count, in_count, 'O');
1688  rfcomm_append_buf(buf, count, in_count, 'K');
1689  rfcomm_append_buf(buf, count, in_count, '\r');
1690  rfcomm_append_buf(buf, count, in_count, c);
1691  continue;
1692  }
1693 
1694  /* we have successfully parsed a '\r\nOK\r\n' string */
1695  return 1;
1696  }
1697 
1698  return res;
1699 }
1700 
1701 
1702 /*!
1703  * \brief Read the remainder of a +CMGR message.
1704  * \note the entire parsed string is \verbatim '+CMGR: ...\r\n...\r\n...\r\n...\r\nOK\r\n' \endverbatim
1705  */
1706 static int rfcomm_read_cmgr(int rsock, char **buf, size_t count, size_t *in_count)
1707 {
1708  int res;
1709 
1710  /* append the \r\n that was stripped by the calling function */
1711  rfcomm_append_buf(buf, count, in_count, '\r');
1712  rfcomm_append_buf(buf, count, in_count, '\n');
1713 
1714  if ((res = rfcomm_read_until_ok(rsock, buf, count, in_count)) != 1) {
1715  ast_log(LOG_ERROR, "error reading +CMGR message on rfcomm socket\n");
1716  }
1717 
1718  return res;
1719 }
1720 
1721 /*!
1722  * \brief Read and AT result code.
1723  * \note the entire parsed string is \verbatim '\r\n<result code>\r\n' \endverbatim
1724  */
1725 static int rfcomm_read_result(int rsock, char **buf, size_t count, size_t *in_count)
1726 {
1727  int res;
1728  char c;
1729 
1730  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\n')) < 1) {
1731  goto e_return;
1732  }
1733 
1734  if ((res = rfcomm_read_and_append_char(rsock, buf, count, in_count, &c, '>')) == 1) {
1735  return rfcomm_read_sms_prompt(rsock, buf, count, in_count);
1736  } else if (res != -2) {
1737  goto e_return;
1738  }
1739 
1740  rfcomm_append_buf(buf, count, in_count, c);
1741  res = rfcomm_read_until_crlf(rsock, buf, count, in_count);
1742 
1743  if (res != 1)
1744  return res;
1745 
1746  /* check for CMGR, which contains an embedded \r\n pairs terminated by
1747  * an \r\nOK\r\n message */
1748  if (*in_count >= 5 && !strncmp(*buf - *in_count, "+CMGR", 5)) {
1749  return rfcomm_read_cmgr(rsock, buf, count, in_count);
1750  }
1751 
1752  return 1;
1753 
1754 e_return:
1755  ast_log(LOG_ERROR, "error parsing AT result on rfcomm socket\n");
1756  return res;
1757 }
1758 
1759 /*!
1760  * \brief Read the remainder of an AT command.
1761  * \note the entire parsed string is \verbatim '<at command>\r' \endverbatim
1762  */
1763 static int rfcomm_read_command(int rsock, char **buf, size_t count, size_t *in_count)
1764 {
1765  int res;
1766  char c;
1767 
1768  while ((res = read(rsock, &c, 1)) == 1) {
1769  rfcomm_read_debug(c);
1770  /* stop when we get to '\r' */
1771  if (c == '\r')
1772  break;
1773 
1774  rfcomm_append_buf(buf, count, in_count, c);
1775  }
1776  return res;
1777 }
1778 
1779 /*!
1780  * \brief Read one Hayes AT message from an rfcomm socket.
1781  * \param rsock the rfcomm socket to read from
1782  * \param buf the buffer to store the result in
1783  * \param count the size of the buffer or the maximum number of characters to read
1784  *
1785  * Here we need to read complete Hayes AT messages. The AT message formats we
1786  * support are listed below.
1787  *
1788  * \verbatim
1789  * \r\n<result code>\r\n
1790  * <at command>\r
1791  * \r\n>
1792  * \endverbatim
1793  *
1794  * These formats correspond to AT result codes, AT commands, and the AT SMS
1795  * prompt respectively. When messages are read the leading and trailing \verbatim '\r' \endverbatim
1796  * and \verbatim '\n' \endverbatim characters are discarded. If the given buffer is not large enough
1797  * to hold the response, what does not fit in the buffer will be dropped.
1798  *
1799  * \note The rfcomm connection to the device is asynchronous, so there is no
1800  * guarantee that responses will be returned in a single read() call. We handle
1801  * this by blocking until we can read an entire response.
1802  *
1803  * \retval 0 end of file
1804  * \retval -1 read error
1805  * \retval -2 parse error
1806  * \retval other the number of characters added to buf
1807  */
1808 static ssize_t rfcomm_read(int rsock, char *buf, size_t count)
1809 {
1810  ssize_t res;
1811  size_t in_count = 0;
1812  char c;
1813 
1814  if ((res = rfcomm_read_and_expect_char(rsock, &c, '\r')) == 1) {
1815  res = rfcomm_read_result(rsock, &buf, count, &in_count);
1816  } else if (res == -2) {
1817  rfcomm_append_buf(&buf, count, &in_count, c);
1818  res = rfcomm_read_command(rsock, &buf, count, &in_count);
1819  }
1820 
1821  if (res < 1)
1822  return res;
1823  else
1824  return in_count;
1825 }
1826 
1827 /*
1828 
1829  sco helpers and callbacks
1830 
1831 */
1832 
1833 static int sco_connect(bdaddr_t src, bdaddr_t dst)
1834 {
1835 
1836  struct sockaddr_sco addr;
1837  int s;
1838 
1839  if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) {
1840  ast_debug(1, "socket() failed (%d).\n", errno);
1841  return -1;
1842  }
1843 
1844 /* XXX this does not work with the do_sco_listen() thread (which also bind()s
1845  * to this address). Also I am not sure if it is necessary. */
1846 #if 0
1847  memset(&addr, 0, sizeof(addr));
1848  addr.sco_family = AF_BLUETOOTH;
1849  bacpy(&addr.sco_bdaddr, &src);
1850  if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1851  ast_debug(1, "bind() failed (%d).\n", errno);
1852  close(s);
1853  return -1;
1854  }
1855 #endif
1856 
1857  memset(&addr, 0, sizeof(addr));
1858  addr.sco_family = AF_BLUETOOTH;
1859  bacpy(&addr.sco_bdaddr, &dst);
1860 
1861  if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1862  ast_debug(1, "sco connect() failed (%d).\n", errno);
1863  close(s);
1864  return -1;
1865  }
1866 
1867  return s;
1868 
1869 }
1870 
1871 static int sco_write(int s, char *buf, int len)
1872 {
1873 
1874  int r;
1875 
1876  if (s == -1) {
1877  ast_debug(3, "sco_write() not ready\n");
1878  return 0;
1879  }
1880 
1881  ast_debug(3, "sco_write()\n");
1882 
1883  r = write(s, buf, len);
1884  if (r == -1) {
1885  ast_debug(3, "sco write error %d\n", errno);
1886  return 0;
1887  }
1888 
1889  return 1;
1890 
1891 }
1892 
1893 /*!
1894  * \brief Accept SCO connections.
1895  * This function is an ast_io callback function used to accept incoming sco
1896  * audio connections.
1897  */
1898 static int sco_accept(int *id, int fd, short events, void *data)
1899 {
1900  struct adapter_pvt *adapter = (struct adapter_pvt *) data;
1901  struct sockaddr_sco addr;
1902  socklen_t addrlen;
1903  struct mbl_pvt *pvt;
1904  socklen_t len;
1905  char saddr[18];
1906  struct sco_options so;
1907  int sock;
1908 
1909  addrlen = sizeof(struct sockaddr_sco);
1910  if ((sock = accept(fd, (struct sockaddr *)&addr, &addrlen)) == -1) {
1911  ast_log(LOG_ERROR, "error accepting audio connection on adapter %s\n", adapter->id);
1912  return 0;
1913  }
1914 
1915  len = sizeof(so);
1916  getsockopt(sock, SOL_SCO, SCO_OPTIONS, &so, &len);
1917 
1918  ba2str(&addr.sco_bdaddr, saddr);
1919  ast_debug(1, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu);
1920 
1921  /* figure out which device this sco connection belongs to */
1922  pvt = NULL;
1924  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
1925  if (!bacmp(&pvt->addr, &addr.sco_bdaddr))
1926  break;
1927  }
1929  if (!pvt) {
1930  ast_log(LOG_WARNING, "could not find device for incoming audio connection\n");
1931  close(sock);
1932  return 1;
1933  }
1934 
1935  ast_mutex_lock(&pvt->lock);
1936  if (pvt->sco_socket != -1) {
1937  close(pvt->sco_socket);
1938  pvt->sco_socket = -1;
1939  }
1940 
1941  pvt->sco_socket = sock;
1942  if (pvt->owner) {
1943  ast_channel_set_fd(pvt->owner, 0, sock);
1944  } else {
1945  ast_debug(1, "incoming audio connection for pvt without owner\n");
1946  }
1947 
1948  ast_mutex_unlock(&pvt->lock);
1949 
1950  return 1;
1951 }
1952 
1953 /*!
1954  * \brief Bind an SCO listener socket for the given adapter.
1955  * \param adapter an adapter_pvt
1956  * \return -1 on error, non zero on success
1957  */
1958 static int sco_bind(struct adapter_pvt *adapter)
1959 {
1960  struct sockaddr_sco addr;
1961  int opt = 1;
1962 
1963  if ((adapter->sco_socket = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) {
1964  ast_log(LOG_ERROR, "Unable to create sco listener socket for adapter %s.\n", adapter->id);
1965  goto e_return;
1966  }
1967 
1968  memset(&addr, 0, sizeof(addr));
1969  addr.sco_family = AF_BLUETOOTH;
1970  bacpy(&addr.sco_bdaddr, &adapter->addr);
1971  if (bind(adapter->sco_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1972  ast_log(LOG_ERROR, "Unable to bind sco listener socket. (%d)\n", errno);
1973  goto e_close_socket;
1974  }
1975  if (setsockopt(adapter->sco_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
1976  ast_log(LOG_ERROR, "Unable to setsockopt sco listener socket.\n");
1977  goto e_close_socket;
1978  }
1979  if (listen(adapter->sco_socket, 5) < 0) {
1980  ast_log(LOG_ERROR, "Unable to listen sco listener socket.\n");
1981  goto e_close_socket;
1982  }
1983 
1984  return adapter->sco_socket;
1985 
1986 e_close_socket:
1987  close(adapter->sco_socket);
1988  adapter->sco_socket = -1;
1989 e_return:
1990  return -1;
1991 }
1992 
1993 
1994 /*
1995  * Hayes AT command helpers.
1996  */
1997 
1998 /*!
1999  * \brief Match the given buffer with the given prefix.
2000  * \param buf the buffer to match
2001  * \param prefix the prefix to match
2002  */
2003 static int at_match_prefix(char *buf, char *prefix)
2004 {
2005  return !strncmp(buf, prefix, strlen(prefix));
2006 }
2007 
2008 /*!
2009  * \brief Read an AT message and classify it.
2010  * \param rsock an rfcomm socket
2011  * \param buf the buffer to store the result in
2012  * \param count the size of the buffer or the maximum number of characters to read
2013  * \return the type of message received, in addition buf will contain the
2014  * message received and will be null terminated
2015  * \see at_read()
2016  */
2017 static at_message_t at_read_full(int rsock, char *buf, size_t count)
2018 {
2019  ssize_t s;
2020  if ((s = rfcomm_read(rsock, buf, count - 1)) < 1)
2021  return s;
2022  buf[s] = '\0';
2023 
2024  if (!strcmp("OK", buf)) {
2025  return AT_OK;
2026  } else if (!strcmp("ERROR", buf)) {
2027  return AT_ERROR;
2028  } else if (!strcmp("RING", buf)) {
2029  return AT_RING;
2030  } else if (!strcmp("AT+CKPD=200", buf)) {
2031  return AT_CKPD;
2032  } else if (!strcmp("> ", buf)) {
2033  return AT_SMS_PROMPT;
2034  } else if (at_match_prefix(buf, "+CMTI:")) {
2035  return AT_CMTI;
2036  } else if (at_match_prefix(buf, "+CIEV:")) {
2037  return AT_CIEV;
2038  } else if (at_match_prefix(buf, "+BRSF:")) {
2039  return AT_BRSF;
2040  } else if (at_match_prefix(buf, "+CIND:")) {
2041  return AT_CIND;
2042  } else if (at_match_prefix(buf, "+CLIP:")) {
2043  return AT_CLIP;
2044  } else if (at_match_prefix(buf, "+CMGR:")) {
2045  return AT_CMGR;
2046  } else if (at_match_prefix(buf, "+VGM:")) {
2047  return AT_VGM;
2048  } else if (at_match_prefix(buf, "+VGS:")) {
2049  return AT_VGS;
2050  } else if (at_match_prefix(buf, "+CMS ERROR:")) {
2051  return AT_CMS_ERROR;
2052  } else if (at_match_prefix(buf, "AT+VGM=")) {
2053  return AT_VGM;
2054  } else if (at_match_prefix(buf, "AT+VGS=")) {
2055  return AT_VGS;
2056  } else if (at_match_prefix(buf, "+CUSD:")) {
2057  return AT_CUSD;
2058  } else if (at_match_prefix(buf, "BUSY")) {
2059  return AT_BUSY;
2060  } else if (at_match_prefix(buf, "NO DIALTONE")) {
2061  return AT_NO_DIALTONE;
2062  } else if (at_match_prefix(buf, "NO CARRIER")) {
2063  return AT_NO_CARRIER;
2064  } else if (at_match_prefix(buf, "*ECAV:")) {
2065  return AT_ECAM;
2066  } else {
2067  return AT_UNKNOWN;
2068  }
2069 }
2070 
2071 /*!
2072  * \brief Get the string representation of the given AT message.
2073  * \param msg the message to process
2074  * \return a string describing the given message
2075  */
2076 static inline const char *at_msg2str(at_message_t msg)
2077 {
2078  switch (msg) {
2079  /* errors */
2080  case AT_PARSE_ERROR:
2081  return "PARSE ERROR";
2082  case AT_READ_ERROR:
2083  return "READ ERROR";
2084  default:
2085  case AT_UNKNOWN:
2086  return "UNKNOWN";
2087  /* at responses */
2088  case AT_OK:
2089  return "OK";
2090  case AT_ERROR:
2091  return "ERROR";
2092  case AT_RING:
2093  return "RING";
2094  case AT_BRSF:
2095  return "AT+BRSF";
2096  case AT_CIND:
2097  return "AT+CIND";
2098  case AT_CIEV:
2099  return "AT+CIEV";
2100  case AT_CLIP:
2101  return "AT+CLIP";
2102  case AT_CMTI:
2103  return "AT+CMTI";
2104  case AT_CMGR:
2105  return "AT+CMGR";
2106  case AT_SMS_PROMPT:
2107  return "SMS PROMPT";
2108  case AT_CMS_ERROR:
2109  return "+CMS ERROR";
2110  case AT_BUSY:
2111  return "BUSY";
2112  case AT_NO_DIALTONE:
2113  return "NO DIALTONE";
2114  case AT_NO_CARRIER:
2115  return "NO CARRIER";
2116  /* at commands */
2117  case AT_A:
2118  return "ATA";
2119  case AT_D:
2120  return "ATD";
2121  case AT_CHUP:
2122  return "AT+CHUP";
2123  case AT_CKPD:
2124  return "AT+CKPD";
2125  case AT_CMGS:
2126  return "AT+CMGS";
2127  case AT_VGM:
2128  return "AT+VGM";
2129  case AT_VGS:
2130  return "AT+VGS";
2131  case AT_VTS:
2132  return "AT+VTS";
2133  case AT_CMGF:
2134  return "AT+CMGF";
2135  case AT_CNMI:
2136  return "AT+CNMI";
2137  case AT_CMER:
2138  return "AT+CMER";
2139  case AT_CIND_TEST:
2140  return "AT+CIND=?";
2141  case AT_CUSD:
2142  return "AT+CUSD";
2143  case AT_ECAM:
2144  return "AT*ECAM";
2145  }
2146 }
2147 
2148 
2149 /*
2150  * bluetooth handsfree profile helpers
2151  */
2152 
2153  /*!
2154  * \brief Parse a ECAV event.
2155  * \param hfp an hfp_pvt struct
2156  * \param buf the buffer to parse (null terminated)
2157  * \return -1 on error (parse error) or a ECAM value on success
2158  *
2159  * Example:
2160  * \verbatim *ECAV: <ccid>,<ccstatus>,<calltype>[,<processid>]
2161  [,exitcause][,<number>,<type>] \endverbatim
2162  *
2163  * Example indicating busy:
2164  * \verbatim *ECAV: 1,7,1 \endverbatim
2165  */
2166 static int hfp_parse_ecav(struct hfp_pvt *hfp, char *buf)
2167 {
2168  int ccid = 0;
2169  int ccstatus = 0;
2170  int calltype = 0;
2171 
2172  if (!sscanf(buf, "*ECAV: %2d,%2d,%2d", &ccid, &ccstatus, &calltype)) {
2173  ast_debug(1, "[%s] error parsing ECAV event '%s'\n", hfp->owner->id, buf);
2174  return -1;
2175  }
2176 
2177  return ccstatus;
2178 }
2179 
2180 /*!
2181  * \brief Enable Sony Ericsson extensions / indications.
2182  * \param hfp an hfp_pvt struct
2183  */
2184 static int hfp_send_ecam(struct hfp_pvt *hfp)
2185 {
2186  return rfcomm_write(hfp->rsock, "AT*ECAM=1\r");
2187 }
2188 
2189 /*!
2190  * \brief Parse a CIEV event.
2191  * \param hfp an hfp_pvt struct
2192  * \param buf the buffer to parse (null terminated)
2193  * \param value a pointer to an int to store the event value in (can be NULL)
2194  * \return 0 on error (parse error, or unknown event) or a HFP_CIND_* value on
2195  * success
2196  */
2197 static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value)
2198 {
2199  int i, v;
2200  if (!value)
2201  value = &v;
2202 
2203  if (!sscanf(buf, "+CIEV: %d,%d", &i, value)) {
2204  ast_debug(2, "[%s] error parsing CIEV event '%s'\n", hfp->owner->id, buf);
2205  return HFP_CIND_NONE;
2206  }
2207 
2208  if (i >= ARRAY_LEN(hfp->cind_state)) {
2209  ast_debug(2, "[%s] CIEV event index too high (%s)\n", hfp->owner->id, buf);
2210  return HFP_CIND_NONE;
2211  }
2212 
2213  hfp->cind_state[i] = *value;
2214  return hfp->cind_index[i];
2215 }
2216 
2217 /*!
2218  * \brief Parse a CLIP event.
2219  * \param hfp an hfp_pvt struct
2220  * \param buf the buffer to parse (null terminated)
2221  * \note buf will be modified when the CID string is parsed
2222  * \return a cidinfo structure pointing to the cnam and cnum
2223  * data in buf. On parse errors, either or both pointers
2224  * will point to null strings
2225  */
2226 static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf)
2227 {
2228  int i;
2229  int tokens[6];
2230  char *cnamtmp;
2231  char delim = ' '; /* First token terminates with space */
2232  int invalid = 0; /* Number of invalid chars in cnam */
2233  struct cidinfo cidinfo = { NULL, NULL };
2234 
2235  /* parse clip info in the following format:
2236  * +CLIP: "123456789",128,...
2237  */
2238  ast_debug(3, "[%s] hfp_parse_clip is processing \"%s\"\n", hfp->owner->id, buf);
2239  tokens[0] = 0; /* First token starts in position 0 */
2240  for (i = 1; i < ARRAY_LEN(tokens); i++) {
2241  tokens[i] = parse_next_token(buf, tokens[i - 1], delim);
2242  delim = ','; /* Subsequent tokens terminate with comma */
2243  }
2244  ast_debug(3, "[%s] hfp_parse_clip found tokens: 0=%s, 1=%s, 2=%s, 3=%s, 4=%s, 5=%s\n",
2245  hfp->owner->id, &buf[tokens[0]], &buf[tokens[1]], &buf[tokens[2]],
2246  &buf[tokens[3]], &buf[tokens[4]], &buf[tokens[5]]);
2247 
2248  /* Clean up cnum, and make sure it is legitimate since it is untrusted. */
2249  cidinfo.cnum = ast_strip_quoted(&buf[tokens[1]], "\"", "\"");
2250  if (!ast_isphonenumber(cidinfo.cnum)) {
2251  ast_debug(1, "[%s] hfp_parse_clip invalid cidinfo.cnum data \"%s\" - deleting\n",
2252  hfp->owner->id, cidinfo.cnum);
2253  cidinfo.cnum = "";
2254  }
2255 
2256  /*
2257  * Some docs say tokens 2 and 3 including the commas are optional.
2258  * If absent, that would move CNAM back to token 3.
2259  */
2260  cidinfo.cnam = &buf[tokens[5]]; /* Assume it's in token 5 */
2261  if (buf[tokens[5]] == '\0' && buf[tokens[4]] == '\0') {
2262  /* Tokens 4 and 5 are empty. See if token 3 looks like CNAM (starts with ") */
2263  i = tokens[3];
2264  while (buf[i] == ' ') { /* Find the first non-blank */
2265  i++;
2266  }
2267  if (buf[i] == '"') {
2268  /* Starts with quote. Use this for CNAM. */
2269  cidinfo.cnam = &buf[i];
2270  }
2271  }
2272 
2273  /* Clean up CNAM. */
2274  cidinfo.cnam = ast_strip_quoted(cidinfo.cnam, "\"", "\"");
2275  for (cnamtmp = cidinfo.cnam; *cnamtmp != '\0'; cnamtmp++) {
2276  if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-,abcdefghijklmnopqrstuvwxyz_", *cnamtmp)) {
2277  *cnamtmp = '_'; /* Invalid. Replace with underscore. */
2278  invalid++;
2279  }
2280  }
2281  if (invalid) {
2282  ast_debug(2, "[%s] hfp_parse_clip replaced %d invalid byte(s) in cnam data\n",
2283  hfp->owner->id, invalid);
2284  }
2285  ast_debug(2, "[%s] hfp_parse_clip returns cnum=%s and cnam=%s\n",
2286  hfp->owner->id, cidinfo.cnum, cidinfo.cnam);
2287 
2288  return cidinfo;
2289 }
2290 
2291 /*!
2292  * \brief Terminate current token and return an index to start of the next token.
2293  * \param string the null-terminated string being parsed (will be altered!)
2294  * \param start where the current token starts
2295  * \param delim the token termination delimiter. \0 is also considered a terminator.
2296  * \return index of the next token. May be the same as this token if the string is
2297  * exhausted.
2298  */
2299 static int parse_next_token(char string[], const int start, const char delim)
2300 {
2301  int index;
2302  int quoting = 0;
2303 
2304  for (index = start; string[index] != 0; index++) {
2305  if ((string[index] == delim) && !quoting ) {
2306  /* Found the delimiter, outside of quotes. This is the end of the token. */
2307  string[index] = '\0'; /* Terminate this token. */
2308  index++; /* Point the index to the start of the next token. */
2309  break; /* We're done. */
2310  } else if (string[index] == '"' && !quoting) {
2311  /* Found a beginning quote mark. Remember it. */
2312  quoting = 1;
2313  } else if (string[index] == '"' ) {
2314  /* Found the end quote mark. */
2315  quoting = 0;
2316  }
2317  }
2318  return index;
2319 }
2320 
2321 /*!
2322  * \brief Parse a CMTI notification.
2323  * \param hfp an hfp_pvt struct
2324  * \param buf the buffer to parse (null terminated)
2325  * \note buf will be modified when the CMTI message is parsed
2326  * \return -1 on error (parse error) or the index of the new sms message
2327  */
2328 static int hfp_parse_cmti(struct hfp_pvt *hfp, char *buf)
2329 {
2330  int index = -1;
2331 
2332  /* parse cmti info in the following format:
2333  * +CMTI: <mem>,<index>
2334  */
2335  if (!sscanf(buf, "+CMTI: %*[^,],%d", &index)) {
2336  ast_debug(2, "[%s] error parsing CMTI event '%s'\n", hfp->owner->id, buf);
2337  return -1;
2338  }
2339 
2340  return index;
2341 }
2342 
2343 /*!
2344  * \brief Parse a CMGR message.
2345  * \param hfp an hfp_pvt struct
2346  * \param buf the buffer to parse (null terminated)
2347  * \param from_number a pointer to a char pointer which will store the from
2348  * number
2349  * \param text a pointer to a char pointer which will store the message text
2350  * \note buf will be modified when the CMGR message is parsed
2351  * \retval -1 parse error
2352  * \retval 0 success
2353  */
2354 static int hfp_parse_cmgr(struct hfp_pvt *hfp, char *buf, char **from_number, char **text)
2355 {
2356  int i, state;
2357  size_t s;
2358 
2359  /* parse cmgr info in the following format:
2360  * +CMGR: <msg status>,"+123456789",...\r\n
2361  * <message text>
2362  */
2363  state = 0;
2364  s = strlen(buf);
2365  for (i = 0; i < s && state != 6; i++) {
2366  switch (state) {
2367  case 0: /* search for start of the number section (,) */
2368  if (buf[i] == ',') {
2369  state++;
2370  }
2371  break;
2372  case 1: /* find the opening quote (") */
2373  if (buf[i] == '"') {
2374  state++;
2375  }
2376  break;
2377  case 2: /* mark the start of the number */
2378  if (from_number) {
2379  *from_number = &buf[i];
2380  state++;
2381  }
2382  /* fall through */
2383  case 3: /* search for the end of the number (") */
2384  if (buf[i] == '"') {
2385  buf[i] = '\0';
2386  state++;
2387  }
2388  break;
2389  case 4: /* search for the start of the message text (\n) */
2390  if (buf[i] == '\n') {
2391  state++;
2392  }
2393  break;
2394  case 5: /* mark the start of the message text */
2395  if (text) {
2396  *text = &buf[i];
2397  state++;
2398  }
2399  break;
2400  }
2401  }
2402 
2403  if (state != 6) {
2404  return -1;
2405  }
2406 
2407  return 0;
2408 }
2409 
2410 /*!
2411  * \brief Parse a CUSD answer.
2412  * \param hfp an hfp_pvt struct
2413  * \param buf the buffer to parse (null terminated)
2414  * \note buf will be modified when the CUSD string is parsed
2415  * \return NULL on error (parse error) or a pointer to the cusd message
2416  * information in buf
2417  */
2418 static char *hfp_parse_cusd(struct hfp_pvt *hfp, char *buf)
2419 {
2420  int i, message_start, message_end;
2421  char *cusd;
2422  size_t s;
2423 
2424  /* parse cusd message in the following format:
2425  * +CUSD: 0,"100,00 EURO, valid till 01.01.2010, you are using tariff "Mega Tariff". More informations *111#."
2426  */
2427  message_start = 0;
2428  message_end = 0;
2429  s = strlen(buf);
2430 
2431  /* Find the start of the message (") */
2432  for (i = 0; i < s; i++) {
2433  if (buf[i] == '"') {
2434  message_start = i + 1;
2435  break;
2436  }
2437  }
2438 
2439  if (message_start == 0 || message_start >= s) {
2440  return NULL;
2441  }
2442 
2443  /* Find the end of the message (") */
2444  for (i = s; i > 0; i--) {
2445  if (buf[i] == '"') {
2446  message_end = i;
2447  break;
2448  }
2449  }
2450 
2451  if (message_end == 0) {
2452  return NULL;
2453  }
2454 
2455  if (message_start >= message_end) {
2456  return NULL;
2457  }
2458 
2459  cusd = &buf[message_start];
2460  buf[message_end] = '\0';
2461 
2462  return cusd;
2463 }
2464 
2465 /*!
2466  * \brief Convert a hfp_hf struct to a BRSF int.
2467  * \param hf an hfp_hf brsf object
2468  * \return an integer representing the given brsf struct
2469  */
2470 static int hfp_brsf2int(struct hfp_hf *hf)
2471 {
2472  int brsf = 0;
2473 
2474  brsf |= hf->ecnr ? HFP_HF_ECNR : 0;
2475  brsf |= hf->cw ? HFP_HF_CW : 0;
2476  brsf |= hf->cid ? HFP_HF_CID : 0;
2477  brsf |= hf->voice ? HFP_HF_VOICE : 0;
2478  brsf |= hf->volume ? HFP_HF_VOLUME : 0;
2479  brsf |= hf->status ? HFP_HF_STATUS : 0;
2480  brsf |= hf->control ? HFP_HF_CONTROL : 0;
2481 
2482  return brsf;
2483 }
2484 
2485 /*!
2486  * \brief Convert a BRSF int to an hfp_ag struct.
2487  * \param brsf a brsf integer
2488  * \param ag a AG (hfp_ag) brsf object
2489  * \return a pointer to the given hfp_ag object populated with the values from
2490  * the given brsf integer
2491  */
2492 static struct hfp_ag *hfp_int2brsf(int brsf, struct hfp_ag *ag)
2493 {
2494  ag->cw = brsf & HFP_AG_CW ? 1 : 0;
2495  ag->ecnr = brsf & HFP_AG_ECNR ? 1 : 0;
2496  ag->voice = brsf & HFP_AG_VOICE ? 1 : 0;
2497  ag->ring = brsf & HFP_AG_RING ? 1 : 0;
2498  ag->tag = brsf & HFP_AG_TAG ? 1 : 0;
2499  ag->reject = brsf & HFP_AG_REJECT ? 1 : 0;
2500  ag->status = brsf & HFP_AG_STATUS ? 1 : 0;
2501  ag->control = brsf & HFP_AG_CONTROL ? 1 : 0;
2502  ag->errors = brsf & HFP_AG_ERRORS ? 1 : 0;
2503 
2504  return ag;
2505 }
2506 
2507 
2508 /*!
2509  * \brief Send a BRSF request.
2510  * \param hfp an hfp_pvt struct
2511  * \param brsf an hfp_hf brsf struct
2512  *
2513  * \retval 0 on success
2514  * \retval -1 on error
2515  */
2516 static int hfp_send_brsf(struct hfp_pvt *hfp, struct hfp_hf *brsf)
2517 {
2518  char cmd[32];
2519  snprintf(cmd, sizeof(cmd), "AT+BRSF=%d\r", hfp_brsf2int(brsf));
2520  return rfcomm_write(hfp->rsock, cmd);
2521 }
2522 
2523 /*!
2524  * \brief Send the CIND read command.
2525  * \param hfp an hfp_pvt struct
2526  */
2527 static int hfp_send_cind(struct hfp_pvt *hfp)
2528 {
2529  return rfcomm_write(hfp->rsock, "AT+CIND?\r");
2530 }
2531 
2532 /*!
2533  * \brief Send the CIND test command.
2534  * \param hfp an hfp_pvt struct
2535  */
2536 static int hfp_send_cind_test(struct hfp_pvt *hfp)
2537 {
2538  return rfcomm_write(hfp->rsock, "AT+CIND=?\r");
2539 }
2540 
2541 /*!
2542  * \brief Enable or disable indicator events reporting.
2543  * \param hfp an hfp_pvt struct
2544  * \param status enable or disable events reporting (should be 1 or 0)
2545  */
2546 static int hfp_send_cmer(struct hfp_pvt *hfp, int status)
2547 {
2548  char cmd[32];
2549  snprintf(cmd, sizeof(cmd), "AT+CMER=3,0,0,%d\r", status ? 1 : 0);
2550  return rfcomm_write(hfp->rsock, cmd);
2551 }
2552 
2553 /*!
2554  * \brief Send the current speaker gain level.
2555  * \param hfp an hfp_pvt struct
2556  * \param value the value to send (must be between 0 and 15)
2557  */
2558 static int hfp_send_vgs(struct hfp_pvt *hfp, int value)
2559 {
2560  char cmd[32];
2561  snprintf(cmd, sizeof(cmd), "AT+VGS=%d\r", value);
2562  return rfcomm_write(hfp->rsock, cmd);
2563 }
2564 
2565 #if 0
2566 /*!
2567  * \brief Send the current microphone gain level.
2568  * \param hfp an hfp_pvt struct
2569  * \param value the value to send (must be between 0 and 15)
2570  */
2571 static int hfp_send_vgm(struct hfp_pvt *hfp, int value)
2572 {
2573  char cmd[32];
2574  snprintf(cmd, sizeof(cmd), "AT+VGM=%d\r", value);
2575  return rfcomm_write(hfp->rsock, cmd);
2576 }
2577 #endif
2578 
2579 /*!
2580  * \brief Enable or disable calling line identification.
2581  * \param hfp an hfp_pvt struct
2582  * \param status enable or disable calling line identification (should be 1 or
2583  * 0)
2584  */
2585 static int hfp_send_clip(struct hfp_pvt *hfp, int status)
2586 {
2587  char cmd[32];
2588  snprintf(cmd, sizeof(cmd), "AT+CLIP=%d\r", status ? 1 : 0);
2589  return rfcomm_write(hfp->rsock, cmd);
2590 }
2591 
2592 /*!
2593  * \brief Send a DTMF command.
2594  * \param hfp an hfp_pvt struct
2595  * \param digit the dtmf digit to send
2596  * \return the result of rfcomm_write() or -1 on an invalid digit being sent
2597  */
2598 static int hfp_send_dtmf(struct hfp_pvt *hfp, char digit)
2599 {
2600  char cmd[10];
2601 
2602  switch(digit) {
2603  case '0':
2604  case '1':
2605  case '2':
2606  case '3':
2607  case '4':
2608  case '5':
2609  case '6':
2610  case '7':
2611  case '8':
2612  case '9':
2613  case '*':
2614  case '#':
2615  snprintf(cmd, sizeof(cmd), "AT+VTS=%c\r", digit);
2616  return rfcomm_write(hfp->rsock, cmd);
2617  default:
2618  return -1;
2619  }
2620 }
2621 
2622 /*!
2623  * \brief Set the SMS mode.
2624  * \param hfp an hfp_pvt struct
2625  * \param mode the sms mode (0 = PDU, 1 = Text)
2626  */
2627 static int hfp_send_cmgf(struct hfp_pvt *hfp, int mode)
2628 {
2629  char cmd[32];
2630  snprintf(cmd, sizeof(cmd), "AT+CMGF=%d\r", mode);
2631  return rfcomm_write(hfp->rsock, cmd);
2632 }
2633 
2634 /*!
2635  * \brief Setup SMS new message indication.
2636  * \param hfp an hfp_pvt struct
2637  */
2638 static int hfp_send_cnmi(struct hfp_pvt *hfp)
2639 {
2640  return rfcomm_write(hfp->rsock, "AT+CNMI=2,1,0,0,0\r");
2641 }
2642 
2643 /*!
2644  * \brief Read an SMS message.
2645  * \param hfp an hfp_pvt struct
2646  * \param index the location of the requested message
2647  */
2648 static int hfp_send_cmgr(struct hfp_pvt *hfp, int index)
2649 {
2650  char cmd[32];
2651  snprintf(cmd, sizeof(cmd), "AT+CMGR=%d\r", index);
2652  return rfcomm_write(hfp->rsock, cmd);
2653 }
2654 
2655 /*!
2656  * \brief Start sending an SMS message.
2657  * \param hfp an hfp_pvt struct
2658  * \param number the destination of the message
2659  */
2660 static int hfp_send_cmgs(struct hfp_pvt *hfp, const char *number)
2661 {
2662  char cmd[64];
2663  snprintf(cmd, sizeof(cmd), "AT+CMGS=\"%s\"\r", number);
2664  return rfcomm_write(hfp->rsock, cmd);
2665 }
2666 
2667 /*!
2668  * \brief Send the text of an SMS message.
2669  * \param hfp an hfp_pvt struct
2670  * \param message the text of the message
2671  */
2672 static int hfp_send_sms_text(struct hfp_pvt *hfp, const char *message)
2673 {
2674  char cmd[162];
2675  snprintf(cmd, sizeof(cmd), "%.160s\x1a", message);
2676  return rfcomm_write(hfp->rsock, cmd);
2677 }
2678 
2679 /*!
2680  * \brief Send AT+CHUP.
2681  * \param hfp an hfp_pvt struct
2682  */
2683 static int hfp_send_chup(struct hfp_pvt *hfp)
2684 {
2685  return rfcomm_write(hfp->rsock, "AT+CHUP\r");
2686 }
2687 
2688 /*!
2689  * \brief Send ATD.
2690  * \param hfp an hfp_pvt struct
2691  * \param number the number to send
2692  */
2693 static int hfp_send_atd(struct hfp_pvt *hfp, const char *number)
2694 {
2695  char cmd[64];
2696  snprintf(cmd, sizeof(cmd), "ATD%s;\r", number);
2697  return rfcomm_write(hfp->rsock, cmd);
2698 }
2699 
2700 /*!
2701  * \brief Send ATA.
2702  * \param hfp an hfp_pvt struct
2703  */
2704 static int hfp_send_ata(struct hfp_pvt *hfp)
2705 {
2706  return rfcomm_write(hfp->rsock, "ATA\r");
2707 }
2708 
2709 /*!
2710  * \brief Send CUSD.
2711  * \param hfp an hfp_pvt struct
2712  * \param code the CUSD code to send
2713  */
2714 static int hfp_send_cusd(struct hfp_pvt *hfp, const char *code)
2715 {
2716  char cmd[128];
2717  snprintf(cmd, sizeof(cmd), "AT+CUSD=1,\"%s\",15\r", code);
2718  return rfcomm_write(hfp->rsock, cmd);
2719 }
2720 
2721 /*!
2722  * \brief Parse BRSF data.
2723  * \param hfp an hfp_pvt struct
2724  * \param buf the buffer to parse (null terminated)
2725  */
2726 static int hfp_parse_brsf(struct hfp_pvt *hfp, const char *buf)
2727 {
2728  int brsf;
2729 
2730  if (!sscanf(buf, "+BRSF:%d", &brsf))
2731  return -1;
2732 
2733  hfp_int2brsf(brsf, &hfp->brsf);
2734 
2735  return 0;
2736 }
2737 
2738 /*!
2739  * \brief Parse and store the given indicator.
2740  * \param hfp an hfp_pvt struct
2741  * \param group the indicator group
2742  * \param indicator the indicator to parse
2743  */
2744 static int hfp_parse_cind_indicator(struct hfp_pvt *hfp, int group, char *indicator)
2745 {
2746  int value;
2747 
2748  /* store the current indicator */
2749  if (group >= ARRAY_LEN(hfp->cind_state)) {
2750  ast_debug(1, "ignoring CIND state '%s' for group %d, we only support up to %d indicators\n", indicator, group, (int) sizeof(hfp->cind_state));
2751  return -1;
2752  }
2753 
2754  if (!sscanf(indicator, "%d", &value)) {
2755  ast_debug(1, "error parsing CIND state '%s' for group %d\n", indicator, group);
2756  return -1;
2757  }
2758 
2759  hfp->cind_state[group] = value;
2760  return 0;
2761 }
2762 
2763 /*!
2764  * \brief Read the result of the AT+CIND? command.
2765  * \param hfp an hfp_pvt struct
2766  * \param buf the buffer to parse (null terminated)
2767  * \note hfp_send_cind_test() and hfp_parse_cind_test() should be called at
2768  * least once before this function is called.
2769  */
2770 static int hfp_parse_cind(struct hfp_pvt *hfp, char *buf)
2771 {
2772  int i, state, group;
2773  size_t s;
2774  char *indicator = NULL;
2775 
2776  /* parse current state of all of our indicators. The list is in the
2777  * following format:
2778  * +CIND: 1,0,2,0,0,0,0
2779  */
2780  group = 0;
2781  state = 0;
2782  s = strlen(buf);
2783  for (i = 0; i < s; i++) {
2784  switch (state) {
2785  case 0: /* search for start of the status indicators (a space) */
2786  if (buf[i] == ' ') {
2787  group++;
2788  state++;
2789  }
2790  break;
2791  case 1: /* mark this indicator */
2792  indicator = &buf[i];
2793  state++;
2794  break;
2795  case 2: /* search for the start of the next indicator (a comma) */
2796  if (buf[i] == ',') {
2797  buf[i] = '\0';
2798 
2799  hfp_parse_cind_indicator(hfp, group, indicator);
2800 
2801  group++;
2802  state = 1;
2803  }
2804  break;
2805  }
2806  }
2807 
2808  /* store the last indicator */
2809  if (state == 2)
2810  hfp_parse_cind_indicator(hfp, group, indicator);
2811 
2812  return 0;
2813 }
2814 
2815 /*!
2816  * \brief Parse the result of the AT+CIND=? command.
2817  * \param hfp an hfp_pvt struct
2818  * \param buf the buffer to parse (null terminated)
2819  */
2820 static int hfp_parse_cind_test(struct hfp_pvt *hfp, char *buf)
2821 {
2822  int i, state, group;
2823  size_t s;
2824  char *indicator = NULL;
2825 
2826  hfp->nocallsetup = 1;
2827 
2828  /* parse the indications list. It is in the follwing format:
2829  * +CIND: ("ind1",(0-1)),("ind2",(0-5))
2830  */
2831  group = 0;
2832  state = 0;
2833  s = strlen(buf);
2834  for (i = 0; i < s; i++) {
2835  switch (state) {
2836  case 0: /* search for start of indicator block */
2837  if (buf[i] == '(') {
2838  group++;
2839  state++;
2840  }
2841  break;
2842  case 1: /* search for '"' in indicator block */
2843  if (buf[i] == '"') {
2844  state++;
2845  }
2846  break;
2847  case 2: /* mark the start of the indicator name */
2848  indicator = &buf[i];
2849  state++;
2850  break;
2851  case 3: /* look for the end of the indicator name */
2852  if (buf[i] == '"') {
2853  buf[i] = '\0';
2854  state++;
2855  }
2856  break;
2857  case 4: /* find the start of the value range */
2858  if (buf[i] == '(') {
2859  state++;
2860  }
2861  break;
2862  case 5: /* mark the start of the value range */
2863  state++;
2864  break;
2865  case 6: /* find the end of the value range */
2866  if (buf[i] == ')') {
2867  buf[i] = '\0';
2868  state++;
2869  }
2870  break;
2871  case 7: /* process the values we found */
2872  if (group < sizeof(hfp->cind_index)) {
2873  if (!strcmp(indicator, "service")) {
2874  hfp->cind_map.service = group;
2875  hfp->cind_index[group] = HFP_CIND_SERVICE;
2876  } else if (!strcmp(indicator, "call")) {
2877  hfp->cind_map.call = group;
2878  hfp->cind_index[group] = HFP_CIND_CALL;
2879  } else if (!strcmp(indicator, "callsetup")) {
2880  hfp->nocallsetup = 0;
2881  hfp->cind_map.callsetup = group;
2882  hfp->cind_index[group] = HFP_CIND_CALLSETUP;
2883  } else if (!strcmp(indicator, "call_setup")) { /* non standard call setup identifier */
2884  hfp->nocallsetup = 0;
2885  hfp->cind_map.callsetup = group;
2886  hfp->cind_index[group] = HFP_CIND_CALLSETUP;
2887  } else if (!strcmp(indicator, "callheld")) {
2888  hfp->cind_map.callheld = group;
2889  hfp->cind_index[group] = HFP_CIND_CALLHELD;
2890  } else if (!strcmp(indicator, "signal")) {
2891  hfp->cind_map.signal = group;
2892  hfp->cind_index[group] = HFP_CIND_SIGNAL;
2893  } else if (!strcmp(indicator, "roam")) {
2894  hfp->cind_map.roam = group;
2895  hfp->cind_index[group] = HFP_CIND_ROAM;
2896  } else if (!strcmp(indicator, "battchg")) {
2897  hfp->cind_map.battchg = group;
2898  hfp->cind_index[group] = HFP_CIND_BATTCHG;
2899  } else {
2900  hfp->cind_index[group] = HFP_CIND_UNKNOWN;
2901  ast_debug(2, "ignoring unknown CIND indicator '%s'\n", indicator);
2902  }
2903  } else {
2904  ast_debug(1, "can't store indicator %d (%s), we only support up to %d indicators", group, indicator, (int) sizeof(hfp->cind_index));
2905  }
2906 
2907  state = 0;
2908  break;
2909  }
2910  }
2911 
2912  hfp->owner->no_callsetup = hfp->nocallsetup;
2913 
2914  return 0;
2915 }
2916 
2917 
2918 /*
2919  * Bluetooth Headset Profile helpers
2920  */
2921 
2922 /*!
2923  * \brief Send an OK AT response.
2924  * \param rsock the rfcomm socket to use
2925  */
2926 static int hsp_send_ok(int rsock)
2927 {
2928  return rfcomm_write(rsock, "\r\nOK\r\n");
2929 }
2930 
2931 /*!
2932  * \brief Send an ERROR AT response.
2933  * \param rsock the rfcomm socket to use
2934  */
2935 static int hsp_send_error(int rsock)
2936 {
2937  return rfcomm_write(rsock, "\r\nERROR\r\n");
2938 }
2939 
2940 /*!
2941  * \brief Send a speaker gain unsolicited AT response
2942  * \param rsock the rfcomm socket to use
2943  * \param gain the speaker gain value
2944  */
2945 static int hsp_send_vgs(int rsock, int gain)
2946 {
2947  char cmd[32];
2948  snprintf(cmd, sizeof(cmd), "\r\n+VGS=%d\r\n", gain);
2949  return rfcomm_write(rsock, cmd);
2950 }
2951 
2952 /*!
2953  * \brief Send a microphone gain unsolicited AT response
2954  * \param rsock the rfcomm socket to use
2955  * \param gain the microphone gain value
2956  */
2957 static int hsp_send_vgm(int rsock, int gain)
2958 {
2959  char cmd[32];
2960  snprintf(cmd, sizeof(cmd), "\r\n+VGM=%d\r\n", gain);
2961  return rfcomm_write(rsock, cmd);
2962 }
2963 
2964 /*!
2965  * \brief Send a RING unsolicited AT response.
2966  * \param rsock the rfcomm socket to use
2967  */
2968 static int hsp_send_ring(int rsock)
2969 {
2970  return rfcomm_write(rsock, "\r\nRING\r\n");
2971 }
2972 
2973 /*
2974  * message queue functions
2975  */
2976 
2977 /*!
2978  * \brief Add an item to the back of the queue.
2979  * \param pvt a mbl_pvt structure
2980  * \param expect the msg we expect to receive
2981  * \param response_to the message that was sent to generate the expected
2982  * response
2983  */
2984 static int msg_queue_push(struct mbl_pvt *pvt, at_message_t expect, at_message_t response_to)
2985 {
2986  struct msg_queue_entry *msg;
2987  if (!(msg = ast_calloc(1, sizeof(*msg)))) {
2988  return -1;
2989  }
2990  msg->expected = expect;
2991  msg->response_to = response_to;
2992 
2993  AST_LIST_INSERT_TAIL(&pvt->msg_queue, msg, entry);
2994  return 0;
2995 }
2996 
2997 /*!
2998  * \brief Add an item to the back of the queue with data.
2999  * \param pvt a mbl_pvt structure
3000  * \param expect the msg we expect to receive
3001  * \param response_to the message that was sent to generate the expected
3002  * response
3003  * \param data data associated with this message, it will be freed when the
3004  * message is freed
3005  */
3006 static int msg_queue_push_data(struct mbl_pvt *pvt, at_message_t expect, at_message_t response_to, void *data)
3007 {
3008  struct msg_queue_entry *msg;
3009  if (!(msg = ast_calloc(1, sizeof(*msg)))) {
3010  return -1;
3011  }
3012  msg->expected = expect;
3013  msg->response_to = response_to;
3014  msg->data = data;
3015 
3016  AST_LIST_INSERT_TAIL(&pvt->msg_queue, msg, entry);
3017  return 0;
3018 }
3019 
3020 /*!
3021  * \brief Remove an item from the front of the queue.
3022  * \param pvt a mbl_pvt structure
3023  * \return a pointer to the removed item
3024  */
3025 static struct msg_queue_entry *msg_queue_pop(struct mbl_pvt *pvt)
3026 {
3027  return AST_LIST_REMOVE_HEAD(&pvt->msg_queue, entry);
3028 }
3029 
3030 /*!
3031  * \brief Remove an item from the front of the queue, and free it.
3032  * \param pvt a mbl_pvt structure
3033  */
3034 static void msg_queue_free_and_pop(struct mbl_pvt *pvt)
3035 {
3036  struct msg_queue_entry *msg;
3037  if ((msg = msg_queue_pop(pvt))) {
3038  if (msg->data)
3039  ast_free(msg->data);
3040  ast_free(msg);
3041  }
3042 }
3043 
3044 /*!
3045  * \brief Remove all items from the queue and free them.
3046  * \param pvt a mbl_pvt structure
3047  */
3048 static void msg_queue_flush(struct mbl_pvt *pvt)
3049 {
3050  struct msg_queue_entry *msg;
3051  while ((msg = msg_queue_head(pvt)))
3053 }
3054 
3055 /*!
3056  * \brief Get the head of a queue.
3057  * \param pvt a mbl_pvt structure
3058  * \return a pointer to the head of the given msg queue
3059  */
3060 static struct msg_queue_entry *msg_queue_head(struct mbl_pvt *pvt)
3061 {
3062  return AST_LIST_FIRST(&pvt->msg_queue);
3063 }
3064 
3065 
3066 
3067 /*
3068 
3069  sdp helpers
3070 
3071 */
3072 
3073 static int sdp_search(char *addr, int profile)
3074 {
3075 
3076  sdp_session_t *session = 0;
3077  bdaddr_t bdaddr;
3078  uuid_t svc_uuid;
3079  uint32_t range = 0x0000ffff;
3080  sdp_list_t *response_list, *search_list, *attrid_list;
3081  int status, port;
3082  sdp_list_t *proto_list;
3083  sdp_record_t *sdprec;
3084 
3085  str2ba(addr, &bdaddr);
3086  port = 0;
3087  session = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY);
3088  if (!session) {
3089  ast_debug(1, "sdp_connect() failed on device %s.\n", addr);
3090  return 0;
3091  }
3092 
3093  sdp_uuid32_create(&svc_uuid, profile);
3094  search_list = sdp_list_append(0, &svc_uuid);
3095  attrid_list = sdp_list_append(0, &range);
3096  response_list = 0x00;
3097  status = sdp_service_search_attr_req(session, search_list, SDP_ATTR_REQ_RANGE, attrid_list, &response_list);
3098  if (status == 0) {
3099  if (response_list) {
3100  sdprec = (sdp_record_t *) response_list->data;
3101  proto_list = 0x00;
3102  if (sdp_get_access_protos(sdprec, &proto_list) == 0) {
3103  port = sdp_get_proto_port(proto_list, RFCOMM_UUID);
3104  sdp_list_free(proto_list, 0);
3105  }
3106  sdp_record_free(sdprec);
3107  sdp_list_free(response_list, 0);
3108  } else
3109  ast_debug(1, "No responses returned for device %s.\n", addr);
3110  } else
3111  ast_debug(1, "sdp_service_search_attr_req() failed on device %s.\n", addr);
3112 
3113  sdp_list_free(search_list, 0);
3114  sdp_list_free(attrid_list, 0);
3115  sdp_close(session);
3116 
3117  return port;
3118 
3119 }
3120 
3121 static sdp_session_t *sdp_register(void)
3122 {
3123  uint32_t service_uuid_int[] = {0, 0, 0, GENERIC_AUDIO_SVCLASS_ID};
3124  uint8_t rfcomm_channel = 1;
3125  const char *service_name = "Asterisk PABX";
3126  const char *service_dsc = "Asterisk PABX";
3127  const char *service_prov = "Asterisk";
3128 
3129  uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid, svc_class1_uuid, svc_class2_uuid;
3130  sdp_list_t *l2cap_list = 0, *rfcomm_list = 0, *root_list = 0, *proto_list = 0, *access_proto_list = 0, *svc_uuid_list = 0;
3131  sdp_data_t *channel = 0;
3132 
3133  sdp_session_t *session = 0;
3134 
3135  sdp_record_t *record = sdp_record_alloc();
3136 
3137  sdp_uuid128_create(&svc_uuid, &service_uuid_int);
3138  sdp_set_service_id(record, svc_uuid);
3139 
3140  sdp_uuid32_create(&svc_class1_uuid, GENERIC_AUDIO_SVCLASS_ID);
3141  sdp_uuid32_create(&svc_class2_uuid, HEADSET_PROFILE_ID);
3142 
3143  svc_uuid_list = sdp_list_append(0, &svc_class1_uuid);
3144  svc_uuid_list = sdp_list_append(svc_uuid_list, &svc_class2_uuid);
3145  sdp_set_service_classes(record, svc_uuid_list);
3146 
3147  sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
3148  root_list = sdp_list_append(0, &root_uuid);
3149  sdp_set_browse_groups( record, root_list );
3150 
3151  sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
3152  l2cap_list = sdp_list_append(0, &l2cap_uuid);
3153  proto_list = sdp_list_append(0, l2cap_list);
3154 
3155  sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
3156  channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
3157  rfcomm_list = sdp_list_append(0, &rfcomm_uuid);
3158  sdp_list_append(rfcomm_list, channel);
3159  sdp_list_append(proto_list, rfcomm_list);
3160 
3161  access_proto_list = sdp_list_append(0, proto_list);
3162  sdp_set_access_protos(record, access_proto_list);
3163 
3164  sdp_set_info_attr(record, service_name, service_prov, service_dsc);
3165 
3166  if (!(session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY)))
3167  ast_log(LOG_WARNING, "Failed to connect sdp and create session.\n");
3168  else {
3169  if (sdp_record_register(session, record, 0) < 0) {
3170  ast_log(LOG_WARNING, "Failed to sdp_record_register error: %d\n", errno);
3171  return NULL;
3172  }
3173  }
3174 
3175  sdp_data_free(channel);
3176  sdp_list_free(rfcomm_list, 0);
3177  sdp_list_free(root_list, 0);
3178  sdp_list_free(access_proto_list, 0);
3179  sdp_list_free(svc_uuid_list, 0);
3180 
3181  return session;
3182 
3183 }
3184 
3185 /*
3186 
3187  Thread routines
3188 
3189 */
3190 
3191 /*!
3192  * \brief Handle the BRSF response.
3193  * \param pvt a mbl_pvt structure
3194  * \param buf a null terminated buffer containing an AT message
3195  * \retval 0 success
3196  * \retval -1 error
3197  */
3198 static int handle_response_brsf(struct mbl_pvt *pvt, char *buf)
3199 {
3200  struct msg_queue_entry *entry;
3201  if ((entry = msg_queue_head(pvt)) && entry->expected == AT_BRSF) {
3202  if (hfp_parse_brsf(pvt->hfp, buf)) {
3203  ast_debug(1, "[%s] error parsing BRSF\n", pvt->id);
3204  goto e_return;
3205  }
3206 
3207  if (msg_queue_push(pvt, AT_OK, AT_BRSF)) {
3208  ast_debug(1, "[%s] error handling BRSF\n", pvt->id);
3209  goto e_return;
3210  }
3211 
3213  } else if (entry) {
3214  ast_debug(1, "[%s] received unexpected AT message 'BRSF' when expecting %s, ignoring\n", pvt->id, at_msg2str(entry->expected));
3215  } else {
3216  ast_debug(1, "[%s] received unexpected AT message 'BRSF'\n", pvt->id);
3217  }
3218 
3219  return 0;
3220 
3221 e_return:
3223  return -1;
3224 }
3225 
3226 /*!
3227  * \brief Handle the CIND response.
3228  * \param pvt a mbl_pvt structure
3229  * \param buf a null terminated buffer containing an AT message
3230  * \retval 0 success
3231  * \retval -1 error
3232  */
3233 static int handle_response_cind(struct mbl_pvt *pvt, char *buf)
3234 {
3235  struct msg_queue_entry *entry;
3236  if ((entry = msg_queue_head(pvt)) && entry->expected == AT_CIND) {
3237  switch (entry->response_to) {
3238  case AT_CIND_TEST:
3239  if (hfp_parse_cind_test(pvt->hfp, buf) || msg_queue_push(pvt, AT_OK, AT_CIND_TEST)) {
3240  ast_debug(1, "[%s] error performing CIND test\n", pvt->id);
3241  goto e_return;
3242  }
3243  break;
3244  case AT_CIND:
3245  if (hfp_parse_cind(pvt->hfp, buf) || msg_queue_push(pvt, AT_OK, AT_CIND)) {
3246  ast_debug(1, "[%s] error getting CIND state\n", pvt->id);
3247  goto e_return;
3248  }
3249  break;
3250  default:
3251  ast_debug(1, "[%s] error getting CIND state\n", pvt->id);
3252  goto e_return;
3253  }
3255  } else if (entry) {
3256  ast_debug(1, "[%s] received unexpected AT message 'CIND' when expecting %s, ignoring\n", pvt->id, at_msg2str(entry->expected));
3257  } else {
3258  ast_debug(1, "[%s] received unexpected AT message 'CIND'\n", pvt->id);
3259  }
3260 
3261  return 0;
3262 
3263 e_return:
3265  return -1;
3266 }
3267 
3268 /*!
3269  * \brief Handle OK AT messages.
3270  * \param pvt a mbl_pvt structure
3271  * \param buf a null terminated buffer containing an AT message
3272  * \retval 0 success
3273  * \retval -1 error
3274  */
3275 static int handle_response_ok(struct mbl_pvt *pvt, char *buf)
3276 {
3277  struct msg_queue_entry *entry;
3278  if ((entry = msg_queue_head(pvt)) && entry->expected == AT_OK) {
3279  switch (entry->response_to) {
3280 
3281  /* initialization stuff */
3282  case AT_BRSF:
3283  ast_debug(1, "[%s] BSRF sent successfully\n", pvt->id);
3284 
3285  /* If this is a blackberry do CMER now, otherwise
3286  * continue with CIND as normal. */
3287  if (pvt->blackberry) {
3288  if (hfp_send_cmer(pvt->hfp, 1) || msg_queue_push(pvt, AT_OK, AT_CMER)) {
3289  ast_debug(1, "[%s] error sending CMER\n", pvt->id);
3290  goto e_return;
3291  }
3292  } else {
3293  if (hfp_send_cind_test(pvt->hfp) || msg_queue_push(pvt, AT_CIND, AT_CIND_TEST)) {
3294  ast_debug(1, "[%s] error sending CIND test\n", pvt->id);
3295  goto e_return;
3296  }
3297  }
3298  break;
3299  case AT_CIND_TEST:
3300  ast_debug(1, "[%s] CIND test sent successfully\n", pvt->id);
3301 
3302  ast_debug(2, "[%s] call: %d\n", pvt->id, pvt->hfp->cind_map.call);
3303  ast_debug(2, "[%s] callsetup: %d\n", pvt->id, pvt->hfp->cind_map.callsetup);
3304  ast_debug(2, "[%s] service: %d\n", pvt->id, pvt->hfp->cind_map.service);
3305 
3306  if (hfp_send_cind(pvt->hfp) || msg_queue_push(pvt, AT_CIND, AT_CIND)) {
3307  ast_debug(1, "[%s] error requesting CIND state\n", pvt->id);
3308  goto e_return;
3309  }
3310  break;
3311  case AT_CIND:
3312  ast_debug(1, "[%s] CIND sent successfully\n", pvt->id);
3313 
3314  /* check if a call is active */
3315  if (pvt->hfp->cind_state[pvt->hfp->cind_map.call]) {
3316  ast_verb(3, "Bluetooth Device %s has a call in progress - delaying connection.\n", pvt->id);
3317  goto e_return;
3318  }
3319 
3320  /* If this is NOT a blackberry proceed with CMER,
3321  * otherwise send CLIP. */
3322  if (!pvt->blackberry) {
3323  if (hfp_send_cmer(pvt->hfp, 1) || msg_queue_push(pvt, AT_OK, AT_CMER)) {
3324  ast_debug(1, "[%s] error sending CMER\n", pvt->id);
3325  goto e_return;
3326  }
3327  } else {
3328  if (hfp_send_clip(pvt->hfp, 1) || msg_queue_push(pvt, AT_OK, AT_CLIP)) {
3329  ast_debug(1, "[%s] error enabling calling line notification\n", pvt->id);
3330  goto e_return;
3331  }
3332  }
3333  break;
3334  case AT_CMER:
3335  ast_debug(1, "[%s] CMER sent successfully\n", pvt->id);
3336 
3337  /* If this is a blackberry proceed with the CIND test,
3338  * otherwise send CLIP. */
3339  if (pvt->blackberry) {
3340  if (hfp_send_cind_test(pvt->hfp) || msg_queue_push(pvt, AT_CIND, AT_CIND_TEST)) {
3341  ast_debug(1, "[%s] error sending CIND test\n", pvt->id);
3342  goto e_return;
3343  }
3344  } else {
3345  if (hfp_send_clip(pvt->hfp, 1) || msg_queue_push(pvt, AT_OK, AT_CLIP)) {
3346  ast_debug(1, "[%s] error enabling calling line notification\n", pvt->id);
3347  goto e_return;
3348  }
3349  }
3350  break;
3351  case AT_CLIP:
3352  ast_debug(1, "[%s] calling line indication enabled\n", pvt->id);
3353  if (hfp_send_ecam(pvt->hfp) || msg_queue_push(pvt, AT_OK, AT_ECAM)) {
3354  ast_debug(1, "[%s] error enabling Sony Ericsson call monitoring extensions\n", pvt->id);
3355  goto e_return;
3356  }
3357 
3358  break;
3359  case AT_ECAM:
3360  ast_debug(1, "[%s] Sony Ericsson call monitoring is active on device\n", pvt->id);
3361  if (hfp_send_vgs(pvt->hfp, 15) || msg_queue_push(pvt, AT_OK, AT_VGS)) {
3362  ast_debug(1, "[%s] error synchronizing gain settings\n", pvt->id);
3363  goto e_return;
3364  }
3365 
3366  pvt->timeout = -1;
3367  pvt->hfp->initialized = 1;
3368  ast_verb(3, "Bluetooth Device %s initialized and ready.\n", pvt->id);
3369 
3370  break;
3371  case AT_VGS:
3372  ast_debug(1, "[%s] volume level synchronization successful\n", pvt->id);
3373 
3374  /* set the SMS operating mode to text mode */
3375  if (pvt->has_sms) {
3376  if (hfp_send_cmgf(pvt->hfp, 1) || msg_queue_push(pvt, AT_OK, AT_CMGF)) {
3377  ast_debug(1, "[%s] error setting CMGF\n", pvt->id);
3378  goto e_return;
3379  }
3380  }
3381  break;
3382  case AT_CMGF:
3383  ast_debug(1, "[%s] sms text mode enabled\n", pvt->id);
3384  /* turn on SMS new message indication */
3385  if (hfp_send_cnmi(pvt->hfp) || msg_queue_push(pvt, AT_OK, AT_CNMI)) {
3386  ast_debug(1, "[%s] error setting CNMI\n", pvt->id);
3387  goto e_return;
3388  }
3389  break;
3390  case AT_CNMI:
3391  ast_debug(1, "[%s] sms new message indication enabled\n", pvt->id);
3392  pvt->has_sms = 1;
3393  break;
3394  /* end initialization stuff */
3395 
3396  case AT_A:
3397  ast_debug(1, "[%s] answer sent successfully\n", pvt->id);
3398  pvt->needchup = 1;
3399  break;
3400  case AT_D:
3401  ast_debug(1, "[%s] dial sent successfully\n", pvt->id);
3402  pvt->needchup = 1;
3403  pvt->outgoing = 1;
3404  mbl_queue_control(pvt, AST_CONTROL_PROGRESS);
3405  break;
3406  case AT_CHUP:
3407  ast_debug(1, "[%s] successful hangup\n", pvt->id);
3408  break;
3409  case AT_CMGS:
3410  ast_debug(1, "[%s] successfully sent sms message\n", pvt->id);
3411  pvt->outgoing_sms = 0;
3412  break;
3413  case AT_VTS:
3414  ast_debug(1, "[%s] digit sent successfully\n", pvt->id);
3415  break;
3416  case AT_CUSD:
3417  ast_debug(1, "[%s] CUSD code sent successfully\n", pvt->id);
3418  break;
3419  case AT_UNKNOWN:
3420  default:
3421  ast_debug(1, "[%s] received OK for unhandled request: %s\n", pvt->id, at_msg2str(entry->response_to));
3422  break;
3423  }
3425  } else if (entry) {
3426  ast_debug(1, "[%s] received AT message 'OK' when expecting %s, ignoring\n", pvt->id, at_msg2str(entry->expected));
3427  } else {
3428  ast_debug(1, "[%s] received unexpected AT message 'OK'\n", pvt->id);
3429  }
3430  return 0;
3431 
3432 e_return:
3434  return -1;
3435 }
3436 
3437 /*!
3438  * \brief Handle ERROR AT messages.
3439  * \param pvt a mbl_pvt structure
3440  * \param buf a null terminated buffer containing an AT message
3441  * \retval 0 success
3442  * \retval -1 error
3443  */
3444 static int handle_response_error(struct mbl_pvt *pvt, char *buf)
3445 {
3446  struct msg_queue_entry *entry;
3447  if ((entry = msg_queue_head(pvt))
3448  && (entry->expected == AT_OK
3449  || entry->expected == AT_ERROR
3450  || entry->expected == AT_CMS_ERROR
3451  || entry->expected == AT_CMGR
3452  || entry->expected == AT_SMS_PROMPT)) {
3453  switch (entry->response_to) {
3454 
3455  /* initialization stuff */
3456  case AT_BRSF:
3457  ast_debug(1, "[%s] error reading BSRF\n", pvt->id);
3458  goto e_return;
3459  case AT_CIND_TEST:
3460  ast_debug(1, "[%s] error during CIND test\n", pvt->id);
3461  goto e_return;
3462  case AT_CIND:
3463  ast_debug(1, "[%s] error requesting CIND state\n", pvt->id);
3464  goto e_return;
3465  case AT_CMER:
3466  ast_debug(1, "[%s] error during CMER request\n", pvt->id);
3467  goto e_return;
3468  case AT_CLIP:
3469  ast_debug(1, "[%s] error enabling calling line indication\n", pvt->id);
3470  goto e_return;
3471  case AT_VGS:
3472  ast_debug(1, "[%s] volume level synchronization failed\n", pvt->id);
3473 
3474  /* this is not a fatal error, let's continue with initialization */
3475 
3476  /* set the SMS operating mode to text mode */
3477  if (hfp_send_cmgf(pvt->hfp, 1) || msg_queue_push(pvt, AT_OK, AT_CMGF)) {
3478  ast_debug(1, "[%s] error setting CMGF\n", pvt->id);
3479  goto e_return;
3480  }
3481  break;
3482  case AT_CMGF:
3483  pvt->has_sms = 0;
3484  ast_debug(1, "[%s] error setting CMGF\n", pvt->id);
3485  ast_debug(1, "[%s] no SMS support\n", pvt->id);
3486  break;
3487  case AT_CNMI:
3488  pvt->has_sms = 0;
3489  ast_debug(1, "[%s] error setting CNMI\n", pvt->id);
3490  ast_debug(1, "[%s] no SMS support\n", pvt->id);
3491  break;
3492  case AT_ECAM:
3493  ast_debug(1, "[%s] Mobile does not support Sony Ericsson extensions\n", pvt->id);
3494 
3495  /* this is not a fatal error, let's continue with the initialization */
3496 
3497  if (hfp_send_vgs(pvt->hfp, 15) || msg_queue_push(pvt, AT_OK, AT_VGS)) {
3498  ast_debug(1, "[%s] error synchronizing gain settings\n", pvt->id);
3499  goto e_return;
3500  }
3501 
3502  pvt->timeout = -1;
3503  pvt->hfp->initialized = 1;
3504  ast_verb(3, "Bluetooth Device %s initialized and ready.\n", pvt->id);
3505 
3506  break;
3507  /* end initialization stuff */
3508 
3509  case AT_A:
3510  ast_debug(1, "[%s] answer failed\n", pvt->id);
3511  mbl_queue_hangup(pvt);
3512  break;
3513  case AT_D:
3514  ast_debug(1, "[%s] dial failed\n", pvt->id);
3515  pvt->needchup = 0;
3516  mbl_queue_control(pvt, AST_CONTROL_CONGESTION);
3517  break;
3518  case AT_CHUP:
3519  ast_debug(1, "[%s] error sending hangup, disconnecting\n", pvt->id);
3520  goto e_return;
3521  case AT_CMGR:
3522  ast_debug(1, "[%s] error reading sms message\n", pvt->id);
3523  pvt->incoming_sms = 0;
3524  break;
3525  case AT_CMGS:
3526  ast_debug(1, "[%s] error sending sms message\n", pvt->id);
3527  pvt->outgoing_sms = 0;
3528  break;
3529  case AT_VTS:
3530  ast_debug(1, "[%s] error sending digit\n", pvt->id);
3531  break;
3532  case AT_CUSD:
3533  ast_verb(0, "[%s] error sending CUSD command\n", pvt->id);
3534  break;
3535  case AT_UNKNOWN:
3536  default:
3537  ast_debug(1, "[%s] received ERROR for unhandled request: %s\n", pvt->id, at_msg2str(entry->response_to));
3538  break;
3539  }
3541  } else if (entry) {
3542  ast_debug(1, "[%s] received AT message 'ERROR' when expecting %s, ignoring\n", pvt->id, at_msg2str(entry->expected));
3543  } else {
3544  ast_debug(1, "[%s] received unexpected AT message 'ERROR'\n", pvt->id);
3545  }
3546 
3547  return 0;
3548 
3549 e_return:
3551  return -1;
3552 }
3553 
3554 /*!
3555  * \brief Handle AT+CIEV messages.
3556  * \param pvt a mbl_pvt structure
3557  * \param buf a null terminated buffer containing an AT message
3558  * \retval 0 success
3559  * \retval -1 error
3560  */
3561 static int handle_response_ciev(struct mbl_pvt *pvt, char *buf)
3562 {
3563  int i;
3564  switch (hfp_parse_ciev(pvt->hfp, buf, &i)) {
3565  case HFP_CIND_CALL:
3566  switch (i) {
3567  case HFP_CIND_CALL_NONE:
3568  ast_debug(1, "[%s] line disconnected\n", pvt->id);
3569  if (pvt->owner) {
3570  ast_debug(1, "[%s] hanging up owner\n", pvt->id);
3571  if (mbl_queue_hangup(pvt)) {
3572  ast_log(LOG_ERROR, "[%s] error queueing hangup, disconnecting...\n", pvt->id);
3573  return -1;
3574  }
3575  }
3576  pvt->needchup = 0;
3577  pvt->needcallerid = 0;
3578  pvt->incoming = 0;
3579  pvt->outgoing = 0;
3580  break;
3581  case HFP_CIND_CALL_ACTIVE:
3582  if (pvt->outgoing) {
3583  ast_debug(1, "[%s] remote end answered\n", pvt->id);
3584  mbl_queue_control(pvt, AST_CONTROL_ANSWER);
3585  } else if (pvt->incoming && pvt->answered) {
3586  ast_setstate(pvt->owner, AST_STATE_UP);
3587  } else if (pvt->incoming) {
3588  /* user answered from handset, disconnecting */
3589  ast_verb(3, "[%s] user answered bluetooth device from handset, disconnecting\n", pvt->id);
3590  mbl_queue_hangup(pvt);
3591  return -1;
3592  }
3593  break;
3594  }
3595  break;
3596 
3597  case HFP_CIND_CALLSETUP:
3598  switch (i) {
3599  case HFP_CIND_CALLSETUP_NONE:
3600  if (pvt->hfp->cind_state[pvt->hfp->cind_map.call] != HFP_CIND_CALL_ACTIVE) {
3601  if (pvt->owner) {
3602  if (pvt->hfp->sent_alerting == 1) {
3603  handle_response_busy(pvt);
3604  }
3605  if (mbl_queue_hangup(pvt)) {
3606  ast_log(LOG_ERROR, "[%s] error queueing hangup, disconnecting...\n", pvt->id);
3607  return -1;
3608  }
3609  }
3610  pvt->needchup = 0;
3611  pvt->needcallerid = 0;
3612  pvt->incoming = 0;
3613  pvt->outgoing = 0;
3614  }
3615  break;
3616  case HFP_CIND_CALLSETUP_INCOMING:
3617  ast_debug(1, "[%s] incoming call, waiting for caller id\n", pvt->id);
3618  pvt->needcallerid = 1;
3619  pvt->incoming = 1;
3620  break;
3621  case HFP_CIND_CALLSETUP_OUTGOING:
3622  if (pvt->outgoing) {
3623  pvt->hfp->sent_alerting = 0;
3624  ast_debug(1, "[%s] outgoing call\n", pvt->id);
3625  } else {
3626  ast_verb(3, "[%s] user dialed from handset, disconnecting\n", pvt->id);
3627  return -1;
3628  }
3629  break;
3630  case HFP_CIND_CALLSETUP_ALERTING:
3631  if (pvt->outgoing) {
3632  ast_debug(1, "[%s] remote alerting\n", pvt->id);
3633  mbl_queue_control(pvt, AST_CONTROL_RINGING);
3634  pvt->hfp->sent_alerting = 1;
3635  }
3636  break;
3637  }
3638  break;
3639  case HFP_CIND_NONE:
3640  ast_debug(1, "[%s] error parsing CIND: %s\n", pvt->id, buf);
3641  break;
3642  }
3643  return 0;
3644 }
3645 
3646 /*!
3647  * \brief Handle AT+CLIP messages.
3648  * \param pvt a mbl_pvt structure
3649  * \param buf a null terminated buffer containing an AT message
3650  * \retval 0 success
3651  * \retval -1 error
3652  */
3653 static int handle_response_clip(struct mbl_pvt *pvt, char *buf)
3654 {
3655  struct msg_queue_entry *msg;
3656  struct ast_channel *chan;
3657  struct cidinfo cidinfo;
3658 
3659  if ((msg = msg_queue_head(pvt)) && msg->expected == AT_CLIP) {
3661 
3662  pvt->needcallerid = 0;
3663  cidinfo = hfp_parse_clip(pvt->hfp, buf);
3664 
3665  if (!(chan = mbl_new(AST_STATE_RING, pvt, &cidinfo, NULL, NULL))) {
3666  ast_log(LOG_ERROR, "[%s] unable to allocate channel for incoming call\n", pvt->id);
3667  hfp_send_chup(pvt->hfp);
3668  msg_queue_push(pvt, AT_OK, AT_CHUP);
3669  return -1;
3670  }
3671 
3672  /* from this point on, we need to send a chup in the event of a
3673  * hangup */
3674  pvt->needchup = 1;
3675 
3676  if (ast_pbx_start(chan)) {
3677  ast_log(LOG_ERROR, "[%s] unable to start pbx on incoming call\n", pvt->id);
3678  mbl_ast_hangup(pvt);
3679  return -1;
3680  }
3681  }
3682 
3683  return 0;
3684 }
3685 
3686 /*!
3687  * \brief Handle RING messages.
3688  * \param pvt a mbl_pvt structure
3689  * \param buf a null terminated buffer containing an AT message
3690  * \retval 0 success
3691  * \retval -1 error
3692  */
3693 static int handle_response_ring(struct mbl_pvt *pvt, char *buf)
3694 {
3695  if (pvt->needcallerid) {
3696  ast_debug(1, "[%s] got ring while waiting for caller id\n", pvt->id);
3697  return msg_queue_push(pvt, AT_CLIP, AT_UNKNOWN);
3698  } else {
3699  return 0;
3700  }
3701 }
3702 
3703 /*!
3704  * \brief Handle AT+CMTI messages.
3705  * \param pvt a mbl_pvt structure
3706  * \param buf a null terminated buffer containing an AT message
3707  * \retval 0 success
3708  * \retval -1 error
3709  */
3710 static int handle_response_cmti(struct mbl_pvt *pvt, char *buf)
3711 {
3712  int index = hfp_parse_cmti(pvt->hfp, buf);
3713  if (index > 0) {
3714  ast_debug(1, "[%s] incoming sms message\n", pvt->id);
3715 
3716  if (hfp_send_cmgr(pvt->hfp, index)
3717  || msg_queue_push(pvt, AT_CMGR, AT_CMGR)) {
3718  ast_debug(1, "[%s] error sending CMGR to retrieve SMS message\n", pvt->id);
3719  return -1;
3720  }
3721 
3722  pvt->incoming_sms = 1;
3723  return 0;
3724  } else {
3725  ast_debug(1, "[%s] error parsing incoming sms message alert, disconnecting\n", pvt->id);
3726  return -1;
3727  }
3728 }
3729 
3730 /*!
3731  * \brief Handle AT+CMGR messages.
3732  * \param pvt a mbl_pvt structure
3733  * \param buf a null terminated buffer containing an AT message
3734  * \retval 0 success
3735  * \retval -1 error
3736  */
3737 static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf)
3738 {
3739  char *from_number = NULL, *text = NULL;
3740  struct ast_channel *chan;
3741  struct msg_queue_entry *msg;
3742 
3743  if ((msg = msg_queue_head(pvt)) && msg->expected == AT_CMGR) {
3745 
3746  if (hfp_parse_cmgr(pvt->hfp, buf, &from_number, &text)) {
3747  ast_debug(1, "[%s] error parsing sms message, disconnecting\n", pvt->id);
3748  return -1;
3749  }
3750 
3751  ast_debug(1, "[%s] successfully read sms message\n", pvt->id);
3752  pvt->incoming_sms = 0;
3753 
3754  /* XXX this channel probably does not need to be associated with this pvt */
3755  if (!(chan = mbl_new(AST_STATE_DOWN, pvt, NULL, NULL, NULL))) {
3756  ast_debug(1, "[%s] error creating sms message channel, disconnecting\n", pvt->id);
3757  return -1;
3758  }
3759 
3760  ast_channel_exten_set(chan, "sms");
3761  pbx_builtin_setvar_helper(chan, "SMSSRC", from_number);
3762  pbx_builtin_setvar_helper(chan, "SMSTXT", text);
3763 
3764  if (ast_pbx_start(chan)) {
3765  ast_log(LOG_ERROR, "[%s] unable to start pbx on incoming sms\n", pvt->id);
3766  mbl_ast_hangup(pvt);
3767  }
3768  } else {
3769  ast_debug(1, "[%s] got unexpected +CMGR message, ignoring\n", pvt->id);
3770  }
3771 
3772  return 0;
3773 }
3774 
3775 /*!
3776  * \brief Send an SMS message from the queue.
3777  * \param pvt a mbl_pvt structure
3778  * \param buf a null terminated buffer containing an AT message
3779  * \retval 0 success
3780  * \retval -1 error
3781  */
3782 static int handle_sms_prompt(struct mbl_pvt *pvt, char *buf)
3783 {
3784  struct msg_queue_entry *msg;
3785  if (!(msg = msg_queue_head(pvt))) {
3786  ast_debug(1, "[%s] error, got sms prompt with no pending sms messages\n", pvt->id);
3787  return 0;
3788  }
3789 
3790  if (msg->expected != AT_SMS_PROMPT) {
3791  ast_debug(1, "[%s] error, got sms prompt but no pending sms messages\n", pvt->id);
3792  return 0;
3793  }
3794 
3795  if (hfp_send_sms_text(pvt->hfp, msg->data)
3796  || msg_queue_push(pvt, AT_OK, AT_CMGS)) {
3798  ast_debug(1, "[%s] error sending sms message\n", pvt->id);
3799  return 0;
3800  }
3801 
3803  return 0;
3804 }
3805 
3806 /*!
3807  * \brief Handle CUSD messages.
3808  * \param pvt a mbl_pvt structure
3809  * \param buf a null terminated buffer containing an AT message
3810  * \retval 0 success
3811  * \retval -1 error
3812  */
3813 static int handle_response_cusd(struct mbl_pvt *pvt, char *buf)
3814 {
3815  char *cusd;
3816 
3817  if (!(cusd = hfp_parse_cusd(pvt->hfp, buf))) {
3818  ast_verb(0, "[%s] error parsing CUSD: %s\n", pvt->id, buf);
3819  return 0;
3820  }
3821 
3822  ast_verb(0, "[%s] CUSD response: %s\n", pvt->id, cusd);
3823 
3824  return 0;
3825 }
3826 
3827 /*!
3828  * \brief Handle BUSY messages.
3829  * \param pvt a mbl_pvt structure
3830  * \retval 0 success
3831  * \retval -1 error
3832  */
3833 static int handle_response_busy(struct mbl_pvt *pvt)
3834 {
3835  pvt->hangupcause = AST_CAUSE_USER_BUSY;
3836  pvt->needchup = 1;
3837  mbl_queue_control(pvt, AST_CONTROL_BUSY);
3838  return 0;
3839 }
3840 
3841 /*!
3842  * \brief Handle NO DIALTONE messages.
3843  * \param pvt a mbl_pvt structure
3844  * \param buf a null terminated buffer containing an AT message
3845  * \retval 0 success
3846  * \retval -1 error
3847  */
3848 static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf)
3849 {
3850  ast_verb(1, "[%s] mobile reports NO DIALTONE\n", pvt->id);
3851  pvt->needchup = 1;
3852  mbl_queue_control(pvt, AST_CONTROL_CONGESTION);
3853  return 0;
3854 }
3855 
3856 /*!
3857  * \brief Handle NO CARRIER messages.
3858  * \param pvt a mbl_pvt structure
3859  * \param buf a null terminated buffer containing an AT message
3860  * \retval 0 success
3861  * \retval -1 error
3862  */
3863 static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf)
3864 {
3865  ast_verb(1, "[%s] mobile reports NO CARRIER\n", pvt->id);
3866  pvt->needchup = 1;
3867  mbl_queue_control(pvt, AST_CONTROL_CONGESTION);
3868  return 0;
3869 }
3870 
3871 
3872 static void *do_monitor_phone(void *data)
3873 {
3874  struct mbl_pvt *pvt = (struct mbl_pvt *)data;
3875  struct hfp_pvt *hfp = pvt->hfp;
3876  char buf[350];
3877  int t;
3878  at_message_t at_msg;
3879  struct msg_queue_entry *entry;
3880 
3881  /* Note: At one point the initialization procedure was neatly contained
3882  * in the hfp_init() function, but that initialization method did not
3883  * work with non standard devices. As a result, the initialization
3884  * procedure is not spread throughout the event handling loop.
3885  */
3886 
3887  /* start initialization with the BRSF request */
3888  ast_mutex_lock(&pvt->lock);
3889  pvt->timeout = 10000;
3890  if (hfp_send_brsf(hfp, &hfp_our_brsf) || msg_queue_push(pvt, AT_BRSF, AT_BRSF)) {
3891  ast_debug(1, "[%s] error sending BRSF\n", hfp->owner->id);
3892  goto e_cleanup;
3893  }
3894  ast_mutex_unlock(&pvt->lock);
3895 
3896  while (!check_unloading()) {
3897  ast_mutex_lock(&pvt->lock);
3898  t = pvt->timeout;
3899  ast_mutex_unlock(&pvt->lock);
3900 
3901  if (!rfcomm_wait(pvt->rfcomm_socket, &t)) {
3902  ast_debug(1, "[%s] timeout waiting for rfcomm data, disconnecting\n", pvt->id);
3903  ast_mutex_lock(&pvt->lock);
3904  if (!hfp->initialized) {
3905  if ((entry = msg_queue_head(pvt))) {
3906  switch (entry->response_to) {
3907  case AT_CIND_TEST:
3908  if (pvt->blackberry)
3909  ast_debug(1, "[%s] timeout during CIND test\n", hfp->owner->id);
3910  else
3911  ast_debug(1, "[%s] timeout during CIND test, try setting 'blackberry=yes'\n", hfp->owner->id);
3912  break;
3913  case AT_CMER:
3914  if (pvt->blackberry)
3915  ast_debug(1, "[%s] timeout after sending CMER, try setting 'blackberry=no'\n", hfp->owner->id);
3916  else
3917  ast_debug(1, "[%s] timeout after sending CMER\n", hfp->owner->id);
3918  break;
3919  default:
3920  ast_debug(1, "[%s] timeout while waiting for %s in response to %s\n", pvt->id, at_msg2str(entry->expected), at_msg2str(entry->response_to));
3921  break;
3922  }
3923  }
3924  }
3925  ast_mutex_unlock(&pvt->lock);
3926  goto e_cleanup;
3927  }
3928 
3929  if ((at_msg = at_read_full(hfp->rsock, buf, sizeof(buf))) < 0) {
3930  ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror(errno), errno);
3931  break;
3932  }
3933 
3934  ast_debug(1, "[%s] read %s\n", pvt->id, buf);
3935 
3936  switch (at_msg) {
3937  case AT_BRSF:
3938  ast_mutex_lock(&pvt->lock);
3939  if (handle_response_brsf(pvt, buf)) {
3940  ast_mutex_unlock(&pvt->lock);
3941  goto e_cleanup;
3942  }
3943  ast_mutex_unlock(&pvt->lock);
3944  break;
3945  case AT_CIND:
3946  ast_mutex_lock(&pvt->lock);
3947  if (handle_response_cind(pvt, buf)) {
3948  ast_mutex_unlock(&pvt->lock);
3949  goto e_cleanup;
3950  }
3951  ast_mutex_unlock(&pvt->lock);
3952  break;
3953  case AT_OK:
3954  ast_mutex_lock(&pvt->lock);
3955  if (handle_response_ok(pvt, buf)) {
3956  ast_mutex_unlock(&pvt->lock);
3957  goto e_cleanup;
3958  }
3959  ast_mutex_unlock(&pvt->lock);
3960  break;
3961  case AT_CMS_ERROR:
3962  case AT_ERROR:
3963  ast_mutex_lock(&pvt->lock);
3964  if (handle_response_error(pvt, buf)) {
3965  ast_mutex_unlock(&pvt->lock);
3966  goto e_cleanup;
3967  }
3968  ast_mutex_unlock(&pvt->lock);
3969  break;
3970  case AT_RING:
3971  ast_mutex_lock(&pvt->lock);
3972  if (handle_response_ring(pvt, buf)) {
3973  ast_mutex_unlock(&pvt->lock);
3974  goto e_cleanup;
3975  }
3976  ast_mutex_unlock(&pvt->lock);
3977  break;
3978  case AT_CIEV:
3979  ast_mutex_lock(&pvt->lock);
3980  if (handle_response_ciev(pvt, buf)) {
3981  ast_mutex_unlock(&pvt->lock);
3982  goto e_cleanup;
3983  }
3984  ast_mutex_unlock(&pvt->lock);
3985  break;
3986  case AT_CLIP:
3987  ast_mutex_lock(&pvt->lock);
3988  if (handle_response_clip(pvt, buf)) {
3989  ast_mutex_unlock(&pvt->lock);
3990  goto e_cleanup;
3991  }
3992  ast_mutex_unlock(&pvt->lock);
3993  break;
3994  case AT_CMTI:
3995  ast_mutex_lock(&pvt->lock);
3996  if (handle_response_cmti(pvt, buf)) {
3997  ast_mutex_unlock(&pvt->lock);
3998  goto e_cleanup;
3999  }
4000  ast_mutex_unlock(&pvt->lock);
4001  break;
4002  case AT_CMGR:
4003  ast_mutex_lock(&pvt->lock);
4004  if (handle_response_cmgr(pvt, buf)) {
4005  ast_mutex_unlock(&pvt->lock);
4006  goto e_cleanup;
4007  }
4008  ast_mutex_unlock(&pvt->lock);
4009  break;
4010  case AT_SMS_PROMPT:
4011  ast_mutex_lock(&pvt->lock);
4012  if (handle_sms_prompt(pvt, buf)) {
4013  ast_mutex_unlock(&pvt->lock);
4014  goto e_cleanup;
4015  }
4016  ast_mutex_unlock(&pvt->lock);
4017  break;
4018  case AT_CUSD:
4019  ast_mutex_lock(&pvt->lock);
4020  if (handle_response_cusd(pvt, buf)) {
4021  ast_mutex_unlock(&pvt->lock);
4022  goto e_cleanup;
4023  }
4024  ast_mutex_unlock(&pvt->lock);
4025  break;
4026  case AT_BUSY:
4027  ast_mutex_lock(&pvt->lock);
4028  if (handle_response_busy(pvt)) {
4029  ast_mutex_unlock(&pvt->lock);
4030  goto e_cleanup;
4031  }
4032  ast_mutex_unlock(&pvt->lock);
4033  break;
4034  case AT_NO_DIALTONE:
4035  ast_mutex_lock(&pvt->lock);
4036  if (handle_response_no_dialtone(pvt, buf)) {
4037  ast_mutex_unlock(&pvt->lock);
4038  goto e_cleanup;
4039  }
4040  ast_mutex_unlock(&pvt->lock);
4041  break;
4042  case AT_NO_CARRIER:
4043  ast_mutex_lock(&pvt->lock);
4044  if (handle_response_no_carrier(pvt, buf)) {
4045  ast_mutex_unlock(&pvt->lock);
4046  goto e_cleanup;
4047  }
4048  ast_mutex_unlock(&pvt->lock);
4049  break;
4050  case AT_ECAM:
4051  ast_mutex_lock(&pvt->lock);
4052  if (hfp_parse_ecav(hfp, buf) == 7) {
4053  if (handle_response_busy(pvt)) {
4054  ast_mutex_unlock(&pvt->lock);
4055  goto e_cleanup;
4056  }
4057  }
4058  ast_mutex_unlock(&pvt->lock);
4059  break;
4060  case AT_UNKNOWN:
4061  ast_debug(1, "[%s] ignoring unknown message: %s\n", pvt->id, buf);
4062  break;
4063  case AT_PARSE_ERROR:
4064  ast_debug(1, "[%s] error parsing message\n", pvt->id);
4065  goto e_cleanup;
4066  case AT_READ_ERROR:
4067  ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror(errno), errno);
4068  goto e_cleanup;
4069  default:
4070  break;
4071  }
4072  }
4073 
4074 e_cleanup:
4075 
4076  if (!hfp->initialized)
4077  ast_verb(3, "Error initializing Bluetooth device %s.\n", pvt->id);
4078 
4079  ast_mutex_lock(&pvt->lock);
4080  if (pvt->owner) {
4081  ast_debug(1, "[%s] device disconnected, hanging up owner\n", pvt->id);
4082  pvt->needchup = 0;
4083  mbl_queue_hangup(pvt);
4084  }
4085 
4086  close(pvt->rfcomm_socket);
4087  close(pvt->sco_socket);
4088  pvt->sco_socket = -1;
4089 
4090  msg_queue_flush(pvt);
4091 
4092  pvt->connected = 0;
4093  hfp->initialized = 0;
4094 
4095  pvt->adapter->inuse = 0;
4096  ast_mutex_unlock(&pvt->lock);
4097 
4098  ast_verb(3, "Bluetooth Device %s has disconnected.\n", pvt->id);
4099  manager_event(EVENT_FLAG_SYSTEM, "MobileStatus", "Status: Disconnect\r\nDevice: %s\r\n", pvt->id);
4100 
4101  return NULL;
4102 }
4103 
4104 static int headset_send_ring(const void *data)
4105 {
4106  struct mbl_pvt *pvt = (struct mbl_pvt *) data;
4107  ast_mutex_lock(&pvt->lock);
4108  if (!pvt->needring) {
4109  ast_mutex_unlock(&pvt->lock);
4110  return 0;
4111  }
4112  ast_mutex_unlock(&pvt->lock);
4113 
4114  if (hsp_send_ring(pvt->rfcomm_socket)) {
4115  ast_debug(1, "[%s] error sending RING\n", pvt->id);
4116  return 0;
4117  }
4118  return 1;
4119 }
4120 
4121 static void *do_monitor_headset(void *data)
4122 {
4123 
4124  struct mbl_pvt *pvt = (struct mbl_pvt *)data;
4125  char buf[256];
4126  int t;
4127  at_message_t at_msg;
4128  struct ast_channel *chan = NULL;
4129 
4130  ast_verb(3, "Bluetooth Device %s initialised and ready.\n", pvt->id);
4131 
4132  while (!check_unloading()) {
4133 
4134  t = ast_sched_wait(pvt->sched);
4135  if (t == -1) {
4136  t = 6000;
4137  }
4138 
4139  ast_sched_runq(pvt->sched);
4140 
4141  if (rfcomm_wait(pvt->rfcomm_socket, &t) == 0)
4142  continue;
4143 
4144  if ((at_msg = at_read_full(pvt->rfcomm_socket, buf, sizeof(buf))) < 0) {
4145  ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror(errno), errno);
4146  goto e_cleanup;
4147  }
4148  ast_debug(1, "[%s] %s\n", pvt->id, buf);
4149 
4150  switch (at_msg) {
4151  case AT_VGS:
4152  case AT_VGM:
4153  /* XXX volume change requested, we will just
4154  * pretend to do something with it */
4155  if (hsp_send_ok(pvt->rfcomm_socket)) {
4156  ast_debug(1, "[%s] error sending AT message 'OK'\n", pvt->id);
4157  goto e_cleanup;
4158  }
4159  break;
4160  case AT_CKPD:
4161  ast_mutex_lock(&pvt->lock);
4162  if (pvt->outgoing) {
4163  pvt->needring = 0;
4164  hsp_send_ok(pvt->rfcomm_socket);
4165  if (pvt->answered) {
4166  /* we have an answered call up to the
4167  * HS, he wants to hangup */
4168  mbl_queue_hangup(pvt);
4169  } else {
4170  /* we have an outgoing call to the HS,
4171  * he wants to answer */
4172  if ((pvt->sco_socket = sco_connect(pvt->adapter->addr, pvt->addr)) == -1) {
4173  ast_log(LOG_ERROR, "[%s] unable to create audio connection\n", pvt->id);
4174  mbl_queue_hangup(pvt);
4175  ast_mutex_unlock(&pvt->lock);
4176  goto e_cleanup;
4177  }
4178 
4179  ast_channel_set_fd(pvt->owner, 0, pvt->sco_socket);
4180 
4181  mbl_queue_control(pvt, AST_CONTROL_ANSWER);
4182  pvt->answered = 1;
4183 
4184  if (hsp_send_vgs(pvt->rfcomm_socket, 13) || hsp_send_vgm(pvt->rfcomm_socket, 13)) {
4185  ast_debug(1, "[%s] error sending VGS/VGM\n", pvt->id);
4186  mbl_queue_hangup(pvt);
4187  ast_mutex_unlock(&pvt->lock);
4188  goto e_cleanup;
4189  }
4190  }
4191  } else if (pvt->incoming) {
4192  /* we have an incoming call from the
4193  * HS, he wants to hang up */
4194  mbl_queue_hangup(pvt);
4195  } else {
4196  /* no call is up, HS wants to dial */
4197  hsp_send_ok(pvt->rfcomm_socket);
4198 
4199  if ((pvt->sco_socket = sco_connect(pvt->adapter->addr, pvt->addr)) == -1) {
4200  ast_log(LOG_ERROR, "[%s] unable to create audio connection\n", pvt->id);
4201  ast_mutex_unlock(&pvt->lock);
4202  goto e_cleanup;
4203  }
4204 
4205  pvt->incoming = 1;
4206 
4207  if (!(chan = mbl_new(AST_STATE_UP, pvt, NULL, NULL, NULL))) {
4208  ast_log(LOG_ERROR, "[%s] unable to allocate channel for incoming call\n", pvt->id);
4209  ast_mutex_unlock(&pvt->lock);
4210  goto e_cleanup;
4211  }
4212 
4213  ast_channel_set_fd(chan, 0, pvt->sco_socket);
4214 
4215  ast_channel_exten_set(chan, "s");
4216  if (ast_pbx_start(chan)) {
4217  ast_log(LOG_ERROR, "[%s] unable to start pbx on incoming call\n", pvt->id);
4218  ast_hangup(chan);
4219  ast_mutex_unlock(&pvt->lock);
4220  goto e_cleanup;
4221  }
4222  }
4223  ast_mutex_unlock(&pvt->lock);
4224  break;
4225  default:
4226  ast_debug(1, "[%s] received unknown AT command: %s (%s)\n", pvt->id, buf, at_msg2str(at_msg));
4227  if (hsp_send_error(pvt->rfcomm_socket)) {
4228  ast_debug(1, "[%s] error sending AT message 'ERROR'\n", pvt->id);
4229  goto e_cleanup;
4230  }
4231  break;
4232  }
4233  }
4234 
4235 e_cleanup:
4236  ast_mutex_lock(&pvt->lock);
4237  if (pvt->owner) {
4238  ast_debug(1, "[%s] device disconnected, hanging up owner\n", pvt->id);
4239  mbl_queue_hangup(pvt);
4240  }
4241 
4242 
4243  close(pvt->rfcomm_socket);
4244  close(pvt->sco_socket);
4245  pvt->sco_socket = -1;
4246 
4247  pvt->connected = 0;
4248 
4249  pvt->needring = 0;
4250  pvt->outgoing = 0;
4251  pvt->incoming = 0;
4252 
4253  pvt->adapter->inuse = 0;
4254  ast_mutex_unlock(&pvt->lock);
4255 
4256  manager_event(EVENT_FLAG_SYSTEM, "MobileStatus", "Status: Disconnect\r\nDevice: %s\r\n", pvt->id);
4257  ast_verb(3, "Bluetooth Device %s has disconnected\n", pvt->id);
4258 
4259  return NULL;
4260 
4261 }
4262 
4263 static int start_monitor(struct mbl_pvt *pvt)
4264 {
4265 
4266  if (pvt->type == MBL_TYPE_PHONE) {
4267  pvt->hfp->rsock = pvt->rfcomm_socket;
4268 
4269  if (ast_pthread_create_background(&pvt->monitor_thread, NULL, do_monitor_phone, pvt) < 0) {
4270  pvt->monitor_thread = AST_PTHREADT_NULL;
4271  return 0;
4272  }
4273  } else {
4274  if (ast_pthread_create_background(&pvt->monitor_thread, NULL, do_monitor_headset, pvt) < 0) {
4275  pvt->monitor_thread = AST_PTHREADT_NULL;
4276  return 0;
4277  }
4278  }
4279 
4280  return 1;
4281 
4282 }
4283 
4284 static void *do_discovery(void *data)
4285 {
4286 
4287  struct adapter_pvt *adapter;
4288  struct mbl_pvt *pvt;
4289 
4290  while (!check_unloading()) {
4291  AST_RWLIST_RDLOCK(&adapters);
4292  AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
4293  if (!adapter->inuse) {
4295  AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
4296  ast_mutex_lock(&pvt->lock);
4297  if (!adapter->inuse && !pvt->connected && !strcmp(adapter->id, pvt->adapter->id)) {
4298  if ((pvt->rfcomm_socket = rfcomm_connect(adapter->addr, pvt->addr, pvt->rfcomm_port)) > -1) {
4299  if (start_monitor(pvt)) {
4300  pvt->connected = 1;
4301  adapter->inuse = 1;
4302  manager_event(EVENT_FLAG_SYSTEM, "MobileStatus", "Status: Connect\r\nDevice: %s\r\n", pvt->id);
4303  ast_verb(3, "Bluetooth Device %s has connected, initializing...\n", pvt->id);
4304  }
4305  }
4306  }
4307  ast_mutex_unlock(&pvt->lock);
4308  }
4310  }
4311  }
4312  AST_RWLIST_UNLOCK(&adapters);
4313 
4314 
4315  /* Go to sleep (only if we are not unloading) */
4316  if (!check_unloading())
4317  sleep(discovery_interval);
4318  }
4319 
4320  return NULL;
4321 }
4322 
4323 /*!
4324  * \brief Service new and existing SCO connections.
4325  * This thread accepts new sco connections and handles audio data. There is
4326  * one do_sco_listen thread for each adapter.
4327  */
4328 static void *do_sco_listen(void *data)
4329 {
4330  struct adapter_pvt *adapter = (struct adapter_pvt *) data;
4331 
4332  while (!check_unloading()) {
4333  /* check for new sco connections */
4334  if (ast_io_wait(adapter->accept_io, 0) == -1) {
4335  /* handle errors */
4336  ast_log(LOG_ERROR, "ast_io_wait() failed for adapter %s\n", adapter->id);
4337  break;
4338  }
4339 
4340  /* handle audio data */
4341  if (ast_io_wait(adapter->io, 1) == -1) {
4342  ast_log(LOG_ERROR, "ast_io_wait() failed for audio on adapter %s\n", adapter->id);
4343  break;
4344  }
4345  }
4346 
4347  return NULL;
4348 }
4349 
4350 /*
4351 
4352  Module
4353 
4354 */
4355 
4356 /*!
4357  * \brief Load an adapter from the configuration file.
4358  * \param cfg the config to load the adapter from
4359  * \param cat the adapter to load
4360  *
4361  * This function loads the given adapter and starts the sco listener thread for
4362  * that adapter.
4363  *
4364  * \return NULL on error, a pointer to the adapter that was loaded on success
4365  */
4366 static struct adapter_pvt *mbl_load_adapter(struct ast_config *cfg, const char *cat)
4367 {
4368  const char *id, *address;
4369  struct adapter_pvt *adapter;
4370  struct ast_variable *v;
4371  struct hci_dev_req dr;
4372  uint16_t vs;
4373 
4374  id = ast_variable_retrieve(cfg, cat, "id");
4375  address = ast_variable_retrieve(cfg, cat, "address");
4376 
4377  if (ast_strlen_zero(id) || ast_strlen_zero(address)) {
4378  ast_log(LOG_ERROR, "Skipping adapter. Missing id or address settings.\n");
4379  goto e_return;
4380  }
4381 
4382  ast_debug(1, "Reading configuration for adapter %s %s.\n", id, address);
4383 
4384  if (!(adapter = ast_calloc(1, sizeof(*adapter)))) {
4385  ast_log(LOG_ERROR, "Skipping adapter %s. Error allocating memory.\n", id);
4386  goto e_return;
4387  }
4388 
4389  ast_copy_string(adapter->id, id, sizeof(adapter->id));
4390  str2ba(address, &adapter->addr);
4391 
4392  /* attempt to connect to the adapter */
4393  adapter->dev_id = hci_devid(address);
4394  adapter->hci_socket = hci_open_dev(adapter->dev_id);
4395  if (adapter->dev_id < 0 || adapter->hci_socket < 0) {
4396  ast_log(LOG_ERROR, "Skipping adapter %s. Unable to communicate with adapter.\n", adapter->id);
4397  goto e_free_adapter;
4398  }
4399 
4400  /* check voice setting */
4401  hci_read_voice_setting(adapter->hci_socket, &vs, 1000);
4402  vs = htobs(vs);
4403  if (vs != 0x0060) {
4404  ast_log(LOG_ERROR, "Skipping adapter %s. Voice setting must be 0x0060 - see 'man hciconfig' for details.\n", adapter->id);
4405  goto e_hci_close_dev;
4406  }
4407 
4408  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
4409  if (!strcasecmp(v->name, "forcemaster")) {
4410  if (ast_true(v->value)) {
4411  dr.dev_id = adapter->dev_id;
4412  if (hci_strtolm("master", &dr.dev_opt)) {
4413  if (ioctl(adapter->hci_socket, HCISETLINKMODE, (unsigned long) &dr) < 0) {
4414  ast_log(LOG_WARNING, "Unable to set adapter %s link mode to MASTER. Ignoring 'forcemaster' option.\n", adapter->id);
4415  }
4416  }
4417  }
4418  } else if (!strcasecmp(v->name, "alignmentdetection")) {
4419  adapter->alignment_detection = ast_true(v->value);
4420  }
4421  }
4422 
4423  /* create io contexts */
4424  if (!(adapter->accept_io = io_context_create())) {
4425  ast_log(LOG_ERROR, "Unable to create I/O context for audio connection listener\n");
4426  goto e_hci_close_dev;
4427  }
4428 
4429  if (!(adapter->io = io_context_create())) {
4430  ast_log(LOG_ERROR, "Unable to create I/O context for audio connections\n");
4431  goto e_destroy_accept_io;
4432  }
4433 
4434  /* bind the sco listener socket */
4435  if (sco_bind(adapter) < 0) {
4436  ast_log(LOG_ERROR, "Skipping adapter %s. Error binding audio connection listener socket.\n", adapter->id);
4437  goto e_destroy_io;
4438  }
4439 
4440  /* add the socket to the io context */
4441  if (!(adapter->sco_id = ast_io_add(adapter->accept_io, adapter->sco_socket, sco_accept, AST_IO_IN, adapter))) {
4442  ast_log(LOG_ERROR, "Skipping adapter %s. Error adding listener socket to I/O context.\n", adapter->id);
4443  goto e_close_sco;
4444  }
4445 
4446  /* start the sco listener for this adapter */
4447  if (ast_pthread_create_background(&adapter->sco_listener_thread, NULL, do_sco_listen, adapter)) {
4448  ast_log(LOG_ERROR, "Skipping adapter %s. Error creating audio connection listener thread.\n", adapter->id);
4449  goto e_remove_sco;
4450  }
4451 
4452  /* add the adapter to our global list */
4453  AST_RWLIST_WRLOCK(&adapters);
4454  AST_RWLIST_INSERT_HEAD(&adapters, adapter, entry);
4455  AST_RWLIST_UNLOCK(&adapters);
4456  ast_debug(1, "Loaded adapter %s %s.\n", adapter->id, address);
4457 
4458  return adapter;
4459 
4460 e_remove_sco:
4461  ast_io_remove(adapter->accept_io, adapter->sco_id);
4462 e_close_sco:
4463  close(adapter->sco_socket);
4464 e_destroy_io:
4465  io_context_destroy(adapter->io);
4466 e_destroy_accept_io:
4467  io_context_destroy(adapter->accept_io);
4468 e_hci_close_dev:
4469  hci_close_dev(adapter->hci_socket);
4470 e_free_adapter:
4471  ast_free(adapter);
4472 e_return:
4473  return NULL;
4474 }
4475 
4476 /*!
4477  * \brief Load a device from the configuration file.
4478  * \param cfg the config to load the device from
4479  * \param cat the device to load
4480  * \return NULL on error, a pointer to the device that was loaded on success
4481  */
4482 static struct mbl_pvt *mbl_load_device(struct ast_config *cfg, const char *cat)
4483 {
4484  struct mbl_pvt *pvt;
4485  struct adapter_pvt *adapter;
4486  struct ast_variable *v;
4487  const char *address, *adapter_str, *port;
4488  ast_debug(1, "Reading configuration for device %s.\n", cat);
4489 
4490  adapter_str = ast_variable_retrieve(cfg, cat, "adapter");
4491  if(ast_strlen_zero(adapter_str)) {
4492  ast_log(LOG_ERROR, "Skipping device %s. No adapter specified.\n", cat);
4493  goto e_return;
4494  }
4495 
4496  /* find the adapter */
4497  AST_RWLIST_RDLOCK(&adapters);
4498  AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
4499  if (!strcmp(adapter->id, adapter_str))
4500  break;
4501  }
4502  AST_RWLIST_UNLOCK(&adapters);
4503  if (!adapter) {
4504  ast_log(LOG_ERROR, "Skipping device %s. Unknown adapter '%s' specified.\n", cat, adapter_str);
4505  goto e_return;
4506  }
4507 
4508  address = ast_variable_retrieve(cfg, cat, "address");
4509  port = ast_variable_retrieve(cfg, cat, "port");
4510  if (ast_strlen_zero(port) || ast_strlen_zero(address)) {
4511  ast_log(LOG_ERROR, "Skipping device %s. Missing required port or address setting.\n", cat);
4512  goto e_return;
4513  }
4514 
4515  /* create and initialize our pvt structure */
4516  if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
4517  ast_log(LOG_ERROR, "Skipping device %s. Error allocating memory.\n", cat);
4518  goto e_return;
4519  }
4520 
4521  ast_mutex_init(&pvt->lock);
4522  AST_LIST_HEAD_INIT_NOLOCK(&pvt->msg_queue);
4523 
4524  /* set some defaults */
4525 
4526  pvt->type = MBL_TYPE_PHONE;
4527  ast_copy_string(pvt->context, "default", sizeof(pvt->context));
4528 
4529  /* populate the pvt structure */
4530  pvt->adapter = adapter;
4531  ast_copy_string(pvt->id, cat, sizeof(pvt->id));
4532  str2ba(address, &pvt->addr);
4533  pvt->timeout = -1;
4534  pvt->rfcomm_socket = -1;
4535  pvt->rfcomm_port = atoi(port);
4536  pvt->sco_socket = -1;
4537  pvt->monitor_thread = AST_PTHREADT_NULL;
4538  pvt->ring_sched_id = -1;
4539  pvt->has_sms = 1;
4540 
4541  /* setup the bt_out_smoother */
4542  if (!(pvt->bt_out_smoother = ast_smoother_new(DEVICE_FRAME_SIZE))) {
4543  ast_log(LOG_ERROR, "Skipping device %s. Error setting up frame bt_out_smoother.\n", cat);
4544  goto e_free_pvt;
4545  }
4546 
4547  /* setup the bt_in_smoother */
4548  if (!(pvt->bt_in_smoother = ast_smoother_new(CHANNEL_FRAME_SIZE))) {
4549  ast_log(LOG_ERROR, "Skipping device %s. Error setting up frame bt_in_smoother.\n", cat);
4550  goto e_free_bt_out_smoother;
4551  }
4552 
4553  /* setup the dsp */
4554  if (!(pvt->dsp = ast_dsp_new())) {
4555  ast_log(LOG_ERROR, "Skipping device %s. Error setting up dsp for dtmf detection.\n", cat);
4556  goto e_free_bt_in_smoother;
4557  }
4558 
4559  /* setup the scheduler */
4560  if (!(pvt->sched = ast_sched_context_create())) {
4561  ast_log(LOG_ERROR, "Unable to create scheduler context for headset device\n");
4562  goto e_free_dsp;
4563  }
4564 
4565  ast_dsp_set_features(pvt->dsp, DSP_FEATURE_DIGIT_DETECT);
4567 
4568  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
4569  if (!strcasecmp(v->name, "type")) {
4570  if (!strcasecmp(v->value, "headset"))
4571  pvt->type = MBL_TYPE_HEADSET;
4572  else
4573  pvt->type = MBL_TYPE_PHONE;
4574  } else if (!strcasecmp(v->name, "context")) {
4575  ast_copy_string(pvt->context, v->value, sizeof(pvt->context));
4576  } else if (!strcasecmp(v->name, "group")) {
4577  /* group is set to 0 if invalid */
4578  pvt->group = atoi(v->value);
4579  } else if (!strcasecmp(v->name, "sms")) {
4580  pvt->has_sms = ast_true(v->value);
4581  } else if (!strcasecmp(v->name, "nocallsetup")) {
4582  pvt->no_callsetup = ast_true(v->value);
4583 
4584  if (pvt->no_callsetup)
4585  ast_debug(1, "Setting nocallsetup mode for device %s.\n", pvt->id);
4586  } else if (!strcasecmp(v->name, "blackberry")) {
4587  pvt->blackberry = ast_true(v->value);
4588  pvt->has_sms = 0;
4589  }
4590  }
4591 
4592  if (pvt->type == MBL_TYPE_PHONE) {
4593  if (!(pvt->hfp = ast_calloc(1, sizeof(*pvt->hfp)))) {
4594  ast_log(LOG_ERROR, "Skipping device %s. Error allocating memory.\n", pvt->id);
4595  goto e_free_sched;
4596  }
4597 
4598  pvt->hfp->owner = pvt;
4599  pvt->hfp->rport = pvt->rfcomm_port;
4600  pvt->hfp->nocallsetup = pvt->no_callsetup;
4601  } else {
4602  pvt->has_sms = 0;
4603  }
4604 
4606  AST_RWLIST_INSERT_HEAD(&devices, pvt, entry);
4608  ast_debug(1, "Loaded device %s.\n", pvt->id);
4609 
4610  return pvt;
4611 
4612 e_free_sched:
4613  ast_sched_context_destroy(pvt->sched);
4614 e_free_dsp:
4615  ast_dsp_free(pvt->dsp);
4616 e_free_bt_in_smoother:
4617  ast_smoother_free(pvt->bt_in_smoother);
4618 e_free_bt_out_smoother:
4619  ast_smoother_free(pvt->bt_out_smoother);
4620 e_free_pvt:
4621  ast_free(pvt);
4622 e_return:
4623  return NULL;
4624 }
4625 
4626 static int mbl_load_config(void)
4627 {
4628  struct ast_config *cfg;
4629  const char *cat;
4630  struct ast_variable *v;
4631  struct ast_flags config_flags = { 0 };
4632 
4633  cfg = ast_config_load(MBL_CONFIG, config_flags);
4634  if (!cfg) {
4635  cfg = ast_config_load(MBL_CONFIG_OLD, config_flags);
4636  }
4637  if (!cfg)
4638  return -1;
4639 
4640  /* parse [general] section */
4641  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
4642  if (!strcasecmp(v->name, "interval")) {
4643  if (!sscanf(v->value, "%d", &discovery_interval)) {
4644  ast_log(LOG_NOTICE, "error parsing 'interval' in general section, using default value\n");
4645  }
4646  }
4647  }
4648 
4649  /* load adapters */
4650  for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
4651  if (!strcasecmp(cat, "adapter")) {
4652  mbl_load_adapter(cfg, cat);
4653  }
4654  }
4655 
4656  if (AST_RWLIST_EMPTY(&adapters)) {
4657  ast_log(LOG_ERROR,
4658  "***********************************************************************\n"
4659  "No adapters could be loaded from the configuration file.\n"
4660  "Please review mobile.conf. See sample for details.\n"
4661  "***********************************************************************\n"
4662  );
4663  ast_config_destroy(cfg);
4664  return -1;
4665  }
4666 
4667  /* now load devices */
4668  for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
4669  if (strcasecmp(cat, "general") && strcasecmp(cat, "adapter")) {
4670  mbl_load_device(cfg, cat);
4671  }
4672  }
4673 
4674  ast_config_destroy(cfg);
4675 
4676  return 0;
4677 }
4678 
4679 /*!
4680  * \brief Check if the module is unloading.
4681  * \retval 0 not unloading
4682  * \retval 1 unloading
4683  */
4684 static inline int check_unloading()
4685 {
4686  int res;
4687  ast_mutex_lock(&unload_mutex);
4688  res = unloading_flag;
4689  ast_mutex_unlock(&unload_mutex);
4690 
4691  return res;
4692 }
4693 
4694 /*!
4695  * \brief Set the unloading flag.
4696  */
4697 static inline void set_unloading()
4698 {
4699  ast_mutex_lock(&unload_mutex);
4700  unloading_flag = 1;
4701  ast_mutex_unlock(&unload_mutex);
4702 }
4703 
4704 static int unload_module(void)
4705 {
4706  struct mbl_pvt *pvt;
4707  struct adapter_pvt *adapter;
4708 
4709  /* First, take us out of the channel loop */
4710  ast_channel_unregister(&mbl_tech);
4711 
4712  /* Unregister the CLI & APP */
4713  ast_cli_unregister_multiple(mbl_cli, sizeof(mbl_cli) / sizeof(mbl_cli[0]));
4714  ast_unregister_application(app_mblstatus);
4715  ast_unregister_application(app_mblsendsms);
4716 
4717  /* signal everyone we are unloading */
4718  set_unloading();
4719 
4720  /* Kill the discovery thread */
4721  if (discovery_thread != AST_PTHREADT_NULL) {
4722  pthread_kill(discovery_thread, SIGURG);
4723  pthread_join(discovery_thread, NULL);
4724  }
4725 
4726  /* stop the sco listener threads */
4727  AST_RWLIST_WRLOCK(&adapters);
4728  AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
4729  pthread_kill(adapter->sco_listener_thread, SIGURG);
4730  pthread_join(adapter->sco_listener_thread, NULL);
4731  }
4732  AST_RWLIST_UNLOCK(&adapters);
4733 
4734  /* Destroy the device list */
4736  while ((pvt = AST_RWLIST_REMOVE_HEAD(&devices, entry))) {
4737  if (pvt->monitor_thread != AST_PTHREADT_NULL) {
4738  pthread_kill(pvt->monitor_thread, SIGURG);
4739  pthread_join(pvt->monitor_thread, NULL);
4740  }
4741 
4742  close(pvt->sco_socket);
4743  close(pvt->rfcomm_socket);
4744 
4745  msg_queue_flush(pvt);
4746 
4747  if (pvt->hfp) {
4748  ast_free(pvt->hfp);
4749  }
4750 
4751  ast_smoother_free(pvt->bt_out_smoother);
4752  ast_smoother_free(pvt->bt_in_smoother);
4753  ast_dsp_free(pvt->dsp);
4754  ast_sched_context_destroy(pvt->sched);
4755  ast_free(pvt);
4756  }
4758 
4759  /* Destroy the adapter list */
4760  AST_RWLIST_WRLOCK(&adapters);
4761  while ((adapter = AST_RWLIST_REMOVE_HEAD(&adapters, entry))) {
4762  close(adapter->sco_socket);
4763  io_context_destroy(adapter->io);
4764  io_context_destroy(adapter->accept_io);
4765  hci_close_dev(adapter->hci_socket);
4766  ast_free(adapter);
4767  }
4768  AST_RWLIST_UNLOCK(&adapters);
4769 
4770  if (sdp_session)
4771  sdp_close(sdp_session);
4772 
4773  ao2_ref(mbl_tech.capabilities, -1);
4774  mbl_tech.capabilities = NULL;
4775  return 0;
4776 }
4777 
4778 static int load_module(void)
4779 {
4780 
4781  int dev_id, s;
4782 
4784  return AST_MODULE_LOAD_DECLINE;
4785  }
4786 
4787  ast_format_cap_append(mbl_tech.capabilities, DEVICE_FRAME_FORMAT, 0);
4788  /* Check if we have Bluetooth, no point loading otherwise... */
4789  dev_id = hci_get_route(NULL);
4790 
4791  s = hci_open_dev(dev_id);
4792  if (dev_id < 0 || s < 0) {
4793  ast_log(LOG_ERROR, "No Bluetooth devices found. Not loading module.\n");
4794  ao2_ref(mbl_tech.capabilities, -1);
4795  mbl_tech.capabilities = NULL;
4796  hci_close_dev(s);
4797  return AST_MODULE_LOAD_DECLINE;
4798  }
4799 
4800  hci_close_dev(s);
4801 
4802  if (mbl_load_config()) {
4803  ast_log(LOG_ERROR, "Errors reading config file %s. Not loading module.\n", MBL_CONFIG);
4804  ao2_ref(mbl_tech.capabilities, -1);
4805  mbl_tech.capabilities = NULL;
4806  return AST_MODULE_LOAD_DECLINE;
4807  }
4808 
4809  sdp_session = sdp_register();
4810 
4811  /* Spin the discovery thread */
4812  if (ast_pthread_create_background(&discovery_thread, NULL, do_discovery, NULL) < 0) {
4813  ast_log(LOG_ERROR, "Unable to create discovery thread.\n");
4814  goto e_cleanup;
4815  }
4816 
4817  /* register our channel type */
4818  if (ast_channel_register(&mbl_tech)) {
4819  ast_log(LOG_ERROR, "Unable to register channel class %s\n", "Mobile");
4820  goto e_cleanup;
4821  }
4822 
4823  ast_cli_register_multiple(mbl_cli, sizeof(mbl_cli) / sizeof(mbl_cli[0]));
4824  ast_register_application(app_mblstatus, mbl_status_exec, mblstatus_synopsis, mblstatus_desc);
4825  ast_register_application(app_mblsendsms, mbl_sendsms_exec, mblsendsms_synopsis, mblsendsms_desc);
4826 
4827  return AST_MODULE_LOAD_SUCCESS;
4828 
4829 e_cleanup:
4830  unload_module();
4831 
4832  return AST_MODULE_LOAD_DECLINE;
4833 }
4834 
4835 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Bluetooth Mobile Device Channel Driver",
4836  .support_level = AST_MODULE_SUPPORT_EXTENDED,
4837  .load = load_module,
4838  .unload = unload_module,
4839  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
4840 );
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:278
struct ast_variable * next
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
static int handle_response_busy(struct mbl_pvt *pvt)
Handle BUSY messages.
Definition: chan_mobile.c:3833
static int handle_response_cind(struct mbl_pvt *pvt, char *buf)
Handle the CIND response.
Definition: chan_mobile.c:3233
static int rfcomm_read_until_ok(int rsock, char **buf, size_t count, size_t *in_count)
Read until a.
Definition: chan_mobile.c:1609
int control
Definition: chan_mobile.c:309
static int handle_response_ciev(struct mbl_pvt *pvt, char *buf)
Handle AT+CIEV messages.
Definition: chan_mobile.c:3561
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1499
Main Channel structure associated with a channel.
int status
Definition: chan_mobile.c:308
static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf)
Handle NO CARRIER messages.
Definition: chan_mobile.c:3863
static int hfp_send_dtmf(struct hfp_pvt *hfp, char digit)
Send a DTMF command.
Definition: chan_mobile.c:2598
static int hfp_send_atd(struct hfp_pvt *hfp, const char *number)
Send ATD.
Definition: chan_mobile.c:2693
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
static int rfcomm_read_result(int rsock, char **buf, size_t count, size_t *in_count)
Read and AT result code.
Definition: chan_mobile.c:1725
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
static int rfcomm_wait(int rsock, int *ms)
Wait for activity on an rfcomm socket.
Definition: chan_mobile.c:1479
static char * hfp_parse_cusd(struct hfp_pvt *hfp, char *buf)
Parse a CUSD answer.
Definition: chan_mobile.c:2418
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:786
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
unsigned int connected
Definition: chan_mobile.c:161
Device state management.
static struct mbl_pvt * mbl_load_device(struct ast_config *cfg, const char *cat)
Load a device from the configuration file.
Definition: chan_mobile.c:4482
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
int ecnr
Definition: chan_mobile.c:317
int cind_index[16]
Definition: chan_mobile.c:349
Convenient Signal Processing routines.
int volume
Definition: chan_mobile.c:307
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static int hfp_parse_cind_test(struct hfp_pvt *hfp, char *buf)
Parse the result of the AT+CIND=? command.
Definition: chan_mobile.c:2820
int ecnr
Definition: chan_mobile.c:303
struct io_context * accept_io
Definition: chan_mobile.c:107
static int handle_response_brsf(struct mbl_pvt *pvt, char *buf)
Handle the BRSF response.
Definition: chan_mobile.c:3198
descriptor for a cli entry.
Definition: cli.h:171
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
int cid
Definition: chan_mobile.c:305
unsigned int answered
Definition: chan_mobile.c:160
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1758
pthread_t sco_listener_thread
Definition: chan_mobile.c:110
static int check_unloading(void)
Check if the module is unloading.
Definition: chan_mobile.c:4684
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
int rsock
Definition: chan_mobile.c:352
static int hfp_parse_brsf(struct hfp_pvt *hfp, const char *buf)
Parse BRSF data.
Definition: chan_mobile.c:2726
Structure for variables, used for configurations and for channel variables.
static int hsp_send_vgs(int rsock, int gain)
Send a speaker gain unsolicited AT response.
Definition: chan_mobile.c:2945
static int hfp_send_cind(struct hfp_pvt *hfp)
Send the CIND read command.
Definition: chan_mobile.c:2527
static struct ast_sockaddr address
Address for UDPTL.
Definition: res_pjsip_t38.c:56
#define AST_IO_IN
Definition: io.h:34
static int handle_response_cmti(struct mbl_pvt *pvt, char *buf)
Handle AT+CMTI messages.
Definition: chan_mobile.c:3710
Definition: sched.c:76
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Definition: dsp.c:1810
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
static int rfcomm_write(int rsock, char *buf)
Write to an rfcomm socket.
Definition: chan_mobile.c:1436
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition: io.c:162
int timeout
Definition: chan_mobile.c:139
int nocallsetup
Definition: chan_mobile.c:347
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
ast_control_frame_type
Internal control frame subtype field values.
static int hfp_send_cmer(struct hfp_pvt *hfp, int status)
Enable or disable indicator events reporting.
Definition: chan_mobile.c:2546
static int rfcomm_write_full(int rsock, char *buf, size_t count)
Write to an rfcomm socket.
Definition: chan_mobile.c:1454
static int hfp_send_ata(struct hfp_pvt *hfp)
Send ATA.
Definition: chan_mobile.c:2704
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int cw
Definition: chan_mobile.c:304
static int hfp_send_sms_text(struct hfp_pvt *hfp, const char *message)
Send the text of an SMS message.
Definition: chan_mobile.c:2672
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
const char * data
I/O Management (derived from Cheops-NG)
static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf)
Handle NO DIALTONE messages.
Definition: chan_mobile.c:3848
static int hsp_send_error(int rsock)
Send an ERROR AT response.
Definition: chan_mobile.c:2935
static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf)
Handle AT+CMGR messages.
Definition: chan_mobile.c:3737
unsigned int incoming
Definition: chan_mobile.c:154
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static int at_match_prefix(char *buf, char *prefix)
Match the given buffer with the given prefix.
Definition: chan_mobile.c:2003
Asterisk internal frame definitions.
static int sco_bind(struct adapter_pvt *adapter)
Bind an SCO listener socket for the given adapter.
Definition: chan_mobile.c:1958
struct ast_frame_subclass subclass
int * sco_id
Definition: chan_mobile.c:108
Utility functions.
static int parse_next_token(char string[], const int start, const char delim)
Terminate current token and return an index to start of the next token.
Definition: chan_mobile.c:2299
enum ast_format_cmp_res ast_format_cap_iscompatible_format(const struct ast_format_cap *cap, const struct ast_format *format)
Find if ast_format is within the capabilities of the ast_format_cap object.
Definition: format_cap.c:581
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
Definition: linkedlists.h:333
Number structure.
Definition: app_followme.c:154
static int hfp_parse_cmti(struct hfp_pvt *hfp, char *buf)
Parse a CMTI notification.
Definition: chan_mobile.c:2328
static int hfp_parse_cind_indicator(struct hfp_pvt *hfp, int group, char *indicator)
Parse and store the given indicator.
Definition: chan_mobile.c:2744
static struct adapter_pvt * mbl_load_adapter(struct ast_config *cfg, const char *cat)
Load an adapter from the configuration file.
Definition: chan_mobile.c:4366
int reject
Definition: chan_mobile.c:321
Configuration File Parser.
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1818
static int hfp_send_clip(struct hfp_pvt *hfp, int status)
Enable or disable calling line identification.
Definition: chan_mobile.c:2585
static int handle_response_cusd(struct mbl_pvt *pvt, char *buf)
Handle CUSD messages.
Definition: chan_mobile.c:3813
#define ast_config_load(filename, flags)
Load a config file.
static int rfcomm_read_and_append_char(int rsock, char **buf, size_t count, size_t *in_count, char *result, char expected)
Read a character from the given stream and append it to the given buffer if it matches the expected c...
Definition: chan_mobile.c:1544
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
Waits for input on an fd.
Definition: channel.c:2980
General Asterisk PBX channel definitions.
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
Definition: chan_dahdi.c:761
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition: io.c:107
const char * src
static int hfp_send_vgs(struct hfp_pvt *hfp, int value)
Send the current speaker gain level.
Definition: chan_mobile.c:2558
struct mbl_pvt * owner
Definition: chan_mobile.c:345
Definition: dsp.c:407
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int control
Definition: chan_mobile.c:323
static int handle_response_clip(struct mbl_pvt *pvt, char *buf)
Handle AT+CLIP messages.
Definition: chan_mobile.c:3653
static int hsp_send_vgm(int rsock, int gain)
Send a microphone gain unsolicited AT response.
Definition: chan_mobile.c:2957
#define ast_register_application(app, execute, synopsis, description)
Register an application.
Definition: module.h:624
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
Global IO variables are now in a struct in order to be made threadsafe.
Definition: io.c:71
static int hfp_send_brsf(struct hfp_pvt *hfp, struct hfp_hf *brsf)
Send a BRSF request.
Definition: chan_mobile.c:2516
struct hfp_pvt * hfp
Definition: chan_mobile.c:130
static int handle_response_ring(struct mbl_pvt *pvt, char *buf)
Handle RING messages.
Definition: chan_mobile.c:3693
static struct stasis_rest_handlers events
REST handler for /api-docs/events.json.
int sent_alerting
Definition: chan_mobile.c:354
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
struct io_context * io
Definition: chan_mobile.c:106
int battchg
Definition: chan_mobile.c:337
A set of macros to manage forward-linked lists.
#define ast_debug(level,...)
Log a DEBUG message.
static int hfp_brsf2int(struct hfp_hf *hf)
Convert a hfp_hf struct to a BRSF int.
Definition: chan_mobile.c:2470
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
static int sco_accept(int *id, int fd, short events, void *data)
Accept SCO connections. This function is an ast_io callback function used to accept incoming sco audi...
Definition: chan_mobile.c:1898
int ring
Definition: chan_mobile.c:319
static int hfp_parse_ecav(struct hfp_pvt *hfp, char *buf)
Parse a ECAV event.
Definition: chan_mobile.c:2166
static int msg_queue_push(struct mbl_pvt *pvt, at_message_t expect, at_message_t response_to)
Add an item to the back of the queue.
Definition: chan_mobile.c:2984
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
This struct holds mappings for indications.
Definition: chan_mobile.c:330
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
static int handle_response_ok(struct mbl_pvt *pvt, char *buf)
Handle OK AT messages.
Definition: chan_mobile.c:3275
Core PBX routines and definitions.
static struct msg_queue_entry * msg_queue_pop(struct mbl_pvt *pvt)
Remove an item from the front of the queue.
Definition: chan_mobile.c:3025
int initialized
Definition: chan_mobile.c:346
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
This struct holds HFP features that we support.
Definition: chan_mobile.c:302
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
static int rfcomm_read_sms_prompt(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of an AT SMS prompt.
Definition: chan_mobile.c:1593
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Definition: linkedlists.h:225
static const char * at_msg2str(at_message_t msg)
Get the string representation of the given AT message.
Definition: chan_mobile.c:2076
int callheld
Definition: chan_mobile.c:334
static int rfcomm_read_cmgr(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of a +CMGR message.
Definition: chan_mobile.c:1706
int callsetup
Definition: chan_mobile.c:333
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
static int hfp_send_cind_test(struct hfp_pvt *hfp)
Send the CIND test command.
Definition: chan_mobile.c:2536
int cind_state[16]
Definition: chan_mobile.c:350
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
Support for dynamic strings.
Definition: strings.h:623
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
struct hfp_cind cind_map
Definition: chan_mobile.c:351
static int rfcomm_read_until_crlf(int rsock, char **buf, size_t count, size_t *in_count)
Read until.
Definition: chan_mobile.c:1564
unsigned int needchup
Definition: chan_mobile.c:158
static int hsp_send_ring(int rsock)
Send a RING unsolicited AT response.
Definition: chan_mobile.c:2968
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
General Definitions for Asterisk top level program Included by asterisk.h to handle platform-specific...
ast_mutex_t lock
Definition: chan_mobile.c:121
struct ast_format_cap * capabilities
Definition: channel.h:632
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
int cw
Definition: chan_mobile.c:316
int signal
Definition: chan_mobile.c:335
static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value)
Parse a CIEV event.
Definition: chan_mobile.c:2197
static int hfp_send_cusd(struct hfp_pvt *hfp, const char *code)
Send CUSD.
Definition: chan_mobile.c:2714
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1768
static int hfp_send_cnmi(struct hfp_pvt *hfp)
Setup SMS new message indication.
Definition: chan_mobile.c:2638
#define AST_MAX_CONTEXT
Definition: channel.h:135
union ast_frame::@224 data
char * command
Definition: cli.h:186
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static struct hfp_ag * hfp_int2brsf(int brsf, struct hfp_ag *ag)
Convert a BRSF int to an hfp_ag struct.
Definition: chan_mobile.c:2492
static int hfp_send_chup(struct hfp_pvt *hfp)
Send AT+CHUP.
Definition: chan_mobile.c:2683
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
int voice
Definition: chan_mobile.c:318
static int hfp_send_ecam(struct hfp_pvt *hfp)
Enable Sony Ericsson extensions / indications.
Definition: chan_mobile.c:2184
Support for logging to various files, console and syslog Configuration in file logger.conf.
static int hfp_send_cmgf(struct hfp_pvt *hfp, int mode)
Set the SMS mode.
Definition: chan_mobile.c:2627
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_isphonenumber(const char *n)
Check if a string consists only of digits and + #.
Definition: callerid.c:1152
static void * do_sco_listen(void *data)
Service new and existing SCO connections. This thread accepts new sco connections and handles audio d...
Definition: chan_mobile.c:4328
int errors
Definition: chan_mobile.c:324
unsigned int outgoing_sms
Definition: chan_mobile.c:155
Definition: chan_mobile.c:460
int tag
Definition: chan_mobile.c:320
static int hsp_send_ok(int rsock)
Send an OK AT response.
Definition: chan_mobile.c:2926
int service
Definition: chan_mobile.c:331
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:567
static at_message_t at_read_full(int rsock, char *buf, size_t count)
Read an AT message and classify it.
Definition: chan_mobile.c:2017
Structure used to handle boolean flags.
Definition: utils.h:199
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:245
struct timeval delivery
const char * usage
Definition: cli.h:177
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static int hfp_send_cmgr(struct hfp_pvt *hfp, int index)
Read an SMS message.
Definition: chan_mobile.c:2648
static int rfcomm_read_command(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of an AT command.
Definition: chan_mobile.c:1763
struct ast_frame ast_null_frame
Definition: main/frame.c:79
unsigned int incoming_sms
Definition: chan_mobile.c:156
struct hfp_ag brsf
Definition: chan_mobile.c:348
static int hfp_send_cmgs(struct hfp_pvt *hfp, const char *number)
Start sending an SMS message.
Definition: chan_mobile.c:2660
unsigned int outgoing
Definition: chan_mobile.c:153
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
static ssize_t rfcomm_read(int rsock, char *buf, size_t count)
Read one Hayes AT message from an rfcomm socket.
Definition: chan_mobile.c:1808
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
static void msg_queue_flush(struct mbl_pvt *pvt)
Remove all items from the queue and free them.
Definition: chan_mobile.c:3048
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386
static int handle_response_error(struct mbl_pvt *pvt, char *buf)
Handle ERROR AT messages.
Definition: chan_mobile.c:3444
static void set_unloading(void)
Set the unloading flag.
Definition: chan_mobile.c:4697
static struct msg_queue_entry * msg_queue_head(struct mbl_pvt *pvt)
Get the head of a queue.
Definition: chan_mobile.c:3060
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:433
static int hfp_parse_cmgr(struct hfp_pvt *hfp, char *buf, char **from_number, char **text)
Parse a CMGR message.
Definition: chan_mobile.c:2354
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
Options provided by main asterisk program.
This struct holds state information about the current hfp connection.
Definition: chan_mobile.c:344
Definition: search.h:40
int voice
Definition: chan_mobile.c:306
int status
Definition: chan_mobile.c:322
unsigned int needring
Definition: chan_mobile.c:159
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
enum ast_frame_type frametype
static int rfcomm_read_and_expect_char(int rsock, char *result, char expected)
Read a character from the given stream and check if it matches what we expected.
Definition: chan_mobile.c:1520
int rport
Definition: chan_mobile.c:353
static int handle_sms_prompt(struct mbl_pvt *pvt, char *buf)
Send an SMS message from the queue.
Definition: chan_mobile.c:3782
struct ast_format * format
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
This struct holds HFP features the AG supports.
Definition: chan_mobile.c:315
unsigned int needcallerid
Definition: chan_mobile.c:157
static void msg_queue_free_and_pop(struct mbl_pvt *pvt)
Remove an item from the front of the queue, and free it.
Definition: chan_mobile.c:3034
static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf)
Parse a CLIP event.
Definition: chan_mobile.c:2226
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:271
static int msg_queue_push_data(struct mbl_pvt *pvt, at_message_t expect, at_message_t response_to, void *data)
Add an item to the back of the queue with data.
Definition: chan_mobile.c:3006
Structure for mutex and tracking information.
Definition: lock.h:135
static void rfcomm_append_buf(char **buf, size_t count, size_t *in_count, char c)
Append the given character to the given buffer and increase the in_count.
Definition: chan_mobile.c:1508
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1857
Media Format Cache API.
static int hfp_parse_cind(struct hfp_pvt *hfp, char *buf)
Read the result of the AT+CIND? command.
Definition: chan_mobile.c:2770
#define AST_APP_ARG(name)
Define an application argument.
static int mbl_has_service(struct mbl_pvt *pvt)
Check if a mobile device has service.
Definition: chan_mobile.c:1369
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition: io.c:81