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 320 133 char rfcomm_buf[256];
145 short alignment_samples[4];
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";
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 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);
393 static int hfp_send_vgm(
struct hfp_pvt *hfp,
int value);
404 static int hfp_send_cusd(
struct hfp_pvt *hfp,
const char *code);
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);
522 snprintf(group,
sizeof(group),
"%d", pvt->
group);
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]");
594 phport =
sdp_search(addr, HANDSFREE_AGW_PROFILE_ID);
596 hsport =
sdp_search(addr, HEADSET_PROFILE_ID);
599 ast_cli(a->
fd,
FORMAT2, addr, name, (phport > 0 || hsport > 0) ?
"Yes" :
"No",
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]))
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]))
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))
756 snprintf(status,
sizeof(status),
"%d", stat);
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);
866 cidinfo ? cidinfo->
cnam : NULL,
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);
1098 ast_debug(1,
"[%s] error sending digit %c\n", pvt->
id, digit);
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) 1491 static 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");
1883 r = write(s, buf, len);
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;
2005 return !strncmp(buf, prefix, strlen(prefix));
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";
2170 if (!sscanf(buf,
"*ECAV: %2d,%2d,%2d", &ccid, &ccstatus, &calltype)) {
2201 if (!sscanf(buf,
"+CIEV: %d,%d", &i, value)) {
2207 ast_debug(2,
"[%s] CIEV event index too high (%s)\n", hfp->
owner->
id, buf);
2224 static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp,
char *
buf)
2236 ast_debug(3,
"[%s] hfp_parse_clip is processing \"%s\"\n", hfp->owner->id,
buf);
2238 for (i = 1; i <
ARRAY_LEN(tokens); i++) {
2242 ast_debug(3,
"[%s] hfp_parse_clip found tokens: 0=%s, 1=%s, 2=%s, 3=%s, 4=%s, 5=%s\n",
2243 hfp->owner->id, &
buf[tokens[0]], &
buf[tokens[1]], &
buf[tokens[2]],
2244 &
buf[tokens[3]], &
buf[tokens[4]], &
buf[tokens[5]]);
2249 ast_debug(1,
"[%s] hfp_parse_clip invalid cidinfo.cnum data \"%s\" - deleting\n",
2250 hfp->owner->id, cidinfo.
cnum);
2258 cidinfo.
cnam = &
buf[tokens[5]];
2259 if (
buf[tokens[5]] ==
'\0' &&
buf[tokens[4]] ==
'\0') {
2262 while (
buf[i] ==
' ') {
2265 if (
buf[i] ==
'"') {
2273 for (cnamtmp = cidinfo.
cnam; *cnamtmp !=
'\0'; cnamtmp++) {
2274 if (!strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-,abcdefghijklmnopqrstuvwxyz_", *cnamtmp)) {
2280 ast_debug(2,
"[%s] hfp_parse_clip replaced %d invalid byte(s) in cnam data\n",
2281 hfp->owner->id, invalid);
2283 ast_debug(2,
"[%s] hfp_parse_clip returns cnum=%s and cnam=%s\n",
2284 hfp->owner->id, cidinfo.
cnum, cidinfo.
cnam);
2302 for (index = start;
string[index] != 0; index++) {
2303 if ((
string[index] == delim) && !quoting ) {
2305 string[index] =
'\0';
2308 }
else if (
string[index] ==
'"' && !quoting) {
2311 }
else if (
string[index] ==
'"' ) {
2333 if (!sscanf(buf,
"+CMTI: %*[^,],%d", &index)) {
2363 for (i = 0; i < s && state != 6; i++) {
2366 if (buf[i] ==
',') {
2371 if (buf[i] ==
'"') {
2377 *from_number = &buf[i];
2382 if (buf[i] ==
'"') {
2388 if (buf[i] ==
'\n') {
2418 int i, message_start, message_end;
2430 for (i = 0; i < s; i++) {
2431 if (buf[i] ==
'"') {
2432 message_start = i + 1;
2437 if (message_start == 0 || message_start >= s) {
2442 for (i = s; i > 0; i--) {
2443 if (buf[i] ==
'"') {
2449 if (message_end == 0) {
2453 if (message_start >= message_end) {
2457 cusd = &buf[message_start];
2458 buf[message_end] =
'\0';
2517 snprintf(cmd,
sizeof(cmd),
"AT+BRSF=%d\r",
hfp_brsf2int(brsf));
2547 snprintf(cmd,
sizeof(cmd),
"AT+CMER=3,0,0,%d\r", status ? 1 : 0);
2559 snprintf(cmd,
sizeof(cmd),
"AT+VGS=%d\r", value);
2569 static int hfp_send_vgm(
struct hfp_pvt *hfp,
int value)
2572 snprintf(cmd,
sizeof(cmd),
"AT+VGM=%d\r", value);
2586 snprintf(cmd,
sizeof(cmd),
"AT+CLIP=%d\r", status ? 1 : 0);
2613 snprintf(cmd,
sizeof(cmd),
"AT+VTS=%c\r", digit);
2628 snprintf(cmd,
sizeof(cmd),
"AT+CMGF=%d\r", mode);
2649 snprintf(cmd,
sizeof(cmd),
"AT+CMGR=%d\r", index);
2661 snprintf(cmd,
sizeof(cmd),
"AT+CMGS=\"%s\"\r", number);
2673 snprintf(cmd,
sizeof(cmd),
"%.160s\x1a", message);
2694 snprintf(cmd,
sizeof(cmd),
"ATD%s;\r", number);
2715 snprintf(cmd,
sizeof(cmd),
"AT+CUSD=1,\"%s\",15\r", code);
2728 if (!sscanf(buf,
"+BRSF:%d", &brsf))
2748 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));
2752 if (!sscanf(indicator,
"%d", &value)) {
2753 ast_debug(1,
"error parsing CIND state '%s' for group %d\n", indicator, group);
2781 for (i = 0; i < s; i++) {
2784 if (buf[i] ==
' ') {
2790 indicator = &buf[i];
2794 if (buf[i] ==
',') {
2832 for (i = 0; i < s; i++) {
2835 if (buf[i] ==
'(') {
2841 if (buf[i] ==
'"') {
2846 indicator = &buf[i];
2850 if (buf[i] ==
'"') {
2856 if (buf[i] ==
'(') {
2864 if (buf[i] ==
')') {
2871 if (!strcmp(indicator,
"service")) {
2874 }
else if (!strcmp(indicator,
"call")) {
2877 }
else if (!strcmp(indicator,
"callsetup")) {
2881 }
else if (!strcmp(indicator,
"call_setup")) {
2885 }
else if (!strcmp(indicator,
"callheld")) {
2888 }
else if (!strcmp(indicator,
"signal")) {
2891 }
else if (!strcmp(indicator,
"roam")) {
2894 }
else if (!strcmp(indicator,
"battchg")) {
2899 ast_debug(2,
"ignoring unknown CIND indicator '%s'\n", indicator);
2902 ast_debug(1,
"can't store indicator %d (%s), we only support up to %d indicators", group, indicator, (
int)
sizeof(hfp->
cind_index));
2946 snprintf(cmd,
sizeof(cmd),
"\r\n+VGS=%d\r\n", gain);
2958 snprintf(cmd,
sizeof(cmd),
"\r\n+VGM=%d\r\n", gain);
3077 uint32_t range = 0x0000ffff;
3078 sdp_list_t *response_list, *search_list, *attrid_list;
3080 sdp_list_t *proto_list;
3081 sdp_record_t *sdprec;
3083 str2ba(addr, &bdaddr);
3085 session = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY);
3087 ast_debug(1,
"sdp_connect() failed on device %s.\n", addr);
3091 sdp_uuid32_create(&svc_uuid, profile);
3092 search_list = sdp_list_append(0, &svc_uuid);
3093 attrid_list = sdp_list_append(0, &range);
3094 response_list = 0x00;
3095 status = sdp_service_search_attr_req(session, search_list, SDP_ATTR_REQ_RANGE, attrid_list, &response_list);
3097 if (response_list) {
3098 sdprec = (sdp_record_t *) response_list->data;
3100 if (sdp_get_access_protos(sdprec, &proto_list) == 0) {
3101 port = sdp_get_proto_port(proto_list, RFCOMM_UUID);
3102 sdp_list_free(proto_list, 0);
3104 sdp_record_free(sdprec);
3105 sdp_list_free(response_list, 0);
3107 ast_debug(1,
"No responses returned for device %s.\n", addr);
3109 ast_debug(1,
"sdp_service_search_attr_req() failed on device %s.\n", addr);
3111 sdp_list_free(search_list, 0);
3112 sdp_list_free(attrid_list, 0);
3121 uint32_t service_uuid_int[] = {0, 0, 0, GENERIC_AUDIO_SVCLASS_ID};
3122 uint8_t rfcomm_channel = 1;
3123 const char *service_name =
"Asterisk PABX";
3124 const char *service_dsc =
"Asterisk PABX";
3125 const char *service_prov =
"Asterisk";
3127 uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_uuid, svc_class1_uuid, svc_class2_uuid;
3128 sdp_list_t *l2cap_list = 0, *rfcomm_list = 0, *root_list = 0, *proto_list = 0, *access_proto_list = 0, *svc_uuid_list = 0;
3133 sdp_record_t *record = sdp_record_alloc();
3135 sdp_uuid128_create(&svc_uuid, &service_uuid_int);
3136 sdp_set_service_id(record, svc_uuid);
3138 sdp_uuid32_create(&svc_class1_uuid, GENERIC_AUDIO_SVCLASS_ID);
3139 sdp_uuid32_create(&svc_class2_uuid, HEADSET_PROFILE_ID);
3141 svc_uuid_list = sdp_list_append(0, &svc_class1_uuid);
3142 svc_uuid_list = sdp_list_append(svc_uuid_list, &svc_class2_uuid);
3143 sdp_set_service_classes(record, svc_uuid_list);
3145 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
3146 root_list = sdp_list_append(0, &root_uuid);
3147 sdp_set_browse_groups( record, root_list );
3149 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
3150 l2cap_list = sdp_list_append(0, &l2cap_uuid);
3151 proto_list = sdp_list_append(0, l2cap_list);
3153 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
3154 channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
3155 rfcomm_list = sdp_list_append(0, &rfcomm_uuid);
3156 sdp_list_append(rfcomm_list, channel);
3157 sdp_list_append(proto_list, rfcomm_list);
3159 access_proto_list = sdp_list_append(0, proto_list);
3160 sdp_set_access_protos(record, access_proto_list);
3162 sdp_set_info_attr(record, service_name, service_prov, service_dsc);
3164 if (!(session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY)))
3167 if (sdp_record_register(session, record, 0) < 0) {
3173 sdp_data_free(channel);
3174 sdp_list_free(rfcomm_list, 0);
3175 sdp_list_free(root_list, 0);
3176 sdp_list_free(access_proto_list, 0);
3177 sdp_list_free(svc_uuid_list, 0);
3201 ast_debug(1,
"[%s] error parsing BRSF\n", pvt->
id);
3206 ast_debug(1,
"[%s] error handling BRSF\n", pvt->
id);
3214 ast_debug(1,
"[%s] received unexpected AT message 'BRSF'\n", pvt->
id);
3238 ast_debug(1,
"[%s] error performing CIND test\n", pvt->
id);
3244 ast_debug(1,
"[%s] error getting CIND state\n", pvt->
id);
3249 ast_debug(1,
"[%s] error getting CIND state\n", pvt->
id);
3256 ast_debug(1,
"[%s] received unexpected AT message 'CIND'\n", pvt->
id);
3281 ast_debug(1,
"[%s] BSRF sent successfully\n", pvt->
id);
3287 ast_debug(1,
"[%s] error sending CMER\n", pvt->
id);
3292 ast_debug(1,
"[%s] error sending CIND test\n", pvt->
id);
3298 ast_debug(1,
"[%s] CIND test sent successfully\n", pvt->
id);
3305 ast_debug(1,
"[%s] error requesting CIND state\n", pvt->
id);
3310 ast_debug(1,
"[%s] CIND sent successfully\n", pvt->
id);
3314 ast_verb(3,
"Bluetooth Device %s has a call in progress - delaying connection.\n", pvt->
id);
3322 ast_debug(1,
"[%s] error sending CMER\n", pvt->
id);
3327 ast_debug(1,
"[%s] error enabling calling line notification\n", pvt->
id);
3333 ast_debug(1,
"[%s] CMER sent successfully\n", pvt->
id);
3339 ast_debug(1,
"[%s] error sending CIND test\n", pvt->
id);
3344 ast_debug(1,
"[%s] error enabling calling line notification\n", pvt->
id);
3350 ast_debug(1,
"[%s] caling line indication enabled\n", pvt->
id);
3352 ast_debug(1,
"[%s] error enabling Sony Ericsson call monitoring extensions\n", pvt->
id);
3358 ast_debug(1,
"[%s] Sony Ericsson call monitoring is active on device\n", pvt->
id);
3360 ast_debug(1,
"[%s] error synchronizing gain settings\n", pvt->
id);
3366 ast_verb(3,
"Bluetooth Device %s initialized and ready.\n", pvt->
id);
3370 ast_debug(1,
"[%s] volume level synchronization successful\n", pvt->
id);
3375 ast_debug(1,
"[%s] error setting CMGF\n", pvt->
id);
3381 ast_debug(1,
"[%s] sms text mode enabled\n", pvt->
id);
3384 ast_debug(1,
"[%s] error setting CNMI\n", pvt->
id);
3389 ast_debug(1,
"[%s] sms new message indication enabled\n", pvt->
id);
3395 ast_debug(1,
"[%s] answer sent successfully\n", pvt->
id);
3399 ast_debug(1,
"[%s] dial sent successfully\n", pvt->
id);
3405 ast_debug(1,
"[%s] successful hangup\n", pvt->
id);
3408 ast_debug(1,
"[%s] successfully sent sms message\n", pvt->
id);
3412 ast_debug(1,
"[%s] digit sent successfully\n", pvt->
id);
3415 ast_debug(1,
"[%s] CUSD code sent successfully\n", pvt->
id);
3426 ast_debug(1,
"[%s] received unexpected AT message 'OK'\n", pvt->
id);
3455 ast_debug(1,
"[%s] error reading BSRF\n", pvt->
id);
3458 ast_debug(1,
"[%s] error during CIND test\n", pvt->
id);
3461 ast_debug(1,
"[%s] error requesting CIND state\n", pvt->
id);
3464 ast_debug(1,
"[%s] error during CMER request\n", pvt->
id);
3467 ast_debug(1,
"[%s] error enabling calling line indication\n", pvt->
id);
3470 ast_debug(1,
"[%s] volume level synchronization failed\n", pvt->
id);
3476 ast_debug(1,
"[%s] error setting CMGF\n", pvt->
id);
3482 ast_debug(1,
"[%s] error setting CMGF\n", pvt->
id);
3487 ast_debug(1,
"[%s] error setting CNMI\n", pvt->
id);
3491 ast_debug(1,
"[%s] Mobile does not support Sony Ericsson extensions\n", pvt->
id);
3496 ast_debug(1,
"[%s] error synchronizing gain settings\n", pvt->
id);
3502 ast_verb(3,
"Bluetooth Device %s initialized and ready.\n", pvt->
id);
3517 ast_debug(1,
"[%s] error sending hangup, disconnecting\n", pvt->
id);
3520 ast_debug(1,
"[%s] error reading sms message\n", pvt->
id);
3524 ast_debug(1,
"[%s] error sending sms message\n", pvt->
id);
3528 ast_debug(1,
"[%s] error sending digit\n", pvt->
id);
3531 ast_verb(0,
"[%s] error sending CUSD command\n", pvt->
id);
3542 ast_debug(1,
"[%s] received unexpected AT message 'ERROR'\n", pvt->
id);
3566 ast_debug(1,
"[%s] line disconnected\n", pvt->
id);
3581 ast_debug(1,
"[%s] remote end answered\n", pvt->
id);
3587 ast_verb(3,
"[%s] user answered bluetooth device from handset, disconnecting\n", pvt->
id);
3615 ast_debug(1,
"[%s] incoming call, waiting for caller id\n", pvt->
id);
3624 ast_verb(3,
"[%s] user dialed from handset, disconnecting\n", pvt->
id);
3638 ast_debug(1,
"[%s] error parsing CIND: %s\n", pvt->
id, buf);
3694 ast_debug(1,
"[%s] got ring while waiting for caller id\n", pvt->
id);
3712 ast_debug(1,
"[%s] incoming sms message\n", pvt->
id);
3716 ast_debug(1,
"[%s] error sending CMGR to retrieve SMS message\n", pvt->
id);
3723 ast_debug(1,
"[%s] error parsing incoming sms message alert, disconnecting\n", pvt->
id);
3745 ast_debug(1,
"[%s] error parsing sms message, disconnecting\n", pvt->
id);
3749 ast_debug(1,
"[%s] successfully read sms message\n", pvt->
id);
3754 ast_debug(1,
"[%s] error creating sms message channel, disconnecting\n", pvt->
id);
3767 ast_debug(1,
"[%s] got unexpected +CMGR message, ignoring\n", pvt->
id);
3784 ast_debug(1,
"[%s] error, got sms prompt with no pending sms messages\n", pvt->
id);
3789 ast_debug(1,
"[%s] error, got sms prompt but no pending sms messages\n", pvt->
id);
3796 ast_debug(1,
"[%s] error sending sms message\n", pvt->
id);
3816 ast_verb(0,
"[%s] error parsing CUSD: %s\n", pvt->
id, buf);
3820 ast_verb(0,
"[%s] CUSD response: %s\n", pvt->
id, cusd);
3848 ast_verb(1,
"[%s] mobile reports NO DIALTONE\n", pvt->
id);
3863 ast_verb(1,
"[%s] mobile reports NO CARRIER\n", pvt->
id);
3873 struct hfp_pvt *hfp = pvt->
hfp;
3900 ast_debug(1,
"[%s] timeout waiting for rfcomm data, disconnecting\n", pvt->
id);
3909 ast_debug(1,
"[%s] timeout during CIND test, try setting 'blackberry=yes'\n", hfp->
owner->
id);
3913 ast_debug(1,
"[%s] timeout after sending CMER, try setting 'blackberry=no'\n", hfp->
owner->
id);
4059 ast_debug(1,
"[%s] ignoring unknown message: %s\n", pvt->
id, buf);
4062 ast_debug(1,
"[%s] error parsing message\n", pvt->
id);
4075 ast_verb(3,
"Error initializing Bluetooth device %s.\n", pvt->
id);
4079 ast_debug(1,
"[%s] device disconnected, hanging up owner\n", pvt->
id);
4096 ast_verb(3,
"Bluetooth Device %s has disconnected.\n", pvt->
id);
4113 ast_debug(1,
"[%s] error sending RING\n", pvt->
id);
4128 ast_verb(3,
"Bluetooth Device %s initialised and ready.\n", pvt->
id);
4154 ast_debug(1,
"[%s] error sending AT message 'OK'\n", pvt->
id);
4183 ast_debug(1,
"[%s] error sending VGS/VGM\n", pvt->
id);
4226 ast_debug(1,
"[%s] error sending AT message 'ERROR'\n", pvt->
id);
4236 ast_debug(1,
"[%s] device disconnected, hanging up owner\n", pvt->
id);
4255 ast_verb(3,
"Bluetooth Device %s has disconnected\n", pvt->
id);
4291 if (!adapter->
inuse) {
4301 ast_verb(3,
"Bluetooth Device %s has connected, initializing...\n", pvt->
id);
4369 struct hci_dev_req dr;
4380 ast_debug(1,
"Reading configuration for adapter %s %s.\n",
id, address);
4382 if (!(adapter =
ast_calloc(1,
sizeof(*adapter)))) {
4388 str2ba(address, &adapter->
addr);
4391 adapter->
dev_id = hci_devid(address);
4394 ast_log(
LOG_ERROR,
"Skipping adapter %s. Unable to communicate with adapter.\n", adapter->
id);
4395 goto e_free_adapter;
4399 hci_read_voice_setting(adapter->
hci_socket, &vs, 1000);
4402 ast_log(
LOG_ERROR,
"Skipping adapter %s. Voice setting must be 0x0060 - see 'man hciconfig' for details.\n", adapter->
id);
4403 goto e_hci_close_dev;
4407 if (!strcasecmp(v->
name,
"forcemaster")) {
4409 dr.dev_id = adapter->
dev_id;
4410 if (hci_strtolm(
"master", &dr.dev_opt)) {
4411 if (ioctl(adapter->
hci_socket, HCISETLINKMODE, (
unsigned long) &dr) < 0) {
4412 ast_log(
LOG_WARNING,
"Unable to set adapter %s link mode to MASTER. Ignoring 'forcemaster' option.\n", adapter->
id);
4416 }
else if (!strcasecmp(v->
name,
"alignmentdetection")) {
4423 ast_log(
LOG_ERROR,
"Unable to create I/O context for audio connection listener\n");
4424 goto e_hci_close_dev;
4428 ast_log(
LOG_ERROR,
"Unable to create I/O context for audio connections\n");
4429 goto e_destroy_accept_io;
4434 ast_log(
LOG_ERROR,
"Skipping adapter %s. Error binding audio connection listerner socket.\n", adapter->
id);
4440 ast_log(
LOG_ERROR,
"Skipping adapter %s. Error adding listener socket to I/O context.\n", adapter->
id);
4446 ast_log(
LOG_ERROR,
"Skipping adapter %s. Error creating audio connection listerner thread.\n", adapter->
id);
4454 ast_debug(1,
"Loaded adapter %s %s.\n", adapter->
id, address);
4464 e_destroy_accept_io:
4485 const char *
address, *adapter_str, *port;
4486 ast_debug(1,
"Reading configuration for device %s.\n", cat);
4497 if (!strcmp(adapter->
id, adapter_str))
4502 ast_log(
LOG_ERROR,
"Skiping device %s. Unknown adapter '%s' specified.\n", cat, adapter_str);
4509 ast_log(
LOG_ERROR,
"Skipping device %s. Missing required port or address setting.\n", cat);
4530 str2ba(address, &pvt->
addr);
4541 ast_log(
LOG_ERROR,
"Skipping device %s. Error setting up frame bt_out_smoother.\n", cat);
4547 ast_log(
LOG_ERROR,
"Skipping device %s. Error setting up frame bt_in_smoother.\n", cat);
4548 goto e_free_bt_out_smoother;
4553 ast_log(
LOG_ERROR,
"Skipping device %s. Error setting up dsp for dtmf detection.\n", cat);
4554 goto e_free_bt_in_smoother;
4559 ast_log(
LOG_ERROR,
"Unable to create scheduler context for headset device\n");
4567 if (!strcasecmp(v->
name,
"type")) {
4568 if (!strcasecmp(v->
value,
"headset"))
4572 }
else if (!strcasecmp(v->
name,
"context")) {
4574 }
else if (!strcasecmp(v->
name,
"group")) {
4577 }
else if (!strcasecmp(v->
name,
"sms")) {
4579 }
else if (!strcasecmp(v->
name,
"nocallsetup")) {
4583 ast_debug(1,
"Setting nocallsetup mode for device %s.\n", pvt->
id);
4584 }
else if (!strcasecmp(v->
name,
"blackberry")) {
4614 e_free_bt_in_smoother:
4616 e_free_bt_out_smoother:
4640 if (!strcasecmp(v->
name,
"interval")) {
4642 ast_log(
LOG_NOTICE,
"error parsing 'interval' in general section, using default value\n");
4649 if (!strcasecmp(cat,
"adapter")) {
4656 "***********************************************************************\n" 4657 "No adapters could be loaded from the configuration file.\n" 4658 "Please review mobile.conf. See sample for details.\n" 4659 "***********************************************************************\n" 4667 if (strcasecmp(cat,
"general") && strcasecmp(cat,
"adapter")) {
4787 dev_id = hci_get_route(
NULL);
4789 s = hci_open_dev(dev_id);
4790 if (dev_id < 0 || s < 0) {
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
struct ast_variable * next
static int mbl_queue_hangup(struct mbl_pvt *pvt)
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
static int handle_response_busy(struct mbl_pvt *pvt)
Handle BUSY messages.
char context[AST_MAX_CONTEXT]
enum sip_cc_notify_state state
static int handle_response_cind(struct mbl_pvt *pvt, char *buf)
Handle the CIND response.
static int rfcomm_read_until_ok(int rsock, char **buf, size_t count, size_t *in_count)
Read until a.
static int handle_response_ciev(struct mbl_pvt *pvt, char *buf)
Handle AT+CIEV messages.
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...
Main Channel structure associated with a channel.
#define HFP_CIND_CALL_ACTIVE
#define AST_CLI_DEFINE(fn, txt,...)
static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf)
Handle NO CARRIER messages.
static int hfp_send_dtmf(struct hfp_pvt *hfp, char digit)
Send a DTMF command.
static int hfp_send_atd(struct hfp_pvt *hfp, const char *number)
Send ATD.
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
#define CHANNEL_FRAME_SIZE
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.
static int rfcomm_read_result(int rsock, char **buf, size_t count, size_t *in_count)
Read and AT result code.
static int sco_connect(bdaddr_t src, bdaddr_t dst)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
static int mbl_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel)
#define ast_smoother_feed(s, f)
struct ast_smoother * ast_smoother_new(int bytes)
static int rfcomm_wait(int rsock, int *ms)
Wait for activity on an rfcomm socket.
static struct ast_cli_entry mbl_cli[]
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
static int load_module(void)
struct ast_smoother * bt_in_smoother
static char * hfp_parse_cusd(struct hfp_pvt *hfp, char *buf)
Parse a CUSD answer.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
static struct mbl_pvt * mbl_load_device(struct ast_config *cfg, const char *cat)
Load a device from the configuration file.
#define DSP_DIGITMODE_DTMF
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
void ast_dsp_free(struct ast_dsp *dsp)
#define DSP_FEATURE_DIGIT_DETECT
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static struct hfp_hf hfp_our_brsf
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)
Convenient Signal Processing routines.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
#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.
struct io_context * accept_io
static int handle_response_brsf(struct mbl_pvt *pvt, char *buf)
Handle the BRSF response.
#define DEADLOCK_AVOIDANCE(lock)
descriptor for a cli entry.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
#define HFP_CIND_CALLSETUP
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
pthread_t sco_listener_thread
static int check_unloading(void)
Check if the module is unloading.
static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen)
static int unloading_flag
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
static char * handle_cli_mobile_cusd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int hfp_parse_brsf(struct hfp_pvt *hfp, const char *buf)
Parse BRSF data.
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.
static int hfp_send_cind(struct hfp_pvt *hfp)
Send the CIND read command.
static int handle_response_cmti(struct mbl_pvt *pvt, char *buf)
Handle AT+CMTI messages.
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
Structure to pass both assignedid values to channel drivers.
static int mbl_hangup(struct ast_channel *ast)
static int rfcomm_write(int rsock, char *buf)
Write to an rfcomm socket.
ast_channel_state
ast_channel states
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
unsigned int do_alignment_detection
static const struct adsi_event events[]
#define ast_cli_register_multiple(e, len)
Register multiple commands.
#define HFP_CIND_CALL_NONE
static int mbl_write(struct ast_channel *ast, struct ast_frame *frame)
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.
static int rfcomm_write_full(int rsock, char *buf, size_t count)
Write to an rfcomm socket.
#define ast_mutex_lock(a)
static int hfp_send_ata(struct hfp_pvt *hfp)
Send ATA.
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 ...
#define ast_str_alloca(init_len)
#define ast_strdup(str)
A wrapper for strdup()
static int hfp_send_sms_text(struct hfp_pvt *hfp, const char *message)
Send the text of an SMS message.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define rfcomm_read_debug(c)
I/O Management (derived from Cheops-NG)
static sdp_session_t * sdp_session
static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf)
Handle NO DIALTONE messages.
void ast_cli(int fd, const char *fmt,...)
static int hsp_send_error(int rsock)
Send an ERROR AT response.
static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf)
Handle AT+CMGR messages.
static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
int ast_unregister_application(const char *app)
Unregister an application.
static int at_match_prefix(char *buf, char *prefix)
Match the given buffer with the given prefix.
#define HFP_CIND_CALLSETUP_ALERTING
Asterisk internal frame definitions.
#define ast_verb(level,...)
static int sco_bind(struct adapter_pvt *adapter)
Bind an SCO listener socket for the given adapter.
struct ast_frame_subclass subclass
static int mbl_ast_hangup(struct mbl_pvt *pvt)
short alignment_samples[4]
static int mbl_answer(struct ast_channel *ast)
#define ast_strlen_zero(foo)
static pthread_t discovery_thread
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.
#define ast_pthread_create_background(a, b, c, d)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
static int hfp_parse_cmti(struct hfp_pvt *hfp, char *buf)
Parse a CMTI notification.
static int headset_send_ring(const void *data)
static int hfp_parse_cind_indicator(struct hfp_pvt *hfp, int group, char *indicator)
Parse and store the given indicator.
static struct adapter_pvt * mbl_load_adapter(struct ast_config *cfg, const char *cat)
Load an adapter from the configuration file.
static int mbl_status_exec(struct ast_channel *ast, const char *data)
Configuration File Parser.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
void ast_smoother_free(struct ast_smoother *s)
#define DSP_DIGITMODE_RELAXDTMF
#define AST_RWLIST_INSERT_HEAD
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
static int hfp_send_clip(struct hfp_pvt *hfp, int status)
Enable or disable calling line identification.
#define EVENT_FLAG_SYSTEM
#define ast_debug(level,...)
Log a DEBUG message.
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
static struct ast_frame * mbl_read(struct ast_channel *ast)
static int handle_response_cusd(struct mbl_pvt *pvt, char *buf)
Handle CUSD messages.
#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...
int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
Waits for input on an fd.
static void * do_monitor_phone(void *data)
General Asterisk PBX channel definitions.
struct adapter_pvt::@4 entry
void ast_channel_rings_set(struct ast_channel *chan, int value)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
void io_context_destroy(struct io_context *ioc)
Destroys a context.
static int hfp_send_vgs(struct hfp_pvt *hfp, int value)
Send the current speaker gain level.
#define ast_mutex_trylock(a)
unsigned int no_callsetup
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define AST_PTHREADT_NULL
static int handle_response_clip(struct mbl_pvt *pvt, char *buf)
Handle AT+CLIP messages.
static struct ast_mansession session
static int hsp_send_vgm(int rsock, int gain)
Send a microphone gain unsolicited AT response.
#define ast_register_application(app, execute, synopsis, description)
Register an application.
Global IO variables are now in a struct in order to be made threadsafe.
#define AST_RWLIST_TRAVERSE
#define ao2_ref(o, delta)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
static int hfp_send_brsf(struct hfp_pvt *hfp, struct hfp_hf *brsf)
Send a BRSF request.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
long int ast_random(void)
#define DEVICE_FRAME_FORMAT
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int handle_response_ring(struct mbl_pvt *pvt, char *buf)
Handle RING messages.
A set of macros to manage forward-linked lists.
unsigned int alignment_detection
static int hfp_brsf2int(struct hfp_hf *hf)
Convert a hfp_hf struct to a BRSF int.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
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...
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
static int hfp_parse_ecav(struct hfp_pvt *hfp, char *buf)
Parse a ECAV event.
static int discovery_interval
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.
This struct holds mappings for indications.
#define AST_CAUSE_FACILITY_NOT_IMPLEMENTED
Structure to describe a channel "technology", ie a channel driver See for examples: ...
static int handle_response_ok(struct mbl_pvt *pvt, char *buf)
Handle OK AT messages.
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.
static int mbl_queue_control(struct mbl_pvt *pvt, enum ast_control_frame_type control)
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
This struct holds HFP features that we support.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
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 sco_write(int s, char *buf, int len)
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
static int mbl_devicestate(const char *data)
static const char * at_msg2str(at_message_t msg)
Get the string representation of the given AT message.
static ast_mutex_t unload_mutex
static int rfcomm_read_cmgr(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of a +CMGR message.
static char * mblsendsms_synopsis
static char * app_mblstatus
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
static int hfp_send_cind_test(struct hfp_pvt *hfp)
Send the CIND test command.
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".
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
struct ast_channel * owner
#define DEVICE_FRAME_SIZE
static int rfcomm_read_until_crlf(int rsock, char **buf, size_t count, size_t *in_count)
Read until.
static int hsp_send_ring(int rsock)
Send a RING unsolicited AT response.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * handle_cli_mobile_search(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int start_monitor(struct mbl_pvt *pvt)
char io_buf[CHANNEL_FRAME_SIZE+AST_FRIENDLY_OFFSET]
static int mbl_load_config(void)
static sdp_session_t * sdp_register(void)
void ast_smoother_reset(struct ast_smoother *s, int bytes)
General Definitions for Asterisk top level program Included by asterisk.h to handle platform-specific...
struct ast_format_cap * capabilities
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define ast_channel_unlock(chan)
static int hfp_parse_ciev(struct hfp_pvt *hfp, char *buf, int *value)
Parse a CIEV event.
static int hfp_send_cusd(struct hfp_pvt *hfp, const char *code)
Send CUSD.
static void parse(struct mgcp_request *req)
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
static int hfp_send_cnmi(struct hfp_pvt *hfp)
Setup SMS new message indication.
#define ast_calloc(num, len)
A wrapper for calloc()
#define HFP_CIND_CALLSETUP_INCOMING
static struct hfp_ag * hfp_int2brsf(int brsf, struct hfp_ag *ag)
Convert a BRSF int to an hfp_ag struct.
static int hfp_send_chup(struct hfp_pvt *hfp)
Send AT+CHUP.
static char * handle_cli_mobile_rfcomm(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
static int mbl_call(struct ast_channel *ast, const char *dest, int timeout)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
static int hfp_send_ecam(struct hfp_pvt *hfp)
Enable Sony Erricson extensions / indications.
#define AST_RWLIST_REMOVE_HEAD
#define HFP_CIND_CALLHELD
static int hfp_send_cmgf(struct hfp_pvt *hfp, int mode)
Set the SMS mode.
Module has failed to load, may be in an inconsistent state.
int ast_isphonenumber(const char *n)
Check if a string consists only of digits and + #.
static void * do_sco_listen(void *data)
Service new and existing SCO connections. This thread accepts new sco connections and handles audio d...
unsigned int alignment_detection_triggered
unsigned int outgoing_sms
static int hsp_send_ok(int rsock)
Send an OK AT response.
static int sdp_search(char *addr, int profile)
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.
static at_message_t at_read_full(int rsock, char *buf, size_t count)
Read an AT message and clasify it.
Structure used to handle boolean flags.
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
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.
static int rfcomm_read_command(int rsock, char **buf, size_t count, size_t *in_count)
Read the remainder of an AT command.
struct ast_frame ast_null_frame
unsigned int incoming_sms
static int hfp_send_cmgs(struct hfp_pvt *hfp, const char *number)
Start sending an SMS message.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct mbl_pvt::msg_queue msg_queue
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
static int mbl_sendsms_exec(struct ast_channel *ast, const char *data)
static ssize_t rfcomm_read(int rsock, char *buf, size_t count)
Read one Hayes AT message from an rfcomm socket.
Standard Command Line Interface.
struct ast_frame * ast_smoother_read(struct ast_smoother *s)
static char * mblsendsms_desc
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct adapter_pvt * adapter
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
const char * ast_channel_name(const struct ast_channel *chan)
static void * do_discovery(void *data)
#define AST_CAUSE_USER_BUSY
static void msg_queue_flush(struct mbl_pvt *pvt)
Remove all itmes from the queue and free them.
struct ast_smoother * bt_out_smoother
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
static int handle_response_error(struct mbl_pvt *pvt, char *buf)
Handle ERROR AT messages.
static void set_unloading(void)
Set the unloading flag.
static struct msg_queue_entry * msg_queue_head(struct mbl_pvt *pvt)
Get the head of a queue.
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.
static int hfp_parse_cmgr(struct hfp_pvt *hfp, char *buf, char **from_number, char **text)
Parse a CMGR message.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
static char * app_mblsendsms
Options provided by main asterisk program.
This struct holds state information about the current hfp connection.
static char * handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
union ast_frame::@263 data
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.
#define ast_mutex_init(pmutex)
#define ast_channel_trylock(chan)
static char * mblstatus_desc
static char context[AST_MAX_CONTEXT]
static int handle_sms_prompt(struct mbl_pvt *pvt, char *buf)
Send an SMS message from the queue.
struct ast_format * format
static void * do_monitor_headset(void *data)
This struct holds HFP features the AG supports.
unsigned int needcallerid
static void msg_queue_free_and_pop(struct mbl_pvt *pvt)
Remove an item from the front of the queue, and free it.
static struct cidinfo hfp_parse_clip(struct hfp_pvt *hfp, char *buf)
Parse a CLIP event.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Asterisk module definitions.
struct ast_sched_context * sched
static struct ast_channel_tech mbl_tech
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
#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
static char * mblstatus_synopsis
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.
#define HFP_CIND_CALLSETUP_NONE
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)
#define AST_MUTEX_DEFINE_STATIC(mutex)
Structure for mutex and tracking information.
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.
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
#define HFP_CIND_CALLSETUP_OUTGOING
static int unload_module(void)
#define ast_mutex_unlock(a)
static int hfp_parse_cind(struct hfp_pvt *hfp, char *buf)
Read the result of the AT+CIND? command.
static char prefix[MAX_PREFIX]
#define AST_APP_ARG(name)
Define an application argument.
#define HFP_CIND_SERVICE_AVAILABLE
static int mbl_has_service(struct mbl_pvt *pvt)
Check if a mobile device has service.
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...