~morphis/phablet-extras/ofono-sms-status-report

« back to all changes in this revision

Viewing changes to src/cdma-netreg.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2012-08-22 19:59:08 UTC
  • mfrom: (1.3.3) (6.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20120822195908-0bmmk1hlh989bgk6
Tags: 1.9-1ubuntu1
* Merge with Debian experimental; remaining changes:
  - debian/control: explicitly Conflicts with modemmanager: having both
    installed / running at the same time causes issues causes issues with
    both claiming modem devices.
  - debian/patches/02-dont-handle-stacktraces.patch: stop catching stacktraces
    and printing the information internally, so apport can catch and report
    the possible bugs.
  - debian/ofono.postinst: on configure, notify the user that a reboot is
    required (so ofono can get started by upstart). (LP: #600501)
  - debian/rules: pass --no-restart-on-upgrade so ofono isn't automatically
    restarted when upgrades.
  - Adding upstart config / Removing standard init script
  - Adding Apport support
  - Patch for recognizing special Huawei devices with weird serial
  - Override lintian to avoid script-in-etc-init.d... warnings.
  - Update debian/compat to 7
* debian/series: add our patches to debian/patches/series now that the package
  uses quilt.
* debian/patches/02-dont-handle-stacktraces.patch: refreshed.
* debian/ofono-dev.install, debian/ofono.install:
  - Install usr/sbin/dundee and ofono.pc to the proper packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  oFono - Open Source Telephony
 
4
 *
 
5
 *  Copyright (C) 2008-2011  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 <errno.h>
 
27
#include <string.h>
 
28
 
 
29
#include <gdbus.h>
 
30
 
 
31
#include "ofono.h"
 
32
 
 
33
static GSList *g_drivers;
 
34
 
 
35
struct ofono_cdma_netreg {
 
36
        enum cdma_netreg_status status;
 
37
        int strength;
 
38
        int hdr_strength;
 
39
        const struct ofono_cdma_netreg_driver *driver;
 
40
        void *driver_data;
 
41
        struct ofono_atom *atom;
 
42
        char *provider_name;
 
43
        char *sid;
 
44
};
 
45
 
 
46
static const char *cdma_netreg_status_to_string(enum cdma_netreg_status status)
 
47
{
 
48
        switch (status) {
 
49
        case CDMA_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED:
 
50
                return "unregistered";
 
51
        case CDMA_NETWORK_REGISTRATION_STATUS_REGISTERED:
 
52
                return "registered";
 
53
        case CDMA_NETWORK_REGISTRATION_STATUS_ROAMING:
 
54
                return "roaming";
 
55
        }
 
56
 
 
57
        return "";
 
58
}
 
59
 
 
60
static DBusMessage *network_get_properties(DBusConnection *conn,
 
61
                                                DBusMessage *msg, void *data)
 
62
{
 
63
        struct ofono_cdma_netreg *cdma_netreg = data;
 
64
        DBusMessage *reply;
 
65
        DBusMessageIter iter;
 
66
        DBusMessageIter dict;
 
67
 
 
68
        const char *status = cdma_netreg_status_to_string(cdma_netreg->status);
 
69
 
 
70
        reply = dbus_message_new_method_return(msg);
 
71
        if (reply == NULL)
 
72
                return NULL;
 
73
 
 
74
        dbus_message_iter_init_append(reply, &iter);
 
75
 
 
76
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
 
77
                                        OFONO_PROPERTIES_ARRAY_SIGNATURE,
 
78
                                        &dict);
 
79
 
 
80
        ofono_dbus_dict_append(&dict, "Status", DBUS_TYPE_STRING, &status);
 
81
 
 
82
        if (cdma_netreg->strength != -1) {
 
83
                unsigned char strength = cdma_netreg->strength;
 
84
 
 
85
                ofono_dbus_dict_append(&dict, "Strength", DBUS_TYPE_BYTE,
 
86
                                        &strength);
 
87
        }
 
88
 
 
89
        if (cdma_netreg->hdr_strength != -1) {
 
90
                unsigned char strength = cdma_netreg->hdr_strength;
 
91
 
 
92
                ofono_dbus_dict_append(&dict, "DataStrength", DBUS_TYPE_BYTE,
 
93
                                        &strength);
 
94
        }
 
95
 
 
96
        if (cdma_netreg->sid)
 
97
                ofono_dbus_dict_append(&dict, "SystemIdentifier",
 
98
                                                DBUS_TYPE_STRING,
 
99
                                                &cdma_netreg->sid);
 
100
 
 
101
        if (cdma_netreg->provider_name)
 
102
                ofono_dbus_dict_append(&dict, "Name", DBUS_TYPE_STRING,
 
103
                                                &cdma_netreg->provider_name);
 
104
 
 
105
        dbus_message_iter_close_container(&iter, &dict);
 
106
 
 
107
        return reply;
 
108
}
 
109
 
 
110
static const GDBusMethodTable cdma_netreg_manager_methods[] = {
 
111
        { GDBUS_METHOD("GetProperties",
 
112
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
 
113
                        network_get_properties) },
 
114
        { }
 
115
};
 
116
 
 
117
static const GDBusSignalTable cdma_netreg_manager_signals[] = {
 
118
        { }
 
119
};
 
120
 
 
121
static void serving_system_callback(const struct ofono_error *error,
 
122
                                        const char *sid, void *data)
 
123
{
 
124
        struct ofono_cdma_netreg *cdma_netreg = data;
 
125
        const char *path = __ofono_atom_get_path(cdma_netreg->atom);
 
126
        DBusConnection *conn = ofono_dbus_get_connection();
 
127
 
 
128
        if (cdma_netreg->status != CDMA_NETWORK_REGISTRATION_STATUS_REGISTERED
 
129
                        && cdma_netreg->status !=
 
130
                                CDMA_NETWORK_REGISTRATION_STATUS_ROAMING)
 
131
                return;
 
132
 
 
133
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
 
134
                DBG("Error during serving system query");
 
135
                return;
 
136
        }
 
137
 
 
138
        DBG("Serving system Identifier: %s", sid);
 
139
 
 
140
        if (cdma_netreg->sid != NULL && !strcmp(cdma_netreg->sid, sid))
 
141
                return;
 
142
 
 
143
        g_free(cdma_netreg->provider_name);
 
144
        g_free(cdma_netreg->sid);
 
145
        cdma_netreg->provider_name = NULL;
 
146
        cdma_netreg->sid = g_strdup(sid);
 
147
 
 
148
        ofono_dbus_signal_property_changed(conn, path,
 
149
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE,
 
150
                                "SystemIdentifier", DBUS_TYPE_STRING,
 
151
                                &cdma_netreg->sid);
 
152
 
 
153
        if (__ofono_cdma_provision_get_name(sid,
 
154
                                &cdma_netreg->provider_name) == FALSE) {
 
155
                ofono_warn("Provider name not found");
 
156
                return;
 
157
        }
 
158
 
 
159
        ofono_dbus_signal_property_changed(conn, path,
 
160
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE,
 
161
                                "Name", DBUS_TYPE_STRING,
 
162
                                &cdma_netreg->provider_name);
 
163
}
 
164
 
 
165
static void set_registration_status(struct ofono_cdma_netreg *cdma_netreg,
 
166
                                                enum cdma_netreg_status status)
 
167
{
 
168
        const char *str_status = cdma_netreg_status_to_string(status);
 
169
        const char *path = __ofono_atom_get_path(cdma_netreg->atom);
 
170
        DBusConnection *conn = ofono_dbus_get_connection();
 
171
 
 
172
        cdma_netreg->status = status;
 
173
 
 
174
        ofono_dbus_signal_property_changed(conn, path,
 
175
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE,
 
176
                                "Status", DBUS_TYPE_STRING,
 
177
                                &str_status);
 
178
 
 
179
        if (cdma_netreg->status == CDMA_NETWORK_REGISTRATION_STATUS_REGISTERED
 
180
                        || cdma_netreg->status ==
 
181
                                CDMA_NETWORK_REGISTRATION_STATUS_ROAMING)
 
182
                if (cdma_netreg->driver->serving_system != NULL)
 
183
                        cdma_netreg->driver->serving_system(cdma_netreg,
 
184
                                serving_system_callback, cdma_netreg);
 
185
}
 
186
 
 
187
void ofono_cdma_netreg_status_notify(struct ofono_cdma_netreg *cdma_netreg,
 
188
                                        enum cdma_netreg_status status)
 
189
{
 
190
        if (cdma_netreg == NULL)
 
191
                return;
 
192
 
 
193
        if (cdma_netreg->status != status)
 
194
                set_registration_status(cdma_netreg, status);
 
195
}
 
196
 
 
197
static void strength_notify_common(struct ofono_cdma_netreg *netreg,
 
198
                                        int strength, const char *property,
 
199
                                        int *dest)
 
200
{
 
201
        if (netreg == NULL)
 
202
                return;
 
203
 
 
204
        if (*dest == strength)
 
205
                return;
 
206
 
 
207
        /*
 
208
         * Theoretically we can get signal strength even when not registered
 
209
         * to any network.  However, what do we do with it in that case?
 
210
         */
 
211
        if (netreg->status == CDMA_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED)
 
212
                return;
 
213
 
 
214
        *dest = strength;
 
215
 
 
216
        if (strength != -1) {
 
217
                DBusConnection *conn = ofono_dbus_get_connection();
 
218
                const char *path = __ofono_atom_get_path(netreg->atom);
 
219
                unsigned char val = strength;
 
220
 
 
221
                ofono_dbus_signal_property_changed(conn, path,
 
222
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE,
 
223
                                property, DBUS_TYPE_BYTE, &val);
 
224
        }
 
225
}
 
226
 
 
227
void ofono_cdma_netreg_strength_notify(struct ofono_cdma_netreg *netreg,
 
228
                                        int strength)
 
229
{
 
230
        return strength_notify_common(netreg, strength,
 
231
                                        "Strength", &netreg->strength);
 
232
}
 
233
 
 
234
void ofono_cdma_netreg_data_strength_notify(struct ofono_cdma_netreg *netreg,
 
235
                                                int data_strength)
 
236
{
 
237
        return strength_notify_common(netreg, data_strength,
 
238
                                        "DataStrength", &netreg->hdr_strength);
 
239
}
 
240
 
 
241
int ofono_cdma_netreg_get_status(struct ofono_cdma_netreg *netreg)
 
242
{
 
243
        if (netreg == NULL)
 
244
                return -1;
 
245
 
 
246
        return netreg->status;
 
247
}
 
248
 
 
249
int ofono_cdma_netreg_driver_register(const struct ofono_cdma_netreg_driver *d)
 
250
{
 
251
        DBG("driver: %p, name: %s", d, d->name);
 
252
 
 
253
        if (d->probe == NULL)
 
254
                return -EINVAL;
 
255
 
 
256
        g_drivers = g_slist_prepend(g_drivers, (void *)d);
 
257
 
 
258
        return 0;
 
259
}
 
260
 
 
261
void ofono_cdma_netreg_driver_unregister(
 
262
                                const struct ofono_cdma_netreg_driver *d)
 
263
{
 
264
        DBG("driver: %p, name: %s", d, d->name);
 
265
 
 
266
        g_drivers = g_slist_remove(g_drivers, (void *)d);
 
267
}
 
268
 
 
269
static void cdma_netreg_unregister(struct ofono_atom *atom)
 
270
{
 
271
        DBusConnection *conn = ofono_dbus_get_connection();
 
272
        struct ofono_modem *modem = __ofono_atom_get_modem(atom);
 
273
        const char *path = __ofono_atom_get_path(atom);
 
274
 
 
275
        g_dbus_unregister_interface(conn, path,
 
276
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE);
 
277
 
 
278
        ofono_modem_remove_interface(modem,
 
279
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE);
 
280
}
 
281
 
 
282
static void cdma_netreg_remove(struct ofono_atom *atom)
 
283
{
 
284
        struct ofono_cdma_netreg *cdma_netreg = __ofono_atom_get_data(atom);
 
285
 
 
286
        DBG("atom: %p", atom);
 
287
 
 
288
        if (cdma_netreg == NULL)
 
289
                return;
 
290
 
 
291
        if (cdma_netreg->driver && cdma_netreg->driver->remove)
 
292
                cdma_netreg->driver->remove(cdma_netreg);
 
293
 
 
294
        g_free(cdma_netreg->sid);
 
295
        g_free(cdma_netreg->provider_name);
 
296
        g_free(cdma_netreg);
 
297
}
 
298
 
 
299
struct ofono_cdma_netreg *ofono_cdma_netreg_create(struct ofono_modem *modem,
 
300
                                                unsigned int vendor,
 
301
                                                const char *driver,
 
302
                                                void *data)
 
303
{
 
304
        struct ofono_cdma_netreg *cdma_netreg;
 
305
        GSList *l;
 
306
 
 
307
        if (driver == NULL)
 
308
                return NULL;
 
309
 
 
310
        cdma_netreg = g_try_new0(struct ofono_cdma_netreg, 1);
 
311
        if (cdma_netreg == NULL)
 
312
                return NULL;
 
313
 
 
314
        cdma_netreg->status = CDMA_NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
 
315
        cdma_netreg->strength = -1;
 
316
        cdma_netreg->hdr_strength = -1;
 
317
 
 
318
        cdma_netreg->atom = __ofono_modem_add_atom(modem,
 
319
                                        OFONO_ATOM_TYPE_CDMA_NETREG,
 
320
                                        cdma_netreg_remove, cdma_netreg);
 
321
 
 
322
        for (l = g_drivers; l; l = l->next) {
 
323
                const struct ofono_cdma_netreg_driver *drv = l->data;
 
324
 
 
325
                if (g_strcmp0(drv->name, driver))
 
326
                        continue;
 
327
 
 
328
                if (drv->probe(cdma_netreg, vendor, data) < 0)
 
329
                        continue;
 
330
 
 
331
                cdma_netreg->driver = drv;
 
332
                break;
 
333
        }
 
334
 
 
335
        return cdma_netreg;
 
336
}
 
337
 
 
338
void ofono_cdma_netreg_register(struct ofono_cdma_netreg *cdma_netreg)
 
339
{
 
340
        DBusConnection *conn = ofono_dbus_get_connection();
 
341
        struct ofono_modem *modem = __ofono_atom_get_modem(cdma_netreg->atom);
 
342
        const char *path = __ofono_atom_get_path(cdma_netreg->atom);
 
343
 
 
344
        if (!g_dbus_register_interface(conn, path,
 
345
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE,
 
346
                                cdma_netreg_manager_methods,
 
347
                                cdma_netreg_manager_signals,
 
348
                                NULL, cdma_netreg, NULL)) {
 
349
                ofono_error("Could not create %s interface",
 
350
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE);
 
351
                return;
 
352
        }
 
353
 
 
354
        ofono_modem_add_interface(modem,
 
355
                                OFONO_CDMA_NETWORK_REGISTRATION_INTERFACE);
 
356
 
 
357
        __ofono_atom_register(cdma_netreg->atom, cdma_netreg_unregister);
 
358
}
 
359
 
 
360
void ofono_cdma_netreg_remove(struct ofono_cdma_netreg *cdma_netreg)
 
361
{
 
362
        __ofono_atom_free(cdma_netreg->atom);
 
363
}
 
364
 
 
365
void ofono_cdma_netreg_set_data(struct ofono_cdma_netreg *cdma_netreg,
 
366
                                        void *data)
 
367
{
 
368
        cdma_netreg->driver_data = data;
 
369
}
 
370
 
 
371
void *ofono_cdma_netreg_get_data(struct ofono_cdma_netreg *cdma_netreg)
 
372
{
 
373
        return cdma_netreg->driver_data;
 
374
}