sensor_commands.cpp 3.1 KB
Newer Older
1
2
3
#include "sensor_commands.h"

namespace sensor_commands {
4
  const uint8_t MAX_CALLBACKS = 20;
Eric Duminil's avatar
Eric Duminil committed
5
  const uint8_t MAX_COMMAND_SIZE = 30;
Eric Duminil's avatar
Eric Duminil committed
6

7
  uint8_t callbacks_count = 0;
Eric Duminil's avatar
Eric Duminil committed
8

9
  struct Callback {
Eric Duminil's avatar
Eric Duminil committed
10
    const char *name;
Eric Duminil's avatar
Eric Duminil committed
11
12
13
14
    union {
      void (*intFunction)(int32_t);
      void (*voidFunction)(void);
    };
15
    const char *doc;
Eric Duminil's avatar
Eric Duminil committed
16
    bool has_parameter;
17
18
  };

19
  Callback callbacks[MAX_CALLBACKS];
20

Eric Duminil's avatar
Eric Duminil committed
21
  //NOTE: Probably possible to DRY (with templates?)
22
  void defineCallback(const char *name, void (*function)(void), const char *doc) {
Eric Duminil's avatar
Eric Duminil committed
23
24
25
26
    if (callbacks_count < MAX_CALLBACKS) {
      callbacks[callbacks_count].name = name;
      callbacks[callbacks_count].voidFunction = function;
      callbacks[callbacks_count].doc = doc;
Eric Duminil's avatar
Eric Duminil committed
27
      callbacks[callbacks_count].has_parameter = false;
Eric Duminil's avatar
Eric Duminil committed
28
29
30
31
      callbacks_count++;
    } else {
      Serial.println(F("Too many callbacks have been defined."));
    }
32
33
  }

Eric Duminil's avatar
Eric Duminil committed
34
  void defineIntCallback(const char *name, void (*function)(int32_t), const char *doc) {
35
    if (callbacks_count < MAX_CALLBACKS) {
Eric Duminil's avatar
Eric Duminil committed
36
37
38
      callbacks[callbacks_count].name = name;
      callbacks[callbacks_count].intFunction = function;
      callbacks[callbacks_count].doc = doc;
Eric Duminil's avatar
Eric Duminil committed
39
      callbacks[callbacks_count].has_parameter = true;
Eric Duminil's avatar
Eric Duminil committed
40
      callbacks_count++;
41
    } else {
Eric Duminil's avatar
Eric Duminil committed
42
      Serial.println(F("Too many callbacks have been defined."));
43
    }
44
45
  }

Eric Duminil's avatar
Eric Duminil committed
46
  uint8_t parseCommand(const char *command, char *function_name, int32_t &argument) {
Eric Duminil's avatar
Eric Duminil committed
47
48
    char split_command[MAX_COMMAND_SIZE];
    strlcpy(split_command, command, MAX_COMMAND_SIZE);
Eric Duminil's avatar
Eric Duminil committed
49
    Serial.print(F("Received : '"));
Eric Duminil's avatar
Eric Duminil committed
50
51
    Serial.print(command);
    Serial.println("'");
Eric Duminil's avatar
Eric Duminil committed
52
    char *arg;
Eric Duminil's avatar
Eric Duminil committed
53
54
55
    char *part1;
    part1 = strtok(split_command, " ");
    if (!part1) {
Eric Duminil's avatar
Eric Duminil committed
56
      // Empty string
Eric Duminil's avatar
Eric Duminil committed
57
      return 1;
Eric Duminil's avatar
Eric Duminil committed
58
    }
Eric Duminil's avatar
Eric Duminil committed
59
    strlcpy(function_name, part1, MAX_COMMAND_SIZE);
Eric Duminil's avatar
Eric Duminil committed
60
    arg = strtok(NULL, " ");
Eric Duminil's avatar
Eric Duminil committed
61
    uint8_t code = 0;
Eric Duminil's avatar
Eric Duminil committed
62
63
    if (arg) {
      char *end;
Eric Duminil's avatar
Eric Duminil committed
64
      argument = strtol(arg, &end, 10);
Eric Duminil's avatar
Eric Duminil committed
65
66
      if (*end) {
        // Second argument isn't a number
Eric Duminil's avatar
Eric Duminil committed
67
        code = 2;
Eric Duminil's avatar
Eric Duminil committed
68
69
      }
    } else {
Eric Duminil's avatar
Eric Duminil committed
70
      // No argument
Eric Duminil's avatar
Eric Duminil committed
71
      code = 2;
Eric Duminil's avatar
Eric Duminil committed
72
    }
Eric Duminil's avatar
Eric Duminil committed
73
    return code;
Eric Duminil's avatar
Eric Duminil committed
74
75
  }

Eric Duminil's avatar
Eric Duminil committed
76
77
78
  void listAvailableCallbacks() {
    for (uint8_t i = 0; i < callbacks_count; i++) {
      Serial.print("  ");
Eric Duminil's avatar
Eric Duminil committed
79
      Serial.print(callbacks[i].name);
80
81
      Serial.print(callbacks[i].doc);
      Serial.println(".");
Eric Duminil's avatar
Eric Duminil committed
82
    }
Eric Duminil's avatar
Eric Duminil committed
83
    led_effects::showKITTWheel(color::red, 1);
Eric Duminil's avatar
Eric Duminil committed
84
85
  }

Eric Duminil's avatar
Eric Duminil committed
86
87
  void run(const char *command) {
    char function_name[MAX_COMMAND_SIZE];
Eric Duminil's avatar
Eric Duminil committed
88
89
90
    int32_t argument = 0;
    bool has_argument;
    has_argument = (parseCommand(command, function_name, argument) == 0);
Eric Duminil's avatar
Eric Duminil committed
91

92
    for (uint8_t i = 0; i < callbacks_count; i++) {
Eric Duminil's avatar
Eric Duminil committed
93
      if (!strcmp(function_name, callbacks[i].name) && has_argument == callbacks[i].has_parameter) {
Eric Duminil's avatar
Eric Duminil committed
94
95
        Serial.print("Calling : ");
        Serial.print(function_name);
Eric Duminil's avatar
Eric Duminil committed
96
97
98
99
100
101
        if (has_argument) {
          Serial.print("(");
          Serial.print(argument);
          Serial.println(")");
          callbacks[i].intFunction(argument);
        } else {
102
          Serial.println();
Eric Duminil's avatar
Eric Duminil committed
103
104
          callbacks[i].voidFunction();
        }
Eric Duminil's avatar
Eric Duminil committed
105
        return;
Eric Duminil's avatar
Eric Duminil committed
106
      }
107
    }
Eric Duminil's avatar
Eric Duminil committed
108
    Serial.println(F("Message not supported. Available commands :"));
Eric Duminil's avatar
Eric Duminil committed
109
    listAvailableCallbacks();
110
111
  }
}