1/****************************************************************************** 2 * 3 * Copyright (C) 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19#include <sys/socket.h> 20#include <unistd.h> 21 22#include "base.h" 23#include "support/callbacks.h" 24#include "support/rfcomm.h" 25 26static const bt_uuid_t HFP_AG_UUID = {{ 0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }}; 27static const char HANDSHAKE_COMMAND[] = "AT+BRSF=29\r"; 28static const char HANDSHAKE_RESPONSE[] = "OK\r\n"; 29 30static bool handshake(int fd) { 31 TASSERT(write(fd, HANDSHAKE_COMMAND, sizeof(HANDSHAKE_COMMAND)) == sizeof(HANDSHAKE_COMMAND), "Unable to send HFP handshake."); 32 33 char response[256] = { 0 }; 34 size_t total = 0; 35 while (!strstr(response, HANDSHAKE_RESPONSE) && total < sizeof(response)) { 36 ssize_t len = read(fd, response + total, sizeof(response) - total); 37 TASSERT(len != -1 && len != 0, "Unable to read complete response from socket."); 38 total += len; 39 } 40 TASSERT(strstr(response, HANDSHAKE_RESPONSE) != NULL, "No valid response from HFP audio gateway."); 41 return true; 42} 43 44bool rfcomm_connect() { 45 int fd; 46 int error; 47 48 error = socket_interface->connect(&bt_remote_bdaddr, BTSOCK_RFCOMM, (const uint8_t *)&HFP_AG_UUID, 0, &fd, 0); 49 TASSERT(error == BT_STATUS_SUCCESS, "Error creating RFCOMM socket: %d", error); 50 TASSERT(fd != -1, "Error creating RFCOMM socket: invalid fd"); 51 52 int channel; 53 sock_connect_signal_t signal; 54 TASSERT(read(fd, &channel, sizeof(channel)) == sizeof(channel), "Channel not read from RFCOMM socket."); 55 TASSERT(read(fd, &signal, sizeof(signal)) == sizeof(signal), "Connection signal not read from RFCOMM socket."); 56 57 TASSERT(!memcmp(&signal.bd_addr, &bt_remote_bdaddr, sizeof(bt_bdaddr_t)), "Connected to a different bdaddr than expected."); 58 TASSERT(channel == signal.channel, "Inconsistent channels returned: %d and %d", channel, signal.channel); 59 60 if (!handshake(fd)) 61 return false; 62 63 close(fd); 64 return true; 65} 66 67bool rfcomm_repeated_connect() { 68 static const int max_iterations = 128; 69 70 for (int i = 0; i < max_iterations; ++i) { 71 TASSERT(rfcomm_connect(), "Connection failed on attempt %d/%d", i, max_iterations); 72 } 73 74 return true; 75} 76