diff --git a/include/Platforms/Mazda/Managers/BluetoothManager.hpp b/include/Platforms/Mazda/Managers/BluetoothManager.hpp index a4eb3d62..da9c4f4d 100644 --- a/include/Platforms/Mazda/Managers/BluetoothManager.hpp +++ b/include/Platforms/Mazda/Managers/BluetoothManager.hpp @@ -18,12 +18,19 @@ #include #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 session_connection); - ~BluetoothManager() override; + ~BluetoothManager() override = default; void start() override; void stop() override; @@ -34,28 +41,24 @@ class BluetoothManager : public IBluetoothManager { bool bdsconfigured = false; uint32_t serviceId = 0; std::shared_ptr bcaClient; - void ConnectionStatusResp(uint32_t, uint32_t, uint32_t, uint32_t, std::tuple>) const; -}; + void ConnectionStatusResp(uint32_t, uint32_t, uint32_t, uint32_t, std::tuple>); + 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; }; \ No newline at end of file diff --git a/include/autoapp/Managers/BluetoothConnection.hpp b/include/autoapp/Managers/BluetoothConnection.hpp new file mode 100644 index 00000000..d7978c6d --- /dev/null +++ b/include/autoapp/Managers/BluetoothConnection.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#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; + +}; \ No newline at end of file diff --git a/include/autoapp/Managers/IBluetoothManager.hpp b/include/autoapp/Managers/IBluetoothManager.hpp index af17cdf6..b7b45829 100644 --- a/include/autoapp/Managers/IBluetoothManager.hpp +++ b/include/autoapp/Managers/IBluetoothManager.hpp @@ -6,11 +6,13 @@ class IBluetoothManager: public IManager{ public: using Pointer = std::shared_ptr; - public: IBluetoothManager() = default; - virtual ~IBluetoothManager() = default; - virtual void start() = 0; - virtual void stop() = 0; + enum wifiMessages{ + WifiInfoRequest = 1, + WifiSecurityRequest = 2, + WifiSecurityReponse = 3, + WifiInfoRequestResponse = 7 + }; }; \ No newline at end of file diff --git a/src/Platforms/Mazda/Managers/BluetoothManager.cpp b/src/Platforms/Mazda/Managers/BluetoothManager.cpp index 504873e2..b7016e4e 100644 --- a/src/Platforms/Mazda/Managers/BluetoothManager.cpp +++ b/src/Platforms/Mazda/Managers/BluetoothManager.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include BluetoothManager::BluetoothManager(autoapp::configuration::IConfiguration::Pointer configuration, std::shared_ptr session_connection) @@ -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> terminalPath) const { + uint32_t /*status*/, std::tuple> terminalPath) { LOG(DEBUG) << "Saw Service: " << found_serviceId; if (found_serviceId == 1 && connStatus == 3) { LOG(DEBUG) << "Saw Service: Handsfree. Inititating connection"; @@ -24,14 +26,12 @@ void BluetoothManager::ConnectionStatusResp(uint32_t found_serviceId, uint32_t c std::vector 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"; @@ -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(e->IntAttribute("id")); + serviceId = static_cast(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); } } @@ -68,155 +67,80 @@ void BluetoothManager::stop() { bcaClient.reset(); } -void BluetoothConnection::sendMessage(google::protobuf::MessageLite &message, uint16_t type) const { - auto byteSize = static_cast(message.ByteSizeLong()); - uint16_t sizeOut = htobe16(static_cast(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 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(be16toh(*(uint16_t *) buf.data())); - msg = static_cast(be16toh(*(uint16_t *) (buf.data() + 2))); - LOG(DEBUG) << "MSG Type: " << msg << " Size: " << msgLen; - - if (static_cast(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(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; } \ No newline at end of file diff --git a/src/autoapp/Managers/BluetoothConnection.cpp b/src/autoapp/Managers/BluetoothConnection.cpp new file mode 100644 index 00000000..6528f64c --- /dev/null +++ b/src/autoapp/Managers/BluetoothConnection.cpp @@ -0,0 +1,107 @@ +#include +#include +#include "aasdk_proto/WifiInfoResponseMessage.pb.h" +#include "aasdk_proto/WifiSecurityResponseMessage.pb.h" + +BluetoothConnection::BluetoothConnection(std::string SSID, + std::string Password, + std::string IpAddress, + std::string MacAddress, + uint32_t Port) + : ipAddress(std::move(IpAddress)), + macAddress(std::move(MacAddress)), + ssid(std::move(SSID)), + password(std::move(Password)), + port(Port) { + LOG(DEBUG) << "Got IP: " << ipAddress << " MAC: " << macAddress; +} + +void BluetoothConnection::handleWifiInfoRequest() { + aasdk::proto::messages::WifiInfoResponse response; + response.set_ip_address(ipAddress.c_str()); + response.set_port(port); + response.set_status(aasdk::proto::messages::WifiInfoResponse_Status_STATUS_SUCCESS); + + sendMessage(response, IBluetoothManager::wifiMessages::WifiInfoRequestResponse); +} + +void BluetoothConnection::handleWifiSecurityRequest(__attribute__((unused)) uint8_t *buffer, + __attribute__((unused)) uint16_t length) { + aasdk::proto::messages::WifiSecurityReponse response; + + response.set_ssid(ssid.c_str()); + response.set_bssid(macAddress.c_str()); + response.set_key(password.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, IBluetoothManager::wifiMessages::WifiSecurityReponse); +} + +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(); +} +void BluetoothConnection::messageHandler() { + handleWifiInfoRequest(); + + const ssize_t bufferLength = 100; + std::array buffer{}; + uint16_t msgLen; + uint16_t msg; + + ssize_t bufferPos = 0; + while (true) { + ssize_t readCount = read(buffer.begin() + bufferPos, buffer.size() - bufferPos); + if (readCount == 0) { + break; + } + bufferPos += readCount; + if (bufferPos < 4) { + continue; + } + + msgLen = static_cast(be16toh(*(uint16_t *) buffer.begin())); + msg = static_cast(be16toh(*(uint16_t *) (buffer.begin() + 2))); + LOG(DEBUG) << "MSG Type: " << msg << " Size: " << msgLen; + + if (static_cast(bufferPos) < msgLen + 4) { + continue; + } + + switch (msg) { + case IBluetoothManager::wifiMessages::WifiInfoRequest:handleWifiInfoRequest(); + break; + case IBluetoothManager::wifiMessages::WifiSecurityRequest: + handleWifiSecurityRequest(reinterpret_cast(buffer.begin() + 4), + msgLen); + break; + case IBluetoothManager::wifiMessages::WifiInfoRequestResponse: + handleWifiInfoRequestResponse(reinterpret_cast(buffer.begin() + 4), msgLen); + break; + default:break; + } + bufferPos = 0; + } +} + +void BluetoothConnection::sendMessage(google::protobuf::MessageLite &message, IBluetoothManager::wifiMessages type) { + auto byteSize = static_cast(message.ByteSizeLong()); + uint16_t sizeOut = htobe16(static_cast(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, (int)byteSize); + + auto written = write(out, byteSize + 4); + if (written > -1) { + LOG(DEBUG) << "Bytes written: " << written; + } else { + LOG(DEBUG) << "Could not write data"; + } + delete[] out; +}