Upgrade ofono to 1.2
[profile/ivi/ofono.git] / gatchat / gatserver.c
1 /*
2  *
3  *  AT server library with GLib integration
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <string.h>
29
30 #include <glib.h>
31
32 #include "ringbuffer.h"
33 #include "gatserver.h"
34 #include "gatio.h"
35
36 #define BUF_SIZE 4096
37 /* <cr><lf> + the max length of information text + <cr><lf> */
38 #define MAX_TEXT_SIZE 2052
39 /* #define WRITE_SCHEDULER_DEBUG 1 */
40
41 enum ParserState {
42         PARSER_STATE_IDLE,
43         PARSER_STATE_A,
44         PARSER_STATE_COMMAND,
45         PARSER_STATE_GARBAGE,
46 };
47
48 enum ParserResult {
49         PARSER_RESULT_COMMAND,
50         PARSER_RESULT_EMPTY_COMMAND,
51         PARSER_RESULT_REPEAT_LAST,
52         PARSER_RESULT_GARBAGE,
53         PARSER_RESULT_UNSURE,
54 };
55
56 /* V.250 Table 1/V.250 Result codes */
57 static const char *server_result_to_string(GAtServerResult result)
58 {
59         switch (result) {
60         case G_AT_SERVER_RESULT_OK:
61                 return "OK";
62         case G_AT_SERVER_RESULT_CONNECT:
63                 return "CONNECT";
64         case G_AT_SERVER_RESULT_RING:
65                 return "RING";
66         case G_AT_SERVER_RESULT_NO_CARRIER:
67                 return "NO CARRIER";
68         case G_AT_SERVER_RESULT_ERROR:
69                 return "ERROR";
70         case G_AT_SERVER_RESULT_NO_DIALTONE:
71                 return "NO DIALTONE";
72         case G_AT_SERVER_RESULT_BUSY:
73                 return "BUSY";
74         case G_AT_SERVER_RESULT_NO_ANSWER:
75                 return "NO ANSWER";
76         default:
77                 return NULL;
78         }
79 }
80
81 /* Basic command setting for V.250 */
82 struct v250_settings {
83         char s0;                        /* set by S0=<val> */
84         char s3;                        /* set by S3=<val> */
85         char s4;                        /* set by S4=<val> */
86         char s5;                        /* set by S5=<val> */
87         int s6;                         /* set by S6=<val> */
88         int s7;                         /* set by S7=<val> */
89         int s8;                         /* set by S8=<val> */
90         int s10;                        /* set by S10=<val> */
91         gboolean echo;                  /* set by E<val> */
92         gboolean quiet;                 /* set by Q<val> */
93         gboolean is_v1;                 /* set by V<val>, v0 or v1 */
94         int res_format;                 /* set by X<val> */
95         int c109;                       /* set by &C<val> */
96         int c108;                       /* set by &D<val> */
97         char l;                         /* set by L<val> */
98         char m;                         /* set by M<val> */
99         char dial_mode;                 /* set by P or T */
100 };
101
102 /* AT command set that server supported */
103 struct at_command {
104         GAtServerNotifyFunc notify;
105         gpointer user_data;
106         GDestroyNotify destroy_notify;
107 };
108
109 struct _GAtServer {
110         gint ref_count;                         /* Ref count */
111         struct v250_settings v250;              /* V.250 command setting */
112         GAtIO *io;                              /* Server IO */
113         guint read_so_far;                      /* Number of bytes processed */
114         GAtDisconnectFunc user_disconnect;      /* User disconnect func */
115         gpointer user_disconnect_data;          /* User disconnect data */
116         GAtDebugFunc debugf;                    /* Debugging output function */
117         gpointer debug_data;                    /* Data to pass to debug func */
118         GHashTable *command_list;               /* List of AT commands */
119         GQueue *write_queue;                    /* Write buffer queue */
120         guint max_read_attempts;                /* Max reads per select */
121         enum ParserState parser_state;
122         gboolean destroyed;                     /* Re-entrancy guard */
123         char *last_line;                        /* Last read line */
124         unsigned int cur_pos;                   /* Where we are on the line */
125         GAtServerResult last_result;
126         gboolean final_sent;
127         gboolean final_async;
128         gboolean in_read_handler;
129         GAtServerFinishFunc finishf;            /* Callback when cmd finishes */
130         gpointer finish_data;                   /* Finish func data */
131 };
132
133 static void server_wakeup_writer(GAtServer *server);
134 static void server_parse_line(GAtServer *server);
135
136 static struct ring_buffer *allocate_next(GAtServer *server)
137 {
138         struct ring_buffer *buf = ring_buffer_new(BUF_SIZE);
139
140         if (buf == NULL)
141                 return NULL;
142
143         g_queue_push_tail(server->write_queue, buf);
144
145         return buf;
146 }
147
148 static void send_common(GAtServer *server, const char *buf, unsigned int len)
149 {
150         gsize towrite = len;
151         gsize bytes_written = 0;
152         struct ring_buffer *write_buf;
153
154         write_buf = g_queue_peek_tail(server->write_queue);
155
156         while (bytes_written < towrite) {
157                 gsize wbytes = MIN((gsize)ring_buffer_avail(write_buf),
158                                                 towrite - bytes_written);
159
160                 bytes_written += ring_buffer_write(write_buf,
161                                                         buf + bytes_written,
162                                                         wbytes);
163
164                 /*
165                  * Make sure we don't allocate a buffer if we've written
166                  * everything out already
167                  */
168                 if (ring_buffer_avail(write_buf) == 0 &&
169                                 bytes_written < towrite)
170                         write_buf = allocate_next(server);
171         }
172
173         server_wakeup_writer(server);
174 }
175
176 static void send_result_common(GAtServer *server, const char *result)
177
178 {
179         struct v250_settings v250 = server->v250;
180         char buf[MAX_TEXT_SIZE + 1];
181         char t = v250.s3;
182         char r = v250.s4;
183         unsigned int len;
184
185         if (v250.quiet)
186                 return;
187
188         if (result == NULL)
189                 return;
190
191         if (strlen(result) > 2048)
192                 return;
193
194         if (v250.is_v1)
195                 len = sprintf(buf, "%c%c%s%c%c", t, r, result, t, r);
196         else
197                 len = sprintf(buf, "%s%c", result, t);
198
199         send_common(server, buf, len);
200 }
201
202 static inline void send_final_common(GAtServer *server, const char *result)
203 {
204         send_result_common(server, result);
205         server->final_async = FALSE;
206
207         if (server->finishf)
208                 server->finishf(server, server->finish_data);
209 }
210
211 static inline void send_final_numeric(GAtServer *server, GAtServerResult result)
212 {
213         char buf[1024];
214
215         if (server->v250.is_v1)
216                 sprintf(buf, "%s", server_result_to_string(result));
217         else
218                 sprintf(buf, "%u", (unsigned int)result);
219
220         send_final_common(server, buf);
221 }
222
223 void g_at_server_send_final(GAtServer *server, GAtServerResult result)
224 {
225         if (server == NULL)
226                 return;
227
228         if (server->final_sent != FALSE)
229                 return;
230
231         server->final_sent = TRUE;
232         server->last_result = result;
233
234         if (result == G_AT_SERVER_RESULT_OK) {
235                 if (server->final_async)
236                         server_parse_line(server);
237
238                 return;
239         }
240
241         send_final_numeric(server, result);
242 }
243
244 void g_at_server_send_ext_final(GAtServer *server, const char *result)
245 {
246         server->final_sent = TRUE;
247         server->last_result = G_AT_SERVER_RESULT_EXT_ERROR;
248         send_final_common(server, result);
249 }
250
251 void g_at_server_send_intermediate(GAtServer *server, const char *result)
252 {
253         send_result_common(server, result);
254 }
255
256 void g_at_server_send_unsolicited(GAtServer *server, const char *result)
257 {
258         send_result_common(server, result);
259 }
260
261 void g_at_server_send_info(GAtServer *server, const char *line, gboolean last)
262 {
263         char buf[MAX_TEXT_SIZE + 1];
264         char t = server->v250.s3;
265         char r = server->v250.s4;
266         unsigned int len;
267
268         if (strlen(line) > 2048)
269                 return;
270
271         if (last)
272                 len = sprintf(buf, "%c%c%s%c%c", t, r, line, t, r);
273         else
274                 len = sprintf(buf, "%c%c%s", t, r, line);
275
276         send_common(server, buf, len);
277 }
278
279 static gboolean get_result_value(GAtServer *server, GAtResult *result,
280                                                 int min, int max, int *value)
281 {
282         GAtResultIter iter;
283         int val;
284
285         g_at_result_iter_init(&iter, result);
286
287         if (!g_at_result_iter_next(&iter, ""))
288                 return FALSE;
289
290         if (!g_at_result_iter_next_number(&iter, &val))
291                 return FALSE;
292
293         if (val < min || val > max)
294                 return FALSE;
295
296         if (value)
297                 *value = val;
298
299         return TRUE;
300 }
301
302 static void v250_settings_create(struct v250_settings *v250)
303 {
304         v250->s0 = 0;
305         v250->s3 = '\r';
306         v250->s4 = '\n';
307         v250->s5 = '\b';
308         v250->s6 = 2;
309         v250->s7 = 50;
310         v250->s8 = 2;
311         v250->s10 = 2;
312         v250->echo = TRUE;
313         v250->quiet = FALSE;
314         v250->is_v1 = TRUE;
315         v250->res_format = 0;
316         v250->c109 = 1;
317         v250->c108 = 0;
318         v250->l = 0;
319         v250->m = 1;
320         v250->dial_mode = 'T';
321 }
322
323 static void s_template_cb(GAtServerRequestType type, GAtResult *result,
324                                         GAtServer *server, char *sreg,
325                                         const char *prefix, int min, int max)
326 {
327         char buf[20];
328         int tmp;
329
330         switch (type) {
331         case G_AT_SERVER_REQUEST_TYPE_SET:
332                 if (!get_result_value(server, result, min, max, &tmp)) {
333                         g_at_server_send_final(server,
334                                                 G_AT_SERVER_RESULT_ERROR);
335                         return;
336                 }
337
338                 *sreg = tmp;
339                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
340                 break;
341
342         case G_AT_SERVER_REQUEST_TYPE_QUERY:
343                 tmp = *sreg;
344                 sprintf(buf, "%03d", tmp);
345                 g_at_server_send_info(server, buf, TRUE);
346                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
347                 break;
348
349         case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
350                 sprintf(buf, "%s: (%d-%d)", prefix, min, max);
351                 g_at_server_send_info(server, buf, TRUE);
352                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
353                 break;
354
355         default:
356                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
357                 break;
358         }
359 }
360
361 static void at_s0_cb(GAtServer *server, GAtServerRequestType type,
362                         GAtResult *result, gpointer user_data)
363 {
364         s_template_cb(type, result, server, &server->v250.s0, "S0", 0, 7);
365 }
366
367 static void at_s3_cb(GAtServer *server, GAtServerRequestType type,
368                         GAtResult *result, gpointer user_data)
369 {
370         s_template_cb(type, result, server, &server->v250.s3, "S3", 0, 127);
371 }
372
373 static void at_s4_cb(GAtServer *server, GAtServerRequestType type,
374                         GAtResult *result, gpointer user_data)
375 {
376         s_template_cb(type, result, server, &server->v250.s4, "S4", 0, 127);
377 }
378
379 static void at_s5_cb(GAtServer *server, GAtServerRequestType type,
380                         GAtResult *result, gpointer user_data)
381 {
382         s_template_cb(type, result, server, &server->v250.s5, "S5", 0, 127);
383 }
384
385 static void at_l_cb(GAtServer *server, GAtServerRequestType type,
386                         GAtResult *result, gpointer user_data)
387 {
388         s_template_cb(type, result, server, &server->v250.l, "L", 0, 3);
389 }
390
391 static void at_m_cb(GAtServer *server, GAtServerRequestType type,
392                         GAtResult *result, gpointer user_data)
393 {
394         s_template_cb(type, result, server, &server->v250.m, "M", 0, 2);
395 }
396
397 static void at_template_cb(GAtServerRequestType type, GAtResult *result,
398                                         GAtServer *server, int *value,
399                                         const char *prefix,
400                                         int min, int max, int deftval)
401 {
402         char buf[20];
403         int tmp;
404
405         switch (type) {
406         case G_AT_SERVER_REQUEST_TYPE_SET:
407                 if (!get_result_value(server, result, min, max, &tmp)) {
408                         g_at_server_send_final(server,
409                                                 G_AT_SERVER_RESULT_ERROR);
410                         return;
411                 }
412
413                 *value = tmp;
414                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
415                 break;
416
417         case G_AT_SERVER_REQUEST_TYPE_QUERY:
418                 tmp = *value;
419                 sprintf(buf, "%s: %d", prefix, tmp);
420                 g_at_server_send_info(server, buf, TRUE);
421                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
422                 break;
423
424         case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
425                 sprintf(buf, "%s: (%d-%d)", prefix, min, max);
426                 g_at_server_send_info(server, buf, TRUE);
427                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
428                 break;
429
430         case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
431                 *value = deftval;
432                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
433                 break;
434
435         default:
436                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
437                 break;
438         }
439 }
440
441 static void at_e_cb(GAtServer *server, GAtServerRequestType type,
442                         GAtResult *result, gpointer user_data)
443 {
444         at_template_cb(type, result, server, &server->v250.echo, "E", 0, 1, 1);
445 }
446
447 static void at_q_cb(GAtServer *server, GAtServerRequestType type,
448                         GAtResult *result, gpointer user_data)
449 {
450         at_template_cb(type, result, server, &server->v250.quiet, "Q", 0, 1, 0);
451 }
452
453 static void at_v_cb(GAtServer *server, GAtServerRequestType type,
454                         GAtResult *result, gpointer user_data)
455 {
456         at_template_cb(type, result, server, &server->v250.is_v1, "V", 0, 1, 1);
457 }
458
459 static void at_x_cb(GAtServer *server, GAtServerRequestType type,
460                         GAtResult *result, gpointer user_data)
461 {
462         at_template_cb(type, result, server, &server->v250.res_format,
463                         "X", 0, 4, 4);
464 }
465
466 static void at_s6_cb(GAtServer *server, GAtServerRequestType type,
467                         GAtResult *result, gpointer user_data)
468 {
469         at_template_cb(type, result, server, &server->v250.s6, "S6", 0, 1, 1);
470 }
471
472 static void at_s7_cb(GAtServer *server, GAtServerRequestType type,
473                         GAtResult *result, gpointer user_data)
474 {
475         at_template_cb(type, result, server, &server->v250.s7, "S7", 1, 255, 50);
476 }
477
478 static void at_s8_cb(GAtServer *server, GAtServerRequestType type,
479                         GAtResult *result, gpointer user_data)
480 {
481         at_template_cb(type, result, server, &server->v250.s8, "S8", 1, 255, 2);
482 }
483
484 static void at_s10_cb(GAtServer *server, GAtServerRequestType type,
485                         GAtResult *result, gpointer user_data)
486 {
487         at_template_cb(type, result, server, &server->v250.s10, "S10", 1, 254, 2);
488 }
489
490 static void at_c109_cb(GAtServer *server, GAtServerRequestType type,
491                         GAtResult *result, gpointer user_data)
492 {
493         at_template_cb(type, result, server, &server->v250.c109, "&C", 0, 1, 1);
494 }
495
496 static void at_c108_cb(GAtServer *server, GAtServerRequestType type,
497                         GAtResult *result, gpointer user_data)
498 {
499         at_template_cb(type, result, server, &server->v250.c108, "&D", 0, 2, 2);
500 }
501
502 /* According to ITU V.250 6.3.2 and 6.3.3: "Implementation of this command
503  * is mandatory; however, if DTMF or pulse dialling is not implemented,
504  * this command will have no effect"
505  */
506 static void at_t_cb(GAtServer *server, GAtServerRequestType type,
507                                         GAtResult *result, gpointer user_data)
508 {
509         switch (type) {
510         case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
511                 server->v250.dial_mode = 'T';
512                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
513                 break;
514
515         default:
516                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
517                 break;
518         }
519 }
520
521 static void at_p_cb(GAtServer *server, GAtServerRequestType type,
522                                         GAtResult *result, gpointer user_data)
523 {
524         switch (type) {
525         case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
526                 server->v250.dial_mode = 'P';
527                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
528                 break;
529
530         default:
531                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
532                 break;
533         }
534 }
535
536 static void at_f_cb(GAtServer *server, GAtServerRequestType type,
537                         GAtResult *result, gpointer user_data)
538 {
539         switch (type) {
540         case G_AT_SERVER_REQUEST_TYPE_SET:
541                 if (!get_result_value(server, result, 0, 0, NULL)) {
542                         g_at_server_send_final(server,
543                                                 G_AT_SERVER_RESULT_ERROR);
544                         return;
545                 }
546                 /* intentional fallback here */
547
548         case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
549                 /* default behavior on AT&F same as ATZ */
550                 v250_settings_create(&server->v250);
551                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
552                 break;
553
554         default:
555                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
556                 break;
557         }
558 }
559
560 static void at_z_cb(GAtServer *server, GAtServerRequestType type,
561                         GAtResult *result, gpointer user_data)
562 {
563         switch (type) {
564         case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
565                 v250_settings_create(&server->v250);
566                 g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
567                 break;
568
569         default:
570                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
571                 break;
572         }
573 }
574
575 static inline gboolean is_extended_command_prefix(const char c)
576 {
577         switch (c) {
578         case '+':
579         case '*':
580         case '!':
581         case '%':
582                 return TRUE;
583         default:
584                 return FALSE;
585         }
586 }
587
588 static void at_command_notify(GAtServer *server, char *command,
589                                 char *prefix, GAtServerRequestType type)
590 {
591         struct at_command *node;
592         GAtResult result;
593
594         node = g_hash_table_lookup(server->command_list, prefix);
595
596         if (node == NULL) {
597                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
598                 return;
599         }
600
601         result.lines = g_slist_prepend(NULL, command);
602         result.final_or_pdu = 0;
603
604         node->notify(server, type, &result, node->user_data);
605
606         g_slist_free(result.lines);
607 }
608
609 static unsigned int parse_extended_command(GAtServer *server, char *buf)
610 {
611         const char *valid_extended_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
612                                                 "0123456789!%-./:_";
613         const char *separators = ";?=";
614         unsigned int prefix_len, i;
615         gboolean in_string = FALSE;
616         gboolean seen_equals = FALSE;
617         char prefix[18]; /* According to V250, 5.4.1 */
618         GAtServerRequestType type;
619         char tmp;
620         unsigned int cmd_start;
621
622         prefix_len = strcspn(buf, separators);
623
624         if (prefix_len > 17 || prefix_len < 2)
625                 return 0;
626
627         /* Convert to upper case, we will always use upper case naming */
628         for (i = 0; i < prefix_len; i++)
629                 prefix[i] = g_ascii_toupper(buf[i]);
630
631         prefix[prefix_len] = '\0';
632
633         if (strspn(prefix + 1, valid_extended_chars) != (prefix_len - 1))
634                 return 0;
635
636         /*
637          * V.250 Section 5.4.1: "The first character following "+" shall be
638          * an alphabetic character in the range "A" through "Z".
639          */
640         if (prefix[1] <= 'A' || prefix[1] >= 'Z')
641                 return 0;
642
643         if (buf[i] != '\0' && buf[i] != ';' && buf[i] != '?' && buf[i] != '=')
644                 return 0;
645
646         type = G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY;
647         cmd_start = prefix_len;
648
649         /* Continue until we hit eol or ';' */
650         while (buf[i] && !(buf[i] == ';' && in_string == FALSE)) {
651                 if (buf[i] == '"') {
652                         in_string = !in_string;
653                         goto next;
654                 }
655
656                 if (in_string == TRUE)
657                         goto next;
658
659                 if (buf[i] == '?') {
660                         if (seen_equals && buf[i-1] != '=')
661                                 return 0;
662
663                         if (buf[i + 1] != '\0' && buf[i + 1] != ';')
664                                 return 0;
665
666                         type = G_AT_SERVER_REQUEST_TYPE_QUERY;
667                         cmd_start += 1;
668
669                         if (seen_equals)
670                                 type = G_AT_SERVER_REQUEST_TYPE_SUPPORT;
671                 } else if (buf[i] == '=') {
672                         if (seen_equals)
673                                 return 0;
674
675                         seen_equals = TRUE;
676                         type = G_AT_SERVER_REQUEST_TYPE_SET;
677                         cmd_start += 1;
678                 }
679
680 next:
681                 i++;
682         }
683
684         /* We can scratch in this buffer, so mark ';' as null */
685         tmp = buf[i];
686         buf[i] = '\0';
687         at_command_notify(server, buf + cmd_start, prefix, type);
688         buf[i] = tmp;
689
690         /* Also consume the terminating null */
691         return i + 1;
692 }
693
694 static int get_basic_prefix_size(const char *buf)
695 {
696         if (g_ascii_isalpha(buf[0])) {
697                 if (g_ascii_toupper(buf[0]) == 'S') {
698                         int size;
699
700                         /* V.250 5.3.2 'S' command follows with a parameter
701                          * number.
702                          */
703                         for (size = 1; g_ascii_isdigit(buf[size]); size++)
704                                 ;
705
706                         /*
707                          * Do some basic sanity checking, don't accept 00, 01,
708                          * etc or empty S values
709                          */
710                         if (size == 1)
711                                 return 0;
712
713                         if (size > 2 && buf[1] == '0')
714                                 return 0;
715
716                         return size;
717                 }
718
719                 /* All other cases it is a simple 1 character prefix */
720                 return 1;
721         }
722
723         if (buf[0] == '&') {
724                 if (g_ascii_isalpha(buf[1]) == FALSE)
725                         return 0;
726
727                 return 2;
728         }
729
730         return 0;
731 }
732
733 static unsigned int parse_basic_command(GAtServer *server, char *buf)
734 {
735         gboolean seen_equals = FALSE;
736         char prefix[4], tmp;
737         unsigned int i, prefix_size;
738         GAtServerRequestType type;
739         unsigned int cmd_start;
740
741         prefix_size = get_basic_prefix_size(buf);
742         if (prefix_size == 0)
743                 return 0;
744
745         i = prefix_size;
746         prefix[0] = g_ascii_toupper(buf[0]);
747         cmd_start = prefix_size;
748
749         if (prefix[0] == 'D') {
750                 type = G_AT_SERVER_REQUEST_TYPE_SET;
751
752                 /* All characters appearing on the same line, up to a
753                  * semicolon character (IA5 3/11) or the end of the
754                  * command line is the part of the call.
755                  */
756                 while (buf[i] != '\0' && buf[i] != ';')
757                         i += 1;
758
759                 if (buf[i] == ';')
760                         i += 1;
761
762                 goto done;
763         }
764
765         type = G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY;
766
767         /* Match '?', '=',  '=?' and '=xxx' */
768         if (buf[i] == '=') {
769                 seen_equals = TRUE;
770                 i += 1;
771                 cmd_start += 1;
772         }
773
774         if (buf[i] == '?') {
775                 i += 1;
776                 cmd_start += 1;
777
778                 if (seen_equals)
779                         type = G_AT_SERVER_REQUEST_TYPE_SUPPORT;
780                 else
781                         type = G_AT_SERVER_REQUEST_TYPE_QUERY;
782         } else {
783                 int before = i;
784
785                 /* V.250 5.3.1 The subparameter (if any) are all digits */
786                 while (g_ascii_isdigit(buf[i]))
787                         i++;
788
789                 if (i - before > 0)
790                         type = G_AT_SERVER_REQUEST_TYPE_SET;
791         }
792
793 done:
794         if (prefix_size <= 3) {
795                 memcpy(prefix + 1, buf + 1, prefix_size - 1);
796                 prefix[prefix_size] = '\0';
797
798                 tmp = buf[i];
799                 buf[i] = '\0';
800                 at_command_notify(server, buf + cmd_start, prefix, type);
801                 buf[i] = tmp;
802         } else /* Handle S-parameter with 100+ */
803                 g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
804
805         /*
806          * Commands like ATA, ATZ cause the remainder linevto be ignored.
807          * In GSM/UMTS the ATD uses the separator ';' character as a voicecall
808          * modifier, so we ignore everything coming after that character
809          * as well.
810          */
811         if (prefix[0] == 'A' || prefix[0] == 'Z' || prefix[0] == 'D')
812                 return strlen(buf);
813
814         /* Consume the seperator ';' */
815         if (buf[i] == ';')
816                 i += 1;
817
818         return i;
819 }
820
821 static void server_parse_line(GAtServer *server)
822 {
823         char *line = server->last_line;
824         unsigned int pos = server->cur_pos;
825         unsigned int len = strlen(line);
826
827         while (pos < len) {
828                 unsigned int consumed;
829
830                 server->final_sent = FALSE;
831                 server->final_async = FALSE;
832
833                 if (is_extended_command_prefix(line[pos]))
834                         consumed = parse_extended_command(server, line + pos);
835                 else
836                         consumed = parse_basic_command(server, line + pos);
837
838                 if (consumed == 0) {
839                         g_at_server_send_final(server,
840                                                 G_AT_SERVER_RESULT_ERROR);
841                         return;
842                 }
843
844                 pos += consumed;
845                 server->cur_pos = pos;
846
847                 /*
848                  * We wait the callback until it finished processing
849                  * the command and called the send_final.
850                  */
851                 if (server->final_sent == FALSE) {
852                         server->final_async = TRUE;
853                         return;
854                 }
855
856                 if (server->last_result != G_AT_SERVER_RESULT_OK)
857                         return;
858         }
859
860         send_final_numeric(server, G_AT_SERVER_RESULT_OK);
861 }
862
863 static enum ParserResult server_feed(GAtServer *server,
864                                         const char *bytes, gsize *len)
865 {
866         gsize i = 0;
867         enum ParserResult res = PARSER_RESULT_UNSURE;
868         char s3 = server->v250.s3;
869
870         while (i < *len) {
871                 char byte = bytes[i];
872
873                 switch (server->parser_state) {
874                 case PARSER_STATE_IDLE:
875                         if (byte == s3) {
876                                 i += 1;
877                                 res = PARSER_RESULT_EMPTY_COMMAND;
878                                 goto out;
879                         } else if (byte == '\n') {
880                                 i += 1;
881                                 res = PARSER_RESULT_GARBAGE;
882                                 goto out;
883                         } else if (byte == 'A' || byte == 'a')
884                                 server->parser_state = PARSER_STATE_A;
885                         else if (byte != ' ' && byte != '\t')
886                                 server->parser_state = PARSER_STATE_GARBAGE;
887                         break;
888
889                 case PARSER_STATE_A:
890                         if (byte == s3) {
891                                 server->parser_state = PARSER_STATE_IDLE;
892                                 i += 1;
893                                 res = PARSER_RESULT_GARBAGE;
894                                 goto out;
895                         } else if (byte == '/') {
896                                 server->parser_state = PARSER_STATE_IDLE;
897                                 i += 1;
898                                 res = PARSER_RESULT_REPEAT_LAST;
899                                 goto out;
900                         } else if (byte == 'T' || byte == 't')
901                                 server->parser_state = PARSER_STATE_COMMAND;
902                         else
903                                 server->parser_state = PARSER_STATE_GARBAGE;
904
905                         break;
906
907                 case PARSER_STATE_COMMAND:
908                         if (byte == s3) {
909                                 server->parser_state = PARSER_STATE_IDLE;
910                                 i += 1;
911                                 res = PARSER_RESULT_COMMAND;
912                                 goto out;
913                         }
914                         break;
915
916                 case PARSER_STATE_GARBAGE:
917                         /* Detect CR or HDLC frame marker flag */
918                         if (byte == s3 || byte == '~') {
919                                 server->parser_state = PARSER_STATE_IDLE;
920                                 i += 1;
921                                 res = PARSER_RESULT_GARBAGE;
922                                 goto out;
923                         }
924                         break;
925
926                 default:
927                         break;
928                 };
929
930                 i += 1;
931         }
932
933 out:
934         *len = i;
935         return res;
936 }
937
938 static char *extract_line(GAtServer *p, struct ring_buffer *rbuf)
939 {
940         unsigned int wrap = ring_buffer_len_no_wrap(rbuf);
941         unsigned int pos = 0;
942         unsigned char *buf = ring_buffer_read_ptr(rbuf, pos);
943         int strip_front = 0;
944         int line_length = 0;
945         gboolean in_string = FALSE;
946         char s3 = p->v250.s3;
947         char s5 = p->v250.s5;
948         char *line;
949         int i;
950
951         while (pos < p->read_so_far) {
952                 if (*buf == '"')
953                         in_string = !in_string;
954
955                 if (in_string == FALSE && (*buf == ' ' || *buf == '\t')) {
956                         if (line_length == 0)
957                                 strip_front += 1;
958                 } else
959                         line_length += 1;
960
961                 buf += 1;
962                 pos += 1;
963
964                 if (pos == wrap)
965                         buf = ring_buffer_read_ptr(rbuf, pos);
966         }
967
968         /* We will strip AT and S3 */
969         line_length -= 3;
970
971         line = g_try_new(char, line_length + 1);
972         if (line == NULL) {
973                 ring_buffer_drain(rbuf, p->read_so_far);
974                 return NULL;
975         }
976
977         /* Strip leading whitespace + AT */
978         ring_buffer_drain(rbuf, strip_front + 2);
979
980         pos = 0;
981         i = 0;
982         wrap = ring_buffer_len_no_wrap(rbuf);
983         buf = ring_buffer_read_ptr(rbuf, pos);
984
985         while (pos < (p->read_so_far - strip_front - 2)) {
986                 if (*buf == '"')
987                         in_string = !in_string;
988
989                 if (*buf == s5) {
990                         if (i != 0)
991                                 i -= 1;
992                 } else if ((*buf == ' ' || *buf == '\t') && in_string == FALSE)
993                         ; /* Skip */
994                 else if (*buf != s3)
995                         line[i++] = *buf;
996
997                 buf += 1;
998                 pos += 1;
999
1000                 if (pos == wrap)
1001                         buf = ring_buffer_read_ptr(rbuf, pos);
1002         }
1003
1004         /* Strip S3 */
1005         ring_buffer_drain(rbuf, p->read_so_far - strip_front - 2);
1006
1007         line[i] = '\0';
1008
1009         return line;
1010 }
1011
1012 static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
1013 {
1014         GAtServer *p = user_data;
1015         unsigned int len = ring_buffer_len(rbuf);
1016         unsigned int wrap = ring_buffer_len_no_wrap(rbuf);
1017         unsigned char *buf = ring_buffer_read_ptr(rbuf, p->read_so_far);
1018         enum ParserResult result;
1019
1020         /* We do not support command abortion, so ignore input */
1021         if (p->final_async) {
1022                 ring_buffer_drain(rbuf, len);
1023                 return;
1024         }
1025
1026         p->in_read_handler = TRUE;
1027
1028         while (p->io && (p->read_so_far < len)) {
1029                 gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
1030                 result = server_feed(p, (char *)buf, &rbytes);
1031
1032                 if (p->v250.echo)
1033                         send_common(p, (char *)buf, rbytes);
1034
1035                 buf += rbytes;
1036                 p->read_so_far += rbytes;
1037
1038                 if (p->read_so_far == wrap) {
1039                         buf = ring_buffer_read_ptr(rbuf, p->read_so_far);
1040                         wrap = len;
1041                 }
1042
1043                 switch (result) {
1044                 case PARSER_RESULT_UNSURE:
1045                         continue;
1046
1047                 case PARSER_RESULT_EMPTY_COMMAND:
1048                         /*
1049                          * According to section 5.2.4 and 5.6 of V250,
1050                          * Empty commands must be OK by the DCE
1051                          */
1052                         g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
1053                         ring_buffer_drain(rbuf, p->read_so_far);
1054                         break;
1055
1056                 case PARSER_RESULT_COMMAND:
1057                 {
1058                         g_free(p->last_line);
1059
1060                         p->last_line = extract_line(p, rbuf);
1061                         p->cur_pos = 0;
1062
1063                         if (p->last_line)
1064                                 server_parse_line(p);
1065                         else
1066                                 g_at_server_send_final(p,
1067                                                 G_AT_SERVER_RESULT_ERROR);
1068                         break;
1069                 }
1070
1071                 case PARSER_RESULT_REPEAT_LAST:
1072                         p->cur_pos = 0;
1073                         ring_buffer_drain(rbuf, p->read_so_far);
1074
1075                         if (p->last_line)
1076                                 server_parse_line(p);
1077                         else
1078                                 g_at_server_send_final(p,
1079                                                 G_AT_SERVER_RESULT_OK);
1080                         break;
1081
1082                 case PARSER_RESULT_GARBAGE:
1083                         ring_buffer_drain(rbuf, p->read_so_far);
1084                         break;
1085                 }
1086
1087                 len -= p->read_so_far;
1088                 wrap -= p->read_so_far;
1089                 p->read_so_far = 0;
1090
1091                 /*
1092                  * Handle situations where we receive two command lines in
1093                  * one read, which should not be possible (and implies the
1094                  * earlier command should be canceled.
1095                  *
1096                  * e.g. AT+CMD1\rAT+CMD2
1097                  */
1098                 if (result != PARSER_RESULT_GARBAGE) {
1099                         ring_buffer_drain(rbuf, len);
1100                         break;
1101                 }
1102         }
1103
1104         p->in_read_handler = FALSE;
1105
1106         if (p->destroyed)
1107                 g_free(p);
1108 }
1109
1110 static gboolean can_write_data(gpointer data)
1111 {
1112         GAtServer *server = data;
1113         gsize bytes_written;
1114         gsize towrite;
1115         struct ring_buffer *write_buf;
1116         unsigned char *buf;
1117 #ifdef WRITE_SCHEDULER_DEBUG
1118         int limiter;
1119 #endif
1120
1121         if (!server->write_queue)
1122                 return FALSE;
1123
1124         /* Write data out from the head of the queue */
1125         write_buf = g_queue_peek_head(server->write_queue);
1126
1127         buf = ring_buffer_read_ptr(write_buf, 0);
1128
1129         towrite = ring_buffer_len_no_wrap(write_buf);
1130
1131 #ifdef WRITE_SCHEDULER_DEBUG
1132         limiter = towrite;
1133
1134         if (limiter > 5)
1135                 limiter = 5;
1136 #endif
1137
1138         bytes_written = g_at_io_write(server->io,
1139                         (char *)buf,
1140 #ifdef WRITE_SCHEDULER_DEBUG
1141                         limiter
1142 #else
1143                         towrite
1144 #endif
1145                         );
1146
1147         if (bytes_written == 0)
1148                 return FALSE;
1149
1150         ring_buffer_drain(write_buf, bytes_written);
1151
1152         /* All data in current buffer is written, free it
1153          * unless it's the last buffer in the queue.
1154          */
1155         if ((ring_buffer_len(write_buf) == 0) &&
1156                         (g_queue_get_length(server->write_queue) > 1)) {
1157                 write_buf = g_queue_pop_head(server->write_queue);
1158                 ring_buffer_free(write_buf);
1159                 write_buf = g_queue_peek_head(server->write_queue);
1160         }
1161
1162         if (ring_buffer_len(write_buf) > 0)
1163                 return TRUE;
1164
1165         return FALSE;
1166 }
1167
1168 static void write_queue_free(GQueue *write_queue)
1169 {
1170         struct ring_buffer *write_buf;
1171
1172         while ((write_buf = g_queue_pop_head(write_queue)))
1173                 ring_buffer_free(write_buf);
1174
1175         g_queue_free(write_queue);
1176 }
1177
1178 static void g_at_server_cleanup(GAtServer *server)
1179 {
1180         /* Cleanup pending data to write */
1181         write_queue_free(server->write_queue);
1182
1183         g_hash_table_destroy(server->command_list);
1184         server->command_list = NULL;
1185
1186         g_free(server->last_line);
1187
1188         g_at_io_unref(server->io);
1189         server->io = NULL;
1190 }
1191
1192 static void io_disconnect(gpointer user_data)
1193 {
1194         GAtServer *server = user_data;
1195
1196         g_at_server_cleanup(server);
1197
1198         if (server->user_disconnect)
1199                 server->user_disconnect(server->user_disconnect_data);
1200 }
1201
1202 static void server_wakeup_writer(GAtServer *server)
1203 {
1204         g_at_io_set_write_handler(server->io, can_write_data, server);
1205 }
1206
1207 static void at_notify_node_destroy(gpointer data)
1208 {
1209         struct at_command *node = data;
1210
1211         if (node->destroy_notify)
1212                 node->destroy_notify(node->user_data);
1213
1214         g_free(node);
1215 }
1216
1217 static void basic_command_register(GAtServer *server)
1218 {
1219         g_at_server_register(server, "S0", at_s0_cb, NULL, NULL);
1220         g_at_server_register(server, "S3", at_s3_cb, NULL, NULL);
1221         g_at_server_register(server, "S4", at_s4_cb, NULL, NULL);
1222         g_at_server_register(server, "S5", at_s5_cb, NULL, NULL);
1223         g_at_server_register(server, "E", at_e_cb, NULL, NULL);
1224         g_at_server_register(server, "Q", at_q_cb, NULL, NULL);
1225         g_at_server_register(server, "V", at_v_cb, NULL, NULL);
1226         g_at_server_register(server, "X", at_x_cb, NULL, NULL);
1227         g_at_server_register(server, "S6", at_s6_cb, NULL, NULL);
1228         g_at_server_register(server, "S7", at_s7_cb, NULL, NULL);
1229         g_at_server_register(server, "S8", at_s8_cb, NULL, NULL);
1230         g_at_server_register(server, "S10", at_s10_cb, NULL, NULL);
1231         g_at_server_register(server, "&C", at_c109_cb, NULL, NULL);
1232         g_at_server_register(server, "&D", at_c108_cb, NULL, NULL);
1233         g_at_server_register(server, "Z", at_z_cb, NULL, NULL);
1234         g_at_server_register(server, "&F", at_f_cb, NULL, NULL);
1235         g_at_server_register(server, "L", at_l_cb, NULL, NULL);
1236         g_at_server_register(server, "M", at_m_cb, NULL, NULL);
1237         g_at_server_register(server, "T", at_t_cb, NULL, NULL);
1238         g_at_server_register(server, "P", at_p_cb, NULL, NULL);
1239 }
1240
1241 GAtServer *g_at_server_new(GIOChannel *io)
1242 {
1243         GAtServer *server;
1244
1245         if (io == NULL)
1246                 return NULL;
1247
1248         server = g_try_new0(GAtServer, 1);
1249         if (server == NULL)
1250                 return NULL;
1251
1252         server->ref_count = 1;
1253         v250_settings_create(&server->v250);
1254         server->io = g_at_io_new(io);
1255         if (!server->io)
1256                 goto error;
1257
1258         g_at_io_set_disconnect_function(server->io, io_disconnect, server);
1259
1260         server->command_list = g_hash_table_new_full(g_str_hash, g_str_equal,
1261                                                         g_free,
1262                                                         at_notify_node_destroy);
1263
1264         server->write_queue = g_queue_new();
1265         if (!server->write_queue)
1266                 goto error;
1267
1268         if (allocate_next(server) == NULL)
1269                 goto error;
1270
1271         server->max_read_attempts = 3;
1272
1273         g_at_io_set_read_handler(server->io, new_bytes, server);
1274
1275         basic_command_register(server);
1276
1277         return server;
1278
1279 error:
1280         g_at_io_unref(server->io);
1281
1282         if (server->command_list)
1283                 g_hash_table_destroy(server->command_list);
1284
1285         if (server->write_queue)
1286                 write_queue_free(server->write_queue);
1287
1288         if (server)
1289                 g_free(server);
1290
1291         return NULL;
1292 }
1293
1294 GIOChannel *g_at_server_get_channel(GAtServer *server)
1295 {
1296         if (server == NULL || server->io == NULL)
1297                 return NULL;
1298
1299         return g_at_io_get_channel(server->io);
1300 }
1301
1302 GAtIO *g_at_server_get_io(GAtServer *server)
1303 {
1304         if (server == NULL)
1305                 return NULL;
1306
1307         return server->io;
1308 }
1309
1310 GAtServer *g_at_server_ref(GAtServer *server)
1311 {
1312         if (server == NULL)
1313                 return NULL;
1314
1315         g_atomic_int_inc(&server->ref_count);
1316
1317         return server;
1318 }
1319
1320 void g_at_server_suspend(GAtServer *server)
1321 {
1322         if (server == NULL)
1323                 return;
1324
1325         g_at_io_set_write_handler(server->io, NULL, NULL);
1326         g_at_io_set_read_handler(server->io, NULL, NULL);
1327
1328         g_at_io_set_debug(server->io, NULL, NULL);
1329 }
1330
1331 void g_at_server_resume(GAtServer *server)
1332 {
1333         if (server == NULL)
1334                 return;
1335
1336         if (g_at_io_get_channel(server->io) == NULL) {
1337                 io_disconnect(server);
1338                 return;
1339         }
1340
1341         g_at_io_set_disconnect_function(server->io, io_disconnect, server);
1342
1343         g_at_io_set_debug(server->io, server->debugf, server->debug_data);
1344         g_at_io_set_read_handler(server->io, new_bytes, server);
1345
1346         if (g_queue_get_length(server->write_queue) > 0)
1347                 server_wakeup_writer(server);
1348 }
1349
1350 void g_at_server_unref(GAtServer *server)
1351 {
1352         gboolean is_zero;
1353
1354         if (server == NULL)
1355                 return;
1356
1357         is_zero = g_atomic_int_dec_and_test(&server->ref_count);
1358
1359         if (is_zero == FALSE)
1360                 return;
1361
1362         if (server->io) {
1363                 g_at_server_suspend(server);
1364                 g_at_server_cleanup(server);
1365         }
1366
1367         g_at_server_shutdown(server);
1368
1369         /* glib delays the destruction of the watcher until it exits, this
1370          * means we can't free the data just yet, even though we've been
1371          * destroyed already.  We have to wait until the read_watcher
1372          * destroy function gets called
1373          */
1374         if (server->in_read_handler)
1375                 server->destroyed = TRUE;
1376         else
1377                 g_free(server);
1378 }
1379
1380 gboolean g_at_server_shutdown(GAtServer *server)
1381 {
1382         if (server == NULL)
1383                 return FALSE;
1384
1385         /* Don't trigger user disconnect on shutdown */
1386         server->user_disconnect = NULL;
1387         server->user_disconnect_data = NULL;
1388
1389         return TRUE;
1390 }
1391
1392 gboolean g_at_server_set_echo(GAtServer *server, gboolean echo)
1393 {
1394         if (server == NULL)
1395                 return FALSE;
1396
1397         server->v250.echo = echo;
1398
1399         return TRUE;
1400 }
1401
1402 gboolean g_at_server_set_disconnect_function(GAtServer *server,
1403                                                 GAtDisconnectFunc disconnect,
1404                                                 gpointer user_data)
1405 {
1406         if (server == NULL)
1407                 return FALSE;
1408
1409         server->user_disconnect = disconnect;
1410         server->user_disconnect_data = user_data;
1411
1412         return TRUE;
1413 }
1414
1415 gboolean g_at_server_set_debug(GAtServer *server, GAtDebugFunc func,
1416                                                 gpointer user_data)
1417 {
1418         if (server == NULL)
1419                 return FALSE;
1420
1421         server->debugf = func;
1422         server->debug_data = user_data;
1423
1424         g_at_io_set_debug(server->io, server->debugf, server->debug_data);
1425
1426         return TRUE;
1427 }
1428
1429 gboolean g_at_server_register(GAtServer *server, const char *prefix,
1430                                         GAtServerNotifyFunc notify,
1431                                         gpointer user_data,
1432                                         GDestroyNotify destroy_notify)
1433 {
1434         struct at_command *node;
1435
1436         if (server == NULL || server->command_list == NULL)
1437                 return FALSE;
1438
1439         if (notify == NULL)
1440                 return FALSE;
1441
1442         if (prefix == NULL || strlen(prefix) == 0)
1443                 return FALSE;
1444
1445         node = g_try_new0(struct at_command, 1);
1446         if (node == NULL)
1447                 return FALSE;
1448
1449         node->notify = notify;
1450         node->user_data = user_data;
1451         node->destroy_notify = destroy_notify;
1452
1453         g_hash_table_replace(server->command_list, g_strdup(prefix), node);
1454
1455         return TRUE;
1456 }
1457
1458 gboolean g_at_server_unregister(GAtServer *server, const char *prefix)
1459 {
1460         struct at_command *node;
1461
1462         if (server == NULL || server->command_list == NULL)
1463                 return FALSE;
1464
1465         if (prefix == NULL || strlen(prefix) == 0)
1466                 return FALSE;
1467
1468         node = g_hash_table_lookup(server->command_list, prefix);
1469         if (node == NULL)
1470                 return FALSE;
1471
1472         g_hash_table_remove(server->command_list, prefix);
1473
1474         return TRUE;
1475 }
1476
1477 gboolean g_at_server_set_finish_callback(GAtServer *server,
1478                                                 GAtServerFinishFunc finishf,
1479                                                 gpointer user_data)
1480 {
1481         if (server == NULL)
1482                 return FALSE;
1483
1484         server->finishf = finishf;
1485         server->finish_data = user_data;
1486
1487         return TRUE;
1488 }
1489
1490 gboolean g_at_server_command_pending(GAtServer *server)
1491 {
1492         if (server == NULL)
1493                 return FALSE;
1494
1495         return server->final_async;
1496 }