WIP: BG95/sequencer
This commit is contained in:
parent
f9b2b8ff6b
commit
2c67fb6069
@ -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:
|
||||
|
@ -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>;
|
||||
//! @}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user