Register mandatory AT command handlers for DUN server.
---
 include/emulator.h |    2 +
 src/emulator.c     |  381 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 383 insertions(+), 0 deletions(-)

diff --git a/include/emulator.h b/include/emulator.h
index 641f38c..1ff813f 100644
--- a/include/emulator.h
+++ b/include/emulator.h
@@ -37,6 +37,8 @@ enum ofono_emulator_status {
        OFONO_EMULATOR_STATUS_DUN_CONNECT,
        OFONO_EMULATOR_STATUS_DUN_CONNECTED,
        OFONO_EMULATOR_STATUS_DUN_DISCONNECTED,
+       OFONO_EMULATOR_STATUS_SET_CGATT,
+       OFONO_EMULATOR_STATUS_SET_CGDCONT,
 };
 
 enum _GAtServerResult;
diff --git a/src/emulator.c b/src/emulator.c
index 378426c..8811f6c 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -49,6 +49,14 @@ struct dun_context {
        struct ofono_gprs_primary_context pri_ctx;
 };
 
+struct modem_settings {
+       int mode;
+       int creg;
+       int cgreg;
+       int cops;
+       int attached;
+};
+
 struct ofono_emulator {
        struct ofono_modem *modem;
        struct ofono_atom *atom;
@@ -57,6 +65,7 @@ struct ofono_emulator {
        GAtServer *server;
        GAtPPP *ppp;
        struct dun_context context;
+       struct modem_settings settings;
        enum ofono_emulator_status status;
        struct ofono_watchlist *status_watches;
 };
@@ -146,6 +155,371 @@ static struct ofono_emulator_req 
*ofono_emulator_req_new(void *cb,
        return req;
 }
 
+static void generic_cb(GAtServerResult res, void *user_data)
+{
+       struct ofono_emulator *e = user_data;
+       GAtServer *server = e->server;
+
+       g_at_server_send_final(server, res);
+
+       e->status = OFONO_EMULATOR_STATUS_IDLE;
+
+       notify_status_watches(e, NULL);
+}
+
+static gboolean send_ok(gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+
+       return FALSE;
+}
+
+static void cfun_cb(GAtServerRequestType type, GAtResult *cmd,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+       char buf[50];
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_info(e, "+CFUN: (0-1)", TRUE);
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+               snprintf(buf, sizeof(buf), "+CFUN: %d", e->settings.mode);
+               ofono_emulator_send_info(e, buf, TRUE);
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+       {
+               GAtResultIter iter;
+               int mode;
+
+               g_at_result_iter_init(&iter, cmd);
+               g_at_result_iter_next(&iter, "+CFUN=");
+
+               if (g_at_result_iter_next_number(&iter, &mode) == FALSE)
+                       goto error;
+
+               if (mode != 0 && mode != 1)
+                       goto error;
+
+               DBG("set CFUN to %d", mode);
+
+               e->settings.mode = mode;
+               g_timeout_add_seconds(1, send_ok, e);
+               break;
+       }
+       default:
+               goto error;
+       };
+
+       return;
+
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void cpin_cb(GAtServerRequestType type, GAtResult *result,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+               /* not implement yet*/
+       default:
+               goto error;
+       };
+
+       return;
+
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void creg_cb(GAtServerRequestType type, GAtResult *result,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+       {
+               GAtResultIter iter;
+               int mode;
+
+               g_at_result_iter_init(&iter, result);
+               g_at_result_iter_next(&iter, "+CREG=");
+
+               if (g_at_result_iter_next_number(&iter, &mode) == FALSE)
+                       goto error;
+
+               if (mode < 0 || mode > 2)
+                       goto error;
+
+               DBG("set netreg status %d", mode);
+
+               e->settings.creg = mode;
+
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+
+               break;
+       }
+       default:
+               goto error;
+       };
+
+       return;
+
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void cgreg_cb(GAtServerRequestType type, GAtResult *result,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+       {
+               GAtResultIter iter;
+               int mode;
+
+               g_at_result_iter_init(&iter, result);
+               g_at_result_iter_next(&iter, "+CGREG=");
+
+               if (g_at_result_iter_next_number(&iter, &mode) == FALSE)
+                       goto error;
+
+               if (mode < 0 || mode > 2)
+                       goto error;
+
+               DBG("set GPRS cgreg status %d", mode);
+
+               e->settings.cgreg = mode;
+
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+
+               break;
+       }
+       default:
+               goto error;
+       };
+
+       return;
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void cops_cb(GAtServerRequestType type, GAtResult *result,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+       char buf[50];
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+               snprintf(buf, sizeof(buf), "+COPS: %d", e->settings.cops);
+               ofono_emulator_send_info(e, buf, TRUE);
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+       {
+               GAtResultIter iter;
+               int mode;
+
+               g_at_result_iter_init(&iter, result);
+               g_at_result_iter_next(&iter, "+COPS=");
+
+               if (g_at_result_iter_next_number(&iter, &mode) == FALSE)
+                       goto error;
+
+               if (mode < 0 || mode > 2)
+                       goto error;
+
+               DBG("set GPRS cops status %d", mode);
+
+               e->settings.cops = mode;
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+
+               break;
+       }
+       default:
+               goto error;
+       };
+
+       return;
+
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void cgatt_cb(GAtServerRequestType type, GAtResult *result,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+       struct ofono_emulator_req *req;
+       char buf[12];
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+               snprintf(buf, sizeof(buf), "+CGATT: %d", e->settings.attached);
+               ofono_emulator_send_info(e, buf, TRUE);
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+       {
+               GAtResultIter iter;
+               int attached;
+
+               g_at_result_iter_init(&iter, result);
+               g_at_result_iter_next(&iter, "+CGATT=");
+
+               if (g_at_result_iter_next_number(&iter, &attached) == FALSE)
+                       goto error;
+
+               if (attached != 0 && attached != 1)
+                       goto error;
+
+               DBG("set GPRS attach status %d", attached);
+
+               req = ofono_emulator_req_new(generic_cb, e);
+               if (!req)
+                       goto error;
+
+               req->data = &attached;
+
+               e->status = OFONO_EMULATOR_STATUS_SET_CGATT;
+
+               notify_status_watches(e, req);
+
+               e->settings.attached = attached;
+               g_free(req);
+               break;
+       }
+       default:
+               goto error;
+       };
+
+       return;
+
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void cgdcont_cb(GAtServerRequestType type, GAtResult *result,
+                                       gpointer user_data)
+{
+       struct ofono_emulator *e = user_data;
+       struct ofono_emulator_gprs_context_req *req;
+       struct dun_context *context = &e->context;
+       struct ofono_gprs_primary_context *ctx = &context->pri_ctx;
+       char buf[256];
+
+       switch (type) {
+       case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       case G_AT_SERVER_REQUEST_TYPE_QUERY:
+       {
+               const char *proto = gprs_proto_to_string(ctx->proto);
+
+               snprintf(buf, sizeof(buf), "+CGDCONT: %d, \"%s\", \"%s\"",
+                                               ctx->cid, proto, ctx->apn);
+               ofono_emulator_send_info(e, buf, TRUE);
+               ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
+               break;
+       }
+       case G_AT_SERVER_REQUEST_TYPE_SET:
+       {
+               GAtResultIter iter;
+               unsigned int cid;
+               const char *proto;
+               const char *apn;
+
+               g_at_result_iter_init(&iter, result);
+               g_at_result_iter_next(&iter, "+CGDCONT=");
+
+               if (g_at_result_iter_next_number(&iter, (gint *)&cid) == FALSE)
+                       goto error;
+
+               if (g_at_result_iter_next_string(&iter, &proto) == FALSE)
+                       goto error;
+
+               if (g_at_result_iter_next_string(&iter, &apn) == FALSE)
+                       goto error;
+
+               DBG("set CGDCONT %d %s %s", cid, proto, apn);
+
+               if (cid <= 0 || proto == NULL || apn == NULL)
+                       goto error;
+
+               if (cid == ctx->cid)
+                       goto error;
+
+               if (context->active)
+                       goto error;
+
+               ctx->cid = cid;
+               gprs_proto_from_string(proto, &ctx->proto);
+               strncpy(ctx->apn, apn, OFONO_GPRS_MAX_APN_LENGTH);
+               ctx->apn[OFONO_GPRS_MAX_APN_LENGTH] = '\0';
+
+               req = g_try_new0(struct ofono_emulator_gprs_context_req, 1);
+               if (!req)
+                       goto error;
+
+               req->proto = proto;
+               req->apn = apn;
+               req->cb = generic_cb;
+               req->cb_data = e;
+
+               e->status = OFONO_EMULATOR_STATUS_SET_CGDCONT;
+
+               notify_status_watches(e, req);
+
+               g_free(req);
+               break;
+       }
+       default:
+               goto error;
+       };
+
+       return;
+
+error:
+       ofono_emulator_send_final(e, G_AT_SERVER_RESULT_ERROR);
+       g_free(req);
+}
+
 static void ppp_connect(const char *interface, const char *local,
                        const char *remote,
                        const char *dns1, const char *dns2,
@@ -426,6 +800,13 @@ struct ofono_emulator *ofono_emulator_create(struct 
ofono_modem *modem,
        __ofono_atom_register(e->atom, emulator_unregister);
 
        g_at_server_register(e->server, "D", dial_cb, e, NULL);
+       g_at_server_register(e->server, "+CFUN", cfun_cb, e, NULL);
+       g_at_server_register(e->server, "+CPIN", cpin_cb, e, NULL);
+       g_at_server_register(e->server, "+CREG", creg_cb, e, NULL);
+       g_at_server_register(e->server, "+CGREG", cgreg_cb, e, NULL);
+       g_at_server_register(e->server, "+COPS", cops_cb, e, NULL);
+       g_at_server_register(e->server, "+CGATT", cgatt_cb, e, NULL);
+       g_at_server_register(e->server, "+CGDCONT", cgdcont_cb, e, NULL);
 
        return e;
 }
-- 
1.7.0.4

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to