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