From: Forest Bond <[email protected]>

---
 plugins/sierra.c |  104 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 86 insertions(+), 18 deletions(-)

diff --git a/plugins/sierra.c b/plugins/sierra.c
index a458e38..1beb59a 100644
--- a/plugins/sierra.c
+++ b/plugins/sierra.c
@@ -25,6 +25,7 @@
 
 #include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <glib.h>
 #include <gatchat.h>
@@ -39,15 +40,20 @@
 #include <ofono/gprs.h>
 #include <ofono/gprs-context.h>
 #include <ofono/phonebook.h>
+#include <ofono/cdma-netreg.h>
+#include <ofono/cdma-connman.h>
 #include <ofono/log.h>
 
 #include <drivers/atmodem/atutil.h>
 #include <drivers/atmodem/vendor.h>
 
 static const char *none_prefix[] = { NULL };
+static const char *gcap_prefix[] = { "+GCAP:", NULL };
 
 struct sierra_data {
        GAtChat *modem;
+       ofono_bool_t have_gsm;
+       ofono_bool_t have_cdma;
 };
 
 static void sierra_debug(const char *str, void *user_data)
@@ -119,7 +125,7 @@ static GAtChat *open_device(struct ofono_modem *modem,
        return chat;
 }
 
-static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
+static void enable_result(ofono_bool_t ok, GAtResult *result, gpointer 
user_data)
 {
        struct ofono_modem *modem = user_data;
        struct sierra_data *data = ofono_modem_get_data(modem);
@@ -134,6 +140,40 @@ static void cfun_enable(gboolean ok, GAtResult *result, 
gpointer user_data)
        ofono_modem_set_powered(modem, ok);
 }
 
+static void gcap_support(ofono_bool_t ok, GAtResult *result, gpointer 
user_data)
+{
+       struct ofono_modem *modem = user_data;
+       struct sierra_data *data = ofono_modem_get_data(modem);
+       GAtResultIter iter;
+       const char *gcap;
+
+       if (!ok)
+               goto done;
+
+       g_at_result_iter_init(&iter, result);
+
+       if (!g_at_result_iter_next(&iter, "+GCAP:"))
+               goto done;
+
+       while (g_at_result_iter_next_unquoted_string(&iter, &gcap)) {
+               if (*gcap == '\0')
+                       break;
+
+               if (!strcmp(gcap, "+CGSM"))
+                       data->have_gsm = TRUE;
+               else if (!strcmp(gcap, "+CIS707-A"))
+                       data->have_cdma = TRUE;
+       }
+
+done:
+       if (data->have_gsm == FALSE && data->have_cdma == TRUE)
+               g_at_chat_send(data->modem, "AT!PCSTATE=1", none_prefix,
+                                               enable_result, modem, NULL);
+       else
+               g_at_chat_send(data->modem, "AT+CFUN=4", none_prefix,
+                                               enable_result, modem, NULL);
+}
+
 static int sierra_enable(struct ofono_modem *modem)
 {
        struct sierra_data *data = ofono_modem_get_data(modem);
@@ -148,13 +188,14 @@ static int sierra_enable(struct ofono_modem *modem)
        /* This is separate because it is not supported by all modems. */
        g_at_chat_send(data->modem, "AT+CMEE=1", NULL, NULL, NULL, NULL);
 
-       g_at_chat_send(data->modem, "AT+CFUN=4", none_prefix,
-                                       cfun_enable, modem, NULL);
+       /* Check for GSM capabilities */
+       g_at_chat_send(data->modem, "ATI", gcap_prefix,
+                                       gcap_support, modem, NULL);
 
        return -EINPROGRESS;
 }
 
-static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data)
+static void disable_result(ofono_bool_t ok, GAtResult *result, gpointer 
user_data)
 {
        struct ofono_modem *modem = user_data;
        struct sierra_data *data = ofono_modem_get_data(modem);
@@ -171,19 +212,25 @@ static void cfun_disable(gboolean ok, GAtResult *result, 
gpointer user_data)
 static int sierra_disable(struct ofono_modem *modem)
 {
        struct sierra_data *data = ofono_modem_get_data(modem);
+       const char *command;
 
        DBG("%p", modem);
 
        g_at_chat_cancel_all(data->modem);
        g_at_chat_unregister_all(data->modem);
 
-       g_at_chat_send(data->modem, "AT+CFUN=0", none_prefix,
-                                       cfun_disable, modem, NULL);
+       if (data->have_gsm == FALSE && data->have_cdma == TRUE)
+               command = "AT!PCSTATE=0";
+       else
+               command = "AT+CFUN=0";
+
+       g_at_chat_send(data->modem, command, none_prefix,
+                               disable_result, modem, NULL);
 
        return -EINPROGRESS;
 }
 
-static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data)
+static void set_online_cb(ofono_bool_t ok, GAtResult *result, gpointer 
user_data)
 {
        struct cb_data *cbd = user_data;
        ofono_modem_online_cb_t cb = cbd->cb;
@@ -198,10 +245,15 @@ static void sierra_set_online(struct ofono_modem *modem, 
ofono_bool_t online,
 {
        struct sierra_data *data = ofono_modem_get_data(modem);
        struct cb_data *cbd = cb_data_new(cb, user_data);
-       char const *command = online ? "AT+CFUN=1" : "AT+CFUN=4";
+       char const *command;
 
        DBG("modem %p %s", modem, online ? "online" : "offline");
 
+       if (data->have_gsm == FALSE && data->have_cdma == TRUE)
+               command = online ? "AT!PCSTATE=1" : "AT!PCSTATE=0";
+       else
+               command = online ? "AT+CFUN=1" : "AT+CFUN=4";
+
        if (g_at_chat_send(data->modem, command, none_prefix,
                                        set_online_cb, cbd, g_free) > 0)
                return;
@@ -214,13 +266,17 @@ static void sierra_set_online(struct ofono_modem *modem, 
ofono_bool_t online,
 static void sierra_pre_sim(struct ofono_modem *modem)
 {
        struct sierra_data *data = ofono_modem_get_data(modem);
-       struct ofono_sim *sim;
+       struct ofono_sim *sim = NULL;
 
        DBG("%p", modem);
 
-       ofono_devinfo_create(modem, 0, "atmodem", data->modem);
-       sim = ofono_sim_create(modem, OFONO_VENDOR_SIERRA,
-                                       "atmodem", data->modem);
+       if (data->have_gsm == TRUE) {
+               ofono_devinfo_create(modem, 0, "atmodem", data->modem);
+               sim = ofono_sim_create(modem, OFONO_VENDOR_SIERRA,
+                                               "atmodem", data->modem);
+       } else if (data->have_cdma == TRUE) {
+               ofono_devinfo_create(modem, 0, "cdmamodem", data->modem);
+       }
 
        if (sim)
                ofono_sim_inserted_notify(sim, TRUE);
@@ -234,13 +290,15 @@ static void sierra_post_sim(struct ofono_modem *modem)
 
        DBG("%p", modem);
 
-       ofono_phonebook_create(modem, 0, "atmodem", data->modem);
+       if (data->have_gsm == TRUE) {
+               ofono_phonebook_create(modem, 0, "atmodem", data->modem);
 
-       gprs = ofono_gprs_create(modem, 0, "atmodem", data->modem);
-       gc = ofono_gprs_context_create(modem, 0, "swmodem", data->modem);
+               gprs = ofono_gprs_create(modem, 0, "atmodem", data->modem);
+               gc = ofono_gprs_context_create(modem, 0, "swmodem", 
data->modem);
 
-       if (gprs && gc)
-               ofono_gprs_add_context(gprs, gc);
+               if (gprs && gc)
+                       ofono_gprs_add_context(gprs, gc);
+       }
 }
 
 static void sierra_post_online(struct ofono_modem *modem)
@@ -249,7 +307,17 @@ static void sierra_post_online(struct ofono_modem *modem)
 
        DBG("%p", modem);
 
-       ofono_netreg_create(modem, 0, "atmodem", data->modem);
+       if (data->have_gsm == TRUE) {
+               ofono_netreg_create(modem, 0, "atmodem", data->modem);
+       } else if (data->have_cdma == TRUE) {
+               /*
+                * Once we have CnS protocol support, we should be able to do
+                * netreg that way instead of using the same port for both.
+                */
+               ofono_cdma_netreg_create(modem, 0, "sierramodem", data->modem);
+               ofono_cdma_connman_create(modem, OFONO_VENDOR_SIERRA,
+                                               "cdmamodem", data->modem);
+       }
 }
 
 static struct ofono_modem_driver sierra_driver = {
-- 
1.7.0.4
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to