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>
78#define MBL_CONFIG "chan_mobile.conf"
79#define MBL_CONFIG_OLD "mobile.conf"
81#define DEVICE_FRAME_SIZE 48
82#define DEVICE_FRAME_FORMAT ast_format_slin
83#define CHANNEL_FRAME_SIZE 80
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";
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";
249static int sdp_search(
char *addr,
int profile);
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)
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)
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
286#define HFP_CIND_CALL_NONE 0
287#define HFP_CIND_CALL_ACTIVE 1
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
296#define HFP_CIND_SERVICE_NONE 0
297#define HFP_CIND_SERVICE_AVAILABLE 1
374static int parse_next_token(
char string[],
const int start,
const char delim);
481 .description =
"Bluetooth Mobile Device Channel Driver",
501#define FORMAT1 "%-15.15s %-17.17s %-5.5s %-15.15s %-9.9s %-10.10s %-3.3s\n"
505 e->
command =
"mobile show devices";
507 "Usage: mobile show devices\n"
508 " Shows the state of Bluetooth Cell / Mobile devices.\n";
517 ast_cli(
a->fd,
FORMAT1,
"ID",
"Address",
"Group",
"Adapter",
"Connected",
"State",
"SMS");
521 ba2str(&pvt->
addr, bdaddr);
544 inquiry_info *ii =
NULL;
545 int max_rsp, num_rsp;
547 int i, phport, hsport;
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"
558 "Usage: mobile search\n"
559 " Searches for Bluetooth Cell / Mobile devices in range.\n";
577 ast_cli(
a->fd,
"All Bluetooth adapters are in use at this time.\n");
583 flags = IREQ_CACHE_FLUSH;
585 ii =
ast_alloca(max_rsp *
sizeof(inquiry_info));
586 num_rsp = hci_inquiry(adapter->
dev_id,
len, max_rsp,
NULL, &ii, flags);
589 for (i = 0; i < num_rsp; i++) {
590 ba2str(&(ii + i)->bdaddr,
addr);
592 if (hci_read_remote_name(adapter->
hci_socket, &(ii + i)->bdaddr,
sizeof(
name) - 1,
name, 0) < 0)
593 strcpy(
name,
"[unknown]");
600 (phport > 0) ?
"Phone" :
"Headset", (phport > 0) ? phport : hsport);
603 ast_cli(
a->fd,
"No Bluetooth Cell / Mobile devices found.\n");
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";
633 if (!strcmp(pvt->
id,
a->argv[2]))
639 ast_cli(
a->fd,
"Device %s not found.\n",
a->argv[2]);
645 ast_cli(
a->fd,
"Device %s not connected.\n",
a->argv[2]);
649 snprintf(
buf,
sizeof(
buf),
"%s\r",
a->argv[3]);
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";
681 if (!strcmp(pvt->
id,
a->argv[2]))
687 ast_cli(
a->fd,
"Device %s not found.\n",
a->argv[2]);
693 ast_cli(
a->fd,
"Device %s not connected.\n",
a->argv[2]);
697 snprintf(
buf,
sizeof(
buf),
"%s",
a->argv[3]);
699 ast_cli(
a->fd,
"[%s] error sending CUSD\n", pvt->
id);
742 if (!strcmp(pvt->
id,
args.device))
788 ast_log(
LOG_ERROR,
"NULL destination for message -- SMS will not be sent.\n");
799 if (!strcmp(pvt->
id,
args.device))
805 ast_log(
LOG_ERROR,
"Bluetooth device %s wasn't found in the list -- SMS will not be sent.\n",
args.device);
811 ast_log(
LOG_ERROR,
"Bluetooth device %s wasn't connected -- SMS will not be sent.\n",
args.device);
816 ast_log(
LOG_ERROR,
"Bluetooth device %s doesn't handle SMS -- SMS will not be sent.\n",
args.device);
867 0, 0, pvt->
context, assignedids, requestor, 0,
884 ast_channel_language_set(chn,
"en");
904 char *dest_dev =
NULL;
905 char *dest_num =
NULL;
923 dest_num = strchr(dest_dev,
'/');
927 if (((dest_dev[0] ==
'g') || (dest_dev[0] ==
'G')) && ((dest_dev[1] >=
'0') && (dest_dev[1] <=
'9'))) {
928 group = atoi(&dest_dev[1]);
940 }
else if (!strcmp(pvt->
id, dest_dev)) {
946 ast_log(
LOG_WARNING,
"Request to call on device %s which is not connected / already in use.\n", dest_dev);
974 char *dest_num =
NULL;
981 dest_num = strchr(dest_dev,
'/');
1039 ast_debug(1,
"[%s] hanging up device\n", pvt->
id);
1129 pvt->
fr.
src =
"Mobile";
1139 ast_debug(1,
"[%s] read error %d, going to wait for new connection\n", pvt->
id,
errno);
1155 }
while (fr ==
NULL);
1201 ast_debug(1,
"fixup failed, no pvt on newchan\n");
1206 if (pvt->
owner == oldchan)
1207 pvt->
owner = newchan;
1223 ast_debug(1,
"Checking device state for device %s\n", device);
1227 if (!strcmp(pvt->
id, device))
1289 for (i=buflen, p=
buf+buflen-1; i>0; i--, p--)
1297 for (i=0,
a=0; i<buflen/2; i++) {
1311 ast_debug(1,
"Alignment Detection Triggered.\n");
1393 struct sockaddr_rc addr;
1396 if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
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) {
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) {
1459 ast_debug(1,
"rfcomm_write() (%d) [%.*s]\n", rsock, (
int) count,
buf);
1461 if ((out_count = write(rsock, p, count)) == -1) {
1481 int exception, outfd;
1489#ifdef RFCOMM_READ_DEBUG
1490#define rfcomm_read_debug(c) __rfcomm_read_debug(c)
1491static void __rfcomm_read_debug(
char c)
1501#define rfcomm_read_debug(c)
1510 if (*in_count < count) {
1528 if ((res = read(rsock,
result, 1)) < 1) {
1533 if (*
result != expected) {
1569 while ((res = read(rsock, &
c, 1)) == 1) {
1574 }
else if (res == -2) {
1736 }
else if (res != -2) {
1748 if (*in_count >= 5 && !strncmp(*
buf - *in_count,
"+CMGR", 5)) {
1768 while ((res = read(rsock, &
c, 1)) == 1) {
1811 size_t in_count = 0;
1816 }
else if (res == -2) {
1836 struct sockaddr_sco addr;
1839 if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 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) {
1857 memset(&addr, 0,
sizeof(addr));
1858 addr.sco_family = AF_BLUETOOTH;
1859 bacpy(&addr.sco_bdaddr, &dst);
1861 if (connect(s, (
struct sockaddr *)&addr,
sizeof(addr)) < 0) {
1877 ast_debug(3,
"sco_write() not ready\n");
1901 struct sockaddr_sco addr;
1906 struct sco_options so;
1909 addrlen =
sizeof(
struct sockaddr_sco);
1910 if ((sock = accept(fd, (
struct sockaddr *)&addr, &addrlen)) == -1) {
1916 getsockopt(sock, SOL_SCO, SCO_OPTIONS, &so, &
len);
1918 ba2str(&addr.sco_bdaddr, saddr);
1919 ast_debug(1,
"Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu);
1925 if (!bacmp(&pvt->
addr, &addr.sco_bdaddr))
1945 ast_debug(1,
"incoming audio connection for pvt without owner\n");
1960 struct sockaddr_sco addr;
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);
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) {
1973 goto e_close_socket;
1975 if (setsockopt(adapter->
sco_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt)) == -1) {
1977 goto e_close_socket;
1981 goto e_close_socket;
2024 if (!strcmp(
"OK",
buf)) {
2026 }
else if (!strcmp(
"ERROR",
buf)) {
2028 }
else if (!strcmp(
"RING",
buf)) {
2030 }
else if (!strcmp(
"AT+CKPD=200",
buf)) {
2032 }
else if (!strcmp(
"> ",
buf)) {
2081 return "PARSE ERROR";
2083 return "READ ERROR";
2107 return "SMS PROMPT";
2109 return "+CMS ERROR";
2113 return "NO DIALTONE";
2115 return "NO CARRIER";
2172 if (!sscanf(
buf,
"*ECAV: %2d,%2d,%2d", &ccid, &ccstatus, &calltype)) {
2203 if (!sscanf(
buf,
"+CIEV: %d,%d", &i,
value)) {
2238 ast_debug(3,
"[%s] hfp_parse_clip is processing \"%s\"\n", hfp->owner->id,
buf);
2240 for (i = 1; i <
ARRAY_LEN(tokens); i++) {
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]]);
2251 ast_debug(1,
"[%s] hfp_parse_clip invalid cidinfo.cnum data \"%s\" - deleting\n",
2261 if (
buf[tokens[5]] ==
'\0' &&
buf[tokens[4]] ==
'\0') {
2264 while (
buf[i] ==
' ') {
2267 if (
buf[i] ==
'"') {
2275 for (cnamtmp =
cidinfo.
cnam; *cnamtmp !=
'\0'; cnamtmp++) {
2276 if (!strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-,abcdefghijklmnopqrstuvwxyz_", *cnamtmp)) {
2282 ast_debug(2,
"[%s] hfp_parse_clip replaced %d invalid byte(s) in cnam data\n",
2283 hfp->owner->id, invalid);
2285 ast_debug(2,
"[%s] hfp_parse_clip returns cnum=%s and cnam=%s\n",
2304 for (index = start;
string[index] != 0; index++) {
2305 if ((
string[index] == delim) && !quoting ) {
2307 string[index] =
'\0';
2310 }
else if (
string[index] ==
'"' && !quoting) {
2313 }
else if (
string[index] ==
'"' ) {
2335 if (!sscanf(
buf,
"+CMTI: %*[^,],%d", &index)) {
2365 for (i = 0; i < s &&
state != 6; i++) {
2368 if (
buf[i] ==
',') {
2373 if (
buf[i] ==
'"') {
2379 *from_number = &
buf[i];
2384 if (
buf[i] ==
'"') {
2390 if (
buf[i] ==
'\n') {
2420 int i, message_start, message_end;
2432 for (i = 0; i < s; i++) {
2433 if (
buf[i] ==
'"') {
2434 message_start = i + 1;
2439 if (message_start == 0 || message_start >= s) {
2444 for (i = s; i > 0; i--) {
2445 if (
buf[i] ==
'"') {
2451 if (message_end == 0) {
2455 if (message_start >= message_end) {
2459 cusd = &
buf[message_start];
2460 buf[message_end] =
'\0';
2519 snprintf(cmd,
sizeof(cmd),
"AT+BRSF=%d\r",
hfp_brsf2int(brsf));
2549 snprintf(cmd,
sizeof(cmd),
"AT+CMER=3,0,0,%d\r",
status ? 1 : 0);
2561 snprintf(cmd,
sizeof(cmd),
"AT+VGS=%d\r",
value);
2574 snprintf(cmd,
sizeof(cmd),
"AT+VGM=%d\r",
value);
2588 snprintf(cmd,
sizeof(cmd),
"AT+CLIP=%d\r",
status ? 1 : 0);
2615 snprintf(cmd,
sizeof(cmd),
"AT+VTS=%c\r",
digit);
2630 snprintf(cmd,
sizeof(cmd),
"AT+CMGF=%d\r", mode);
2651 snprintf(cmd,
sizeof(cmd),
"AT+CMGR=%d\r", index);
2663 snprintf(cmd,
sizeof(cmd),
"AT+CMGS=\"%s\"\r",
number);
2675 snprintf(cmd,
sizeof(cmd),
"%.160s\x1a",
message);
2696 snprintf(cmd,
sizeof(cmd),
"ATD%s;\r",
number);
2717 snprintf(cmd,
sizeof(cmd),
"AT+CUSD=1,\"%s\",15\r", code);
2730 if (!sscanf(
buf,
"+BRSF:%d", &brsf))
2783 for (i = 0; i < s; i++) {
2786 if (
buf[i] ==
' ') {
2796 if (
buf[i] ==
',') {
2834 for (i = 0; i < s; i++) {
2837 if (
buf[i] ==
'(') {
2843 if (
buf[i] ==
'"') {
2852 if (
buf[i] ==
'"') {
2858 if (
buf[i] ==
'(') {
2866 if (
buf[i] ==
')') {
2876 }
else if (!strcmp(
indicator,
"call")) {
2879 }
else if (!strcmp(
indicator,
"callsetup")) {
2883 }
else if (!strcmp(
indicator,
"call_setup")) {
2887 }
else if (!strcmp(
indicator,
"callheld")) {
2890 }
else if (!strcmp(
indicator,
"signal")) {
2893 }
else if (!strcmp(
indicator,
"roam")) {
2896 }
else if (!strcmp(
indicator,
"battchg")) {
2948 snprintf(cmd,
sizeof(cmd),
"\r\n+VGS=%d\r\n", gain);
2960 snprintf(cmd,
sizeof(cmd),
"\r\n+VGM=%d\r\n", gain);
3079 uint32_t range = 0x0000ffff;
3080 sdp_list_t *response_list, *search_list, *attrid_list;
3082 sdp_list_t *proto_list;
3083 sdp_record_t *sdprec;
3085 str2ba(addr, &bdaddr);
3087 session = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY);
3089 ast_debug(1,
"sdp_connect() failed on device %s.\n", addr);
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);
3099 if (response_list) {
3100 sdprec = (sdp_record_t *) response_list->data;
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);
3106 sdp_record_free(sdprec);
3107 sdp_list_free(response_list, 0);
3109 ast_debug(1,
"No responses returned for device %s.\n", addr);
3111 ast_debug(1,
"sdp_service_search_attr_req() failed on device %s.\n", addr);
3113 sdp_list_free(search_list, 0);
3114 sdp_list_free(attrid_list, 0);
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";
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;
3135 sdp_record_t *record = sdp_record_alloc();
3137 sdp_uuid128_create(&svc_uuid, &service_uuid_int);
3138 sdp_set_service_id(record, svc_uuid);
3140 sdp_uuid32_create(&svc_class1_uuid, GENERIC_AUDIO_SVCLASS_ID);
3141 sdp_uuid32_create(&svc_class2_uuid, HEADSET_PROFILE_ID);
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);
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 );
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);
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);
3161 access_proto_list = sdp_list_append(0, proto_list);
3162 sdp_set_access_protos(record, access_proto_list);
3164 sdp_set_info_attr(record, service_name, service_prov, service_dsc);
3166 if (!(
session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY)))
3169 if (sdp_record_register(
session, record, 0) < 0) {
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);
3203 ast_debug(1,
"[%s] error parsing BRSF\n", pvt->
id);
3208 ast_debug(1,
"[%s] error handling BRSF\n", pvt->
id);
3214 ast_debug(1,
"[%s] received unexpected AT message 'BRSF' when expecting %s, ignoring\n", pvt->
id,
at_msg2str(
entry->expected));
3216 ast_debug(1,
"[%s] received unexpected AT message 'BRSF'\n", pvt->
id);
3237 switch (
entry->response_to) {
3240 ast_debug(1,
"[%s] error performing CIND test\n", pvt->
id);
3246 ast_debug(1,
"[%s] error getting CIND state\n", pvt->
id);
3251 ast_debug(1,
"[%s] error getting CIND state\n", pvt->
id);
3256 ast_debug(1,
"[%s] received unexpected AT message 'CIND' when expecting %s, ignoring\n", pvt->
id,
at_msg2str(
entry->expected));
3258 ast_debug(1,
"[%s] received unexpected AT message 'CIND'\n", pvt->
id);
3279 switch (
entry->response_to) {
3283 ast_debug(1,
"[%s] BSRF sent successfully\n", pvt->
id);
3289 ast_debug(1,
"[%s] error sending CMER\n", pvt->
id);
3294 ast_debug(1,
"[%s] error sending CIND test\n", pvt->
id);
3300 ast_debug(1,
"[%s] CIND test sent successfully\n", pvt->
id);
3307 ast_debug(1,
"[%s] error requesting CIND state\n", pvt->
id);
3312 ast_debug(1,
"[%s] CIND sent successfully\n", pvt->
id);
3316 ast_verb(3,
"Bluetooth Device %s has a call in progress - delaying connection.\n", pvt->
id);
3324 ast_debug(1,
"[%s] error sending CMER\n", pvt->
id);
3329 ast_debug(1,
"[%s] error enabling calling line notification\n", pvt->
id);
3335 ast_debug(1,
"[%s] CMER sent successfully\n", pvt->
id);
3341 ast_debug(1,
"[%s] error sending CIND test\n", pvt->
id);
3346 ast_debug(1,
"[%s] error enabling calling line notification\n", pvt->
id);
3352 ast_debug(1,
"[%s] calling line indication enabled\n", pvt->
id);
3354 ast_debug(1,
"[%s] error enabling Sony Ericsson call monitoring extensions\n", pvt->
id);
3360 ast_debug(1,
"[%s] Sony Ericsson call monitoring is active on device\n", pvt->
id);
3362 ast_debug(1,
"[%s] error synchronizing gain settings\n", pvt->
id);
3368 ast_verb(3,
"Bluetooth Device %s initialized and ready.\n", pvt->
id);
3372 ast_debug(1,
"[%s] volume level synchronization successful\n", pvt->
id);
3377 ast_debug(1,
"[%s] error setting CMGF\n", pvt->
id);
3383 ast_debug(1,
"[%s] sms text mode enabled\n", pvt->
id);
3386 ast_debug(1,
"[%s] error setting CNMI\n", pvt->
id);
3391 ast_debug(1,
"[%s] sms new message indication enabled\n", pvt->
id);
3397 ast_debug(1,
"[%s] answer sent successfully\n", pvt->
id);
3401 ast_debug(1,
"[%s] dial sent successfully\n", pvt->
id);
3407 ast_debug(1,
"[%s] successful hangup\n", pvt->
id);
3410 ast_debug(1,
"[%s] successfully sent sms message\n", pvt->
id);
3414 ast_debug(1,
"[%s] digit sent successfully\n", pvt->
id);
3417 ast_debug(1,
"[%s] CUSD code sent successfully\n", pvt->
id);
3428 ast_debug(1,
"[%s] received unexpected AT message 'OK'\n", pvt->
id);
3453 switch (
entry->response_to) {
3457 ast_debug(1,
"[%s] error reading BSRF\n", pvt->
id);
3460 ast_debug(1,
"[%s] error during CIND test\n", pvt->
id);
3463 ast_debug(1,
"[%s] error requesting CIND state\n", pvt->
id);
3466 ast_debug(1,
"[%s] error during CMER request\n", pvt->
id);
3469 ast_debug(1,
"[%s] error enabling calling line indication\n", pvt->
id);
3472 ast_debug(1,
"[%s] volume level synchronization failed\n", pvt->
id);
3478 ast_debug(1,
"[%s] error setting CMGF\n", pvt->
id);
3484 ast_debug(1,
"[%s] error setting CMGF\n", pvt->
id);
3489 ast_debug(1,
"[%s] error setting CNMI\n", pvt->
id);
3493 ast_debug(1,
"[%s] Mobile does not support Sony Ericsson extensions\n", pvt->
id);
3498 ast_debug(1,
"[%s] error synchronizing gain settings\n", pvt->
id);
3504 ast_verb(3,
"Bluetooth Device %s initialized and ready.\n", pvt->
id);
3519 ast_debug(1,
"[%s] error sending hangup, disconnecting\n", pvt->
id);
3522 ast_debug(1,
"[%s] error reading sms message\n", pvt->
id);
3526 ast_debug(1,
"[%s] error sending sms message\n", pvt->
id);
3530 ast_debug(1,
"[%s] error sending digit\n", pvt->
id);
3533 ast_verb(0,
"[%s] error sending CUSD command\n", pvt->
id);
3544 ast_debug(1,
"[%s] received unexpected AT message 'ERROR'\n", pvt->
id);
3568 ast_debug(1,
"[%s] line disconnected\n", pvt->
id);
3583 ast_debug(1,
"[%s] remote end answered\n", pvt->
id);
3589 ast_verb(3,
"[%s] user answered bluetooth device from handset, disconnecting\n", pvt->
id);
3617 ast_debug(1,
"[%s] incoming call, waiting for caller id\n", pvt->
id);
3626 ast_verb(3,
"[%s] user dialed from handset, disconnecting\n", pvt->
id);
3696 ast_debug(1,
"[%s] got ring while waiting for caller id\n", pvt->
id);
3714 ast_debug(1,
"[%s] incoming sms message\n", pvt->
id);
3718 ast_debug(1,
"[%s] error sending CMGR to retrieve SMS message\n", pvt->
id);
3725 ast_debug(1,
"[%s] error parsing incoming sms message alert, disconnecting\n", pvt->
id);
3747 ast_debug(1,
"[%s] error parsing sms message, disconnecting\n", pvt->
id);
3751 ast_debug(1,
"[%s] successfully read sms message\n", pvt->
id);
3756 ast_debug(1,
"[%s] error creating sms message channel, disconnecting\n", pvt->
id);
3769 ast_debug(1,
"[%s] got unexpected +CMGR message, ignoring\n", pvt->
id);
3786 ast_debug(1,
"[%s] error, got sms prompt with no pending sms messages\n", pvt->
id);
3791 ast_debug(1,
"[%s] error, got sms prompt but no pending sms messages\n", pvt->
id);
3798 ast_debug(1,
"[%s] error sending sms message\n", pvt->
id);
3822 ast_verb(0,
"[%s] CUSD response: %s\n", pvt->
id, cusd);
3850 ast_verb(1,
"[%s] mobile reports NO DIALTONE\n", pvt->
id);
3865 ast_verb(1,
"[%s] mobile reports NO CARRIER\n", pvt->
id);
3902 ast_debug(1,
"[%s] timeout waiting for rfcomm data, disconnecting\n", pvt->
id);
3906 switch (
entry->response_to) {
3911 ast_debug(1,
"[%s] timeout during CIND test, try setting 'blackberry=yes'\n", hfp->
owner->
id);
3915 ast_debug(1,
"[%s] timeout after sending CMER, try setting 'blackberry=no'\n", hfp->
owner->
id);
4061 ast_debug(1,
"[%s] ignoring unknown message: %s\n", pvt->
id,
buf);
4064 ast_debug(1,
"[%s] error parsing message\n", pvt->
id);
4077 ast_verb(3,
"Error initializing Bluetooth device %s.\n", pvt->
id);
4081 ast_debug(1,
"[%s] device disconnected, hanging up owner\n", pvt->
id);
4098 ast_verb(3,
"Bluetooth Device %s has disconnected.\n", pvt->
id);
4115 ast_debug(1,
"[%s] error sending RING\n", pvt->
id);
4130 ast_verb(3,
"Bluetooth Device %s initialised and ready.\n", pvt->
id);
4156 ast_debug(1,
"[%s] error sending AT message 'OK'\n", pvt->
id);
4185 ast_debug(1,
"[%s] error sending VGS/VGM\n", pvt->
id);
4228 ast_debug(1,
"[%s] error sending AT message 'ERROR'\n", pvt->
id);
4238 ast_debug(1,
"[%s] device disconnected, hanging up owner\n", pvt->
id);
4257 ast_verb(3,
"Bluetooth Device %s has disconnected\n", pvt->
id);
4303 ast_verb(3,
"Bluetooth Device %s has connected, initializing...\n", pvt->
id);
4371 struct hci_dev_req
dr;
4384 if (!(adapter =
ast_calloc(1,
sizeof(*adapter)))) {
4396 ast_log(
LOG_ERROR,
"Skipping adapter %s. Unable to communicate with adapter.\n", adapter->
id);
4397 goto e_free_adapter;
4401 hci_read_voice_setting(adapter->
hci_socket, &vs, 1000);
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;
4409 if (!strcasecmp(v->
name,
"forcemaster")) {
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);
4418 }
else if (!strcasecmp(v->
name,
"alignmentdetection")) {
4425 ast_log(
LOG_ERROR,
"Unable to create I/O context for audio connection listener\n");
4426 goto e_hci_close_dev;
4430 ast_log(
LOG_ERROR,
"Unable to create I/O context for audio connections\n");
4431 goto e_destroy_accept_io;
4436 ast_log(
LOG_ERROR,
"Skipping adapter %s. Error binding audio connection listener socket.\n", adapter->
id);
4442 ast_log(
LOG_ERROR,
"Skipping adapter %s. Error adding listener socket to I/O context.\n", adapter->
id);
4448 ast_log(
LOG_ERROR,
"Skipping adapter %s. Error creating audio connection listener thread.\n", adapter->
id);
4487 const char *
address, *adapter_str, *port;
4488 ast_debug(1,
"Reading configuration for device %s.\n", cat);
4499 if (!strcmp(adapter->
id, adapter_str))
4504 ast_log(
LOG_ERROR,
"Skipping device %s. Unknown adapter '%s' specified.\n", cat, adapter_str);
4511 ast_log(
LOG_ERROR,
"Skipping device %s. Missing required port or address setting.\n", cat);
4543 ast_log(
LOG_ERROR,
"Skipping device %s. Error setting up frame bt_out_smoother.\n", cat);
4549 ast_log(
LOG_ERROR,
"Skipping device %s. Error setting up frame bt_in_smoother.\n", cat);
4550 goto e_free_bt_out_smoother;
4555 ast_log(
LOG_ERROR,
"Skipping device %s. Error setting up dsp for dtmf detection.\n", cat);
4556 goto e_free_bt_in_smoother;
4561 ast_log(
LOG_ERROR,
"Unable to create scheduler context for headset device\n");
4569 if (!strcasecmp(v->
name,
"type")) {
4570 if (!strcasecmp(v->
value,
"headset"))
4574 }
else if (!strcasecmp(v->
name,
"context")) {
4576 }
else if (!strcasecmp(v->
name,
"group")) {
4579 }
else if (!strcasecmp(v->
name,
"sms")) {
4581 }
else if (!strcasecmp(v->
name,
"nocallsetup")) {
4585 ast_debug(1,
"Setting nocallsetup mode for device %s.\n", pvt->
id);
4586 }
else if (!strcasecmp(v->
name,
"blackberry")) {
4616e_free_bt_in_smoother:
4618e_free_bt_out_smoother:
4642 if (!strcasecmp(v->
name,
"interval")) {
4644 ast_log(
LOG_NOTICE,
"error parsing 'interval' in general section, using default value\n");
4651 if (!strcasecmp(cat,
"adapter")) {
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"
4669 if (strcasecmp(cat,
"general") && strcasecmp(cat,
"adapter")) {
4791 s = hci_open_dev(
dev_id);
4792 if (
dev_id < 0 || s < 0) {
static const struct adsi_event events[]
General Definitions for Asterisk top level program Included by asterisk.h to handle platform-specific...
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int ast_isphonenumber(const char *n)
Check if a string consists only of digits and + #.
Internal Asterisk hangup causes.
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
#define AST_CAUSE_FACILITY_NOT_IMPLEMENTED
#define AST_CAUSE_USER_BUSY
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...
static int mbl_hangup(struct ast_channel *ast)
static char * mblsendsms_desc
static struct adapter_pvt * mbl_load_adapter(struct ast_config *cfg, const char *cat)
Load an adapter from the configuration file.
static int handle_response_brsf(struct mbl_pvt *pvt, char *buf)
Handle the BRSF response.
static int hsp_send_ring(int rsock)
Send a RING unsolicited AT response.
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.
static void * do_monitor_headset(void *data)
static int discovery_interval
static int hfp_send_brsf(struct hfp_pvt *hfp, struct hfp_hf *brsf)
Send a BRSF request.
static const char * at_msg2str(at_message_t msg)
Get the string representation of the given AT message.
static int handle_response_cmti(struct mbl_pvt *pvt, char *buf)
Handle AT+CMTI messages.
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...
static void * do_monitor_phone(void *data)
static void msg_queue_free_and_pop(struct mbl_pvt *pvt)
Remove an item from the front of the queue, and free it.
static int mbl_call(struct ast_channel *ast, const char *dest, int timeout)
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.
static int handle_response_clip(struct mbl_pvt *pvt, char *buf)
Handle AT+CLIP messages.
static int hfp_parse_cmgr(struct hfp_pvt *hfp, char *buf, char **from_number, char **text)
Parse a CMGR message.
static int sco_bind(struct adapter_pvt *adapter)
Bind an SCO listener socket for the given adapter.
static int hsp_send_error(int rsock)
Send an ERROR AT response.
static void * do_sco_listen(void *data)
Service new and existing SCO connections. This thread accepts new sco connections and handles audio d...
static ssize_t rfcomm_read(int rsock, char *buf, size_t count)
Read one Hayes AT message from an rfcomm socket.
static int handle_response_ciev(struct mbl_pvt *pvt, char *buf)
Handle AT+CIEV messages.
static char * handle_cli_mobile_cusd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define DEVICE_FRAME_FORMAT
static int hfp_send_cind(struct hfp_pvt *hfp)
Send the CIND read command.
static struct hfp_ag * hfp_int2brsf(int brsf, struct hfp_ag *ag)
Convert a BRSF int to an hfp_ag struct.
static int rfcomm_read_cmgr(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of a +CMGR message.
static int handle_response_cind(struct mbl_pvt *pvt, char *buf)
Handle the CIND response.
static int hfp_send_sms_text(struct hfp_pvt *hfp, const char *message)
Send the text of an SMS message.
#define HFP_CIND_CALL_ACTIVE
static int hfp_parse_cmti(struct hfp_pvt *hfp, char *buf)
Parse a CMTI notification.
static char * app_mblsendsms
static int hfp_parse_cind_indicator(struct hfp_pvt *hfp, int group, char *indicator)
Parse and store the given indicator.
static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf)
Handle AT+CMGR messages.
static void msg_queue_flush(struct mbl_pvt *pvt)
Remove all items from the queue and free them.
#define rfcomm_read_debug(c)
static int hfp_send_cnmi(struct hfp_pvt *hfp)
Setup SMS new message indication.
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.
static int hfp_send_atd(struct hfp_pvt *hfp, const char *number)
Send ATD.
#define HFP_CIND_CALLSETUP
static int handle_response_ring(struct mbl_pvt *pvt, char *buf)
Handle RING messages.
static int mbl_status_exec(struct ast_channel *ast, const char *data)
static int hfp_send_cmgf(struct hfp_pvt *hfp, int mode)
Set the SMS mode.
static int mbl_write(struct ast_channel *ast, struct ast_frame *frame)
#define DEVICE_FRAME_SIZE
static void * do_discovery(void *data)
#define CHANNEL_FRAME_SIZE
static int at_match_prefix(char *buf, char *prefix)
Match the given buffer with the given prefix.
static int sdp_search(char *addr, int profile)
static sdp_session_t * sdp_session
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.
static char * handle_cli_mobile_rfcomm(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define HFP_CIND_CALL_NONE
static char * mblstatus_desc
static int mbl_load_config(void)
static int hfp_send_dtmf(struct hfp_pvt *hfp, char digit)
Send a DTMF command.
static struct mbl_pvt * mbl_load_device(struct ast_config *cfg, const char *cat)
Load a device from the configuration file.
static int rfcomm_wait(int rsock, int *ms)
Wait for activity on an rfcomm socket.
#define HFP_CIND_SERVICE_AVAILABLE
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.
static int rfcomm_read_result(int rsock, char **buf, size_t count, size_t *in_count)
Read and AT result code.
static struct hfp_hf hfp_our_brsf
static int handle_response_busy(struct mbl_pvt *pvt)
Handle BUSY messages.
static void set_unloading(void)
Set the unloading flag.
static int hfp_send_vgs(struct hfp_pvt *hfp, int value)
Send the current speaker gain level.
static int mbl_queue_hangup(struct mbl_pvt *pvt)
static int mbl_sendsms_exec(struct ast_channel *ast, const char *data)
static int check_unloading(void)
Check if the module is unloading.
static int hsp_send_vgm(int rsock, int gain)
Send a microphone gain unsolicited AT response.
static struct ast_cli_entry mbl_cli[]
static char * app_mblstatus
static int handle_response_ok(struct mbl_pvt *pvt, char *buf)
Handle OK AT messages.
static int headset_send_ring(const void *data)
static int hsp_send_ok(int rsock)
Send an OK AT response.
static int rfcomm_read_command(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of an AT command.
static struct ast_channel * mbl_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value)
Parse a CIEV event.
static int mbl_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
static int hfp_send_ata(struct hfp_pvt *hfp)
Send ATA.
static int mbl_has_service(struct mbl_pvt *pvt)
Check if a mobile device has service.
static char * mblstatus_synopsis
static int rfcomm_write_full(int rsock, char *buf, size_t count)
Write to an rfcomm socket.
#define HFP_CIND_CALLSETUP_INCOMING
static char * handle_cli_mobile_search(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int hfp_parse_cind_test(struct hfp_pvt *hfp, char *buf)
Parse the result of the AT+CIND=? command.
static int hfp_send_cmgs(struct hfp_pvt *hfp, const char *number)
Start sending an SMS message.
static int handle_response_cusd(struct mbl_pvt *pvt, char *buf)
Handle CUSD messages.
static int handle_response_error(struct mbl_pvt *pvt, char *buf)
Handle ERROR AT messages.
static int unloading_flag
static int mbl_devicestate(const char *data)
static int rfcomm_read_until_crlf(int rsock, char **buf, size_t count, size_t *in_count)
Read until.
static char * hfp_parse_cusd(struct hfp_pvt *hfp, char *buf)
Parse a CUSD answer.
#define HFP_CIND_CALLSETUP_OUTGOING
static struct msg_queue_entry * msg_queue_head(struct mbl_pvt *pvt)
Get the head of a queue.
#define HFP_CIND_CALLHELD
static int handle_sms_prompt(struct mbl_pvt *pvt, char *buf)
Send an SMS message from the queue.
static int load_module(void)
static int mbl_answer(struct ast_channel *ast)
static int hfp_send_ecam(struct hfp_pvt *hfp)
Enable Sony Ericsson extensions / indications.
static int hfp_send_chup(struct hfp_pvt *hfp)
Send AT+CHUP.
static int hfp_send_cind_test(struct hfp_pvt *hfp)
Send the CIND test command.
static struct ast_channel * mbl_new(int state, struct mbl_pvt *pvt, struct cidinfo *cidinfo, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
static int hfp_parse_ecav(struct hfp_pvt *hfp, char *buf)
Parse a ECAV event.
static int hfp_send_cusd(struct hfp_pvt *hfp, const char *code)
Send CUSD.
static int mbl_queue_control(struct mbl_pvt *pvt, enum ast_control_frame_type control)
static at_message_t at_read_full(int rsock, char *buf, size_t count)
Read an AT message and classify it.
static int sco_connect(bdaddr_t src, bdaddr_t dst)
static int mbl_ast_hangup(struct mbl_pvt *pvt)
static int unload_module(void)
static pthread_t discovery_thread
static char * handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int hfp_send_clip(struct hfp_pvt *hfp, int status)
Enable or disable calling line identification.
static int hfp_parse_cind(struct hfp_pvt *hfp, char *buf)
Read the result of the AT+CIND? command.
static struct ast_frame * mbl_read(struct ast_channel *ast)
static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int hfp_brsf2int(struct hfp_hf *hf)
Convert a hfp_hf struct to a BRSF int.
static int hsp_send_vgs(int rsock, int gain)
Send a speaker gain unsolicited AT response.
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.
static sdp_session_t * sdp_register(void)
static int rfcomm_write(int rsock, char *buf)
Write to an rfcomm socket.
#define HFP_CIND_CALLSETUP_NONE
static int hfp_parse_brsf(struct hfp_pvt *hfp, const char *buf)
Parse BRSF data.
static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen)
static struct ast_channel_tech mbl_tech
#define HFP_CIND_CALLSETUP_ALERTING
static struct msg_queue_entry * msg_queue_pop(struct mbl_pvt *pvt)
Remove an item from the front of the queue.
static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel)
static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf)
Parse a CLIP event.
static int rfcomm_read_until_ok(int rsock, char **buf, size_t count, size_t *in_count)
Read until a.
static char * mblsendsms_synopsis
static int start_monitor(struct mbl_pvt *pvt)
static int sco_write(int s, char *buf, int len)
static ast_mutex_t unload_mutex
static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf)
Handle NO CARRIER messages.
static int hfp_send_cmer(struct hfp_pvt *hfp, int status)
Enable or disable indicator events reporting.
static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf)
Handle NO DIALTONE messages.
static int hfp_send_cmgr(struct hfp_pvt *hfp, int index)
Read an SMS message.
General Asterisk PBX channel definitions.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_rings_set(struct ast_channel *chan, int value)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
Waits for input on an fd.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
#define ast_channel_trylock(chan)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
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 ...
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
ast_channel_state
ast_channel states
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Convenient Signal Processing routines.
void ast_dsp_free(struct ast_dsp *dsp)
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
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,...
#define DSP_FEATURE_DIGIT_DETECT
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
#define DSP_DIGITMODE_DTMF
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
#define DSP_DIGITMODE_RELAXDTMF
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char prefix[MAX_PREFIX]
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
ast_control_frame_type
Internal control frame subtype field values.
struct ast_frame ast_null_frame
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
I/O Management (derived from Cheops-NG)
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...
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
void io_context_destroy(struct io_context *ioc)
Destroys a context.
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
A set of macros to manage forward-linked lists.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
#define AST_RWLIST_REMOVE_HEAD
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_HEAD
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Asterisk locking-related definitions:
#define AST_PTHREADT_NULL
#define ast_mutex_init(pmutex)
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
#define DEADLOCK_AVOIDANCE(lock)
#define ast_mutex_unlock(a)
#define ast_mutex_trylock(a)
#define ast_mutex_lock(a)
#define AST_MUTEX_DEFINE_STATIC(mutex)
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
#define EVENT_FLAG_SYSTEM
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
#define ast_register_application(app, execute, synopsis, description)
Register an application.
@ AST_MODPRI_CHANNEL_DRIVER
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Options provided by main asterisk program.
Core PBX routines and definitions.
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.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
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.
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
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.
Asterisk internal frame definitions.
void ast_smoother_free(struct ast_smoother *s)
struct ast_frame * ast_smoother_read(struct ast_smoother *s)
#define ast_smoother_feed(s, f)
struct ast_smoother * ast_smoother_new(int bytes)
void ast_smoother_reset(struct ast_smoother *s, int bytes)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_alloca(init_len)
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
pthread_t sco_listener_thread
struct io_context * accept_io
struct adapter_pvt::@0 entry
unsigned int alignment_detection
Structure to pass both assignedid values to channel drivers.
Structure to describe a channel "technology", ie a channel driver See for examples:
struct ast_format_cap * capabilities
Main Channel structure associated with a channel.
descriptor for a cli entry.
Structure used to handle boolean flags.
struct ast_format * format
Data structure associated with a single frame of data.
union ast_frame::@228 data
struct ast_frame_subclass subclass
enum ast_frame_type frametype
Structure for mutex and tracking information.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
This struct holds HFP features the AG supports.
This struct holds mappings for indications.
This struct holds HFP features that we support.
This struct holds state information about the current hfp connection.
Global IO variables are now in a struct in order to be made threadsafe.
unsigned int do_alignment_detection
unsigned int outgoing_sms
struct ast_sched_context * sched
short alignment_samples[4]
char io_buf[CHANNEL_FRAME_SIZE+AST_FRIENDLY_OFFSET]
struct mbl_pvt::msg_queue msg_queue
struct ast_smoother * bt_in_smoother
struct ast_smoother * bt_out_smoother
struct ast_channel * owner
struct adapter_pvt * adapter
unsigned int incoming_sms
unsigned int no_callsetup
char context[AST_MAX_CONTEXT]
unsigned int needcallerid
unsigned int alignment_detection_triggered
struct msg_queue_entry::@2 entry
#define ast_pthread_create_background(a, b, c, d)
long int ast_random(void)