summaryrefslogtreecommitdiff
path: root/plugins/hso.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-12-30 20:19:00 +0100
committerMarcel Holtmann <marcel@holtmann.org>2008-12-30 20:19:00 +0100
commit655c0e47d64295fd94fbd4bfb09539cb9300e300 (patch)
treefe6669f95df6a6c90c366e0b70d5aa6931afac7e /plugins/hso.c
parenteee11dfca5d8c21eaad3f1958a4db2483e634734 (diff)
downloadconnman-655c0e47d64295fd94fbd4bfb09539cb9300e300.tar.gz
connman-655c0e47d64295fd94fbd4bfb09539cb9300e300.tar.bz2
connman-655c0e47d64295fd94fbd4bfb09539cb9300e300.zip
Add more HSO implementation details
Diffstat (limited to 'plugins/hso.c')
-rw-r--r--plugins/hso.c193
1 files changed, 191 insertions, 2 deletions
diff --git a/plugins/hso.c b/plugins/hso.c
index ac851d8d..335655c9 100644
--- a/plugins/hso.c
+++ b/plugins/hso.c
@@ -23,38 +23,227 @@
#include <config.h>
#endif
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <glib.h>
+
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/device.h>
+#include <connman/resolver.h>
#include <connman/log.h>
+#include "modem.h"
+
+struct hso_data {
+ int index;
+ GIOChannel *channel;
+ struct modem_data *modem;
+};
+
+static void owandata_callback(const char *buf, void *user_data)
+{
+ //struct hso_data *data = user_data;
+ char *str, ip[16], nm[16], ns1[16], ns2[16], ns3[16], ns4[16], val[20];
+ int err, num;
+
+ str = g_strrstr(buf, "_OWANDATA");
+ if (str == NULL || strstr(buf, "ERROR") != NULL)
+ return;
+
+ err = sscanf(str, "_OWANDATA: %d, %[^,], %[^,], "
+ "%[^,], %[^,], %[^,], %[^,], %s",
+ &num, ip, nm, ns1, ns2, ns3, ns4, val);
+
+ if (err != 8) {
+ DBG("parsed %d arguments", err);
+ return;
+ }
+
+ DBG("ip %s dns %s %s val %s", ip, ns1, ns2, val);
+
+ //connman_resolver_append(data->iface, NULL, ns1);
+ //connman_resolver_append(data->iface, NULL, ns2);
+}
+
+static void owancall_callback(const char *buf, void *user_data)
+{
+ struct hso_data *data = user_data;
+
+ DBG("");
+
+ if (g_strrstr(buf, "_OWANCALL: 1, 3") != NULL) {
+ DBG("%s", buf);
+ //modem_command(modem, owancall_callback, data,
+ // "_OWANCALL", "%d,%d,%d", 1, 1, 1);
+ }
+
+ if (g_strrstr(buf, "_OWANCALL: 1, 1") != NULL) {
+ DBG("%s", buf);
+ modem_command(data->modem, owandata_callback, data,
+ "_OWANDATA", "%d", 1);
+ }
+
+ if (g_strrstr(buf, "\r\nOK\r\n") != NULL) {
+ modem_command(data->modem, owandata_callback, data,
+ "_OWANDATA", "%d", 1);
+ }
+}
+
+static int network_probe(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ return 0;
+}
+
+static void network_remove(struct connman_network *network)
+{
+ DBG("network %p", network);
+}
+
+static int network_connect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ return 0;
+}
+
+static int network_disconnect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ return 0;
+}
+
+static struct connman_network_driver network_driver = {
+ .name = "hso-network",
+ .type = CONNMAN_NETWORK_TYPE_HSO,
+ .probe = network_probe,
+ .remove = network_remove,
+ .connect = network_connect,
+ .disconnect = network_disconnect,
+};
+
static int hso_probe(struct connman_device *device)
{
+ struct hso_data *data;
+
DBG("device %p", device);
+ data = g_try_new0(struct hso_data, 1);
+ if (data == NULL)
+ return -ENOMEM;
+
+ data->index = connman_device_get_index(device);
+
+ data->modem = modem_create("/dev/ttyHS0");
+ if (data->modem == NULL) {
+ g_free(data);
+ return -EIO;
+ }
+
+ connman_device_set_data(device, data);
+
+ modem_add_callback(data->modem, "_OWANCALL",
+ owancall_callback, data);
+
return 0;
}
static void hso_remove(struct connman_device *device)
{
+ struct hso_data *data = connman_device_get_data(device);
+
DBG("device %p", device);
+
+ connman_device_set_data(device, NULL);
+
+ modem_destroy(data->modem);
+
+ g_free(data);
+}
+
+static int hso_enable(struct connman_device *device)
+{
+ struct hso_data *data = connman_device_get_data(device);
+ struct connman_network *network;
+ int err;
+
+ DBG("device %p", device);
+
+ err = modem_open(data->modem);
+ if (err < 0)
+ return err;
+
+ connman_device_set_powered(device, TRUE);
+
+ modem_command(data->modem, NULL, NULL, "Z", NULL);
+ modem_command(data->modem, NULL, NULL, "I", NULL);
+
+ modem_command(data->modem, owancall_callback, data,
+ "_OWANCALL", "%d,%d,%d", 1, 1, 1);
+
+ network = connman_network_create("internet", CONNMAN_NETWORK_TYPE_HSO);
+ connman_device_add_network(device, network);
+
+ return 0;
+}
+
+static int hso_disable(struct connman_device *device)
+{
+ struct hso_data *data = connman_device_get_data(device);
+ //const char *iface = connman_device_get_interface(device);
+
+ DBG("device %p", device);
+
+ //connman_resolver_remove_all(iface);
+
+ modem_command(data->modem, owancall_callback, data,
+ "_OWANCALL", "%d,%d,%d", 1, 0, 0);
+
+ connman_device_set_powered(device, FALSE);
+
+ modem_close(data->modem);
+
+ g_io_channel_shutdown(data->channel, TRUE, NULL);
+ g_io_channel_unref(data->channel);
+
+ return 0;
}
static struct connman_device_driver hso_driver = {
- .name = "hso",
+ .name = "hso-device",
.type = CONNMAN_DEVICE_TYPE_HSO,
.probe = hso_probe,
.remove = hso_remove,
+ .enable = hso_enable,
+ .disable = hso_disable,
};
static int hso_init(void)
{
- return connman_device_driver_register(&hso_driver);
+ int err;
+
+ err = connman_network_driver_register(&network_driver);
+ if (err < 0)
+ return err;
+
+ err = connman_device_driver_register(&hso_driver);
+ if (err < 0) {
+ connman_network_driver_unregister(&network_driver);
+ return err;
+ }
+
+ return 0;
}
static void hso_exit(void)
{
connman_device_driver_unregister(&hso_driver);
+ connman_network_driver_register(&network_driver);
}
CONNMAN_PLUGIN_DEFINE(hso, "Option HSO device plugin", VERSION,