commit 5c492c6014b6315362bf3eff47006de40a353b8e Author: Alastair Pharo Date: Sun Nov 19 19:38:28 2017 +1300 Attempt to fix Huawei E220 quirk -- doesn't work diff --git a/plugins/Makefile.am b/plugins/Makefile.am index c1b0917b..57fd4d52 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -284,6 +284,8 @@ libmm_plugin_huawei_la_SOURCES = \ huawei/mm-plugin-huawei.h \ huawei/mm-sim-huawei.c \ huawei/mm-sim-huawei.h \ + huawei/mm-sms-huawei.c \ + huawei/mm-sms-huawei.h \ huawei/mm-call-huawei.c \ huawei/mm-call-huawei.h \ huawei/mm-broadband-modem-huawei.c \ diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c index 3d743675..983d1c1e 100644 --- a/plugins/huawei/mm-broadband-modem-huawei.c +++ b/plugins/huawei/mm-broadband-modem-huawei.c @@ -40,6 +40,7 @@ #include "mm-iface-modem-3gpp.h" #include "mm-iface-modem-3gpp-ussd.h" #include "mm-iface-modem-location.h" +#include "mm-iface-modem-messaging.h" #include "mm-iface-modem-time.h" #include "mm-iface-modem-cdma.h" #include "mm-iface-modem-signal.h" @@ -49,12 +50,14 @@ #include "mm-broadband-bearer.h" #include "mm-bearer-list.h" #include "mm-sim-huawei.h" +#include "mm-sms-huawei.h" #include "mm-call-huawei.h" static void iface_modem_init (MMIfaceModem *iface); static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); static void iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface); static void iface_modem_location_init (MMIfaceModemLocation *iface); +static void iface_modem_messaging_init (MMIfaceModemMessaging *iface); static void iface_modem_cdma_init (MMIfaceModemCdma *iface); static void iface_modem_time_init (MMIfaceModemTime *iface); static void iface_modem_voice_init (MMIfaceModemVoice *iface); @@ -72,6 +75,7 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemHuawei, mm_broadband_modem_huawei, MM_TY G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_USSD, iface_modem_3gpp_ussd_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init) + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init) G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIGNAL, iface_modem_signal_init)) @@ -3564,6 +3568,15 @@ huawei_modem_create_sim (MMIfaceModem *self, user_data); } +/*****************************************************************************/ +/* Create SMS (Modem interface) */ + +static MMBaseSms * +modem_messaging_create_sms (MMIfaceModemMessaging *self) +{ + return mm_sms_huawei_new (MM_BASE_MODEM (self)); +} + /*****************************************************************************/ /* Location capabilities loading (Location interface) */ @@ -4320,6 +4333,7 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self) self->priv->prefmode_support = FEATURE_SUPPORT_UNKNOWN; self->priv->nwtime_support = FEATURE_SUPPORT_UNKNOWN; self->priv->time_support = FEATURE_SUPPORT_UNKNOWN; + } static void @@ -4466,6 +4480,12 @@ iface_modem_location_init (MMIfaceModemLocation *iface) } static void +iface_modem_messaging_init (MMIfaceModemMessaging *iface) +{ + iface->create_sms = modem_messaging_create_sms; +} + +static void iface_modem_time_init (MMIfaceModemTime *iface) { iface->check_support = modem_time_check_support; diff --git a/plugins/huawei/mm-sms-huawei.c b/plugins/huawei/mm-sms-huawei.c new file mode 100644 index 00000000..fae546bf --- /dev/null +++ b/plugins/huawei/mm-sms-huawei.c @@ -0,0 +1,198 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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: + * + * Copyright (C) 2012 Google, Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include +#define _LIBMM_INSIDE_MM +#include + +//#include "mm-modem-helpers-huawei.h" +//#include "mm-iface-modem.h" +//#include "mm-iface-modem-messaging.h" +#include "mm-sms-huawei.h" +#include "mm-broadband-modem.h" +#include "mm-broadband-modem-huawei.h" +#include "mm-base-modem-at.h" +#include "mm-log.h" + +G_DEFINE_TYPE (MMSmsHuawei, mm_sms_huawei, MM_TYPE_BASE_SMS) + +/*****************************************************************************/ + +#define MM_BROADBAND_MODEM_HUAWEI_CSCA_CHECK_DONE "huawei-csca-check-done" + +static void +parent_send_finished (MMBaseSms *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + gboolean result = g_task_propagate_boolean (G_TASK (res), &error); + + if (error) + g_task_return_error (task, error); + else + g_task_return_boolean (task, result); + + g_object_unref (task); +} + +static void +csca_set_ready (MMBaseModem *modem, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + const gchar *response; + MMBaseSms *self; + + response = mm_base_modem_at_command_finish (modem, res, &error); + if (error) { + g_task_return_error (task, error); + g_object_unref (task); + } + else { + /* Set the tag to prevent the check from being performed on this modem again */ + g_object_set_data (G_OBJECT (modem), MM_BROADBAND_MODEM_HUAWEI_CSCA_CHECK_DONE, GUINT_TO_POINTER (TRUE)); + + self = g_task_get_source_object (task); + MM_BASE_SMS_CLASS (mm_sms_huawei_parent_class)->send(self, (GAsyncReadyCallback)parent_send_finished, task); + } +} + +static void +csca_check_ready (MMBaseModem *modem, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + const gchar *response; + GRegex *r; + GMatchInfo *match_info = NULL; + gchar *smsc, *command; + guint address_type = 0; + + response = mm_base_modem_at_command_finish (modem, res, &error); + if (error) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* The modem will respond with a UCS-2 representation of the SMSC, but be + * need to set a UTF-8 representation, so we have to parse the response + */ + r = g_regex_new ("\\+CSCA:\\s*\"([0-9a-fA-F]+)\",(\\d+)", 0, 0, NULL); + g_assert (r); + + if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) { + g_task_return_new_error (task, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Unexpected +CSCA response: '%s'", + response); + + g_object_unref (task); + g_match_info_free (match_info); + g_regex_unref (r); + return; + } + + smsc = mm_get_string_unquoted_from_match_info (match_info, 1); + g_assert (smsc); + + smsc = mm_broadband_modem_take_and_convert_to_utf8 (MM_BROADBAND_MODEM (modem), + smsc); + mm_dbg ("Got SMSC: %s", smsc); + + mm_get_uint_from_match_info (match_info, 2, &address_type); + g_assert (address_type); + + command = g_strdup_printf ("+CSCA=\"%s\",%u", smsc, address_type); + mm_base_modem_at_command (modem, + command, + 3, + FALSE, + (GAsyncReadyCallback)csca_set_ready, + task); + + g_free (command); + g_match_info_free (match_info); + g_regex_unref (r); +} + +static void +sms_send (MMBaseSms *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MMBaseModem *modem; + + mm_dbg("Huawei send SMS"); + + g_object_get (self, + MM_BASE_SMS_MODEM, &modem, + NULL); + g_assert (modem); + + /* If there is no pointer, we need to do the check-and-set before sending. + * Otherwise, send as usual via the base class method. + */ + mm_dbg ("Checking to see if SMSC hack has been performed ..."); + if (g_object_get_data (G_OBJECT (modem), MM_BROADBAND_MODEM_HUAWEI_CSCA_CHECK_DONE)) { + mm_dbg ("SMSC hack has been performed; sending message as ususal"); + MM_BASE_SMS_CLASS (mm_sms_huawei_parent_class)->send(self, callback, user_data); + } + else { + mm_dbg ("SMSC hack has not been performed"); + mm_base_modem_at_command (modem, + "+CSCA?", + 3, + FALSE, + (GAsyncReadyCallback)csca_check_ready, + g_task_new (self, NULL, callback, user_data)); + } +} + +/*****************************************************************************/ + +MMBaseSms * +mm_sms_huawei_new (MMBaseModem *modem) +{ + mm_dbg ("New Huawei SMS"); + return MM_BASE_SMS (g_object_new (MM_TYPE_SMS_HUAWEI, + MM_BASE_SMS_MODEM, modem, + NULL)); +} + +static void +mm_sms_huawei_init (MMSmsHuawei *self) +{ + mm_dbg ("Init new Huawei SMS"); +} + +static void +mm_sms_huawei_class_init (MMSmsHuaweiClass *klass) +{ + MMBaseSmsClass *base_sms_class = MM_BASE_SMS_CLASS (klass); + + base_sms_class->send = sms_send; +} diff --git a/plugins/huawei/mm-sms-huawei.h b/plugins/huawei/mm-sms-huawei.h new file mode 100644 index 00000000..d6adb624 --- /dev/null +++ b/plugins/huawei/mm-sms-huawei.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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: + * + * Author: Aleksander Morgado + * + * Copyright (C) 2012 Google, Inc. + */ + +#ifndef MM_SMS_HUAWEI_H +#define MM_SMS_HUAWEI_H + +#include +#include + +#define _LIBMM_INSIDE_MM +#include + +#include "mm-base-sms.h" + +#define MM_TYPE_SMS_HUAWEI (mm_sms_huawei_get_type ()) +#define MM_SMS_HUAWEI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SMS_HUAWEI, MMSmsHuawei)) +#define MM_SMS_HUAWEI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_SMS_HUAWEI, MMSmsHuaweiClass)) +#define MM_IS_SMS_HUAWEI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SMS_HUAWEI)) +#define MM_IS_SMS_HUAWEI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_SMS_HUAWEI)) +#define MM_SMS_HUAWEI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_SMS_HUAWEI, MMSmsHuaweiClass)) + +typedef struct _MMSmsHuawei MMSmsHuawei; +typedef struct _MMSmsHuaweiClass MMSmsHuaweiClass; + +struct _MMSmsHuawei { + MMBaseSms parent; +}; + +struct _MMSmsHuaweiClass { + MMBaseSmsClass parent; +}; + +GType mm_sms_huawei_get_type (void); + +MMBaseSms *mm_sms_huawei_new (MMBaseModem *modem); + +#endif /* MM_SMS_HUAWEI_H */