Check that service is actually registered
[framework/connectivity/connman.git] / plugins / hso.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <errno.h>
28 #include <string.h>
29
30 #include <glib.h>
31
32 #define CONNMAN_API_SUBJECT_TO_CHANGE
33 #include <connman/plugin.h>
34 #include <connman/device.h>
35 #include <connman/resolver.h>
36 #include <connman/log.h>
37
38 #include "modem.h"
39
40 struct hso_data {
41         int index;
42         struct modem_data *modem;
43 };
44
45 static void owandata_callback(const char *buf, void *user_data)
46 {
47         //struct hso_data *data = user_data;
48         char *str, ip[16], nm[16], ns1[16], ns2[16], ns3[16], ns4[16], val[20];
49         int err, num;
50
51         str = g_strrstr(buf, "_OWANDATA");
52         if (str == NULL || strstr(buf, "ERROR") != NULL)
53                 return;
54
55         err = sscanf(str, "_OWANDATA: %d, %[^,], %[^,], "
56                                         "%[^,], %[^,], %[^,], %[^,], %s",
57                                 &num, ip, nm, ns1, ns2, ns3, ns4, val);
58
59         if (err != 8) {
60                 DBG("parsed %d arguments", err);
61                 return;
62         }
63
64         DBG("ip %s dns %s %s val %s", ip, ns1, ns2, val);
65
66         //connman_resolver_append(data->iface, NULL, ns1);
67         //connman_resolver_append(data->iface, NULL, ns2);
68 }
69
70 static void owancall_callback(const char *buf, void *user_data)
71 {
72         struct hso_data *data = user_data;
73
74         DBG("");
75
76         if (g_strrstr(buf, "_OWANCALL: 1, 3") != NULL) {
77                 DBG("%s", buf);
78                 //modem_command(modem, owancall_callback, data,
79                 //                      "_OWANCALL", "%d,%d,%d", 1, 1, 1);
80         }
81
82         if (g_strrstr(buf, "_OWANCALL: 1, 1") != NULL) {
83                 DBG("%s", buf);
84                 modem_command(data->modem, owandata_callback, data,
85                                                 "_OWANDATA", "%d", 1);
86         }
87
88         if (g_strrstr(buf, "\r\nOK\r\n") != NULL) {
89                 modem_command(data->modem, owandata_callback, data,
90                                                 "_OWANDATA", "%d", 1);
91         }
92 }
93
94 static int network_probe(struct connman_network *network)
95 {
96         DBG("network %p", network);
97
98         return 0;
99 }
100
101 static void network_remove(struct connman_network *network)
102 {
103         DBG("network %p", network);
104 }
105
106 static int network_connect(struct connman_network *network)
107 {
108         DBG("network %p", network);
109
110         return 0;
111 }
112
113 static int network_disconnect(struct connman_network *network)
114 {
115         DBG("network %p", network);
116
117         return 0;
118 }
119
120 static struct connman_network_driver network_driver = {
121         .name           = "hso-network",
122         .type           = CONNMAN_NETWORK_TYPE_HSO,
123         .probe          = network_probe,
124         .remove         = network_remove,
125         .connect        = network_connect,
126         .disconnect     = network_disconnect,
127 };
128
129 static int hso_probe(struct connman_device *device)
130 {
131         struct hso_data *data;
132
133         DBG("device %p", device);
134
135         data = g_try_new0(struct hso_data, 1);
136         if (data == NULL)
137                 return -ENOMEM;
138
139         data->index = connman_device_get_index(device);
140
141         data->modem = modem_create("/dev/ttyHS0");
142         if (data->modem == NULL) {
143                 g_free(data);
144                 return -EIO;
145         }
146
147         connman_device_set_data(device, data);
148
149         modem_add_callback(data->modem, "_OWANCALL",
150                                                 owancall_callback, data);
151
152         return 0;
153 }
154
155 static void hso_remove(struct connman_device *device)
156 {
157         struct hso_data *data = connman_device_get_data(device);
158
159         DBG("device %p", device);
160
161         connman_device_set_data(device, NULL);
162
163         modem_destroy(data->modem);
164
165         g_free(data);
166 }
167
168 static int hso_enable(struct connman_device *device)
169 {
170         struct hso_data *data = connman_device_get_data(device);
171         struct connman_network *network;
172         int err;
173
174         DBG("device %p", device);
175
176         err = modem_open(data->modem);
177         if (err < 0)
178                 return err;
179
180         connman_device_set_powered(device, TRUE);
181
182         modem_command(data->modem, NULL, NULL, "Z", NULL);
183         modem_command(data->modem, NULL, NULL, "I", NULL);
184
185         modem_command(data->modem, owancall_callback, data,
186                                         "_OWANCALL", "%d,%d,%d", 1, 1, 1);
187
188         network = connman_network_create("internet", CONNMAN_NETWORK_TYPE_HSO);
189         connman_device_add_network(device, network);
190
191         return 0;
192 }
193
194 static int hso_disable(struct connman_device *device)
195 {
196         struct hso_data *data = connman_device_get_data(device);
197         //const char *iface = connman_device_get_interface(device);
198
199         DBG("device %p", device);
200
201         //connman_resolver_remove_all(iface);
202
203         modem_command(data->modem, owancall_callback, data,
204                                         "_OWANCALL", "%d,%d,%d", 1, 0, 0);
205
206         connman_device_set_powered(device, FALSE);
207
208         modem_close(data->modem);
209
210         return 0;
211 }
212
213 static struct connman_device_driver hso_driver = {
214         .name           = "hso",
215         .type           = CONNMAN_DEVICE_TYPE_HSO,
216         .probe          = hso_probe,
217         .remove         = hso_remove,
218         .enable         = hso_enable,
219         .disable        = hso_disable,
220 };
221
222 static int hso_init(void)
223 {
224         int err;
225
226         err = connman_network_driver_register(&network_driver);
227         if (err < 0)
228                 return err;
229
230         err = connman_device_driver_register(&hso_driver);
231         if (err < 0) {
232                 connman_network_driver_unregister(&network_driver);
233                 return err;
234         }
235
236         return 0;
237 }
238
239 static void hso_exit(void)
240 {
241         connman_device_driver_unregister(&hso_driver);
242         connman_network_driver_register(&network_driver);
243 }
244
245 CONNMAN_PLUGIN_DEFINE(hso, "Option HSO device plugin", VERSION,
246                 CONNMAN_PLUGIN_PRIORITY_DEFAULT, hso_init, hso_exit)