Implement hashtable to store server supported command list. AT command could be action command or parameter command. Defined in V.250 5.2.5. --- gatchat/gatserver.c | 29 +++++++++++++++++++++++++++++ gatchat/gatserver.h | 21 +++++++++++++++++++++ 2 files changed, 50 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 4a19b6b..829dc1d 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -75,6 +75,16 @@ static const char *server_result_to_string(GAtServerResult result) } } +/* AT command set that server supported */ +struct at_command { + int id; + char *prefix; + GAtServerCommandType type; + GAtServerNotifyFunc notify; + gpointer user_data; + GDestroyNotify destroy_notify; +}; + /* Basic command setting for V.250 */ struct v250_settings { char s3; /* set by S3= */ @@ -99,6 +109,8 @@ struct _GAtServer { gpointer user_disconnect_data; /* User disconnect data */ GAtDebugFunc debugf; /* Debugging output function */ gpointer debug_data; /* Data to pass to debug func */ + GHashTable *command_list; /* List of supported at command */ + guint next_command_id; /* Next command id */ struct ring_buffer *read_buf; /* Current read buffer */ GQueue *write_queue; /* Write buffer queue */ guint max_read_attempts; /* Max reads per select */ @@ -714,6 +726,14 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond, return FALSE; } +static void at_command_free(gpointer key, gpointer value, gpointer data) +{ + struct at_command *node = value; + + g_free(node->prefix); + g_free(node); +} + static void write_queue_free(GQueue *write_queue) { struct ring_buffer *write_buf; @@ -733,6 +753,11 @@ static void g_at_server_cleanup(GAtServer *server) /* Cleanup pending data to write */ write_queue_free(server->write_queue); + /* Cleanup registered notifications */ + g_hash_table_foreach(server->command_list, at_command_free, NULL); + g_hash_table_destroy(server->command_list); + server->command_list = NULL; + server->channel = NULL; } @@ -792,6 +817,7 @@ GAtServer *g_at_server_new(GIOChannel *io) server->ref_count = 1; v250_settings_create(&server->v250); server->channel = io; + server->command_list = g_hash_table_new(g_str_hash, g_str_equal); server->read_buf = ring_buffer_new(BUF_SIZE); if (!server->read_buf) goto error; @@ -816,6 +842,9 @@ GAtServer *g_at_server_new(GIOChannel *io) return server; error: + if (server->command_list) + g_hash_table_destroy(server->command_list); + if (server->read_buf) ring_buffer_free(server->read_buf); diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h index 698f7e0..5db9321 100644 --- a/gatchat/gatserver.h +++ b/gatchat/gatserver.h @@ -26,6 +26,7 @@ extern "C" { #endif +#include "gatresult.h" #include "gatutil.h" struct _GAtServer; @@ -46,6 +47,26 @@ enum _GAtServerResult { typedef enum _GAtServerResult GAtServerResult; +enum _GAtServerRequestType { + G_AT_SERVER_REQUEST_TYPE_NONE, + G_AT_SERVER_REQUEST_TYPE_ACTION, + G_AT_SERVER_REQUEST_TYPE_QUERY, + G_AT_SERVER_REQUEST_TYPE_SET, + G_AT_SERVER_REQUEST_TYPE_SUPPORT, +}; + +typedef enum _GAtServerRequestType GAtServerRequestType; + +enum _GAtServerCommandType { + G_AT_SERVER_COMMAND_TYPE_ACTION, + G_AT_SERVER_COMMAND_TYPE_PARAMETER, +}; + +typedef enum _GAtServerCommandType GAtServerCommandType; + +typedef int (*GAtServerNotifyFunc)(GAtServerRequestType type, GAtResult *result, + gpointer user_data); + GAtServer *g_at_server_new(GIOChannel *io); GAtServer *g_at_server_ref(GAtServer *server); -- 1.6.6.1