changeset 785:3ff074ba25f1

updates to mqtt message API; much more consistent logging
author drewp@bigasterisk.com
date Fri, 28 Aug 2020 01:39:08 -0700
parents 415d7853ad45
children e8654a3bd1c7
files espNode/desk/src/fingerprint.cpp espNode/desk/src/main.cpp espNode/desk/src/mqtt.cpp
diffstat 3 files changed, 158 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/espNode/desk/src/fingerprint.cpp	Thu Aug 27 23:54:11 2020 -0700
+++ b/espNode/desk/src/fingerprint.cpp	Fri Aug 28 01:39:08 2020 -0700
@@ -57,7 +57,36 @@
   }
 }
 
-void PublishError(std::string caller, int16_t p) {
+bool NeedToGetBackToMainLoopSoon() {
+  return mqtt::HasPendingMessage() || queued;
+}
+
+void LogStatus(const std::string& log_mode, const std::string& msg) {
+  mqtt::Publish(log_mode + "/status", msg);
+}
+void LogError(const std::string& log_mode, const std::string& caller,
+              const std::string& err) {
+  mqtt::Publish(log_mode + "/error/" + caller, err);
+}
+void LogStore(const std::string& msg) { mqtt::Publish("store", msg); }
+void LogDetect(const std::string& msg) { mqtt::Publish("detected", msg); }
+
+void PublishModel(uint16_t fid, char* model, size_t model_len) {
+  std::string msg(model, model_len);
+  char subtopic[50];
+  snprintf(subtopic, sizeof(subtopic), "model/%d", fid);
+  mqtt::Publish(subtopic, msg);
+}
+
+void PublishImage(char* image_data, size_t image_len) {
+  std::string msg(image_data, image_len);
+  char subtopic[50];
+  snprintf(subtopic, sizeof(subtopic), "image/%d", -1);
+  mqtt::Publish(subtopic, msg);
+}
+
+void LogFpmError(const std::string& log_mode, const std::string& caller,
+                 int16_t p) {
   std::string errStr;
   switch (p) {
     case FPM_FEATUREFAIL:
@@ -105,60 +134,61 @@
       errStr = buf;
       break;
   }
-  mqtt::Publish("messages", caller + ": " + errStr);
+  LogError(log_mode, caller, errStr);
 }
 
-bool GetImage() {
+bool GetImage(const std::string& log_mode) {
   int16_t p = -1;
-  mqtt::Publish("messages", "Waiting for valid finger");
+  LogStatus(log_mode, "Waiting for valid finger");
 
   while (p != FPM_OK) {
     p = finger.getImage();
 
     if (p == FPM_OK) {
-      mqtt::Publish("messages", "getImage: Image taken");
+      LogStatus(log_mode, "Image taken");
     } else if (p == FPM_NOFINGER) {
-      if (mqtt::HasPendingMessage() || queued) {
+      if (NeedToGetBackToMainLoopSoon()) {
         return false;
       }
     } else {
-      PublishError("getImage", p);
+      LogFpmError(log_mode, "getImage", p);
       return false;
     }
     yield();
   }
-  mqtt::Publish("messages", "getImage: got image");
+  LogStatus(log_mode, "Got image");
 
   BlinkProgress();
   return true;
 }
 
-bool ConvertImage(uint8_t slot = 1) {
+bool ConvertImage(const std::string& log_mode, uint8_t slot = 1) {
   int16_t p = -1;
   p = finger.image2Tz(slot);
   if (p == FPM_OK) {
-    mqtt::Publish("messages", "image2Tz: Image converted");
+    LogStatus(log_mode, "Image converted");
   } else {
-    PublishError("image2Tz", p);
+    LogFpmError(log_mode, "image2Tz", p);
     return false;
   }
   return true;
 }
 
-bool SearchDatabase(uint16_t* fid, uint16_t* score) {
+bool SearchDatabase(const std::string& log_mode, uint16_t* fid,
+                    uint16_t* score) {
   int16_t p = -1;
   p = finger.searchDatabase(fid, score);
 
   /* now wait to remove the finger, though not necessary;
      this was moved here after the search because of the R503 sensor,
      which seems to wipe its buffers after each scan */
-  mqtt::Publish("messages", "Waiting for finger removal");
+  LogStatus(log_mode, "Waiting for finger removal");
   while (finger.getImage() != FPM_NOFINGER) {
     delay(500);
   }
 
   if (p != FPM_OK) {
-    PublishError("searchDatabase", p);
+    LogFpmError(log_mode, "searchDatabase", p);
 
     if (p == FPM_NOTFOUND) {
       BlinkError();
@@ -170,51 +200,52 @@
 
 void ReportFoundMatch(uint16_t fid, uint16_t score) {
   char msg[100];
-  snprintf(msg, sizeof(msg), "found id %d confidence %d", fid, score);
-  mqtt::Publish("match", msg);
+  snprintf(msg, sizeof(msg), "Found id %d confidence %d", fid, score);
+  LogDetect(msg);
 }
 
 void ScanLoop() {
-  if (!GetImage()) {
+  const std::string& log_mode = "scan";
+  if (!GetImage(log_mode)) {
     return;
   }
 
-  if (!ConvertImage()) {
+  if (!ConvertImage(log_mode)) {
     return;
   }
 
   uint16_t fid, score;
-  if (!SearchDatabase(&fid, &score)) {
+  if (!SearchDatabase(log_mode, &fid, &score)) {
     return;
   }
 
   ReportFoundMatch(fid, score);
 }
 
-bool get_free_id(int16_t* fid) {
+bool get_free_id(const std::string& log_mode, int16_t* fid) {
   int16_t p = -1;
   for (int page = 0; page < (params.capacity / FPM_TEMPLATES_PER_PAGE) + 1;
        page++) {
     p = finger.getFreeIndex(page, fid);
     if (p != FPM_OK) {
-      PublishError("getFreeIndex", p);
+      LogFpmError(log_mode, "getFreeIndex", p);
       return false;
     }
     if (*fid != FPM_NOFREEINDEX) {
       char buf[100];
-      snprintf(buf, sizeof(buf), "getFreeIndex: Free slot at id %d", *fid);
-      mqtt::Publish("messages", buf);
+      snprintf(buf, sizeof(buf), "Free slot at id %d", *fid);
+      LogStatus(log_mode, buf);
       return true;
     }
     yield();
   }
-  mqtt::Publish("messages", "getFreeIndex: No free slots");
+  LogStatus(log_mode, "getFreeIndex: No free slots");
   return false;
 }
 
-void WaitForRemove() {
+void WaitForRemove(const std::string& log_mode) {
   int16_t p = -1;
-  mqtt::Publish("messages", "Remove finger");
+  LogStatus(log_mode, "Remove finger");
   delay(2000);
   p = 0;
   while (p != FPM_NOFINGER) {
@@ -223,74 +254,73 @@
   }
 }
 
-void EnrollFailed() {
-  mqtt::Publish("messages", "mode=enroll; exiting enroll");
+void EnrollFailed(const std::string& log_mode) {
+  LogStatus(log_mode, "Exiting enroll");
   BlinkError();
-  WaitForRemove();
+  WaitForRemove(log_mode);
 }
 
-void enroll_finger(int16_t fid) {
+void enroll_finger(const std::string& log_mode, int16_t fid) {
   int16_t p = -1;
-  mqtt::Publish("messages", "mode=enroll; Waiting for valid finger to enroll");
+  LogStatus(log_mode, "Waiting for valid finger to enroll");
   BlinkStartEnroll();
-  if (!GetImage()) {
-    return EnrollFailed();
+  if (!GetImage(log_mode)) {
+    return EnrollFailed(log_mode);
   }
 
-  if (!ConvertImage(1)) {
-    return EnrollFailed();
+  if (!ConvertImage(log_mode, 1)) {
+    return EnrollFailed(log_mode);
   }
 
-  WaitForRemove();
+  WaitForRemove(log_mode);
 
   BlinkStartEnrollRepeat();
-  mqtt::Publish("messages", "mode=enroll; Place same finger again");
-  if (!GetImage()) {
-    return EnrollFailed();
+  LogStatus(log_mode, "Place same finger again");
+  if (!GetImage(log_mode)) {
+    return EnrollFailed(log_mode);
   }
-  if (!ConvertImage(2)) {
-    return EnrollFailed();
+  if (!ConvertImage(log_mode, 2)) {
+    return EnrollFailed(log_mode);
   }
 
   p = finger.createModel();
   if (p == FPM_OK) {
-    mqtt::Publish("messages", "mode=enroll; createModel: Prints matched");
+    LogStatus(log_mode, "Prints matched");
   } else {
-    PublishError("createModel", p);
-    return EnrollFailed();
+    LogFpmError(log_mode, "createModel", p);
+    return EnrollFailed(log_mode);
   }
 
   p = finger.storeModel(fid);
   if (p == FPM_OK) {
     char buf[100];
-    snprintf(buf, sizeof(buf), "mode=enroll; stored as id %d", fid);
-    mqtt::Publish("messages", "mode=enroll; Stored!");
+    snprintf(buf, sizeof(buf), "Stored as id %d", fid);
+    LogStore(buf);
     BlinkSuccess();
-    WaitForRemove();
+    WaitForRemove(log_mode);
     BlinkClearSuccess();
     return;
   } else {
-    PublishError("storeModel", p);
-    return EnrollFailed();
+    LogFpmError(log_mode, "storeModel", p);
+    return EnrollFailed(log_mode);
   }
 }
 
 void Enroll() {
+  const std::string log_mode = "enroll";
   BlinkStartEnroll();
-  mqtt::Publish("messages",
-                "mode=enroll; Searching for a free slot to store the template...");
+  LogStatus(log_mode, "Searching for a free slot to store the template...");
   int16_t fid;
-  if (get_free_id(&fid)) {
-    enroll_finger(fid);
-  } else {
-    mqtt::Publish("messages", "mode=enroll; No free slot in flash library!");
+  if (!get_free_id(log_mode, &fid)) {
     BlinkError();
+    return;
   }
+  enroll_finger(log_mode, fid);
 }
 
 // a GetImage image must be in the buffer to get the real bitmap image
-void DownloadLastImage() {
-  mqtt::Publish("messages", "Starting image stream");
+void DownloadLastImage(const std::string& log_mode) {
+  LogStatus(log_mode, "Starting image stream");
   finger.downImage();
   std::vector<char> image(256 * 288 / 2);
   size_t image_pos = 0;
@@ -301,7 +331,7 @@
     read_len = image.size() - image_pos;
     if (!finger.readRaw(FPM_OUTPUT_TO_BUFFER, image.data() + image_pos,
                         &read_complete, &read_len)) {
-      mqtt::Publish("messages", "readRaw: failed");
+      LogFpmError(log_mode, "readRaw", -1);
       return;
     }
     image_pos += read_len;
@@ -312,29 +342,27 @@
   size_t image_len = image_pos;
 
   char buf[100];
-  snprintf(buf, sizeof(buf), "got %d bytes to download", image_len);
-  mqtt::Publish("messages", buf);
+  snprintf(buf, sizeof(buf), "Got %d bytes to download", image_len);
+  LogStatus(log_mode, buf);
 
-  std::string msg(image.data(), image_len);
-  char subtopic[50];
-  snprintf(subtopic, sizeof(subtopic), "image/%d", -1);
-  mqtt::Publish(subtopic, msg);
+  PublishImage(image.data(), image_len);
 }
 
 void DownloadModel(uint16_t fid) {
+  const std::string log_mode = "download";
   int p = -1;
-  mqtt::Publish("messages", "retrieve model for download");
+  LogStatus(log_mode, "Retrieve model for download");
   p = finger.loadModel(fid);
   if (p != FPM_OK) {
-    PublishError("loadModel", p);
+    LogFpmError(log_mode, "loadModel", p);
     return;
   }
   p = finger.downloadModel(fid);
   if (p != FPM_OK) {
-    PublishError("downloadModel", p);
+    LogFpmError(log_mode, "downloadModel", p);
     return;
   }
-  byte model[2048];  // expect 1536 bytes
+  char model[2048];  // expect 1536 bytes
   size_t model_pos = 0;
   bool read_complete = false;
   uint16_t read_len;
@@ -342,7 +370,7 @@
     read_len = sizeof(model) - model_pos;
     if (!finger.readRaw(FPM_OUTPUT_TO_BUFFER, model + model_pos, &read_complete,
                         &read_len)) {
-      mqtt::Publish("messages", "readRaw: failed");
+      LogFpmError(log_mode, "readRaw", -1);
       return;
     }
     model_pos += read_len;
@@ -353,22 +381,20 @@
   size_t model_len = model_pos;
   char buf[100];
 
-  snprintf(buf, sizeof(buf), "got %d bytes to download", model_len);
-  mqtt::Publish("messages", buf);
+  snprintf(buf, sizeof(buf), "Got %d bytes to download", model_len);
+  LogStatus(log_mode, buf);
 
-  std::string msg(reinterpret_cast<char*>(model), model_len);
-  char subtopic[50];
-  snprintf(subtopic, sizeof(subtopic), "model/%d", fid);
-  mqtt::Publish(subtopic, msg);
+  PublishModel(fid, model, model_len);
 }
 
 void SetModel(uint16_t fid, const std::vector<uint8_t>& payload) {
+  const std::string log_mode = "setModel";
   int16_t p = -1;
-  mqtt::Publish("messages", "upload buffer to slot 1");
+  LogStatus(log_mode, "Upload buffer to slot 1");
 
   p = finger.uploadModel();
   if (p != FPM_OK) {
-    PublishError("uploadModel", p);
+    LogFpmError(log_mode, "uploadModel", p);
     return;
   }
   yield();
@@ -376,23 +402,26 @@
   delay(
       100);  // load-bearing sleep. Without this, the storeModel doesn't answer.
 
-  mqtt::Publish("messages", "store model from slot 1 to fid");
+  LogStatus(log_mode, "Store model from slot 1 to fid");
   p = finger.storeModel(fid);
   if (p != FPM_OK) {
-    PublishError("storeModel", p);
+    LogFpmError(log_mode, "storeModel", p);
     return;
   }
-  mqtt::Publish("messages", "SetModel successful");
+  char buf[100];
+  snprintf(buf, sizeof(buf), "SetModel successful for id %d", fid);
+  LogStore(buf);
 }
 
 void DeleteModel(uint16_t fid) {
+  const std::string log_mode = "deleteModel";
   int16_t p = finger.deleteModel(fid);
   if (p == FPM_OK) {
     char msg[100];
-    snprintf(msg, sizeof(msg), "deleted id %d", fid);
-    mqtt::Publish("messages", msg);
+    snprintf(msg, sizeof(msg), "Deleted id %d", fid);
+    LogStore(msg);
   } else {
-    PublishError("deleteModel", p);
+    LogFpmError(log_mode, "deleteModel", p);
   }
 }
 
--- a/espNode/desk/src/main.cpp	Thu Aug 27 23:54:11 2020 -0700
+++ b/espNode/desk/src/main.cpp	Fri Aug 28 01:39:08 2020 -0700
@@ -31,6 +31,26 @@
 }
 }  // namespace
 
+void HandleCommand(const std::string &payload_string) {
+  if (payload_string == "enroll") {
+    fingerprint::Enroll();
+  } else if (payload_string == "show_success") {
+    fingerprint::BlinkSuccess();
+    while (!mqtt::HasPendingMessage()) yield();
+    mqtt::PopPendingMessage();
+    // hope it's "clear_success", but who cares
+    fingerprint::BlinkClearSuccess();
+  } else if (payload_string == "delete_all") {
+    fingerprint::DeleteAll();
+  } else if (payload_string.rfind("delete/model/", 0) == 0) {
+    uint16_t fid = LastComponentNumber(payload_string);
+    fingerprint::DeleteModel(fid);
+  } else if (payload_string.rfind("get/model/", 0) == 0) {
+    uint16_t fid = LastComponentNumber(payload_string);
+    fingerprint::DownloadModel(fid);
+  }
+}
+
 void loop() {
   Serial.println("--loop--");
 
@@ -42,26 +62,10 @@
     std::pair<std::string, std::vector<byte>> msg = mqtt::PopPendingMessage();
     const std::string &topic = msg.first;
     const std::vector<byte> &payload = msg.second;
-    const std::string payload_string(payload.begin(), payload.end());
 
     if (topic == "fingerprint/command") {
-      if (payload_string == "enroll") {
-        fingerprint::Enroll();
-      } else if (payload_string == "show_success") {
-        fingerprint::BlinkSuccess();
-        while (!mqtt::HasPendingMessage()) yield();
-        mqtt::PopPendingMessage();
-        // hope it's "clear_success", but who cares
-        fingerprint::BlinkClearSuccess();
-      } else if (payload_string == "delete_all") {
-        fingerprint::DeleteAll();
-      } else if (payload_string.rfind("delete/model/", 0) == 0) {
-        uint16_t fid = LastComponentNumber(payload_string);
-        fingerprint::DeleteModel(fid);
-      } else if (payload_string.rfind("download/model/", 0) == 0) {
-        uint16_t fid = LastComponentNumber(payload_string);
-        fingerprint::DownloadModel(fid);
-      }
+      const std::string payload_string(payload.begin(), payload.end());
+      HandleCommand(payload_string);
     } else if (topic.rfind("fingerprint/set/model/", 0) == 0) {
       uint16_t fid = LastComponentNumber(topic);
 
--- a/espNode/desk/src/mqtt.cpp	Thu Aug 27 23:54:11 2020 -0700
+++ b/espNode/desk/src/mqtt.cpp	Fri Aug 28 01:39:08 2020 -0700
@@ -22,10 +22,32 @@
              0);  // ensure we don't reconnect to MQTT while reconnecting
                   // to Wi-Fi
 }
+/*
 
-void Publish(std::string subtopic, std::string msg) {
+Subscribed by MCU:
+
+fingerprint/command =
+    'enroll'
+  | 'show_success'
+  | 'clear_success'
+  | 'delete_all'
+  | 'delete/model/<fid>'
+  | 'get/model/<fid>'
+fingerprint/set/model/<fid> = binary model data
+
+Published from MCU:
+
+fingerprint/<mode>/status = junk
+fingerprint/<mode>/error/<caller> = FPM error message
+fingerprint/store = some change to fingerprint storage
+fingerprint/detect = input finger
+fingerprint/model/<fid> = binary model data
+fingerprint/image/<fid> = binary image data
+*/
+void Publish(const std::string& subtopic, const std::string& msg) {
   std::string topic = "fingerprint/" + subtopic;
-  mqttClient.publish(topic.c_str(), 1, /*retain=*/false, msg.data(), msg.size());
+  mqttClient.publish(topic.c_str(), 1, /*retain=*/false, msg.data(),
+                     msg.size());
 }
 
 void ConnectToMqtt() {