/* * Copyright (C) 2018 OTA keys S.A. * 2018 Inria * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup tests * @{ * * @file * @brief AT module test application * * @author Vincent Dupont * @author Alexandre Abadie * * @} */ #include #include #include #include "at.h" #include "shell.h" #include "timex.h" #include "periph/uart.h" static at_dev_t at_dev; static char buf[256]; static char resp[1024]; static int init(int argc, char **argv) { (void)argc; (void)argv; if (argc < 3) { printf("Usage: %s \n", argv[0]); return 1; } uint8_t uart = atoi(argv[1]); uint32_t baudrate = atoi(argv[2]); int res = at_dev_init(&at_dev, UART_DEV(uart), baudrate, buf, sizeof(buf)); /* check the UART initialization return value and respond as needed */ if (res == UART_NODEV) { puts("Invalid UART device given!"); return 1; } else if (res == UART_NOBAUD) { puts("Baudrate is not applicable!"); return 1; } return res; } static int send(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } ssize_t len; if ((len = at_send_cmd_get_resp(&at_dev, argv[1], resp, sizeof(resp), 10 * US_PER_SEC)) < 0) { puts("Error"); return 1; } printf("Response (len=%d): %s\n", (int)len, resp); return 0; } static int send_ok(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } if (at_send_cmd_wait_ok(&at_dev, argv[1], 10 * US_PER_SEC) < 0) { puts("Error"); return 1; } puts("OK"); return 0; } static int send_lines(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } ssize_t len; if ((len = at_send_cmd_get_lines(&at_dev, argv[1], resp, sizeof(resp), true, 10 * US_PER_SEC)) < 0) { puts("Error"); return 1; } printf("Response (len=%d): %s\n", (int)len, resp); return 0; } static int send_recv_bytes(int argc, char **argv) { char buffer[64]; if (argc < 3) { printf("Usage: %s \n", argv[0]); return 1; } sprintf(buffer, "%s%s", argv[1], CONFIG_AT_SEND_EOL); at_send_bytes(&at_dev, buffer, strlen(buffer)); ssize_t len = at_recv_bytes(&at_dev, buffer, atoi(argv[2]), 10 * US_PER_SEC); printf("Response (len=%d): %s\n", (int)len, buffer); return 0; } static int send_recv_bytes_until_string(int argc, char **argv) { char buffer[128]; size_t len = sizeof(buffer); memset(buffer, 0, sizeof(buffer)); if (argc < 3) { printf("Usage: %s \n", argv[0]); return 1; } sprintf(buffer, "%s%s", argv[1], CONFIG_AT_SEND_EOL); at_send_bytes(&at_dev, buffer, strlen(buffer)); memset(buffer, 0, sizeof(buffer)); int res = at_recv_bytes_until_string(&at_dev, argv[2], buffer, &len, 10 * US_PER_SEC); if (res) { puts("Error"); return 1; } printf("Response (len=%d): %s\n", (int)len, buffer); return 0; } static int drain(int argc, char **argv) { (void)argc; (void)argv; at_drain(&at_dev); return 0; } static int power_on(int argc, char **argv) { (void)argc; (void)argv; at_dev_poweron(&at_dev); puts("Powered on"); return 0; } static int power_off(int argc, char **argv) { (void)argc; (void)argv; at_dev_poweroff(&at_dev); puts("Powered off"); return 0; } #ifdef MODULE_AT_URC #ifndef MAX_URC_NB #define MAX_URC_NB 5 #endif #ifndef MAX_URC_LEN #define MAX_URC_LEN 32 #endif static at_urc_t urc_list[MAX_URC_NB]; static char urc_str[MAX_URC_NB][MAX_URC_LEN]; static bool urc_used[MAX_URC_NB]; static void _urc_cb(void *arg, const char *urc) { (void)arg; printf("urc received: %s\n", urc); } static int add_urc(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } if (strlen(argv[1]) > MAX_URC_LEN - 1) { puts("urc is too long"); return 1; } for (size_t i = 0; i < MAX_URC_NB; i++) { if (!urc_used[i]) { strcpy(urc_str[i], argv[1]); urc_list[i].code = urc_str[i]; urc_list[i].arg = NULL; urc_list[i].cb = _urc_cb; urc_used[i] = true; at_add_urc(&at_dev, &urc_list[i]); puts("urc registered"); return 0; } } puts("Not enough memory, urc is not registered"); return 1; } static int process_urc(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } uint32_t timeout = strtoul(argv[1], NULL, 0); at_process_urc(&at_dev, timeout); puts("urc processed"); return 0; } static int remove_urc(int argc, char **argv) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } for (size_t i = 0; i < MAX_URC_NB; i++) { if (urc_used[i] && strcmp(urc_list[i].code, argv[1]) == 0) { at_remove_urc(&at_dev, &urc_list[i]); urc_used[i] = false; puts("urc removed"); return 0; } } puts("urc not found"); return 1; } #endif static const shell_command_t shell_commands[] = { { "init", "Initialize AT device", init }, { "send", "Send a command and wait response", send }, { "send_ok", "Send a command and wait OK", send_ok }, { "send_lines", "Send a command and wait lines", send_lines }, { "send_recv_bytes", "Send a command and wait response as raw bytes", send_recv_bytes }, { "send_recv_until_string", "Send a command and receive response until " "the expected pattern arrives", send_recv_bytes_until_string }, { "drain", "Drain AT device", drain }, { "power_on", "Power on AT device", power_on }, { "power_off", "Power off AT device", power_off }, #ifdef MODULE_AT_URC { "add_urc", "Register an URC", add_urc }, { "remove_urc", "De-register an URC", remove_urc }, { "process_urc", "Process the URCs", process_urc }, #endif { NULL, NULL, NULL }, }; int main(void) { puts("AT command test app"); /* run the shell */ char line_buf[SHELL_DEFAULT_BUFSIZE]; shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); return 0; }