aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-07-19 10:39:58 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-06 20:07:25 +0200
commit4dc9d674d14a9a1eaffada2c02ab51b59613a202 (patch)
tree6af012525e9b6ef9d6437e4b765f99ef35ca3e58 /plugins
parent35df0bfc743857d70c67f104bf21c608e2c56790 (diff)
icera: listen for %IPDPACT unsolicited messages and report connection status
Diffstat (limited to 'plugins')
-rw-r--r--plugins/icera/mm-iface-icera.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/plugins/icera/mm-iface-icera.c b/plugins/icera/mm-iface-icera.c
index 9f2d4a72..1b14ba3b 100644
--- a/plugins/icera/mm-iface-icera.c
+++ b/plugins/icera/mm-iface-icera.c
@@ -28,6 +28,7 @@
#include "mm-iface-icera.h"
#include "mm-broadband-bearer-icera.h"
#include "mm-base-modem-at.h"
+#include "mm-bearer-list.h"
/*****************************************************************************/
/* Icera context */
@@ -38,6 +39,7 @@ static GQuark icera_context_quark;
typedef struct {
GRegex *nwstate_regex;
GRegex *pacsp_regex;
+ GRegex *ipdpact_regex;
/* Cache of the most recent value seen by the unsolicited message handler */
MMModemAccessTechnology last_act;
@@ -48,6 +50,7 @@ icera_context_free (IceraContext *ctx)
{
g_regex_unref (ctx->nwstate_regex);
g_regex_unref (ctx->pacsp_regex);
+ g_regex_unref (ctx->ipdpact_regex);
g_slice_free (IceraContext, ctx);
}
@@ -69,6 +72,9 @@ get_icera_context (MMBroadbandModem *self)
ctx->pacsp_regex = (g_regex_new (
"\\r\\n\\+PACSP(\\d)\\r\\n",
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL));
+ ctx->ipdpact_regex = (g_regex_new (
+ "\\r\\n%IPDPACT:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)\\r\\n",
+ G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL));
ctx->last_act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
g_object_set_qdata_full (G_OBJECT (self),
icera_context_quark,
@@ -258,6 +264,80 @@ mm_iface_icera_modem_set_allowed_modes (MMIfaceModem *self,
/*****************************************************************************/
/* Icera-specific unsolicited events handling */
+typedef struct {
+ guint cid;
+ MMBroadbandBearerIceraConnectionStatus status;
+} BearerListReportStatusForeachContext;
+
+static void
+bearer_list_report_status_foreach (MMBearer *bearer,
+ BearerListReportStatusForeachContext *ctx)
+{
+ if (mm_broadband_bearer_get_3gpp_cid (MM_BROADBAND_BEARER (bearer)) != ctx->cid)
+ return;
+
+ if (!MM_IS_BROADBAND_BEARER_ICERA (bearer))
+ return;
+
+ mm_broadband_bearer_icera_report_connection_status (MM_BROADBAND_BEARER_ICERA (bearer),
+ ctx->status);
+}
+
+static void
+ipdpact_received (MMAtSerialPort *port,
+ GMatchInfo *match_info,
+ MMBroadbandModem *self)
+{
+ MMBearerList *list = NULL;
+ BearerListReportStatusForeachContext ctx;
+ guint cid;
+ guint status;
+
+ /* Ensure we got proper parsed values */
+ if (!mm_get_uint_from_match_info (match_info, 1, &cid) ||
+ !mm_get_uint_from_match_info (match_info, 2, &status))
+ return;
+
+ /* Setup context */
+ ctx.cid = 0;
+ ctx.status = MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN;
+
+ switch (status) {
+ case 0:
+ ctx.status = MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_DISCONNECTED;
+ break;
+ case 1:
+ ctx.status = MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTED;
+ break;
+ case 2:
+ /* activating */
+ break;
+ case 3:
+ ctx.status = MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_CONNECTION_FAILED;
+ break;
+ default:
+ mm_warn ("Unknown Icera connect status %d", status);
+ break;
+ }
+
+ /* If unknown status, don't try to report anything */
+ if (ctx.status == MM_BROADBAND_BEARER_ICERA_CONNECTION_STATUS_UNKNOWN)
+ return;
+
+ /* If empty bearer list, nothing else to do */
+ g_object_get (self,
+ MM_IFACE_MODEM_BEARER_LIST, &list,
+ NULL);
+ if (!list)
+ return;
+
+ /* Will report status only in the bearer with the specific CID */
+ mm_bearer_list_foreach (list,
+ (MMBearerListForeachFunc)bearer_list_report_status_foreach,
+ &ctx);
+ g_object_unref (list);
+}
+
static MMModemAccessTechnology
nwstate_to_act (const gchar *str)
{
@@ -361,6 +441,14 @@ mm_iface_icera_modem_set_unsolicited_events_handlers (MMBroadbandModem *self,
enable ? self : NULL,
NULL);
+ /* Connection status related */
+ mm_at_serial_port_add_unsolicited_msg_handler (
+ ports[i],
+ ctx->ipdpact_regex,
+ enable ? (MMAtSerialUnsolicitedMsgFn)ipdpact_received : NULL,
+ enable ? self : NULL,
+ NULL);
+
/* Always to ignore */
if (!enable) {
mm_at_serial_port_add_unsolicited_msg_handler (