Adicionar primeiro
This commit is contained in:
340
components/api/lib/cAT/tests/test_cmd_list.c
Executable file
340
components/api/lib/cAT/tests/test_cmd_list.c
Executable file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char ack_results[512];
|
||||
|
||||
static int8_t var1;
|
||||
static int8_t var2;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_run(const struct cat_command *cmd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_cmd_list(const struct cat_command *cmd)
|
||||
{
|
||||
return CAT_RETURN_STATE_PRINT_CMD_LIST_OK;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_ro[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write,
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_wo[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write,
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars2[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars2_ro[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write,
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars2_wo[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write,
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+V1",
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+V1RO",
|
||||
.var = vars_ro,
|
||||
.var_num = sizeof(vars_ro) / sizeof(vars_ro[0])
|
||||
},
|
||||
{
|
||||
.name = "+V1RW",
|
||||
.var = vars_wo,
|
||||
.var_num = sizeof(vars_wo) / sizeof(vars_wo[0])
|
||||
},
|
||||
{
|
||||
.name = "+V11",
|
||||
.var = vars2,
|
||||
.var_num = sizeof(vars2) / sizeof(vars2[0])
|
||||
},
|
||||
{
|
||||
.name = "+V11RO",
|
||||
.var = vars2_ro,
|
||||
.var_num = sizeof(vars2_ro) / sizeof(vars2_ro[0])
|
||||
},
|
||||
{
|
||||
.name = "+V11WO",
|
||||
.var = vars2_wo,
|
||||
.var_num = sizeof(vars2_wo) / sizeof(vars2_wo[0])
|
||||
},
|
||||
{
|
||||
.name = "+V2",
|
||||
.write = cmd_write,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+V3",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+V4",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.test = cmd_test,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+V5",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.test = cmd_test,
|
||||
.run = cmd_run,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+S1",
|
||||
},
|
||||
{
|
||||
.name = "+S2",
|
||||
.write = cmd_write,
|
||||
},
|
||||
{
|
||||
.name = "+S3",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
},
|
||||
{
|
||||
.name = "+S4",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.test = cmd_test,
|
||||
},
|
||||
{
|
||||
.name = "+S5",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.test = cmd_test,
|
||||
.run = cmd_run,
|
||||
},
|
||||
{
|
||||
.name = "+D1",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.test = cmd_test,
|
||||
.run = cmd_run,
|
||||
.disable = true,
|
||||
},
|
||||
{
|
||||
.name = "+T1",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.test = cmd_test,
|
||||
.run = cmd_run,
|
||||
.only_test = true,
|
||||
},
|
||||
{
|
||||
.name = "+T2",
|
||||
.only_test = true,
|
||||
},
|
||||
{
|
||||
.name = "#HELP",
|
||||
.run = print_cmd_list,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[512];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static void print_raw_text(char *p)
|
||||
{
|
||||
while (*p != '\0') {
|
||||
if (*p == '\n') {
|
||||
printf("\\n");
|
||||
} else {
|
||||
putchar(*p);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input("\nAT#HELP\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nAT+V1?\nAT+V1=\nAT+V1=?\n\nAT+V1RO?\nAT+V1RO=?\n\nAT+V1RW=\nAT+V1RW=?\n\nAT+V11?\nAT+V11=\nAT+V11=?\n\nAT+V11RO?\nAT+V11RO=\nAT+V11RO=?\n\nAT+V11WO?\nAT+V11WO=\nAT+V11WO=?\n\nAT+V2?\nAT+V2=\nAT+V2=?\n\nAT+V3?\nAT+V3=\nAT+V3=?\n\nAT+V4?\nAT+V4=\nAT+V4=?\n\nAT+V5\nAT+V5?\nAT+V5=\nAT+V5=?\n\nAT+S2=\n\nAT+S3?\nAT+S3=\n\nAT+S4?\nAT+S4=\nAT+S4=?\n\nAT+S5\nAT+S5?\nAT+S5=\nAT+S5=?\n\nAT+T1=?\n\nAT#HELP\n\nOK\n") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
229
components/api/lib/cAT/tests/test_hold_state.c
Executable file
229
components/api/lib/cAT/tests/test_hold_state.c
Executable file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char cmd_results[256];
|
||||
static char var_read_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x, var_u1, var_u2;
|
||||
static struct cat_object at;
|
||||
|
||||
static struct cat_command u_cmds[];
|
||||
|
||||
static cat_return_state cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(cmd_results, " write:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if (var_x < 2) {
|
||||
s = cat_trigger_unsolicited_read(&at, &u_cmds[var_x]);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
|
||||
return CAT_RETURN_STATE_HOLD;
|
||||
}
|
||||
|
||||
return CAT_RETURN_STATE_ERROR;
|
||||
}
|
||||
|
||||
static cat_return_state cmd1_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(cmd_results, " read1:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if (var_u1 > 0) {
|
||||
var_u1--;
|
||||
s = cat_trigger_unsolicited_read(&at, cmd);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
return CAT_RETURN_STATE_HOLD_EXIT_OK;
|
||||
}
|
||||
|
||||
static cat_return_state cmd2_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(cmd_results, " read2:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if (var_u2 > 0) {
|
||||
var_u2--;
|
||||
s = cat_trigger_unsolicited_read(&at, cmd);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
cat_hold_exit(&at, CAT_STATUS_OK);
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
static int var_read(const struct cat_variable *var)
|
||||
{
|
||||
strcat(var_read_results, " var_read:");
|
||||
strcat(var_read_results, var->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable u_vars[] = {
|
||||
{
|
||||
.name = "U1",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u1,
|
||||
.data_size = sizeof(var_u1),
|
||||
.read = var_read
|
||||
},
|
||||
{
|
||||
.name = "U2",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u2,
|
||||
.data_size = sizeof(var_u2),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.write = cmd_write,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command u_cmds[] = {
|
||||
{
|
||||
.name = "+U1CMD",
|
||||
.read = cmd1_read,
|
||||
.var = &u_vars[0],
|
||||
.var_num = 1,
|
||||
},
|
||||
{
|
||||
.name = "+U2CMD",
|
||||
.read = cmd2_read,
|
||||
.var = &u_vars[1],
|
||||
.var_num = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_u1 = 2;
|
||||
var_u2 = 3;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(cmd_results, 0, sizeof(cmd_results));
|
||||
memset(var_read_results, 0, sizeof(var_read_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD=0\n\nAT+CMD=1\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+U1CMD=2\n\n+U1CMD=1\n\nOK\n\n+U2CMD=3\n\n+U2CMD=2\n\n+U2CMD=1\n\n+U2CMD=0\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD read1:+U1CMD read1:+U1CMD read1:+U1CMD write:+CMD read2:+U2CMD read2:+U2CMD read2:+U2CMD read2:+U2CMD") == 0);
|
||||
assert(strcmp(var_read_results, " var_read:U1 var_read:U1 var_read:U1 var_read:U2 var_read:U2 var_read:U2 var_read:U2") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
185
components/api/lib/cAT/tests/test_mutex.c
Executable file
185
components/api/lib/cAT/tests/test_mutex.c
Executable file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int a_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " A:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " AP:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " +TEST:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.run = a_run
|
||||
},
|
||||
{
|
||||
.name = "AP",
|
||||
.run = ap_run
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.run = test_run
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static int mutex_ret_lock;
|
||||
static int mutex_ret_unlock;
|
||||
|
||||
static int mutex_lock(void)
|
||||
{
|
||||
return mutex_ret_lock;
|
||||
}
|
||||
|
||||
static int mutex_unlock(void)
|
||||
{
|
||||
return mutex_ret_unlock;
|
||||
}
|
||||
|
||||
static struct cat_mutex_interface mutex = {
|
||||
.lock = mutex_lock,
|
||||
.unlock = mutex_unlock
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
mutex_ret_lock = 0;
|
||||
mutex_ret_unlock = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT\nAT+test\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, &mutex);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(run_results, " +TEST:+TEST") == 0);
|
||||
|
||||
mutex_ret_lock = 1;
|
||||
mutex_ret_unlock = 0;
|
||||
assert(cat_service(&at) == CAT_STATUS_ERROR_MUTEX_LOCK);
|
||||
|
||||
mutex_ret_lock = 0;
|
||||
mutex_ret_unlock = 1;
|
||||
assert(cat_service(&at) == CAT_STATUS_ERROR_MUTEX_UNLOCK);
|
||||
|
||||
mutex_ret_lock = 1;
|
||||
mutex_ret_unlock = 0;
|
||||
assert(cat_is_busy(&at) == CAT_STATUS_ERROR_MUTEX_LOCK);
|
||||
|
||||
mutex_ret_lock = 0;
|
||||
mutex_ret_unlock = 1;
|
||||
assert(cat_is_busy(&at) == CAT_STATUS_ERROR_MUTEX_UNLOCK);
|
||||
|
||||
mutex_ret_lock = 0;
|
||||
mutex_ret_unlock = 0;
|
||||
assert(cat_service(&at) == CAT_STATUS_OK);
|
||||
assert(cat_is_busy(&at) == CAT_STATUS_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
223
components/api/lib/cAT/tests/test_order.c
Executable file
223
components/api/lib/cAT/tests/test_order.c
Executable file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int e_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " E:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e0_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " E0:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int e1_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " E1:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_command cmds1[] = {
|
||||
{
|
||||
.name = "E",
|
||||
.run = e_run,
|
||||
},
|
||||
{
|
||||
.name = "E0",
|
||||
.run = e0_run,
|
||||
},
|
||||
{
|
||||
.name = "E1",
|
||||
.run = e1_run,
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds2[] = {
|
||||
{
|
||||
.name = "E0",
|
||||
.run = e0_run,
|
||||
},
|
||||
{
|
||||
.name = "E1",
|
||||
.run = e1_run,
|
||||
},
|
||||
{
|
||||
.name = "E",
|
||||
.run = e_run,
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds3[] = {
|
||||
{
|
||||
.name = "E0",
|
||||
.run = e0_run,
|
||||
},
|
||||
{
|
||||
.name = "E",
|
||||
.run = e_run,
|
||||
},
|
||||
{
|
||||
.name = "E1",
|
||||
.run = e1_run,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_1_group = {
|
||||
.cmd = cmds1,
|
||||
.cmd_num = sizeof(cmds1) / sizeof(cmds1[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_1_desc[] = {
|
||||
&cmd_1_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc_1 = {
|
||||
.cmd_group = cmd_1_desc,
|
||||
.cmd_group_num = sizeof(cmd_1_desc) / sizeof(cmd_1_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static struct cat_command_group cmd_2_group = {
|
||||
.cmd = cmds2,
|
||||
.cmd_num = sizeof(cmds2) / sizeof(cmds2[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_2_desc[] = {
|
||||
&cmd_2_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc_2 = {
|
||||
.cmd_group = cmd_2_desc,
|
||||
.cmd_group_num = sizeof(cmd_2_desc) / sizeof(cmd_2_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static struct cat_command_group cmd_3_group = {
|
||||
.cmd = cmds3,
|
||||
.cmd_num = sizeof(cmds3) / sizeof(cmds3[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_3_desc[] = {
|
||||
&cmd_3_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc_3 = {
|
||||
.cmd_group = cmd_3_desc,
|
||||
.cmd_group_num = sizeof(cmd_3_desc) / sizeof(cmd_3_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nATE\n\nATE0\n\nATE1\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc_1, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(run_results, " E:E E0:E0 E1:E1") == 0);
|
||||
|
||||
cat_init(&at, &desc_2, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(run_results, " E:E E0:E0 E1:E1") == 0);
|
||||
|
||||
cat_init(&at, &desc_3, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(run_results, " E:E E0:E0 E1:E1") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
195
components/api/lib/cAT/tests/test_parse.c
Executable file
195
components/api/lib/cAT/tests/test_parse.c
Executable file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int a_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " A:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " AP:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " +TEST:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.run = a_run,
|
||||
.disable = false,
|
||||
},
|
||||
{
|
||||
.name = "AP",
|
||||
.run = ap_run,
|
||||
.disable = false,
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.run = test_run,
|
||||
.disable = false,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nsa\rAT\n\r\nAT\nAT+\n\nATA\r\natap\naaaattttap\na\n\r+test\r\n+testATA\nATAPATAP\n\rAT\rATA\nAT+test\r\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\r\nERROR\r\n\nOK\n\nOK\n\r\nOK\r\n\nOK\n\nERROR\n\nERROR\n\r\nERROR\r\n\nERROR\n\nERROR\n\r\nERROR\r\n\r\nOK\r\n") == 0);
|
||||
assert(strcmp(run_results, " +TEST:+TEST A:A AP:AP +TEST:+TEST") == 0);
|
||||
|
||||
prepare_input("\nAT\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(cat_is_busy(&at) == 0);
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(run_results, "") == 0);
|
||||
|
||||
prepare_input("\nAT+te");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(cat_is_busy(&at) != 0);
|
||||
assert(strcmp(ack_results, "") == 0);
|
||||
assert(strcmp(run_results, "") == 0);
|
||||
|
||||
prepare_input("st\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(cat_is_busy(&at) == 0);
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(run_results, " +TEST:+TEST") == 0);
|
||||
|
||||
struct cat_command *cmd;
|
||||
|
||||
cmd = (struct cat_command*)cat_search_command_by_name(&at, "A");
|
||||
cmd->disable = true;
|
||||
cmd = (struct cat_command*)cat_search_command_by_name(&at, "+TEST");
|
||||
cmd->disable = true;
|
||||
|
||||
prepare_input("\nATA\n\nATAP\n\nAT+TEST\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(run_results, " AP:AP AP:AP") == 0);
|
||||
|
||||
struct cat_command_group *cmd_group;
|
||||
cmd_group = (struct cat_command_group*)cat_search_command_group_by_name(&at, "standard");
|
||||
assert(cmd_group == NULL);
|
||||
|
||||
cmd_desc[0]->name = "standard";
|
||||
cmd_group = (struct cat_command_group*)cat_search_command_group_by_name(&at, "standard");
|
||||
assert(cmd_group == cmd_desc[0]);
|
||||
cmd_group->disable = true;
|
||||
|
||||
prepare_input("\nATA\n\nATAP\n\nAT+TEST\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nERROR\n\nERROR\n") == 0);
|
||||
assert(strcmp(run_results, "") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
165
components/api/lib/cAT/tests/test_read.c
Executable file
165
components/api/lib/cAT/tests/test_read.c
Executable file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char read_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int a_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " A_");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(read_results, " A:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
snprintf(data, max_data_size, "%s=A-val", cmd->name);
|
||||
*data_size = strlen(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(read_results, " AP:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
*data_size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(read_results, " +TEST:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.read = a_read,
|
||||
.run = a_run
|
||||
},
|
||||
{
|
||||
.name = "AP",
|
||||
.read = ap_read
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.read = test_read
|
||||
},
|
||||
{
|
||||
.name = "+EMPTY"
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(read_results, 0, sizeof(read_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT\r\nAT+\nAT+?\nATA?\r\nATAP\nATAP?\nATAPA?\nAT+TEST?\nAT+te?\nAT+e?\nAT+empTY?\r\nATA\r\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\r\nOK\r\n\nERROR\n\nERROR\n\r\nA=A-val\r\n\r\nOK\r\n\nERROR\n\nAP=\n\nOK\n\nERROR\n\nERROR\n\nERROR\n\nERROR\n\r\nERROR\r\n\r\nOK\r\n") == 0);
|
||||
assert(strcmp(run_results, " A_A") == 0);
|
||||
assert(strcmp(read_results, " A:A AP:AP +TEST:+TEST +TEST:+TEST") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
225
components/api/lib/cAT/tests/test_read_args.c
Executable file
225
components/api/lib/cAT/tests/test_read_args.c
Executable file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char ack_results[256];
|
||||
|
||||
static int8_t var_int;
|
||||
static uint8_t var_uint;
|
||||
static uint8_t var_hex8;
|
||||
static uint16_t var_hex16;
|
||||
static uint32_t var_hex32;
|
||||
static uint8_t var_buf[4];
|
||||
static char var_string[16];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
static int common_cntr;
|
||||
static uint8_t ctx;
|
||||
|
||||
static int cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd2_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
sprintf(data, "%s=test", cmd->name);
|
||||
*data_size = strlen(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int common_var_read_handler(const struct cat_variable *var)
|
||||
{
|
||||
common_cntr++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* var_int_data_getter(const struct cat_variable *var, void *context, size_t *data_size)
|
||||
{
|
||||
*data_size = sizeof(var_int);
|
||||
assert(context == &ctx);
|
||||
return &var_int;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.read = common_var_read_handler,
|
||||
.data_getter = var_int_data_getter,
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint,
|
||||
.data_size = sizeof(var_uint),
|
||||
.read = common_var_read_handler
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex8,
|
||||
.data_size = sizeof(var_hex8),
|
||||
.read = common_var_read_handler
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex16,
|
||||
.data_size = sizeof(var_hex16),
|
||||
.read = common_var_read_handler
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex32,
|
||||
.data_size = sizeof(var_hex32),
|
||||
.read = common_var_read_handler
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = &var_buf,
|
||||
.data_size = sizeof(var_buf),
|
||||
.read = common_var_read_handler
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = &var_string,
|
||||
.data_size = sizeof(var_string),
|
||||
.read = common_var_read_handler
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
.read = cmd_read,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
.context = &ctx,
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.read = cmd2_read,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
.context = &ctx,
|
||||
},
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_int = -1;
|
||||
var_uint = 255;
|
||||
var_hex8 = 0xAA;
|
||||
var_hex16 = 0x0123;
|
||||
var_hex32 = 0xFF001234;
|
||||
|
||||
var_buf[0] = 0x12;
|
||||
var_buf[1] = 0x34;
|
||||
var_buf[2] = 0x56;
|
||||
var_buf[3] = 0x78;
|
||||
|
||||
common_cntr = 0;
|
||||
|
||||
sprintf(var_string, "\\\"test\n");
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET?\r\n";
|
||||
static const char test_case_2[] = "\nAT+TEST?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\r\n+SET=-1,255,0xAA,0x0123,0xFF001234,12345678,\"\\\\\\\"test\\n\"\r\n\r\nOK\r\n") == 0);
|
||||
assert(common_cntr == 7);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+TEST=test\n\nOK\n") == 0);
|
||||
assert(common_cntr == 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
206
components/api/lib/cAT/tests/test_return_read.c
Executable file
206
components/api/lib/cAT/tests/test_return_read.c
Executable file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char cmd_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x;
|
||||
static struct cat_object at;
|
||||
|
||||
static cat_return_state ret;
|
||||
static bool ret_error;
|
||||
|
||||
static cat_return_state cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(cmd_results, " read:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if (cat_is_hold(&at) == CAT_STATUS_HOLD) {
|
||||
var_x++;
|
||||
if (var_x > 4) {
|
||||
ret = (ret_error == false) ? CAT_RETURN_STATE_HOLD_EXIT_OK : CAT_RETURN_STATE_HOLD_EXIT_ERROR;
|
||||
} else {
|
||||
if (var_x == 4) {
|
||||
strcpy(data, "test");
|
||||
*data_size = strlen(data);
|
||||
}
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
}
|
||||
} else {
|
||||
if ((ret == CAT_RETURN_STATE_DATA_NEXT) || (ret == CAT_RETURN_STATE_NEXT)) {
|
||||
var_x++;
|
||||
if (var_x > 2)
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
} else if (ret == CAT_RETURN_STATE_HOLD) {
|
||||
cat_trigger_unsolicited_read(&at, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x)
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
var_x = 1;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(cmd_results, 0, sizeof(cmd_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
ret = CAT_RETURN_STATE_ERROR;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=1\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=1\n\n+CMD=2\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD read:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=2\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD read:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD") == 0);
|
||||
|
||||
ret_error = false;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=1\n\n+CMD=2\n\ntest\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD read:+CMD read:+CMD read:+CMD read:+CMD") == 0);
|
||||
|
||||
ret_error = true;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=1\n\n+CMD=2\n\ntest\n\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " read:+CMD read:+CMD read:+CMD read:+CMD read:+CMD") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
236
components/api/lib/cAT/tests/test_return_run.c
Executable file
236
components/api/lib/cAT/tests/test_return_run.c
Executable file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char cmd_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x;
|
||||
static struct cat_object at;
|
||||
|
||||
static cat_return_state ret;
|
||||
static bool ret_error;
|
||||
|
||||
static cat_return_state cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(cmd_results, " read:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
var_x++;
|
||||
if (var_x > 5) {
|
||||
ret = (ret_error == false) ? CAT_RETURN_STATE_HOLD_EXIT_OK : CAT_RETURN_STATE_HOLD_EXIT_ERROR;
|
||||
} else {
|
||||
if (var_x == 5) {
|
||||
strcpy(data, "test");
|
||||
*data_size = strlen(data);
|
||||
}
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static cat_return_state cmd_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(cmd_results, " run:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if ((ret == CAT_RETURN_STATE_DATA_NEXT) || (ret == CAT_RETURN_STATE_NEXT)) {
|
||||
var_x++;
|
||||
if (var_x > 3)
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
} else if (ret == CAT_RETURN_STATE_HOLD) {
|
||||
cat_trigger_unsolicited_read(&at, cmd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x)
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.run = cmd_run,
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
var_x = 2;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(cmd_results, 0, sizeof(cmd_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
ret = CAT_RETURN_STATE_ERROR;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD run:+CMD") == 0);
|
||||
assert(var_x == 4);
|
||||
|
||||
ret = CAT_RETURN_STATE_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD run:+CMD") == 0);
|
||||
assert(var_x == 4);
|
||||
|
||||
ret = CAT_RETURN_STATE_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret_error = false;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=2\n\n+CMD=3\n\ntest\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD read:+CMD read:+CMD read:+CMD read:+CMD") == 0);
|
||||
assert(var_x == 6);
|
||||
|
||||
ret_error = true;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=2\n\n+CMD=3\n\ntest\n\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD read:+CMD read:+CMD read:+CMD read:+CMD") == 0);
|
||||
assert(var_x == 6);
|
||||
|
||||
ret = CAT_RETURN_STATE_HOLD_EXIT_ERROR;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret = CAT_RETURN_STATE_HOLD_EXIT_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " run:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
206
components/api/lib/cAT/tests/test_return_test.c
Executable file
206
components/api/lib/cAT/tests/test_return_test.c
Executable file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char cmd_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x;
|
||||
static struct cat_object at;
|
||||
|
||||
static cat_return_state ret;
|
||||
static bool ret_error;
|
||||
|
||||
static cat_return_state cmd_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(cmd_results, " test:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if (cat_is_hold(&at) == CAT_STATUS_HOLD) {
|
||||
var_x++;
|
||||
if (var_x > 4) {
|
||||
ret = (ret_error == false) ? CAT_RETURN_STATE_HOLD_EXIT_OK : CAT_RETURN_STATE_HOLD_EXIT_ERROR;
|
||||
} else {
|
||||
if (var_x == 4) {
|
||||
strcpy(data, "test");
|
||||
*data_size = strlen(data);
|
||||
}
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
}
|
||||
} else {
|
||||
if ((ret == CAT_RETURN_STATE_DATA_NEXT) || (ret == CAT_RETURN_STATE_NEXT)) {
|
||||
var_x++;
|
||||
if (var_x > 2)
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
} else if (ret == CAT_RETURN_STATE_HOLD) {
|
||||
cat_trigger_unsolicited_test(&at, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x)
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.test = cmd_test,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
var_x = 1;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(cmd_results, 0, sizeof(cmd_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD=?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
ret = CAT_RETURN_STATE_ERROR;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=<X:INT32[RW]>\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=<X:INT32[RW]>\n\n+CMD=<X:INT32[RW]>\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD test:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=<X:INT32[RW]>\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD test:+CMD") == 0);
|
||||
|
||||
ret = CAT_RETURN_STATE_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD") == 0);
|
||||
|
||||
ret_error = false;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=<X:INT32[RW]>\n\n+CMD=<X:INT32[RW]>\n\ntest\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD test:+CMD test:+CMD test:+CMD test:+CMD") == 0);
|
||||
|
||||
ret_error = true;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=<X:INT32[RW]>\n\n+CMD=<X:INT32[RW]>\n\ntest\n\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:+CMD test:+CMD test:+CMD test:+CMD test:+CMD") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
236
components/api/lib/cAT/tests/test_return_write.c
Executable file
236
components/api/lib/cAT/tests/test_return_write.c
Executable file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char cmd_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x;
|
||||
static struct cat_object at;
|
||||
|
||||
static cat_return_state ret;
|
||||
static bool ret_error;
|
||||
|
||||
static cat_return_state cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(cmd_results, " read:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
var_x++;
|
||||
if (var_x > 5) {
|
||||
ret = (ret_error == false) ? CAT_RETURN_STATE_HOLD_EXIT_OK : CAT_RETURN_STATE_HOLD_EXIT_ERROR;
|
||||
} else {
|
||||
if (var_x == 5) {
|
||||
strcpy(data, "test");
|
||||
*data_size = strlen(data);
|
||||
}
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static cat_return_state cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(cmd_results, " write:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
if ((ret == CAT_RETURN_STATE_DATA_NEXT) || (ret == CAT_RETURN_STATE_NEXT)) {
|
||||
var_x++;
|
||||
if (var_x > 3)
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
} else if (ret == CAT_RETURN_STATE_HOLD) {
|
||||
cat_trigger_unsolicited_read(&at, cmd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x)
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.write = cmd_write,
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
var_x = 1;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(cmd_results, 0, sizeof(cmd_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD=2\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
ret = CAT_RETURN_STATE_ERROR;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret = CAT_RETURN_STATE_DATA_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD write:+CMD") == 0);
|
||||
assert(var_x == 4);
|
||||
|
||||
ret = CAT_RETURN_STATE_NEXT;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD write:+CMD") == 0);
|
||||
assert(var_x == 4);
|
||||
|
||||
ret = CAT_RETURN_STATE_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret_error = false;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=2\n\n+CMD=3\n\ntest\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD read:+CMD read:+CMD read:+CMD read:+CMD") == 0);
|
||||
assert(var_x == 6);
|
||||
|
||||
ret_error = true;
|
||||
ret = CAT_RETURN_STATE_HOLD;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+CMD=2\n\n+CMD=3\n\ntest\n\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD read:+CMD read:+CMD read:+CMD read:+CMD") == 0);
|
||||
assert(var_x == 6);
|
||||
|
||||
ret = CAT_RETURN_STATE_HOLD_EXIT_ERROR;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
ret = CAT_RETURN_STATE_HOLD_EXIT_OK;
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " write:+CMD") == 0);
|
||||
assert(var_x == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
157
components/api/lib/cAT/tests/test_run.c
Executable file
157
components/api/lib/cAT/tests/test_run.c
Executable file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int a_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " A:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " AP:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " +TEST:");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int force_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " FORCE:");
|
||||
strcat(run_results, cmd->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.run = a_run
|
||||
},
|
||||
{
|
||||
.name = "AP",
|
||||
.run = ap_run
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.run = test_run
|
||||
},
|
||||
{
|
||||
.name = "+EMPTY"
|
||||
},
|
||||
{
|
||||
.name = "FORCE",
|
||||
.run = force_run,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT\nAT+\nATA\r\nATAP\nATAPA\nAT+TEST\nAT+te\nAT+e\nAT+empTY\naTf\nAtFoRcE\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nERROR\n\r\nOK\r\n\nOK\n\nERROR\n\nOK\n\nOK\n\nERROR\n\nERROR\n\nERROR\n\nERROR\n") == 0);
|
||||
assert(strcmp(run_results, " A:A AP:AP +TEST:+TEST +TEST:+TEST FORCE:FORCE FORCE:FORCE") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
224
components/api/lib/cAT/tests/test_search_cmd.c
Executable file
224
components/api/lib/cAT/tests/test_search_cmd.c
Executable file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static int ap_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars_ap1[] = {
|
||||
{
|
||||
.name = "var_ap1_1"
|
||||
},
|
||||
{
|
||||
.name = "var_ap1_2"
|
||||
},
|
||||
{
|
||||
.name = "var_ap1_3"
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_apx2[] = {
|
||||
{
|
||||
.name = "var_apx2_1"
|
||||
},
|
||||
{
|
||||
.name = "var_apx2_2"
|
||||
},
|
||||
{
|
||||
.name = "var_apx2_3"
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "AP1",
|
||||
.write = ap_write,
|
||||
.only_test = true,
|
||||
.var = vars_ap1,
|
||||
.var_num = sizeof(vars_ap1) / sizeof(vars_ap1[0])
|
||||
},
|
||||
{
|
||||
.name = "AP2",
|
||||
.read = ap_read,
|
||||
.only_test = false
|
||||
},
|
||||
};
|
||||
|
||||
static struct cat_command cmds2[] = {
|
||||
{
|
||||
.name = "APX1",
|
||||
.write = ap_write,
|
||||
.only_test = true
|
||||
},
|
||||
{
|
||||
.name = "APX2",
|
||||
.read = ap_read,
|
||||
.only_test = false,
|
||||
.var = vars_apx2,
|
||||
.var_num = sizeof(vars_apx2) / sizeof(vars_apx2[0])
|
||||
},
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group1 = {
|
||||
.name = "std",
|
||||
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group cmd_group2 = {
|
||||
.name = "ext",
|
||||
|
||||
.cmd = cmds2,
|
||||
.cmd_num = sizeof(cmds2) / sizeof(cmds2[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group1,
|
||||
&cmd_group2
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
struct cat_command const *cmd;
|
||||
struct cat_command_group const *cmd_group;
|
||||
struct cat_variable const *var;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "A");
|
||||
assert(cmd == NULL);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "AP");
|
||||
assert(cmd == NULL);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "AP1");
|
||||
assert(cmd == &cmds[0]);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "AP2");
|
||||
assert(cmd == &cmds[1]);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "AP3");
|
||||
assert(cmd == NULL);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "APX1");
|
||||
assert(cmd == &cmds2[0]);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "APX2");
|
||||
assert(cmd == &cmds2[1]);
|
||||
|
||||
cmd = cat_search_command_by_name(&at, "APX3");
|
||||
assert(cmd == NULL);
|
||||
|
||||
cmd_group = cat_search_command_group_by_name(&at, "std");
|
||||
assert(cmd_group == cmd_desc[0]);
|
||||
|
||||
cmd_group = cat_search_command_group_by_name(&at, "ext");
|
||||
assert(cmd_group == cmd_desc[1]);
|
||||
|
||||
cmd_group = cat_search_command_group_by_name(&at, "not");
|
||||
assert(cmd_group == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "v");
|
||||
assert(var == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "var_ap");
|
||||
assert(var == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "var_apx2");
|
||||
assert(var == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "var_ap1_1");
|
||||
assert(var == &vars_ap1[0]);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "var_ap1_2");
|
||||
assert(var == &vars_ap1[1]);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "var_ap1_3");
|
||||
assert(var == &vars_ap1[2]);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[0], "var_ap1_4");
|
||||
assert(var == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds[1], "var_ap1_1");
|
||||
assert(var == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds2[1], "var_apx2_1");
|
||||
assert(var == &vars_apx2[0]);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds2[1], "var_apx2_2");
|
||||
assert(var == &vars_apx2[1]);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds2[1], "var_apx2_3");
|
||||
assert(var == &vars_apx2[2]);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds2[1], "var_apx2_4");
|
||||
assert(var == NULL);
|
||||
|
||||
var = cat_search_variable_by_name(&at, &cmds2[0], "var_apx2_1");
|
||||
assert(var == NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
149
components/api/lib/cAT/tests/test_shortcuts.c
Executable file
149
components/api/lib/cAT/tests/test_shortcuts.c
Executable file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int print_name(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, cmd->name);
|
||||
strcat(run_results, " ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+TEST",
|
||||
.run = print_name
|
||||
},
|
||||
{
|
||||
.name = "+TEST_A",
|
||||
.run = print_name
|
||||
},
|
||||
{
|
||||
.name = "+TEST_B",
|
||||
.run = print_name
|
||||
},
|
||||
{
|
||||
.name = "+ONE",
|
||||
.run = print_name
|
||||
},
|
||||
{
|
||||
.name = "+TWO",
|
||||
.run = print_name
|
||||
},
|
||||
};
|
||||
|
||||
static char buf[256];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT\nAT+\nAT+T\nAT+TE\nAT+TES\nAT+TEST\nAT+TEST_\nAT+TEST_A\nAT+TEST_B\nAT+O\nAT+ON\nAT+ONE\nAT+TW\nAT+TWO\n";
|
||||
|
||||
static void print_raw_text(char *p)
|
||||
{
|
||||
while (*p != '\0') {
|
||||
if (*p == '\n') {
|
||||
printf("\\n");
|
||||
} else {
|
||||
putchar(*p);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nERROR\n\nERROR\n\nERROR\n\nERROR\n\nOK\n\nERROR\n\nOK\n\nOK\n\nOK\n\nOK\n\nOK\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(run_results, "+TEST +TEST_A +TEST_B +ONE +ONE +ONE +TWO +TWO ") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
183
components/api/lib/cAT/tests/test_test.c
Executable file
183
components/api/lib/cAT/tests/test_test.c
Executable file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char test_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int a_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(test_results, " A:");
|
||||
strcat(test_results, cmd->name);
|
||||
|
||||
snprintf(data, max_data_size, "%s=A-val", cmd->name);
|
||||
*data_size = strlen(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(test_results, " AP:");
|
||||
strcat(test_results, cmd->name);
|
||||
|
||||
*data_size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(test_results, " AP_W:");
|
||||
strcat(test_results, cmd->name);
|
||||
|
||||
assert(args_num == 0);
|
||||
assert(data[0] == 'a');
|
||||
assert(data_size == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apw_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(test_results, " APW:");
|
||||
strcat(test_results, cmd->name);
|
||||
|
||||
assert(args_num == 0);
|
||||
assert(data[0] == '?');
|
||||
assert(data_size == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(test_results, " +TEST:");
|
||||
strcat(test_results, cmd->name);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.test = a_test
|
||||
},
|
||||
{
|
||||
.name = "AP",
|
||||
.test = ap_test,
|
||||
.write = ap_write
|
||||
},
|
||||
{
|
||||
.name = "APW",
|
||||
.write = apw_write
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.test = test_test
|
||||
},
|
||||
{
|
||||
.name = "+EMPTY"
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(test_results, 0, sizeof(test_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT\r\nAT\nATAP=?\nATAP=?a\nATAP=a\nATAPW=?\nAT+TEST=?\nATA=?\nAT+EMPTY=?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\r\nOK\r\n\nOK\n\nAP=\n\nOK\n\nERROR\n\nOK\n\nOK\n\nERROR\n\nA=A-val\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(test_results, " AP:AP AP_W:AP APW:APW +TEST:+TEST A:A") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
459
components/api/lib/cAT/tests/test_test_args.c
Executable file
459
components/api/lib/cAT/tests/test_test_args.c
Executable file
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char ack_results[256];
|
||||
|
||||
static int8_t var_int8;
|
||||
static int16_t var_int16;
|
||||
static int32_t var_int32;
|
||||
static uint8_t var_uint8;
|
||||
static uint16_t var_uint16;
|
||||
static uint32_t var_uint32;
|
||||
static uint8_t var_hex8;
|
||||
static uint16_t var_hex16;
|
||||
static uint32_t var_hex32;
|
||||
static uint8_t var_buf[4];
|
||||
static char var_string[16];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_override_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(data, "\ntest");
|
||||
*data_size = strlen(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_error_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_ok_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcpy(data, "test1");
|
||||
*data_size = strlen(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_ok2_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(data, "test2");
|
||||
*data_size = strlen(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int8,
|
||||
.data_size = sizeof(var_int8),
|
||||
.name = "x"
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int16,
|
||||
.data_size = sizeof(var_int16),
|
||||
.name = "y"
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int32,
|
||||
.data_size = sizeof(var_int32)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint8,
|
||||
.data_size = sizeof(var_uint8)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint16,
|
||||
.data_size = sizeof(var_uint16)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint32,
|
||||
.data_size = sizeof(var_uint32)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex8,
|
||||
.data_size = sizeof(var_hex8)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex16,
|
||||
.data_size = sizeof(var_hex16)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex32,
|
||||
.data_size = sizeof(var_hex32)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = &var_buf,
|
||||
.data_size = sizeof(var_buf)
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = &var_string,
|
||||
.data_size = sizeof(var_string),
|
||||
.name = "msg"
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_ro[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int8,
|
||||
.data_size = sizeof(var_int8),
|
||||
.name = "x",
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int16,
|
||||
.data_size = sizeof(var_int16),
|
||||
.name = "y",
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int32,
|
||||
.data_size = sizeof(var_int32),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint8,
|
||||
.data_size = sizeof(var_uint8),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint16,
|
||||
.data_size = sizeof(var_uint16),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint32,
|
||||
.data_size = sizeof(var_uint32),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex8,
|
||||
.data_size = sizeof(var_hex8),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex16,
|
||||
.data_size = sizeof(var_hex16),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex32,
|
||||
.data_size = sizeof(var_hex32),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = &var_buf,
|
||||
.data_size = sizeof(var_buf),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = &var_string,
|
||||
.data_size = sizeof(var_string),
|
||||
.name = "msg",
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_wo[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int8,
|
||||
.data_size = sizeof(var_int8),
|
||||
.name = "x",
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int16,
|
||||
.data_size = sizeof(var_int16),
|
||||
.name = "y",
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int32,
|
||||
.data_size = sizeof(var_int32),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint8,
|
||||
.data_size = sizeof(var_uint8),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint16,
|
||||
.data_size = sizeof(var_uint16),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint32,
|
||||
.data_size = sizeof(var_uint32),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex8,
|
||||
.data_size = sizeof(var_hex8),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex16,
|
||||
.data_size = sizeof(var_hex16),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex32,
|
||||
.data_size = sizeof(var_hex32),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = &var_buf,
|
||||
.data_size = sizeof(var_buf),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = &var_string,
|
||||
.data_size = sizeof(var_string),
|
||||
.name = "msg",
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars2[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int8,
|
||||
.data_size = sizeof(var_int8),
|
||||
.name = "var"
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+SETRO",
|
||||
|
||||
.var = vars_ro,
|
||||
.var_num = sizeof(vars_ro) / sizeof(vars_ro[0])
|
||||
},
|
||||
{
|
||||
.name = "+SETWO",
|
||||
|
||||
.var = vars_wo,
|
||||
.var_num = sizeof(vars_wo) / sizeof(vars_wo[0])
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.description = "test_desc",
|
||||
.test = cmd_override_test,
|
||||
|
||||
.var = vars2,
|
||||
.var_num = sizeof(vars2) / sizeof(vars2[0])
|
||||
},
|
||||
{
|
||||
.name = "+TEST2",
|
||||
.description = "test2_desc",
|
||||
|
||||
.var = vars2,
|
||||
.var_num = sizeof(vars2) / sizeof(vars2[0])
|
||||
},
|
||||
{
|
||||
.name = "+AP",
|
||||
.test = cmd_error_test,
|
||||
|
||||
.var = vars2,
|
||||
.var_num = sizeof(vars2) / sizeof(vars2[0])
|
||||
},
|
||||
{
|
||||
.name = "+ZZ",
|
||||
.test = cmd_ok_test,
|
||||
},
|
||||
{
|
||||
.name = "+ZZ2",
|
||||
.description = "zz2_desc",
|
||||
.test = cmd_ok_test,
|
||||
},
|
||||
{
|
||||
.name = "+ZZ3",
|
||||
.description = "zz3_desc",
|
||||
.test = cmd_ok2_test,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[256];
|
||||
static char unsolicited_buf[256];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
.unsolicited_buf = unsolicited_buf,
|
||||
.unsolicited_buf_size = sizeof(unsolicited_buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_int8 = -8;
|
||||
var_int16 = -16;
|
||||
var_int32 = -32;
|
||||
var_uint8 = 8;
|
||||
var_uint8 = 16;
|
||||
var_uint8 = 32;
|
||||
var_hex8 = 0x08;
|
||||
var_hex16 = 0x16;
|
||||
var_hex32 = 0x32;
|
||||
var_hex16 = 0x0123;
|
||||
var_hex32 = 0xFF001234;
|
||||
|
||||
var_buf[0] = 0x12;
|
||||
var_buf[1] = 0x34;
|
||||
var_buf[2] = 0x56;
|
||||
var_buf[3] = 0x78;
|
||||
|
||||
sprintf(var_string, "TST");
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=?\n";
|
||||
static const char test_case_1_ro[] = "\nAT+SETRO=?\n";
|
||||
static const char test_case_1_wo[] = "\nAT+SETWO=?\n";
|
||||
static const char test_case_2[] = "\nAT+TEST=?\nAT+TEST2=?\r\nAT+AP=?\n";
|
||||
static const char test_case_3[] = "\nAT+ZZ=?\nAT+ZZ2=?\nAT+ZZ3=?\r\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+SET=<x:INT8[RW]>,<y:INT16[RW]>,<INT32[RW]>,<UINT8[RW]>,<UINT16[RW]>,<UINT32[RW]>,<HEX8[RW]>,<HEX16[RW]>,<HEX32[RW]>,<HEXBUF[RW]>,<msg:STRING[RW]>\n\nOK\n") == 0);
|
||||
|
||||
prepare_input(test_case_1_ro);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+SETRO=<x:INT8[RO]>,<y:INT16[RO]>,<INT32[RO]>,<UINT8[RO]>,<UINT16[RO]>,<UINT32[RO]>,<HEX8[RO]>,<HEX16[RO]>,<HEX32[RO]>,<HEXBUF[RO]>,<msg:STRING[RO]>\n\nOK\n") == 0);
|
||||
|
||||
prepare_input(test_case_1_wo);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+SETWO=<x:INT8[WO]>,<y:INT16[WO]>,<INT32[WO]>,<UINT8[WO]>,<UINT16[WO]>,<UINT32[WO]>,<HEX8[WO]>,<HEX16[WO]>,<HEX32[WO]>,<HEXBUF[WO]>,<msg:STRING[WO]>\n\nOK\n") == 0);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+TEST=<var:INT8[RW]>\ntest_desc\ntest\n\nOK\n\r\n+TEST2=<var:INT8[RW]>\r\ntest2_desc\r\n\r\nOK\r\n\nERROR\n") == 0);
|
||||
|
||||
prepare_input(test_case_3);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\ntest1\n\nOK\n\ntest1\n\nOK\n\r\n+ZZ3=\r\nzz3_desctest2\r\n\r\nOK\r\n") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
173
components/api/lib/cAT/tests/test_test_only.c
Executable file
173
components/api/lib/cAT/tests/test_test_only.c
Executable file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char cmd_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int ap_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(cmd_results, " test:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
strcpy(data, "ap_test");
|
||||
*data_size = strlen(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(cmd_results, " run:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
strcat(cmd_results, " read:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
strcpy(data, "ap_read");
|
||||
*data_size = strlen(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(cmd_results, " write:");
|
||||
strcat(cmd_results, cmd->name);
|
||||
|
||||
assert(strcmp(data, "1") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "AP1",
|
||||
.test = ap_test,
|
||||
.write = ap_write,
|
||||
.read = ap_read,
|
||||
.run = ap_run,
|
||||
.only_test = true
|
||||
},
|
||||
{
|
||||
.name = "AP2",
|
||||
.test = ap_test,
|
||||
.write = ap_write,
|
||||
.read = ap_read,
|
||||
.run = ap_run,
|
||||
.only_test = false
|
||||
},
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(cmd_results, 0, sizeof(cmd_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nATAP1=?\n\nATAP1?\n\nATAP1=1\n\nATAP1\n";
|
||||
static const char test_case_2[] = "\nATAP2=?\n\nATAP2?\n\nATAP2=1\n\nATAP2\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nap_test\n\nOK\n\nERROR\n\nERROR\n\nERROR\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:AP1") == 0);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nap_test\n\nOK\n\nap_read\n\nOK\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(cmd_results, " test:AP2 read:AP2 write:AP2 run:AP2") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
203
components/api/lib/cAT/tests/test_unsolicited_read.c
Executable file
203
components/api/lib/cAT/tests/test_unsolicited_read.c
Executable file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char read_results[256];
|
||||
static char var_read_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x, var_u1, var_u2;
|
||||
static struct cat_object at;
|
||||
|
||||
static struct cat_command u_cmds[];
|
||||
|
||||
static cat_return_state cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(read_results, " read:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
if (strcmp(cmd->name, "+CMD") == 0) {
|
||||
s = cat_trigger_unsolicited_read(&at, &u_cmds[1]);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
}
|
||||
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
static int var_read(const struct cat_variable *var)
|
||||
{
|
||||
strcat(var_read_results, " var_read:");
|
||||
strcat(var_read_results, var->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable u_vars[] = {
|
||||
{
|
||||
.name = "U1",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u1,
|
||||
.data_size = sizeof(var_u1),
|
||||
.read = var_read
|
||||
},
|
||||
{
|
||||
.name = "U2",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u2,
|
||||
.data_size = sizeof(var_u2),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command u_cmds[] = {
|
||||
{
|
||||
.name = "+U1CMD",
|
||||
.read = cmd_read,
|
||||
.var = &u_vars[0],
|
||||
.var_num = 1,
|
||||
},
|
||||
{
|
||||
.name = "+U2CMD",
|
||||
.read = cmd_read,
|
||||
.var = &u_vars[1],
|
||||
.var_num = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_x = 1;
|
||||
var_u1 = 2;
|
||||
var_u2 = 3;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(read_results, 0, sizeof(read_results));
|
||||
memset(var_read_results, 0, sizeof(var_read_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_trigger_unsolicited_event(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_ERROR_BUFFER_FULL);
|
||||
s = cat_trigger_unsolicited_read(&at, &u_cmds[1]);
|
||||
assert(s == CAT_STATUS_ERROR_BUFFER_FULL);
|
||||
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+U1CMD=2\n\n+CMD=1\n\n+U2CMD=3\n\nOK\n") == 0);
|
||||
assert(strcmp(read_results, " read:+U1CMD read:+CMD read:+U2CMD") == 0);
|
||||
assert(strcmp(var_read_results, " var_read:U1 var_read:X var_read:U2") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
238
components/api/lib/cAT/tests/test_unsolicited_read_buffer.c
Executable file
238
components/api/lib/cAT/tests/test_unsolicited_read_buffer.c
Executable file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char read_results[256];
|
||||
static char var_read_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x, var_u1, var_u2;
|
||||
static struct cat_object at;
|
||||
|
||||
static struct cat_command u_cmds[];
|
||||
|
||||
static cat_return_state cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(read_results, " read:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
if (strcmp(cmd->name, "+CMD") == 0) {
|
||||
s = cat_trigger_unsolicited_read(&at, &u_cmds[1]);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
}
|
||||
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
static int var_read(const struct cat_variable *var)
|
||||
{
|
||||
strcat(var_read_results, " var_read:");
|
||||
strcat(var_read_results, var->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable u_vars[] = {
|
||||
{
|
||||
.name = "U1",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u1,
|
||||
.data_size = sizeof(var_u1),
|
||||
.read = var_read
|
||||
},
|
||||
{
|
||||
.name = "U2",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u2,
|
||||
.data_size = sizeof(var_u2),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command u_cmds[] = {
|
||||
{
|
||||
.name = "+U1CMD",
|
||||
.read = cmd_read,
|
||||
.var = &u_vars[0],
|
||||
.var_num = 1,
|
||||
},
|
||||
{
|
||||
.name = "+U2CMD",
|
||||
.read = cmd_read,
|
||||
.var = &u_vars[1],
|
||||
.var_num = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_x = 1;
|
||||
var_u1 = 2;
|
||||
var_u2 = 3;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(read_results, 0, sizeof(read_results));
|
||||
memset(var_read_results, 0, sizeof(var_read_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_trigger_unsolicited_event(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_TEST);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_trigger_unsolicited_event(&at, &u_cmds[1], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_TEST);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[1], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[1], CAT_CMD_TYPE_TEST);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[1], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_ERROR_BUFFER_FULL);
|
||||
s = cat_trigger_unsolicited_read(&at, &u_cmds[1]);
|
||||
assert(s == CAT_STATUS_ERROR_BUFFER_FULL);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_TEST);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[1], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+U1CMD=2\n\n+CMD=1\n\n+U2CMD=3\n\nOK\n\n+U2CMD=3\n") == 0);
|
||||
assert(strcmp(read_results, " read:+U1CMD read:+CMD read:+U2CMD read:+U2CMD") == 0);
|
||||
assert(strcmp(var_read_results, " var_read:U1 var_read:X var_read:U2 var_read:U2") == 0);
|
||||
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
211
components/api/lib/cAT/tests/test_unsolicited_read_stress.c
Executable file
211
components/api/lib/cAT/tests/test_unsolicited_read_stress.c
Executable file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char read_results[256];
|
||||
static char var_read_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x, var_u1;
|
||||
static struct cat_object at;
|
||||
|
||||
static struct cat_command u_cmds[];
|
||||
|
||||
static cat_return_state cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(read_results, " read:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
static int var_read(const struct cat_variable *var)
|
||||
{
|
||||
strcat(var_read_results, " var_read:");
|
||||
strcat(var_read_results, var->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable u_vars[] = {
|
||||
{
|
||||
.name = "U1",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u1,
|
||||
.data_size = sizeof(var_u1),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x),
|
||||
.read = var_read
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.read = cmd_read,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command u_cmds[] = {
|
||||
{
|
||||
.name = "+UCMD",
|
||||
.read = cmd_read,
|
||||
.var = u_vars,
|
||||
.var_num = sizeof(u_vars) / sizeof(u_vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_x = 1;
|
||||
var_u1 = 2;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(read_results, 0, sizeof(read_results));
|
||||
memset(var_read_results, 0, sizeof(var_read_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
int events = 4;
|
||||
struct cat_command const *cmd;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
|
||||
cmd = cat_get_processed_command(&at, CAT_FSM_TYPE_ATCMD);
|
||||
assert(cmd == NULL);
|
||||
cmd = cat_get_processed_command(&at, CAT_FSM_TYPE_UNSOLICITED);
|
||||
assert(cmd == NULL);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
|
||||
while (events > 0) {
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
cmd = cat_get_processed_command(&at, CAT_FSM_TYPE_UNSOLICITED);
|
||||
if ((s == CAT_STATUS_OK) && (cmd == NULL)) {
|
||||
var_u1 = events;
|
||||
s = cat_trigger_unsolicited_event(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
events--;
|
||||
} else {
|
||||
assert(cmd == &u_cmds[0]);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_READ);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_TEST);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_event_buffered(&at, &u_cmds[0], CAT_CMD_TYPE_NONE);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
}
|
||||
s = cat_service(&at);
|
||||
assert(s == CAT_STATUS_BUSY);
|
||||
}
|
||||
|
||||
while (cat_service(&at) != 0) {};
|
||||
cmd = cat_get_processed_command(&at, CAT_FSM_TYPE_ATCMD);
|
||||
assert(cmd == NULL);
|
||||
cmd = cat_get_processed_command(&at, CAT_FSM_TYPE_UNSOLICITED);
|
||||
assert(cmd == NULL);
|
||||
|
||||
assert(strcmp(ack_results, "\n+UCMD=4\n\n+CMD=1\n\n+UCMD=3\n\nOK\n\n+UCMD=2\n\n+UCMD=1\n") == 0);
|
||||
assert(strcmp(read_results, " read:+UCMD read:+CMD read:+UCMD read:+UCMD read:+UCMD") == 0);
|
||||
assert(strcmp(var_read_results, " var_read:U1 var_read:X var_read:U1 var_read:U1 var_read:U1") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
189
components/api/lib/cAT/tests/test_unsolicited_test.c
Executable file
189
components/api/lib/cAT/tests/test_unsolicited_test.c
Executable file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char read_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var_x, var_u1, var_u2;
|
||||
static struct cat_object at;
|
||||
|
||||
static struct cat_command u_cmds[];
|
||||
|
||||
static cat_return_state cmd_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
strcat(read_results, " test:");
|
||||
strcat(read_results, cmd->name);
|
||||
|
||||
if (strcmp(cmd->name, "+CMD") == 0) {
|
||||
s = cat_trigger_unsolicited_test(&at, &u_cmds[1]);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
}
|
||||
|
||||
return CAT_RETURN_STATE_DATA_OK;
|
||||
}
|
||||
|
||||
static struct cat_variable u_vars[] = {
|
||||
{
|
||||
.name = "U1",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u1,
|
||||
.data_size = sizeof(var_u1)
|
||||
},
|
||||
{
|
||||
.name = "U2",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_u2,
|
||||
.data_size = sizeof(var_u2)
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.name = "X",
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_x,
|
||||
.data_size = sizeof(var_x)
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+CMD",
|
||||
.test = cmd_test,
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command u_cmds[] = {
|
||||
{
|
||||
.name = "+U1CMD",
|
||||
.test = cmd_test,
|
||||
.var = &u_vars[0],
|
||||
.var_num = 1,
|
||||
},
|
||||
{
|
||||
.name = "+U2CMD",
|
||||
.test = cmd_test,
|
||||
.var = &u_vars[1],
|
||||
.var_num = 1,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var_x = 1;
|
||||
var_u1 = 2;
|
||||
var_u2 = 3;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(read_results, 0, sizeof(read_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+CMD=?\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cat_status s;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_trigger_unsolicited_event(&at, &u_cmds[0], CAT_CMD_TYPE_TEST);
|
||||
assert(s == CAT_STATUS_OK);
|
||||
s = cat_is_unsolicited_buffer_full(&at);
|
||||
assert(s == CAT_STATUS_ERROR_BUFFER_FULL);
|
||||
s = cat_trigger_unsolicited_test(&at, &u_cmds[1]);
|
||||
assert(s == CAT_STATUS_ERROR_BUFFER_FULL);
|
||||
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+U1CMD=<U1:INT32[RW]>\n\n+CMD=<X:INT32[RW]>\n\n+U2CMD=<U2:INT32[RW]>\n\nOK\n") == 0);
|
||||
assert(strcmp(read_results, " test:+U1CMD test:+CMD test:+U2CMD") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
545
components/api/lib/cAT/tests/test_var_access.c
Executable file
545
components/api/lib/cAT/tests/test_var_access.c
Executable file
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char ack_results[256];
|
||||
|
||||
static int8_t var1;
|
||||
static int8_t var2;
|
||||
static int8_t var3;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int var2_write_cntr;
|
||||
static int var3_read_cntr;
|
||||
|
||||
static int8_t var_int8;
|
||||
static int16_t var_int16;
|
||||
static int32_t var_int32;
|
||||
static uint8_t var_uint8;
|
||||
static uint16_t var_uint16;
|
||||
static uint32_t var_uint32;
|
||||
static uint8_t var_hex8;
|
||||
static uint16_t var_hex16;
|
||||
static uint32_t var_hex32;
|
||||
static uint8_t var_buf[4];
|
||||
static char var_string[16];
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_read(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_test(const struct cat_command *cmd, uint8_t *data, size_t *data_size, const size_t max_data_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_run(const struct cat_command *cmd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_read(const struct cat_variable *var)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
var2_write_cntr++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_read(const struct cat_variable *var)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var3_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var3_read(const struct cat_variable *var)
|
||||
{
|
||||
var3_read_cntr++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_cmd_list(const struct cat_command *cmd)
|
||||
{
|
||||
return CAT_RETURN_STATE_PRINT_CMD_LIST_OK;
|
||||
}
|
||||
|
||||
static struct cat_variable vars_ro[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write,
|
||||
.read = var2_read,
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_wo[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var3,
|
||||
.data_size = sizeof(var3),
|
||||
.write = var3_write,
|
||||
.read = var3_read,
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write,
|
||||
.read = var1_read,
|
||||
.access = CAT_VAR_ACCESS_READ_WRITE
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write,
|
||||
.read = var2_read,
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var3,
|
||||
.data_size = sizeof(var3),
|
||||
.write = var3_write,
|
||||
.read = var3_read,
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_misc_ro[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.access = CAT_VAR_ACCESS_READ_WRITE
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int8,
|
||||
.data_size = sizeof(var_int8),
|
||||
.name = "x",
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int16,
|
||||
.data_size = sizeof(var_int16),
|
||||
.name = "y",
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int32,
|
||||
.data_size = sizeof(var_int32),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint8,
|
||||
.data_size = sizeof(var_uint8),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint16,
|
||||
.data_size = sizeof(var_uint16),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint32,
|
||||
.data_size = sizeof(var_uint32),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex8,
|
||||
.data_size = sizeof(var_hex8),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex16,
|
||||
.data_size = sizeof(var_hex16),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex32,
|
||||
.data_size = sizeof(var_hex32),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = &var_buf,
|
||||
.data_size = sizeof(var_buf),
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = &var_string,
|
||||
.data_size = sizeof(var_string),
|
||||
.name = "msg",
|
||||
.access = CAT_VAR_ACCESS_READ_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_variable vars_misc_wo[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.access = CAT_VAR_ACCESS_READ_WRITE
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int8,
|
||||
.data_size = sizeof(var_int8),
|
||||
.name = "x",
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int16,
|
||||
.data_size = sizeof(var_int16),
|
||||
.name = "y",
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var_int32,
|
||||
.data_size = sizeof(var_int32),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint8,
|
||||
.data_size = sizeof(var_uint8),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint16,
|
||||
.data_size = sizeof(var_uint16),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var_uint32,
|
||||
.data_size = sizeof(var_uint32),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex8,
|
||||
.data_size = sizeof(var_hex8),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex16,
|
||||
.data_size = sizeof(var_hex16),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var_hex32,
|
||||
.data_size = sizeof(var_hex32),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = &var_buf,
|
||||
.data_size = sizeof(var_buf),
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = &var_string,
|
||||
.data_size = sizeof(var_string),
|
||||
.name = "msg",
|
||||
.access = CAT_VAR_ACCESS_WRITE_ONLY
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+VRW",
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+VRO",
|
||||
.var = vars_ro,
|
||||
.var_num = sizeof(vars_ro) / sizeof(vars_ro[0])
|
||||
},
|
||||
{
|
||||
.name = "+VWO",
|
||||
.var = vars_wo,
|
||||
.var_num = sizeof(vars_wo) / sizeof(vars_wo[0])
|
||||
},
|
||||
{
|
||||
.name = "+MRO",
|
||||
.var = vars_misc_ro,
|
||||
.var_num = sizeof(vars_misc_ro) / sizeof(vars_misc_ro[0])
|
||||
},
|
||||
{
|
||||
.name = "+MWO",
|
||||
.var = vars_misc_wo,
|
||||
.var_num = sizeof(vars_misc_wo) / sizeof(vars_misc_wo[0])
|
||||
},
|
||||
{
|
||||
.name = "#HELP",
|
||||
.run = print_cmd_list,
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[256];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
}
|
||||
|
||||
static void print_raw_text(char *p)
|
||||
{
|
||||
while (*p != '\0') {
|
||||
if (*p == '\n') {
|
||||
printf("\\n");
|
||||
} else {
|
||||
putchar(*p);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input("\nAT#HELP\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nAT+VRW?\nAT+VRW=\nAT+VRW=?\n\nAT+VRO?\nAT+VRO=?\n\nAT+VWO=\nAT+VWO=?\n\nAT+MRO?\nAT+MRO=\nAT+MRO=?\n\nAT+MWO?\nAT+MWO=\nAT+MWO=?\n\nAT#HELP\n\nOK\n") == 0);
|
||||
|
||||
prepare_input("\nAT+VRW=?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+VRW=<INT8[RW]>,<INT8[RO]>,<INT8[WO]>\n\nOK\n") == 0);
|
||||
|
||||
prepare_input("\nAT+VRO=?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+VRO=<INT8[RO]>\n\nOK\n") == 0);
|
||||
|
||||
prepare_input("\nAT+VWO=?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+VWO=<INT8[WO]>\n\nOK\n") == 0);
|
||||
|
||||
var2 = 1;
|
||||
prepare_input("\nAT+VRO=1\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(var2 == 1);
|
||||
|
||||
var3 = 3;
|
||||
prepare_input("\nAT+VWO?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n") == 0);
|
||||
assert(var3 == 3);
|
||||
|
||||
var1 = -1;
|
||||
var2 = -2;
|
||||
var3 = -3;
|
||||
var2_write_cntr = 0;
|
||||
var3_read_cntr = 0;
|
||||
|
||||
prepare_input("\nAT+VRW?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+VRW=-1,-2,0\n\nOK\n") == 0);
|
||||
assert(var2_write_cntr == 0);
|
||||
assert(var3_read_cntr == 1);
|
||||
|
||||
prepare_input("\nAT+VRW=1,2,3\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(var2_write_cntr == 1);
|
||||
assert(var3_read_cntr == 1);
|
||||
assert(var1 == 1);
|
||||
assert(var2 == -2);
|
||||
assert(var3 == 3);
|
||||
|
||||
var1 = 100;
|
||||
var_int8 = 1;
|
||||
var_int16 = 2;
|
||||
var_int32 = 3;
|
||||
var_uint8 = 4;
|
||||
var_uint16 = 5;
|
||||
var_uint32 = 6;
|
||||
var_hex8 = 7;
|
||||
var_hex16 = 8;
|
||||
var_hex32 = 9;
|
||||
var_buf[0] = 0x10;
|
||||
var_buf[1] = 0x11;
|
||||
var_buf[2] = 0x12;
|
||||
var_buf[3] = 0x13;
|
||||
strcpy(var_string, "test_string");
|
||||
|
||||
prepare_input("\nAT+MWO?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+MWO=100,0,0,0,0,0,0,0x00,0x0000,0x00000000,00000000,\"\"\n\nOK\n") == 0);
|
||||
|
||||
prepare_input("\nAT+MWO=1,2,3,4,5,6,7,0x08,0x0009,0x0000000A,01020304,\"abc\"\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(var1 == 1);
|
||||
assert(var_int8 == 2);
|
||||
assert(var_int16 == 3);
|
||||
assert(var_int32 == 4);
|
||||
assert(var_uint8 == 5);
|
||||
assert(var_uint16 == 6);
|
||||
assert(var_uint32 == 7);
|
||||
assert(var_hex8 == 8);
|
||||
assert(var_hex16 == 9);
|
||||
assert(var_hex32 == 10);
|
||||
assert(var_buf[0] == 0x01);
|
||||
assert(var_buf[1] == 0x02);
|
||||
assert(var_buf[2] == 0x03);
|
||||
assert(var_buf[3] == 0x04);
|
||||
assert(strcmp(var_string, "abc") == 0);
|
||||
|
||||
prepare_input("\nAT+MRO?\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\n+MRO=1,2,3,4,5,6,7,0x08,0x0009,0x0000000A,01020304,\"abc\"\n\nOK\n") == 0);
|
||||
|
||||
prepare_input("\nAT+MRO=2,0,0,0,0,0,0,0x00,0x0000,0x00000000,00000000,\"cba\"\n");
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n") == 0);
|
||||
assert(var1 == 2);
|
||||
assert(var_int8 == 2);
|
||||
assert(var_int16 == 3);
|
||||
assert(var_int32 == 4);
|
||||
assert(var_uint8 == 5);
|
||||
assert(var_uint16 == 6);
|
||||
assert(var_uint32 == 7);
|
||||
assert(var_hex8 == 8);
|
||||
assert(var_hex16 == 9);
|
||||
assert(var_hex32 == 10);
|
||||
assert(var_buf[0] == 0x01);
|
||||
assert(var_buf[1] == 0x02);
|
||||
assert(var_buf[2] == 0x03);
|
||||
assert(var_buf[3] == 0x04);
|
||||
assert(strcmp(var_string, "abc") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
166
components/api/lib/cAT/tests/test_write.c
Executable file
166
components/api/lib/cAT/tests/test_write.c
Executable file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char run_results[256];
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int a_run(const struct cat_command *cmd)
|
||||
{
|
||||
strcat(run_results, " A_");
|
||||
strcat(run_results, cmd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " A:");
|
||||
strncat(write_results, data, data_size);
|
||||
|
||||
assert(args_num == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " AP:");
|
||||
strncat(write_results, data, data_size);
|
||||
|
||||
assert(args_num == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " +TEST:");
|
||||
strncat(write_results, data, data_size);
|
||||
|
||||
assert(args_num == 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.write = a_write,
|
||||
.run = a_run
|
||||
},
|
||||
{
|
||||
.name = "AP",
|
||||
.write = ap_write
|
||||
},
|
||||
{
|
||||
.name = "+TEST",
|
||||
.write = test_write
|
||||
},
|
||||
{
|
||||
.name = "+EMPTY"
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(run_results, 0, sizeof(run_results));
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT\nAT+\nAT+?\nATA=123\r\nATA=\nATAP?\nATAP=11\r22\r\nAT+TEST=456\nAT+te=789\nAT+e=1\nAT+empTY=2\r\nATA\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nERROR\n\nERROR\n\r\nOK\r\n\nOK\n\nERROR\n\r\nOK\r\n\nERROR\n\nERROR\n\nERROR\n\r\nERROR\r\n\nOK\n") == 0);
|
||||
assert(strcmp(run_results, " A_A") == 0);
|
||||
assert(strcmp(write_results, " A:123 A: AP:1122 +TEST:456 +TEST:789") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
174
components/api/lib/cAT/tests/test_write_hex_buffer.c
Executable file
174
components/api/lib/cAT/tests/test_write_hex_buffer.c
Executable file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static uint8_t var[4];
|
||||
static size_t var_write_size[4];
|
||||
static int var_write_size_index;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " CMD:");
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
var_write_size[var_write_size_index++] = write_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_BUF_HEX,
|
||||
.data = var,
|
||||
.data_size = sizeof(var),
|
||||
.write = var_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
.write = cmd_write,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(var, 0, sizeof(var));
|
||||
memset(var_write_size, 0, sizeof(var_write_size));
|
||||
var_write_size_index = 0;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=0\nAT+SET=aa\nAT+SET=001\nAT+SET=12345678\nAT+SET=ffAA\n";
|
||||
static const char test_case_2[] = "\nAT+SET=0x11\nAT+SET=11\nAT+SET=-1\nAT+SET=87654321\nAT+SET=0001\nAT+SET=1122334455\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nERROR\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:aa CMD:12345678 CMD:ffAA") == 0);
|
||||
|
||||
assert(var[0] == 0xFF);
|
||||
assert(var[1] == 0xAA);
|
||||
assert(var[2] == 0x56);
|
||||
assert(var[3] == 0x78);
|
||||
|
||||
assert(var_write_size[0] == 1);
|
||||
assert(var_write_size[1] == 4);
|
||||
assert(var_write_size[2] == 2);
|
||||
assert(var_write_size[3] == 0);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nERROR\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:11 CMD:87654321 CMD:0001") == 0);
|
||||
|
||||
assert(var[0] == 0x11);
|
||||
assert(var[1] == 0x22);
|
||||
assert(var[2] == 0x33);
|
||||
assert(var[3] == 0x44);
|
||||
|
||||
assert(var_write_size[0] == 1);
|
||||
assert(var_write_size[1] == 4);
|
||||
assert(var_write_size[2] == 2);
|
||||
assert(var_write_size[3] == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
212
components/api/lib/cAT/tests/test_write_hex_range.c
Executable file
212
components/api/lib/cAT/tests/test_write_hex_range.c
Executable file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static uint8_t var1, var1b;
|
||||
static uint16_t var2, var2b;
|
||||
static uint32_t var3, var3b;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " CMD:");
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 1);
|
||||
var1b = *(uint8_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 2);
|
||||
var2b = *(uint16_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var3_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 4);
|
||||
var3b = *(uint32_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_NUM_HEX,
|
||||
.data = &var3,
|
||||
.data_size = sizeof(var3),
|
||||
.write = var3_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
.write = cmd_write,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var1 = 1;
|
||||
var2 = 2;
|
||||
var3 = 3;
|
||||
var1b = 10;
|
||||
var2b = 20;
|
||||
var3b = 30;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=0\nAT+SET=0x0\nAT+SET=0x01\nAT+SET=0x0ff\nAT+SET=0x100\n";
|
||||
static const char test_case_2[] = "\nAT+SET=0x,0x00\nAT+SET=0x1,0x00\nAT+SET=0x2,0xFFf\nAT+SET=0x3,0xFFFF\nAT+SET=0x4,0xFFFFF\n";
|
||||
static const char test_case_3[] = "\nAT+SET=0x0,0x0,0\nAT+SET=0x0,0x0,0x0000000000000\nAT+SET=0x0,0x0,0x1\nAT+SET=0x0,0x0,0xffffFFFF\nAT+SET=0x10,0x20,0x100000000\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0x0 CMD:0x01 CMD:0x0ff") == 0);
|
||||
|
||||
assert(var1 == 255);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 2);
|
||||
assert(var2b == 20);
|
||||
assert(var3 == 3);
|
||||
assert(var3b == 30);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0x1,0x00 CMD:0x2,0xFFf CMD:0x3,0xFFFF") == 0);
|
||||
|
||||
assert(var1 == 4);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 0xFFFF);
|
||||
assert(var2b == var2);
|
||||
assert(var3 == 3);
|
||||
assert(var3b == 30);
|
||||
|
||||
prepare_input(test_case_3);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0x0,0x0,0x0000000000000 CMD:0x0,0x0,0x1 CMD:0x0,0x0,0xffffFFFF") == 0);
|
||||
|
||||
assert(var1 == 0x10);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 0x20);
|
||||
assert(var2b == var2);
|
||||
assert(var3 == 0xFFFFFFFF);
|
||||
assert(var3b == var3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
212
components/api/lib/cAT/tests/test_write_int_range.c
Executable file
212
components/api/lib/cAT/tests/test_write_int_range.c
Executable file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static int8_t var1, var1b;
|
||||
static int16_t var2, var2b;
|
||||
static int32_t var3, var3b;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " CMD:");
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 1);
|
||||
var1b = *(int8_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 2);
|
||||
var2b = *(int16_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var3_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 4);
|
||||
var3b = *(int32_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var3,
|
||||
.data_size = sizeof(var3),
|
||||
.write = var3_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
.write = cmd_write,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf),
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var1 = 1;
|
||||
var2 = 2;
|
||||
var3 = 3;
|
||||
var1b = -1;
|
||||
var2b = -2;
|
||||
var3b = -3;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=-128\nAT+SET=-129\nAT+SET=127\nAT+SET=128\n";
|
||||
static const char test_case_2[] = "\nAT+SET=-128,-32768\nAT+SET=-128,-40000\nAT+SET=-128,32767\nAT+SET=-100,40000\n";
|
||||
static const char test_case_3[] = "\nAT+SET=0,0,-2147483648\nAT+SET=0,0,-2147483649\nAT+SET=1,1,2147483647\nAT+SET=2,2,2147483648\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nERROR\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:-128 CMD:127") == 0);
|
||||
|
||||
assert(var1 == 127);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 2);
|
||||
assert(var2b == -2);
|
||||
assert(var3 == 3);
|
||||
assert(var3b == -3);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nERROR\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:-128,-32768 CMD:-128,32767") == 0);
|
||||
|
||||
assert(var1 == -100);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 32767);
|
||||
assert(var2b == var2);
|
||||
assert(var3 == 3);
|
||||
assert(var3b == -3);
|
||||
|
||||
prepare_input(test_case_3);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nERROR\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0,0,-2147483648 CMD:1,1,2147483647") == 0);
|
||||
|
||||
assert(var1 == 2);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 2);
|
||||
assert(var2b == var2);
|
||||
assert(var3 == 2147483647);
|
||||
assert(var3b == var3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
234
components/api/lib/cAT/tests/test_write_parse.c
Executable file
234
components/api/lib/cAT/tests/test_write_parse.c
Executable file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static int8_t var1, var2, var3;
|
||||
static int8_t var1b, var2b, var3b;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write1(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, " CMD1_%ld:", args_num);
|
||||
strcat(write_results, tmp);
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_write3(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, " CMD3_%ld:", args_num);
|
||||
strcat(write_results, tmp);
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 1);
|
||||
var1b = *(int8_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 1);
|
||||
var2b = *(int8_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var3_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 1);
|
||||
var3b = *(int8_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_INT_DEC,
|
||||
.data = &var3,
|
||||
.data_size = sizeof(var3),
|
||||
.write = var3_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET1",
|
||||
.write = cmd_write1,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+SET3",
|
||||
.write = cmd_write3,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
},
|
||||
{
|
||||
.name = "+SETALL",
|
||||
.write = cmd_write3,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0]),
|
||||
.need_all_vars = true
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var1 = 1;
|
||||
var2 = 2;
|
||||
var3 = 3;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=-10,-20,-30\r\nAT+SET1=-10,-20,-30\r\nAT+SET1=-1\r\n";
|
||||
static const char test_case_2[] = "\nAT+SET3=-1,-2,-3,0\nAT+SET3=-1,-2,-3\nAT+SET3=-100\n";
|
||||
static const char test_case_3[] = "\nAT+SETALL=-11,-22,-33\nAT+SETALL=-1,-2,-3\nAT+SETALL=100\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\r\nERROR\r\n\r\nOK\r\n\r\nOK\r\n") == 0);
|
||||
assert(strcmp(write_results, " CMD1_3:-10,-20,-30 CMD1_1:-1") == 0);
|
||||
|
||||
assert(var1 == -1);
|
||||
assert(var2 == -20);
|
||||
assert(var3 == -30);
|
||||
assert(var1b == -1);
|
||||
assert(var2b == -20);
|
||||
assert(var3b == -30);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(write_results, " CMD3_3:-1,-2,-3 CMD3_1:-100") == 0);
|
||||
|
||||
assert(var1 == -100);
|
||||
assert(var2 == -2);
|
||||
assert(var3 == -3);
|
||||
assert(var1b == -100);
|
||||
assert(var2b == -2);
|
||||
assert(var3b == -3);
|
||||
|
||||
prepare_input(test_case_3);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD3_3:-11,-22,-33 CMD3_3:-1,-2,-3") == 0);
|
||||
|
||||
assert(var1 == 100);
|
||||
assert(var2 == -2);
|
||||
assert(var3 == -3);
|
||||
assert(var1b == 100);
|
||||
assert(var2b == -2);
|
||||
assert(var3b == -3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
168
components/api/lib/cAT/tests/test_write_string_buffer.c
Executable file
168
components/api/lib/cAT/tests/test_write_string_buffer.c
Executable file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static uint8_t var[8];
|
||||
static size_t var_write_size[4];
|
||||
static int var_write_size_index;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " CMD:");
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
var_write_size[var_write_size_index++] = write_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_BUF_STRING,
|
||||
.data = var,
|
||||
.data_size = sizeof(var),
|
||||
.write = var_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
.write = cmd_write,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
memset(var, 0, sizeof(var));
|
||||
memset(var_write_size, 0, sizeof(var_write_size));
|
||||
var_write_size_index = 0;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=0\nAT+SET=\"\\\"abcd\\\"\"\nAT+SET=\"\"a\nAT+SET=\"1122334\"\nAT+SET=\"t\"\r\n";
|
||||
static const char test_case_2[] = "\nAT+SET=\"12345678\"\nAT+SET=\"\"\nAT+SET=\"\\\\\\\\\"\nAT+SET=\"r1\\nr2\\n\"\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nERROR\n\nOK\n\r\nOK\r\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:\"\\\"abcd\\\"\" CMD:\"1122334\" CMD:\"t\"") == 0);
|
||||
|
||||
assert(strcmp(var, "t") == 0);
|
||||
|
||||
assert(var_write_size[0] == 6);
|
||||
assert(var_write_size[1] == 7);
|
||||
assert(var_write_size[2] == 1);
|
||||
assert(var_write_size[3] == 0);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nOK\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:\"\" CMD:\"\\\\\\\\\" CMD:\"r1\\nr2\\n\"") == 0);
|
||||
|
||||
assert(strcmp(var, "r1\nr2\n") == 0);
|
||||
|
||||
assert(var_write_size[0] == 0);
|
||||
assert(var_write_size[1] == 2);
|
||||
assert(var_write_size[2] == 6);
|
||||
assert(var_write_size[3] == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
212
components/api/lib/cAT/tests/test_write_uint_range.c
Executable file
212
components/api/lib/cAT/tests/test_write_uint_range.c
Executable file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Marcin Borowicz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../src/cat.h"
|
||||
|
||||
static char write_results[256];
|
||||
static char ack_results[256];
|
||||
|
||||
static uint8_t var1, var1b;
|
||||
static uint16_t var2, var2b;
|
||||
static uint32_t var3, var3b;
|
||||
|
||||
static char const *input_text;
|
||||
static size_t input_index;
|
||||
|
||||
static int cmd_write(const struct cat_command *cmd, const uint8_t *data, const size_t data_size, const size_t args_num)
|
||||
{
|
||||
strcat(write_results, " CMD:");
|
||||
strncat(write_results, data, data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var1_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 1);
|
||||
var1b = *(uint8_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var2_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 2);
|
||||
var2b = *(uint16_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int var3_write(const struct cat_variable *var, size_t write_size)
|
||||
{
|
||||
assert(write_size == 4);
|
||||
var3b = *(uint32_t*)(var->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cat_variable vars[] = {
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var1,
|
||||
.data_size = sizeof(var1),
|
||||
.write = var1_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var2,
|
||||
.data_size = sizeof(var2),
|
||||
.write = var2_write
|
||||
},
|
||||
{
|
||||
.type = CAT_VAR_UINT_DEC,
|
||||
.data = &var3,
|
||||
.data_size = sizeof(var3),
|
||||
.write = var3_write
|
||||
}
|
||||
};
|
||||
|
||||
static struct cat_command cmds[] = {
|
||||
{
|
||||
.name = "+SET",
|
||||
.write = cmd_write,
|
||||
|
||||
.var = vars,
|
||||
.var_num = sizeof(vars) / sizeof(vars[0])
|
||||
}
|
||||
};
|
||||
|
||||
static char buf[128];
|
||||
|
||||
static struct cat_command_group cmd_group = {
|
||||
.cmd = cmds,
|
||||
.cmd_num = sizeof(cmds) / sizeof(cmds[0]),
|
||||
};
|
||||
|
||||
static struct cat_command_group *cmd_desc[] = {
|
||||
&cmd_group
|
||||
};
|
||||
|
||||
static struct cat_descriptor desc = {
|
||||
.cmd_group = cmd_desc,
|
||||
.cmd_group_num = sizeof(cmd_desc) / sizeof(cmd_desc[0]),
|
||||
|
||||
.buf = buf,
|
||||
.buf_size = sizeof(buf)
|
||||
};
|
||||
|
||||
static int write_char(char ch)
|
||||
{
|
||||
char str[2];
|
||||
str[0] = ch;
|
||||
str[1] = 0;
|
||||
strcat(ack_results, str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_char(char *ch)
|
||||
{
|
||||
if (input_index >= strlen(input_text))
|
||||
return 0;
|
||||
|
||||
*ch = input_text[input_index];
|
||||
input_index++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cat_io_interface iface = {
|
||||
.read = read_char,
|
||||
.write = write_char
|
||||
};
|
||||
|
||||
static void prepare_input(const char *text)
|
||||
{
|
||||
input_text = text;
|
||||
input_index = 0;
|
||||
|
||||
var1 = 1;
|
||||
var2 = 2;
|
||||
var3 = 3;
|
||||
var1b = 10;
|
||||
var2b = 20;
|
||||
var3b = 30;
|
||||
|
||||
memset(ack_results, 0, sizeof(ack_results));
|
||||
memset(write_results, 0, sizeof(write_results));
|
||||
}
|
||||
|
||||
static const char test_case_1[] = "\nAT+SET=-128\nAT+SET=0\nAT+SET=255\nAT+SET=256\n";
|
||||
static const char test_case_2[] = "\nAT+SET=0,-1\nAT+SET=0,0\nAT+SET=0,65535\nAT+SET=1,65536\n";
|
||||
static const char test_case_3[] = "\nAT+SET=0,0,-1\nAT+SET=0,0,0\nAT+SET=1,1,4294967295\nAT+SET=2,2,4294967296\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct cat_object at;
|
||||
|
||||
cat_init(&at, &desc, &iface, NULL);
|
||||
|
||||
prepare_input(test_case_1);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0 CMD:255") == 0);
|
||||
|
||||
assert(var1 == 255);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 2);
|
||||
assert(var2b == 20);
|
||||
assert(var3 == 3);
|
||||
assert(var3b == 30);
|
||||
|
||||
prepare_input(test_case_2);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0,0 CMD:0,65535") == 0);
|
||||
|
||||
assert(var1 == 1);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 65535);
|
||||
assert(var2b == var2);
|
||||
assert(var3 == 3);
|
||||
assert(var3b == 30);
|
||||
|
||||
prepare_input(test_case_3);
|
||||
while (cat_service(&at) != 0) {};
|
||||
|
||||
assert(strcmp(ack_results, "\nERROR\n\nOK\n\nOK\n\nERROR\n") == 0);
|
||||
assert(strcmp(write_results, " CMD:0,0,0 CMD:1,1,4294967295") == 0);
|
||||
|
||||
assert(var1 == 2);
|
||||
assert(var1b == var1);
|
||||
assert(var2 == 2);
|
||||
assert(var2b == var2);
|
||||
assert(var3 == 4294967295);
|
||||
assert(var3b == var3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user