r3553 - in trunk/src/target/OM-2007.2/applications/openmoko-dialer2: . src/dialer src/phone-kit
chris at sita.openmoko.org
chris at sita.openmoko.org
Mon Dec 3 15:49:54 CET 2007
Author: chris
Date: 2007-12-03 15:49:48 +0100 (Mon, 03 Dec 2007)
New Revision: 3553
Added:
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.c
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.h
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-mcc-dc.h
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network-dbus.xml
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.c
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.h
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms-dbus.xml
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.c
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.h
Removed:
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-mcc-dc.h
Modified:
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/ChangeLog
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/dialer/dialer-main.c
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/Makefile.am
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/dialer-main.c
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-dbus.xml
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.c
trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.h
Log:
* src/dialer/dialer-main.c: (main):
Change object path/interface name to match re-factoring
* src/phone-kit/Makefile.am:
* src/phone-kit/dialer-main.c: (_dial_number), (main):
* src/phone-kit/moko-dialer-dbus.xml:
* src/phone-kit/moko-dialer-mcc-dc.h:
* src/phone-kit/moko-dialer.[ch]:
* src/phone-kit/moko-listener.[ch]:
* src/phone-kit/moko-network-dbus.xml:
* src/phone-kit/moko-network.[ch]:
* src/phone-kit/moko-sms-dbus.xml:
* src/phone-kit/moko-sms.[ch]:
Re-factor into three separate objects for Network, Dialer and SMS
interaction that share a common gsmd connection
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/ChangeLog
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/ChangeLog 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/ChangeLog 2007-12-03 14:49:48 UTC (rev 3553)
@@ -1,3 +1,21 @@
+2007-11-30 Chris Lord <chris at openedhand.com>
+
+ * src/dialer/dialer-main.c: (main):
+ Change object path/interface name to match re-factoring
+
+ * src/phone-kit/Makefile.am:
+ * src/phone-kit/dialer-main.c: (_dial_number), (main):
+ * src/phone-kit/moko-dialer-dbus.xml:
+ * src/phone-kit/moko-dialer-mcc-dc.h:
+ * src/phone-kit/moko-dialer.[ch]:
+ * src/phone-kit/moko-listener.[ch]:
+ * src/phone-kit/moko-network-dbus.xml:
+ * src/phone-kit/moko-network.[ch]:
+ * src/phone-kit/moko-sms-dbus.xml:
+ * src/phone-kit/moko-sms.[ch]:
+ Re-factor into three separate objects for Network, Dialer and SMS
+ interaction that share a common gsmd connection
+
2007-11-28 Thomas Wood <thomas at openedhand.com>
* data/Makefile.am:
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/dialer/dialer-main.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/dialer/dialer-main.c 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/dialer/dialer-main.c 2007-12-03 14:49:48 UTC (rev 3553)
@@ -120,8 +120,9 @@
exit (1);
}
- data->dialer_proxy = dbus_g_proxy_new_for_name (connection, "org.openmoko.Dialer",
- "/org/openmoko/Dialer", "org.openmoko.Dialer");
+ data->dialer_proxy = dbus_g_proxy_new_for_name (connection,
+ "org.openmoko.PhoneKit",
+ "/org/openmoko/PhoneKit/Dialer", "org.openmoko.PhoneKit.Dialer");
/* application object */
g_set_application_name ("OpenMoko Dialer");
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/Makefile.am
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/Makefile.am 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/Makefile.am 2007-12-03 14:49:48 UTC (rev 3553)
@@ -7,13 +7,15 @@
phone_kit_SOURCES = \
dialer-main.c \
+ moko-listener.c moko-listener.h \
+ moko-network.c moko-network.h \
+ moko-sms.c moko-sms.h \
moko-dialer.c moko-dialer.h \
moko-notify.c moko-notify.h \
moko-sound.c moko-sound.h \
moko-talking.c moko-talking.h \
- moko-pin.c \
- moko-pin.h \
- moko-dialer-mcc-dc.h
+ moko-pin.c moko-pin.h \
+ moko-mcc-dc.h
phone_kit_LDADD = @DIALER_LIBS@ @JANA_LIBS@ $(top_srcdir)/src/common/libdialer-common.a
@@ -21,7 +23,7 @@
%-glue.h: %-dbus.xml
$(LIBTOOL) --mode=execute $(DBUS_GLIB_BIN)/dbus-binding-tool --prefix=$(subst -,_,$*) --mode=glib-server --output=$@ $<
-BUILT_SOURCES = moko-dialer-glue.h
+BUILT_SOURCES = moko-dialer-glue.h moko-sms-glue.h moko-network-glue.h
-EXTRA_DIST = moko-dialer-dbus.xml
+EXTRA_DIST = moko-dialer-dbus.xml moko-sms-dbus.xml moko-network-dbus.xml
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/dialer-main.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/dialer-main.c 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/dialer-main.c 2007-12-03 14:49:48 UTC (rev 3553)
@@ -20,10 +20,15 @@
#include <dbus/dbus-glib-bindings.h>
#include <glib-object.h>
+#include "moko-network.h"
#include "moko-dialer.h"
+#include "moko-sms.h"
-#define DIALER_NAMESPACE "org.openmoko.Dialer"
-#define DIALER_OBJECT "/org/openmoko/Dialer"
+#define PHONEKIT_NAMESPACE "org.openmoko.PhoneKit"
+#define NETWORK_PATH "/org/openmoko/PhoneKit/Network"
+#define DIALER_PATH "/org/openmoko/PhoneKit/Dialer"
+#define SMS_PATH "/org/openmoko/PhoneKit/Sms"
+#define DIALER_INTERFACE "org.openmoko.PhoneKit.Dialer"
static gchar *number = NULL;
@@ -34,9 +39,9 @@
GError *error = NULL;
proxy = dbus_g_proxy_new_for_name (conn,
- DIALER_NAMESPACE,
- DIALER_OBJECT,
- DIALER_NAMESPACE);
+ PHONEKIT_NAMESPACE,
+ DIALER_PATH,
+ DIALER_INTERFACE);
if (!proxy)
return;
@@ -52,7 +57,9 @@
int
main (int argc, char **argv)
{
+ MokoNetwork *network;
MokoDialer *dialer;
+ MokoSms *sms;
DBusGConnection *connection;
DBusGProxy *proxy;
GError *error = NULL;
@@ -75,7 +82,7 @@
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
if (!org_freedesktop_DBus_request_name (proxy,
- DIALER_NAMESPACE,
+ PHONEKIT_NAMESPACE,
0, &ret, &error))
{
/* Error requesting the name */
@@ -104,13 +111,21 @@
/* Initialize Threading & GTK+ */
gtk_init (&argc, &argv);
- /* Create the MokoDialer object */
- dialer = moko_dialer_get_default ();
+ /* Create the PhoneKit objects */
+ network = moko_network_get_default ();
+ dialer = moko_dialer_get_default (network);
+ sms = moko_sms_get_default (network);
/* Add the objects onto the bus */
dbus_g_connection_register_g_object (connection,
- DIALER_OBJECT,
+ NETWORK_PATH,
+ G_OBJECT (network));
+ dbus_g_connection_register_g_object (connection,
+ DIALER_PATH,
G_OBJECT (dialer));
+ dbus_g_connection_register_g_object (connection,
+ SMS_PATH,
+ G_OBJECT (sms));
/* application object */
g_set_application_name ("OpenMoko Dialer");
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-dbus.xml
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-dbus.xml 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-dbus.xml 2007-12-03 14:49:48 UTC (rev 3553)
@@ -1,11 +1,10 @@
<?xml version="1.0"?>
-<node name="/org/openmoko/Dialer">
-<interface name="org.openmoko.Dialer">
+<node name="/org/openmoko/PhoneKit">
+<interface name="org.openmoko.PhoneKit.Dialer">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="moko_dialer"/>
- <method name="GetStatus">
- <arg type="i" name="status" direction="out" />
- </method>
+ <property name="Status" type="i" access="read" />
+
<method name="Dial">
<arg type="s" name="number" direction="in" />
</method>
@@ -14,28 +13,6 @@
<arg type="s" name="message" direction="in" />
</method>
- <method name="SendSms">
- <arg type="s" name="number" />
- <arg type="s" name="message" />
- <arg type="s" name="uid" direction="out" />
- </method>
-
- <method name="GetProviderName">
- <arg type="s" name="name" direction="out" />
- </method>
-
- <method name="GetSubscriberNumber">
- <arg type="s" name="number" direction="out" />
- </method>
-
- <method name="GetCountryCode">
- <arg type="s" name="dial_code" direction="out" />
- </method>
-
- <method name="GetHomeCountryCode">
- <arg type="s" name="dial_code" direction="out" />
- </method>
-
<signal name="IncomingCall">
<arg type="s" name="number"/>
</signal>
@@ -52,5 +29,9 @@
<signal name="Rejected">
</signal>
+ <signal name="StatusChanged">
+ <arg type="i" name="status" />
+ </signal>
+
</interface>
</node>
Deleted: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-mcc-dc.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-mcc-dc.h 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-mcc-dc.h 2007-12-03 14:49:48 UTC (rev 3553)
@@ -1,244 +0,0 @@
-
-/* The following is a mapping of GSM MCC codes to country dialing codes */
-
-/* This mapping generated by cross-referencing
- * ITU E.212[1] ("Land Mobile Numbering Plan") with the wikipedia list of
- * country dialing codes[2]. FIXME: It may not be 100% correct.
- *
- * [1] http://www.itu.int/itudoc/itu-t/ob-lists/icc/e212_685.html
- * [2] http://en.wikipedia.org/wiki/List_of_country_calling_codes
- */
-
-static const gchar * mcc_to_dc[][3] = {
-{ "412", "+93", "Afghanistan" },
-{ "276", "+355", "Albania" },
-{ "603", "+213", "Algeria" },
-{ "544", "+1684", "American Samoa (US)" },
-{ "213", "+376", "Andorra" },
-{ "631", "+244", "Angola" },
-{ "365", "+1264", "Anguilla" },
-{ "344", "+1268", "Antigua and Barbuda" },
-{ "722", "+54", "Argentine Republic" },
-{ "283", "+374", "Armenia" },
-{ "363", "+297", "Aruba (Netherlands)" },
-{ "505", "+61", "Australia" },
-{ "232", "+43", "Austria" },
-{ "400", "+994", "Azerbaijani Republic" },
-{ "364", "+1242", "Bahamas" },
-{ "426", "+973", "Bahrain" },
-{ "470", "+880", "Bangladesh" },
-{ "342", "+1246", "Barbados" },
-{ "257", "+375", "Belarus" },
-{ "206", "+32", "Belgium" },
-{ "702", "+501", "Belize" },
-{ "616", "+229", "Benin" },
-{ "350", "+1441", "Bermuda (UK)" },
-{ "402", "+975", "Bhutan" },
-{ "736", "+591", "Bolivia" },
-{ "218", "+387", "Bosnia and Herzegovina" },
-{ "652", "+267", "Botswana" },
-{ "724", "+55", "Brazil" },
-{ "348", "+1284", "British Virgin Islands (UK)" },
-{ "528", "+673", "Brunei Darussalam" },
-{ "284", "+359", "Bulgaria" },
-{ "613", "+226", "Burkina Faso" },
-{ "642", "+257", "Burundi" },
-{ "456", "+855", "Cambodia" },
-{ "624", "+237", "Cameroon" },
-{ "302", "+1", "Canada" },
-{ "625", "+238", "Cape Verde" },
-{ "346", "+1345", "Cayman Islands (UK)" },
-{ "623", "+236", "Central African Republic" },
-{ "622", "+235", "Chad" },
-{ "730", "+56", "Chile" },
-{ "460", "+86", "China" },
-{ "732", "+57", "Colombia" },
-{ "654", "+269", "Comoros" },
-{ "629", "+242", "Republic of the Congo" },
-{ "548", "+682", "Cook Islands (NZ)" },
-{ "712", "+506", "Costa Rica" },
-{ "612", "+225", "Côte d'Ivoire" },
-{ "219", "+385", "Croatia" },
-{ "368", "+53", "Cuba" },
-{ "280", "+357", "Cyprus" },
-{ "230", "+420", "Czech Republic" },
-{ "630", "+243", "Democratic Republic of the Congo" },
-{ "238", "+45", "Denmark" },
-{ "638", "+253", "Djibouti" },
-{ "366", "+1767", "Dominica" },
-{ "370", "+1809", "Dominican Republic" },
-{ "514", "+670", "East Timor" },
-{ "740", "+593", "Ecuador" },
-{ "602", "+20", "Egypt" },
-{ "706", "+503", "El Salvador" },
-{ "627", "+240", "Equatorial Guinea" },
-{ "657", "+291", "Eritrea" },
-{ "248", "+372", "Estonia" },
-{ "636", "+251", "Ethiopia" },
-{ "288", "+298", "Faroe Islands (Denmark)" },
-{ "542", "+679", "Fiji" },
-{ "244", "+358", "Finland" },
-{ "208", "+33", "France" },
-{ "742", "+594", "French Guiana (France)" },
-{ "547", "+689", "French Polynesia (France)" },
-{ "628", "+241", "Gabonese Republic" },
-{ "607", "+220", "Gambia" },
-{ "282", "+995", "Georgia" },
-{ "262", "+49", "Germany" },
-{ "620", "+233", "Ghana" },
-{ "266", "+350", "Gibraltar (UK)" },
-{ "202", "+30", "Greece" },
-{ "290", "+299", "Greenland (Denmark)" },
-{ "352", "+1473", "Grenada" },
-{ "340", "+590", "Guadeloupe (France)" },
-{ "535", "+1671", "Guam (US)" },
-{ "704", "+502", "Guatemala" },
-{ "611", "+224", "Guinea" },
-{ "632", "+245", "Guinea-Bissau" },
-{ "738", "+592", "Guyana" },
-{ "372", "+509", "Haiti" },
-{ "708", "+504", "Honduras" },
-{ "454", "+852", "Hong Kong (PRC)" },
-{ "216", "+36", "Hungary" },
-{ "274", "+354", "Iceland" },
-{ "404", "+91", "India" },
-{ "405", "+91", "India" },
-{ "510", "+62", "Indonesia" },
-{ "432", "+98", "Iran" },
-{ "418", "+964", "Iraq" },
-{ "272", "+353", "Ireland" },
-{ "425", "+972", "Israel" },
-{ "222", "+39", "Italy" },
-{ "338", "+1876", "Jamaica" },
-{ "441", "+81", "Japan" },
-{ "440", "+81", "Japan" },
-{ "416", "+962", "Jordan" },
-{ "401", "+7", "Kazakhstan" },
-{ "639", "+254", "Kenya" },
-{ "545", "+686", "Kiribati" },
-{ "467", "+850", "Korea North" },
-{ "450", "+82", "Korea South" },
-{ "419", "+965", "Kuwait" },
-{ "437", "+996", "Kyrgyz Republic" },
-{ "457", "+856", "Laos" },
-{ "247", "+371", "Latvia" },
-{ "415", "+961", "Lebanon" },
-{ "651", "+266", "Lesotho" },
-{ "618", "+231", "Liberia" },
-{ "606", "+218", "Libya" },
-{ "295", "+423", "Liechtenstein" },
-{ "246", "+370", "Lithuania" },
-{ "270", "+352", "Luxembourg" },
-{ "455", "+853", "Macao (PRC)" },
-{ "294", "+389", "Republic of Macedonia" },
-{ "646", "+261", "Madagascar" },
-{ "650", "+265", "Malawi" },
-{ "502", "+60", "Malaysia" },
-{ "472", "+960", "Maldives" },
-{ "610", "+223", "Mali" },
-{ "278", "+356", "Malta" },
-{ "551", "+692", "Marshall Islands" },
-{ "340", "+596", "Martinique (France)" },
-{ "609", "+222", "Mauritania" },
-{ "617", "+230", "Mauritius" },
-{ "334", "+52", "Mexico" },
-{ "550", "+691", "Federated States of Micronesia" },
-{ "259", "+373", "Moldova" },
-{ "212", "+377", "Monaco" },
-{ "428", "+976", "Mongolia" },
-{ "354", "+1664", "Montserrat (UK)" },
-{ "604", "+212", "Morocco" },
-{ "643", "+258", "Mozambique" },
-{ "414", "+95", "Myanmar" },
-{ "649", "+264", "Namibia" },
-{ "536", "+674", "Nauru" },
-{ "429", "+977", "Nepal" },
-{ "204", "+31", "Netherlands" },
-{ "362", "+599", "Netherlands Antilles (Netherlands)" },
-{ "546", "+687", "New Caledonia (France)" },
-{ "530", "+64", "New Zealand" },
-{ "710", "+505", "Nicaragua" },
-{ "614", "+227", "Niger" },
-{ "621", "+234", "Nigeria" },
-{ "534", "+1670", "Northern Mariana Islands (US)" },
-{ "242", "+47", "Norway" },
-{ "422", "+968", "Oman" },
-{ "410", "+92", "Pakistan" },
-{ "552", "+680", "Palau" },
-{ "714", "+507", "Panama" },
-{ "537", "+675", "Papua New Guinea" },
-{ "744", "+595", "Paraguay" },
-{ "716", "+51", "Peru" },
-{ "515", "+63", "Philippines" },
-{ "260", "+48", "Poland" },
-{ "351", "+351", "Portugal" },
-{ "330", "+1787", "Puerto Rico (US)" },
-{ "427", "+974", "Qatar" },
-{ "647", "+262", "Réunion (France)" },
-{ "226", "+40", "Romania" },
-{ "250", "+7", "Russian Federation" },
-{ "635", "+250", "Rwandese Republic" },
-{ "356", "+1869", "Saint Kitts and Nevis" },
-{ "358", "+1758", "Saint Lucia" },
-{ "308", "+508", "Saint Pierre and Miquelon (France)" },
-{ "360", "+1784", "Saint Vincent and the Grenadines" },
-{ "549", "+685", "Samoa" },
-{ "292", "+378", "San Marino" },
-{ "626", "+239", "São Tomé and Príncipe" },
-{ "420", "+966", "Saudi Arabia" },
-{ "608", "+221", "Senegal" },
-{ "220", "+382", "Montenegro" },
-{ "633", "+248", "Seychelles" },
-{ "619", "+232", "Sierra Leone" },
-{ "525", "+65", "Singapore" },
-{ "231", "+421", "Slovakia" },
-{ "293", "+386", "Slovenia" },
-{ "540", "+677", "Solomon Islands" },
-{ "637", "+252", "Somalia" },
-{ "655", "+27", "South Africa" },
-{ "214", "+34", "Spain" },
-{ "413", "+94", "Sri Lanka" },
-{ "634", "+249", "Sudan" },
-{ "746", "+597", "Suriname" },
-{ "653", "+268", "Swaziland" },
-{ "240", "+46", "Sweden" },
-{ "228", "+41", "Switzerland" },
-{ "417", "+963", "Syria" },
-{ "466", "+886", "Taiwan" },
-{ "436", "+992", "Tajikistan" },
-{ "640", "+255", "Tanzania" },
-{ "520", "+66", "Thailand" },
-{ "615", "+228", "Togolese Republic" },
-{ "539", "+676", "Tonga" },
-{ "374", "+1868", "Trinidad and Tobago" },
-{ "605", "+216", "Tunisia" },
-{ "286", "+90", "Turkey" },
-{ "438", "+993", "Turkmenistan" },
-{ "376", "+1649", "Turks and Caicos Islands (UK)" },
-{ "641", "+256", "Uganda" },
-{ "255", "+380", "Ukraine" },
-{ "424", "+971", "United Arab Emirates" },
-{ "430", "+971", "United Arab Emirates (Abu Dhabi)" },
-{ "431", "+971", "United Arab Emirates (Dubai)" },
-{ "235", "+44", "United Kingdom" },
-{ "234", "+44", "United Kingdom" },
-{ "310", "+1", "United States of America" },
-{ "311", "+1", "United States of America" },
-{ "312", "+1", "United States of America" },
-{ "313", "+1", "United States of America" },
-{ "314", "+1", "United States of America" },
-{ "315", "+1", "United States of America" },
-{ "316", "+1", "United States of America" },
-{ "332", "+1340", "United States Virgin Islands (US)" },
-{ "748", "+598", "Uruguay" },
-{ "434", "+998", "Uzbekistan" },
-{ "541", "+678", "Vanuatu" },
-{ "225", "+39", "Vatican City State" },
-{ "734", "+58", "Venezuela" },
-{ "452", "+84", "Viet Nam" },
-{ "543", "+681", "Wallis and Futuna (France)" },
-{ "421", "+967", "Yemen" },
-{ "645", "+260", "Zambia" },
-{ "648", "+263", "Zimbabwe" },
-{NULL}
-};
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.c 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.c 2007-12-03 14:49:48 UTC (rev 3553)
@@ -28,18 +28,11 @@
#include <moko-journal.h>
#include <moko-stock.h>
-#include <libgsmd/libgsmd.h>
-#include <libgsmd/event.h>
-#include <libgsmd/misc.h>
-#include <libgsmd/sms.h>
-#include <libgsmd/voicecall.h>
-#include <libgsmd/phonebook.h>
-#include <gsmd/usock.h>
-
#include <libjana/jana.h>
#include <libjana-ecal/jana-ecal.h>
#include "moko-dialer.h"
+#include "moko-listener.h"
#include "moko-contacts.h"
#include "moko-notify.h"
@@ -47,53 +40,44 @@
#include "moko-sound.h"
#include "moko-pin.h"
-#include "moko-dialer-mcc-dc.h"
+static void
+listener_interface_init (gpointer g_iface, gpointer iface_data);
-G_DEFINE_TYPE (MokoDialer, moko_dialer, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (MokoDialer, moko_dialer, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MOKO_TYPE_LISTENER,
+ listener_interface_init))
#define MOKO_DIALER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
MOKO_TYPE_DIALER, MokoDialerPrivate))
-typedef struct {
- GSource source;
- GPollFD pollfd;
- struct lgsm_handle *handle;
-} MokoDialerSource;
-
struct _MokoDialerPrivate
{
- gint status;
- gchar *incoming_clip;
- gchar *own_number;
- gchar *network_name;
- gchar *network_number;
- gchar *imsi;
+ PhoneKitDialerStatus status;
+ gchar *incoming_clip;
/* handles user interaction */
- GtkWidget *talking;
+ GtkWidget *talking;
/* gsmd connection variables */
- struct lgsm_handle *handle;
- MokoDialerSource *source;
- gboolean handling_sms;
+ MokoNetwork *network;
+ enum lgsm_netreg_state registered;
+ MokoGSMLocation gsm_location;
/* Storage objects */
- JanaStore *sms_store;
- gboolean sms_store_open;
- JanaNote *last_msg;
- MokoJournal *journal;
- MokoContacts *contacts;
+ MokoJournal *journal;
+ MokoContacts *contacts;
/* Notification handling object */
- MokoNotify *notify;
+ MokoNotify *notify;
/* The shared MokoJournalEntry which is constantly created */
- MokoJournalEntry *entry;
- MokoTime *time;
+ MokoJournalEntry *entry;
+ MokoTime *time;
+};
- /* Registration variables */
- enum lgsm_netreg_state registered;
- MokoGSMLocation gsm_location;
+enum {
+ PROP_STATUS = 1,
+ PROP_NETWORK,
};
enum
@@ -103,29 +87,53 @@
TALKING,
HUNG_UP,
REJECTED,
+ STATUS_CHANGED,
LAST_SIGNAL
};
static guint dialer_signals[LAST_SIGNAL] = {0, };
-static void dialer_init_gsmd (MokoDialer *dialer);
-
-static const gchar *moko_dialer_cc_from_mcc (gchar *mcc);
-
/* DBus functions */
-static gboolean
-moko_dialer_get_status (MokoDialer *dialer, gint *OUT_status, GError **error)
+static void
+moko_dialer_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
{
- MokoDialerPrivate *priv;
+ switch (property_id) {
+ case PROP_STATUS :
+ g_value_set_int (value, moko_dialer_get_status (MOKO_DIALER (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+moko_dialer_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ MokoDialerPrivate *priv = MOKO_DIALER (object)->priv;
- g_return_val_if_fail (MOKO_IS_DIALER (dialer), FALSE);
- priv = dialer->priv;
+ switch (property_id) {
+ case PROP_NETWORK :
+ if (priv->network) {
+ moko_network_remove_listener (priv->network, MOKO_LISTENER (object));
+ g_object_unref (priv->network);
+ }
+ priv->network = g_value_dup_object (value);
+ moko_network_add_listener (priv->network, MOKO_LISTENER (object));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
- *OUT_status = priv->status;
-
- return TRUE;
+PhoneKitDialerStatus
+moko_dialer_get_status (MokoDialer *dialer)
+{
+ MokoDialerPrivate *priv = dialer->priv;
+ return priv->status;
}
gboolean
@@ -134,25 +142,22 @@
MokoDialerPrivate *priv;
struct lgsm_addr addr;
+ struct lgsm_handle *handle;
MokoContactEntry *entry = NULL;
+ PhoneKitDialerStatus status;
g_return_val_if_fail (MOKO_IS_DIALER (dialer), FALSE);
g_return_val_if_fail (number != NULL, FALSE);
priv = dialer->priv;
+ status = priv->status;
g_debug ("Received dial request: %s", number);
-
- if (!priv->handle) dialer_init_gsmd (dialer);
-
- if (!priv->handle)
- {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_GSMD, "Could not connect to gsmd");
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, error))
return FALSE;
- }
/* check current dialer state */
- if (0 || priv->status != DIALER_STATUS_NORMAL)
+ if (0 || priv->status != PK_DIALER_NORMAL)
{
gchar *strings[] = {
"Normal",
@@ -167,7 +172,7 @@
return FALSE;
}
- priv->status = DIALER_STATUS_DIALING;
+ priv->status = PK_DIALER_DIALING;
/* check for network connection */
if (priv->registered != GSMD_NETREG_REG_HOME
@@ -185,10 +190,14 @@
};
g_warning ("Not connected to network.\nCurrent status = %s ", strings[priv->registered]);
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_NOT_CONNECTED, "No Network");
+ *error = g_error_new (PHONE_KIT_NETWORK_ERROR, PK_NETWORK_ERROR_NOT_CONNECTED, "No Network");
/* no point continuing if we're not connected to a network! */
- priv->status = DIALER_STATUS_NORMAL;
+ priv->status = PK_DIALER_NORMAL;
+ if (status != priv->status) {
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
return FALSE;
}
@@ -213,8 +222,13 @@
*/
addr.type = 129;
g_stpcpy (&addr.addr[0], number);
- lgsm_voice_out_init (priv->handle, &addr);
+ lgsm_voice_out_init (handle, &addr);
+ if (status != priv->status) {
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
+
return TRUE;
}
@@ -222,18 +236,14 @@
moko_dialer_hang_up (MokoDialer *dialer, const gchar *message, GError **error)
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
priv = dialer->priv;
g_return_val_if_fail (MOKO_IS_DIALER (dialer), FALSE);
/* check for gsmd connection */
- if (!priv->handle) dialer_init_gsmd (dialer);
-
- if (!priv->handle)
- {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_GSMD, "Could not connect to gsmd");
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, error))
return FALSE;
- }
/* FIXME: Create a dialog and let the user know that another program is
* requesting the connection be dropped, and why ($message).
@@ -254,8 +264,12 @@
moko_dialer_talking (MokoDialer *dialer)
{
g_return_if_fail (MOKO_IS_DIALER (dialer));
- dialer->priv->status = DIALER_STATUS_TALKING;
-
+
+ if (dialer->priv->status == PK_DIALER_TALKING) return;
+
+ dialer->priv->status = PK_DIALER_TALKING;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ dialer->priv->status);
g_signal_emit (G_OBJECT (dialer), dialer_signals[TALKING], 0);
}
@@ -263,13 +277,20 @@
moko_dialer_hung_up (MokoDialer *dialer)
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
- priv->status = DIALER_STATUS_NORMAL;
-
- lgsm_voice_hangup (priv->handle);
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL))
+ return;
+
+ if (priv->status != PK_DIALER_NORMAL) {
+ priv->status = PK_DIALER_NORMAL;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
+ lgsm_voice_hangup (handle);
g_signal_emit (G_OBJECT (dialer), dialer_signals[HUNG_UP], 0);
}
@@ -278,16 +299,24 @@
moko_dialer_rejected (MokoDialer *dialer)
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
- priv->status = DIALER_STATUS_NORMAL;
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL))
+ return;
+ if (priv->status != PK_DIALER_NORMAL) {
+ priv->status = PK_DIALER_NORMAL;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
+
/* Stop the notification */
moko_notify_stop (priv->notify);
- lgsm_voice_hangup (priv->handle);
+ lgsm_voice_hangup (handle);
g_signal_emit (G_OBJECT (dialer), dialer_signals[REJECTED], 0);
}
@@ -296,15 +325,23 @@
on_talking_accept_call (MokoTalking *talking, MokoDialer *dialer)
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
- if (priv->status != DIALER_STATUS_INCOMING)
+ if (priv->status != PK_DIALER_INCOMING)
return;
- lgsm_voice_in_accept (priv->handle);
- priv->status = DIALER_STATUS_TALKING;
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL))
+ return;
+
+ lgsm_voice_in_accept (handle);
+ if (priv->status != PK_DIALER_TALKING) {
+ priv->status = PK_DIALER_TALKING;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
/* Stop the notification */
moko_notify_stop (priv->notify);
@@ -317,13 +354,21 @@
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
- lgsm_voice_hangup (priv->handle);
- priv->status = DIALER_STATUS_NORMAL;
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL))
+ return;
+ lgsm_voice_hangup (handle);
+ if (priv->status != PK_DIALER_NORMAL) {
+ priv->status = PK_DIALER_NORMAL;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
+
/* Finalise and add the journal entry */
if (priv->journal && priv->entry)
{
@@ -345,13 +390,20 @@
on_talking_cancel_call (MokoTalking *talking, MokoDialer *dialer)
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
- lgsm_voice_hangup (priv->handle);
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL))
+ return;
+ lgsm_voice_hangup (handle);
- priv->status = DIALER_STATUS_NORMAL;
+ if (priv->status != PK_DIALER_NORMAL) {
+ priv->status = PK_DIALER_NORMAL;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
g_signal_emit (G_OBJECT (dialer), dialer_signals[HUNG_UP], 0);
}
@@ -391,84 +443,67 @@
MokoDialer *dialer)
{
MokoDialerPrivate *priv;
+ struct lgsm_handle *handle;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL))
+ return;
if ((digit == '+') || (digit == 'w') || (digit == 'p'))
return;
- if (priv->status == DIALER_STATUS_TALKING)
+ if (priv->status == PK_DIALER_TALKING)
{
- lgsm_voice_dtmf (priv->handle, digit);
+ lgsm_voice_dtmf (handle, digit);
}
}
/* Callbacks for gsmd events */
static void
-on_network_registered (MokoDialer *dialer,
+on_network_registered (MokoListener *listener,
+ struct lgsm_handle *handle,
int type,
int lac,
int cell)
{
+ MokoDialer *dialer = (MokoDialer *)listener;
MokoDialerPrivate *priv;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
-
- switch (type)
- {
- case GSMD_NETREG_UNREG:
- case GSMD_NETREG_UNREG_BUSY:
- /* Do nothing */
- g_debug ("Searching for network");
- break;
- case GSMD_NETREG_DENIED:
- /* This may be a pin issue*/
- break;
- case GSMD_NETREG_REG_HOME:
- case GSMD_NETREG_REG_ROAMING:
- g_debug ("Network registered: LocationAreaCode: %x. CellID: %x.", lac, cell);
-
- /* Retrieve details when we switch location/type */
- if ((priv->registered != type) || (priv->gsm_location.lac != lac)) {
- /* Retrieve operator name */
- lgsm_oper_get (priv->handle);
-
- /* Retrieve operator list to get current country code */
- lgsm_opers_get (priv->handle);
-
- /* Retrieve IMSI to get home country code */
- lgsm_get_imsi (priv->handle);
- }
-
- priv->gsm_location.lac = lac;
- priv->gsm_location.cid = cell;
-
- break;
- default:
- g_warning ("Unhandled register event type = %d\n", type);
- };
-
+
+ if ((type == GSMD_NETREG_REG_HOME) || (type == GSMD_NETREG_REG_ROAMING)) {
+ priv->gsm_location.lac = lac;
+ priv->gsm_location.cid = cell;
+ }
+
priv->registered = type;
}
static void
-on_incoming_call (MokoDialer *dialer, int type)
+on_incoming_call (MokoListener *listener, struct lgsm_handle *handle,
+ int type)
{
+ MokoDialer *dialer = (MokoDialer *)listener;
MokoDialerPrivate *priv;
g_return_if_fail (MOKO_IS_DIALER (dialer));
priv = dialer->priv;
/* We sometimes get the signals multiple times */
- if (priv->status == DIALER_STATUS_INCOMING
- || priv->status == DIALER_STATUS_TALKING)
+ if (priv->status == PK_DIALER_INCOMING
+ || priv->status == PK_DIALER_TALKING)
{
g_debug ("We are already showing the incoming page");
return;
}
- priv->status = DIALER_STATUS_INCOMING;
+
+ if (priv->status != PK_DIALER_INCOMING) {
+ priv->status = PK_DIALER_INCOMING;
+ g_signal_emit (G_OBJECT (dialer), dialer_signals[STATUS_CHANGED], 0,
+ priv->status);
+ }
if (priv->incoming_clip)
g_free (priv->incoming_clip);
@@ -492,8 +527,10 @@
}
static void
-on_incoming_clip (MokoDialer *dialer, const gchar *number)
+on_incoming_clip (MokoListener *listener, struct lgsm_handle *handle,
+ const gchar *number)
{
+ MokoDialer *dialer = (MokoDialer *)listener;
MokoDialerPrivate *priv;
MokoContactEntry *entry;
@@ -522,44 +559,15 @@
g_debug ("Incoming Number = %s", number);
}
-static gboolean
-register_to_network (MokoDialer *dialer)
-{
- g_return_val_if_fail (MOKO_IS_DIALER (dialer), FALSE);
-
- lgsm_netreg_register (dialer->priv->handle, "");
- return FALSE;
-}
-
static void
-on_pin_requested (MokoDialer *dialer, int type)
+on_call_progress (MokoListener *listener, struct lgsm_handle *handle,
+ int type)
{
+ MokoDialer *dialer = (MokoDialer *)listener;
MokoDialerPrivate *priv;
- gchar *pin;
g_return_if_fail (MOKO_IS_DIALER (dialer));
- g_debug ("Pin Requested");
priv = dialer->priv;
-
- pin = get_pin_from_user ();
- if (!pin)
- return;
-
- lgsm_pin (priv->handle, 1, pin, NULL);
- g_free (pin);
-
- /* temporary delay before we try registering
- * FIXME: this should check if pin was OK */
- g_timeout_add_seconds (1, (GSourceFunc) register_to_network, dialer);
-}
-
-static void
-on_call_progress_changed (MokoDialer *dialer, int type)
-{
- MokoDialerPrivate *priv;
-
- g_return_if_fail (MOKO_IS_DIALER (dialer));
- priv = dialer->priv;
switch (type)
{
@@ -571,7 +579,7 @@
priv->time = moko_time_new_today ();
moko_journal_entry_set_dtend (priv->entry, priv->time);
- if (priv->status == DIALER_STATUS_INCOMING)
+ if (priv->status == PK_DIALER_INCOMING)
{
moko_journal_entry_set_dtstart (priv->entry, priv->time);
moko_journal_voice_info_set_was_missed (priv->entry, TRUE);
@@ -599,7 +607,7 @@
break;
case GSMD_CALLPROG_CONNECTED:
- if (priv->status != DIALER_STATUS_TALKING)
+ if (priv->status != PK_DIALER_TALKING)
moko_dialer_talking (dialer);
moko_talking_accepted_call (MOKO_TALKING (priv->talking), NULL, NULL);
@@ -643,21 +651,6 @@
dialer = MOKO_DIALER (object);
priv = dialer->priv;
- if (priv->handle) {
- lgsm_exit (priv->handle);
- priv->handle = NULL;
- }
-
- if (priv->source) {
- g_source_destroy ((GSource *)priv->source);
- priv->source = NULL;
- }
-
- if (priv->sms_store) {
- g_object_unref (priv->sms_store);
- priv->sms_store = NULL;
- }
-
/* Close journal */
if (priv->journal)
{
@@ -665,6 +658,7 @@
moko_journal_close (priv->journal);
priv->journal = NULL;
}
+
G_OBJECT_CLASS (moko_dialer_parent_class)->dispose (object);
}
@@ -677,11 +671,6 @@
dialer = MOKO_DIALER (object);
priv = dialer->priv;
- g_free (priv->own_number);
- g_free (priv->network_name);
- g_free (priv->network_number);
- g_free (priv->imsi);
-
G_OBJECT_CLASS (moko_dialer_parent_class)->finalize (object);
}
@@ -692,9 +681,32 @@
{
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
+ obj_class->get_property = moko_dialer_get_property;
+ obj_class->set_property = moko_dialer_set_property;
obj_class->finalize = moko_dialer_finalize;
obj_class->dispose = moko_dialer_dispose;
+ /* Add class properties */
+ g_object_class_install_property (obj_class,
+ PROP_STATUS,
+ g_param_spec_int (
+ "status",
+ "PhoneKitDialerStatus",
+ "The current SMS status.",
+ PK_DIALER_NORMAL,
+ PK_DIALER_TALKING,
+ PK_DIALER_NORMAL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (obj_class,
+ PROP_NETWORK,
+ g_param_spec_object (
+ "network",
+ "MokoNetwork *",
+ "The parent MokoNetwork object.",
+ MOKO_TYPE_NETWORK,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
/* add class signals */
dialer_signals[INCOMING_CALL] =
g_signal_new ("incoming_call",
@@ -743,410 +755,33 @@
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ dialer_signals[STATUS_CHANGED] =
+ g_signal_new ("status_changed",
+ G_TYPE_FROM_CLASS (obj_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MokoDialerClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1, G_TYPE_INT);
+
g_type_class_add_private (obj_class, sizeof (MokoDialerPrivate));
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
&dbus_glib_moko_dialer_object_info);
}
static void
-status_report_added_cb (JanaStoreView *view, GList *components, gchar *ref)
+listener_interface_init (gpointer g_iface, gpointer iface_data)
{
- MokoDialerPrivate *priv = moko_dialer_get_default ()->priv;
-
- for (; components; components = components->next) {
- gchar *compref;
- JanaComponent *comp = JANA_COMPONENT (components->data);
-
- compref = jana_component_get_custom_prop (
- comp, "X-PHONEKIT-SMS-REF");
- if (compref && (strcmp (compref, ref) == 0)) {
- jana_utils_component_remove_category (comp, "Sending");
- jana_utils_component_insert_category (comp, "Sent", 0);
- jana_store_modify_component (priv->sms_store, comp);
- g_debug ("Setting message status to confirmed sent");
- }
- g_free (ref);
- }
-}
-
-static void
-status_report_progress_cb (JanaStoreView *view, gint percent, gchar *ref)
-{
- if (percent != 100) return;
+ MokoListenerInterface *iface = (MokoListenerInterface *)g_iface;
- g_object_unref (view);
- g_free (ref);
+ iface->on_network_registered = on_network_registered;
+ iface->on_incoming_call = on_incoming_call;
+ iface->on_incoming_clip = on_incoming_clip;
+ iface->on_call_progress = on_call_progress;
}
static void
-store_sms (MokoDialer *dialer, struct gsmd_sms_list *sms)
-{
- gchar *message;
-
- MokoDialerPrivate *priv = dialer->priv;
-
- /* Return if we haven't opened the journal yet - signals will be re-fired
- * when the journal is opened anyway.
- */
- if (!priv->sms_store_open) return;
-
- /* Ignore voicemail notifications */
- if (sms->payload.is_voicemail) return;
-
- /* TODO: Verify type of message for journal (sent/received) -
- * Assuming received for now, as messages sent with phone-kit
- * will be marked already.
- */
- message = NULL;
- switch (sms->payload.coding_scheme) {
- case ALPHABET_DEFAULT :
- g_debug ("Decoding 7-bit ASCII message");
- message = g_malloc0 (GSMD_SMS_DATA_MAXLEN);
- unpacking_7bit_character (&sms->payload, message);
- break;
- case ALPHABET_8BIT :
- /* TODO: Verify: Is this encoding just UTF-8? (it is on my Samsung phone) */
- g_debug ("Decoding UTF-8 message");
- message = g_strdup (sms->payload.data);
- break;
- case ALPHABET_UCS2 :
- g_debug ("Decoding UCS-2 message");
- message = g_utf16_to_utf8 ((const gunichar2 *)sms->payload.data,
- sms->payload.length, NULL, NULL, NULL);
- break;
- }
-
- /* Store message in the journal */
- if (message) {
- struct lgsm_sms_delete sms_del;
- gchar *author;
- JanaNote *note = jana_ecal_note_new ();
-
- g_debug ("Moving message to journal:\n\"%s\"", message);
-
- author = g_strconcat (((sms->addr.type & __GSMD_TOA_TON_MASK) ==
- GSMD_TOA_TON_INTERNATIONAL) ? "+" : "",
- sms->addr.number, NULL);
- jana_note_set_author (note, author);
- g_free (author);
-
- jana_note_set_recipient (note, priv->own_number);
-
- jana_note_set_body (note, message);
-
- /* TODO: Set creation time from SMS timestamp */
-
- /* Add SMS to store */
- jana_store_add_component (priv->sms_store, JANA_COMPONENT (note));
-
- /* Delete SMS from internal storage */
- sms_del.index = sms->index;
- sms_del.delflg = LGSM_SMS_DELFLG_INDEX;
- lgsm_sms_delete (priv->handle, &sms_del);
-
- g_free (message);
- }
-}
-
-static int
-gsmd_eventhandler (struct lgsm_handle *lh, int evt_type,
- struct gsmd_evt_auxdata *aux)
-{
- MokoDialer *dialer = moko_dialer_get_default ();
- MokoDialerPrivate *priv = dialer->priv;
-
- switch (evt_type) {
- case GSMD_EVT_IN_CALL :
- on_incoming_call (dialer, aux->u.call.type);
- break;
- case GSMD_EVT_IN_SMS : /* Incoming SMS */
- /* TODO: Read UDH for multi-part messages */
- g_debug ("Received incoming SMS");
- if (aux->u.sms.inlined) {
- struct gsmd_sms_list * sms = (struct gsmd_sms_list *)aux->data;
- g_debug ("Message inline");
- store_sms (dialer, sms);
- } else {
- g_debug ("Message stored on SIM, reading...");
- lgsm_sms_read (lh, aux->u.sms.index);
- }
- break;
- case GSMD_EVT_IN_DS : /* SMS status report */
- if (aux->u.ds.inlined) {
- struct gsmd_sms_list *sms = (struct gsmd_sms_list *) aux->data;
-
- /* TODO: I'm not entirely sure of the spec when if
- * storing an unsent message means it failed?
- */
- if (sms->payload.coding_scheme == LGSM_SMS_STO_SENT) {
- gchar *ref = g_strdup_printf ("%d", sms->index);
- JanaStoreView *view = jana_store_get_view (priv->sms_store);
-
- g_debug ("Received sent SMS status report");
- jana_store_view_add_match (view, JANA_STORE_VIEW_CATEGORY, "Sending");
- g_signal_connect (view, "added",
- G_CALLBACK (status_report_added_cb), ref);
- g_signal_connect (view, "progress",
- G_CALLBACK (status_report_progress_cb), ref);
- }
- } else {
- g_warning ("Not an in-line event, unhandled");
- }
- break;
- case GSMD_EVT_IN_CLIP :
- on_incoming_clip (dialer, aux->u.clip.addr.number);
- break;
- case GSMD_EVT_NETREG :
- on_network_registered (dialer, aux->u.netreg.state,
- aux->u.netreg.lac, aux->u.netreg.ci);
- break;
- case GSMD_EVT_PIN :
- on_pin_requested (dialer, aux->u.pin.type);
- break;
- case GSMD_EVT_OUT_STATUS :
- on_call_progress_changed (dialer, aux->u.call_status.prog);
- break;
- default :
- g_warning ("Unhandled gsmd event (%d)", evt_type);
- }
-
- return 0;
-}
-
-static int
-sms_msghandler (struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
-{
- MokoDialer *dialer = moko_dialer_get_default ();
- MokoDialerPrivate *priv = dialer->priv;
-
- /* Store sent messages */
- if ((gmh->msg_subtype == GSMD_SMS_SEND) && priv->last_msg) {
- int *result = (int *) ((void *) gmh + sizeof(*gmh));
- gchar *uid = jana_component_get_uid (
- JANA_COMPONENT (priv->last_msg));
-
- if (*result >= 0) {
- gchar *ref = g_strdup_printf ("%d", *result);
- jana_component_set_custom_prop (JANA_COMPONENT (priv->last_msg),
- "X-PHONEKIT-SMS-REF", ref);
- g_free (ref);
- g_debug ("Sent message accepted");
- } else {
- g_debug ("Sent message rejected");
- jana_utils_component_remove_category (JANA_COMPONENT(priv->last_msg),
- "Sending");
- jana_utils_component_insert_category (JANA_COMPONENT(priv->last_msg),
- "Rejected", 0);
- /* TODO: Add error codes? 42 = congestion? */
- }
- jana_store_modify_component (priv->sms_store,
- JANA_COMPONENT (priv->last_msg));
-
- g_free (uid);
- g_object_unref (priv->last_msg);
- priv->last_msg = NULL;
- } else if ((gmh->msg_subtype == GSMD_SMS_LIST) ||
- (gmh->msg_subtype == GSMD_SMS_READ)) {
- struct gsmd_sms_list *sms_list = (struct gsmd_sms_list *)
- ((void *) gmh + sizeof(*gmh));
-
- g_debug ("Storing message on SIM");
- store_sms (dialer, sms_list);
- } else {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void
-start_handling_sms (MokoDialer *dialer)
-{
- MokoDialerPrivate *priv = dialer->priv;
-
- /* Register SMS handling callback */
- lgsm_register_handler (priv->handle, GSMD_MSG_SMS, &sms_msghandler);
-
- /* List all messages to move to journal */
- lgsm_sms_list (priv->handle, GSMD_SMS_ALL);
-
- priv->handling_sms = TRUE;
-}
-
-static int
-net_msghandler (struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
-{
- MokoDialer *dialer = moko_dialer_get_default ();
- MokoDialerPrivate *priv = dialer->priv;
-
- const char *oper = (char *) gmh + sizeof(*gmh);
- const struct gsmd_own_number *num = (struct gsmd_own_number *)
- ((void *) gmh + sizeof(*gmh));
- const struct gsmd_msg_oper *opers = (struct gsmd_msg_oper *)
- ((void *) gmh + sizeof(*gmh));
-
- switch (gmh->msg_subtype) {
- case GSMD_NETWORK_GET_NUMBER :
- g_free (priv->own_number);
-
- if ((num->addr.number) && (num->addr.number[0] == '0') && (priv->imsi))
- priv->own_number = g_strconcat (moko_dialer_cc_from_mcc (priv->imsi),
- num->addr.number + 1, NULL);
- else
- priv->own_number = g_strdup (num->addr.number);
-
- if ((priv->sms_store_open) && (!priv->handling_sms)) {
- start_handling_sms (dialer);
- }
-
- break;
- case GSMD_NETWORK_OPER_GET :
- g_free (priv->network_name);
- if (oper[0]) priv->network_name = g_strdup (oper);
- else priv->network_name = NULL;
- break;
- case GSMD_NETWORK_OPER_LIST :
- for (; !opers->is_last; opers++) {
- if (opers->stat == GSMD_OPER_CURRENT) {
- g_free (priv->network_number);
- priv->network_number = g_strndup (opers->opname_num,
- sizeof(opers->opname_num));
- break;
- }
- }
- break;
- default :
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-pb_msghandler (struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
-{
- MokoDialer *dialer = moko_dialer_get_default ();
- MokoDialerPrivate *priv = dialer->priv;
-
- switch (gmh->msg_subtype) {
- case GSMD_PHONE_GET_IMSI :
- priv->imsi = g_strdup ((char *)gmh + sizeof (*gmh));
-
- /* Get phone number */
- lgsm_get_subscriber_num (priv->handle);
- break;
- default :
- return -EINVAL;
- }
-
- return 0;
-}
-
-static gboolean
-connection_source_prepare (GSource* self, gint* timeout)
-{
- return FALSE;
-}
-
-static gboolean
-connection_source_check (GSource* source)
-{
- MokoDialerSource *self = (MokoDialerSource *)source;
- return self->pollfd.revents & G_IO_IN;
-}
-
-static gboolean
-connection_source_dispatch (GSource *source, GSourceFunc callback,
- gpointer data)
-{
- char buf[1025];
- int size;
-
- MokoDialerSource *self = (MokoDialerSource *)source;
-
- size = read (self->pollfd.fd, &buf, sizeof(buf));
- if (size < 0) {
- g_warning ("moko_gsmd_connection_source_dispatch:%s %s",
- "read error from libgsmd:", strerror (errno));
- } else {
- if (size == 0) /* EOF */
- return FALSE;
- lgsm_handle_packet (self->handle, buf, size);
- }
-
- return TRUE;
-}
-
-static void
-sms_store_opened_cb (JanaStore *store, MokoDialer *self)
-{
- MokoDialerPrivate *priv = self->priv;
- priv->sms_store_open = TRUE;
-
- g_debug ("SMS store opened");
-
- if (priv->handle && priv->own_number) {
- start_handling_sms (self);
- }
-}
-
-static void
-dialer_init_gsmd (MokoDialer *dialer)
-{
- static GSourceFuncs funcs = {
- connection_source_prepare,
- connection_source_check,
- connection_source_dispatch,
- NULL,
- };
-
- MokoDialerPrivate *priv;
- priv = dialer->priv;
-
- /* Get a gsmd handle */
- if (!(priv->handle = lgsm_init (LGSMD_DEVICE_GSMD))) {
- g_warning ("Error connecting to gsmd");
- return;
- }
-
- /* Add event handlers */
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_CALL, gsmd_eventhandler);
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_CLIP, gsmd_eventhandler);
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_SMS, gsmd_eventhandler);
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_DS, gsmd_eventhandler);
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_NETREG, gsmd_eventhandler);
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_OUT_STATUS, gsmd_eventhandler);
- lgsm_evt_handler_register (priv->handle, GSMD_EVT_PIN, gsmd_eventhandler);
- lgsm_register_handler (priv->handle, GSMD_MSG_NETWORK, &net_msghandler);
- lgsm_register_handler (priv->handle, GSMD_MSG_PHONEBOOK, &pb_msghandler);
-
- /* Power the gsm modem up */
- if (lgsm_phone_power (priv->handle, 1) < 0) {
- g_warning ("Error powering up gsm modem");
- lgsm_exit (priv->handle);
- priv->handle = NULL;
- return;
- }
-
- /* Register with network */
- priv->registered = GSMD_NETREG_UNREG;
- lgsm_netreg_register (priv->handle, "");
-
- /* Get phone number */
- lgsm_get_subscriber_num (priv->handle);
-
- /* Start polling for events */
- priv->source = (MokoDialerSource *)
- g_source_new (&funcs, sizeof (MokoDialerSource));
- priv->source->handle = priv->handle;
- priv->source->pollfd.fd = lgsm_fd (priv->handle);
- priv->source->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- priv->source->pollfd.revents = 0;
- g_source_add_poll ((GSource*)priv->source, &priv->source->pollfd);
- g_source_attach ((GSource*)priv->source, NULL);
-}
-
-static void
moko_dialer_init (MokoDialer *dialer)
{
MokoDialerPrivate *priv;
@@ -1154,7 +789,7 @@
priv = dialer->priv = MOKO_DIALER_GET_PRIVATE (dialer);
/* create the dialer_data struct */
- priv->status = DIALER_STATUS_NORMAL;
+ priv->status = PK_DIALER_NORMAL;
/* clear incoming clip */
priv->incoming_clip = NULL;
@@ -1162,8 +797,6 @@
/* Initialise the contacts list */
//contact_init_contact_data (&(priv->data->g_contactlist));
- dialer_init_gsmd (dialer);
-
/* Set up the journal */
priv->journal = moko_journal_open_default ();
if (!priv->journal || !moko_journal_load_from_storage (priv->journal))
@@ -1174,12 +807,6 @@
else
g_debug ("Journal Loaded");
- /* Get the SMS note store */
- priv->sms_store = jana_ecal_store_new (JANA_COMPONENT_NOTE);
- g_signal_connect (priv->sms_store, "opened",
- G_CALLBACK (sms_store_opened_cb), dialer);
- jana_store_open (priv->sms_store);
-
/* Load the contacts store */
priv->contacts = moko_contacts_get_default ();
@@ -1206,236 +833,14 @@
}
MokoDialer*
-moko_dialer_get_default (void)
+moko_dialer_get_default (MokoNetwork *network)
{
static MokoDialer *dialer = NULL;
if (dialer)
return dialer;
- dialer = g_object_new (MOKO_TYPE_DIALER, NULL);
+ dialer = g_object_new (MOKO_TYPE_DIALER, "network", network, NULL);
return dialer;
}
-static gboolean
-moko_dialer_check_gsmd (MokoDialer *self, GError **error)
-{
- MokoDialerPrivate *priv = self->priv;
-
- if (!priv->handle) dialer_init_gsmd (self);
-
- if (!priv->handle) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_GSMD,
- "Failed to connect to gsmd");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-moko_dialer_check_registration (MokoDialer *self, GError **error)
-{
- MokoDialerPrivate *priv = self->priv;
-
- if ((priv->registered != GSMD_NETREG_REG_HOME) &&
- (priv->registered != GSMD_NETREG_REG_ROAMING)) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_NOT_CONNECTED,
- "Not registered to a network");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static const gchar *
-moko_dialer_cc_from_mcc (gchar *mcc)
-{
- gint i;
- for (i = 0; mcc_to_dc[i][0]; i++) {
- if (strncmp (mcc, mcc_to_dc[i][0], 3) == 0) {
- return mcc_to_dc[i][1];
- }
- }
-
- return NULL;
-}
-
-gboolean
-moko_dialer_send_sms (MokoDialer *self, const gchar *number,
- const gchar *message, gchar **uid, GError **error)
-{
- MokoDialerPrivate *priv;
- struct lgsm_sms sms;
- gint msg_length, c;
- gboolean ascii;
- JanaNote *note;
- const gchar *dialcode;
-
- g_assert (self && number && message);
-
- if (!moko_dialer_check_gsmd (self, error)) return FALSE;
- if (!moko_dialer_check_registration (self, error)) return FALSE;
- priv = self->priv;
-
- if (!priv->sms_store_open) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_SMS_STORE,
- "SMS store not opened");
- return FALSE;
- }
-
- /* Ask for delivery report */
- sms.ask_ds = 1;
-
- /* Set destination number */
- if (strlen (number) > GSMD_ADDR_MAXLEN + 1) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR,
- PK_DIALER_ERROR_INVALID_NUMBER,
- "Invalid number");
- return FALSE;
- } else {
- strcpy (sms.addr, number);
- }
-
- /* Set message */
- /* Check if the text is ascii (and pack in 7 bits if so) */
- ascii = TRUE;
- for (c = 0; message[c] != '\0'; c++) {
- if (((guint8)message[c]) > 0x7F) {
- ascii = FALSE;
- break;
- }
- }
-
- /* TODO: Multi-part messages using UDH */
- msg_length = strlen (message);
- if ((ascii && (msg_length > 160)) || (msg_length > 140)) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_SMS_TOOLONG,
- "Message too long");
- return FALSE;
- }
- if (ascii) {
- packing_7bit_character (message, &sms);
- } else {
- sms.alpha = ALPHABET_8BIT;
- strcpy ((gchar *)sms.data, message);
- }
- sms.length = msg_length;
-
- /* Send message */
- lgsm_sms_send (priv->handle, &sms);
-
- /* Store sent message in journal */
- note = jana_ecal_note_new ();
- if ((number[0] == '0') && (priv->network_number) &&
- (dialcode = moko_dialer_cc_from_mcc (priv->network_number))) {
- gchar *full_number = g_strconcat (dialcode, number + 1, NULL);
- jana_note_set_recipient (note, full_number);
- g_free (full_number);
- } else
- jana_note_set_recipient (note, number);
- jana_note_set_author (note, priv->own_number);
-
- jana_note_set_body (note, message);
- jana_component_set_categories (JANA_COMPONENT (note),
- (const gchar *[]){ "Sending", NULL});
-
- jana_store_add_component (priv->sms_store,
- JANA_COMPONENT (note));
- if (uid) *uid = jana_component_get_uid (JANA_COMPONENT (note));
-
- if (priv->last_msg) {
- g_warning ("Confirmation not received for last sent SMS, "
- "delivery report will be lost.");
- g_object_unref (priv->last_msg);
- priv->last_msg = NULL;
- }
- priv->last_msg = note;
-
- return TRUE;
-}
-
-gboolean
-moko_dialer_get_provider_name (MokoDialer *self, gchar **name, GError **error)
-{
- MokoDialerPrivate *priv;
-
- if (!moko_dialer_check_gsmd (self, error)) return FALSE;
- if (!moko_dialer_check_registration (self, error)) return FALSE;
- priv = self->priv;
-
- if (!priv->network_name) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_NO_PROVIDER,
- "No current provider");
- return FALSE;
- }
-
- if (name) *name = g_strdup (priv->network_name);
- return TRUE;
-}
-
-gboolean
-moko_dialer_get_subscriber_number (MokoDialer *self, gchar **number,
- GError **error)
-{
- MokoDialerPrivate *priv;
-
- if (!moko_dialer_check_gsmd (self, error)) return FALSE;
- priv = self->priv;
-
- if (!priv->own_number) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR, PK_DIALER_ERROR_NO_NUMBER,
- "Unable to retrieve subscriber number");
- return FALSE;
- }
-
- if (number) *number = g_strdup (priv->own_number);
- return TRUE;
-}
-
-gboolean
-moko_dialer_get_country_code (MokoDialer *self, gchar **dial_code,
- GError **error)
-{
- MokoDialerPrivate *priv;
-
- if (!moko_dialer_check_gsmd (self, error)) return FALSE;
- if (!moko_dialer_check_registration (self, error)) return FALSE;
- priv = self->priv;
-
- if (!priv->network_number) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR,
- PK_DIALER_ERROR_NO_PROVIDER_NUM,
- "Unable to retrieve provider number");
- return FALSE;
- }
-
- if (dial_code)
- *dial_code = g_strdup (moko_dialer_cc_from_mcc (priv->network_number));
-
- return TRUE;
-}
-
-gboolean
-moko_dialer_get_home_country_code (MokoDialer *self, gchar **dial_code,
- GError **error)
-{
- MokoDialerPrivate *priv;
-
- if (!moko_dialer_check_gsmd (self, error)) return FALSE;
- if (!moko_dialer_check_registration (self, error)) return FALSE;
- priv = self->priv;
-
- if (!priv->network_number) {
- *error = g_error_new (PHONE_KIT_DIALER_ERROR,
- PK_DIALER_ERROR_NO_IMSI,
- "Unable to retrieve IMSI");
- return FALSE;
- }
-
- if (dial_code)
- *dial_code = g_strdup (moko_dialer_cc_from_mcc (priv->imsi));
-
- return TRUE;
-}
-
Modified: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.h 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer.h 2007-12-03 14:49:48 UTC (rev 3553)
@@ -23,6 +23,7 @@
#include <glib.h>
#include <glib-object.h>
+#include "moko-network.h"
G_BEGIN_DECLS
@@ -45,31 +46,22 @@
#define PHONE_KIT_DIALER_ERROR g_quark_from_static_string("phone-kit-dialer")
+typedef struct _MokoDialer MokoDialer;
+typedef struct _MokoDialerClass MokoDialerClass;
+typedef struct _MokoDialerPrivate MokoDialerPrivate;
+
typedef enum {
PK_DIALER_ERROR_BUSY,
- PK_DIALER_ERROR_GSMD,
- PK_DIALER_ERROR_NOT_CONNECTED,
- PK_DIALER_ERROR_SMS_STORE,
- PK_DIALER_ERROR_SMS_TOOLONG,
- PK_DIALER_ERROR_NO_PROVIDER,
- PK_DIALER_ERROR_NO_PROVIDER_NUM,
- PK_DIALER_ERROR_NO_IMSI,
- PK_DIALER_ERROR_NO_NUMBER,
PK_DIALER_ERROR_INVALID_NUMBER,
} PhoneKitDialerError;
-typedef struct _MokoDialer MokoDialer;
-typedef struct _MokoDialerClass MokoDialerClass;
-typedef struct _MokoDialerPrivate MokoDialerPrivate;
+typedef enum {
+ PK_DIALER_NORMAL,
+ PK_DIALER_INCOMING,
+ PK_DIALER_DIALING,
+ PK_DIALER_TALKING,
+} PhoneKitDialerStatus;
-enum
-{
- DIALER_STATUS_NORMAL=0,
- DIALER_STATUS_INCOMING,
- DIALER_STATUS_DIALING,
- DIALER_STATUS_TALKING
-};
-
struct _MokoDialer
{
GObject parent;
@@ -84,6 +76,7 @@
GObjectClass parent_class;
/* signals */
+ void (*status_changed) (MokoDialer *dialer, PhoneKitDialerStatus status);
/* Initiating a connection */
void (*incoming_call) (MokoDialer *dialer, const gchar *number);
@@ -108,7 +101,7 @@
GType moko_dialer_get_type (void) G_GNUC_CONST;
MokoDialer*
-moko_dialer_get_default (void);
+moko_dialer_get_default (MokoNetwork *network);
gboolean
moko_dialer_show_dialer (MokoDialer *dialer, GError **error);
@@ -116,6 +109,11 @@
gboolean
moko_dialer_show_missed_calls (MokoDialer *dialer, GError **error);
+PhoneKitDialerStatus
+moko_dialer_get_status (MokoDialer *dialer);
+
+/* Dialer interface */
+
gboolean
moko_dialer_dial (MokoDialer *dialer, const gchar *number, GError **error);
@@ -131,25 +129,6 @@
void
moko_dialer_rejected (MokoDialer *dialer);
-gboolean
-moko_dialer_send_sms (MokoDialer *self, const gchar *number,
- const gchar *message, gchar **uid, GError **error);
-
-gboolean
-moko_dialer_get_provider_name (MokoDialer *self, gchar **name, GError **error);
-
-gboolean
-moko_dialer_get_subscriber_number (MokoDialer *self, gchar **number,
- GError **error);
-
-gboolean
-moko_dialer_get_country_code (MokoDialer *self, gchar **dial_code,
- GError **error);
-
-gboolean
-moko_dialer_get_home_country_code (MokoDialer *self, gchar **dial_code,
- GError **error);
-
G_END_DECLS
#endif /* _HAVE_MOKO_DIALER_H */
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.c 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.c 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,170 @@
+/*
+ * moko-listener; An interface for listening to libgsmd events
+ *
+ * Authored by OpenedHand Ltd <info at openedhand.com>
+ *
+ * Copyright (C) 2006-2007 OpenMoko Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser Public License as published by
+ * the Free Software Foundation; version 2 of the license.
+ *
+ * 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 Lesser Public License for more details.
+ *
+ * Current Version: $Rev$ ($Date$) [$Author$]
+ */
+
+#include "moko-listener.h"
+
+static void
+moko_listener_base_init (gpointer g_class)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ /* create interface signals here. */
+ initialized = TRUE;
+ }
+}
+
+GType
+moko_listener_get_type (void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof (MokoListenerInterface),
+ moko_listener_base_init, /* base_init */
+ NULL,
+
+ };
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "MokoListener", &info, 0);
+ }
+ return type;
+}
+
+void
+moko_listener_on_network_registered (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int type,
+ int lac,
+ int cell)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_network_registered)
+ interface->on_network_registered (listener, handle, type, lac, cell);
+}
+
+void
+moko_listener_on_pin_requested (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int type)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_pin_requested)
+ interface->on_pin_requested (listener, handle, type);
+}
+
+void
+moko_listener_on_network_name (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *name)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_network_name)
+ interface->on_network_name (listener, handle, name);
+}
+
+void
+moko_listener_on_network_list (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_msg_oper *opers)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_network_list)
+ interface->on_network_list (listener, handle, opers);
+}
+
+void
+moko_listener_on_imsi (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *imsi)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_imsi)
+ interface->on_imsi (listener, handle, imsi);
+}
+
+void
+moko_listener_on_subscriber_number (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *number)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_subscriber_number)
+ interface->on_subscriber_number (listener, handle, number);
+}
+
+void
+moko_listener_on_incoming_call (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int type)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_incoming_call)
+ interface->on_incoming_call (listener, handle, type);
+}
+
+void
+moko_listener_on_incoming_clip (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *number)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_incoming_clip)
+ interface->on_incoming_clip (listener, handle, number);
+}
+
+void
+moko_listener_on_call_progress (MokoListener *listener,
+ struct lgsm_handle *handle, int type)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_call_progress)
+ interface->on_call_progress (listener, handle, type);
+}
+
+void
+moko_listener_on_incoming_sms (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_incoming_sms)
+ interface->on_incoming_sms (listener, handle, sms);
+}
+
+void
+moko_listener_on_incoming_ds (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_incoming_ds)
+ interface->on_incoming_ds (listener, handle, sms);
+}
+
+void
+moko_listener_on_send_sms (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int result)
+{
+ MokoListenerInterface *interface = MOKO_LISTENER_GET_INTERFACE (listener);
+ if (interface->on_send_sms)
+ interface->on_send_sms (listener, handle, result);
+}
+
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.h 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-listener.h 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,118 @@
+/*
+ * moko-listener; An interface for listening to libgsmd events
+ *
+ * Authored by OpenedHand Ltd <info at openedhand.com>
+ *
+ * Copyright (C) 2006-2007 OpenMoko Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser Public License as published by
+ * the Free Software Foundation; version 2 of the license.
+ *
+ * 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 Lesser Public License for more details.
+ *
+ * Current Version: $Rev$ ($Date$) [$Author$]
+ */
+
+#ifndef MOKO_LISTENER_H
+#define MOKO_LISTENER_H
+
+#include <glib-object.h>
+#include <libgsmd/libgsmd.h>
+#include <libgsmd/event.h>
+#include <libgsmd/misc.h>
+#include <libgsmd/sms.h>
+#include <libgsmd/voicecall.h>
+#include <libgsmd/phonebook.h>
+#include <gsmd/usock.h>
+
+#define MOKO_TYPE_LISTENER (moko_listener_get_type ())
+#define MOKO_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+ MOKO_TYPE_LISTENER, MokoListener))
+#define MOKO_IS_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ MOKO_TYPE_LISTENER))
+#define MOKO_LISTENER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst),\
+ MOKO_TYPE_LISTENER, MokoListenerInterface))
+
+typedef struct _MokoListener MokoListener; /* Dummy object */
+typedef struct _MokoListenerInterface MokoListenerInterface;
+
+struct _MokoListenerInterface {
+ GTypeInterface parent;
+
+ void (*on_network_registered) (MokoListener *listener,
+ struct lgsm_handle *handle, int type,
+ int lac, int cell);
+ void (*on_pin_requested) (MokoListener *listener,
+ struct lgsm_handle *handle, int type);
+ void (*on_network_name) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *name);
+ void (*on_network_list) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_msg_oper *opers);
+ void (*on_imsi) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *imsi);
+ void (*on_subscriber_number) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *number);
+ void (*on_incoming_call) (MokoListener *listener,
+ struct lgsm_handle *handle, int type);
+ void (*on_incoming_clip) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *number);
+ void (*on_call_progress) (MokoListener *listener,
+ struct lgsm_handle *handle, int type);
+ void (*on_incoming_sms) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms);
+ void (*on_incoming_ds) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms);
+ void (*on_send_sms) (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int result);
+};
+
+GType moko_listener_get_type (void);
+
+void moko_listener_on_network_registered (MokoListener *listener,
+ struct lgsm_handle *handle, int type,
+ int lac, int cell);
+void moko_listener_on_pin_requested (MokoListener *listener,
+ struct lgsm_handle *handle, int type);
+void moko_listener_on_network_name (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *name);
+void moko_listener_on_network_list (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_msg_oper *opers);
+void moko_listener_on_imsi (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *imsi);
+void moko_listener_on_subscriber_number (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *number);
+void moko_listener_on_incoming_call (MokoListener *listener,
+ struct lgsm_handle *handle, int type);
+void moko_listener_on_incoming_clip (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const gchar *number);
+void moko_listener_on_call_progress (MokoListener *listener,
+ struct lgsm_handle *handle, int type);
+void moko_listener_on_incoming_sms (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms);
+void moko_listener_on_incoming_ds (MokoListener *listener,
+ struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms);
+void moko_listener_on_send_sms (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int result);
+
+#endif /* MOKO_LISTENER_H */
+
Copied: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-mcc-dc.h (from rev 3524, trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-dialer-mcc-dc.h)
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network-dbus.xml
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network-dbus.xml 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network-dbus.xml 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<node name="/org/openmoko/PhoneKit">
+<interface name="org.openmoko.PhoneKit.Network">
+<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="moko_network"/>
+
+ <property name="Status" type="i" access="read" />
+
+ <method name="GetProviderName">
+ <arg type="s" name="name" direction="out" />
+ </method>
+
+ <method name="GetSubscriberNumber">
+ <arg type="s" name="number" direction="out" />
+ </method>
+
+ <method name="GetCountryCode">
+ <arg type="s" name="dial_code" direction="out" />
+ </method>
+
+ <method name="GetHomeCountryCode">
+ <arg type="s" name="dial_code" direction="out" />
+ </method>
+
+ <signal name="SubscriberNumberChanged">
+ <arg type="s" name="number" />
+ </signal>
+
+ <signal name="ProviderChanged">
+ <arg type="s" name="name" />
+ </signal>
+
+ <signal name="StatusChanged">
+ <arg type="i" name="status" />
+ </signal>
+
+</interface>
+</node>
+
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.c 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.c 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,818 @@
+/*
+ * moko-network; a GObject wrapper for phone-kit that exports method and
+ * signals over dbus relating to GSM network status and properties
+ *
+ * Authored by OpenedHand Ltd <info at openedhand.com>
+ *
+ * Copyright (C) 2006-2007 OpenMoko Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser Public License as published by
+ * the Free Software Foundation; version 2 of the license.
+ *
+ * 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 Lesser Public License for more details.
+ *
+ * Current Version: $Rev$ ($Date$) [$Author$]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "moko-network.h"
+#include "moko-pin.h"
+
+#include "moko-mcc-dc.h"
+
+static void
+listener_interface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (MokoNetwork, moko_network, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MOKO_TYPE_LISTENER,
+ listener_interface_init))
+
+#define MOKO_NETWORK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
+ MOKO_TYPE_NETWORK, MokoNetworkPrivate))
+
+enum {
+ PROP_STATUS = 1,
+};
+
+enum
+{
+ STATUS_CHANGED,
+ SUBSCRIBER_CHANGED,
+ PROVIDER_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0, };
+
+typedef struct {
+ GSource source;
+ GPollFD pollfd;
+ struct lgsm_handle *handle;
+} MokoNetworkSource;
+
+struct _MokoNetworkPrivate
+{
+ gchar *own_number;
+ gchar *network_name;
+ gchar *network_number;
+ gchar *imsi;
+
+ /* gsmd connection variables */
+ struct lgsm_handle *handle;
+ MokoNetworkSource *source;
+ int lac;
+
+ /* Registration variables */
+ enum lgsm_netreg_state registered;
+ gboolean pin_requested;
+
+ /* List of listeners */
+ GList *listeners;
+};
+
+static void network_init_gsmd (MokoNetwork *network);
+
+static const gchar *moko_network_cc_from_mcc (gchar *mcc);
+
+static void
+moko_network_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_STATUS :
+ g_value_set_int (value, moko_network_get_status (MOKO_NETWORK (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+/* Callbacks for gsmd events */
+static void
+on_network_registered (MokoListener *listener,
+ struct lgsm_handle *handle,
+ int type,
+ int lac,
+ int cell)
+{
+ MokoNetworkPrivate *priv;
+
+ g_return_if_fail (MOKO_IS_NETWORK (listener));
+ priv = MOKO_NETWORK (listener)->priv;
+
+ switch (type)
+ {
+ case GSMD_NETREG_UNREG:
+ case GSMD_NETREG_UNREG_BUSY:
+ /* Do nothing */
+ g_debug ("Searching for network");
+ break;
+ case GSMD_NETREG_DENIED:
+ /* This may be a pin issue*/
+ break;
+ case GSMD_NETREG_REG_HOME:
+ case GSMD_NETREG_REG_ROAMING:
+ g_debug ("Network registered: LocationAreaCode: %x. CellID: %x.", lac, cell);
+
+ /* Retrieve details when we switch location/type */
+ if ((priv->registered != type) || (priv->lac != lac)) {
+ priv->lac = lac;
+
+ /* Retrieve operator name */
+ lgsm_oper_get (handle);
+
+ /* Retrieve operator list to get current country code */
+ lgsm_opers_get (handle);
+
+ /* Retrieve IMSI to get home country code */
+ lgsm_get_imsi (handle);
+ }
+
+ break;
+ default:
+ g_warning ("Unhandled register event type = %d\n", type);
+ };
+
+ if (priv->registered != type) {
+ priv->registered = type;
+ g_signal_emit (listener, signals[STATUS_CHANGED], 0,
+ moko_network_get_status (MOKO_NETWORK (listener)));
+ }
+}
+
+static gboolean
+register_to_network (MokoNetwork *network)
+{
+ g_return_val_if_fail (MOKO_IS_NETWORK (network), FALSE);
+
+ lgsm_netreg_register (network->priv->handle, "");
+ return FALSE;
+}
+
+static void
+on_pin_requested (MokoListener *listener, struct lgsm_handle *handle,
+ int type)
+{
+ MokoNetworkPrivate *priv;
+ gchar *pin;
+
+ g_return_if_fail (MOKO_IS_NETWORK (listener));
+ priv = MOKO_NETWORK (listener)->priv;
+
+ g_debug ("Pin Requested");
+
+ pin = get_pin_from_user ();
+ if (!pin)
+ return;
+
+ lgsm_pin (handle, 1, pin, NULL);
+ g_free (pin);
+
+ /* temporary delay before we try registering
+ * FIXME: this should check if pin was OK */
+ g_timeout_add_seconds (1, (GSourceFunc) register_to_network, listener);
+}
+
+static void
+on_subscriber_number (MokoListener *listener, struct lgsm_handle *handle,
+ const gchar *number)
+{
+ MokoNetwork *network = MOKO_NETWORK (listener);
+ MokoNetworkPrivate *priv = network->priv;
+
+ g_free (priv->own_number);
+
+ if ((number) && (number[0] == '0') && (priv->imsi))
+ priv->own_number = g_strconcat (moko_network_cc_from_mcc (priv->imsi),
+ number + 1, NULL);
+ else
+ priv->own_number = g_strdup (number);
+
+ g_signal_emit (listener, signals[SUBSCRIBER_CHANGED], 0, priv->own_number);
+}
+
+static void
+on_network_name (MokoListener *listener, struct lgsm_handle *handle,
+ const gchar *name)
+{
+ MokoNetwork *network = MOKO_NETWORK (listener);
+ MokoNetworkPrivate *priv = network->priv;
+
+ if ((!name) && (!priv->network_name))
+ return;
+
+ g_free (priv->network_name);
+ if (name && name[0]) priv->network_name = g_strdup (name);
+ else priv->network_name = NULL;
+
+ g_signal_emit (listener, signals[PROVIDER_CHANGED], 0, priv->network_name);
+}
+
+static void
+on_network_list (MokoListener *listener, struct lgsm_handle *handle,
+ const struct gsmd_msg_oper *opers)
+{
+ MokoNetwork *network = MOKO_NETWORK (listener);
+ MokoNetworkPrivate *priv = network->priv;
+
+ for (; !opers->is_last; opers++) {
+ if (opers->stat == GSMD_OPER_CURRENT) {
+ g_free (priv->network_number);
+ priv->network_number = g_strndup (opers->opname_num,
+ sizeof(opers->opname_num));
+ break;
+ }
+ }
+}
+
+static void
+on_imsi (MokoListener *listener, struct lgsm_handle *handle,
+ const gchar *imsi)
+{
+ MokoNetwork *network = MOKO_NETWORK (listener);
+ MokoNetworkPrivate *priv = network->priv;
+
+ g_free (priv->imsi);
+ priv->imsi = g_strdup (imsi);
+
+ /* Get phone number */
+ lgsm_get_subscriber_num (handle);
+}
+
+/* GObject functions */
+static void
+moko_network_dispose (GObject *object)
+{
+ MokoNetwork *network;
+ MokoNetworkPrivate *priv;
+
+ network = MOKO_NETWORK (object);
+ priv = network->priv;
+
+ if (priv->handle) {
+ lgsm_exit (priv->handle);
+ priv->handle = NULL;
+ }
+
+ if (priv->source) {
+ g_source_destroy ((GSource *)priv->source);
+ priv->source = NULL;
+ }
+
+ G_OBJECT_CLASS (moko_network_parent_class)->dispose (object);
+}
+
+static void
+moko_network_finalize (GObject *object)
+{
+ MokoNetwork *network;
+ MokoNetworkPrivate *priv;
+
+ network = MOKO_NETWORK (object);
+ priv = network->priv;
+
+ g_free (priv->own_number);
+ g_free (priv->network_name);
+ g_free (priv->network_number);
+ g_free (priv->imsi);
+
+ G_OBJECT_CLASS (moko_network_parent_class)->finalize (object);
+}
+
+#include "moko-network-glue.h"
+
+static void
+moko_network_class_init (MokoNetworkClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
+
+ obj_class->get_property = moko_network_get_property;
+ obj_class->finalize = moko_network_finalize;
+ obj_class->dispose = moko_network_dispose;
+
+ /* add class properties */
+ g_object_class_install_property (obj_class,
+ PROP_STATUS,
+ g_param_spec_int (
+ "status",
+ "PhoneKitNetworkStatus",
+ "The current network status.",
+ PK_NETWORK_UNREGISTERED,
+ PK_NETWORK_REGISTERED_ROAMING,
+ PK_NETWORK_UNREGISTERED,
+ G_PARAM_READABLE));
+
+ /* add class signals */
+ signals[STATUS_CHANGED] =
+ g_signal_new ("status_changed",
+ G_TYPE_FROM_CLASS (obj_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MokoNetworkClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1, G_TYPE_INT);
+
+ signals[SUBSCRIBER_CHANGED] =
+ g_signal_new ("subscriber_number_changed",
+ G_TYPE_FROM_CLASS (obj_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MokoNetworkClass, subscriber_number_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
+ signals[PROVIDER_CHANGED] =
+ g_signal_new ("provider_changed",
+ G_TYPE_FROM_CLASS (obj_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MokoNetworkClass, provider_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
+ g_type_class_add_private (obj_class, sizeof (MokoNetworkPrivate));
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_moko_network_object_info);
+}
+
+static void
+listener_interface_init (gpointer g_iface, gpointer iface_data)
+{
+ MokoListenerInterface *iface = (MokoListenerInterface *)g_iface;
+
+ iface->on_network_registered = on_network_registered;
+ iface->on_pin_requested = on_pin_requested;
+ iface->on_network_name = on_network_name;
+ iface->on_network_list = on_network_list;
+ iface->on_imsi = on_imsi;
+ iface->on_subscriber_number = on_subscriber_number;
+}
+
+static int
+gsmd_eventhandler (struct lgsm_handle *lh, int evt_type,
+ struct gsmd_evt_auxdata *aux)
+{
+ GList *l;
+ MokoNetwork *network = moko_network_get_default ();
+ MokoNetworkPrivate *priv = network->priv;
+
+ switch (evt_type) {
+ case GSMD_EVT_IN_CALL :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_incoming_call (MOKO_LISTENER (l->data), priv->handle,
+ aux->u.call.type);
+ }
+ break;
+ case GSMD_EVT_IN_SMS : /* Incoming SMS */
+ g_debug ("Received incoming SMS");
+ if (aux->u.sms.inlined) {
+ struct gsmd_sms_list * sms = (struct gsmd_sms_list *)aux->data;
+ g_debug ("Message inline");
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_incoming_sms (MOKO_LISTENER (l->data), priv->handle,
+ sms);
+ }
+ } else {
+ g_debug ("Message stored on SIM, reading...");
+ lgsm_sms_read (lh, aux->u.sms.index);
+ }
+ break;
+ case GSMD_EVT_IN_DS : /* SMS status report */
+ if (aux->u.ds.inlined) {
+ struct gsmd_sms_list *sms = (struct gsmd_sms_list *) aux->data;
+
+ /* TODO: I'm not entirely sure of the spec when if
+ * storing an unsent message means it failed?
+ */
+ if (sms->payload.coding_scheme == LGSM_SMS_STO_SENT) {
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_incoming_ds (MOKO_LISTENER (l->data), priv->handle,
+ sms);
+ }
+ }
+ } else {
+ g_warning ("Delivery status report not in-line, left unhandled");
+ }
+ break;
+ case GSMD_EVT_IN_CLIP :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_incoming_clip (MOKO_LISTENER (l->data), priv->handle,
+ aux->u.clip.addr.number);
+ }
+ break;
+ case GSMD_EVT_NETREG :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_network_registered (MOKO_LISTENER (l->data),
+ priv->handle, aux->u.netreg.state,
+ aux->u.netreg.lac, aux->u.netreg.ci);
+ }
+ break;
+ case GSMD_EVT_PIN :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_pin_requested (MOKO_LISTENER (l->data), priv->handle,
+ aux->u.pin.type);
+ }
+ break;
+ case GSMD_EVT_OUT_STATUS :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_call_progress (MOKO_LISTENER (l->data), priv->handle,
+ aux->u.call_status.prog);
+ }
+ break;
+ default :
+ g_warning ("Unhandled gsmd event (%d)", evt_type);
+ }
+
+ return 0;
+}
+
+static int
+sms_msghandler (struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+ GList *l;
+ MokoNetwork *network = moko_network_get_default ();
+ MokoNetworkPrivate *priv = network->priv;
+
+ if (gmh->msg_subtype == GSMD_SMS_SEND) {
+ int *result = (int *) ((void *) gmh + sizeof(*gmh));
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_send_sms (MOKO_LISTENER (l->data), priv->handle,
+ *result);
+ }
+ } else if ((gmh->msg_subtype == GSMD_SMS_LIST) ||
+ (gmh->msg_subtype == GSMD_SMS_READ)) {
+ struct gsmd_sms_list *sms_list = (struct gsmd_sms_list *)
+ ((void *) gmh + sizeof(*gmh));
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_incoming_sms (MOKO_LISTENER (l->data), priv->handle,
+ sms_list);
+ }
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+net_msghandler (struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+ GList *l;
+ MokoNetwork *network = moko_network_get_default ();
+ MokoNetworkPrivate *priv = network->priv;
+
+ const char *oper = (char *) gmh + sizeof(*gmh);
+ const struct gsmd_own_number *num = (struct gsmd_own_number *)
+ ((void *) gmh + sizeof(*gmh));
+ const struct gsmd_msg_oper *opers = (struct gsmd_msg_oper *)
+ ((void *) gmh + sizeof(*gmh));
+
+ switch (gmh->msg_subtype) {
+ case GSMD_NETWORK_GET_NUMBER :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_subscriber_number (MOKO_LISTENER (l->data),
+ priv->handle, num->addr.number);
+ }
+ break;
+ case GSMD_NETWORK_OPER_GET :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_network_name (MOKO_LISTENER (l->data),
+ priv->handle, oper);
+ }
+ break;
+ case GSMD_NETWORK_OPER_LIST :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_network_list (MOKO_LISTENER (l->data),
+ priv->handle, opers);
+ }
+ break;
+ default :
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+phone_msghandler (struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh)
+{
+ GList *l;
+ MokoNetwork *network = moko_network_get_default ();
+ MokoNetworkPrivate *priv = network->priv;
+
+ switch (gmh->msg_subtype) {
+ case GSMD_PHONE_GET_IMSI :
+ for (l = priv->listeners; l; l = l->next) {
+ moko_listener_on_imsi (MOKO_LISTENER (l->data), priv->handle,
+ (const gchar *)gmh + sizeof (*gmh));
+ }
+ break;
+ default :
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static gboolean
+connection_source_prepare (GSource* self, gint* timeout)
+{
+ return FALSE;
+}
+
+static gboolean
+connection_source_check (GSource* source)
+{
+ MokoNetworkSource *self = (MokoNetworkSource *)source;
+ return self->pollfd.revents & G_IO_IN;
+}
+
+static gboolean
+connection_source_dispatch (GSource *source, GSourceFunc callback,
+ gpointer data)
+{
+ char buf[1025];
+ int size;
+
+ MokoNetworkSource *self = (MokoNetworkSource *)source;
+
+ size = read (self->pollfd.fd, &buf, sizeof(buf));
+ if (size < 0) {
+ g_warning ("moko_gsmd_connection_source_dispatch:%s %s",
+ "read error from libgsmd:", strerror (errno));
+ } else {
+ if (size == 0) /* EOF */
+ return FALSE;
+ lgsm_handle_packet (self->handle, buf, size);
+ }
+
+ return TRUE;
+}
+
+static void
+network_init_gsmd (MokoNetwork *network)
+{
+ static GSourceFuncs funcs = {
+ connection_source_prepare,
+ connection_source_check,
+ connection_source_dispatch,
+ NULL,
+ };
+
+ MokoNetworkPrivate *priv;
+ priv = network->priv;
+
+ /* Add ourselves as an event listener */
+ /* TODO: Split this file into two classes, MokoBase, MokoNetwork? */
+ moko_network_add_listener (network, MOKO_LISTENER (network));
+
+ /* Get a gsmd handle */
+ if (!(priv->handle = lgsm_init (LGSMD_DEVICE_GSMD))) {
+ g_warning ("Error connecting to gsmd");
+ return;
+ }
+
+ /* Add event handlers */
+ lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_CALL, gsmd_eventhandler);
+ lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_CLIP, gsmd_eventhandler);
+ lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_SMS, gsmd_eventhandler);
+ lgsm_evt_handler_register (priv->handle, GSMD_EVT_IN_DS, gsmd_eventhandler);
+ lgsm_evt_handler_register (priv->handle, GSMD_EVT_NETREG, gsmd_eventhandler);
+ lgsm_evt_handler_register (priv->handle, GSMD_EVT_OUT_STATUS, gsmd_eventhandler);
+ lgsm_register_handler (priv->handle, GSMD_MSG_NETWORK, net_msghandler);
+ lgsm_register_handler (priv->handle, GSMD_MSG_PHONE, phone_msghandler);
+ lgsm_register_handler (priv->handle, GSMD_MSG_SMS, sms_msghandler);
+
+ /* Power the gsm modem up */
+ if (lgsm_phone_power (priv->handle, 1) == -1) {
+ g_warning ("Error powering up gsm modem");
+ lgsm_exit (priv->handle);
+ priv->handle = NULL;
+ return;
+ }
+
+ /* Register with network */
+ priv->registered = GSMD_NETREG_UNREG;
+ lgsm_netreg_register (priv->handle, "");
+
+ /* Get phone number */
+ lgsm_get_subscriber_num (priv->handle);
+
+ /* Start polling for events */
+ priv->source = (MokoNetworkSource *)
+ g_source_new (&funcs, sizeof (MokoNetworkSource));
+ priv->source->handle = priv->handle;
+ priv->source->pollfd.fd = lgsm_fd (priv->handle);
+ priv->source->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ priv->source->pollfd.revents = 0;
+ g_source_add_poll ((GSource*)priv->source, &priv->source->pollfd);
+ g_source_attach ((GSource*)priv->source, NULL);
+}
+
+static void
+moko_network_init (MokoNetwork *network)
+{
+ MokoNetworkPrivate *priv;
+
+ priv = network->priv = MOKO_NETWORK_GET_PRIVATE (network);
+
+ network_init_gsmd (network);
+}
+
+MokoNetwork*
+moko_network_get_default (void)
+{
+ static MokoNetwork *network = NULL;
+ if (network)
+ return network;
+
+ network = g_object_new (MOKO_TYPE_NETWORK, NULL);
+
+ return network;
+}
+
+static gboolean
+moko_network_check_registration (MokoNetwork *self, GError **error)
+{
+ MokoNetworkPrivate *priv = self->priv;
+
+ if ((priv->registered != GSMD_NETREG_REG_HOME) &&
+ (priv->registered != GSMD_NETREG_REG_ROAMING)) {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_NOT_CONNECTED,
+ "Not registered to a network");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static const gchar *
+moko_network_cc_from_mcc (gchar *mcc)
+{
+ gint i;
+ for (i = 0; mcc_to_dc[i][0]; i++) {
+ if (strncmp (mcc, mcc_to_dc[i][0], 3) == 0) {
+ return mcc_to_dc[i][1];
+ }
+ }
+
+ return NULL;
+}
+
+PhoneKitNetworkStatus
+moko_network_get_status (MokoNetwork *network)
+{
+ MokoNetworkPrivate *priv = network->priv;
+
+ switch (priv->registered) {
+ default:
+ case GSMD_NETREG_UNREG:
+ case GSMD_NETREG_UNREG_BUSY:
+ return PK_NETWORK_UNREGISTERED;
+ case GSMD_NETREG_DENIED:
+ return PK_NETWORK_DENIED;
+ case GSMD_NETREG_REG_HOME:
+ return PK_NETWORK_REGISTERED_HOME;
+ case GSMD_NETREG_REG_ROAMING:
+ return PK_NETWORK_REGISTERED_ROAMING;
+ }
+}
+
+gboolean
+moko_network_get_lgsm_handle (MokoNetwork *network, struct lgsm_handle **handle,
+ GError **error)
+{
+ MokoNetworkPrivate *priv = network->priv;
+
+ if (!priv->handle) network_init_gsmd (network);
+
+ if (priv->handle) {
+ if (handle) *handle = priv->handle;
+ return TRUE;
+ } else {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_GSMD,
+ "Failed to connect to gsmd");
+ return FALSE;
+ }
+}
+
+void
+moko_network_add_listener (MokoNetwork *network, MokoListener *listener)
+{
+ MokoNetworkPrivate *priv = network->priv;
+
+ priv->listeners = g_list_prepend (priv->listeners, listener);
+}
+
+void
+moko_network_remove_listener (MokoNetwork *network, MokoListener *listener)
+{
+ MokoNetworkPrivate *priv = network->priv;
+
+ priv->listeners = g_list_remove (priv->listeners, listener);
+}
+
+/* DBus functions */
+gboolean
+moko_network_get_provider_name (MokoNetwork *self, gchar **name, GError **error)
+{
+ MokoNetworkPrivate *priv;
+
+ if (!moko_network_get_lgsm_handle (self, NULL, error)) return FALSE;
+ if (!moko_network_check_registration (self, error)) return FALSE;
+ priv = self->priv;
+
+ if (!priv->network_name) {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_NO_PROVIDER_NAME,
+ "Unable to retrieve provider name");
+ return FALSE;
+ }
+
+ if (name) *name = g_strdup (priv->network_name);
+ return TRUE;
+}
+
+gboolean
+moko_network_get_subscriber_number (MokoNetwork *self, gchar **number,
+ GError **error)
+{
+ MokoNetworkPrivate *priv;
+
+ if (!moko_network_get_lgsm_handle (self, NULL, error)) return FALSE;
+ priv = self->priv;
+
+ if (!priv->own_number) {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_NO_SUBSCRIBER_NUM,
+ "Unable to retrieve subscriber number");
+ return FALSE;
+ }
+
+ if (number) *number = g_strdup (priv->own_number);
+ return TRUE;
+}
+
+gboolean
+moko_network_get_country_code (MokoNetwork *self, gchar **dial_code,
+ GError **error)
+{
+ MokoNetworkPrivate *priv;
+
+ if (!moko_network_get_lgsm_handle (self, NULL, error)) return FALSE;
+ if (!moko_network_check_registration (self, error)) return FALSE;
+ priv = self->priv;
+
+ if (!priv->network_number) {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_NO_PROVIDER_NUM,
+ "Unable to retrieve provider number");
+ return FALSE;
+ }
+
+ if (dial_code)
+ *dial_code = g_strdup (moko_network_cc_from_mcc (priv->network_number));
+
+ return TRUE;
+}
+
+gboolean
+moko_network_get_home_country_code (MokoNetwork *self, gchar **dial_code,
+ GError **error)
+{
+ MokoNetworkPrivate *priv;
+
+ if (!moko_network_get_lgsm_handle (self, NULL, error)) return FALSE;
+ if (!moko_network_check_registration (self, error)) return FALSE;
+ priv = self->priv;
+
+ if (!priv->network_number) {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_NO_IMSI,
+ "Unable to retrieve IMSI");
+ return FALSE;
+ }
+
+ if (dial_code)
+ *dial_code = g_strdup (moko_network_cc_from_mcc (priv->imsi));
+
+ return TRUE;
+}
+
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.h 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-network.h 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,132 @@
+/*
+ * moko-network; a GObject wrapper for phone-kit that exports method and
+ * signals over dbus relating to GSM network status and properties
+ *
+ * Authored by OpenedHand Ltd <info at openedhand.com>
+ *
+ * Copyright (C) 2006-2007 OpenMoko Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser Public License as published by
+ * the Free Software Foundation; version 2 of the license.
+ *
+ * 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 Lesser Public License for more details.
+ *
+ * Current Version: $Rev$ ($Date$) [$Author$]
+ */
+
+#ifndef _HAVE_MOKO_NETWORK_H
+#define _HAVE_MOKO_NETWORK_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libgsmd/libgsmd.h>
+#include "moko-listener.h"
+
+G_BEGIN_DECLS
+
+#define MOKO_TYPE_NETWORK (moko_network_get_type ())
+
+#define MOKO_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ MOKO_TYPE_NETWORK, MokoNetwork))
+
+#define MOKO_NETWORK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ MOKO_TYPE_NETWORK, MokoNetworkClass))
+
+#define MOKO_IS_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ MOKO_TYPE_NETWORK))
+
+#define MOKO_IS_NETWORK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ MOKO_TYPE_NETWORK))
+
+#define MOKO_NETWORK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ MOKO_TYPE_NETWORK, MokoNetworkClass))
+
+#define PHONE_KIT_NETWORK_ERROR g_quark_from_static_string("phone-kit-network")
+
+typedef struct _MokoNetwork MokoNetwork;
+typedef struct _MokoNetworkClass MokoNetworkClass;
+typedef struct _MokoNetworkPrivate MokoNetworkPrivate;
+
+typedef enum {
+ PK_NETWORK_ERROR_GSMD,
+ PK_NETWORK_ERROR_NOT_CONNECTED,
+ PK_NETWORK_ERROR_NO_PROVIDER_NAME,
+ PK_NETWORK_ERROR_NO_PROVIDER_NUM,
+ PK_NETWORK_ERROR_NO_IMSI,
+ PK_NETWORK_ERROR_NO_SUBSCRIBER_NUM,
+} PhoneKitNetworkError;
+
+typedef enum {
+ PK_NETWORK_UNREGISTERED,
+ PK_NETWORK_DENIED,
+ PK_NETWORK_REGISTERED_HOME,
+ PK_NETWORK_REGISTERED_ROAMING,
+} PhoneKitNetworkStatus;
+
+struct _MokoNetwork
+{
+ GObject parent;
+
+ /*< private >*/
+ MokoNetworkPrivate *priv;
+};
+
+struct _MokoNetworkClass
+{
+ /*< private >*/
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*status_changed) (MokoNetwork *network, PhoneKitNetworkStatus status);
+ void (*subscriber_number_changed) (MokoNetwork *network, const gchar *number);
+ void (*provider_changed) (MokoNetwork *network, const gchar *name);
+
+ /* future padding */
+ void (*_moko_network_1) (void);
+ void (*_moko_network_2) (void);
+ void (*_moko_network_3) (void);
+ void (*_moko_network_4) (void);
+};
+
+GType moko_network_get_type (void) G_GNUC_CONST;
+
+MokoNetwork*
+moko_network_get_default (void);
+
+PhoneKitNetworkStatus
+moko_network_get_status (MokoNetwork *network);
+
+gboolean
+moko_network_get_lgsm_handle (MokoNetwork *network, struct lgsm_handle **handle,
+ GError **error);
+
+void
+moko_network_add_listener (MokoNetwork *network, MokoListener *listener);
+
+void
+moko_network_remove_listener (MokoNetwork *network, MokoListener *listener);
+
+/* Network interface */
+gboolean
+moko_network_get_provider_name (MokoNetwork *self, gchar **name, GError **error);
+
+gboolean
+moko_network_get_subscriber_number (MokoNetwork *self, gchar **number,
+ GError **error);
+
+gboolean
+moko_network_get_country_code (MokoNetwork *self, gchar **dial_code,
+ GError **error);
+
+gboolean
+moko_network_get_home_country_code (MokoNetwork *self, gchar **dial_code,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* _HAVE_MOKO_NETWORK_H */
+
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms-dbus.xml
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms-dbus.xml 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms-dbus.xml 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<node name="/org/openmoko/PhoneKit">
+<interface name="org.openmoko.PhoneKit.Sms">
+<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="moko_sms"/>
+
+ <property name="Status" type="i" access="read" />
+
+ <method name="Send">
+ <arg type="s" name="number" />
+ <arg type="s" name="message" />
+ <arg type="s" name="uid" direction="out" />
+ </method>
+
+ <signal name="StatusChanged">
+ <arg type="i" name="status" />
+ </signal>
+
+</interface>
+</node>
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.c
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.c 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.c 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,579 @@
+/*
+ * moko-sms; a GObject wrapper for phone-kit that exports method and
+ * signals over dbus relating to SMS messaging
+ *
+ * Authored by OpenedHand Ltd <info at openedhand.com>
+ *
+ * Copyright (C) 2006-2007 OpenMoko Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser Public License as published by
+ * the Free Software Foundation; version 2 of the license.
+ *
+ * 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 Lesser Public License for more details.
+ *
+ * Current Version: $Rev$ ($Date$) [$Author$]
+ */
+
+#include <string.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libjana/jana.h>
+#include <libjana-ecal/jana-ecal.h>
+
+#include "moko-sms.h"
+#include "moko-network.h"
+#include "moko-listener.h"
+
+static void
+listener_interface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (MokoSms, moko_sms, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MOKO_TYPE_LISTENER,
+ listener_interface_init))
+
+#define MOKO_SMS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
+ MOKO_TYPE_SMS, MokoSmsPrivate))
+
+enum {
+ PROP_STATUS = 1,
+ PROP_NETWORK,
+};
+
+enum
+{
+ STATUS_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0, };
+
+struct _MokoSmsPrivate
+{
+ MokoNetwork *network;
+ gboolean got_subscriber_number;
+ gboolean handling_sms;
+
+ JanaStore *sms_store;
+ gboolean sms_store_open;
+ JanaNote *last_msg;
+};
+
+static void start_handling_sms (MokoSms *sms);
+
+static void
+moko_sms_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_STATUS :
+ g_value_set_int (value, moko_sms_get_status (MOKO_SMS (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+subscriber_number_changed_cb (MokoNetwork *network, const gchar *number,
+ MokoSms *sms)
+{
+ MokoSmsPrivate *priv = sms->priv;
+
+ if (number) {
+ if (!priv->got_subscriber_number) {
+ priv->got_subscriber_number = TRUE;
+ if (!priv->handling_sms) start_handling_sms (sms);
+ if (priv->sms_store_open)
+ g_signal_emit (sms, signals[STATUS_CHANGED], 0, PK_SMS_READY);
+ }
+ } else {
+ if (priv->got_subscriber_number) {
+ priv->got_subscriber_number = FALSE;
+ moko_network_remove_listener (priv->network, MOKO_LISTENER (sms));
+ priv->handling_sms = FALSE;
+ if (priv->sms_store_open)
+ g_signal_emit (sms, signals[STATUS_CHANGED], 0, PK_SMS_NOTREADY);
+ }
+ }
+}
+
+static void
+moko_sms_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ gchar *number;
+ MokoSms *sms = MOKO_SMS (object);
+ MokoSmsPrivate *priv = sms->priv;
+
+ switch (property_id) {
+ case PROP_NETWORK :
+ if (priv->network) {
+ moko_network_remove_listener (priv->network, MOKO_LISTENER (object));
+ g_object_unref (priv->network);
+ }
+ priv->network = g_value_dup_object (value);
+ if (!moko_network_get_subscriber_number (priv->network, &number, NULL)) {
+ subscriber_number_changed_cb (priv->network, NULL, MOKO_SMS (object));
+ } else {
+ subscriber_number_changed_cb (priv->network, number, MOKO_SMS (object));
+ }
+ g_signal_connect (priv->network, "subscriber_number_changed",
+ G_CALLBACK (subscriber_number_changed_cb), object);
+ /* moko_network_add_listener happens in start_handling_sms */
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+moko_sms_dispose (GObject *object)
+{
+ MokoSms *sms;
+ MokoSmsPrivate *priv;
+
+ sms = MOKO_SMS (object);
+ priv = sms->priv;
+
+ if (priv->sms_store) {
+ g_object_unref (priv->sms_store);
+ priv->sms_store = NULL;
+ }
+
+ if (priv->last_msg) {
+ g_object_unref (priv->last_msg);
+ priv->last_msg = NULL;
+ }
+
+ G_OBJECT_CLASS (moko_sms_parent_class)->dispose (object);
+}
+
+static void
+moko_sms_finalize (GObject *object)
+{
+ MokoSms *sms;
+ MokoSmsPrivate *priv;
+
+ sms = MOKO_SMS (object);
+ priv = sms->priv;
+
+ G_OBJECT_CLASS (moko_sms_parent_class)->finalize (object);
+}
+
+#include "moko-sms-glue.h"
+
+static void
+moko_sms_class_init (MokoSmsClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS (klass);
+
+ obj_class->get_property = moko_sms_get_property;
+ obj_class->set_property = moko_sms_set_property;
+ obj_class->finalize = moko_sms_finalize;
+ obj_class->dispose = moko_sms_dispose;
+
+ /* add class properties */
+ g_object_class_install_property (obj_class,
+ PROP_STATUS,
+ g_param_spec_int (
+ "status",
+ "PhoneKitSmsStatus",
+ "The current SMS status.",
+ PK_SMS_NOTREADY,
+ PK_SMS_READY,
+ PK_SMS_NOTREADY,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (obj_class,
+ PROP_NETWORK,
+ g_param_spec_object (
+ "network",
+ "MokoNetwork *",
+ "The parent MokoNetwork object.",
+ MOKO_TYPE_NETWORK,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ /* add class signals */
+ signals[STATUS_CHANGED] =
+ g_signal_new ("status_changed",
+ G_TYPE_FROM_CLASS (obj_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MokoSmsClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1, G_TYPE_INT);
+
+ g_type_class_add_private (obj_class, sizeof (MokoSmsPrivate));
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_moko_sms_object_info);
+}
+
+static void
+on_incoming_sms (MokoListener *listener, struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms)
+{
+ gchar *message;
+
+ MokoSms *moko_sms = MOKO_SMS (listener);
+ MokoSmsPrivate *priv = moko_sms->priv;
+
+ /* Return if we're not ready - this shouldn't happen as we don't listen to
+ * events when we're not ready...
+ */
+ if (!priv->handling_sms) return;
+
+ /* Ignore voicemail notifications */
+ if (sms->payload.is_voicemail) return;
+
+ /* TODO: Verify type of message for journal (sent/received) -
+ * Assuming received for now, as messages sent with phone-kit
+ * will be marked already.
+ */
+ message = NULL;
+ switch (sms->payload.coding_scheme) {
+ case ALPHABET_DEFAULT :
+ g_debug ("Decoding 7-bit ASCII message");
+ message = g_malloc0 (GSMD_SMS_DATA_MAXLEN);
+ unpacking_7bit_character (&sms->payload, message);
+ break;
+ case ALPHABET_8BIT :
+ /* TODO: Verify: Is this encoding just UTF-8? (it is on my Samsung phone) */
+ g_debug ("Decoding UTF-8 message");
+ message = g_strdup (sms->payload.data);
+ break;
+ case ALPHABET_UCS2 :
+ g_debug ("Decoding UCS-2 message");
+ message = g_utf16_to_utf8 ((const gunichar2 *)sms->payload.data,
+ sms->payload.length, NULL, NULL, NULL);
+ break;
+ }
+
+ /* Store message in the journal */
+ if (message) {
+ struct lgsm_sms_delete sms_del;
+ gchar *author, *own_number;
+ JanaNote *note = jana_ecal_note_new ();
+
+ g_debug ("Moving message to journal:\n\"%s\"", message);
+
+ author = g_strconcat (((sms->addr.type & __GSMD_TOA_TON_MASK) ==
+ GSMD_TOA_TON_INTERNATIONAL) ? "+" : "",
+ sms->addr.number, NULL);
+ jana_note_set_author (note, author);
+ g_free (author);
+
+ own_number = NULL;
+ moko_network_get_subscriber_number (priv->network, &own_number, NULL);
+ jana_note_set_recipient (note, own_number);
+ g_free (own_number);
+
+ jana_note_set_body (note, message);
+
+ /* TODO: Set creation time from SMS timestamp */
+
+ /* Add SMS to store */
+ jana_store_add_component (priv->sms_store, JANA_COMPONENT (note));
+
+ /* Delete SMS from internal storage */
+ sms_del.index = sms->index;
+ sms_del.delflg = LGSM_SMS_DELFLG_INDEX;
+ lgsm_sms_delete (handle, &sms_del);
+
+ g_free (message);
+ }
+}
+
+typedef struct {
+ MokoSms *moko_sms;
+ gchar *ref;
+} MokoSmsStatusReport;
+
+static void
+status_report_added_cb (JanaStoreView *view, GList *components,
+ MokoSmsStatusReport *sr)
+{
+ MokoSmsPrivate *priv = sr->moko_sms->priv;
+
+ for (; components; components = components->next) {
+ gchar *compref;
+ JanaComponent *comp = JANA_COMPONENT (components->data);
+
+ compref = jana_component_get_custom_prop (
+ comp, "X-PHONEKIT-SMS-REF");
+ if (compref && (strcmp (compref, sr->ref) == 0)) {
+ jana_utils_component_remove_category (comp, "Sending");
+ jana_utils_component_insert_category (comp, "Sent", 0);
+ jana_store_modify_component (priv->sms_store, comp);
+ g_debug ("Setting message status to confirmed sent");
+ }
+ g_free (compref);
+ }
+}
+
+static void
+status_report_progress_cb (JanaStoreView *view, gint percent,
+ MokoSmsStatusReport *sr)
+{
+ if (percent != 100) return;
+
+ g_object_unref (view);
+
+ g_object_unref (sr->moko_sms);
+ g_free (sr->ref);
+ g_slice_free (MokoSmsStatusReport, sr);
+}
+
+static void
+on_incoming_ds (MokoListener *listener, struct lgsm_handle *handle,
+ const struct gsmd_sms_list *sms)
+{
+ MokoSms *moko_sms = MOKO_SMS (listener);
+ MokoSmsPrivate *priv = moko_sms->priv;
+
+ if (sms->payload.coding_scheme == LGSM_SMS_STO_SENT) {
+ gchar *ref = g_strdup_printf ("%d", sms->index);
+ JanaStoreView *view = jana_store_get_view (priv->sms_store);
+ MokoSmsStatusReport *sr = g_slice_new (MokoSmsStatusReport);
+
+ sr->moko_sms = g_object_ref (moko_sms);
+ sr->ref = ref;
+
+ g_debug ("Received sent SMS status report");
+ jana_store_view_add_match (view, JANA_STORE_VIEW_CATEGORY, "Sending");
+ g_signal_connect (view, "added",
+ G_CALLBACK (status_report_added_cb), sr);
+ g_signal_connect (view, "progress",
+ G_CALLBACK (status_report_progress_cb), sr);
+ }
+}
+
+static void
+on_send_sms (MokoListener *listener, struct lgsm_handle *handle,
+ int result)
+{
+ MokoSms *sms = MOKO_SMS (listener);
+ MokoSmsPrivate *priv = sms->priv;
+
+ if (priv->last_msg) {
+ gchar *uid = jana_component_get_uid (
+ JANA_COMPONENT (priv->last_msg));
+
+ if (result >= 0) {
+ gchar *ref = g_strdup_printf ("%d", result);
+ jana_component_set_custom_prop (JANA_COMPONENT (priv->last_msg),
+ "X-PHONEKIT-SMS-REF", ref);
+ g_free (ref);
+ g_debug ("Sent message accepted");
+ } else {
+ g_debug ("Sent message rejected");
+ jana_utils_component_remove_category (JANA_COMPONENT(priv->last_msg),
+ "Sending");
+ jana_utils_component_insert_category (JANA_COMPONENT(priv->last_msg),
+ "Rejected", 0);
+ /* TODO: Add error codes? 42 = congestion? */
+ }
+ jana_store_modify_component (priv->sms_store,
+ JANA_COMPONENT (priv->last_msg));
+
+ g_free (uid);
+ g_object_unref (priv->last_msg);
+ priv->last_msg = NULL;
+ }
+}
+
+static void
+listener_interface_init (gpointer g_iface, gpointer iface_data)
+{
+ MokoListenerInterface *iface = (MokoListenerInterface *)g_iface;
+
+ iface->on_incoming_sms = on_incoming_sms;
+ iface->on_incoming_ds = on_incoming_ds;
+ iface->on_send_sms = on_send_sms;
+}
+
+static void
+start_handling_sms (MokoSms *sms)
+{
+ MokoSmsPrivate *priv = sms->priv;
+ struct lgsm_handle *handle;
+
+ if (priv->handling_sms ||
+ (!priv->sms_store_open) || (!priv->got_subscriber_number)) return;
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, NULL)) return;
+
+ /* Add listener to MokoNetwork object */
+ moko_network_add_listener (priv->network, MOKO_LISTENER (sms));
+
+ /* List all messages to move to journal */
+ lgsm_sms_list (handle, GSMD_SMS_ALL);
+
+ priv->handling_sms = TRUE;
+}
+
+static void
+sms_store_opened_cb (JanaStore *store, MokoSms *self)
+{
+ MokoSmsPrivate *priv = self->priv;
+ priv->sms_store_open = TRUE;
+
+ if (!priv->handling_sms) start_handling_sms (self);
+ if (priv->got_subscriber_number)
+ g_signal_emit (self, signals[STATUS_CHANGED], 0, PK_SMS_READY);
+}
+
+static void
+moko_sms_init (MokoSms *sms)
+{
+ MokoSmsPrivate *priv;
+
+ priv = sms->priv = MOKO_SMS_GET_PRIVATE (sms);
+
+ /* Get the SMS note store */
+ priv->sms_store = jana_ecal_store_new (JANA_COMPONENT_NOTE);
+ g_signal_connect (priv->sms_store, "opened",
+ G_CALLBACK (sms_store_opened_cb), sms);
+ jana_store_open (priv->sms_store);
+}
+
+MokoSms*
+moko_sms_get_default (MokoNetwork *network)
+{
+ static MokoSms *sms = NULL;
+ if (sms)
+ return sms;
+
+ sms = g_object_new (MOKO_TYPE_SMS, "network", network, NULL);
+
+ return sms;
+}
+
+PhoneKitSmsStatus
+moko_sms_get_status (MokoSms *sms)
+{
+ MokoSmsPrivate *priv = sms->priv;
+
+ if (priv->sms_store_open && priv->got_subscriber_number)
+ return PK_SMS_READY;
+ else
+ return PK_SMS_NOTREADY;
+}
+
+gboolean
+moko_sms_send (MokoSms *self, const gchar *number,
+ const gchar *message, gchar **uid, GError **error)
+{
+ PhoneKitNetworkStatus status;
+ struct lgsm_handle *handle;
+ MokoSmsPrivate *priv;
+ struct lgsm_sms sms;
+ gint msg_length, c;
+ gboolean ascii;
+ JanaNote *note;
+ gchar *dialcode = NULL;
+ gchar *sub_num = NULL;
+
+ g_assert (self && number && message);
+ priv = self->priv;
+
+ if (!moko_network_get_lgsm_handle (priv->network, &handle, error))
+ return FALSE;
+ status = moko_network_get_status (priv->network);
+ if (status < PK_NETWORK_REGISTERED_HOME) {
+ if (error) *error = g_error_new (PHONE_KIT_NETWORK_ERROR,
+ PK_NETWORK_ERROR_NOT_CONNECTED,
+ "Not registered to a network");
+ return FALSE;
+ }
+
+ if (!priv->sms_store_open) {
+ *error = g_error_new (PHONE_KIT_SMS_ERROR, PK_SMS_ERROR_STORE_NOTOPEN,
+ "SMS store not opened");
+ return FALSE;
+ }
+
+ if (!moko_network_get_subscriber_number (priv->network, &sub_num, error))
+ return FALSE;
+
+ /* Ask for delivery report */
+ sms.ask_ds = 1;
+
+ /* Set destination number */
+ if (strlen (number) > GSMD_ADDR_MAXLEN + 1) {
+ *error = g_error_new (PHONE_KIT_SMS_ERROR,
+ PK_SMS_ERROR_INVALID_NUMBER,
+ "Invalid number");
+ return FALSE;
+ } else {
+ strcpy (sms.addr, number);
+ }
+
+ /* Set message */
+ /* Check if the text is ascii (and pack in 7 bits if so) */
+ ascii = TRUE;
+ for (c = 0; message[c] != '\0'; c++) {
+ if (((guint8)message[c]) > 0x7F) {
+ ascii = FALSE;
+ break;
+ }
+ }
+
+ /* TODO: Multi-part messages using UDH */
+ msg_length = strlen (message);
+ if ((ascii && (msg_length > 160)) || (msg_length > 140)) {
+ *error = g_error_new (PHONE_KIT_SMS_ERROR, PK_SMS_ERROR_MSG_TOOLONG,
+ "Message too long");
+ return FALSE;
+ }
+ if (ascii) {
+ packing_7bit_character (message, &sms);
+ } else {
+ sms.alpha = ALPHABET_8BIT;
+ strcpy ((gchar *)sms.data, message);
+ }
+ sms.length = msg_length;
+
+ /* Send message */
+ lgsm_sms_send (handle, &sms);
+
+ /* Store sent message in journal */
+ note = jana_ecal_note_new ();
+
+ moko_network_get_country_code (priv->network, &dialcode, NULL);
+
+ if ((number[0] == '0') && (number[1] != '0') && (dialcode)) {
+ gchar *full_number = g_strconcat (dialcode, number + 1, NULL);
+ jana_note_set_recipient (note, full_number);
+ g_free (full_number);
+ } else
+ jana_note_set_recipient (note, number);
+ jana_note_set_author (note, sub_num);
+ g_free (dialcode);
+ g_free (sub_num);
+
+ jana_note_set_body (note, message);
+ jana_component_set_categories (JANA_COMPONENT (note),
+ (const gchar *[]){ "Sending", NULL});
+
+ jana_store_add_component (priv->sms_store,
+ JANA_COMPONENT (note));
+ if (uid) *uid = jana_component_get_uid (JANA_COMPONENT (note));
+
+ if (priv->last_msg) {
+ g_warning ("Confirmation not received for last sent SMS, "
+ "delivery report will be lost.");
+ g_object_unref (priv->last_msg);
+ priv->last_msg = NULL;
+ }
+ priv->last_msg = note;
+
+ return TRUE;
+}
+
Added: trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.h
===================================================================
--- trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.h 2007-12-03 12:17:54 UTC (rev 3552)
+++ trunk/src/target/OM-2007.2/applications/openmoko-dialer2/src/phone-kit/moko-sms.h 2007-12-03 14:49:48 UTC (rev 3553)
@@ -0,0 +1,104 @@
+/*
+ * moko-sms; a GObject wrapper for phone-kit that exports method and
+ * signals over dbus relating to SMS messaging
+ *
+ * Authored by OpenedHand Ltd <info at openedhand.com>
+ *
+ * Copyright (C) 2006-2007 OpenMoko Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser Public License as published by
+ * the Free Software Foundation; version 2 of the license.
+ *
+ * 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 Lesser Public License for more details.
+ *
+ * Current Version: $Rev$ ($Date$) [$Author$]
+ */
+
+#ifndef _HAVE_MOKO_SMS_H
+#define _HAVE_MOKO_SMS_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include "moko-listener.h"
+#include "moko-network.h"
+
+G_BEGIN_DECLS
+
+#define MOKO_TYPE_SMS (moko_sms_get_type ())
+
+#define MOKO_SMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ MOKO_TYPE_SMS, MokoSms))
+
+#define MOKO_SMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ MOKO_TYPE_SMS, MokoSmsClass))
+
+#define MOKO_IS_SMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ MOKO_TYPE_SMS))
+
+#define MOKO_IS_SMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ MOKO_TYPE_SMS))
+
+#define MOKO_SMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ MOKO_TYPE_SMS, MokoSmsClass))
+
+#define PHONE_KIT_SMS_ERROR g_quark_from_static_string("phone-kit-sms")
+
+typedef struct _MokoSms MokoSms;
+typedef struct _MokoSmsClass MokoSmsClass;
+typedef struct _MokoSmsPrivate MokoSmsPrivate;
+
+typedef enum {
+ PK_SMS_ERROR_STORE_NOTOPEN,
+ PK_SMS_ERROR_MSG_TOOLONG,
+ PK_SMS_ERROR_INVALID_NUMBER,
+} PhoneKitSmsError;
+
+typedef enum {
+ PK_SMS_NOTREADY,
+ PK_SMS_READY,
+} PhoneKitSmsStatus;
+
+struct _MokoSms
+{
+ GObject parent;
+
+ /*< private >*/
+ MokoSmsPrivate *priv;
+};
+
+struct _MokoSmsClass
+{
+ /*< private >*/
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*status_changed) (MokoSms *sms, PhoneKitSmsStatus status);
+
+ /* future padding */
+ void (*_moko_sms_1) (void);
+ void (*_moko_sms_2) (void);
+ void (*_moko_sms_3) (void);
+ void (*_moko_sms_4) (void);
+};
+
+GType moko_sms_get_type (void) G_GNUC_CONST;
+
+MokoSms*
+moko_sms_get_default (MokoNetwork *network);
+
+PhoneKitSmsStatus
+moko_sms_get_status (MokoSms *sms);
+
+/* SMS interface */
+gboolean
+moko_sms_send (MokoSms *self, const gchar *number,
+ const gchar *message, gchar **uid, GError **error);
+
+G_END_DECLS
+
+#endif /* _HAVE_MOKO_SMS_H */
+
More information about the commitlog
mailing list