From: Jay Freyensee <jpfre...@fedora-5150-smashcake.(none)>

---
 Makefile.am        |    3 +-
 Makefile.plugins   |    7 +
 configure.ac       |   12 ++
 plugins/openplug.c |  404 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 425 insertions(+), 1 deletions(-)
 create mode 100644 plugins/openplug.c

diff --git a/Makefile.am b/Makefile.am
index 37d5ef8..8b01e1c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -180,7 +180,8 @@ DISTCHECK_CONFIGURE_FLAGS = --disable-gtk-doc \
                                --enable-mbm \
                                --enable-udev \
                                --enable-client \
-                               --enable-tools
+                               --enable-tools \
+                               --enable-openplug
 
 DISTCLEANFILES = $(pkgconfig_DATA)
 
diff --git a/Makefile.plugins b/Makefile.plugins
index 2406327..9d03cde 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -53,6 +53,13 @@ plugins_wifi_la_LDFLAGS = $(plugin_ldflags)
 endif
 endif
 
+if OPENPLUG
+plugin_LTLIBRARIES += plugins/openplug.la
+plugin_objects += $(plugins_openplug_la_OBJECTS)
+plugins_openplug_la_LDFLAGS = $(plugin_ldflags) $(optelephony_LIBS)
+plugins_openplug_la_CFLAGS = $(plugin_cflags) $(optelephony_CFLAGS)
+endif
+
 if BLUETOOTH
 if BLUETOOTH_BUILTIN
 builtin_modules += bluetooth
diff --git a/configure.ac b/configure.ac
index afb14cf..97e03aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -203,6 +203,18 @@ AC_ARG_ENABLE(mbm,
 AM_CONDITIONAL(MBM, test "${enable_mbm}" != "no")
 AM_CONDITIONAL(MBM_BUILTIN, test "${enable_mbm}" = "builtin")
 
+AC_ARG_ENABLE(openplug,
+        AC_HELP_STRING([--enable-openplug], [enable OPENPLUG support]),
+                        [enable_openplug=${enableval}], [enable_openplug="no"])
+AM_CONDITIONAL(OPENPLUG, test "${enable_openplug}" != "no")
+AM_CONDITIONAL(OPENPLUG_BUILTIN, test "${enable_openplug}" = "builtin")
+if test "$enable_openplug" = "yes" ; then
+   PKG_CHECK_MODULES([optelephony], [optelephony], dummy=yes,
+                     AC_MSG_ERROR(optelephony is required))
+   AC_SUBST(OPTELEPHONY_CFLAGS)
+   AC_SUBST(OPTELEPHONY_LIBS)
+fi
+
 AC_CHECK_LIB(dl, dlopen, dummy=yes,
                        AC_MSG_ERROR(dynamic linking loader is required))
 
diff --git a/plugins/openplug.c b/plugins/openplug.c
new file mode 100644
index 0000000..db62db1
--- /dev/null
+++ b/plugins/openplug.c
@@ -0,0 +1,404 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2008-2009  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <net/if.h>
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP   0x10000
+#endif
+
+#include <glib.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/plugin.h>
+#include <connman/device.h>
+#include <connman/inet.h>
+#include <connman/log.h>
+#include <connman/resolver.h>
+#include <connman/notifier.h>
+#include <connman/rtnl.h>
+
+#include <optelephony/settings.h>
+#include <optelephony/dcm.h>
+#include <optelephony/telephony_server.h>
+#include <optelephony/tapi.h>
+
+static dcm_connection_t dcm_connection;
+static dcm_ip_config_t dcm_ip_config;
+
+struct telephony_data {
+       int index;
+       struct connman_network *network;
+       unsigned flags;
+       unsigned int watch;
+};
+
+static unsigned char netmask2prefixlen(const char *netmask)
+{
+       unsigned char bits = 0;
+       in_addr_t mask = inet_network(netmask);
+       in_addr_t host = ~mask;
+
+       /* a valid netmask must be 2^n - 1 */
+       if ((host & (host + 1)) != 0)
+               return -1;
+
+       for (; mask; mask <<= 1)
+               ++bits;
+
+       return bits;
+}
+
+static int setup_interface(struct connman_device *device)
+{
+       int index;
+       struct connman_ipaddress *ipaddress;
+
+       index = connman_device_get_index(device);
+
+       if (dcm_connection != NULL)
+               dcm_get_ip_config(dcm_connection, &dcm_ip_config);
+
+               DBG("IFNAME: %s IP ADDR: %s DNS1: %s DNS2: %s GW: %s\n",
+                       dcm_ip_config.interface_name,
+                       dcm_ip_config.ip_addr,
+                       dcm_ip_config.dns1_addr,
+                       dcm_ip_config.dns2_addr,
+                       dcm_ip_config.gateway_addr);
+
+       if (strcmp(dcm_ip_config.gateway_addr, "0.0.0.0") == 0) {
+               DBG(" No gateway specified, defaulting to 0.0.0.0\n");
+               strcpy(dcm_ip_config.gateway_addr, dcm_ip_config.ip_addr);
+       }
+
+       ipaddress = connman_ipaddress_alloc();
+       ipaddress->local = dcm_ip_config.ip_addr;
+       ipaddress->peer = 0;
+       ipaddress->prefixlen = netmask2prefixlen("255.255.255.0");
+       ipaddress->broadcast = "0.0.0.0";
+
+       connman_inet_set_address(index, ipaddress);
+
+       connman_inet_set_gateway_address(index, dcm_ip_config.gateway_addr);
+
+       connman_resolver_append(dcm_ip_config.interface_name, NULL,
+                               dcm_ip_config.dns1_addr);
+       connman_resolver_append(dcm_ip_config.interface_name, NULL,
+                               dcm_ip_config.dns2_addr);
+       connman_device_set_connected(device, TRUE);
+
+       return 0;
+}
+
+static int setdown_interface(struct connman_device *device)
+{
+       int index = connman_device_get_index(device);
+       connman_inet_ifdown(index);
+       connman_resolver_remove_all(dcm_ip_config.interface_name);
+       connman_device_set_connected(device, FALSE);
+       return 0;
+}
+
+/**
+ * Connection event callback from dcm, in the telephony context.
+ */
+static void openplug_plugin_event_cb(dcm_connection_event_t *event,
+                                     const void *user_data)
+{
+       dcm_connection_event_t *evt = (dcm_connection_event_t *) event;
+       struct connman_device *device = (struct connman_device *) user_data;
+
+       if (evt == NULL)
+               return;
+
+       if (evt->ret == dcm_return_success) {
+               switch (evt->status) {
+               case dcm_connection_connecting:
+                       break;
+
+               case dcm_connection_authenticating:
+                       break;
+
+               case dcm_connection_authenticated:
+                       break;
+
+               case dcm_connection_connected:
+                       setup_interface(device);
+                       break;
+
+               case dcm_connection_disconnected:
+                       setdown_interface(device);
+                       break;
+
+               default:
+                       break;
+               }
+       }
+       return;
+}
+
+static int dcm_disconnect(struct connman_device *device)
+{
+
+       if (dcm_connection != NULL) {
+               if (dcm_deactivate_connection(dcm_connection) !=
+                                             dcm_return_success) {
+                       DBG("dcm connection deactivate failed\n");
+                       dcm_destroy_connection(dcm_connection);
+                       return -1;
+               }
+               DBG("dcm connection deactivated\n");
+       }
+       return 0;
+}
+
+static int dcm_connect(struct connman_device *device)
+{
+
+       char *profile = NULL;
+       dcm_return_t dcm_ret;
+
+       if (connman_settings_get_current_profile_name(&profile) ==
+                                       SETTINGS_RETURN_SUCCESS) {
+
+               if (dcm_create_connection(&dcm_connection) ==
+                                       dcm_return_success) {
+
+                       if (dcm_connection_event_register(dcm_connection,
+                                       openplug_plugin_event_cb,
+                                       device) == dcm_return_success) {
+
+                               dcm_ret = dcm_activate_connection(
+                                                       dcm_connection,
+                                                       profile, 1);
+                               if (dcm_ret == dcm_return_success) {
+                                       free(profile);
+                                       return TRUE;
+                               } else {
+                                       if (dcm_ret == dcm_return_failure)
+                                               DBG("failure profile %s",
+                                                       profile);
+                               }
+                               dcm_connection_event_unregister(
+                                                       dcm_connection);
+                       }
+                       dcm_destroy_connection(dcm_connection);
+               }
+               free(profile);
+       }
+       return TRUE;
+}
+
+static void openplug_newlink(unsigned flags, unsigned change, void *user_data)
+{
+       struct connman_device *device = user_data;
+       struct telephony_data *data = connman_device_get_data(device);
+
+       if (data->network == NULL)
+               goto done;
+
+       DBG("device %p flags %d change %d", device, flags, change);
+
+       if ((data->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
+               if (flags & IFF_LOWER_UP)
+                       connman_network_set_connected(data->network, TRUE);
+               else
+                       connman_network_set_connected(data->network, FALSE);
+       }
+
+done:
+       data->flags = flags;
+}
+
+static int openplug_probe(struct connman_device *device)
+{
+       struct telephony_data *data;
+       int index;
+       const char *interface_name;
+
+       DBG("device: %p", device);
+
+
+       data = g_try_new0(struct telephony_data, 1);
+       if (data == NULL)
+               return -ENOMEM;
+
+
+       connman_device_set_data(device, data);
+       index = connman_device_get_index(device);
+
+       interface_name = connman_device_get_name(device);
+       DBG("Device name : %s", interface_name);
+
+       data->watch = connman_rtnl_add_newlink_watch(index,
+                                               openplug_newlink, device);
+
+       return 0;
+}
+
+static void openplug_remove(struct connman_device *device)
+{
+       DBG("");
+       dcm_disconnect(device);
+}
+
+static int openplug_enable(struct connman_device *device)
+{
+       int index;
+
+       DBG("openplug_enable");
+
+       connman_device_set_powered(device, TRUE);
+       connman_device_set_mode(device, CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE);
+       connman_device_set_connected(device, FALSE);
+
+       index = connman_device_get_index(device);
+       connman_inet_ifup(index);
+       dcm_connect(device);
+       return -EINPROGRESS;
+}
+
+static int openplug_disable(struct connman_device *device)
+{
+
+       int index;
+
+       DBG("openplug_disable");
+
+       index = connman_device_get_index(device);
+       connman_inet_ifdown(index);
+
+       return -EINPROGRESS;
+}
+
+static struct connman_device_driver openplug_modem_driver = {
+       .name       = "openplug",
+       .type       = CONNMAN_DEVICE_TYPE_HSO,
+       .probe      = openplug_probe,
+       .remove     = openplug_remove,
+       .enable     = openplug_enable,
+       .disable    = openplug_disable,
+};
+
+static int network_connect(struct connman_network *network)
+{
+       struct connman_device *device = connman_network_get_device(network);
+       int index;
+
+       DBG("network_connect: %p", network);
+       if (connman_network_get_index(network) >= 0)
+               return -EISCONN;
+
+       index = connman_device_get_index(device);
+       connman_inet_ifup(index);
+       dcm_connect(device);
+
+       return 0;
+}
+
+static int network_disconnect(struct connman_network *network)
+{
+       struct connman_device *device = connman_network_get_device(network);
+
+       if (connman_network_get_index(network) < 0)
+               return -ENOTCONN;
+
+       dcm_disconnect(device);
+       return 0;
+}
+
+static void network_remove(struct connman_network *network)
+{
+       struct connman_device *device = connman_network_get_device(network);
+       struct telephony_data *data;
+
+       DBG("network_remove: %p", network);
+
+       data = connman_device_get_data(device);
+       data->network = NULL;
+
+       connman_network_set_data(network, NULL);
+}
+
+static int network_probe(struct connman_network *network)
+{
+       struct connman_device *device = connman_network_get_device(network);
+       struct telephony_data *data;
+
+       DBG("network %p", network);
+
+       data = connman_device_get_data(device);
+       connman_network_set_data(network, data);
+
+       return 0;
+}
+
+static struct connman_network_driver openplug_network_driver = {
+       .name           = "openplug",
+       .type           = CONNMAN_NETWORK_TYPE_HSO,
+       .probe          = network_probe,
+       .remove         = network_remove,
+       .connect        = network_connect,
+       .disconnect     = network_disconnect,
+};
+
+static int openplug_init(void)
+{
+       int err;
+
+       DBG("openplug_init");
+
+       err = connman_network_driver_register(&openplug_network_driver);
+       if (err < 0)
+               return err;
+
+       err = connman_device_driver_register(&openplug_modem_driver);
+
+       if (err < 0) {
+               connman_network_driver_unregister(&openplug_network_driver);
+               return err;
+       }
+
+       return 0;
+}
+
+static void openplug_exit(void)
+{
+       DBG("openplug_exit");
+       connman_device_driver_unregister(&openplug_modem_driver);
+       connman_network_driver_register(&openplug_network_driver);
+}
+
+CONNMAN_PLUGIN_DEFINE(openplug, "Telephony interface plugin",
+                     CONNMAN_VERSION,
+                     CONNMAN_PLUGIN_PRIORITY_DEFAULT,
+                     openplug_init, openplug_exit)
+
-- 
1.6.0.6

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to