From 8aadb9731035fbc4a13d85b72ed4a3cd3d8cdb9a Mon Sep 17 00:00:00 2001 From: egisz Date: Mon, 30 Aug 2021 21:54:36 +0300 Subject: [PATCH] switch to TV input on AA reconnect or rear gear, inject false can frames --- bmw_f10_idrive.cpp | 72 +++++++++++++++++++++++++++++++++++++++------- bmw_f10_idrive.hpp | 6 ++++ 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/bmw_f10_idrive.cpp b/bmw_f10_idrive.cpp index ab91e53..386c18b 100644 --- a/bmw_f10_idrive.cpp +++ b/bmw_f10_idrive.cpp @@ -1,14 +1,40 @@ + + #include "bmw_f10_idrive.hpp" +// QString BmwF10::toDebug(const QByteArray & line) { + +// QString s; +// uchar c; + +// for ( int i=0 ; i < line.size() ; i++ ){ +// c = line[i]; +// if ( c >= 0x20 and c <= 126 ) { +// s.append(c); +// } else { +// s.append(QString("<%1>").arg(c, 2, 16, QChar('0'))); +// } +// } +// return s; +// } + bool BmwF10::init(ICANBus* canbus){ if (this->arbiter) { this->debug = new DebugWindow(*this->arbiter); F10_LOG(info)<<"loading plugin..."; + this->canbus = canbus; canbus->registerFrameHandler(0x264, [this](QByteArray payload){this->monitorIdriveRotaryStatus(payload);}); canbus->registerFrameHandler(0x267, [this](QByteArray payload){this->monitorIdriveButtonStatus(payload);}); canbus->registerFrameHandler(0x21A, [this](QByteArray payload){this->monitorGearStatus(payload);}); - canbus->registerFrameHandler(0x0A5, [this](QByteArray payload){this->monitorEngineRPM(payload);}); canbus->registerFrameHandler(0x1A1, [this](QByteArray payload){this->monitorVehicleSpeed(payload);}); + canbus->registerFrameHandler(0x0A5, [this](QByteArray payload){this->monitorEngineRPM(payload);}); + canbus->registerFrameHandler(0x273, [this](QByteArray payload){this->monitorCicStatus(payload);}); + + // Switch to TV screen on connect. + auto *oaPage = this->arbiter->layout().openauto_page; + connect(oaPage, &OpenAutoPage::connected, this, [this](bool connected){ + this->switchTVInput(); + }); F10_LOG(info)<<"loaded successfully"; return true; } @@ -50,17 +76,26 @@ void BmwF10::monitorIdriveRotaryStatus(QByteArray payload){ // Idrive buttons // and message.data[0] == 0xE1 and message.data[1] == 0x0FD and message.data[2] > c2): void BmwF10::monitorIdriveButtonStatus(QByteArray payload){ - if(payload.at(0) == 0xE1 && payload.at(1) == 0xFD && payload.at(2) > this->msgCounter) { - if(payload.at(3) == 0x00 && (payload.at(4) == 0xDD || payload.at(4) == 0xDE) && this->lastKey != aasdk::proto::enums::ButtonCode::NONE){ + // unsigned char j = 0xE1; + // F10_LOG(info)<<"got 0x267 frame: "<< QString::number(j, 16).toStdString(); + // qDebug() << "Value : " << hex << j; + + if(this->cic_fullscreen && payload.at(2) > this->msgCounter && + payload.at(0) == 0xE1 && payload.at(1) == 0xFD && + (payload.at(4) == 0xDD || payload.at(4) == 0xDE)) { + if(payload.at(3) == 0x00 && this->lastKey != aasdk::proto::enums::ButtonCode::NONE){ // Release + F10_LOG(info)<<"Idrive button release"; this->arbiter->send_openauto_button_press(this->lastKey); this->lastKey = aasdk::proto::enums::ButtonCode::NONE; } else if(payload.at(3) == 0x01 && payload.at(4) == 0xDE){ // Enter + F10_LOG(info)<<"Enter"; this->lastKey = aasdk::proto::enums::ButtonCode::ENTER; this->debug->lastKey->setText(QString("Enter")); } else if(payload.at(3) == 0x11 && payload.at(4) == 0xDD){ // UP + F10_LOG(info)<<"Idrive button UP"; this->lastKey = aasdk::proto::enums::ButtonCode::UP; this->debug->lastKey->setText(QString("Up")); } else if(payload.at(3) == 0x12 && payload.at(4) == 0xDD){ @@ -69,6 +104,7 @@ void BmwF10::monitorIdriveButtonStatus(QByteArray payload){ this->debug->lastKey->setText(QString("Up Hold >> Back")); } else if(payload.at(3) == 0x41 && payload.at(4) == 0xDD){ // DOWN + F10_LOG(info)<<"Idrive button Down"; this->lastKey = aasdk::proto::enums::ButtonCode::DOWN; this->debug->lastKey->setText(QString("Down")); } else if(payload.at(3) == 0x42 && payload.at(4) == 0xDD){ @@ -76,38 +112,52 @@ void BmwF10::monitorIdriveButtonStatus(QByteArray payload){ this->lastKey = aasdk::proto::enums::ButtonCode::HOME; this->debug->lastKey->setText(QString("Down Hold >> HOME")); } - // this->debug->msgCounter->setText(QString::number(this->msgCounter)); + payload[3] = (uint) 0xFF; + payload[4] = (uint) 0xDD; + this->canbus->writeFrame(QCanBusFrame(0x267, payload)); } + this->msgCounter = payload.at(2); } void BmwF10::monitorGearStatus(QByteArray payload){ if(payload.at(1)%2 == 1 && !this->inReverse){ F10_LOG(info)<<"Reverse Gear"; + this->switchTVInput(); this->debug->inReverse->setText(QString("Yes")); this->inReverse = true; - this->arbiter->send_openauto_full_screen(false); this->arbiter->set_curr_page(3); } else if(payload.at(1)%2 == 0 && this->inReverse){ F10_LOG(info)<<"Not reverse"; this->debug->inReverse->setText(QString("No")); this->inReverse = false; this->arbiter->set_curr_page(0); - this->arbiter->send_openauto_full_screen(); } } void BmwF10::monitorEngineRPM(QByteArray payload){ int rpm = ((256.0 * (int)payload.at(6)) + (int)payload.at(5)) / 4.0; - // F10_LOG(info)<<"RPM: "<debug->rpm->setText(QString::number(rpm)); - this->arbiter->vehicle_update_data("rpm", rpm); + // this->arbiter->vehicle_update_data("rpm", rpm); } void BmwF10::monitorVehicleSpeed(QByteArray payload){ int speed = ((256.0 * (int)payload.at(3)) + (int)payload.at(2)) * 1.609344 / 100.0; - // F10_LOG(info)<<"Speed: "<debug->speed->setText(QString::number(speed)); - this->arbiter->vehicle_update_data("speed", speed); + F10_LOG(info)<<"Speed: "<arbiter->vehicle_update_data("speed", speed); +} + +void BmwF10::monitorCicStatus(QByteArray payload){ + this->cic_fullscreen = payload.at(0) == 0x5D; + F10_LOG(info)<<"CIC fullscreen: "<cic_fullscreen; +} + +void BmwF10::switchTVInput(){ + if (!this->cic_fullscreen) { + F10_LOG(info)<<"Switch to TV source"; + this->canbus->writeFrame(QCanBusFrame(0x0A2, QByteArray::fromHex("0080"))); + this->canbus->writeFrame(QCanBusFrame(0x0A2, QByteArray::fromHex("0000"))); + } } DebugWindow::DebugWindow(Arbiter &arbiter, QWidget *parent) : QWidget(parent) diff --git a/bmw_f10_idrive.hpp b/bmw_f10_idrive.hpp index c4d4c8f..76229be 100644 --- a/bmw_f10_idrive.hpp +++ b/bmw_f10_idrive.hpp @@ -35,6 +35,8 @@ class BmwF10 : public QObject, VehiclePlugin private: QList widgets() override; + ICANBus* canbus; + bool cic_fullscreen = false; bool inReverse = false; int rotaryPrevPos = -1; int rotaryPos = -1; @@ -46,6 +48,10 @@ class BmwF10 : public QObject, VehiclePlugin void monitorGearStatus(QByteArray payload); void monitorEngineRPM(QByteArray payload); void monitorVehicleSpeed(QByteArray payload); + void monitorCicStatus(QByteArray payload); + void injectFrame(QByteArray payload); + void switchTVInput(); + // QString toDebug(const QByteArray & line); DebugWindow *debug; };