Skip to content

Commit

Permalink
Separate out reusable logic for handling the bluetooth wifi connect.
Browse files Browse the repository at this point in the history
  • Loading branch information
silverchris committed Aug 13, 2022
1 parent b5ba8ad commit dd65bef
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 158 deletions.
35 changes: 19 additions & 16 deletions include/Platforms/Mazda/Managers/BluetoothManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@
#include <com_jci_bca_objectProxy.h>

#include "autoapp/Managers/IBluetoothManager.hpp"
#include "autoapp/Managers/BluetoothConnection.hpp"

struct connectionInfo {
std::string ipAddress;
std::string macAddress;
};


class BluetoothManager : public IBluetoothManager {
public:
explicit BluetoothManager(autoapp::configuration::IConfiguration::Pointer configuration,
std::shared_ptr<DBus::Connection> session_connection);
~BluetoothManager() override;
~BluetoothManager() override = default;

void start() override;
void stop() override;
Expand All @@ -34,28 +41,24 @@ class BluetoothManager : public IBluetoothManager {
bool bdsconfigured = false;
uint32_t serviceId = 0;
std::shared_ptr<com_jci_bca_objectProxy> bcaClient;
void ConnectionStatusResp(uint32_t, uint32_t, uint32_t, uint32_t, std::tuple<std::vector<uint8_t>>) const;
};
void ConnectionStatusResp(uint32_t, uint32_t, uint32_t, uint32_t, std::tuple<std::vector<uint8_t>>);
int update_connection_info();
connectionInfo info;

struct connectionInfo {
std::string ipAddress;
std::string macAddress;
};

int update_connection_info(connectionInfo &info);
};

class BluetoothConnection {
class MazdaBluetoothConnection: public BluetoothConnection{
public:
explicit BluetoothConnection(autoapp::configuration::IConfiguration::Pointer configuration);
MazdaBluetoothConnection(std::string SSID, std::string Password, std::string IpAddress, std::string MacAddress, uint32_t Port);
void handle_connect(const std::string &pty);

protected:
ssize_t read(char *buf, ssize_t size) override;
ssize_t write(char *buf, ssize_t size) override;


private:
int fd = 0;
connectionInfo info;
autoapp::configuration::IConfiguration::Pointer configuration_;

void handleWifiInfoRequest(uint8_t *buffer, uint16_t length);
void handleWifiSecurityRequest(__attribute__((unused)) uint8_t *buffer, __attribute__((unused)) uint16_t length);
static int handleWifiInfoRequestResponse(uint8_t *buffer, uint16_t length);
void sendMessage(google::protobuf::MessageLite &message, uint16_t type) const;
};
25 changes: 25 additions & 0 deletions include/autoapp/Managers/BluetoothConnection.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once
#include <google/protobuf/message_lite.h>
#include "IBluetoothManager.hpp"
#include "autoapp/Configuration/IConfiguration.hpp"

class BluetoothConnection {
public:
BluetoothConnection(std::string SSID, std::string Password, std::string IpAddress, std::string MacAddress, uint32_t Port);
void messageHandler();
void sendMessage(google::protobuf::MessageLite &message, IBluetoothManager::wifiMessages type);
void handleWifiInfoRequest();
void handleWifiSecurityRequest(__attribute__((unused)) uint8_t *buffer, __attribute__((unused)) uint16_t length);
static int handleWifiInfoRequestResponse(uint8_t *buffer, uint16_t length);

protected:
std::string ipAddress;
std::string macAddress;
std::string ssid;
std::string password;
uint32_t port;

virtual ssize_t read(char *buf, ssize_t size) = 0;
virtual ssize_t write(char *buf, ssize_t size) = 0;

};
10 changes: 6 additions & 4 deletions include/autoapp/Managers/IBluetoothManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class IBluetoothManager: public IManager{
public:
using Pointer = std::shared_ptr<IBluetoothManager>;

public:
IBluetoothManager() = default;
virtual ~IBluetoothManager() = default;

virtual void start() = 0;
virtual void stop() = 0;
enum wifiMessages{
WifiInfoRequest = 1,
WifiSecurityRequest = 2,
WifiSecurityReponse = 3,
WifiInfoRequestResponse = 7
};

};
200 changes: 62 additions & 138 deletions src/Platforms/Mazda/Managers/BluetoothManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <iomanip>
#include <utility>

BluetoothManager::BluetoothManager(autoapp::configuration::IConfiguration::Pointer configuration,
std::shared_ptr<DBus::Connection> session_connection)
Expand All @@ -15,7 +17,7 @@ BluetoothManager::BluetoothManager(autoapp::configuration::IConfiguration::Point
}

void BluetoothManager::ConnectionStatusResp(uint32_t found_serviceId, uint32_t connStatus, uint32_t /*btDeviceId*/,
uint32_t /*status*/, std::tuple<std::vector<uint8_t>> terminalPath) const {
uint32_t /*status*/, std::tuple<std::vector<uint8_t>> terminalPath) {
LOG(DEBUG) << "Saw Service: " << found_serviceId;
if (found_serviceId == 1 && connStatus == 3) {
LOG(DEBUG) << "Saw Service: Handsfree. Inititating connection";
Expand All @@ -24,14 +26,12 @@ void BluetoothManager::ConnectionStatusResp(uint32_t found_serviceId, uint32_t c
std::vector<uint8_t> tpath = std::get<0>(terminalPath);
std::string pty(tpath.begin(), tpath.end());
LOG(DEBUG) << "PTY: " << pty;
BluetoothConnection bconnection(configuration_);
update_connection_info();
MazdaBluetoothConnection bconnection(configuration_->wifiSSID(), configuration_->wifiPassword(), info.ipAddress, info.macAddress, configuration_->wifiPort());
bconnection.handle_connect(pty);
}
}

BluetoothManager::~BluetoothManager(){
};

void BluetoothManager::start() {
LOG(DEBUG) << "Reading BdsConfiguration.xml";

Expand All @@ -45,20 +45,19 @@ void BluetoothManager::start() {
if (serviceconfig == nullptr) {
LOG(DEBUG) << "Couldn't find serviceConfiguration in /jci/bds/BdsConfiguration.xml";
} else {
for (tinyxml2::XMLElement *e = serviceconfig->FirstChildElement(); e != nullptr; e = e->NextSiblingElement()) {
if (std::string(e->Attribute("name")) == "AndroidAuto") {
for (tinyxml2::XMLElement *childElement = serviceconfig->FirstChildElement(); childElement != nullptr; childElement = childElement->NextSiblingElement()) {
if (std::string(childElement->Attribute("name")) == "AndroidAuto") {
LOG(INFO) << "BDSCONFIG: AndroidAuto Entry found";
bdsconfigured = true;
serviceId = static_cast<uint32_t>(e->IntAttribute("id"));
serviceId = static_cast<uint32_t>(childElement->IntAttribute("id"));
}
VLOG(9) << "BDSCONFIG: " << e->Attribute("name");
VLOG(9) << "BDSCONFIG: " << childElement->Attribute("name");
}
}

if (bdsconfigured) {
bcaClient = com_jci_bca_objectProxy::create(dbusConnection, "com.jci.bca", "/com/jci/bca");
bcaClient->getcom_jci_bcaInterface()->signal_ConnectionStatusResp()->connect(sigc::mem_fun(*this,
&BluetoothManager::ConnectionStatusResp));
bcaClient->getcom_jci_bcaInterface()->signal_ConnectionStatusResp()->connect(sigc::mem_fun(*this, &BluetoothManager::ConnectionStatusResp));
bcaClient->getcom_jci_bcaInterface()->StartAdd(serviceId);
}
}
Expand All @@ -68,155 +67,80 @@ void BluetoothManager::stop() {
bcaClient.reset();
}

void BluetoothConnection::sendMessage(google::protobuf::MessageLite &message, uint16_t type) const {
auto byteSize = static_cast<size_t>(message.ByteSizeLong());
uint16_t sizeOut = htobe16(static_cast<uint16_t>(byteSize));
uint16_t typeOut = htobe16(type);
auto *out = new char[byteSize + 4];
memcpy(out, &sizeOut, 2);
memcpy(out + 2, &typeOut, 2);

message.SerializeToArray(out + 4, byteSize);

auto written = write(fd, out, byteSize + 4);
if (written > -1) {
LOG(DEBUG) << "Bytes written: " << written;
} else {
LOG(DEBUG) << "Could not write data";
}
delete[] out;
}

void BluetoothConnection::handleWifiInfoRequest(uint8_t *buffer, uint16_t length) {
aasdk::proto::messages::WifiInfoRequest msg;
msg.ParseFromArray(buffer, length);
LOG(DEBUG) << "WifiInfoRequest: " << msg.DebugString();

aasdk::proto::messages::WifiInfoResponse response;
response.set_ip_address(info.ipAddress.c_str());
response.set_port(configuration_->wifiPort());
response.set_status(aasdk::proto::messages::WifiInfoResponse_Status_STATUS_SUCCESS);

sendMessage(response, 7);
MazdaBluetoothConnection::MazdaBluetoothConnection(std::string SSID,
std::string Password,
std::string IpAddress,
std::string MacAddress,
uint32_t Port) : BluetoothConnection(std::move(SSID),
std::move(Password),
std::move(IpAddress),
std::move(MacAddress),
Port) {
}

void BluetoothConnection::handleWifiSecurityRequest(__attribute__((unused)) uint8_t *buffer,
__attribute__((unused)) uint16_t length) {
aasdk::proto::messages::WifiSecurityReponse response;

response.set_ssid(configuration_->wifiSSID().c_str());
response.set_bssid(info.macAddress.c_str());
response.set_key(configuration_->wifiPassword().c_str());
response.set_security_mode(aasdk::proto::messages::WifiSecurityReponse_SecurityMode_WPA2_PERSONAL);
response.set_access_point_type(aasdk::proto::messages::WifiSecurityReponse_AccessPointType_DYNAMIC);

sendMessage(response, 3);
}
ssize_t MazdaBluetoothConnection::read(char *buf, ssize_t size){
fd_set set;
timeval timeout{1, 0};

int BluetoothConnection::handleWifiInfoRequestResponse(uint8_t *buffer, uint16_t length) {
aasdk::proto::messages::WifiInfoResponse msg;
msg.ParseFromArray(buffer, length);
LOG(DEBUG) << "WifiInfoResponse: " << msg.DebugString();
return msg.status();
FD_ZERO(&set);
FD_SET(fd, &set);
if (select(fd + 1, &set, nullptr, nullptr, &timeout) <= 0) {
return 0;
}
return ::read(fd, buf, size);
}

BluetoothConnection::BluetoothConnection(autoapp::configuration::IConfiguration::Pointer configuration)
: configuration_(std::move(configuration)) {
update_connection_info(info);
LOG(DEBUG) << "Got IP: " << info.ipAddress << " MAC: " << info.macAddress;

ssize_t MazdaBluetoothConnection::write(char *buf, ssize_t size){
return ::write(fd, buf, size);
}

void BluetoothConnection::handle_connect(const std::string &pty) {
// char buf[100];
std::vector<char> buf;
void MazdaBluetoothConnection::handle_connect(const std::string &pty) {
LOG(DEBUG) << "PTY: " << pty;
fd = open(pty.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);

char iptables[100];
sprintf(iptables, "iptables -L |grep -c %u", configuration_->wifiPort());
LOG(DEBUG) << iptables;
int result = system(iptables);
if (result) {
sprintf(iptables,
"iptables -A INPUT -p tcp --dport %u -m state --state NEW,ESTABLISHED -j ACCEPT",
configuration_->wifiPort());
LOG(DEBUG) << iptables;
system(iptables);
std::ostringstream check_iptables;
check_iptables << "iptables -L |grep -c " << port;
LOG(DEBUG) << check_iptables.str();
int result = system(check_iptables.str().c_str());
if (result != 0) {
std::ostringstream iptables_cmd;
iptables_cmd << "iptables -A INPUT -p tcp --dport " << port
<< " -m state --state NEW,ESTABLISHED -j ACCEPT";
LOG(DEBUG) << iptables_cmd.str();
system(iptables_cmd.str().c_str());
}

aasdk::proto::messages::WifiInfoRequest request;
request.set_ip_address(info.ipAddress.c_str());
request.set_port(configuration_->wifiPort());

sendMessage(request, 1);
char tmp[100];
uint16_t msgLen;
uint16_t msg;

fd_set set;
timeval timeout{1, 0};

FD_ZERO(&set);
FD_SET(fd, &set);

while (true) {
if (select(fd + 1, &set, nullptr, nullptr, &timeout) <= 0) {
break;
}
ssize_t i = read(fd, &tmp, 100);
if (i > 0) {
buf.insert(buf.cend(), tmp, tmp + i);
}
if (buf.size() < 4) {
continue;
}

msgLen = static_cast<uint16_t>(be16toh(*(uint16_t *) buf.data()));
msg = static_cast<uint16_t>(be16toh(*(uint16_t *) (buf.data() + 2)));
LOG(DEBUG) << "MSG Type: " << msg << " Size: " << msgLen;

if (static_cast<uint16_t>(buf.size()) < msgLen + 4) {
continue;
}

auto *buffer = new uint8_t[msgLen];
std::copy(buf.cbegin() + 4, buf.cbegin() + msgLen, buffer);
switch (msg) {
case 1:handleWifiInfoRequest(buffer, msgLen);
break;
case 2:handleWifiSecurityRequest(buffer, msgLen);
break;
case 7:handleWifiInfoRequestResponse(buffer, msgLen);
break;
default:break;
}
delete[] buffer;
buf.erase(buf.cbegin(), buf.cbegin() + msgLen + 4);
}
messageHandler();

close(fd);
}

int update_connection_info(connectionInfo &info) {
int fd;

int BluetoothManager::update_connection_info() {
int fileDescriptor;
struct ifreq ifr{};
char iface[] = "wlan0";
unsigned char *mac;
const std::string iface = "wlan0";

fd = socket(AF_INET, SOCK_DGRAM, 0);
fileDescriptor = socket(AF_INET, SOCK_DGRAM, 0);

ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, iface, IFNAMSIZ - 1);

ioctl(fd, SIOCGIFHWADDR, &ifr);
mac = (unsigned char *) ifr.ifr_hwaddr.sa_data;
info.macAddress.resize(18);
sprintf((info.macAddress).data(), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
ioctl(fd, SIOCGIFADDR, &ifr);
strncpy(ifr.ifr_name, iface.c_str(), IFNAMSIZ - 1);

ioctl(fileDescriptor, SIOCGIFHWADDR, &ifr);
std::ostringstream macString;
macString << std::setfill('0') << std::setw(2) << std::hex << std::uppercase;
const int macLength = 5;
for (int position = 0; position <= macLength; position++) {
if(!macString.str().empty()){
macString << ":";
}
macString << static_cast<int>(ifr.ifr_hwaddr.sa_data[position]);
}
info.macAddress.assign(macString.str());
ioctl(fileDescriptor, SIOCGIFADDR, &ifr);
info.ipAddress = inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr);

close(fd);
close(fileDescriptor);

return 0;
}
Loading

0 comments on commit dd65bef

Please sign in to comment.