Переглянути джерело

WIP: BG95/sequencer

master
Christos Choutouridis 3 роки тому
джерело
коміт
2c67fb6069
3 змінених файлів з 64 додано та 55 видалено
  1. +53
    -52
      include/drv/BG95_base.h
  2. +2
    -1
      include/utils/sequencer.h
  3. +9
    -2
      test/tests/BG95_base.cpp

+ 53
- 52
include/drv/BG95_base.h Переглянути файл

@@ -175,7 +175,33 @@ class BG95_base
//! \name Private functionality
//! @{
private:
template<typename T>
ptrdiff_t parse (char* str, size_t n, char next, T& value) {
auto next_ptr = std::find(str, &str[n], next);
char save = *next_ptr;
*next_ptr =0;
if constexpr (std::is_same_v<std::remove_cv_t<T>, int>) {
sscanf(str, "%d", &value);
} else if (std::is_same_v<std::remove_cv_t<T>, float>) {
sscanf(str, "%f", &value);
} else if (std::is_same_v<std::remove_cv_t<T>, double>) {
sscanf(str, "%lf", &value);
} else if (std::is_same_v<std::remove_cv_t<T>, char>) {
sscanf(str, "%c", &value);
}
*next_ptr = save;
return next_ptr - str;
}
ptrdiff_t parse (char* str, size_t n, char next, char* value) {
auto next_ptr = std::find(str, &str[n], next);
char save = *next_ptr;
*next_ptr =0;
strcpy(value, str);
*next_ptr = save;
return next_ptr - str;
}
//! @}
//! \name public functionality
@@ -222,6 +248,33 @@ class BG95_base
return 0;
}
// cmd: "AT+CREG?"
// expected: "\r\n+CREG: 0,%\r\n\r\nOK\r\n"
template <typename T, char Marker = '%'>
bool command (const char* cmd, const str_view_t expected, T& t) {
char buffer[N];
transmit(cmd);
for (size_t pos =0, i=0, j=0 ; pos < expected.size(); pos += j) {
str_view_t ex = expected.substr(pos); // get starting point of expected
size_t sz = receive(buffer, 1); // load the answer
for (i=0, j=0 ; i<sz ; ) {
if (ex[j] == Marker) {
i += parse(&buffer[i], sz, ex[j+1], t); // parse and convert
++j;
}
else if (ex[j] == buffer[i]) {
++i;
++j; // consume current character
}
else
return false; // Fail to parse
}
}
return true;
}
/*!
* \brief
* inetd daemon functionality provided as member function of the driver. This should be running
@@ -257,58 +310,6 @@ class BG95_base
} while (loop);
}
template <size_t Steps, size_t Nhandles>
bool configure (const script_t<Steps, Nhandles>& script) {
return base_type::run (script);
}
// // General API
// static constexpr typename base_type::handle_t error_handle_ = {
// "ERROR", match_t::CONTAINS, nullptr, action_t::EXIT_ERROR, 0
// };
template<typename T>
void parse (char* str, size_t n, char next, T value) {
auto next_ptr = std::find(str, &str[n], next);
char save = *next_ptr;
*next_ptr =0;
if constexpr (std::is_same_v<std::remove_cv<T>, int>) {
sscanf(str, "%d", &value);
} else if (std::is_same_v<std::remove_cv<T>, float>) {
sscanf(str, "%f", &value);
} else if (std::is_same_v<std::remove_cv<T>, double>) {
sscanf(str, "%lf", &value);
} else if (std::is_same_v<std::remove_cv<T>, char>) {
sscanf(str, "%c", &value);
} else if (std::is_same_v<std::remove_cv<T>, char*>) {
strcpy(value, str);
}
*next_ptr = save;
}
// cmd: "AT+CREG?"
// expected: "\r\n+CREG: 0,%\r\nOK\r\n"
template <typename T, char Marker = '%'>
bool command (const str_view_t cmd, const str_view_t expected, T& t) {
char buffer[N];
transmit(cmd);
for (size_t pos =0 ; pos < expected.size(); ) {
str_view_t ex = expected.substr(pos); // get starting point of expected
size_t sz = receive(buffer, 1); // load the answer
for (size_t i ; i<sz ; ) {
if (ex[i] == Marker)
parse(buffer[i], sz, ex[i+1], t); // parse and convert
else if (ex[i] == buffer[i])
++i; // consume current character
else
return false; // Fail to parse
}
}
return true;
}
//! @}
private:


+ 2
- 1
include/utils/sequencer.h Переглянути файл

@@ -82,7 +82,6 @@ class sequencer {
);
// local type dispatch
using str_view_t = std::basic_string_view<Data_t>;
using range_t = typename Cont_t::range_t;
//! \name Public types
@@ -186,6 +185,8 @@ class sequencer {
*/
template <size_t Nrecords, size_t Nhandles =2>
using script_t = std::array<record_t<Nhandles>, Nrecords>;
using str_view_t = std::basic_string_view<Data_t>;
//! @}


+ 9
- 2
test/tests/BG95_base.cpp Переглянути файл

@@ -262,8 +262,15 @@ namespace test_bg95_base {
modem.inetd(false);
while (lock.load(std::memory_order_acquire));
});
EXPECT_EQ (modem.registered(), true);
lock.store(false, std::memory_order_acq_rel);
int status;
EXPECT_EQ (modem.command("AT+CREG?\r\n", "\r\n+CREG: 0,%\r\n\r\nOK\r\n", status), true);
EXPECT_EQ (status, 5);
char substr[32];
EXPECT_EQ (modem.command("AT+CREG?\r\n", "\r\n%\r\n\r\nOK\r\n", substr), true);
EXPECT_EQ (strcmp("+CREG: 0,5", substr), 0);
lock.store(false, std::memory_order_acq_rel); // stop and join inetd
th1.join();
}


Завантаження…
Відмінити
Зберегти