hostintf: make sure block counters are not adjusted in case of failure

Bug: 30325656
Change-Id: If109b3e45b9ff2ffaf9d6b96746bd3e6adaf69fb
Signed-off-by: Alexey Polyudov <apolyudov@google.com>
diff --git a/firmware/os/core/hostIntf.c b/firmware/os/core/hostIntf.c
index 4311f10..5be88fe 100644
--- a/firmware/os/core/hostIntf.c
+++ b/firmware/os/core/hostIntf.c
@@ -542,6 +542,17 @@
     mBusy = busy;
 }
 
+static inline struct ActiveSensor *getActiveSensorByType(uint32_t sensorType)
+{
+    struct ActiveSensor *sensor = NULL;
+
+    if (sensorType > SENS_TYPE_INVALID && sensorType <= SENS_TYPE_LAST_USER &&
+        mSensorList[sensorType - 1] < MAX_REGISTERED_SENSORS)
+        sensor = mActiveSensorTable + mSensorList[sensorType - 1];
+
+    return sensor;
+}
+
 bool hostIntfPacketDequeue(void *data, uint32_t *wakeup, uint32_t *nonwakeup)
 {
     struct HostIntfDataBuffer *buffer = data;
@@ -551,8 +562,9 @@
 
     ret = simpleQueueDequeue(mOutputQ, data);
     while (ret) {
-        if (buffer->sensType > SENS_TYPE_INVALID && buffer->sensType <= SENS_TYPE_LAST_USER && mSensorList[buffer->sensType - 1] < MAX_REGISTERED_SENSORS) {
-            sensor = mActiveSensorTable + mSensorList[buffer->sensType - 1];
+        sensor = getActiveSensorByType(buffer->sensType);
+        if (sensor) {
+            // do not sent sensor data if sensor is not requested; only maintain stats
             if (sensor->sensorHandle == 0 && !buffer->firstSample.biasPresent && !buffer->firstSample.numFlushes) {
                 if (sensor->interrupt == NANOHUB_INT_WAKEUP)
                     mWakeupBlocks--;
@@ -583,8 +595,8 @@
     }
 
     if (ret) {
-        if (buffer->sensType > SENS_TYPE_INVALID && buffer->sensType <= SENS_TYPE_LAST_USER && mSensorList[buffer->sensType - 1] < MAX_REGISTERED_SENSORS) {
-            sensor = mActiveSensorTable + mSensorList[buffer->sensType - 1];
+        sensor = getActiveSensorByType(buffer->sensType);
+        if (sensor) {
             if (sensor->interrupt == NANOHUB_INT_WAKEUP)
                 mWakeupBlocks--;
             else if (sensor->interrupt == NANOHUB_INT_NONWAKEUP)
@@ -613,11 +625,9 @@
 static bool queueDiscard(void *data, bool onDelete)
 {
     struct HostIntfDataBuffer *buffer = data;
-    struct ActiveSensor *sensor;
+    struct ActiveSensor *sensor = getActiveSensorByType(buffer->sensType);
 
-    if (buffer->sensType > SENS_TYPE_INVALID && buffer->sensType <= SENS_TYPE_LAST_USER && mSensorList[buffer->sensType - 1] < MAX_REGISTERED_SENSORS) { // data
-        sensor = mActiveSensorTable + mSensorList[buffer->sensType - 1];
-
+    if (sensor) {
         if (sensor->curSamples - buffer->firstSample.numSamples >= sensor->minSamples || onDelete) {
             if (sensor->interrupt == NANOHUB_INT_WAKEUP)
                 mWakeupBlocks--;
@@ -798,17 +808,32 @@
     return deltaTime;
 }
 
+static bool enqueueSensorBuffer(struct ActiveSensor *sensor)
+{
+    bool queued = simpleQueueEnqueue(mOutputQ, &sensor->buffer,
+                                     sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
+
+    if (!queued) {
+        // undo counters if failed to add buffer
+        if (sensor->interrupt == NANOHUB_INT_WAKEUP)
+            mWakeupBlocks--;
+        else if (sensor->interrupt == NANOHUB_INT_NONWAKEUP)
+            mNonWakeupBlocks--;
+    }
+    resetBuffer(sensor);
+    return queued;
+}
+
 static void copySingleSamples(struct ActiveSensor *sensor, const struct SingleAxisDataEvent *single)
 {
     int i;
     uint32_t deltaTime;
     uint8_t numSamples;
+    uint8_t evtNumSamples = single->samples[0].firstSample.numSamples;
 
-    for (i = 0; i < single->samples[0].firstSample.numSamples; i++) {
-        if (sensor->buffer.firstSample.numSamples == sensor->packetSamples) {
-            simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-            resetBuffer(sensor);
-        }
+    for (i = 0; i < evtNumSamples; i++) {
+        if (sensor->buffer.firstSample.numSamples == sensor->packetSamples)
+            enqueueSensorBuffer(sensor);
 
         if (sensor->buffer.firstSample.numSamples == 0) {
             if (i == 0) {
@@ -831,12 +856,10 @@
             if (i == 0) {
                 if (sensor->lastTime > single->referenceTime) {
                     // shouldn't happen. flush current packet
-                    simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                    resetBuffer(sensor);
+                    enqueueSensorBuffer(sensor);
                     i--;
                 } else if (single->referenceTime - sensor->lastTime >= delta_time_max) {
-                    simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                    resetBuffer(sensor);
+                    enqueueSensorBuffer(sensor);
                     i--;
                 } else {
                     deltaTime = encodeDeltaTime(single->referenceTime - sensor->lastTime);
@@ -871,10 +894,8 @@
     uint8_t numSamples;
 
     for (i = 0; i < triple->samples[0].firstSample.numSamples; i++) {
-        if (sensor->buffer.firstSample.numSamples == sensor->packetSamples) {
-            simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-            resetBuffer(sensor);
-        }
+        if (sensor->buffer.firstSample.numSamples == sensor->packetSamples)
+            enqueueSensorBuffer(sensor);
 
         if (sensor->buffer.firstSample.numSamples == 0) {
             if (i == 0) {
@@ -905,12 +926,10 @@
             if (i == 0) {
                 if (sensor->lastTime > triple->referenceTime) {
                     // shouldn't happen. flush current packet
-                    simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                    resetBuffer(sensor);
+                    enqueueSensorBuffer(sensor);
                     i--;
                 } else if (triple->referenceTime - sensor->lastTime >= delta_time_max) {
-                    simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                    resetBuffer(sensor);
+                    enqueueSensorBuffer(sensor);
                     i--;
                 } else {
                     deltaTime = encodeDeltaTime(triple->referenceTime - sensor->lastTime);
@@ -963,16 +982,12 @@
     } else {
         // Bias needs to be sent with a different sensType, so enqueue any pending buffer, enqueue
         // bias with a different sensor type, then restore the sensType
-        if (sensor->buffer.firstSample.numSamples > 0) {
-            simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-            resetBuffer(sensor);
-        }
+        if (sensor->buffer.firstSample.numSamples > 0)
+            enqueueSensorBuffer(sensor);
         sensor->buffer.sensType = sensor->biasReportType;
         copyTripleSamples(sensor, triple);
-        if (sensor->buffer.firstSample.numSamples > 0) {
-            simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-            resetBuffer(sensor);
-        }
+        if (sensor->buffer.firstSample.numSamples > 0)
+            enqueueSensorBuffer(sensor);
         sensor->buffer.sensType = sensType;
     }
 }
@@ -991,10 +1006,8 @@
     }
 
     for (i = 0; i < triple->samples[0].firstSample.numSamples; i++) {
-        if (sensor->buffer.firstSample.numSamples == sensor->packetSamples) {
-            simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-            resetBuffer(sensor);
-        }
+        if (sensor->buffer.firstSample.numSamples == sensor->packetSamples)
+            enqueueSensorBuffer(sensor);
 
         if (sensor->buffer.firstSample.numSamples == 0) {
             if (i == 0) {
@@ -1019,12 +1032,10 @@
             if (i == 0) {
                 if (sensor->lastTime > triple->referenceTime) {
                     // shouldn't happen. flush current packet
-                    simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                    resetBuffer(sensor);
+                    enqueueSensorBuffer(sensor);
                     i--;
                 } else if (triple->referenceTime - sensor->lastTime >= delta_time_max) {
-                    simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                    resetBuffer(sensor);
+                    enqueueSensorBuffer(sensor);
                     i--;
                 } else {
                     deltaTime = encodeDeltaTime(triple->referenceTime - sensor->lastTime);
@@ -1056,8 +1067,11 @@
     }
 }
 
-static void hostIntfAddBlock(struct HostIntfDataBuffer *data)
+static void hostIntfAddBlock(struct HostIntfDataBuffer *data, bool discardable)
 {
+    if (!simpleQueueEnqueue(mOutputQ, data, sizeof(uint32_t) + data->length, discardable))
+        return;
+
     if (data->interrupt == NANOHUB_INT_WAKEUP)
         mWakeupBlocks++;
     else if (data->interrupt == NANOHUB_INT_NONWAKEUP)
@@ -1108,8 +1122,10 @@
     buffer->sensType = cmd->sensType;
     buffer->length = sizeof(buffer->referenceTime) + sizeof(struct SensorFirstSample);
     buffer->interrupt = NANOHUB_INT_WAKEUP;
+    mWakeupBlocks++;
     buffer->firstSample.numFlushes = 1;
-    simpleQueueEnqueue(mOutputQ, buffer, size, false);
+    if (!simpleQueueEnqueue(mOutputQ, buffer, size, false))
+        mWakeupBlocks--;
 }
 
 static void onEvtAppStart(const void *evtData)
@@ -1132,8 +1148,7 @@
         data->dataType = HOSTINTF_DATA_TYPE_RESET_REASON;
         data->interrupt = NANOHUB_INT_WAKEUP;
         memcpy(data->buffer, &reason, sizeof(reason));
-        simpleQueueEnqueue(mOutputQ, data, sizeof(uint32_t) + data->length, false);
-        hostIntfAddBlock(data);
+        hostIntfAddBlock(data, false);
         hostIntfNotifyReboot(reason);
     }
 }
@@ -1150,8 +1165,7 @@
         data->dataType = HOSTINTF_DATA_TYPE_APP_TO_HOST;
         data->interrupt = NANOHUB_INT_WAKEUP;
         memcpy(data->buffer, evtData, data->length);
-        simpleQueueEnqueue(mOutputQ, data, sizeof(uint32_t) + data->length, false);
-        hostIntfAddBlock(data);
+        hostIntfAddBlock(data, false);
     }
 }
 
@@ -1168,10 +1182,8 @@
 {
     struct HostIntfDataBuffer *data = (struct HostIntfDataBuffer *)evtData;
 
-    if (data->sensType == SENS_TYPE_INVALID && data->dataType == HOSTINTF_DATA_TYPE_LOG) {
-        simpleQueueEnqueue(mOutputQ, evtData, sizeof(uint32_t) + data->length, true);
-        hostIntfAddBlock(data);
-    }
+    if (data->sensType == SENS_TYPE_INVALID && data->dataType == HOSTINTF_DATA_TYPE_LOG)
+        hostIntfAddBlock(data, true);
 }
 #endif
 
@@ -1255,9 +1267,8 @@
     sensor->oneshot = false;
     sensor->sensorHandle = 0;
     if (sensor->buffer.length) {
-        simpleQueueEnqueue(mOutputQ, &sensor->buffer, sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
+        enqueueSensorBuffer(sensor);
         hostIntfSetInterrupt(sensor->interrupt);
-        resetBuffer(sensor);
     }
 }
 
@@ -1285,11 +1296,8 @@
 static void onEvtNoSensorConfigEvent(const void *evtData)
 {
     struct ConfigCmd *cmd = (struct ConfigCmd *)evtData;
-
-    if (cmd->sensType > SENS_TYPE_INVALID && cmd->sensType <= SENS_TYPE_LAST_USER &&
-        mSensorList[cmd->sensType - 1] < MAX_REGISTERED_SENSORS) {
-        struct ActiveSensor *sensor = mActiveSensorTable + mSensorList[cmd->sensType - 1];
-
+    struct ActiveSensor *sensor = getActiveSensorByType(cmd->sensType);
+    if (sensor) {
         if (sensor->sensorHandle) {
             switch (cmd->cmd) {
             case CONFIG_CMD_FLUSH:
@@ -1331,11 +1339,10 @@
 static void copyEmbeddedSamples(struct ActiveSensor *sensor, const void* evtData)
 {
     uint64_t sensorTime = sensorGetTime();
-    if (sensor->buffer.length > 0 && sensorTime - sensor->lastTime >= delta_time_max) {
-        simpleQueueEnqueue(mOutputQ, &sensor->buffer,
-                           sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-        resetBuffer(sensor);
-    }
+
+    if (sensor->buffer.length > 0 && sensorTime - sensor->lastTime >= delta_time_max)
+        enqueueSensorBuffer(sensor);
+
     if (sensor->buffer.length == 0) {
         sensor->buffer.length = sizeof(struct SingleAxisDataEvent) + sizeof(struct SingleAxisDataPoint);
         sensor->lastTime = sensor->buffer.referenceTime = sensorTime;
@@ -1380,18 +1387,13 @@
     if (evtData == SENSOR_DATA_EVENT_FLUSH) {
         queueFlush(sensor);
     } else {
-        if (sensor->buffer.length > 0) {
-            if (sensor->buffer.firstSample.numFlushes > 0) {
-                if (!(simpleQueueEnqueue(mOutputQ, &sensor->buffer,
-                                         sizeof(uint32_t) + sensor->buffer.length, sensor->discard)))
-                    return; // flushes more important than samples
-                else
-                    resetBuffer(sensor);
-            } else if (sensor->buffer.firstSample.numSamples == sensor->packetSamples) {
-                simpleQueueEnqueue(mOutputQ, &sensor->buffer,
-                                   sizeof(uint32_t) + sensor->buffer.length, sensor->discard);
-                resetBuffer(sensor);
-            }
+        bool haveFlush = sensor->buffer.firstSample.numFlushes > 0;
+        if (sensor->buffer.length > 0 &&
+            (haveFlush || sensor->buffer.firstSample.numSamples == sensor->packetSamples)) {
+                // processing will be aborted if we have pending flush and are not able to send
+                // in this case, send eventually will be retried, otherwise data will be lost
+                if (!enqueueSensorBuffer(sensor) && haveFlush)
+                    return;
         }
 
         switch (sensor->numAxis) {
@@ -1440,14 +1442,14 @@
 
 static void onEvtSensorData(uint32_t evtType, const void* evtData)
 {
-    if (evtType > EVT_NO_FIRST_SENSOR_EVENT && evtType < EVT_NO_SENSOR_CONFIG_EVENT &&
-        mSensorList[(evtType & 0xFF)-1] < MAX_REGISTERED_SENSORS) { // data
-        struct ActiveSensor *sensor = mActiveSensorTable + mSensorList[(evtType & 0xFF) - 1];
-
-        if (sensor->sensorHandle)
-            onEvtSensorDataActive(sensor, evtType, evtData);
-        else
-            onEvtSensorDataInactive(sensor, evtType, evtData);
+    if (evtType > EVT_NO_FIRST_SENSOR_EVENT && evtType < EVT_NO_SENSOR_CONFIG_EVENT) {
+        struct ActiveSensor *sensor = getActiveSensorByType(evtType & 0xFF);
+        if (sensor) {
+            if (sensor->sensorHandle)
+                onEvtSensorDataActive(sensor, evtType, evtData);
+            else
+                onEvtSensorDataInactive(sensor, evtType, evtData);
+        }
     }
 }