Contiki-NG
at-master.c
1/*
2 * Copyright (c) 2015, Zolertia - http://www.zolertia.com
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30#include "contiki.h"
31#include "contiki-lib.h"
32#include "at-master.h"
33#include "cpu.h"
34#include "dev/uart.h"
35#include "dev/serial-line.h"
36#include "dev/sys-ctrl.h"
37#include "lib/list.h"
38#include "sys/cc.h"
39
40#include <ctype.h>
41#include <string.h>
42#include <stdio.h>
43#include <stdint.h>
44/*---------------------------------------------------------------------------*/
45#define DEBUG 0
46#if DEBUG
47#define PRINTF(...) printf(__VA_ARGS__)
48#else
49#define PRINTF(...)
50#endif
51/*---------------------------------------------------------------------------*/
52LIST(at_cmd_list);
53process_event_t at_cmd_received_event;
54/*---------------------------------------------------------------------------*/
55static uint8_t at_uart = 0;
56/*---------------------------------------------------------------------------*/
57PROCESS(at_process, "AT process");
58/*---------------------------------------------------------------------------*/
59PROCESS_THREAD(at_process, ev, data)
60{
61 uint8_t plen;
62 char *pch, *buf;
63 struct at_cmd *a;
65
66 while(1) {
68 buf = (char *)data;
69 plen = strlen(buf);
70 for(a = list_head(at_cmd_list); a != NULL; a = list_item_next(a)) {
71 pch = strstr(buf, a->cmd_header);
72 if((plen <= a->cmd_max_len) && (pch != NULL)) {
73 if(strncmp(a->cmd_header, pch, a->cmd_hdr_len) == 0) {
74 if((a->cmd_hdr_len == plen) || (a->cmd_max_len > a->cmd_hdr_len)) {
75 a->event_callback(a, plen, (char *)pch);
76 process_post(a->app_process, at_cmd_received_event, NULL);
77 break;
78 }
79 }
80 }
81 }
82 }
84}
85/*---------------------------------------------------------------------------*/
86struct at_cmd *
87at_list(void)
88{
89 return list_head(at_cmd_list);
90}
91/*---------------------------------------------------------------------------*/
92uint8_t
93at_send(char *s, uint8_t len)
94{
95 uint8_t i = 0;
96 while(s && *s != 0) {
97 if(i >= len) {
98 break;
99 }
100 uart_write_byte(at_uart, *s++);
101 i++;
102 }
103 return i;
104}
105/*---------------------------------------------------------------------------*/
106void
107at_init(uint8_t uart_sel)
108{
109 static uint8_t inited = 0;
110 if(!inited) {
111 list_init(at_cmd_list);
112 at_cmd_received_event = process_alloc_event();
113 inited = 1;
114
115 at_uart = uart_sel;
116 uart_init(at_uart);
118 serial_line_init();
119
120 process_start(&at_process, NULL);
121 PRINTF("AT: Started (%u)\n", at_uart);
122 }
123}
124/*---------------------------------------------------------------------------*/
125at_status_t
126at_register(struct at_cmd *cmd, struct process *app_process,
127 const char *cmd_hdr, const uint8_t hdr_len,
128 const uint8_t cmd_max_len, at_event_callback_t event_callback)
129{
130 if((hdr_len < 1) || (cmd_max_len < 1) || (strncmp(cmd_hdr, "AT", 2) != 0) ||
131 (event_callback == NULL)) {
132 PRINTF("AT: Invalid argument\n");
133 return AT_STATUS_INVALID_ARGS_ERROR;
134 }
135
136 memset(cmd, 0, sizeof(struct at_cmd));
137 cmd->event_callback = event_callback;
138 cmd->cmd_header = cmd_hdr;
139 cmd->cmd_hdr_len = hdr_len;
140 cmd->cmd_max_len = cmd_max_len;
141 cmd->app_process = app_process;
142 list_add(at_cmd_list, cmd);
143 PRINTF("AT: registered HDR %s LEN %u MAX %u\n", cmd->cmd_header,
144 cmd->cmd_hdr_len,
145 cmd->cmd_max_len);
146 return AT_STATUS_OK;
147}
148/*---------------------------------------------------------------------------*/
Default definitions of C compiler quirk work-arounds.
Header file with prototypes for interrupt control on the cc2538 Cortex-M3 micro.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1154
void uart_set_input(uint8_t uart, int(*input)(unsigned char c))
Assigns a callback to be called when the UART receives a byte.
Definition: uart.c:334
void uart_write_byte(uint8_t uart, uint8_t b)
Sends a single character down the UART.
Definition: uart.c:344
void uart_init(uint8_t uart)
Initialises the UART controller, configures I/O control and interrupts.
Definition: uart.c:241
void list_init(list_t list)
Initialize a list.
Definition: list.c:57
#define LIST(name)
Declare a linked list.
Definition: list.h:89
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition: list.c:89
void * list_item_next(const void *item)
Get the next item following this item.
Definition: list.c:203
void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition: list.c:63
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
process_event_t process_alloc_event(void)
Allocate a global event number.
Definition: process.c:93
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition: process.h:157
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
Linked list manipulation routines.
Generic serial I/O process header filer.
int serial_line_input_byte(unsigned char c)
Get one byte of input from the serial driver.
Definition: serial-line.c:64
process_event_t serial_line_event_message
Event posted when a line of input has been received.
Definition: serial-line.c:60
Header file for the cc2538 System Control driver.
Header file for the cc2538 UART driver.