---
 gatchat/gatserver.c |   98 ++++++++++++++++++++++++++++++++++++++++++++-------
 gatchat/gatserver.h |   17 +++++++++
 2 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 07999a8..cad9d91 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -33,6 +33,8 @@
 #include "gatserver.h"
 
 #define BUF_SIZE 4096
+/* <cr><lf> + the max length of information text + <cr><lf> */
+#define MAX_TEXT_SIZE 2052
 /* #define WRITE_SCHEDULER_DEBUG 1 */
 
 enum ParserState {
@@ -117,6 +119,7 @@ struct _GAtServer {
 };
 
 static void g_at_server_wakeup_writer(GAtServer *server);
+static void server_parse_line(GAtServer *server);
 
 static struct ring_buffer *allocate_next(GAtServer *server)
 {
@@ -158,11 +161,11 @@ static void send_common(GAtServer *server, const char 
*buf, unsigned int len)
        g_at_server_wakeup_writer(server);
 }
 
-static void g_at_server_send_final(GAtServer *server, GAtServerResult result)
+static void send_result_common(GAtServer *server, const char *result)
+
 {
        struct v250_settings v250 = server->v250;
-       const char *result_str = server_result_to_string(result);
-       char buf[1024];
+       char buf[MAX_TEXT_SIZE];
        char t = v250.s3;
        char r = v250.s4;
        unsigned int len;
@@ -170,19 +173,88 @@ static void g_at_server_send_final(GAtServer *server, 
GAtServerResult result)
        if (v250.quiet)
                return;
 
-       if (result_str == NULL)
+       if (result == NULL)
                return;
 
        if (v250.is_v1)
-               len = snprintf(buf, sizeof(buf), "%c%c%s%c%c", t, r, result_str,
+               len = snprintf(buf, sizeof(buf), "%c%c%s%c%c", t, r, result,
                                t, r);
        else
-               len = snprintf(buf, sizeof(buf), "%u%c", (unsigned int) result,
+               len = snprintf(buf, sizeof(buf), "%s%c", result,
                                t);
 
        send_common(server, buf, MIN(len, sizeof(buf)-1));
 }
 
+static void g_at_server_send_result(GAtServer *server, GAtServerResult result)
+{
+       char buf[1024];
+
+       if (server->v250.is_v1)
+               sprintf(buf, "%s", server_result_to_string(result));
+       else
+               sprintf(buf, "%u", (unsigned int)result);
+
+       send_result_common(server, buf);
+}
+
+void g_at_server_send_final(GAtServer *server, GAtServerResult result)
+{
+       char *line = server->read_line;
+       unsigned int pos = server->read_pos;
+       unsigned int len = strlen(line);
+
+       /* Continue only if the result is OK and we have further commands */
+       if (result == G_AT_SERVER_RESULT_OK && pos < len)
+               server_parse_line(server);
+       else if (result == G_AT_SERVER_RESULT_EXT_ERROR)
+               ;       /* Skip */
+       else
+               g_at_server_send_result(server, result);
+}
+
+void g_at_server_send_ext_final(GAtServer *server, const char *result)
+{
+       send_result_common(server, result);
+}
+
+void g_at_server_send_intermediate(GAtServer *server, const char *result)
+{
+       send_result_common(server, result);
+}
+
+void g_at_server_send_unsolicited(GAtServer *server, const char *result)
+{
+       send_result_common(server, result);
+}
+
+void g_at_server_send_info_text(GAtServer *server, GSList *text)
+{
+       char buf[MAX_TEXT_SIZE];
+       char t = server->v250.s3;
+       char r = server->v250.s4;
+       unsigned int len;
+       GSList *l = text;
+       char *line;
+
+       if (!text)
+               return;
+
+       while (l) {
+               line = l->data;
+               if (!line)
+                       return;
+
+               len = snprintf(buf, sizeof(buf), "%c%c%s", t, r, line);
+               send_common(server, buf, MIN(len, sizeof(buf)-1));
+
+               l = l->next;
+       }
+
+       len = snprintf(buf, sizeof(buf), "%c%c", t, r);
+       send_common(server, buf, len);
+}
+
 static inline gboolean is_extended_command_prefix(const char c)
 {
        switch (c) {
@@ -205,7 +277,7 @@ static void at_command_notify(GAtServer *server, char 
*command,
        node = g_hash_table_lookup(server->command_list, prefix);
 
        if (node == NULL) {
-               g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+               g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR);
                return;
        }
 
@@ -301,7 +373,7 @@ next:
        return;
 
 error:
-       g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+       g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR);
 }
 
 static int get_basic_prefix_size(const char *buf)
@@ -427,7 +499,7 @@ done:
        return;
 
 error:
-       g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+       g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR);
 }
 
 static void server_parse_line(GAtServer *server)
@@ -437,7 +509,7 @@ static void server_parse_line(GAtServer *server)
        unsigned int len = strlen(line);
 
        if (len == 0) {
-               g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+               g_at_server_send_result(server, G_AT_SERVER_RESULT_OK);
                return;
        }
 
@@ -620,7 +692,7 @@ static void new_bytes(GAtServer *p)
                         * According to section 5.2.4 and 5.6 of V250,
                         * Empty commands must be OK by the DCE
                         */
-                       g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
+                       g_at_server_send_result(p, G_AT_SERVER_RESULT_OK);
                        ring_buffer_drain(p->read_buf, p->read_so_far);
                        break;
 
@@ -634,14 +706,14 @@ static void new_bytes(GAtServer *p)
 
                                server_parse_line(p);
                        } else
-                               g_at_server_send_final(p,
+                               g_at_server_send_result(p,
                                                G_AT_SERVER_RESULT_ERROR);
                        break;
                }
 
                case PARSER_RESULT_REPEAT_LAST:
                        /* TODO */
-                       g_at_server_send_final(p, G_AT_SERVER_RESULT_OK);
+                       g_at_server_send_result(p, G_AT_SERVER_RESULT_OK);
                        ring_buffer_drain(p->read_buf, p->read_so_far);
                        break;
 
diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h
index 2ae19ca..a508be6 100644
--- a/gatchat/gatserver.h
+++ b/gatchat/gatserver.h
@@ -87,6 +87,23 @@ gboolean g_at_server_register(GAtServer *server, char 
*prefix,
                                        GDestroyNotify destroy_notify);
 gboolean g_at_server_unregister(GAtServer *server, const char *prefix);
 
+/* Send a final result code. E.g. G_AT_SERVER_RESULT_NO_DIALTONE */
+void g_at_server_send_final(GAtServer *server, GAtServerResult result);
+
+/* Send an extended final result code. E.g. +CME ERROR: SIM failure. */
+void g_at_server_send_ext_final(GAtServer *server, const char *result);
+
+/* Send an intermediate result code to report the progress. E.g. CONNECT */
+void g_at_server_send_intermediate(GAtServer *server, const char *result);
+
+/* Send an unsolicited result code. E.g. RING */
+void g_at_server_send_unsolicited(GAtServer *server, const char *result);
+
+/* Send an information text. The text could contain multiple lines. Each
+ * line, including line terminators, should not exceed 2048 characters.
+ */
+void g_at_server_send_info_text(GAtServer *server, GSList *text);
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.6.6.1

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to