diff options
author | Tambet Ingo <tambet@gmail.com> | 2009-02-18 14:48:08 +0200 |
---|---|---|
committer | Tambet Ingo <tambet@gmail.com> | 2009-02-18 14:48:08 +0200 |
commit | 1215bd6a9d607018e0af7ad7afa85bc35cb713a0 (patch) | |
tree | cc33208fdbd4de15703fe8fefbd578f2d68908be /src/mm-serial.c | |
parent | 13facad4fa3be24d07768892135caebd88e95fcc (diff) |
Rework unsolicited message handling.
Implement registration using unsolicited messages for generic GSM class (which
is disabled by default, HSO and Huawei plugins enable it).
Modify all GSM modem subclasses that used unsolicited messages to use the new
method.
Diffstat (limited to 'src/mm-serial.c')
-rw-r--r-- | src/mm-serial.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/mm-serial.c b/src/mm-serial.c index c81ca70d..3bd2b0d6 100644 --- a/src/mm-serial.c +++ b/src/mm-serial.c @@ -49,6 +49,7 @@ typedef struct { MMSerialResponseParserFn response_parser_fn; gpointer response_parser_user_data; GDestroyNotify response_parser_notify; + GSList *unsolicited_msg_handlers; struct termios old_t; @@ -65,6 +66,13 @@ typedef struct { guint timeout_id; } MMSerialPrivate; +typedef struct { + GRegex *regex; + MMSerialUnsolicitedMsgFn callback; + gpointer user_data; + GDestroyNotify notify; +} MMUnsolicitedMsgHandler; + const char * mm_serial_get_device (MMSerial *serial) { @@ -436,6 +444,29 @@ mm_serial_queue_process (gpointer data) } void +mm_serial_add_unsolicited_msg_handler (MMSerial *self, + GRegex *regex, + MMSerialUnsolicitedMsgFn callback, + gpointer user_data, + GDestroyNotify notify) +{ + MMUnsolicitedMsgHandler *handler; + MMSerialPrivate *priv; + + g_return_if_fail (MM_IS_SERIAL (self)); + g_return_if_fail (regex != NULL); + + handler = g_slice_new (MMUnsolicitedMsgHandler); + handler->regex = g_regex_ref (regex); + handler->callback = callback; + handler->user_data = user_data; + handler->notify = notify; + + priv = MM_SERIAL_GET_PRIVATE (self); + priv->unsolicited_msg_handlers = g_slist_append (priv->unsolicited_msg_handlers, handler); +} + +void mm_serial_set_response_parser (MMSerial *self, MMSerialResponseParserFn fn, gpointer user_data, @@ -454,6 +485,58 @@ mm_serial_set_response_parser (MMSerial *self, } static gboolean +remove_eval_cb (const GMatchInfo *match_info, + GString *result, + gpointer user_data) +{ + int *result_len = (int *) user_data; + int start; + int end; + + if (g_match_info_fetch_pos (match_info, 0, &start, &end)) + *result_len -= (end - start); + + return FALSE; +} + +static void +parse_unsolicited_messages (MMSerial *self, + GString *response) +{ + MMSerialPrivate *priv = MM_SERIAL_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->unsolicited_msg_handlers; iter; iter = iter->next) { + MMUnsolicitedMsgHandler *handler = (MMUnsolicitedMsgHandler *) iter->data; + GMatchInfo *match_info; + gboolean matches; + + matches = g_regex_match_full (handler->regex, response->str, response->len, 0, 0, &match_info, NULL); + if (handler->callback) { + while (g_match_info_matches (match_info)) { + handler->callback (self, match_info, handler->user_data); + g_match_info_next (match_info, NULL); + } + } + + g_match_info_free (match_info); + + if (matches) { + /* Remove matches */ + char *str; + int result_len = response->len; + + str = g_regex_replace_eval (handler->regex, response->str, response->len, 0, 0, + remove_eval_cb, &result_len, NULL); + + g_string_truncate (response, 0); + g_string_append_len (response, str, result_len); + g_free (str); + } + } +} + +static gboolean parse_response (MMSerial *self, GString *response, GError **error) @@ -462,6 +545,8 @@ parse_response (MMSerial *self, g_return_val_if_fail (priv->response_parser_fn != NULL, FALSE); + parse_unsolicited_messages (self, response); + return priv->response_parser_fn (priv->response_parser_user_data, response, error); } @@ -841,6 +926,18 @@ finalize (GObject *object) g_string_free (priv->response, TRUE); g_free (priv->device); + while (priv->unsolicited_msg_handlers) { + MMUnsolicitedMsgHandler *handler = (MMUnsolicitedMsgHandler *) priv->unsolicited_msg_handlers->data; + + if (handler->notify) + handler->notify (handler->user_data); + + g_regex_unref (handler->regex); + g_slice_free (MMUnsolicitedMsgHandler, handler); + priv->unsolicited_msg_handlers = g_slist_delete_link (priv->unsolicited_msg_handlers, + priv->unsolicited_msg_handlers); + } + if (priv->response_parser_notify) priv->response_parser_notify (priv->response_parser_user_data); |