Hi Pablo,

On 04/30/2012 09:45 AM, [email protected] wrote:
> From: Pablo Neira Ayuso <[email protected]>
> 
> This patch adds support for voice calls and SMS for Wavecom
> Q2403/Q2686.
> 
> The existing Wavecom driver in tree slightly differs from these
> modems. Thus, it doesn't work work with them. We (the osmocom
> team) are use these Wavecom Q2403/Q2686 modems in our testbed.
> ---
>  Makefile.am              |    3 +
>  drivers/atmodem/sim.c    |    8 ++
>  drivers/atmodem/sms.c    |   31 ++++++--
>  drivers/atmodem/vendor.h |    1 +
>  gatchat/gatchat.c        |    3 +-
>  plugins/udev.c           |    2 +
>  plugins/wavecom_q.c      |  192 
> ++++++++++++++++++++++++++++++++++++++++++++++

Can you please break this patch up, we prefer one patch for every
directory.  See HACKING document for patch submission guidelines.

>  7 files changed, 234 insertions(+), 6 deletions(-)
>  create mode 100644 plugins/wavecom_q.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index 9cb490d..0bcbb8a 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -371,6 +371,9 @@ builtin_sources += plugins/samsung.c
>  builtin_modules += sim900
>  builtin_sources += plugins/sim900.c
>  
> +builtin_modules += wavecom_q
> +builtin_sources += plugins/wavecom_q.c
> +
>  if BLUETOOTH
>  builtin_modules += bluetooth
>  builtin_sources += plugins/bluetooth.c plugins/bluetooth.h
> diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
> index dd86980..64f38a8 100644
> --- a/drivers/atmodem/sim.c
> +++ b/drivers/atmodem/sim.c
> @@ -146,6 +146,14 @@ static void at_sim_read_info(struct ofono_sim *sim, int 
> fileid,
>                       return;
>               }
>       }
> +     /* AT+CRSM not supported by Q2403. */
> +     if (sd->vendor == OFONO_VENDOR_WAVECOM_Q) {
> +             unsigned char access[3] = { 0x00, 0x00, 0x00 };
> +
> +             CALLBACK_WITH_SUCCESS(cb, 4, 0, 0, access,
> +                                     EF_STATUS_VALID, data);

Why don't you simply return an error here?

> +             return;
> +     }
>  
>       cbd = cb_data_new(cb, data);
>  
> diff --git a/drivers/atmodem/sms.c b/drivers/atmodem/sms.c
> index 27dc2c0..af53880 100644
> --- a/drivers/atmodem/sms.c
> +++ b/drivers/atmodem/sms.c
> @@ -984,8 +984,12 @@ static gboolean set_cpms(gpointer user_data)
>       const char *incoming = storages[data->incoming];
>       char buf[128];
>  
> -     snprintf(buf, sizeof(buf), "AT+CPMS=\"%s\",\"%s\",\"%s\"",
> -                     store, store, incoming);
> +     if (data->vendor != OFONO_VENDOR_WAVECOM_Q) {
> +             snprintf(buf, sizeof(buf), "AT+CPMS=\"%s\",\"%s\",\"%s\"",
> +                             store, store, incoming);
> +     } else {
> +             snprintf(buf, sizeof(buf), "AT+CPMS=\"%s\"", store);
> +     }

There is no need for any curly braces.

>  
>       g_at_chat_send(data->chat, buf, cpms_prefix,
>                       at_cpms_set_cb, sms, NULL);
> @@ -1037,7 +1041,7 @@ static void at_cpms_query_cb(gboolean ok, GAtResult 
> *result,
>       gboolean supported = FALSE;
>  
>       if (ok) {
> -             int mem = 0;
> +             int mem = 0, mem_max;
>               GAtResultIter iter;
>               const char *store;
>               gboolean me_supported[3];
> @@ -1053,7 +1057,23 @@ static void at_cpms_query_cb(gboolean ok, GAtResult 
> *result,
>               if (!g_at_result_iter_next(&iter, "+CPMS:"))
>                       goto out;
>  
> -             for (mem = 0; mem < 3; mem++) {
> +             /* Wavecom Q replies something like this:
> +              *
> +              * +CPMS: (("SM","BM","SR"),("SM"))
> +              *
> +              * It does not provide the way income messages are stored.
> +              * 3GPP TS 07.05 allows mem2 and mem3 to be optional.
> +              */

Just how old is this modem and what version of 07.05 are you using?

For reference, 07.05 version 7.0.1 from July 1999:
"
+CPMS=?
+CPMS: (list of supported <mem1>s),(list of supported <mem2>s),
(list of supported <mem3>s)
"

So the comment should probably be changed to indicate that this modem is
just broken.

> +             if (data->vendor == OFONO_VENDOR_WAVECOM_Q) {
> +                     /* skip initial `(' */
> +                     if (!g_at_result_iter_open_list(&iter))
> +                             goto out;
> +
> +                     mem_max = 2;
> +             } else
> +                     mem_max = 3;
> +
> +             for (mem = 0; mem < mem_max; mem++) {
>                       if (!g_at_result_iter_open_list(&iter))
>                               goto out;
>  
> @@ -1070,7 +1090,8 @@ static void at_cpms_query_cb(gboolean ok, GAtResult 
> *result,
>                               goto out;
>               }
>  
> -             if (!sm_supported[2] && !me_supported[2] && !mt_supported[2])
> +             if (data->vendor != OFONO_VENDOR_WAVECOM_Q &&
> +                 !sm_supported[2] && !me_supported[2] && !mt_supported[2])

Please don't use spaces for indentation, always tabs

>                       goto out;
>  
>               if (sm_supported[0] && sm_supported[1]) {
> diff --git a/drivers/atmodem/vendor.h b/drivers/atmodem/vendor.h
> index 44b037f..1b296a0 100644
> --- a/drivers/atmodem/vendor.h
> +++ b/drivers/atmodem/vendor.h
> @@ -39,4 +39,5 @@ enum ofono_vendor {
>       OFONO_VENDOR_SPEEDUP,
>       OFONO_VENDOR_SAMSUNG,
>       OFONO_VENDOR_SIMCOM,
> +     OFONO_VENDOR_WAVECOM_Q,
>  };
> diff --git a/gatchat/gatchat.c b/gatchat/gatchat.c
> index 7a0ef35..eb5d83a 100644
> --- a/gatchat/gatchat.c
> +++ b/gatchat/gatchat.c
> @@ -478,7 +478,8 @@ static struct terminator_info terminator_table[] = {
>       { "NO ANSWER", -1, FALSE },
>       { "+CMS ERROR:", 11, FALSE },
>       { "+CME ERROR:", 11, FALSE },
> -     { "+EXT ERROR:", 11, FALSE }
> +     { "+EXT ERROR:", 11, FALSE },
> +     { "+CPIN: READY", -1, TRUE },

Are you sure you can't reuse the same behavior as OFONO_VENDOR_WAVECOM
quirk inside drivers/atmodem/sim.c?

e.g. in at_sim_probe():
        switch (sd->vendor) {
        case OFONO_VENDOR_WAVECOM:
                g_at_chat_add_terminator(sd->chat, "+CPIN:", 6, TRUE);
                break;

>  };
>  
>  static void at_chat_add_terminator(struct at_chat *chat, char *terminator,
> diff --git a/plugins/udev.c b/plugins/udev.c
> index 8cb87a5..e599296 100644
> --- a/plugins/udev.c
> +++ b/plugins/udev.c
> @@ -286,6 +286,8 @@ done:
>               add_nokiacdma(modem, udev_device);
>       else if (g_strcmp0(driver, "sim900") == 0)
>               add_sim900(modem, udev_device);
> +     else if (g_strcmp0(driver, "wavecom_q") == 0)
> +             add_calypso(modem, udev_device);

This is probably wrong, I suspect we need to add a generic function to
register (real) serial tty based modems.

>  }
>  
>  static gboolean devpath_remove(gpointer key, gpointer value, gpointer 
> user_data)
> diff --git a/plugins/wavecom_q.c b/plugins/wavecom_q.c
> new file mode 100644
> index 0000000..73e478a
> --- /dev/null
> +++ b/plugins/wavecom_q.c
> @@ -0,0 +1,192 @@
> +/*
> + *
> + *  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 <config.h>
> +#endif
> +
> +#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/log.h>
> +#include <ofono/modem.h>
> +#include <ofono/call-barring.h>
> +#include <ofono/call-forwarding.h>
> +#include <ofono/call-meter.h>
> +#include <ofono/call-settings.h>
> +#include <ofono/devinfo.h>
> +#include <ofono/message-waiting.h>
> +#include <ofono/netreg.h>
> +#include <ofono/phonebook.h>
> +#include <ofono/sim.h>
> +#include <ofono/sms.h>
> +#include <ofono/ussd.h>
> +#include <ofono/voicecall.h>
> +
> +#include <drivers/atmodem/vendor.h>
> +
> +
> +static int wavecom_q_probe(struct ofono_modem *modem)
> +{
> +     return 0;
> +}
> +
> +static void wavecom_q_remove(struct ofono_modem *modem)
> +{
> +}
> +
> +static void wavecom_q_debug(const char *str, void *user_data)
> +{
> +     const char *prefix = user_data;
> +
> +     ofono_info("%s%s", prefix, str);
> +}
> +
> +static int wavecom_q_enable(struct ofono_modem *modem)
> +{
> +     GAtChat *chat;
> +     GIOChannel *channel;
> +     GAtSyntax *syntax;
> +     const char *device;
> +     GHashTable *options;
> +
> +     DBG("%p", modem);
> +
> +     device = ofono_modem_get_string(modem, "Device");
> +     if (device == NULL)
> +             return -EINVAL;
> +
> +     options = g_hash_table_new(g_str_hash, g_str_equal);
> +
> +     if (options == NULL)
> +             return -ENOMEM;
> +
> +     g_hash_table_insert(options, "Baud", "115200");
> +     g_hash_table_insert(options, "Parity", "none");
> +     g_hash_table_insert(options, "StopBits", "1");
> +     g_hash_table_insert(options, "DataBits", "8");
> +
> +     channel = g_at_tty_open(device, options);
> +
> +     g_hash_table_destroy(options);
> +
> +     if (channel == NULL)
> +             return -EIO;
> +
> +     /*
> +      * Could not figure out whether it is fully compliant or not, use
> +      * permissive for now
> +      * */
> +     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 == NULL)
> +             return -ENOMEM;
> +
> +     if (getenv("OFONO_AT_DEBUG"))
> +             g_at_chat_set_debug(chat, wavecom_q_debug, "");
> +
> +     ofono_modem_set_data(modem, chat);
> +
> +     return 0;
> +}
> +
> +static int wavecom_q_disable(struct ofono_modem *modem)
> +{
> +     GAtChat *chat = ofono_modem_get_data(modem);
> +
> +     DBG("%p", modem);
> +
> +     ofono_modem_set_data(modem, NULL);
> +
> +     g_at_chat_unref(chat);
> +
> +     return 0;
> +}
> +
> +static void wavecom_q_pre_sim(struct ofono_modem *modem)
> +{
> +     GAtChat *chat = ofono_modem_get_data(modem);
> +     struct ofono_sim *sim;
> +
> +     DBG("%p", modem);
> +
> +     ofono_devinfo_create(modem, 0, "atmodem", chat);
> +     sim = ofono_sim_create(modem, OFONO_VENDOR_WAVECOM, "atmodem", chat);
> +     ofono_voicecall_create(modem, 0, "atmodem", chat);
> +
> +     if (sim)
> +             ofono_sim_inserted_notify(sim, TRUE);
> +}
> +
> +static void wavecom_q_post_sim(struct ofono_modem *modem)
> +{
> +     GAtChat *chat = ofono_modem_get_data(modem);
> +     struct ofono_message_waiting *mw;
> +
> +     DBG("%p", modem);
> +
> +     ofono_ussd_create(modem, 0, "atmodem", chat);
> +     ofono_call_forwarding_create(modem, 0, "atmodem", chat);
> +     ofono_call_settings_create(modem, 0, "atmodem", chat);
> +     ofono_netreg_create(modem, 0, "atmodem", chat);
> +     ofono_call_meter_create(modem, 0, "atmodem", chat);
> +     ofono_call_barring_create(modem, 0, "atmodem", chat);
> +     /* We need to specify the vendor to support AT+CPMS=? reply. */
> +     ofono_sms_create(modem, OFONO_VENDOR_WAVECOM_Q, "atmodem", chat);
> +     ofono_phonebook_create(modem, 0, "atmodem", chat);
> +
> +     mw = ofono_message_waiting_create(modem);
> +     if (mw)
> +             ofono_message_waiting_register(mw);
> +}
> +
> +static struct ofono_modem_driver wavecom_q_driver = {
> +     .name           = "wavecom_q",
> +     .probe          = wavecom_q_probe,
> +     .remove         = wavecom_q_remove,
> +     .enable         = wavecom_q_enable,
> +     .disable        = wavecom_q_disable,
> +     .pre_sim        = wavecom_q_pre_sim,
> +     .post_sim       = wavecom_q_post_sim,
> +};
> +
> +static int wavecom_q_init(void)
> +{
> +     return ofono_modem_driver_register(&wavecom_q_driver);
> +}
> +
> +static void wavecom_q_exit(void)
> +{
> +     ofono_modem_driver_unregister(&wavecom_q_driver);
> +}
> +
> +OFONO_PLUGIN_DEFINE(wavecom_q, "Wavecom-Q driver", VERSION,
> +             OFONO_PLUGIN_PRIORITY_DEFAULT, wavecom_q_init, wavecom_q_exit)

Is there a way to just re-use the wavecom driver instead of creating a
brand new one?

Regards,
-Denis
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to