1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2006-2007 Nokia Corporation 6 * Copyright (C) 2004-2009 Marcel Holtmann <marcel (at) holtmann.org> 7 * Copyright (C) 2008-2009 Leonid Movshovich <event.riga (at) gmail.org> 8 * 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 */ 25 26 #ifdef HAVE_CONFIG_H 27 #include <config.h> 28 #endif 29 30 #include <stdint.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <fcntl.h> 34 #include <errno.h> 35 36 #include <glib.h> 37 #include <dbus/dbus.h> 38 #include <gdbus.h> 39 40 #include <bluetooth/bluetooth.h> 41 #include <bluetooth/hci.h> 42 #include <bluetooth/hci_lib.h> 43 #include <bluetooth/sco.h> 44 #include <bluetooth/sdp.h> 45 #include <bluetooth/sdp_lib.h> 46 47 #include "glib-helper.h" 48 #include "device.h" 49 #include "gateway.h" 50 #include "logging.h" 51 #include "error.h" 52 #include "btio.h" 53 #include "dbus-common.h" 54 55 #define RFCOMM_BUF_SIZE 256 56 /* not-more-then-16 defined by GSM + 1 for NULL + padding */ 57 #define AG_INDICATOR_DESCR_SIZE 20 58 #define AG_CALLER_NUM_SIZE 64 /* size of number + type */ 59 60 /* commands */ 61 #define AG_FEATURES "AT+BRSF=26\r" /* = 0x7F = All features supported */ 62 #define AG_INDICATORS_SUPP "AT+CIND=?\r" 63 #define AG_INDICATORS_VAL "AT+CIND?\r" 64 #define AG_INDICATORS_ENABLE "AT+CMER=3,0,0,1\r" 65 #define AG_HOLD_MPTY_SUPP "AT+CHLD=?\r" 66 #define AG_CALLER_IDENT_ENABLE "AT+CLIP=1\r" 67 #define AG_CARRIER_FORMAT "AT+COPS=3,0\r" 68 #define AG_EXTENDED_RESULT_CODE "AT+CMEE=1\r" 69 70 #define AG_FEATURE_3WAY 0x1 71 #define AG_FEATURE_EXTENDED_RES_CODE 0x100 72 /* Hold and multipary AG features. 73 * Comments below are copied from hands-free spec for reference */ 74 /* Releases all held calls or sets User Determined User Busy (UDUB) 75 * for a waiting call */ 76 #define AG_CHLD_0 0x01 77 /* Releases all active calls (if any exist) and accepts the other 78 * (held or waiting) call */ 79 #define AG_CHLD_1 0x02 80 /* Releases specified active call only <x> */ 81 #define AG_CHLD_1x 0x04 82 /* Places all active calls (if any exist) on hold and accepts the other 83 * (held or waiting) call */ 84 #define AG_CHLD_2 0x08 85 /* Request private consultation mode with specified call <x> (Place all 86 * calls on hold EXCEPT the call <x>) */ 87 #define AG_CHLD_2x 0x10 88 /* Adds a held call to the conversation */ 89 #define AG_CHLD_3 0x20 90 /* Connects the two calls and disconnects the subscriber from both calls 91 * (Explicit Call Transfer). Support for this value and its associated 92 * functionality is optional for the HF. */ 93 #define AG_CHLD_4 0x40 94 95 #define OK_RESPONSE "\r\nOK\r\n" 96 #define ERROR_RESPONSE "\r\nERROR\r\n" 97 98 struct indicator { 99 gchar descr[AG_INDICATOR_DESCR_SIZE]; 100 gint value; 101 }; 102 103 struct gateway { 104 gateway_state_t state; 105 GIOChannel *rfcomm; 106 guint rfcomm_watch_id; 107 GIOChannel *sco; 108 gateway_stream_cb_t sco_start_cb; 109 void *sco_start_cb_data; 110 DBusMessage *connect_message; 111 guint ag_features; 112 guint hold_multiparty_features; 113 GSList *indies; 114 gboolean is_dialing; 115 gboolean call_active; 116 117 int sp_gain; 118 int mic_gain; 119 }; 120 121 static gboolean rfcomm_ag_data_cb(GIOChannel *chan, GIOCondition cond, 122 struct audio_device *device); 123 124 int gateway_close(struct audio_device *device); 125 126 static void rfcomm_start_watch(struct audio_device *dev) 127 { 128 struct gateway *gw = dev->gateway; 129 130 gw->rfcomm_watch_id = g_io_add_watch(gw->rfcomm, 131 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, 132 (GIOFunc) rfcomm_ag_data_cb, dev); 133 } 134 135 static void rfcomm_stop_watch(struct audio_device *dev) 136 { 137 struct gateway *gw = dev->gateway; 138 139 g_source_remove(gw->rfcomm_watch_id); 140 } 141 142 static gboolean io_channel_write_all(GIOChannel *io, gchar *data, 143 gsize count) 144 { 145 gsize written = 0; 146 GIOStatus status; 147 148 while (count > 0) { 149 status = g_io_channel_write_chars(io, data, count, &written, 150 NULL); 151 if (status != G_IO_STATUS_NORMAL) 152 return FALSE; 153 154 data += written; 155 count -= written; 156 } 157 return TRUE; 158 } 159 160 /* it's worth to mention that data and response could be the same pointers */ 161 static gboolean rfcomm_send_and_read(struct gateway *gw, gchar *data, 162 gchar *response, gsize count) 163 { 164 GIOChannel *rfcomm = gw->rfcomm; 165 gsize read = 0; 166 gboolean got_ok = FALSE; 167 gboolean got_error = FALSE; 168 gchar *resp_buf = response; 169 gsize toread = RFCOMM_BUF_SIZE - 1; 170 GIOStatus status; 171 172 if (!io_channel_write_all(rfcomm, data, count)) 173 return FALSE; 174 175 while (!(got_ok || got_error)) { 176 status = g_io_channel_read_chars(rfcomm, resp_buf, toread, 177 &read, NULL); 178 if (status == G_IO_STATUS_NORMAL) 179 resp_buf[read] = '\0'; 180 else { 181 debug("rfcomm_send_and_read(): %m"); 182 return FALSE; 183 } 184 got_ok = NULL != strstr(resp_buf, OK_RESPONSE); 185 got_error = NULL != strstr(resp_buf, ERROR_RESPONSE); 186 resp_buf += read; 187 toread -= read; 188 } 189 return TRUE; 190 } 191 192 /* get <descr> from the names: (<descr>, (<values>)), (<descr>, (<values>)) 193 * ... */ 194 static GSList *parse_indicator_names(gchar *names, GSList *indies) 195 { 196 gchar *current = names - 1; 197 GSList *result = indies; 198 gchar *next; 199 struct indicator *ind; 200 201 while (current != NULL) { 202 current += 2; 203 next = strstr(current, ",("); 204 ind = g_slice_new(struct indicator); 205 strncpy(ind->descr, current, 20); 206 ind->descr[(intptr_t) next - (intptr_t) current] = '\0'; 207 result = g_slist_append(result, (gpointer) ind); 208 current = strstr(next + 1, ",("); 209 } 210 return result; 211 } 212 213 /* get values from <val0>,<val1>,... */ 214 static GSList *parse_indicator_values(gchar *values, GSList *indies) 215 { 216 gint val; 217 gchar *current = values - 1; 218 GSList *runner = indies; 219 struct indicator *ind; 220 221 while (current != NULL) { 222 current += 1; 223 sscanf(current, "%d", &val); 224 current = strchr(current, ','); 225 ind = g_slist_nth_data(runner, 0); 226 ind->value = val; 227 runner = g_slist_next(runner); 228 } 229 return indies; 230 } 231 232 /* get values from <val0>,<val1>,... */ 233 static guint get_hold_mpty_features(gchar *features) 234 { 235 guint result = 0; 236 237 if (strstr(features, "0")) 238 result |= AG_CHLD_0; 239 240 if (strstr(features, "1")) 241 result |= AG_CHLD_1; 242 243 if (strstr(features, "1x")) 244 result |= AG_CHLD_1x; 245 246 if (strstr(features, "2")) 247 result |= AG_CHLD_2; 248 249 if (strstr(features, "2x")) 250 result |= AG_CHLD_2x; 251 252 if (strstr(features, "3")) 253 result |= AG_CHLD_3; 254 255 if (strstr(features, "4")) 256 result |= AG_CHLD_4; 257 258 return result; 259 } 260 261 static gboolean establish_service_level_conn(struct gateway *gw) 262 { 263 gchar buf[RFCOMM_BUF_SIZE]; 264 gboolean res; 265 266 debug("at the begin of establish_service_level_conn()"); 267 res = rfcomm_send_and_read(gw, AG_FEATURES, buf, 268 sizeof(AG_FEATURES) - 1); 269 if (!res || sscanf(buf, "\r\n+BRSF:%d", &gw->ag_features) != 1) 270 return FALSE; 271 272 debug("features are 0x%X", gw->ag_features); 273 res = rfcomm_send_and_read(gw, AG_INDICATORS_SUPP, buf, 274 sizeof(AG_INDICATORS_SUPP) - 1); 275 if (!res || !strstr(buf, "+CIND:")) 276 return FALSE; 277 278 gw->indies = parse_indicator_names(strchr(buf, '('), NULL); 279 280 res = rfcomm_send_and_read(gw, AG_INDICATORS_VAL, buf, 281 sizeof(AG_INDICATORS_VAL) - 1); 282 if (!res || !strstr(buf, "+CIND:")) 283 return FALSE; 284 285 gw->indies = parse_indicator_values(strchr(buf, ':') + 1, gw->indies); 286 287 res = rfcomm_send_and_read(gw, AG_INDICATORS_ENABLE, buf, 288 sizeof(AG_INDICATORS_ENABLE) - 1); 289 if (!res || !strstr(buf, "OK")) 290 return FALSE; 291 292 if ((gw->ag_features & AG_FEATURE_3WAY) != 0) { 293 res = rfcomm_send_and_read(gw, AG_HOLD_MPTY_SUPP, buf, 294 sizeof(AG_HOLD_MPTY_SUPP) - 1); 295 if (!res || !strstr(buf, "+CHLD:")) { 296 g_slice_free1(RFCOMM_BUF_SIZE, buf); 297 return FALSE; 298 } 299 gw->hold_multiparty_features = get_hold_mpty_features( 300 strchr(buf, '(')); 301 302 } else 303 gw->hold_multiparty_features = 0; 304 305 debug("Service layer connection successfully established!"); 306 rfcomm_send_and_read(gw, AG_CALLER_IDENT_ENABLE, buf, 307 sizeof(AG_CALLER_IDENT_ENABLE) - 1); 308 rfcomm_send_and_read(gw, AG_CARRIER_FORMAT, buf, 309 sizeof(AG_CARRIER_FORMAT) - 1); 310 if ((gw->ag_features & AG_FEATURE_EXTENDED_RES_CODE) != 0) 311 rfcomm_send_and_read(gw, AG_EXTENDED_RESULT_CODE, buf, 312 sizeof(AG_EXTENDED_RESULT_CODE) - 1); 313 314 return TRUE; 315 } 316 317 static void process_ind_change(struct audio_device *dev, guint index, 318 gint value) 319 { 320 struct gateway *gw = dev->gateway; 321 struct indicator *ind = g_slist_nth_data(gw->indies, index - 1); 322 gchar *name = ind->descr; 323 324 ind->value = value; 325 326 debug("at the begin of process_ind_change, name is %s", name); 327 if (!strcmp(name, "\"call\"")) { 328 if (value > 0) { 329 g_dbus_emit_signal(dev->conn, dev->path, 330 AUDIO_GATEWAY_INTERFACE, 331 "CallStarted", DBUS_TYPE_INVALID); 332 gw->is_dialing = FALSE; 333 gw->call_active = TRUE; 334 } else { 335 g_dbus_emit_signal(dev->conn, dev->path, 336 AUDIO_GATEWAY_INTERFACE, 337 "CallEnded", DBUS_TYPE_INVALID); 338 gw->call_active = FALSE; 339 } 340 341 } else if (!strcmp(name, "\"callsetup\"")) { 342 if (value == 0 && gw->is_dialing) { 343 g_dbus_emit_signal(dev->conn, dev->path, 344 AUDIO_GATEWAY_INTERFACE, 345 "CallTerminated", 346 DBUS_TYPE_INVALID); 347 gw->is_dialing = FALSE; 348 } else if (!gw->is_dialing && value > 0) 349 gw->is_dialing = TRUE; 350 351 } else if (!strcmp(name, "\"callheld\"")) { 352 /* FIXME: The following code is based on assumptions only. 353 * Has to be tested for interoperability 354 * I assume that callheld=2 would be sent when dial from HF 355 * failed in case of 3-way call 356 * Unfortunately this path is not covered by the HF spec so 357 * the code has to be tested for interop 358 */ 359 /* '2' means: all calls held, no active calls */ 360 if (value == 2) { 361 if (gw->is_dialing) { 362 g_dbus_emit_signal(dev->conn, dev->path, 363 AUDIO_GATEWAY_INTERFACE, 364 "CallTerminated", 365 DBUS_TYPE_INVALID); 366 gw->is_dialing = FALSE; 367 } 368 } 369 } else if (!strcmp(name, "\"service\"")) 370 emit_property_changed(dev->conn, dev->path, 371 AUDIO_GATEWAY_INTERFACE, "RegistrationStatus", 372 DBUS_TYPE_UINT16, &value); 373 else if (!strcmp(name, "\"signal\"")) 374 emit_property_changed(dev->conn, dev->path, 375 AUDIO_GATEWAY_INTERFACE, "SignalStrength", 376 DBUS_TYPE_UINT16, &value); 377 else if (!strcmp(name, "\"roam\"")) 378 emit_property_changed(dev->conn, dev->path, 379 AUDIO_GATEWAY_INTERFACE, "RoamingStatus", 380 DBUS_TYPE_UINT16, &value); 381 else if (!strcmp(name, "\"battchg\"")) 382 emit_property_changed(dev->conn, dev->path, 383 AUDIO_GATEWAY_INTERFACE, "BatteryCharge", 384 DBUS_TYPE_UINT16, &value); 385 } 386 387 static void process_ring(struct audio_device *device, GIOChannel *chan, 388 gchar *buf) 389 { 390 gchar number[AG_CALLER_NUM_SIZE]; 391 gchar *cli; 392 gchar *sep; 393 gsize read; 394 GIOStatus status; 395 396 rfcomm_stop_watch(device); 397 status = g_io_channel_read_chars(chan, buf, RFCOMM_BUF_SIZE - 1, &read, NULL); 398 if (status != G_IO_STATUS_NORMAL) 399 return; 400 401 debug("at the begin of process_ring"); 402 if (strlen(buf) > AG_CALLER_NUM_SIZE + 10) 403 error("process_ring(): buf is too long '%s'", buf); 404 else if ((cli = strstr(buf, "\r\n+CLIP"))) { 405 if (sscanf(cli, "\r\n+CLIP: \"%s", number) == 1) { 406 sep = strchr(number, '"'); 407 sep[0] = '\0'; 408 409 /* FIXME:signal will be emitted on each RING+CLIP. 410 * That's bad */ 411 cli = number; 412 g_dbus_emit_signal(device->conn, device->path, 413 AUDIO_GATEWAY_INTERFACE, "Ring", 414 DBUS_TYPE_STRING, &cli, 415 DBUS_TYPE_INVALID); 416 device->gateway->is_dialing = TRUE; 417 } else 418 error("process_ring(): '%s' in place of +CLIP after RING", buf); 419 420 } 421 422 rfcomm_start_watch(device); 423 } 424 425 static gboolean rfcomm_ag_data_cb(GIOChannel *chan, GIOCondition cond, 426 struct audio_device *device) 427 { 428 gchar buf[RFCOMM_BUF_SIZE]; 429 struct gateway *gw; 430 gsize read; 431 /* some space for value */ 432 gchar indicator[AG_INDICATOR_DESCR_SIZE + 4]; 433 gint value; 434 guint index; 435 gchar *sep; 436 437 debug("at the begin of rfcomm_ag_data_cb()"); 438 if (cond & G_IO_NVAL) 439 return FALSE; 440 441 gw = device->gateway; 442 443 if (cond & (G_IO_ERR | G_IO_HUP)) { 444 debug("connection with remote BT is closed"); 445 gateway_close(device); 446 return FALSE; 447 } 448 449 if (g_io_channel_read_chars(chan, buf, sizeof(buf) - 1, &read, NULL) 450 != G_IO_STATUS_NORMAL) 451 return TRUE; 452 buf[read] = '\0'; 453 454 if (strlen(buf) > AG_INDICATOR_DESCR_SIZE + 14) 455 error("rfcomm_ag_data_cb(): buf is too long '%s'", buf); 456 else if (sscanf(buf, "\r\n+CIEV:%s\r\n", indicator) == 1) { 457 sep = strchr(indicator, ','); 458 sep[0] = '\0'; 459 sep += 1; 460 index = atoi(indicator); 461 value = atoi(sep); 462 process_ind_change(device, index, value); 463 } else if (strstr(buf, "RING")) 464 process_ring(device, chan, buf); 465 else if (sscanf(buf, "\r\n+BVRA:%d\r\n", &value) == 1) { 466 if (value == 0) 467 g_dbus_emit_signal(device->conn, device->path, 468 AUDIO_GATEWAY_INTERFACE, 469 "VoiceRecognitionActive", 470 DBUS_TYPE_INVALID); 471 else 472 g_dbus_emit_signal(device->conn, device->path, 473 AUDIO_GATEWAY_INTERFACE, 474 "VoiceRecognitionInactive", 475 DBUS_TYPE_INVALID); 476 } else if (sscanf(buf, "\r\n+VGS:%d\r\n", &value) == 1) { 477 gw->sp_gain = value; 478 emit_property_changed(device->conn, device->path, 479 AUDIO_GATEWAY_INTERFACE, "SpeakerGain", 480 DBUS_TYPE_UINT16, &value); 481 } else if (sscanf(buf, "\r\n+VGM:%d\r\n", &value) == 1) { 482 gw->mic_gain = value; 483 emit_property_changed(device->conn, device->path, 484 AUDIO_GATEWAY_INTERFACE, "MicrophoneGain", 485 DBUS_TYPE_UINT16, &value); 486 } else 487 error("rfcomm_ag_data_cb(): read wrong data '%s'", buf); 488 489 return TRUE; 490 } 491 492 static gboolean sco_io_cb(GIOChannel *chan, GIOCondition cond, 493 struct audio_device *dev) 494 { 495 struct gateway *gw = dev->gateway; 496 497 if (cond & G_IO_NVAL) 498 return FALSE; 499 500 if (cond & (G_IO_ERR | G_IO_HUP)) { 501 debug("sco connection is released"); 502 g_io_channel_shutdown(gw->sco, TRUE, NULL); 503 g_io_channel_unref(gw->sco); 504 gw->sco = NULL; 505 return FALSE; 506 } 507 508 return TRUE; 509 } 510 511 static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) 512 { 513 struct audio_device *dev = (struct audio_device *) user_data; 514 struct gateway *gw = dev->gateway; 515 516 debug("at the begin of sco_connect_cb() in gateway.c"); 517 518 if (err) { 519 error("sco_connect_cb(): %s", err->message); 520 /* not sure, but from other point of view, 521 * what is the reason to have headset which 522 * cannot play audio? */ 523 if (gw->sco_start_cb) 524 gw->sco_start_cb(NULL, gw->sco_start_cb_data); 525 gateway_close(dev); 526 return; 527 } 528 529 gw->sco = g_io_channel_ref(chan); 530 if (gw->sco_start_cb) 531 gw->sco_start_cb(dev, gw->sco_start_cb_data); 532 533 /* why is this here? */ 534 fcntl(g_io_channel_unix_get_fd(chan), F_SETFL, 0); 535 g_io_add_watch(gw->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, 536 (GIOFunc) sco_io_cb, dev); 537 } 538 539 static void rfcomm_connect_cb(GIOChannel *chan, GError *err, 540 gpointer user_data) 541 { 542 struct audio_device *dev = user_data; 543 struct gateway *gw = dev->gateway; 544 DBusMessage *conn_mes = gw->connect_message; 545 gchar gw_addr[18]; 546 GIOFlags flags; 547 548 if (err) { 549 error("connect(): %s", err->message); 550 if (gw->sco_start_cb) 551 gw->sco_start_cb(NULL, gw->sco_start_cb_data); 552 return; 553 } 554 555 ba2str(&dev->dst, gw_addr); 556 /* Blocking mode should be default, but just in case: */ 557 flags = g_io_channel_get_flags(chan); 558 flags &= ~G_IO_FLAG_NONBLOCK; 559 flags &= G_IO_FLAG_MASK; 560 g_io_channel_set_flags(chan, flags, NULL); 561 g_io_channel_set_encoding(chan, NULL, NULL); 562 g_io_channel_set_buffered(chan, FALSE); 563 if (!gw->rfcomm) 564 gw->rfcomm = g_io_channel_ref(chan); 565 566 if (establish_service_level_conn(dev->gateway)) { 567 gboolean value = TRUE; 568 569 debug("%s: Connected to %s", dev->path, gw_addr); 570 rfcomm_start_watch(dev); 571 if (conn_mes) { 572 DBusMessage *reply = 573 dbus_message_new_method_return(conn_mes); 574 dbus_connection_send(dev->conn, reply, NULL); 575 dbus_message_unref(reply); 576 dbus_message_unref(conn_mes); 577 gw->connect_message = NULL; 578 } 579 580 gw->state = GATEWAY_STATE_CONNECTED; 581 emit_property_changed(dev->conn, dev->path, 582 AUDIO_GATEWAY_INTERFACE, 583 "Connected", DBUS_TYPE_BOOLEAN, &value); 584 return; 585 } else 586 error("%s: Failed to establish service layer connection to %s", 587 dev->path, gw_addr); 588 589 if (NULL != gw->sco_start_cb) 590 gw->sco_start_cb(NULL, gw->sco_start_cb_data); 591 592 gateway_close(dev); 593 } 594 595 static void get_record_cb(sdp_list_t *recs, int perr, gpointer user_data) 596 { 597 struct audio_device *dev = user_data; 598 DBusMessage *msg = dev->gateway->connect_message; 599 int ch = -1; 600 sdp_list_t *protos, *classes; 601 uuid_t uuid; 602 gateway_stream_cb_t sco_cb; 603 GIOChannel *io; 604 GError *err = NULL; 605 606 if (perr < 0) { 607 error("Unable to get service record: %s (%d)", strerror(-perr), 608 -perr); 609 goto fail; 610 } 611 612 if (!recs || !recs->data) { 613 error("No records found"); 614 goto fail; 615 } 616 617 if (sdp_get_service_classes(recs->data, &classes) < 0) { 618 error("Unable to get service classes from record"); 619 goto fail; 620 } 621 622 if (sdp_get_access_protos(recs->data, &protos) < 0) { 623 error("Unable to get access protocols from record"); 624 goto fail; 625 } 626 627 memcpy(&uuid, classes->data, sizeof(uuid)); 628 sdp_list_free(classes, free); 629 630 if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 || 631 uuid.value.uuid16 != HANDSFREE_AGW_SVCLASS_ID) { 632 sdp_list_free(protos, NULL); 633 error("Invalid service record or not HFP"); 634 goto fail; 635 } 636 637 ch = sdp_get_proto_port(protos, RFCOMM_UUID); 638 sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); 639 sdp_list_free(protos, NULL); 640 if (ch <= 0) { 641 error("Unable to extract RFCOMM channel from service record"); 642 goto fail; 643 } 644 645 io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, dev, NULL, &err, 646 BT_IO_OPT_SOURCE_BDADDR, &dev->src, 647 BT_IO_OPT_DEST_BDADDR, &dev->dst, 648 BT_IO_OPT_CHANNEL, ch, 649 BT_IO_OPT_INVALID); 650 if (!io) { 651 error("Unable to connect: %s", err->message); 652 if (msg) { 653 error_common_reply(dev->conn, msg, ERROR_INTERFACE 654 ".ConnectionAttemptFailed", 655 err->message); 656 msg = NULL; 657 } 658 g_error_free(err); 659 gateway_close(dev); 660 } 661 662 g_io_channel_unref(io); 663 return; 664 665 fail: 666 if (msg) 667 error_common_reply(dev->conn, msg, ERROR_INTERFACE 668 ".NotSupported", "Not supported"); 669 670 dev->gateway->connect_message = NULL; 671 672 sco_cb = dev->gateway->sco_start_cb; 673 if (sco_cb) 674 sco_cb(NULL, dev->gateway->sco_start_cb_data); 675 } 676 677 static int get_records(struct audio_device *device) 678 { 679 uuid_t uuid; 680 681 sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); 682 return bt_search_service(&device->src, &device->dst, &uuid, 683 get_record_cb, device, NULL); 684 } 685 686 static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg, 687 void *data) 688 { 689 struct audio_device *au_dev = (struct audio_device *) data; 690 struct gateway *gw = au_dev->gateway; 691 692 debug("at the begin of ag_connect()"); 693 if (gw->rfcomm) 694 return g_dbus_create_error(msg, ERROR_INTERFACE 695 ".AlreadyConnected", 696 "Already Connected"); 697 698 gw->connect_message = dbus_message_ref(msg); 699 if (get_records(au_dev) < 0) { 700 dbus_message_unref(gw->connect_message); 701 return g_dbus_create_error(msg, ERROR_INTERFACE 702 ".ConnectAttemptFailed", 703 "Connect Attempt Failed"); 704 } 705 debug("at the end of ag_connect()"); 706 return NULL; 707 } 708 709 static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg, 710 void *data) 711 { 712 struct audio_device *device = data; 713 struct gateway *gw = device->gateway; 714 DBusMessage *reply = NULL; 715 char gw_addr[18]; 716 717 reply = dbus_message_new_method_return(msg); 718 if (!reply) 719 return NULL; 720 721 if (!gw->rfcomm) 722 return g_dbus_create_error(msg, ERROR_INTERFACE 723 ".NotConnected", 724 "Device not Connected"); 725 726 gateway_close(device); 727 ba2str(&device->dst, gw_addr); 728 debug("Disconnected from %s, %s", gw_addr, device->path); 729 730 return reply; 731 } 732 733 static DBusMessage *process_ag_reponse(DBusMessage *msg, gchar *response) 734 { 735 DBusMessage *reply; 736 737 738 debug("in process_ag_reponse, response is %s", response); 739 if (strstr(response, OK_RESPONSE)) 740 reply = dbus_message_new_method_return(msg); 741 else { 742 /* FIXME: some code should be here to processes errors 743 * in better fasion */ 744 debug("AG responded with '%s' to %s method call", response, 745 dbus_message_get_member(msg)); 746 reply = dbus_message_new_error(msg, ERROR_INTERFACE 747 ".OperationFailed", 748 "Operation failed.See log for details"); 749 } 750 return reply; 751 } 752 753 static DBusMessage *process_simple(DBusMessage *msg, struct audio_device *dev, 754 gchar *data) 755 { 756 struct gateway *gw = dev->gateway; 757 gchar buf[RFCOMM_BUF_SIZE]; 758 759 rfcomm_stop_watch(dev); 760 rfcomm_send_and_read(gw, data, buf, strlen(data)); 761 rfcomm_start_watch(dev); 762 return process_ag_reponse(msg, buf); 763 } 764 765 #define AG_ANSWER "ATA\r" 766 767 static DBusMessage *ag_answer(DBusConnection *conn, DBusMessage *msg, 768 void *data) 769 { 770 struct audio_device *dev = data; 771 struct gateway *gw = dev->gateway; 772 773 if (!gw->rfcomm) 774 return g_dbus_create_error(msg, ERROR_INTERFACE 775 ".NotConnected", 776 "Not Connected"); 777 778 if (gw->call_active) 779 return g_dbus_create_error(msg, ERROR_INTERFACE 780 ".CallAlreadyAnswered", 781 "Call AlreadyAnswered"); 782 783 return process_simple(msg, dev, AG_ANSWER); 784 } 785 786 #define AG_HANGUP "AT+CHUP\r" 787 788 static DBusMessage *ag_terminate_call(DBusConnection *conn, DBusMessage *msg, 789 void *data) 790 { 791 struct audio_device *dev = data; 792 struct gateway *gw = dev->gateway; 793 794 if (!gw->rfcomm) 795 return g_dbus_create_error(msg, ERROR_INTERFACE 796 ".NotConnected", 797 "Not Connected"); 798 799 return process_simple(msg, dev, AG_HANGUP); 800 } 801 802 /* according to GSM spec */ 803 #define ALLOWED_NUMBER_SYMBOLS "1234567890*#ABCD" 804 #define AG_PLACE_CALL "ATD%s;\r" 805 /* dialing from memory is not supported as headset spec doesn't define a way 806 * to retreive phone memory entries. 807 */ 808 static DBusMessage *ag_call(DBusConnection *conn, DBusMessage *msg, 809 void *data) 810 { 811 struct audio_device *device = data; 812 struct gateway *gw = device->gateway; 813 gchar buf[RFCOMM_BUF_SIZE]; 814 gchar *number; 815 gint atd_len; 816 DBusMessage *result; 817 818 debug("at the begin of ag_call()"); 819 if (!gw->rfcomm) 820 return g_dbus_create_error(msg, ERROR_INTERFACE 821 ".NotConnected", 822 "Not Connected"); 823 824 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number, 825 DBUS_TYPE_INVALID); 826 if (strlen(number) != strspn(number, ALLOWED_NUMBER_SYMBOLS)) 827 return dbus_message_new_error(msg, 828 ERROR_INTERFACE ".BadNumber", 829 "Number contains characters which are not allowed"); 830 831 atd_len = sprintf(buf, AG_PLACE_CALL, number); 832 rfcomm_stop_watch(device); 833 rfcomm_send_and_read(gw, buf, buf, atd_len); 834 rfcomm_start_watch(device); 835 836 result = process_ag_reponse(msg, buf); 837 return result; 838 } 839 840 #define AG_GET_CARRIER "AT+COPS?\r" 841 842 static DBusMessage *ag_get_operator(DBusConnection *conn, DBusMessage *msg, 843 void *data) 844 { 845 struct audio_device *dev = (struct audio_device *) data; 846 struct gateway *gw = dev->gateway; 847 gchar buf[RFCOMM_BUF_SIZE]; 848 GIOChannel *rfcomm = gw->rfcomm; 849 gsize read; 850 gchar *result, *sep; 851 DBusMessage *reply; 852 GIOStatus status; 853 854 if (!gw->rfcomm) 855 return g_dbus_create_error(msg, ERROR_INTERFACE 856 ".NotConnected", 857 "Not Connected"); 858 859 rfcomm_stop_watch(dev); 860 io_channel_write_all(rfcomm, AG_GET_CARRIER, strlen(AG_GET_CARRIER)); 861 862 status = g_io_channel_read_chars(rfcomm, buf, RFCOMM_BUF_SIZE - 1, 863 &read, NULL); 864 rfcomm_start_watch(dev); 865 if (G_IO_STATUS_NORMAL == status) { 866 buf[read] = '\0'; 867 if (strstr(buf, "+COPS")) { 868 if (!strrchr(buf, ',')) 869 result = "0"; 870 else { 871 result = strchr(buf, '\"') + 1; 872 sep = strchr(result, '\"'); 873 sep[0] = '\0'; 874 } 875 876 reply = dbus_message_new_method_return(msg); 877 dbus_message_append_args(reply, DBUS_TYPE_STRING, 878 &result, DBUS_TYPE_INVALID); 879 } else { 880 info("ag_get_operator(): '+COPS' expected but" 881 " '%s' received", buf); 882 reply = dbus_message_new_error(msg, ERROR_INTERFACE 883 ".Failed", 884 "Unexpected response from AG"); 885 } 886 } else { 887 error("ag_get_operator(): %m"); 888 reply = dbus_message_new_error(msg, ERROR_INTERFACE 889 ".ConnectionFailed", 890 "Failed to receive response from AG"); 891 } 892 893 return reply; 894 } 895 896 #define AG_SEND_DTMF "AT+VTS=%c\r" 897 static DBusMessage *ag_send_dtmf(DBusConnection *conn, DBusMessage *msg, 898 void *data) 899 { 900 struct audio_device *device = data; 901 struct gateway *gw = device->gateway; 902 gchar buf[RFCOMM_BUF_SIZE]; 903 gchar *number; 904 gint com_len; 905 gboolean got_ok = TRUE; 906 gint num_len; 907 gint i = 0; 908 909 if (!gw->rfcomm) 910 return g_dbus_create_error(msg, ERROR_INTERFACE 911 ".NotConnected", 912 "Not Connected"); 913 914 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number, 915 DBUS_TYPE_INVALID); 916 if (strlen(number) != strspn(number, ALLOWED_NUMBER_SYMBOLS)) 917 return dbus_message_new_error(msg, 918 ERROR_INTERFACE ".BadNumber", 919 "Number contains characters which are not allowed"); 920 921 num_len = strlen(number); 922 rfcomm_stop_watch(device); 923 while (i < num_len && got_ok) { 924 com_len = sprintf(buf, AG_SEND_DTMF, number[i]); 925 rfcomm_send_and_read(gw, buf, buf, com_len); 926 got_ok = NULL != strstr(buf, OK_RESPONSE); 927 i += 1; 928 } 929 rfcomm_start_watch(device); 930 return process_ag_reponse(msg, buf); 931 } 932 933 #define AG_GET_SUBSCRIBER_NUMS "AT+CNUM\r" 934 #define CNUM_LEN 5 /* length of "+CNUM" string */ 935 #define MAX_NUMBER_CNT 16 936 static DBusMessage *ag_get_subscriber_num(DBusConnection *conn, 937 DBusMessage *msg, void *data) 938 { 939 struct audio_device *device = data; 940 struct gateway *gw = device->gateway; 941 gchar buf[RFCOMM_BUF_SIZE]; 942 gchar *number, *end; 943 DBusMessage *reply = dbus_message_new_method_return(msg); 944 945 if (!gw->rfcomm) 946 return g_dbus_create_error(msg, ERROR_INTERFACE 947 ".NotConnected", 948 "Not Connected"); 949 950 rfcomm_stop_watch(device); 951 rfcomm_send_and_read(gw, AG_GET_SUBSCRIBER_NUMS, buf, 952 strlen(AG_GET_SUBSCRIBER_NUMS)); 953 rfcomm_start_watch(device); 954 955 if (strlen(buf) > AG_CALLER_NUM_SIZE + 21) 956 error("ag_get_subscriber_num(): buf is too long '%s'", buf); 957 else if (strstr(buf, "+CNUM")) { 958 number = strchr(buf, ','); 959 number++; 960 end = strchr(number, ','); 961 if (end) { 962 *end = '\0'; 963 dbus_message_append_args(reply, DBUS_TYPE_STRING, 964 &number, DBUS_TYPE_INVALID); 965 } 966 } else 967 error("ag_get_subscriber_num(): read wrong data '%s'", buf); 968 969 return reply; 970 } 971 972 static DBusMessage *ag_get_properties(DBusConnection *conn, DBusMessage *msg, 973 void *data) 974 { 975 struct audio_device *device = data; 976 struct gateway *gw = device->gateway; 977 DBusMessage *reply; 978 DBusMessageIter iter; 979 DBusMessageIter dict; 980 gboolean value; 981 guint index = 0; 982 struct indicator *ind; 983 984 reply = dbus_message_new_method_return(msg); 985 if (!reply) 986 return NULL; 987 988 dbus_message_iter_init_append(reply, &iter); 989 990 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 991 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 992 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 993 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 994 995 /* Connected */ 996 value = gateway_is_connected(device); 997 dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &value); 998 999 if (!value) 1000 goto done; 1001 1002 while ((ind = g_slist_nth_data(gw->indies, index))) { 1003 if(!strcmp(ind->descr, "\"service\"")) 1004 dict_append_entry(&dict, "RegistrationStatus", 1005 DBUS_TYPE_UINT16, &ind->value); 1006 else if (!strcmp(ind->descr, "\"signal\"")) 1007 dict_append_entry(&dict, "SignalStrength", 1008 DBUS_TYPE_UINT16, &ind->value); 1009 else if (!strcmp(ind->descr, "\"roam\"")) 1010 dict_append_entry(&dict, "RoamingStatus", 1011 DBUS_TYPE_UINT16, &ind->value); 1012 else if (!strcmp(ind->descr, "\"battchg\"")) 1013 dict_append_entry(&dict, "BatteryCharge", 1014 DBUS_TYPE_UINT16, &ind->value); 1015 index++; 1016 } 1017 1018 /* SpeakerGain */ 1019 dict_append_entry(&dict, "SpeakerGain", DBUS_TYPE_UINT16, 1020 &device->gateway->sp_gain); 1021 1022 /* MicrophoneGain */ 1023 dict_append_entry(&dict, "MicrophoneGain", DBUS_TYPE_UINT16, 1024 &device->gateway->mic_gain); 1025 done: 1026 dbus_message_iter_close_container(&iter, &dict); 1027 return reply; 1028 } 1029 1030 static GDBusMethodTable gateway_methods[] = { 1031 { "Connect", "", "", ag_connect, G_DBUS_METHOD_FLAG_ASYNC }, 1032 { "Disconnect", "", "", ag_disconnect }, 1033 { "AnswerCall", "", "", ag_answer }, 1034 { "TerminateCall", "", "", ag_terminate_call }, 1035 { "Call", "s", "", ag_call }, 1036 { "GetOperatorName", "", "s", ag_get_operator }, 1037 { "SendDTMF", "s", "", ag_send_dtmf }, 1038 { "GetSubscriberNumber", "", "s", ag_get_subscriber_num }, 1039 { "GetProperties", "", "a{sv}", ag_get_properties }, 1040 { NULL, NULL, NULL, NULL } 1041 }; 1042 1043 static GDBusSignalTable gateway_signals[] = { 1044 { "Ring", "s" }, 1045 { "CallTerminated", "" }, 1046 { "CallStarted", "" }, 1047 { "CallEnded", "" }, 1048 { "PropertyChanged", "sv" }, 1049 { NULL, NULL } 1050 }; 1051 1052 struct gateway *gateway_init(struct audio_device *dev) 1053 { 1054 struct gateway *gw; 1055 1056 if (!g_dbus_register_interface(dev->conn, dev->path, 1057 AUDIO_GATEWAY_INTERFACE, 1058 gateway_methods, gateway_signals, 1059 NULL, dev, NULL)) 1060 return NULL; 1061 1062 debug("in gateway_init, dev is %p", dev); 1063 gw = g_new0(struct gateway, 1); 1064 gw->indies = NULL; 1065 gw->is_dialing = FALSE; 1066 gw->call_active = FALSE; 1067 gw->state = GATEWAY_STATE_DISCONNECTED; 1068 return gw; 1069 1070 } 1071 1072 gboolean gateway_is_connected(struct audio_device *dev) 1073 { 1074 return (dev && dev->gateway && 1075 dev->gateway->state == GATEWAY_STATE_CONNECTED); 1076 } 1077 1078 int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io) 1079 { 1080 if (!io) 1081 return -EINVAL; 1082 1083 g_io_channel_ref(io); 1084 dev->gateway->rfcomm = io; 1085 1086 return 0; 1087 } 1088 1089 int gateway_connect_sco(struct audio_device *dev, GIOChannel *io) 1090 { 1091 struct gateway *gw = dev->gateway; 1092 1093 if (gw->sco) 1094 return -EISCONN; 1095 1096 gw->sco = g_io_channel_ref(io); 1097 1098 g_io_add_watch(gw->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, 1099 (GIOFunc) sco_io_cb, dev); 1100 return 0; 1101 } 1102 1103 void gateway_start_service(struct audio_device *device) 1104 { 1105 rfcomm_connect_cb(device->gateway->rfcomm, NULL, device); 1106 } 1107 1108 static void indicator_slice_free(gpointer mem) 1109 { 1110 g_slice_free(struct indicator, mem); 1111 } 1112 1113 int gateway_close(struct audio_device *device) 1114 { 1115 struct gateway *gw = device->gateway; 1116 GIOChannel *rfcomm = gw->rfcomm; 1117 GIOChannel *sco = gw->sco; 1118 gboolean value = FALSE; 1119 1120 g_slist_foreach(gw->indies, (GFunc) indicator_slice_free, NULL); 1121 g_slist_free(gw->indies); 1122 if (rfcomm) { 1123 g_io_channel_shutdown(rfcomm, TRUE, NULL); 1124 g_io_channel_unref(rfcomm); 1125 gw->rfcomm = NULL; 1126 } 1127 1128 if (sco) { 1129 g_io_channel_shutdown(sco, TRUE, NULL); 1130 g_io_channel_unref(sco); 1131 gw->sco = NULL; 1132 gw->sco_start_cb = NULL; 1133 gw->sco_start_cb_data = NULL; 1134 } 1135 1136 gw->state = GATEWAY_STATE_DISCONNECTED; 1137 1138 emit_property_changed(device->conn, device->path, 1139 AUDIO_GATEWAY_INTERFACE, 1140 "Connected", DBUS_TYPE_BOOLEAN, &value); 1141 return 0; 1142 } 1143 1144 /* These are functions to be called from unix.c for audio system 1145 * ifaces (alsa, gstreamer, etc.) */ 1146 gboolean gateway_request_stream(struct audio_device *dev, 1147 gateway_stream_cb_t cb, void *user_data) 1148 { 1149 struct gateway *gw = dev->gateway; 1150 GError *err = NULL; 1151 GIOChannel *io; 1152 1153 if (!gw->rfcomm) { 1154 gw->sco_start_cb = cb; 1155 gw->sco_start_cb_data = user_data; 1156 get_records(dev); 1157 } else if (!gw->sco) { 1158 gw->sco_start_cb = cb; 1159 gw->sco_start_cb_data = user_data; 1160 io = bt_io_connect(BT_IO_SCO, sco_connect_cb, dev, NULL, &err, 1161 BT_IO_OPT_SOURCE_BDADDR, &dev->src, 1162 BT_IO_OPT_DEST_BDADDR, &dev->dst, 1163 BT_IO_OPT_INVALID); 1164 if (!io) { 1165 error("%s", err->message); 1166 g_error_free(err); 1167 return FALSE; 1168 } 1169 } else { 1170 if (cb) 1171 cb(dev, user_data); 1172 } 1173 1174 return TRUE; 1175 } 1176 1177 int gateway_config_stream(struct audio_device *dev, gateway_stream_cb_t sco_cb, 1178 void *user_data) 1179 { 1180 struct gateway *gw = dev->gateway; 1181 1182 if (!gw->rfcomm) { 1183 gw->sco_start_cb = sco_cb; 1184 gw->sco_start_cb_data = user_data; 1185 return get_records(dev); 1186 } 1187 1188 if (sco_cb) 1189 sco_cb(dev, user_data); 1190 1191 return 0; 1192 } 1193 1194 gboolean gateway_cancel_stream(struct audio_device *dev, unsigned int id) 1195 { 1196 gateway_close(dev); 1197 return TRUE; 1198 } 1199 1200 int gateway_get_sco_fd(struct audio_device *dev) 1201 { 1202 struct gateway *gw = dev->gateway; 1203 1204 if (!gw || !gw->sco) 1205 return -1; 1206 1207 return g_io_channel_unix_get_fd(gw->sco); 1208 } 1209 1210 void gateway_suspend_stream(struct audio_device *dev) 1211 { 1212 struct gateway *gw = dev->gateway; 1213 1214 if (!gw || !gw->sco) 1215 return; 1216 1217 g_io_channel_shutdown(gw->sco, TRUE, NULL); 1218 g_io_channel_unref(gw->sco); 1219 gw->sco = NULL; 1220 gw->sco_start_cb = NULL; 1221 gw->sco_start_cb_data = NULL; 1222 } 1223 1224