upload tizen1.0 source
[framework/telephony/libslp-tapi.git] / src / tapi_proxy_common.c
1 /*
2  * libslp-tapi
3  *
4  * Copyright (c) 2011 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 <string.h>
23 #include <stdlib.h>
24
25 #include <dbus/dbus-glib.h>
26 #include <dbus/dbus-glib-lowlevel.h>
27 #include <dbus/dbus.h>
28
29 #include <vconf.h>
30
31 #include "TelDefines.h"
32 #include "tel_cs_conn.h"
33 #include "TapiUtility.h"
34 #include "TelUtility.h"
35 #include "TapiCommon.h"
36 #include "tapi_proxy.h"
37
38 #include "tel_marshaler.h"
39
40 enum {
41         TAPI_SIGNAL0,
42         TAPI_SIGNAL1,
43         TAPI_SIGNAL2,
44         TAPI_SIGNAL3,
45         TAPI_SIGNAL_MAX
46 };
47
48 static char *_evt_sig_members[] = {
49         TAPI_SIGNAL_MEMBER_ARG0,
50         TAPI_SIGNAL_MEMBER_ARG2,
51         TAPI_SIGNAL_MEMBER_ARG4,
52         TAPI_SIGNAL_MEMBER_ARG5,
53 };
54
55 extern char *g_cookie_name;
56 extern int g_cookie_size;
57
58 tapi_dbus_connection_name conn_name;
59
60 typedef enum {
61         TAPI_EVTMODE_NONE,
62         TAPI_EVTMODE_GLIB,
63         TAPI_EVTMODE_ECORE,
64 } TelTapiEvtMode_t;
65
66 typedef struct GDBusEvtItem_t {
67         unsigned int id;
68         DBusGProxy *robj;
69         GCallback cb[4];
70         void *data;
71 } GDBusEvtItem_t;
72
73 typedef struct {
74         void *data;
75         TelAppCallback cb;
76 } UserData_t;
77
78 typedef GCallback (*GDBusConnSig_t)(DBusGProxy *, const char *, void *);
79
80 static GCallback gdbus_conn_signal0(DBusGProxy *robj, const char *member, void *data);
81 static GCallback gdbus_conn_signal2(DBusGProxy *robj, const char *member, void *data);
82 static GCallback gdbus_conn_signal4(DBusGProxy *robj, const char *member, void *data);
83 static GCallback gdbus_conn_signal5(DBusGProxy *robj, const char *member, void *data);
84
85 static GDBusConnSig_t GDBusConnSig[TAPI_SIGNAL_MAX] = { gdbus_conn_signal0, gdbus_conn_signal2, gdbus_conn_signal4,
86                 gdbus_conn_signal5 };
87
88 static DBusGConnection *GDBusHandle = NULL;
89
90 static int _tapi_init_ref_count = 0;
91
92 static GSList *EvtList = NULL;
93 static long int EvtId = 0;
94
95 static TelTapiEvtMode_t EvtMode = TAPI_EVTMODE_NONE;
96
97 #define CHK_EVENT_MODE(MODE) \
98         if (EvtMode != MODE) { \
99                 TAPI_LIB_DEBUG(LEVEL_DEBUG,"Event MODE check failed (current: %d)", EvtMode); \
100                 return TAPI_API_OPERATION_FAILED; \
101         }
102
103 #define CHK_EVENT_INIT_MODE(MODE) \
104         if (EvtMode != MODE && EvtMode != TAPI_EVTMODE_NONE) { \
105                 TAPI_LIB_DEBUG(LEVEL_DEBUG,"Event MODE check failed (current: %d)", EvtMode); \
106                 return TAPI_API_OPERATION_FAILED; \
107         }
108
109 #define EVENT_DUMP(Event) \
110         { \
111                 TAPI_LIB_DEBUG(LEVEL_DEBUG, " Received group is :0x%x", Event.EventClass); \
112                 TAPI_LIB_DEBUG(LEVEL_DEBUG, " received event type is :0x%x", Event.EventType); \
113                 TAPI_LIB_DEBUG(LEVEL_DEBUG, " received requestid is :0x%x", Event.RequestId); \
114                 TAPI_LIB_DEBUG(LEVEL_DEBUG, " received status is :%d", Event.Status); \
115         } \
116
117 static void on_gdbus_event_receive0(DBusGProxy *proxy, void *local_data)
118 {
119         TelTapiEvent_t Event;
120
121         Event.EventClass = -1;
122         Event.EventType = 0;
123         Event.RequestId = -1;
124         Event.Status = 0;
125         Event.pData = NULL;
126         Event.pDataLen = 0;
127
128         EVENT_DUMP(Event);
129
130         /* Contents of parameters is defined by every notification. */
131         UserData_t *user_data;
132         user_data = (UserData_t *) local_data;
133         user_data->cb(&Event, user_data->data);
134
135         TAPI_LIB_DEBUG(LEVEL_DEBUG," Application Callback Invoked successfully ");
136 }
137
138 static void on_gdbus_event_receive2(DBusGProxy *proxy, int type, const char *data, void *local_data)
139 {
140         TelTapiEvent_t Event;
141         guchar *result = NULL;
142         size_t out_len;
143
144         Event.EventClass = -1;
145         Event.EventType = type;
146         Event.RequestId = -1;
147         Event.Status = 0;
148         Event.pData = NULL;
149
150         EVENT_DUMP(Event);
151
152         TAPI_BASE64_DECODE(data, result, &out_len);
153         if (out_len > 0)
154                 Event.pData = result;
155         Event.pDataLen = out_len;
156
157         /* Contents of parameters is defined by every notification. */
158         UserData_t *user_data;
159         user_data = (UserData_t *) local_data;
160         user_data->cb(&Event, user_data->data);
161
162         TAPI_LIB_DEBUG(LEVEL_DEBUG," Application Callback Invoked successfully ");
163
164         if (result)
165                 g_free(result);
166 }
167
168 static void on_gdbus_event_receive4(
169                 DBusGProxy *proxy,
170                 int grp,
171                 int type,
172                 int status,
173                 const char *data,
174                 void *local_data)
175 {
176         TelTapiEvent_t Event;
177         guchar *result = NULL;
178         size_t out_len;
179
180         Event.EventClass = grp;
181         Event.EventType = type;
182         Event.RequestId = -1;
183         Event.Status = status;
184         Event.pData = NULL;
185
186         EVENT_DUMP(Event);
187
188         TAPI_BASE64_DECODE(data, result, &out_len);
189         if (out_len > 0)
190                 Event.pData = result;
191         Event.pDataLen = out_len;
192
193         /* Contents of parameters is defined by every notification. */
194         UserData_t *user_data;
195         user_data = (UserData_t *) local_data;
196         user_data->cb(&Event, user_data->data);
197
198         TAPI_LIB_DEBUG(LEVEL_DEBUG," Application Callback Invoked successfully ");
199         if (result)
200                 g_free(result);
201 }
202
203 static void on_gdbus_event_receive5(
204                 DBusGProxy *proxy,
205                 int grp,
206                 int type,
207                 int req_id,
208                 int status,
209                 const char *data,
210                 void *local_data)
211 {
212         TelTapiEvent_t Event;
213         guchar *result = NULL;
214         size_t out_len = 0;
215
216         Event.EventClass = grp;
217         Event.EventType = type;
218         Event.RequestId = req_id;
219         Event.Status = status;
220         Event.pData = NULL;
221
222         EVENT_DUMP(Event);
223
224
225         TAPI_BASE64_DECODE(data, result, &out_len);
226         Event.pData = result;
227         if (result == NULL){
228                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "result =0x%p", result);
229                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "out_len =%d", out_len);
230                 Event.pDataLen = 0;
231         }
232         else{
233                 Event.pDataLen = out_len;
234         }
235
236         /* Contents of parameters is defined by every notification. */
237         UserData_t *user_data;
238         user_data = (UserData_t *) local_data;
239
240         user_data->cb(&Event, user_data->data);
241
242         TAPI_LIB_DEBUG(LEVEL_DEBUG," Application Callback Invoked successfully ");
243         if (result)
244                 g_free(result);
245 }
246
247 static GCallback gdbus_conn_signal0(DBusGProxy *robj, const char *member, void *data)
248 {
249         dbus_g_proxy_add_signal(robj, member, G_TYPE_INVALID);
250         dbus_g_proxy_connect_signal(robj, member, G_CALLBACK(on_gdbus_event_receive0), data, NULL);
251         return G_CALLBACK(on_gdbus_event_receive0);
252 }
253
254 static GCallback gdbus_conn_signal2(DBusGProxy *robj, const char *member, void *data)
255 {
256         dbus_g_proxy_add_signal(robj, member, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID);
257         dbus_g_proxy_connect_signal(robj, member, G_CALLBACK(on_gdbus_event_receive2), data, NULL);
258         return G_CALLBACK(on_gdbus_event_receive2);
259 }
260
261 static GCallback gdbus_conn_signal4(DBusGProxy *robj, const char *member, void *data)
262 {
263         dbus_g_proxy_add_signal(robj, member, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID);
264         dbus_g_proxy_connect_signal(robj, member, G_CALLBACK(on_gdbus_event_receive4), data, NULL);
265         return G_CALLBACK(on_gdbus_event_receive4);
266 }
267
268 static GCallback gdbus_conn_signal5(DBusGProxy *robj, const char *member, void *data)
269 {
270         dbus_g_proxy_add_signal(robj, member, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID);
271         dbus_g_proxy_connect_signal(robj, member, G_CALLBACK(on_gdbus_event_receive5), data, NULL);
272         return G_CALLBACK(on_gdbus_event_receive5);
273 }
274
275 static void gdbus_del_signal(GDBusEvtItem_t *it)
276 {
277         int i;
278         for (i = 0; i < TAPI_SIGNAL_MAX; i++) {
279                 dbus_g_proxy_disconnect_signal(it->robj, _evt_sig_members[i], G_CALLBACK(it->cb[i]), it->data);
280         }
281         if (it->data) {
282                 free(it->data);
283         }
284         g_free(it);
285 }
286
287 static GDBusEvtItem_t *gdbus_add_signal(const char *event_string, void *data)
288 {
289         GDBusEvtItem_t *it = NULL;
290         DBusGProxy *robj;
291         int i;
292
293         robj = dbus_g_proxy_new_for_name(GDBusHandle, TAPI_SIGNAL_SENDER, TAPI_SIGNAL_OBJPATH, event_string);
294         if (!robj) {
295                 TAPI_LIB_DEBUG(LEVEL_DEBUG,"failed to get proxy for iface: %s", event_string);
296                 return it;
297         }
298
299         it = (GDBusEvtItem_t *) g_malloc0(sizeof(GDBusEvtItem_t));
300         if (!it) {
301                 TAPI_LIB_DEBUG(LEVEL_DEBUG,"failed to allocate item memory");
302                 return it;
303         }
304
305         it->id = EvtId;
306         it->robj = robj;
307         it->data = data;
308
309         if ((EvtList = g_slist_append(EvtList, it)) == NULL) {
310                 TAPI_LIB_DEBUG(LEVEL_ERR, "failed to event info append");
311                 g_free(it);
312                 return NULL;
313         }
314
315         for (i = 0; i < TAPI_SIGNAL_MAX; i++)
316                 it->cb[i] = GDBusConnSig[i](robj, _evt_sig_members[i], data);
317
318         return it;
319 }
320
321 static void _cookie_deinit(void)
322 {
323         if (g_cookie_name)
324                 free(g_cookie_name);
325
326         g_cookie_name = NULL;
327         g_cookie_size = 0;
328 }
329
330 EXPORT_API int tel_init(void)
331 {
332         DBusGConnection *conn;
333         GError *err = NULL;
334
335         TAPI_LIB_DEBUG(LEVEL_DEBUG, "TelTapiInit");
336
337         if (++_tapi_init_ref_count > 1) {
338                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "Already initialized. (ref_count=%d)", _tapi_init_ref_count);
339                 return TAPI_API_SUCCESS;
340         }
341
342         CHK_EVENT_INIT_MODE(TAPI_EVTMODE_GLIB);
343         EvtMode = TAPI_EVTMODE_GLIB;
344
345         if (GDBusHandle)
346                 return TAPI_API_SUCCESS;
347
348         g_type_init();
349
350         conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err);
351         if (conn == NULL) {
352                 TAPI_LIB_DEBUG(LEVEL_ERR, "dbus_bus_get failed: %s", (char *)err->message);
353                 EvtMode = TAPI_EVTMODE_NONE;
354                 return TAPI_API_OPERATION_FAILED;
355         }
356         GDBusHandle = conn;
357
358         EvtId = 0;
359
360         dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT_INT_INT_INT_STRING, G_TYPE_NONE, G_TYPE_INT,
361                         G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID);
362
363         dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT_INT_INT_STRING, G_TYPE_NONE, G_TYPE_INT,
364                         G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID);
365
366         dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT_STRING, G_TYPE_NONE, G_TYPE_INT, G_TYPE_STRING,
367                         G_TYPE_INVALID);
368
369         /* Check TAPI READY vconf */
370         int ts_status = 0;
371         int ret_val;
372
373         ret_val = vconf_get_int(VCONFKEY_TELEPHONY_TAPI_STATE, &ts_status);
374         if (ret_val < 0) {
375                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "[%s] vconf key default set (value=%d)",
376                                 VCONFKEY_TELEPHONY_TAPI_STATE,
377                                 VCONFKEY_TELEPHONY_TAPI_STATE_NONE);
378                 vconf_set_int(VCONFKEY_TELEPHONY_TAPI_STATE, VCONFKEY_TELEPHONY_TAPI_STATE_NONE);
379         }
380
381         return TAPI_API_SUCCESS;
382 }
383
384 EXPORT_API int tel_register_event(int EventType, unsigned int *SubscriptionId, TelAppCallback AppCallBack, void *data)
385 {
386         char event_string[IF_NAME_MAX];
387         GDBusEvtItem_t *it = NULL;
388
389         CHK_EVENT_MODE(TAPI_EVTMODE_GLIB);
390
391         /*      CHECK THE INPUT */
392         TAPI_RET_ERR_NUM_IF_FAIL(AppCallBack, TAPI_API_INVALID_PTR);
393         TAPI_RET_ERR_NUM_IF_FAIL(SubscriptionId, TAPI_API_INVALID_PTR);
394         /*
395          if ((EventType < TAPI_EVENT_CALL_SETUP_CNF) || (EventType > TAPI_EVENT_TYPE_MAX)) {
396          TAPI_LIB_DEBUG(LEVEL_DEBUG,"Unknown EventClass");
397          return TAPI_EVENT_CLASS_UNKNOWN;
398          }
399          */
400         UserData_t *user_data;
401         user_data = (UserData_t *) malloc(sizeof(UserData_t));
402         user_data->data = data;
403         user_data->cb = AppCallBack;
404
405         TAPI_GET_EVENT_NAME(EventType, event_string);
406         TAPI_LIB_DEBUG(LEVEL_DEBUG,"PROXY COMMON EVENT STRING=%s", event_string);
407         it = gdbus_add_signal(event_string, (void *) user_data);
408         if (!it) {
409                 return TAPI_API_OPERATION_FAILED;
410         }
411
412         *SubscriptionId = EvtId++;
413         TAPI_LIB_DEBUG(LEVEL_DEBUG,"Noti Subscribe Successful with id %d", *SubscriptionId);
414
415         return TAPI_API_SUCCESS;
416 }
417
418 EXPORT_API int tel_deregister_event(unsigned int SubscriptionId)
419 {
420         GSList *iter;
421         GDBusEvtItem_t *it;
422         CHK_EVENT_MODE(TAPI_EVTMODE_GLIB);
423         for (iter = EvtList; iter != NULL; iter = iter->next) {
424                 it = (GDBusEvtItem_t *) iter->data;
425                 if (it->id == SubscriptionId) {
426                         gdbus_del_signal(it);
427                         EvtList = g_slist_delete_link(EvtList, iter);
428                         return TAPI_API_SUCCESS;
429                 }
430         }
431
432         return TAPI_API_INVALID_INPUT;
433 }
434
435 static void _tel_remove_signal(gpointer data, gpointer user_data)
436 {
437         GDBusEvtItem_t *it;
438         it = (GDBusEvtItem_t *) data;
439         if (it) {
440                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "TEL_REGI deletenode it=0x%x id=%d",it, it->id);
441                 gdbus_del_signal(it);
442         }
443 }
444
445 EXPORT_API int tel_deinit(void)
446 {
447         TAPI_LIB_DEBUG(LEVEL_DEBUG, "TelTapiDeinit");
448
449         if (--_tapi_init_ref_count > 0) {
450                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "no work. (ref_count=%d)", _tapi_init_ref_count);
451                 return TAPI_API_SUCCESS;
452         }
453
454         TAPI_LIB_DEBUG(LEVEL_DEBUG, "remove all signal");
455
456         g_slist_foreach(EvtList, _tel_remove_signal, NULL);
457         EvtList = NULL;
458         EvtId = 0;
459         EvtMode = TAPI_EVTMODE_NONE;
460         g_slist_free(EvtList);
461
462         _cookie_deinit();
463
464         return TAPI_API_SUCCESS;
465 }
466
467 EXPORT_API int tel_register_app_name(char *name)
468 {
469         if (name == NULL) {
470                 TAPI_LIB_DEBUG(LEVEL_ERR, "The 1st parameter, the connection name, is NULL\n");
471                 return TAPI_API_INVALID_PTR;
472         }
473
474         DBusConnection *dbus_connection = NULL;
475         DBusError err;
476         dbus_error_init(&err);
477
478         if (GDBusHandle) {
479                 dbus_connection = dbus_g_connection_get_connection(GDBusHandle);
480                 if (dbus_bus_request_name(dbus_connection, name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err) < 0) {
481                         TAPI_LIB_DEBUG(LEVEL_ERR, "Fail to request dbus connection name\n");
482                         return TAPI_API_INVALID_OPERATION;
483                 }
484         }
485         else {
486                 TAPI_LIB_DEBUG(LEVEL_ERR, "No valid dbus connection\n");
487         }
488
489         TAPI_LIB_DEBUG(LEVEL_DEBUG,"Request connection name = %s", name );
490         snprintf(conn_name.name, 255, "%s", name);
491         conn_name.length_of_name = strlen(conn_name.name);
492
493         return TAPI_API_SUCCESS;
494 }
495
496 EXPORT_API int tel_get_app_name(tapi_dbus_connection_name *app_name)
497 {
498         if (app_name == NULL) {
499                 TAPI_LIB_DEBUG(LEVEL_ERR, "The 1st parameter, the application name, is NULL\n");
500                 return TAPI_API_INVALID_PTR;
501         }
502
503         snprintf(app_name->name, TAPI_DBUS_CONNECTION_NAME_LEN_MAX, "%s", conn_name.name);
504         app_name->length_of_name = strlen(app_name->name);
505
506         return TAPI_API_SUCCESS;
507 }
508
509 /*
510  This Api interacts with Telephony servers STATUS library to get the ready status
511  According to Lee this new code will be opened only in rel 1.0. Ramu is the author.
512  */
513 EXPORT_API int tel_check_service_ready(int *bStatus)
514 {
515         int ts_status = 0;
516         int ret_val = 0;
517         int api_err = TAPI_API_SUCCESS;
518
519         TAPI_RET_ERR_NUM_IF_FAIL(bStatus, TAPI_API_INVALID_PTR);
520
521         ret_val = vconf_get_int(VCONFKEY_TELEPHONY_TAPI_STATE, (int*) &ts_status);
522         if (ret_val == 0) {
523                 ret_val = 1;
524         }
525         else {
526                 TAPI_LIB_DEBUG(LEVEL_ERR, "[FAIL] GET VCONFKEY_TELEPHONY_TAPI_STATE");
527                 ret_val = -1;
528         }
529
530         /*      for testing     */
531         TAPI_LIB_DEBUG(LEVEL_DEBUG, "NEW: Status Check value is %d", ts_status);
532
533         if (ret_val != 1) {
534                 TAPI_LIB_DEBUG(LEVEL_DEBUG, "GETTING STATUS_TAPI_STATE Failed............\n");
535                 return TAPI_API_SERVER_LAYER_FAILURE;
536         }
537         else {
538                 *bStatus = ts_status;
539                 return TAPI_API_SUCCESS;
540         }
541         return api_err;
542 }
543
544 EXPORT_API int tel_request_tunnel(const TelTunnelInfo_t *pTunnelInfo, int *pRequestId)
545 {
546         int ret = FALSE;
547         int returnStatus = TAPI_API_SUCCESS;
548
549         TAPI_RET_ERR_NUM_IF_FAIL(pRequestId, TAPI_API_INVALID_PTR);
550         TAPI_RET_ERR_NUM_IF_FAIL(pTunnelInfo, TAPI_API_INVALID_PTR);
551
552         if (conn_name.length_of_name == 0) {
553                 TAPI_LIB_DEBUG(LEVEL_ERR, "No dbus connection name");
554                 return TAPI_API_OPERATION_FAILED;
555         }
556
557         /*       check for the RPC link....     */
558         TAPI_RET_ERR_NUM_IF_FAIL(tapi_check_dbus_status(), TAPI_API_SYSTEM_RPC_LINK_DOWN);
559         TAPI_GLIB_INIT_PARAMS();
560
561         TAPI_GLIB_ALLOC_PARAMS(in_param1,in_param2,in_param3,in_param4,out_param1,out_param2,out_param3,out_param4);
562
563         g_array_append_vals(in_param1, pTunnelInfo, sizeof(TelTunnelInfo_t));
564         g_array_append_vals(in_param2, (unsigned char *) (pTunnelInfo->pTunnelData), pTunnelInfo->TunnelDataLen);
565         g_array_append_vals(in_param4, &conn_name, sizeof(tapi_dbus_connection_name));
566
567         ret = tapi_send_request(TAPI_EVENT_CLASS_UTIL, TAPI_CS_UTIL_TUNNEL_REQ, in_param1, in_param2, in_param3, in_param4,
568                         &out_param1, &out_param2, &out_param3, &out_param4);
569
570         if (TRUE == ret) {
571                 returnStatus = g_array_index(out_param1, int , 0);
572                 *pRequestId = g_array_index(out_param2, int , 0);
573         }
574         else {
575                 *pRequestId = -1;
576                 returnStatus = TAPI_API_SYSTEM_RPC_LINK_DOWN;
577         }
578
579         TAPI_LIB_DEBUG(LEVEL_DEBUG, "Tunnel Request: Return Status : %d", returnStatus);
580         TAPI_LIB_DEBUG(LEVEL_DEBUG, "RequestId: %d", *pRequestId);
581
582         TAPI_GLIB_FREE_PARAMS(in_param1,in_param2,in_param3,in_param4,out_param1,out_param2,out_param3,out_param4);
583
584         return returnStatus;
585 }
586
587 /*      EOF     */
588