WIFI service

* Changes to WIFI service to handle messages from Android Auto. This fixes issues reported with AA > 12.6.
* Modifications to support aasdk proto updates.
* Docker cross compile build for RPI.
* Boost log filtering via `openauto-logs.ini` file
This commit is contained in:
SonOfGib 2024-10-29 18:50:11 -04:00
parent 35005a0e54
commit e3aa777467
No known key found for this signature in database
GPG Key ID: AAC7AE796C4F06D6
13 changed files with 228 additions and 10 deletions

View File

@ -1,4 +1,10 @@
cmake_minimum_required(VERSION 3.5.1) cmake_minimum_required(VERSION 3.5.1)
if(CROSS_COMPILE_ARMHF)
message("Cross compiling for armhf")
set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc-8)
set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++-8)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf")
endif(CROSS_COMPILE)
project(openauto CXX) project(openauto CXX)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
@ -27,7 +33,7 @@ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3")
add_definitions(-DBOOST_ALL_DYN_LINK) add_definitions(-DBOOST_ALL_DYN_LINK)
find_package(Boost REQUIRED COMPONENTS system log OPTIONAL_COMPONENTS unit_test_framework) find_package(Boost REQUIRED COMPONENTS system log_setup log OPTIONAL_COMPONENTS unit_test_framework)
find_package(libusb-1.0 REQUIRED) find_package(libusb-1.0 REQUIRED)
find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth Network) find_package(Qt5 COMPONENTS Multimedia MultimediaWidgets Bluetooth Network)
find_package(Protobuf REQUIRED) find_package(Protobuf REQUIRED)

49
buildenv/Dockerfile Normal file
View File

@ -0,0 +1,49 @@
FROM debian:buster AS prebuilts
COPY ./buildenv/pi_binaries/buster.tar.gz buster.tar.gz
COPY ./buildenv/pi_binaries/aasdk_armhf.deb aasdk_armhf.deb
RUN apt-get update &&\
apt-get -y install cmake build-essential git zip &&\
git clone https://github.com/SonOfGib/prebuilts.git &&\
mkdir qt5 &&\
cat prebuilts/qt5/Qt_5151_armv7l_OpenGLES2.tar.xz* > Qt5_OpenGLES2.tar.xz
FROM debian:buster AS openauto
COPY --from=prebuilts Qt5_OpenGLES2.tar.xz Qt5_OpenGLES2.tar.xz
COPY --from=prebuilts buster.tar.gz buster.tar.gz
COPY --from=prebuilts aasdk_armhf.deb aasdk_armhf.deb
RUN dpkg --add-architecture armhf &&\
apt-get update &&\
apt-get -y install cmake build-essential git &&\
apt-get -y install gcc-arm-linux-gnueabihf cpp-arm-linux-gnueabihf g++-arm-linux-gnueabihf protobuf-compiler &&\
apt-get -y install gcc-8-base:armhf libc6:armhf libgcc1:armhf libicu63:armhf libidn2-0:armhf libstdc++6:armhf libunistring2:armhf pulseaudio:armhf librtaudio-dev:armhf libgps-dev:armhf libblkid-dev:armhf libtag1-dev:armhf libgles2-mesa-dev:armhf libdouble-conversion-dev:armhf &&\
tar -xf Qt5_OpenGLES2.tar.xz -C / &&\
tar -xf buster.tar.gz -C /
# These are all the libboost requirements. It would be shorter if libboost-log-dev wasn't a disaster that's being dealt with manually.
RUN apt-get install -y libprotobuf-dev libusb-1.0.0-dev libssl-dev libboost-dev libboost-system-dev libboost-atomic1.67.0 libboost-chrono1.67.0 libboost-date-time1.67.0 libboost-filesystem1.67.0 libboost-regex1.67.0 libboost-thread1.67.0 libboost-filesystem1.67-dev libboost-thread1.67-dev libboost-date-time1.67-dev &&\
apt-get install -y libprotobuf-dev:armhf libusb-1.0.0-dev:armhf libssl-dev:armhf libboost-dev:armhf libboost-system-dev:armhf libboost-atomic1.67.0:armhf libboost-chrono1.67.0:armhf libboost-date-time1.67.0:armhf libboost-filesystem1.67.0:armhf libboost-regex1.67.0:armhf libboost-system1.67.0:armhf libboost-thread1.67.0:armhf libboost-filesystem1.67-dev:armhf libboost-thread1.67-dev:armhf libboost-date-time1.67-dev:armhf
COPY / /src
WORKDIR /src
# Import resources
COPY ./buildenv/patch-libboost-log-deb.sh /src/resources/patch-libboost-log-deb.sh
COPY ./buildenv/entrypoint.sh /entrypoint.sh
# Patch libboost-log-dev and install
RUN chmod +x ./resources/patch-libboost-log-deb.sh
RUN ./resources/patch-libboost-log-deb.sh
# Make Executable
RUN chmod +x /entrypoint.sh
WORKDIR /
RUN dpkg-deb -xv aasdk_armhf.deb /
WORKDIR /src
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

16
buildenv/cross-compile.md Normal file
View File

@ -0,0 +1,16 @@
### RPI Cross Compile
The docker image in this folder is intended to be used to cross compile `openauto` without having to configure your
host pc with multiarch or installing a toolchain.
#### Setup
The `openauto` build for RPI3 requires some files from the PI, as well as aasdk libraries compiled for amrhf.
- RPI files should be compressed to `buildenv/pi_binaries/buster.tar.gz`. The files required in the archive should
match the path/files in the `if(RPI3_BUILD)` section of `CMakeLists.txt`
- Copy the `.deb` file from `aasdk` docker cross compile build and place it in `buildenv/pi_binaries/aasdk_armhf.dev`
#### Build
```bash
cd buildenv
sudo docker compose up --build
```
Binary files will then be available in `buildenv/release`.

View File

@ -0,0 +1,7 @@
services:
openauto-build:
build:
context: ../
dockerfile: buildenv/Dockerfile
volumes:
- ./release/:/release/

14
buildenv/entrypoint.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/bash
# Clear out the /build directory
mkdir build;
cd build;
cmake -DCMAKE_BUILD_TYPE=Release -DRPI3_BUILD=true -DCROSS_COMPILE_ARMHF=true -DAASDK_INCLUDE_DIRS=/usr/include/aasdk -DAASDK_LIBRARIES=/usr/lib/libaasdk.so -DAASDK_PROTO_INCLUDE_DIRS=/usr/include/aasdk_proto -DAASDK_PROTO_LIBRARIES=/usr/lib/libaasdk_proto.so ../
make -j4
cd ../bin
# Move it to release
rm -f /release/autoapp
rm -f /release/btservice
mv autoapp /release
mv btservice /release

View File

@ -0,0 +1,46 @@
# All this because of a packaging bug in libboost-log-dev
# 'Multi-Arch: same' is not present in the control file of Debian packages, all the way up to Sid
# Rather than recompiling the parent libbost suite, download the 6 packages, extract, edit, and repackage.
# https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=libboost-log-dev
apt-get -y install --download-only libboost-log-dev:amd64 libboost-log1.67.0:amd64 libboost-log1.67-dev:amd64
apt-get -y install --download-only libboost-log-dev:armhf libboost-log1.67.0:armhf libboost-log1.67-dev:armhf
mkdir -p /tmp/armhf/libboost-log-dev/
dpkg-deb -x /var/cache/apt/archives/libboost-log-dev_1.67.0.1_armhf.deb /tmp/armhf/libboost-log-dev/
dpkg-deb -e /var/cache/apt/archives/libboost-log-dev_1.67.0.1_armhf.deb /tmp/armhf/libboost-log-dev/DEBIAN/
sed -i '/^Priority: optional/a Multi-Arch: same' /tmp/armhf/libboost-log-dev/DEBIAN/control
dpkg-deb -b /tmp/armhf/libboost-log-dev/ /tmp/libboost-log-dev_1.67.0.1_armhf.deb
mkdir -p /tmp/amd64/libboost-log-dev/
dpkg-deb -x /var/cache/apt/archives/libboost-log-dev_1.67.0.1_amd64.deb /tmp/amd64/libboost-log-dev/
dpkg-deb -e /var/cache/apt/archives/libboost-log-dev_1.67.0.1_amd64.deb /tmp/amd64/libboost-log-dev/DEBIAN/
sed -i '/^Priority: optional/a Multi-Arch: same' /tmp/amd64/libboost-log-dev/DEBIAN/control
dpkg-deb -b /tmp/amd64/libboost-log-dev/ /tmp/libboost-log-dev_1.67.0.1_amd64.deb
mkdir -p /tmp/armhf/libboost-log1.67-dev/
dpkg-deb -x /var/cache/apt/archives/libboost-log1.67-dev_1.67.0-13+deb10u1_armhf.deb /tmp/armhf/libboost-log1.67-dev/
dpkg-deb -e /var/cache/apt/archives/libboost-log1.67-dev_1.67.0-13+deb10u1_armhf.deb /tmp/armhf/libboost-log1.67-dev/DEBIAN/
sed -i '/^Priority: optional/a Multi-Arch: same' /tmp/armhf/libboost-log1.67-dev/DEBIAN/control
dpkg-deb -b /tmp/armhf/libboost-log1.67-dev/ /tmp/libboost-log1.67-dev_1.67.0-13+deb10u1_armhf.deb
mkdir -p /tmp/amd64/libboost-log1.67-dev/
dpkg-deb -x /var/cache/apt/archives/libboost-log1.67-dev_1.67.0-13+deb10u1_amd64.deb /tmp/amd64/libboost-log1.67-dev/
dpkg-deb -e /var/cache/apt/archives/libboost-log1.67-dev_1.67.0-13+deb10u1_amd64.deb /tmp/amd64/libboost-log1.67-dev/DEBIAN/
sed -i '/^Priority: optional/a Multi-Arch: same' /tmp/amd64/libboost-log1.67-dev/DEBIAN/control
dpkg-deb -b /tmp/amd64/libboost-log1.67-dev/ /tmp/libboost-log1.67-dev_1.67.0-13+deb10u1_amd64.deb
mkdir -p /tmp/armhf/libboost-log1.67.0/
dpkg-deb -x /var/cache/apt/archives/libboost-log1.67.0_1.67.0-13+deb10u1_armhf.deb /tmp/armhf/libboost-log1.67.0/
dpkg-deb -e /var/cache/apt/archives/libboost-log1.67.0_1.67.0-13+deb10u1_armhf.deb /tmp/armhf/libboost-log1.67.0/DEBIAN/
sed -i '/^Priority: optional/a Multi-Arch: same' /tmp/armhf/libboost-log1.67.0/DEBIAN/control
dpkg-deb -b /tmp/armhf/libboost-log1.67.0/ /tmp/libboost-log1.67.0_1.67.0-13+deb10u1_armhf.deb
mkdir -p /tmp/amd64/libboost-log1.67.0/
dpkg-deb -x /var/cache/apt/archives/libboost-log1.67.0_1.67.0-13+deb10u1_amd64.deb /tmp/amd64/libboost-log1.67.0/
dpkg-deb -e /var/cache/apt/archives/libboost-log1.67.0_1.67.0-13+deb10u1_amd64.deb /tmp/amd64/libboost-log1.67.0/DEBIAN/
sed -i '/^Priority: optional/a Multi-Arch: same' /tmp/amd64/libboost-log1.67.0/DEBIAN/control
dpkg-deb -b /tmp/amd64/libboost-log1.67.0/ /tmp/libboost-log1.67.0_1.67.0-13+deb10u1_amd64.deb
dpkg -i /tmp/libboost*.deb

2
buildenv/pi_binaries/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

2
buildenv/release/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -22,6 +22,8 @@
#include <f1x/openauto/autoapp/Service/IService.hpp> #include <f1x/openauto/autoapp/Service/IService.hpp>
#include <boost/asio/io_service.hpp> #include <boost/asio/io_service.hpp>
#include <aasdk/Messenger/IMessenger.hpp> #include <aasdk/Messenger/IMessenger.hpp>
#include <aasdk/Channel/WIFI/WIFIServiceChannel.hpp>
#include <aasdk/Channel/WIFI/IWIFIServiceChannelEventHandler.hpp>
namespace f1x namespace f1x
{ {
@ -32,22 +34,27 @@ namespace autoapp
namespace service namespace service
{ {
class WifiService: public IService, public std::enable_shared_from_this<WifiService> class WifiService: public aasdk::channel::wifi::IWIFIServiceChannelEventHandler, public IService, public std::enable_shared_from_this<WifiService>
{ {
public: public:
typedef std::shared_ptr<WifiService> Pointer; typedef std::shared_ptr<WifiService> Pointer;
WifiService(configuration::IConfiguration::Pointer configuration); WifiService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, configuration::IConfiguration::Pointer configuration);
void start() override; void start() override;
void stop() override; void stop() override;
void pause() override; void pause() override;
void resume() override; void resume() override;
void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override; void fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) override;
void onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest& request) override;
void onChannelError(const aasdk::error::Error& e) override;
void onWifiSecurityRequest() override;
private: private:
using std::enable_shared_from_this<WifiService>::shared_from_this; using std::enable_shared_from_this<WifiService>::shared_from_this;
configuration::IConfiguration::Pointer configuration_; configuration::IConfiguration::Pointer configuration_;
boost::asio::io_service::strand strand_;
aasdk::channel::wifi::WIFIServiceChannel::Pointer channel_;
}; };
} }

View File

@ -68,7 +68,7 @@ ServiceList ServiceFactory::create(aasdk::messenger::IMessenger::Pointer messeng
serviceList.emplace_back(this->createVideoService(messenger)); serviceList.emplace_back(this->createVideoService(messenger));
serviceList.emplace_back(this->createBluetoothService(messenger)); serviceList.emplace_back(this->createBluetoothService(messenger));
serviceList.emplace_back(this->createInputService(messenger)); serviceList.emplace_back(this->createInputService(messenger));
// serviceList.emplace_back(std::make_shared<WifiService>(configuration_)); Wifi service causes no video with AA > 12.6 serviceList.emplace_back(std::make_shared<WifiService>(ioService_, messenger, configuration_));
return serviceList; return serviceList;
} }

View File

@ -19,6 +19,7 @@
#include <f1x/openauto/Common/Log.hpp> #include <f1x/openauto/Common/Log.hpp>
#include <f1x/openauto/autoapp/Service/WifiService.hpp> #include <f1x/openauto/autoapp/Service/WifiService.hpp>
#include <fstream> #include <fstream>
#include <QNetworkInterface>
#include <QString> #include <QString>
namespace f1x namespace f1x
@ -30,26 +31,41 @@ namespace autoapp
namespace service namespace service
{ {
WifiService::WifiService(configuration::IConfiguration::Pointer configuration) WifiService::WifiService(boost::asio::io_service& ioService, aasdk::messenger::IMessenger::Pointer messenger, configuration::IConfiguration::Pointer configuration)
: configuration_(std::move(configuration)) : configuration_(std::move(configuration))
, strand_(ioService)
, channel_(std::make_shared<aasdk::channel::wifi::WIFIServiceChannel>(strand_, std::move(messenger)))
{ {
} }
void WifiService::start() void WifiService::start()
{ {
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[WifiService] start.";
channel_->receive(this->shared_from_this());
});
} }
void WifiService::stop() void WifiService::stop()
{ {
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[WifiService] stop.";
});
} }
void WifiService::pause() void WifiService::pause()
{ {
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[WifiService] pause.";
});
} }
void WifiService::resume() void WifiService::resume()
{ {
strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[WifiService] resume.";
});
} }
void WifiService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response) void WifiService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse& response)
@ -57,12 +73,47 @@ void WifiService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResponse&
OPENAUTO_LOG(info) << "[WifiService] fill features."; OPENAUTO_LOG(info) << "[WifiService] fill features.";
auto* channelDescriptor = response.add_channels(); auto* channelDescriptor = response.add_channels();
channelDescriptor->set_channel_id(14); channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto* channel = channelDescriptor->mutable_wifi_channel(); auto* channel = channelDescriptor->mutable_wifi_channel();
channel->set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString()); channel->set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString());
} }
void WifiService::onChannelOpenRequest(const aasdk::proto::messages::ChannelOpenRequest &request) {
OPENAUTO_LOG(info) << "[WifiService] open request, priority: " << request.priority();
const aasdk::proto::enums::Status::Enum status = aasdk::proto::enums::Status::OK;
OPENAUTO_LOG(info) << "[WifiService] open status: " << status;
aasdk::proto::messages::ChannelOpenResponse response;
response.set_status(status);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&WifiService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendChannelOpenResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
void WifiService::onChannelError(const aasdk::error::Error &e) {
OPENAUTO_LOG(error) << "[WifiService] channel error: " << e.what();
}
void WifiService::onWifiSecurityRequest() {
OPENAUTO_LOG(info) << "[WifiService] handle Wifi Security Request ";
aasdk::proto::messages::WifiSecurityResponse response;
response.set_access_point_type(aasdk::proto::messages::WifiSecurityResponse_AccessPointType_STATIC);
response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString());
response.set_key(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","wpa_passphrase").toStdString());
// response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString());
response.set_security_mode(aasdk::proto::messages::WifiSecurityResponse_SecurityMode_WPA2_PERSONAL);
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&WifiService::onChannelError, this->shared_from_this(), std::placeholders::_1));
channel_->sendWifiSecurityResponse(response, std::move(promise));
channel_->receive(this->shared_from_this());
}
} }
} }
} }

View File

@ -25,6 +25,7 @@
#include <aasdk/USB/AccessoryModeQueryChainFactory.hpp> #include <aasdk/USB/AccessoryModeQueryChainFactory.hpp>
#include <aasdk/USB/AccessoryModeQueryFactory.hpp> #include <aasdk/USB/AccessoryModeQueryFactory.hpp>
#include <aasdk/TCP/TCPWrapper.hpp> #include <aasdk/TCP/TCPWrapper.hpp>
#include <boost/log/utility/setup.hpp>
#include <f1x/openauto/autoapp/App.hpp> #include <f1x/openauto/autoapp/App.hpp>
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp> #include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
#include <f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp> #include <f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp>
@ -70,8 +71,25 @@ void startIOServiceWorkers(boost::asio::io_service& ioService, ThreadPool& threa
threadPool.emplace_back(ioServiceWorker); threadPool.emplace_back(ioServiceWorker);
} }
void configureLogging() {
const std::string logIni = "openauto-logs.ini";
std::ifstream logSettings(logIni);
if (logSettings.good()) {
try {
// For boost < 1.71 the severity types are not automatically parsed so lets register them.
boost::log::register_simple_filter_factory<boost::log::trivial::severity_level>("Severity");
boost::log::register_simple_formatter_factory<boost::log::trivial::severity_level, char>("Severity");
boost::log::init_from_stream(logSettings);
} catch (std::exception const & e) {
OPENAUTO_LOG(warning) << "[OpenAuto] " << logIni << " was provided but was not valid.";
}
}
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
configureLogging();
libusb_context* usbContext; libusb_context* usbContext;
if(libusb_init(&usbContext) != 0) if(libusb_init(&usbContext) != 0)
{ {

View File

@ -135,13 +135,13 @@ namespace f1x {
} }
void AndroidBluetoothServer::handleWifiSecurityRequest(QByteArray &buffer, uint16_t length) { void AndroidBluetoothServer::handleWifiSecurityRequest(QByteArray &buffer, uint16_t length) {
::aasdk::proto::messages::WifiSecurityReponse response; ::aasdk::proto::messages::WifiSecurityResponse response;
response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString()); response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString());
response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString()); // response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString());
response.set_key(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","wpa_passphrase").toStdString()); response.set_key(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","wpa_passphrase").toStdString());
response.set_security_mode(::aasdk::proto::messages::WifiSecurityReponse_SecurityMode_WPA2_PERSONAL); response.set_security_mode(::aasdk::proto::messages::WifiSecurityResponse_SecurityMode_WPA2_PERSONAL);
response.set_access_point_type(::aasdk::proto::messages::WifiSecurityReponse_AccessPointType_STATIC); response.set_access_point_type(::aasdk::proto::messages::WifiSecurityResponse_AccessPointType_STATIC);
sendMessage(response, 3); sendMessage(response, 3);
} }