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 /*---------------------------------------------------------------------------*/
52 LIST(at_cmd_list);
53 process_event_t at_cmd_received_event;
54 /*---------------------------------------------------------------------------*/
55 static uint8_t at_uart = 0;
56 /*---------------------------------------------------------------------------*/
57 PROCESS(at_process, "AT process");
58 /*---------------------------------------------------------------------------*/
59 PROCESS_THREAD(at_process, ev, data)
60 {
61  uint8_t plen;
62  char *pch, *buf;
63  struct at_cmd *a;
64  PROCESS_BEGIN();
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  }
83  PROCESS_END();
84 }
85 /*---------------------------------------------------------------------------*/
86 struct at_cmd *
87 at_list(void)
88 {
89  return list_head(at_cmd_list);
90 }
91 /*---------------------------------------------------------------------------*/
92 uint8_t
93 at_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 /*---------------------------------------------------------------------------*/
106 void
107 at_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 /*---------------------------------------------------------------------------*/
125 at_status_t
126 at_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 /*---------------------------------------------------------------------------*/
Header file for the cc2538 UART driver.
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
Header file for the cc2538 System Control driver.
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void uart_init(uint8_t uart)
Initialises the UART controller, configures I/O control and interrupts.
Definition: uart.c:241
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition: process.h:157
void uart_write_byte(uint8_t uart, uint8_t b)
Sends a single character down the UART.
Definition: uart.c:344
int serial_line_input_byte(unsigned char c)
Get one byte of input from the serial driver.
Definition: serial-line.c:64
Linked list manipulation routines.
void * list_head(list_t list)
Get a pointer to the first element of a list.
Definition: list.c:82
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
Header file with prototypes for interrupt control on the cc2538 Cortex-M3 micro.
process_event_t process_alloc_event(void)
Allocate a global event number.
Definition: process.c:93
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition: list.c:142
void list_init(list_t list)
Initialize a list.
Definition: list.c:65
#define LIST(name)
Declare a linked list.
Definition: list.h:89
process_event_t serial_line_event_message
Event posted when a line of input has been received.
Definition: serial-line.c:60
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
Generic serial I/O process header filer.
Default definitions of C compiler quirk work-arounds.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1110
void * list_item_next(void *item)
Get the next item following this item.
Definition: list.c:322
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99