xref: /nrf52832-nimble/rt-thread/components/net/at/src/at_server.c (revision 104654410c56c573564690304ae786df310c91fc)
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