[PATCH 2/7] Add framework of server parser

Zhenhua Zhang zhenhua.zhang at intel.com
Wed Mar 3 06:56:47 PST 2010


1. The parser fetches one basic or extended command per iteration.
The prefix is the command prefix without parameter. For example, in
command "AT+CLIP=1", prefix is "+CLIP".
2. Search registered notification node in command_list. If found,
get command type and invoke callback, and then return result.
3. Termiate the execution if the result in an error. Otherwise,
fetch next command.
---
 gatchat/gatserver.c |   95 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 94 insertions(+), 1 deletions(-)

diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c
index 4175112..c54170e 100644
--- a/gatchat/gatserver.c
+++ b/gatchat/gatserver.c
@@ -173,9 +173,99 @@ static void g_at_server_send_result(GAtServer *server, GAtServerResult result)
 	send_common(server, buf, MIN(len, sizeof(buf)-1));
 }
 
+static inline gboolean is_extended_command_prefix(const char c)
+{
+	switch (c) {
+	case '+':
+	case '*':
+	case '!':
+	case '%':
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
+
+static gboolean is_basic_command_prefix(char *buf)
+{
+	if (g_ascii_isalpha(buf[0]))
+		return TRUE;
+
+	if (buf[0] == '&' && g_ascii_isalpha(buf[1]))
+		return TRUE;
+
+	return FALSE;
+}
+
+static GAtServerResult at_notify_callback(GAtServer *server, char *command,
+					char *prefix)
+{
+	int res = G_AT_SERVER_RESULT_ERROR;
+
+	return res;
+}
+
+static char *parse_extended_command(GAtServer *server, char *buf,
+					char *prefix)
+{
+	return NULL;
+}
+
+static char *parse_basic_command(GAtServer *server, char *buf, char *prefix)
+{
+	return NULL;
+}
+
+static char *server_parse_next_command(GAtServer *server, char *buf,
+					char *prefix)
+{
+	char *command = NULL;
+
+	if (is_extended_command_prefix(*buf))
+		command = parse_extended_command(server, buf, prefix);
+	else if (is_basic_command_prefix(buf))
+		command = parse_basic_command(server, buf, prefix);
+
+	return command;
+}
+
 static GAtServerResult server_parse_line(GAtServer *server, char *line)
 {
 	GAtServerResult res = G_AT_SERVER_RESULT_ERROR;
+	char *command = NULL;
+	char prefix[20];
+
+	while (line) {
+		if (*line == '\0') {
+			res = G_AT_SERVER_RESULT_OK;
+			break;
+		}
+
+		/* skip semicolon */
+		if (*line == ';')
+			line++;
+
+		memset(prefix, 0, sizeof(prefix));
+
+		command = server_parse_next_command(server, line, prefix);
+		if (!command) {
+			res = G_AT_SERVER_RESULT_ERROR;
+			break;
+		}
+
+		res = at_notify_callback(server, command, prefix);
+		/* Termiate the execution if command result in an error */
+		if (res != G_AT_SERVER_RESULT_OK)
+			break;
+
+		line += strlen(command);
+
+		g_free(command);
+		command = NULL;
+	}
+
+	if (command)
+		g_free(command);
 
 	return res;
 }
@@ -331,6 +421,7 @@ static void new_bytes(GAtServer *p)
 	unsigned char *buf = ring_buffer_read_ptr(p->read_buf, p->read_so_far);
 	enum ParserState state;
 	GAtServerResult result;
+	char *line;
 
 	while (p->channel && (p->read_so_far < len)) {
 		gsize rbytes = MIN(len - p->read_so_far, wrap - p->read_so_far);
@@ -361,8 +452,10 @@ static void new_bytes(GAtServer *p)
 			break;
 
 		case PARSER_RESULT_COMMAND:
-			result = server_parse_line(p, extract_line(p));
+			line = extract_line(p);
+			result = server_parse_line(p, line);
 			g_at_server_send_result(p, result);
+			g_free(line);
 			break;
 
 		case PARSER_RESULT_REPEAT_LAST:
-- 
1.6.6.1



More information about the ofono mailing list