Przeglądaj źródła

[FL-1513] Fix IRDA crash (#557)

Albert Kharisov 4 lat temu
rodzic
commit
df9a6673da

+ 16 - 6
applications/irda/irda-app-transceiver.cpp

@@ -9,7 +9,6 @@ void IrdaAppSignalTransceiver::irda_rx_callback(void* ctx, bool level, uint32_t
 
 
     irda_message = irda_decode(this_->decoder, level, duration);
     irda_message = irda_decode(this_->decoder, level, duration);
     if(irda_message) {
     if(irda_message) {
-        this_->capture_stop();
         this_->message = *irda_message;
         this_->message = *irda_message;
         event.type = IrdaAppEvent::Type::IrdaMessageReceived;
         event.type = IrdaAppEvent::Type::IrdaMessageReceived;
         osStatus_t result = osMessageQueuePut(this_->event_queue, &event, 0, 0);
         osStatus_t result = osMessageQueuePut(this_->event_queue, &event, 0, 0);
@@ -18,23 +17,34 @@ void IrdaAppSignalTransceiver::irda_rx_callback(void* ctx, bool level, uint32_t
 }
 }
 
 
 IrdaAppSignalTransceiver::IrdaAppSignalTransceiver(void)
 IrdaAppSignalTransceiver::IrdaAppSignalTransceiver(void)
-    : decoder(irda_alloc_decoder()) {
+    : capture_started(false)
+    , decoder(irda_alloc_decoder()) {
 }
 }
 
 
 IrdaAppSignalTransceiver::~IrdaAppSignalTransceiver() {
 IrdaAppSignalTransceiver::~IrdaAppSignalTransceiver() {
-    api_hal_irda_rx_irq_deinit();
+    capture_stop();
     irda_free_decoder(decoder);
     irda_free_decoder(decoder);
 }
 }
 
 
 void IrdaAppSignalTransceiver::capture_once_start(osMessageQueueId_t queue) {
 void IrdaAppSignalTransceiver::capture_once_start(osMessageQueueId_t queue) {
     event_queue = queue;
     event_queue = queue;
     irda_reset_decoder(decoder);
     irda_reset_decoder(decoder);
-    api_hal_irda_rx_irq_init();
-    api_hal_irda_rx_irq_set_callback(IrdaAppSignalTransceiver::irda_rx_callback, this);
+    if(!capture_started) {
+        capture_started = true;
+        api_hal_irda_rx_irq_set_callback(IrdaAppSignalTransceiver::irda_rx_callback, this);
+        api_hal_irda_rx_irq_init();
+    }
 }
 }
 
 
 void IrdaAppSignalTransceiver::capture_stop(void) {
 void IrdaAppSignalTransceiver::capture_stop(void) {
-    api_hal_irda_rx_irq_deinit();
+    IrdaAppEvent event;
+
+    if(capture_started) {
+        capture_started = false;
+        api_hal_irda_rx_irq_deinit();
+        while(osMessageQueueGet(this->event_queue, &event, 0, 0) == osOK)
+            ;
+    }
 }
 }
 
 
 IrdaMessage* IrdaAppSignalTransceiver::get_last_message(void) {
 IrdaMessage* IrdaAppSignalTransceiver::get_last_message(void) {

+ 1 - 0
applications/irda/irda-app-transceiver.hpp

@@ -12,6 +12,7 @@ public:
     void send_message(const IrdaMessage* message) const;
     void send_message(const IrdaMessage* message) const;
 
 
 private:
 private:
+    bool capture_started;
     osMessageQueueId_t event_queue;
     osMessageQueueId_t event_queue;
     static void irda_rx_callback(void* ctx, bool level, uint32_t duration);
     static void irda_rx_callback(void* ctx, bool level, uint32_t duration);
     IrdaHandler* decoder;
     IrdaHandler* decoder;

+ 2 - 0
applications/irda/scene/irda-app-scene-learn.cpp

@@ -37,4 +37,6 @@ bool IrdaAppSceneLearn::on_event(IrdaApp* app, IrdaAppEvent* event) {
 }
 }
 
 
 void IrdaAppSceneLearn::on_exit(IrdaApp* app) {
 void IrdaAppSceneLearn::on_exit(IrdaApp* app) {
+    auto transceiver = app->get_transceiver();
+    transceiver->capture_stop();
 }
 }

+ 0 - 1
lib/irda/irda_common_decoder.c

@@ -95,7 +95,6 @@ IrdaMessage* irda_common_decode(IrdaCommonDecoder* decoder, bool level, uint32_t
     DecodeStatus status = DecodeStatusError;
     DecodeStatus status = DecodeStatusError;
 
 
     if (decoder->level == level) {
     if (decoder->level == level) {
-        furi_assert(0);
         decoder->timings_cnt = 0;
         decoder->timings_cnt = 0;
     }
     }
     decoder->level = level;   // start with high level (Space timing)
     decoder->level = level;   // start with high level (Space timing)