Code sync from tizen_2.4
[platform/core/telephony/libtcore.git] / src / user_request.c
1 /*
2  * libtcore
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <glib.h>
26
27 #include "tcore.h"
28 #include "user_request.h"
29 #include "communicator.h"
30
31 struct tcore_user_request_type {
32         int ref;
33
34         /* Communicator information */
35         void *user_info;
36         Communicator *comm;
37
38         char *modem_name;
39
40         enum tcore_request_command command;
41
42         void *data;
43         unsigned int data_len;
44
45         void *metainfo;
46         unsigned int metainfo_len;
47
48         UserRequestFreeHook free_hook;
49         GSList *response_hook;
50 };
51
52 struct hook_response_type {
53         UserRequestResponseHook func;
54         void *user_data;
55 };
56
57 UserRequest *tcore_user_request_new(Communicator *comm, const char *modem_name)
58 {
59         UserRequest *ur;
60
61         ur = calloc(1, sizeof(struct tcore_user_request_type));
62         if (!ur)
63                 return NULL;
64
65         ur->comm = comm;
66
67         if (modem_name)
68                 ur->modem_name = strdup(modem_name);
69         else
70                 ur->modem_name = NULL;
71
72         return ur;
73 }
74
75 void tcore_user_request_free(UserRequest *ur)
76 {
77         if (!ur)
78                 return;
79
80         if (ur->ref > 0) {
81                 ur->ref--;
82                 return;
83         }
84
85         g_slist_free_full(ur->response_hook, free);
86
87         if (ur->free_hook)
88                 ur->free_hook(ur);
89
90         if (ur->modem_name)
91                 free(ur->modem_name);
92
93         if (ur->data)
94                 free(ur->data);
95
96         if (ur->metainfo)
97                 free(ur->metainfo);
98
99         dbg("user_request(%p) free.", ur);
100
101         free(ur);
102 }
103
104 UserRequest *tcore_user_request_ref(UserRequest *ur)
105 {
106         if (!ur)
107                 return NULL;
108
109         ur->ref++;
110
111         return ur;
112 }
113
114 void tcore_user_request_unref(UserRequest *ur)
115 {
116         if (!ur)
117                 return;
118
119         if (ur->ref > 0)
120                 ur->ref--;
121         else
122                 tcore_user_request_free(ur);
123
124         return;
125 }
126
127 TReturn tcore_user_request_set_free_hook(UserRequest *ur,
128                 UserRequestFreeHook free_hook)
129 {
130         if (!ur)
131                 return TCORE_RETURN_EINVAL;
132
133         ur->free_hook = free_hook;
134
135         return TCORE_RETURN_SUCCESS;
136 }
137
138 TReturn tcore_user_request_set_response_hook(UserRequest *ur,
139                 UserRequestResponseHook resp_hook, void *user_data)
140 {
141         struct hook_response_type *hook;
142
143         if (!ur)
144                 return TCORE_RETURN_EINVAL;
145
146         hook = calloc(1, sizeof(struct hook_response_type));
147         if (!hook)
148                 return TCORE_RETURN_ENOMEM;
149
150         hook->func = resp_hook;
151         hook->user_data = user_data;
152
153         ur->response_hook = g_slist_append(ur->response_hook, hook);
154
155         return TCORE_RETURN_SUCCESS;
156 }
157
158 Communicator *tcore_user_request_ref_communicator(UserRequest *ur)
159 {
160         if (!ur)
161                 return NULL;
162
163         return ur->comm;
164 }
165
166 char *tcore_user_request_get_modem_name(UserRequest *ur)
167 {
168         if (!ur)
169                 return NULL;
170
171         if (!ur->modem_name)
172                 return NULL;
173
174         return strdup(ur->modem_name);
175 }
176
177 TReturn tcore_user_request_set_user_info(UserRequest *ur, void *user_info)
178 {
179         if (!ur)
180                 return TCORE_RETURN_EINVAL;
181
182         ur->user_info = user_info;
183
184         return TCORE_RETURN_SUCCESS;
185 }
186
187 void *tcore_user_request_ref_user_info(UserRequest *ur)
188 {
189         if (!ur)
190                 return NULL;
191
192         return ur->user_info;
193 }
194
195 TReturn tcore_user_request_send_response(UserRequest *ur,
196                 enum tcore_response_command command,
197                 unsigned int data_len, const void *data)
198 {
199         GSList *list;
200         struct hook_response_type *hook;
201
202         if (!ur) {
203                 dbg("ur is NULL");
204                 return TCORE_RETURN_EINVAL;
205         }
206
207         for (list = ur->response_hook; list;) {
208                 hook = list->data;
209                 list = list->next;
210
211                 if (!hook)
212                         continue;
213
214                 if (hook->func)
215                         hook->func(ur, command, data_len, data, hook->user_data);
216         }
217
218         if (ur->comm) {
219                 return tcore_communicator_send_response(ur->comm, ur,
220                                 command, data_len, data);
221         }
222
223         return TCORE_RETURN_SUCCESS;
224 }
225
226 TReturn tcore_user_request_set_command(UserRequest *ur,
227                 enum tcore_request_command command)
228 {
229         if (!ur)
230                 return TCORE_RETURN_EINVAL;
231
232         ur->command = command;
233
234         return TCORE_RETURN_SUCCESS;
235 }
236
237 enum tcore_request_command tcore_user_request_get_command(UserRequest *ur)
238 {
239         if (!ur)
240                 return 0;
241
242         return ur->command;
243 }
244
245 TReturn tcore_user_request_set_data(UserRequest *ur,
246                 unsigned int data_len, const void *data)
247 {
248         if (!ur)
249                 return TCORE_RETURN_EINVAL;
250
251         if (ur->data != NULL) {
252                 free(ur->data);
253                 ur->data = NULL;
254         }
255
256         ur->data_len = data_len;
257
258         if (data_len > 0) {
259                 if (data != NULL) {
260                         ur->data = calloc(data_len, 1);
261                         if (!ur->data) {
262                                 ur->data_len = 0;
263                                 return TCORE_RETURN_ENOMEM;
264                         }
265
266                         memcpy(ur->data, data, data_len);
267                 } else
268                         ur->data_len = 0;
269         } else
270                 ur->data = NULL;
271
272         return TCORE_RETURN_SUCCESS;
273 }
274
275 TReturn tcore_user_request_set_metainfo(UserRequest *ur,
276                 unsigned int metainfo_len, const void *metainfo)
277 {
278         if (!ur)
279                 return TCORE_RETURN_EINVAL;
280
281         if (ur->metainfo != NULL) {
282                 free(ur->metainfo);
283                 ur->metainfo = NULL;
284         }
285
286         ur->metainfo_len = metainfo_len;
287
288         if (metainfo_len > 0) {
289                 if (metainfo != NULL) {
290                         ur->metainfo = calloc(metainfo_len, 1);
291                         if (!ur->metainfo) {
292                                 ur->metainfo_len = 0;
293                                 return TCORE_RETURN_ENOMEM;
294                         }
295
296                         memcpy(ur->metainfo, metainfo, metainfo_len);
297                 } else
298                         ur->metainfo_len = 0;
299         } else
300                 ur->metainfo = NULL;
301
302         return TCORE_RETURN_SUCCESS;
303 }
304
305 const void *tcore_user_request_ref_data(UserRequest *ur,
306                 unsigned int *data_len)
307 {
308         if (!ur)
309                 return NULL;
310
311         if (data_len)
312                 *data_len = ur->data_len;
313
314         return ur->data;
315 }
316
317 const void *tcore_user_request_ref_metainfo(UserRequest *ur,
318                 unsigned int *metainfo_len)
319 {
320         if (!ur)
321                 return NULL;
322
323         if (metainfo_len)
324                 *metainfo_len = ur->metainfo_len;
325
326         return ur->metainfo;
327 }