sim: Reset additional state info
[platform/upstream/ofono.git] / src / history.c
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 <string.h>
27 #include <stdio.h>
28
29 #include <glib.h>
30
31 #include "ofono.h"
32
33 static GSList *history_drivers = NULL;
34
35 struct history_call_foreach_data {
36         const struct ofono_call *call;
37         union {
38                 struct {
39                         time_t start;
40                         time_t end;
41                 };
42
43                 time_t when;
44         };
45 };
46
47 struct history_sms_foreach_data {
48         const struct ofono_uuid *uuid;
49         const char *address;
50         const char *text;
51         union {
52                 struct {
53                         const struct tm *remote;
54                         const struct tm *local;
55                 };
56                 struct {
57                         time_t when;
58                         enum ofono_history_sms_status status;
59                 };
60         };
61 };
62
63 static struct ofono_history_context *history_context_create(
64                                         struct ofono_modem *modem,
65                                         struct ofono_history_driver *driver)
66 {
67         struct ofono_history_context *context;
68
69         if (driver->probe == NULL)
70                 return NULL;
71
72         context = g_try_new0(struct ofono_history_context, 1);
73
74         if (context == NULL)
75                 return NULL;
76
77         context->driver = driver;
78         context->modem = modem;
79
80         if (driver->probe(context) < 0) {
81                 g_free(context);
82                 return NULL;
83         }
84
85         return context;
86 }
87
88 static void context_remove(struct ofono_atom *atom)
89 {
90         struct ofono_history_context *context = __ofono_atom_get_data(atom);
91
92         if (context->driver->remove)
93                 context->driver->remove(context);
94
95         g_free(context);
96 }
97
98 void __ofono_history_probe_drivers(struct ofono_modem *modem)
99 {
100         struct ofono_history_driver *driver;
101         struct ofono_history_context *context;
102         GSList *l;
103
104         for (l = history_drivers; l; l = l->next) {
105                 driver = l->data;
106
107                 context = history_context_create(modem, driver);
108                 if (context == NULL)
109                         continue;
110
111                 __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_HISTORY,
112                                                 context_remove, context);
113         }
114 }
115
116 static void history_call_ended(struct ofono_atom *atom, void *data)
117 {
118         struct ofono_history_context *context = __ofono_atom_get_data(atom);
119         struct history_call_foreach_data *hfd = data;
120
121         if (context->driver->call_ended == NULL)
122                 return;
123
124         context->driver->call_ended(context, hfd->call, hfd->start, hfd->end);
125 }
126
127 void __ofono_history_call_ended(struct ofono_modem *modem,
128                                 const struct ofono_call *call,
129                                 time_t start, time_t end)
130 {
131         struct history_call_foreach_data hfd;
132
133         hfd.call = call;
134         hfd.start = start;
135         hfd.end = end;
136
137         __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_HISTORY,
138                                         history_call_ended, &hfd);
139 }
140
141 static void history_call_missed(struct ofono_atom *atom, void *data)
142 {
143         struct ofono_history_context *context = __ofono_atom_get_data(atom);
144         struct history_call_foreach_data *hfd = data;
145
146         if (context->driver->call_missed == NULL)
147                 return;
148
149         context->driver->call_missed(context, hfd->call, hfd->when);
150 }
151
152 void __ofono_history_call_missed(struct ofono_modem *modem,
153                                 const struct ofono_call *call, time_t when)
154 {
155         struct history_call_foreach_data hfd;
156
157         hfd.call = call;
158         hfd.when = when;
159
160         __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_HISTORY,
161                                         history_call_missed, &hfd);
162 }
163
164 static void history_sms_received(struct ofono_atom *atom, void *data)
165 {
166         struct ofono_history_context *context = __ofono_atom_get_data(atom);
167         struct history_sms_foreach_data *hfd = data;
168
169         if (context->driver->sms_received == NULL)
170                 return;
171
172         context->driver->sms_received(context, hfd->uuid, hfd->address,
173                                         hfd->remote, hfd->local, hfd->text);
174 }
175
176 void __ofono_history_sms_received(struct ofono_modem *modem,
177                                         const struct ofono_uuid *uuid,
178                                         const char *from,
179                                         const struct tm *remote,
180                                         const struct tm *local,
181                                         const char *text)
182 {
183         struct history_sms_foreach_data hfd;
184
185         hfd.uuid = uuid;
186         hfd.address = from;
187         hfd.remote = remote;
188         hfd.local = local;
189         hfd.text = text;
190
191         __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_HISTORY,
192                                         history_sms_received, &hfd);
193 }
194
195 static void history_sms_send_pending(struct ofono_atom *atom, void *data)
196 {
197         struct ofono_history_context *context = __ofono_atom_get_data(atom);
198         struct history_sms_foreach_data *hfd = data;
199
200         if (context->driver->sms_send_pending == NULL)
201                 return;
202
203         context->driver->sms_send_pending(context, hfd->uuid, hfd->address,
204                                                 hfd->when, hfd->text);
205 }
206
207 void __ofono_history_sms_send_pending(struct ofono_modem *modem,
208                                         const struct ofono_uuid *uuid,
209                                         const char *to,
210                                         time_t when, const char *text)
211 {
212         struct history_sms_foreach_data hfd;
213
214         hfd.uuid = uuid;
215         hfd.address = to;
216         hfd.text = text;
217         hfd.when = when;
218         hfd.status = OFONO_HISTORY_SMS_STATUS_PENDING;
219
220         __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_HISTORY,
221                                         history_sms_send_pending, &hfd);
222 }
223
224 static void history_sms_send_status(struct ofono_atom *atom, void *data)
225 {
226         struct ofono_history_context *context = __ofono_atom_get_data(atom);
227         struct history_sms_foreach_data *hfd = data;
228
229         if (context->driver->sms_send_status == NULL)
230                 return;
231
232         context->driver->sms_send_status(context, hfd->uuid,
233                                                 hfd->when, hfd->status);
234 }
235
236 void __ofono_history_sms_send_status(struct ofono_modem *modem,
237                                         const struct ofono_uuid *uuid,
238                                         time_t when,
239                                         enum ofono_history_sms_status status)
240 {
241         struct history_sms_foreach_data hfd;
242
243         hfd.uuid = uuid;
244         hfd.address = NULL;
245         hfd.text = NULL;
246         hfd.when = when;
247         hfd.status = status;
248
249         __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_HISTORY,
250                                         history_sms_send_status, &hfd);
251 }
252
253 int ofono_history_driver_register(const struct ofono_history_driver *driver)
254 {
255         DBG("driver: %p name: %s", driver, driver->name);
256
257         history_drivers = g_slist_prepend(history_drivers, (void *) driver);
258
259         return 0;
260 }
261
262 void ofono_history_driver_unregister(const struct ofono_history_driver *driver)
263 {
264         DBG("driver: %p name: %s", driver, driver->name);
265
266         history_drivers = g_slist_remove(history_drivers, driver);
267 }