diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2010-08-16 15:16:01 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-08-16 15:16:01 +0200 |
commit | 885880512d7c4e0d22ccc78802f58ecc7052ad1a (patch) | |
tree | da3cc3b71277df23db640b1099ba0120d816c475 /plugins | |
parent | 83a04505bf86248e526261d1041cfc6457626ccf (diff) | |
download | ofono-885880512d7c4e0d22ccc78802f58ecc7052ad1a.tar.bz2 |
zte: Add initial support for devinfo, sim and netreg atoms
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/zte.c | 158 |
1 files changed, 156 insertions, 2 deletions
diff --git a/plugins/zte.c b/plugins/zte.c index d1fa146f..d0cbf3ea 100644 --- a/plugins/zte.c +++ b/plugins/zte.c @@ -23,45 +23,199 @@ #include <config.h> #endif +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> + +#include <glib.h> +#include <gatchat.h> +#include <gattty.h> + #define OFONO_API_SUBJECT_TO_CHANGE #include <ofono/plugin.h> #include <ofono/modem.h> +#include <ofono/devinfo.h> +#include <ofono/netreg.h> +#include <ofono/sim.h> #include <ofono/log.h> +#include <drivers/atmodem/vendor.h> + +static const char *none_prefix[] = { NULL }; + +struct zte_data { + GAtChat *modem; + GAtChat *aux; +}; + static int zte_probe(struct ofono_modem *modem) { + struct zte_data *data; + DBG("%p", modem); + data = g_try_new0(struct zte_data, 1); + if (!data) + return -ENOMEM; + + ofono_modem_set_data(modem, data); + return 0; } static void zte_remove(struct ofono_modem *modem) { + struct zte_data *data = ofono_modem_get_data(modem); + DBG("%p", modem); + + ofono_modem_set_data(modem, NULL); + + g_at_chat_unref(data->modem); + g_at_chat_unref(data->aux); + + g_free(data); +} + +static void zte_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + ofono_info("%s%s", prefix, str); +} + +static GAtChat *open_device(struct ofono_modem *modem, + const char *key, char *debug) +{ + const char *device; + GAtSyntax *syntax; + GIOChannel *channel; + GAtChat *chat; + + device = ofono_modem_get_string(modem, key); + if (device == NULL) + return NULL; + + DBG("%s %s", key, device); + + channel = g_at_tty_open(device, NULL); + if (!channel) + return NULL; + + syntax = g_at_syntax_new_gsm_permissive(); + chat = g_at_chat_new(channel, syntax); + g_at_syntax_unref(syntax); + g_io_channel_unref(channel); + + if (!chat) + return NULL; + + if (getenv("OFONO_AT_DEBUG")) + g_at_chat_set_debug(chat, zte_debug, debug); + + return chat; +} + +static void zte_disconnect(gpointer user_data) +{ + DBG(""); +} + +static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_modem *modem = user_data; + + DBG(""); + + ofono_modem_set_powered(modem, ok); } static int zte_enable(struct ofono_modem *modem) { + struct zte_data *data = ofono_modem_get_data(modem); + DBG("%p", modem); - return 0; + data->modem = open_device(modem, "Modem", "Modem:"); + if (data->modem == NULL) + return -EINVAL; + + g_at_chat_set_disconnect_function(data->modem, + zte_disconnect, modem); + + data->aux = open_device(modem, "Aux", "Aux:"); + if (data->aux == NULL) { + g_at_chat_unref(data->modem); + data->modem = NULL; + return -EIO; + } + + g_at_chat_send(data->aux, "ATE0 +CMEE=1", none_prefix, NULL, NULL, NULL); + + g_at_chat_send(data->aux, "AT+CFUN=1", none_prefix, + cfun_enable, modem, NULL); + + return -EINPROGRESS; +} + +static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct zte_data *data = ofono_modem_get_data(modem); + + DBG(""); + + g_at_chat_unref(data->aux); + data->aux = NULL; + + if (ok) + ofono_modem_set_powered(modem, FALSE); } static int zte_disable(struct ofono_modem *modem) { + struct zte_data *data = ofono_modem_get_data(modem); + DBG("%p", modem); - return 0; + if (data->modem) { + g_at_chat_cancel_all(data->modem); + g_at_chat_unregister_all(data->modem); + g_at_chat_unref(data->modem); + data->modem = NULL; + } + + if (!data->aux) + return 0; + + g_at_chat_cancel_all(data->aux); + g_at_chat_unregister_all(data->aux); + g_at_chat_send(data->aux, "AT+CFUN=0", none_prefix, + cfun_disable, modem, NULL); + + return -EINPROGRESS; } static void zte_pre_sim(struct ofono_modem *modem) { + struct zte_data *data = ofono_modem_get_data(modem); + struct ofono_sim *sim; + DBG("%p", modem); + + ofono_devinfo_create(modem, 0, "atmodem", data->aux); + sim = ofono_sim_create(modem, 0, "atmodem", data->aux); + + if (sim) + ofono_sim_inserted_notify(sim, TRUE); } static void zte_post_sim(struct ofono_modem *modem) { + struct zte_data *data = ofono_modem_get_data(modem); + DBG("%p", modem); + + ofono_netreg_create(modem, OFONO_VENDOR_ZTE, "atmodem", data->aux); } static struct ofono_modem_driver zte_driver = { |