1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero * 2018-03-30 chenyong first version
9*10465441SEvalZero * 2018-04-14 chenyong modify parse arguments
10*10465441SEvalZero */
11*10465441SEvalZero
12*10465441SEvalZero #include <at.h>
13*10465441SEvalZero #include <stdlib.h>
14*10465441SEvalZero #include <stdio.h>
15*10465441SEvalZero #include <string.h>
16*10465441SEvalZero
17*10465441SEvalZero #include <rthw.h>
18*10465441SEvalZero
19*10465441SEvalZero #define LOG_TAG "at.svr"
20*10465441SEvalZero #include <at_log.h>
21*10465441SEvalZero
22*10465441SEvalZero #ifdef AT_USING_SERVER
23*10465441SEvalZero
24*10465441SEvalZero #define AT_CMD_CHAR_0 '0'
25*10465441SEvalZero #define AT_CMD_CHAR_9 '9'
26*10465441SEvalZero #define AT_CMD_QUESTION_MARK '?'
27*10465441SEvalZero #define AT_CMD_EQUAL_MARK '='
28*10465441SEvalZero #define AT_CMD_L_SQ_BRACKET '['
29*10465441SEvalZero #define AT_CMD_R_SQ_BRACKET ']'
30*10465441SEvalZero #define AT_CMD_L_ANGLE_BRACKET '<'
31*10465441SEvalZero #define AT_CMD_R_ANGLE_BRACKET '>'
32*10465441SEvalZero #define AT_CMD_COMMA_MARK ','
33*10465441SEvalZero #define AT_CMD_SEMICOLON ';'
34*10465441SEvalZero #define AT_CMD_CR '\r'
35*10465441SEvalZero #define AT_CMD_LF '\n'
36*10465441SEvalZero
37*10465441SEvalZero static at_server_t at_server_local = RT_NULL;
38*10465441SEvalZero static at_cmd_t cmd_table = RT_NULL;
39*10465441SEvalZero static rt_size_t cmd_num;
40*10465441SEvalZero
41*10465441SEvalZero extern void at_vprintf(rt_device_t device, const char *format, va_list args);
42*10465441SEvalZero extern void at_vprintfln(rt_device_t device, const char *format, va_list args);
43*10465441SEvalZero
44*10465441SEvalZero /**
45*10465441SEvalZero * AT server send data to AT device
46*10465441SEvalZero *
47*10465441SEvalZero * @param format the input format
48*10465441SEvalZero */
at_server_printf(const char * format,...)49*10465441SEvalZero void at_server_printf(const char *format, ...)
50*10465441SEvalZero {
51*10465441SEvalZero va_list args;
52*10465441SEvalZero
53*10465441SEvalZero va_start(args, format);
54*10465441SEvalZero
55*10465441SEvalZero at_vprintf(at_server_local->device, format, args);
56*10465441SEvalZero
57*10465441SEvalZero va_end(args);
58*10465441SEvalZero }
59*10465441SEvalZero
60*10465441SEvalZero /**
61*10465441SEvalZero * AT server send data and newline to AT device
62*10465441SEvalZero *
63*10465441SEvalZero * @param format the input format
64*10465441SEvalZero */
at_server_printfln(const char * format,...)65*10465441SEvalZero void at_server_printfln(const char *format, ...)
66*10465441SEvalZero {
67*10465441SEvalZero va_list args;
68*10465441SEvalZero
69*10465441SEvalZero va_start(args, format);
70*10465441SEvalZero
71*10465441SEvalZero at_vprintfln(at_server_local->device, format, args);
72*10465441SEvalZero
73*10465441SEvalZero va_end(args);
74*10465441SEvalZero }
75*10465441SEvalZero
76*10465441SEvalZero
77*10465441SEvalZero /**
78*10465441SEvalZero * AT server request arguments parse arguments
79*10465441SEvalZero *
80*10465441SEvalZero * @param req_args request arguments
81*10465441SEvalZero * @param req_expr request expression
82*10465441SEvalZero *
83*10465441SEvalZero * @return -1 : parse arguments failed
84*10465441SEvalZero * 0 : parse without match
85*10465441SEvalZero * >0 : The number of arguments successfully parsed
86*10465441SEvalZero */
at_req_parse_args(const char * req_args,const char * req_expr,...)87*10465441SEvalZero int at_req_parse_args(const char *req_args, const char *req_expr, ...)
88*10465441SEvalZero {
89*10465441SEvalZero va_list args;
90*10465441SEvalZero int req_args_num = 0;
91*10465441SEvalZero
92*10465441SEvalZero RT_ASSERT(req_args);
93*10465441SEvalZero RT_ASSERT(req_expr);
94*10465441SEvalZero
95*10465441SEvalZero va_start(args, req_expr);
96*10465441SEvalZero
97*10465441SEvalZero req_args_num = vsscanf(req_args, req_expr, args);
98*10465441SEvalZero
99*10465441SEvalZero va_end(args);
100*10465441SEvalZero
101*10465441SEvalZero return req_args_num;
102*10465441SEvalZero }
103*10465441SEvalZero
104*10465441SEvalZero /**
105*10465441SEvalZero * AT server send command execute result to AT device
106*10465441SEvalZero *
107*10465441SEvalZero * @param result AT command execute result
108*10465441SEvalZero */
at_server_print_result(at_result_t result)109*10465441SEvalZero void at_server_print_result(at_result_t result)
110*10465441SEvalZero {
111*10465441SEvalZero switch (result)
112*10465441SEvalZero {
113*10465441SEvalZero case AT_RESULT_OK:
114*10465441SEvalZero at_server_printfln("");
115*10465441SEvalZero at_server_printfln("OK");
116*10465441SEvalZero break;
117*10465441SEvalZero
118*10465441SEvalZero case AT_RESULT_FAILE:
119*10465441SEvalZero at_server_printfln("");
120*10465441SEvalZero at_server_printfln("ERROR");
121*10465441SEvalZero break;
122*10465441SEvalZero
123*10465441SEvalZero case AT_RESULT_NULL:
124*10465441SEvalZero break;
125*10465441SEvalZero
126*10465441SEvalZero case AT_RESULT_CMD_ERR:
127*10465441SEvalZero at_server_printfln("ERR CMD MATCH FAILED!");
128*10465441SEvalZero at_server_print_result(AT_RESULT_FAILE);
129*10465441SEvalZero break;
130*10465441SEvalZero
131*10465441SEvalZero case AT_RESULT_CHECK_FAILE:
132*10465441SEvalZero at_server_printfln("ERR CHECK ARGS FORMAT FAILED!");
133*10465441SEvalZero at_server_print_result(AT_RESULT_FAILE);
134*10465441SEvalZero break;
135*10465441SEvalZero
136*10465441SEvalZero case AT_RESULT_PARSE_FAILE:
137*10465441SEvalZero at_server_printfln("ERR PARSE ARGS FAILED!");
138*10465441SEvalZero at_server_print_result(AT_RESULT_FAILE);
139*10465441SEvalZero break;
140*10465441SEvalZero
141*10465441SEvalZero default:
142*10465441SEvalZero break;
143*10465441SEvalZero }
144*10465441SEvalZero }
145*10465441SEvalZero
146*10465441SEvalZero /**
147*10465441SEvalZero * AT server print all commands to AT device
148*10465441SEvalZero */
rt_at_server_print_all_cmd(void)149*10465441SEvalZero void rt_at_server_print_all_cmd(void)
150*10465441SEvalZero {
151*10465441SEvalZero rt_size_t i = 0;
152*10465441SEvalZero
153*10465441SEvalZero at_server_printfln("Commands list : ");
154*10465441SEvalZero
155*10465441SEvalZero for (i = 0; i < cmd_num; i++)
156*10465441SEvalZero {
157*10465441SEvalZero at_server_printf("%s", cmd_table[i].name);
158*10465441SEvalZero
159*10465441SEvalZero if (cmd_table[i].args_expr)
160*10465441SEvalZero {
161*10465441SEvalZero at_server_printfln("%s", cmd_table[i].args_expr);
162*10465441SEvalZero }
163*10465441SEvalZero else
164*10465441SEvalZero {
165*10465441SEvalZero at_server_printf("%c%c", AT_CMD_CR, AT_CMD_LF);
166*10465441SEvalZero }
167*10465441SEvalZero }
168*10465441SEvalZero }
169*10465441SEvalZero
at_get_server(void)170*10465441SEvalZero at_server_t at_get_server(void)
171*10465441SEvalZero {
172*10465441SEvalZero RT_ASSERT(at_server_local);
173*10465441SEvalZero RT_ASSERT(at_server_local->status != AT_STATUS_UNINITIALIZED);
174*10465441SEvalZero
175*10465441SEvalZero return at_server_local;
176*10465441SEvalZero }
177*10465441SEvalZero
at_check_args(const char * args,const char * args_format)178*10465441SEvalZero static rt_err_t at_check_args(const char *args, const char *args_format)
179*10465441SEvalZero {
180*10465441SEvalZero rt_size_t left_sq_bracket_num = 0, right_sq_bracket_num = 0;
181*10465441SEvalZero rt_size_t left_angle_bracket_num = 0, right_angle_bracket_num = 0;
182*10465441SEvalZero rt_size_t comma_mark_num = 0;
183*10465441SEvalZero rt_size_t i = 0;
184*10465441SEvalZero
185*10465441SEvalZero RT_ASSERT(args);
186*10465441SEvalZero RT_ASSERT(args_format);
187*10465441SEvalZero
188*10465441SEvalZero for (i = 0; i < strlen(args_format); i++)
189*10465441SEvalZero {
190*10465441SEvalZero switch (args_format[i])
191*10465441SEvalZero {
192*10465441SEvalZero case AT_CMD_L_SQ_BRACKET:
193*10465441SEvalZero left_sq_bracket_num++;
194*10465441SEvalZero break;
195*10465441SEvalZero
196*10465441SEvalZero case AT_CMD_R_SQ_BRACKET:
197*10465441SEvalZero right_sq_bracket_num++;
198*10465441SEvalZero break;
199*10465441SEvalZero
200*10465441SEvalZero case AT_CMD_L_ANGLE_BRACKET:
201*10465441SEvalZero left_angle_bracket_num++;
202*10465441SEvalZero break;
203*10465441SEvalZero
204*10465441SEvalZero case AT_CMD_R_ANGLE_BRACKET:
205*10465441SEvalZero right_angle_bracket_num++;
206*10465441SEvalZero break;
207*10465441SEvalZero
208*10465441SEvalZero default:
209*10465441SEvalZero break;
210*10465441SEvalZero }
211*10465441SEvalZero }
212*10465441SEvalZero
213*10465441SEvalZero if (left_sq_bracket_num != right_sq_bracket_num || left_angle_bracket_num != right_angle_bracket_num
214*10465441SEvalZero || left_sq_bracket_num > left_angle_bracket_num)
215*10465441SEvalZero {
216*10465441SEvalZero return -RT_ERROR;
217*10465441SEvalZero }
218*10465441SEvalZero
219*10465441SEvalZero for (i = 0; i < strlen(args); i++)
220*10465441SEvalZero {
221*10465441SEvalZero if (args[i] == AT_CMD_COMMA_MARK)
222*10465441SEvalZero {
223*10465441SEvalZero comma_mark_num++;
224*10465441SEvalZero }
225*10465441SEvalZero }
226*10465441SEvalZero
227*10465441SEvalZero if ((comma_mark_num + 1 < left_angle_bracket_num - left_sq_bracket_num)
228*10465441SEvalZero || comma_mark_num + 1 > left_angle_bracket_num)
229*10465441SEvalZero {
230*10465441SEvalZero return -RT_ERROR;
231*10465441SEvalZero }
232*10465441SEvalZero
233*10465441SEvalZero return RT_EOK;
234*10465441SEvalZero }
235*10465441SEvalZero
at_cmd_process(at_cmd_t cmd,const char * cmd_args)236*10465441SEvalZero static rt_err_t at_cmd_process(at_cmd_t cmd, const char *cmd_args)
237*10465441SEvalZero {
238*10465441SEvalZero at_result_t result = AT_RESULT_OK;
239*10465441SEvalZero
240*10465441SEvalZero RT_ASSERT(cmd);
241*10465441SEvalZero RT_ASSERT(cmd_args);
242*10465441SEvalZero
243*10465441SEvalZero if (cmd_args[0] == AT_CMD_EQUAL_MARK && cmd_args[1] == AT_CMD_QUESTION_MARK && cmd_args[2] == AT_CMD_CR)
244*10465441SEvalZero {
245*10465441SEvalZero if (cmd->test == RT_NULL)
246*10465441SEvalZero {
247*10465441SEvalZero at_server_print_result(AT_RESULT_CMD_ERR);
248*10465441SEvalZero return -RT_ERROR;
249*10465441SEvalZero }
250*10465441SEvalZero
251*10465441SEvalZero result = cmd->test();
252*10465441SEvalZero at_server_print_result(result);
253*10465441SEvalZero }
254*10465441SEvalZero else if (cmd_args[0] == AT_CMD_QUESTION_MARK && cmd_args[1] == AT_CMD_CR)
255*10465441SEvalZero {
256*10465441SEvalZero if (cmd->query == RT_NULL)
257*10465441SEvalZero {
258*10465441SEvalZero at_server_print_result(AT_RESULT_CMD_ERR);
259*10465441SEvalZero return -RT_ERROR;
260*10465441SEvalZero }
261*10465441SEvalZero
262*10465441SEvalZero result = cmd->query();
263*10465441SEvalZero at_server_print_result(result);
264*10465441SEvalZero }
265*10465441SEvalZero else if (cmd_args[0] == AT_CMD_EQUAL_MARK
266*10465441SEvalZero || (cmd_args[0] >= AT_CMD_CHAR_0 && cmd_args[0] <= AT_CMD_CHAR_9 && cmd_args[1] == AT_CMD_CR))
267*10465441SEvalZero {
268*10465441SEvalZero if (cmd->setup == RT_NULL)
269*10465441SEvalZero {
270*10465441SEvalZero at_server_print_result(AT_RESULT_CMD_ERR);
271*10465441SEvalZero return -RT_ERROR;
272*10465441SEvalZero }
273*10465441SEvalZero
274*10465441SEvalZero if(at_check_args(cmd_args, cmd->args_expr) < 0)
275*10465441SEvalZero {
276*10465441SEvalZero at_server_print_result(AT_RESULT_CHECK_FAILE);
277*10465441SEvalZero return -RT_ERROR;
278*10465441SEvalZero }
279*10465441SEvalZero
280*10465441SEvalZero result = cmd->setup(cmd_args);
281*10465441SEvalZero at_server_print_result(result);
282*10465441SEvalZero }
283*10465441SEvalZero else if (cmd_args[0] == AT_CMD_CR)
284*10465441SEvalZero {
285*10465441SEvalZero if (cmd->exec == RT_NULL)
286*10465441SEvalZero {
287*10465441SEvalZero at_server_print_result(AT_RESULT_CMD_ERR);
288*10465441SEvalZero return -RT_ERROR;
289*10465441SEvalZero }
290*10465441SEvalZero
291*10465441SEvalZero result = cmd->exec();
292*10465441SEvalZero at_server_print_result(result);
293*10465441SEvalZero }
294*10465441SEvalZero else
295*10465441SEvalZero {
296*10465441SEvalZero return -RT_ERROR;
297*10465441SEvalZero }
298*10465441SEvalZero
299*10465441SEvalZero return RT_EOK;
300*10465441SEvalZero }
301*10465441SEvalZero
at_find_cmd(const char * cmd)302*10465441SEvalZero static at_cmd_t at_find_cmd(const char *cmd)
303*10465441SEvalZero {
304*10465441SEvalZero rt_size_t i = 0;
305*10465441SEvalZero
306*10465441SEvalZero RT_ASSERT(cmd_table);
307*10465441SEvalZero
308*10465441SEvalZero for (i = 0; i < cmd_num; i++)
309*10465441SEvalZero {
310*10465441SEvalZero if (!strcasecmp(cmd, cmd_table[i].name))
311*10465441SEvalZero {
312*10465441SEvalZero return &cmd_table[i];
313*10465441SEvalZero }
314*10465441SEvalZero }
315*10465441SEvalZero return RT_NULL;
316*10465441SEvalZero }
317*10465441SEvalZero
at_cmd_get_name(const char * cmd_buffer,char * cmd_name)318*10465441SEvalZero static rt_err_t at_cmd_get_name(const char *cmd_buffer, char *cmd_name)
319*10465441SEvalZero {
320*10465441SEvalZero rt_size_t cmd_name_len = 0, i = 0;
321*10465441SEvalZero
322*10465441SEvalZero RT_ASSERT(cmd_name);
323*10465441SEvalZero RT_ASSERT(cmd_buffer);
324*10465441SEvalZero
325*10465441SEvalZero for (i = 0; i < strlen(cmd_buffer) + 1; i++)
326*10465441SEvalZero {
327*10465441SEvalZero if (*(cmd_buffer + i) == AT_CMD_QUESTION_MARK || *(cmd_buffer + i) == AT_CMD_EQUAL_MARK
328*10465441SEvalZero || *(cmd_buffer + i) == AT_CMD_CR
329*10465441SEvalZero || (*(cmd_buffer + i) >= AT_CMD_CHAR_0 && *(cmd_buffer + i) <= AT_CMD_CHAR_9))
330*10465441SEvalZero {
331*10465441SEvalZero cmd_name_len = i;
332*10465441SEvalZero memcpy(cmd_name, cmd_buffer, cmd_name_len);
333*10465441SEvalZero *(cmd_name + cmd_name_len) = '\0';
334*10465441SEvalZero
335*10465441SEvalZero return RT_EOK;
336*10465441SEvalZero }
337*10465441SEvalZero }
338*10465441SEvalZero
339*10465441SEvalZero return -RT_ERROR;
340*10465441SEvalZero }
341*10465441SEvalZero
at_server_gerchar(void)342*10465441SEvalZero static char at_server_gerchar(void)
343*10465441SEvalZero {
344*10465441SEvalZero char ch;
345*10465441SEvalZero
346*10465441SEvalZero while (rt_device_read(at_server_local->device, 0, &ch, 1) == 0)
347*10465441SEvalZero {
348*10465441SEvalZero rt_sem_control(at_server_local->rx_notice, RT_IPC_CMD_RESET, RT_NULL);
349*10465441SEvalZero rt_sem_take(at_server_local->rx_notice, RT_WAITING_FOREVER);
350*10465441SEvalZero }
351*10465441SEvalZero
352*10465441SEvalZero return ch;
353*10465441SEvalZero }
354*10465441SEvalZero
server_parser(at_server_t server)355*10465441SEvalZero static void server_parser(at_server_t server)
356*10465441SEvalZero {
357*10465441SEvalZero #define ESC_KEY 0x1B
358*10465441SEvalZero #define BACKSPACE_KEY 0x08
359*10465441SEvalZero #define DELECT_KEY 0x7F
360*10465441SEvalZero
361*10465441SEvalZero char cur_cmd_name[AT_CMD_NAME_LEN] = { 0 };
362*10465441SEvalZero at_cmd_t cur_cmd = RT_NULL;
363*10465441SEvalZero char *cur_cmd_args = RT_NULL, ch, last_ch;
364*10465441SEvalZero
365*10465441SEvalZero RT_ASSERT(server);
366*10465441SEvalZero RT_ASSERT(server->status != AT_STATUS_UNINITIALIZED);
367*10465441SEvalZero
368*10465441SEvalZero while (ESC_KEY != (ch = server->get_char()))
369*10465441SEvalZero {
370*10465441SEvalZero if (server->echo_mode)
371*10465441SEvalZero {
372*10465441SEvalZero if (ch == AT_CMD_CR || (ch == AT_CMD_LF && last_ch != AT_CMD_CR))
373*10465441SEvalZero {
374*10465441SEvalZero at_server_printf("%c%c", AT_CMD_CR, AT_CMD_LF);
375*10465441SEvalZero }
376*10465441SEvalZero else if (ch == BACKSPACE_KEY || ch == DELECT_KEY)
377*10465441SEvalZero {
378*10465441SEvalZero if (server->cur_recv_len)
379*10465441SEvalZero {
380*10465441SEvalZero server->recv_buffer[--server->cur_recv_len] = 0;
381*10465441SEvalZero at_server_printf("\b \b");
382*10465441SEvalZero }
383*10465441SEvalZero
384*10465441SEvalZero continue;
385*10465441SEvalZero }
386*10465441SEvalZero else
387*10465441SEvalZero {
388*10465441SEvalZero at_server_printf("%c", ch);
389*10465441SEvalZero }
390*10465441SEvalZero }
391*10465441SEvalZero
392*10465441SEvalZero server->recv_buffer[server->cur_recv_len++] = ch;
393*10465441SEvalZero last_ch = ch;
394*10465441SEvalZero
395*10465441SEvalZero if(!strstr(server->recv_buffer, server->end_mark))
396*10465441SEvalZero {
397*10465441SEvalZero continue;
398*10465441SEvalZero }
399*10465441SEvalZero
400*10465441SEvalZero if (at_cmd_get_name(server->recv_buffer, cur_cmd_name) < 0)
401*10465441SEvalZero {
402*10465441SEvalZero at_server_print_result(AT_RESULT_CMD_ERR);
403*10465441SEvalZero goto __retry;
404*10465441SEvalZero }
405*10465441SEvalZero
406*10465441SEvalZero cur_cmd = at_find_cmd(cur_cmd_name);
407*10465441SEvalZero if (!cur_cmd)
408*10465441SEvalZero {
409*10465441SEvalZero at_server_print_result(AT_RESULT_CMD_ERR);
410*10465441SEvalZero goto __retry;
411*10465441SEvalZero }
412*10465441SEvalZero
413*10465441SEvalZero cur_cmd_args = server->recv_buffer + strlen(cur_cmd_name);
414*10465441SEvalZero if (at_cmd_process(cur_cmd, cur_cmd_args) < 0)
415*10465441SEvalZero {
416*10465441SEvalZero goto __retry;
417*10465441SEvalZero }
418*10465441SEvalZero
419*10465441SEvalZero __retry:
420*10465441SEvalZero memset(server->recv_buffer, 0x00, AT_SERVER_RECV_BUFF_LEN);
421*10465441SEvalZero server->cur_recv_len = 0;
422*10465441SEvalZero }
423*10465441SEvalZero }
424*10465441SEvalZero
at_rx_ind(rt_device_t dev,rt_size_t size)425*10465441SEvalZero static rt_err_t at_rx_ind(rt_device_t dev, rt_size_t size)
426*10465441SEvalZero {
427*10465441SEvalZero if (size > 0)
428*10465441SEvalZero {
429*10465441SEvalZero rt_sem_release(at_server_local->rx_notice);
430*10465441SEvalZero }
431*10465441SEvalZero
432*10465441SEvalZero return RT_EOK;
433*10465441SEvalZero }
434*10465441SEvalZero
435*10465441SEvalZero #if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */
436*10465441SEvalZero #pragma section="RtAtCmdTab"
437*10465441SEvalZero #endif
438*10465441SEvalZero
at_server_init(void)439*10465441SEvalZero int at_server_init(void)
440*10465441SEvalZero {
441*10465441SEvalZero rt_err_t result = RT_EOK;
442*10465441SEvalZero rt_err_t open_result = RT_EOK;
443*10465441SEvalZero
444*10465441SEvalZero if (at_server_local)
445*10465441SEvalZero {
446*10465441SEvalZero return result;
447*10465441SEvalZero }
448*10465441SEvalZero
449*10465441SEvalZero /* initialize the AT commands table.*/
450*10465441SEvalZero #if defined(__CC_ARM) /* ARM C Compiler */
451*10465441SEvalZero extern const int RtAtCmdTab$$Base;
452*10465441SEvalZero extern const int RtAtCmdTab$$Limit;
453*10465441SEvalZero cmd_table = (at_cmd_t)&RtAtCmdTab$$Base;
454*10465441SEvalZero cmd_num = (at_cmd_t)&RtAtCmdTab$$Limit - cmd_table;
455*10465441SEvalZero #elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
456*10465441SEvalZero cmd_table = (at_cmd_t)__section_begin("RtAtCmdTab");
457*10465441SEvalZero cmd_num = (at_cmd_t)__section_end("RtAtCmdTab") - cmd_table;
458*10465441SEvalZero #elif defined (__GNUC__) /* for GCC Compiler */
459*10465441SEvalZero extern const int __rtatcmdtab_start;
460*10465441SEvalZero extern const int __rtatcmdtab_end;
461*10465441SEvalZero cmd_table = (at_cmd_t)&__rtatcmdtab_start;
462*10465441SEvalZero cmd_num = (at_cmd_t) &__rtatcmdtab_end - cmd_table;
463*10465441SEvalZero #endif /* defined(__CC_ARM) */
464*10465441SEvalZero
465*10465441SEvalZero at_server_local = (at_server_t) rt_calloc(1, sizeof(struct at_server));
466*10465441SEvalZero if (!at_server_local)
467*10465441SEvalZero {
468*10465441SEvalZero result = -RT_ENOMEM;
469*10465441SEvalZero LOG_E("AT server session initialize failed! No memory for at_server structure !");
470*10465441SEvalZero goto __exit;
471*10465441SEvalZero }
472*10465441SEvalZero
473*10465441SEvalZero at_server_local->echo_mode = 1;
474*10465441SEvalZero at_server_local->status = AT_STATUS_UNINITIALIZED;
475*10465441SEvalZero
476*10465441SEvalZero memset(at_server_local->recv_buffer, 0x00, AT_SERVER_RECV_BUFF_LEN);
477*10465441SEvalZero at_server_local->cur_recv_len = 0;
478*10465441SEvalZero
479*10465441SEvalZero at_server_local->rx_notice = rt_sem_create("at_svr", 0, RT_IPC_FLAG_FIFO);
480*10465441SEvalZero if (!at_server_local->rx_notice)
481*10465441SEvalZero {
482*10465441SEvalZero LOG_E("AT server session initialize failed! at_rx_notice semaphore create failed!");
483*10465441SEvalZero result = -RT_ENOMEM;
484*10465441SEvalZero goto __exit;
485*10465441SEvalZero }
486*10465441SEvalZero
487*10465441SEvalZero /* Find and open command device */
488*10465441SEvalZero at_server_local->device = rt_device_find(AT_SERVER_DEVICE);
489*10465441SEvalZero if (at_server_local->device)
490*10465441SEvalZero {
491*10465441SEvalZero RT_ASSERT(at_server_local->device->type == RT_Device_Class_Char);
492*10465441SEvalZero
493*10465441SEvalZero /* using DMA mode first */
494*10465441SEvalZero open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
495*10465441SEvalZero /* using interrupt mode when DMA mode not supported */
496*10465441SEvalZero if (open_result == -RT_EIO)
497*10465441SEvalZero {
498*10465441SEvalZero open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
499*10465441SEvalZero }
500*10465441SEvalZero RT_ASSERT(open_result == RT_EOK);
501*10465441SEvalZero
502*10465441SEvalZero rt_device_set_rx_indicate(at_server_local->device, at_rx_ind);
503*10465441SEvalZero }
504*10465441SEvalZero else
505*10465441SEvalZero {
506*10465441SEvalZero LOG_E("AT device initialize failed! Not find the device : %s.", AT_SERVER_DEVICE);
507*10465441SEvalZero result = -RT_ERROR;
508*10465441SEvalZero goto __exit;
509*10465441SEvalZero }
510*10465441SEvalZero
511*10465441SEvalZero at_server_local->get_char = at_server_gerchar;
512*10465441SEvalZero memcpy(at_server_local->end_mark, AT_CMD_END_MARK, sizeof(AT_CMD_END_MARK));
513*10465441SEvalZero
514*10465441SEvalZero at_server_local->parser_entry = server_parser;
515*10465441SEvalZero at_server_local->parser = rt_thread_create("at_svr",
516*10465441SEvalZero (void (*)(void *parameter))server_parser,
517*10465441SEvalZero at_server_local,
518*10465441SEvalZero 2 * 1024,
519*10465441SEvalZero RT_THREAD_PRIORITY_MAX / 3 - 1,
520*10465441SEvalZero 5);
521*10465441SEvalZero if (at_server_local->parser == RT_NULL)
522*10465441SEvalZero {
523*10465441SEvalZero result = -RT_ENOMEM;
524*10465441SEvalZero goto __exit;
525*10465441SEvalZero }
526*10465441SEvalZero
527*10465441SEvalZero __exit:
528*10465441SEvalZero if (!result)
529*10465441SEvalZero {
530*10465441SEvalZero at_server_local->status = AT_STATUS_INITIALIZED;
531*10465441SEvalZero
532*10465441SEvalZero rt_thread_startup(at_server_local->parser);
533*10465441SEvalZero
534*10465441SEvalZero LOG_I("RT-Thread AT server (V%s) initialize success.", AT_SW_VERSION);
535*10465441SEvalZero }
536*10465441SEvalZero else
537*10465441SEvalZero {
538*10465441SEvalZero if (at_server_local)
539*10465441SEvalZero {
540*10465441SEvalZero rt_free(at_server_local);
541*10465441SEvalZero }
542*10465441SEvalZero
543*10465441SEvalZero LOG_E("RT-Thread AT server (V%s) initialize failed(%d).", AT_SW_VERSION, result);
544*10465441SEvalZero }
545*10465441SEvalZero
546*10465441SEvalZero return result;
547*10465441SEvalZero }
548*10465441SEvalZero INIT_COMPONENT_EXPORT(at_server_init);
549*10465441SEvalZero
at_port_reset(void)550*10465441SEvalZero RT_WEAK void at_port_reset(void)
551*10465441SEvalZero {
552*10465441SEvalZero LOG_E("The reset for AT server is not implement.");
553*10465441SEvalZero }
554*10465441SEvalZero
at_port_factory_reset(void)555*10465441SEvalZero RT_WEAK void at_port_factory_reset(void)
556*10465441SEvalZero {
557*10465441SEvalZero LOG_E("The factory reset for AT server is not implement.");
558*10465441SEvalZero }
559*10465441SEvalZero
560*10465441SEvalZero #endif /* AT_USING_SERVER */
561