diff options
author | Dan Williams <dcbw@redhat.com> | 2012-12-05 12:17:38 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2012-12-05 13:49:21 -0600 |
commit | 8c1f80a9a44e686b8f12dcbafa0d3d9b6ad5b7f0 (patch) | |
tree | 42632b8cc3bcfca14fb273716871c7181a6aca30 | |
parent | 4e980d17396bc65acd49edbaf195013dcae5e5d0 (diff) |
huawei: implement Time interface for CDMA modems
-rw-r--r-- | plugins/huawei/mm-broadband-modem-huawei.c | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c index 44e6f6ed..abff4e54 100644 --- a/plugins/huawei/mm-broadband-modem-huawei.c +++ b/plugins/huawei/mm-broadband-modem-huawei.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <unistd.h> | 23 | #include <unistd.h> |
24 | #include <ctype.h> | 24 | #include <ctype.h> |
25 | #include <time.h> | ||
25 | 26 | ||
26 | #include <ModemManager.h> | 27 | #include <ModemManager.h> |
27 | #define _LIBMM_INSIDE_MM | 28 | #define _LIBMM_INSIDE_MM |
@@ -34,6 +35,7 @@ | |||
34 | #include "mm-iface-modem.h" | 35 | #include "mm-iface-modem.h" |
35 | #include "mm-iface-modem-3gpp.h" | 36 | #include "mm-iface-modem-3gpp.h" |
36 | #include "mm-iface-modem-3gpp-ussd.h" | 37 | #include "mm-iface-modem-3gpp-ussd.h" |
38 | #include "mm-iface-modem-time.h" | ||
37 | #include "mm-iface-modem-cdma.h" | 39 | #include "mm-iface-modem-cdma.h" |
38 | #include "mm-broadband-modem-huawei.h" | 40 | #include "mm-broadband-modem-huawei.h" |
39 | 41 | ||
@@ -41,6 +43,7 @@ static void iface_modem_init (MMIfaceModem *iface); | |||
41 | static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); | 43 | static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); |
42 | static void iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface); | 44 | static void iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface); |
43 | static void iface_modem_cdma_init (MMIfaceModemCdma *iface); | 45 | static void iface_modem_cdma_init (MMIfaceModemCdma *iface); |
46 | static void iface_modem_time_init (MMIfaceModemTime *iface); | ||
44 | 47 | ||
45 | static MMIfaceModem *iface_modem_parent; | 48 | static MMIfaceModem *iface_modem_parent; |
46 | static MMIfaceModem3gpp *iface_modem_3gpp_parent; | 49 | static MMIfaceModem3gpp *iface_modem_3gpp_parent; |
@@ -50,7 +53,8 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemHuawei, mm_broadband_modem_huawei, MM_TY | |||
50 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) | 53 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) |
51 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init) | 54 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init) |
52 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_USSD, iface_modem_3gpp_ussd_init) | 55 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_USSD, iface_modem_3gpp_ussd_init) |
53 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init)); | 56 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init) |
57 | G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init)); | ||
54 | 58 | ||
55 | struct _MMBroadbandModemHuaweiPrivate { | 59 | struct _MMBroadbandModemHuaweiPrivate { |
56 | /* Regex for signal quality related notifications */ | 60 | /* Regex for signal quality related notifications */ |
@@ -1810,6 +1814,126 @@ get_detailed_registration_state (MMIfaceModemCdma *self, | |||
1810 | } | 1814 | } |
1811 | 1815 | ||
1812 | /*****************************************************************************/ | 1816 | /*****************************************************************************/ |
1817 | /* Load network time (Time interface) */ | ||
1818 | |||
1819 | static gchar * | ||
1820 | modem_time_load_network_time_finish (MMIfaceModemTime *self, | ||
1821 | GAsyncResult *res, | ||
1822 | GError **error) | ||
1823 | { | ||
1824 | const gchar *response; | ||
1825 | GRegex *r; | ||
1826 | GMatchInfo *match_info = NULL; | ||
1827 | GError *match_error = NULL; | ||
1828 | guint year, month, day, hour, minute, second; | ||
1829 | gchar *result = NULL; | ||
1830 | |||
1831 | response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); | ||
1832 | if (!response) | ||
1833 | return NULL; | ||
1834 | |||
1835 | /* Already in ISO-8601 format, but verify just to be sure */ | ||
1836 | r = g_regex_new ("\\^TIME:\\s*(\\d+)/(\\d+)/(\\d+)\\s*(\\d+):(\\d+):(\\d*)$", 0, 0, NULL); | ||
1837 | g_assert (r != NULL); | ||
1838 | |||
1839 | if (!g_regex_match_full (r, response, -1, 0, 0, &match_info, &match_error)) { | ||
1840 | if (match_error) { | ||
1841 | g_propagate_error (error, match_error); | ||
1842 | g_prefix_error (error, "Could not parse ^TIME results: "); | ||
1843 | } else { | ||
1844 | g_set_error_literal (error, | ||
1845 | MM_CORE_ERROR, | ||
1846 | MM_CORE_ERROR_FAILED, | ||
1847 | "Couldn't match ^TIME reply"); | ||
1848 | } | ||
1849 | } else { | ||
1850 | /* Remember that g_match_info_get_match_count() includes match #0 */ | ||
1851 | g_assert (g_match_info_get_match_count (match_info) >= 7); | ||
1852 | |||
1853 | if (mm_get_uint_from_match_info (match_info, 1, &year) && | ||
1854 | mm_get_uint_from_match_info (match_info, 2, &month) && | ||
1855 | mm_get_uint_from_match_info (match_info, 3, &day) && | ||
1856 | mm_get_uint_from_match_info (match_info, 4, &hour) && | ||
1857 | mm_get_uint_from_match_info (match_info, 5, &minute) && | ||
1858 | mm_get_uint_from_match_info (match_info, 6, &second)) { | ||
1859 | /* Return ISO-8601 format date/time string */ | ||
1860 | result = g_strdup_printf ("%04d/%02d/%02d %02d:%02d:%02d", | ||
1861 | year, month, day, hour, minute, second); | ||
1862 | } else { | ||
1863 | g_set_error_literal (error, | ||
1864 | MM_CORE_ERROR, | ||
1865 | MM_CORE_ERROR_FAILED, | ||
1866 | "Failed to parse ^TIME reply"); | ||
1867 | } | ||
1868 | } | ||
1869 | |||
1870 | if (match_info) | ||
1871 | g_match_info_free (match_info); | ||
1872 | g_regex_unref (r); | ||
1873 | return result; | ||
1874 | } | ||
1875 | |||
1876 | static void | ||
1877 | modem_time_load_network_time (MMIfaceModemTime *self, | ||
1878 | GAsyncReadyCallback callback, | ||
1879 | gpointer user_data) | ||
1880 | { | ||
1881 | mm_base_modem_at_command (MM_BASE_MODEM (self), | ||
1882 | "^TIME", | ||
1883 | 3, | ||
1884 | FALSE, | ||
1885 | callback, | ||
1886 | user_data); | ||
1887 | } | ||
1888 | |||
1889 | /*****************************************************************************/ | ||
1890 | /* Check support (Time interface) */ | ||
1891 | |||
1892 | static gboolean | ||
1893 | modem_time_check_support_finish (MMIfaceModemTime *self, | ||
1894 | GAsyncResult *res, | ||
1895 | GError **error) | ||
1896 | { | ||
1897 | return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); | ||
1898 | } | ||
1899 | |||
1900 | static void | ||
1901 | modem_time_check_ready (MMBroadbandModem *self, | ||
1902 | GAsyncResult *res, | ||
1903 | GSimpleAsyncResult *simple) | ||
1904 | { | ||
1905 | GError *error = NULL; | ||
1906 | |||
1907 | mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); | ||
1908 | if (error) | ||
1909 | g_simple_async_result_take_error (simple, error); | ||
1910 | |||
1911 | g_simple_async_result_complete (simple); | ||
1912 | g_object_unref (simple); | ||
1913 | } | ||
1914 | |||
1915 | static void | ||
1916 | modem_time_check_support (MMIfaceModemTime *self, | ||
1917 | GAsyncReadyCallback callback, | ||
1918 | gpointer user_data) | ||
1919 | { | ||
1920 | GSimpleAsyncResult *result; | ||
1921 | |||
1922 | result = g_simple_async_result_new (G_OBJECT (self), | ||
1923 | callback, | ||
1924 | user_data, | ||
1925 | modem_time_check_support); | ||
1926 | |||
1927 | /* Only CDMA devices support this at the moment */ | ||
1928 | mm_base_modem_at_command (MM_BASE_MODEM (self), | ||
1929 | "^TIME", | ||
1930 | 3, | ||
1931 | TRUE, | ||
1932 | (GAsyncReadyCallback)modem_time_check_ready, | ||
1933 | result); | ||
1934 | } | ||
1935 | |||
1936 | /*****************************************************************************/ | ||
1813 | /* Setup ports (Broadband modem class) */ | 1937 | /* Setup ports (Broadband modem class) */ |
1814 | 1938 | ||
1815 | static void | 1939 | static void |
@@ -1994,6 +2118,15 @@ iface_modem_cdma_init (MMIfaceModemCdma *iface) | |||
1994 | } | 2118 | } |
1995 | 2119 | ||
1996 | static void | 2120 | static void |
2121 | iface_modem_time_init (MMIfaceModemTime *iface) | ||
2122 | { | ||
2123 | iface->check_support = modem_time_check_support; | ||
2124 | iface->check_support_finish = modem_time_check_support_finish; | ||
2125 | iface->load_network_time = modem_time_load_network_time; | ||
2126 | iface->load_network_time_finish = modem_time_load_network_time_finish; | ||
2127 | } | ||
2128 | |||
2129 | static void | ||
1997 | mm_broadband_modem_huawei_class_init (MMBroadbandModemHuaweiClass *klass) | 2130 | mm_broadband_modem_huawei_class_init (MMBroadbandModemHuaweiClass *klass) |
1998 | { | 2131 | { |
1999 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | 2132 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |