From b9e86d98be634d98a0b95d3f882a64c7e1f8ff10 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jan 2012 19:52:34 -0800 Subject: huaweimodem: Move CDMA network registration into default driver With merging the GSM/UTMS and CDMA modem plugin into a unified version, it also makes sense to merge the Huawei specific vendor atom drivers into one. --- drivers/huaweimodem/cdma-netreg.c | 227 ++++++++++++++++++++++++++++++++++++++ drivers/huaweimodem/huaweimodem.c | 4 + drivers/huaweimodem/huaweimodem.h | 3 + 3 files changed, 234 insertions(+) create mode 100644 drivers/huaweimodem/cdma-netreg.c (limited to 'drivers/huaweimodem') diff --git a/drivers/huaweimodem/cdma-netreg.c b/drivers/huaweimodem/cdma-netreg.c new file mode 100644 index 00000000..2ae66e17 --- /dev/null +++ b/drivers/huaweimodem/cdma-netreg.c @@ -0,0 +1,227 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include + +#include +#include +#include + +#include "gatchat.h" + +#include "huaweimodem.h" + +static const char *sysinfo_prefix[] = { "^SYSINFO:", NULL }; + +static gboolean parse_sysinfo(GAtResult *result, gint *status) +{ + GAtResultIter iter; + gint srv_status; + gint srv_domain; + gint roaming_status; + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "^SYSINFO:")) + return FALSE; + + if (!g_at_result_iter_next_number(&iter, &srv_status)) + return FALSE; + + if (!g_at_result_iter_next_number(&iter, &srv_domain)) + return FALSE; + + if (!g_at_result_iter_next_number(&iter, &roaming_status)) + return FALSE; + + DBG("%d, %d, %d", srv_status, srv_domain, roaming_status); + + switch (srv_status) { + case 1: /* Restricted service */ + case 2: /* Service valid */ + case 3: /* Restricted region service */ + if (roaming_status) + *status = CDMA_NETWORK_REGISTRATION_STATUS_ROAMING; + else + *status = CDMA_NETWORK_REGISTRATION_STATUS_REGISTERED; + break; + case 0: /* No service */ + case 4: /* Not registered */ + default: + *status = CDMA_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED; + break; + } + + switch (srv_domain) { + case 0: /* No service */ + *status = CDMA_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED; + break; + case 1: /* Only CS */ + case 2: /* Only PS */ + case 3: /* CS PS */ + case 4: /* CS registered, PS in searching state */ + case 255: /* CDMA not supported */ + break; + } + + return TRUE; +} + +static void sysinfo_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_cdma_netreg *netreg = user_data; + int status; + + if (!ok) + return; + + if (parse_sysinfo(result, &status) == FALSE) { + ofono_error("Invalid SYSINFO values"); + return; + } + + ofono_cdma_netreg_status_notify(netreg, status); +} + +static void mode_notify(GAtResult *result, gpointer user_data) +{ + struct ofono_cdma_netreg *netreg = user_data; + GAtChat *chat = ofono_cdma_netreg_get_data(netreg); + + g_at_chat_send(chat, "AT^SYSINFO", sysinfo_prefix, + sysinfo_cb, netreg, NULL); +} + +static void rssilvl_notify(GAtResult *result, gpointer user_data) +{ + struct ofono_cdma_netreg *netreg = user_data; + int strength; + GAtResultIter iter; + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "^RSSILVL:")) + goto error; + + if (!g_at_result_iter_next_number(&iter, &strength)) + goto error; + + if (strength == 99) + strength = 100; + + ofono_cdma_netreg_strength_notify(netreg, strength); + + return; + +error: + ofono_error("Invalid RSSILVL value"); +} + +static void hrssilvl_notify(GAtResult *result, gpointer user_data) +{ + struct ofono_cdma_netreg *netreg = user_data; + int strength; + GAtResultIter iter; + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "^HRSSILVL:")) + goto error; + + if (!g_at_result_iter_next_number(&iter, &strength)) + goto error; + + if (strength == 99) + strength = 100; + + ofono_cdma_netreg_data_strength_notify(netreg, strength); + + return; + +error: + ofono_error("Invalid HRSSILVL value"); +} + +static void probe_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct ofono_cdma_netreg *netreg = user_data; + GAtChat *chat = ofono_cdma_netreg_get_data(netreg); + + if (!ok) { + ofono_cdma_netreg_remove(netreg); + return; + } + + g_at_chat_register(chat, "^MODE:", + mode_notify, FALSE, netreg, NULL); + + g_at_chat_register(chat, "^RSSILVL:", + rssilvl_notify, FALSE, netreg, NULL); + + g_at_chat_register(chat, "^HRSSILVL:", + hrssilvl_notify, FALSE, netreg, NULL); + + ofono_cdma_netreg_register(netreg); +} + +static int huawei_cdma_netreg_probe(struct ofono_cdma_netreg *netreg, + unsigned int vendor, void *data) +{ + GAtChat *chat = g_at_chat_clone(data); + + ofono_cdma_netreg_set_data(netreg, chat); + + g_at_chat_send(chat, "AT^SYSINFO", sysinfo_prefix, + probe_cb, netreg, NULL); + + return 0; +} + +static void huawei_cdma_netreg_remove(struct ofono_cdma_netreg *netreg) +{ + GAtChat *chat = ofono_cdma_netreg_get_data(netreg); + + ofono_cdma_netreg_set_data(netreg, NULL); + + g_at_chat_unref(chat); +} + +static struct ofono_cdma_netreg_driver driver = { + .name = "huaweimodem", + .probe = huawei_cdma_netreg_probe, + .remove = huawei_cdma_netreg_remove, +}; + +void huawei_cdma_netreg_init(void) +{ + ofono_cdma_netreg_driver_register(&driver); +} + +void huawei_cdma_netreg_exit(void) +{ + ofono_cdma_netreg_driver_unregister(&driver); +} diff --git a/drivers/huaweimodem/huaweimodem.c b/drivers/huaweimodem/huaweimodem.c index 53b91ed3..ac084c2d 100644 --- a/drivers/huaweimodem/huaweimodem.c +++ b/drivers/huaweimodem/huaweimodem.c @@ -39,11 +39,15 @@ static int huaweimodem_init(void) huawei_radio_settings_init(); huawei_gprs_context_init(); + huawei_cdma_netreg_init(); + return 0; } static void huaweimodem_exit(void) { + huawei_cdma_netreg_exit(); + huawei_gprs_context_exit(); huawei_radio_settings_exit(); huawei_audio_settings_exit(); diff --git a/drivers/huaweimodem/huaweimodem.h b/drivers/huaweimodem/huaweimodem.h index 898f6fcb..31ab9f96 100644 --- a/drivers/huaweimodem/huaweimodem.h +++ b/drivers/huaweimodem/huaweimodem.h @@ -32,3 +32,6 @@ extern void huawei_radio_settings_exit(void); extern void huawei_gprs_context_init(void); extern void huawei_gprs_context_exit(void); + +extern void huawei_cdma_netreg_init(void); +extern void huawei_cdma_netreg_exit(void); -- cgit v1.2.3