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