Revert "Changed logging to dlog"
[sdk/target/sdbd.git] / src / plugin.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <string.h>
18 #include <dlfcn.h>
19
20 #define TRACE_TAG TRACE_SDB
21 #include "log.h"
22
23 #include "sdb.h"
24
25 #include "hashtable.h"
26 #include "parameter.h"
27 #include "plugin.h"
28 #include "sdbd_plugin.h"
29
30 void* g_plugin_handle = NULL;
31
32 PLUGIN_INIT plugin_init_proc = NULL;
33 PLUGIN_SYNCHRONOUS_CMD_PROC plugin_sync_proc = NULL;
34 PLUGIN_ASYNCHRONOUS_CMD_PROC plugin_async_proc = NULL;
35
36 hashtable* plugin_cmd_hashtable = NULL;
37
38 typedef struct _async_parameter {
39     int cmd;
40     parameters* in;
41     int out_fd;
42 } async_parameter;
43
44 // handler of event to be detected by plugin
45 int plugin_event_handler ( int event_type, parameters* data )
46 {
47     // TODO : implement event handler
48     if ( event_type == PLUGIN_EVENT_PWLOCK || event_type == PLUGIN_EVENT_FMMLOCK ) {
49         if ( data != NULL && data->number_of_parameter == 1 && data->array_of_parameter != NULL
50                 && data->array_of_parameter[0].type == type_int32 ) {
51
52             if ( data->array_of_parameter[0].v_int32 == PLUGIN_RET_ON ) {
53                 // locked
54                 is_pwlocked = 1;
55             } else {
56                 // unlocked
57                 is_pwlocked = 0;
58             }
59
60             send_device_status();
61
62             if ( data != NULL ) {
63                 release_parameters ( data );
64                 free ( data );
65             }
66         }
67     }
68
69     return 0;
70 }
71
72 // register commands that are supported by plugin
73 static int plugin_register_command ( int command, priority cmd_priority )
74 {
75     if ( plugin_cmd_hashtable ) {
76         int ret = hashtable_put ( plugin_cmd_hashtable, command, cmd_priority );
77         D ("register plugin command : cmd(%d), result(%d)\n", command, ret);
78     } else {
79         D ("hashtable is not created\n");
80     }
81     return 0;
82 }
83
84 // return 0 if fail to load sdbd plugin (use default plugin)
85 // return 1 if succeed to load sdbd plugin and get function pointer of plugin_init
86 static int load_plugin_not_default()
87 {
88     plugin_init_proc = NULL;
89     plugin_sync_proc = NULL;
90     plugin_async_proc = NULL;
91
92     g_plugin_handle = dlopen ( PLUGIN_PATH, RTLD_NOW );
93     if ( g_plugin_handle == NULL ) {
94         D ( "failed to dlopen(%s). error: %s\n", PLUGIN_PATH, dlerror() );
95         return 0;
96     }
97
98     plugin_init_proc = dlsym ( g_plugin_handle, PLUGIN_PROC_NAME_INIT );
99     if ( plugin_init_proc == NULL ) {
100         D ( "failed to get the sdbd plugin init function. error: %s\n", dlerror() );
101         dlclose ( g_plugin_handle );
102         g_plugin_handle = NULL;
103         return 0;
104     }
105
106     // if there is no implementation of plugin_sync_proc and plugin_async_proc,
107     // then use default_plugin_sync_proc and default_plugin_async_proc
108     plugin_sync_proc = dlsym ( g_plugin_handle, PLUGIN_PROC_NAME_SYNC_CMD );
109     if ( plugin_sync_proc == NULL ) {
110         plugin_sync_proc = default_plugin_sync_proc;
111     }
112
113     plugin_async_proc = dlsym ( g_plugin_handle, PLUGIN_PROC_NAME_ASYNC_CMD );
114     if ( plugin_async_proc == NULL ) {
115         plugin_async_proc = default_plugin_async_proc;
116     }
117
118     return 1;
119 }
120
121 void load_sdbd_plugin()
122 {
123     int ret;
124
125     plugin_cmd_hashtable = hashtable_create ( ht_size_31 );
126
127     ret = load_plugin_not_default();
128     if ( ret == 0 ) {
129         // use default plugin
130         plugin_init_proc = default_plugin_init;
131         plugin_sync_proc = default_plugin_sync_proc;
132         plugin_async_proc = default_plugin_async_proc;
133
134         D ( "using default plugin interface.\n" );
135     } else {
136         D ( "using sdbd plugin interface.(%s)\n", PLUGIN_PATH );
137
138         plugin_init_proc ( plugin_event_handler, plugin_register_command );
139     }
140
141     // use default plugin feature for the commands or events that are not supported by plugin
142     default_plugin_init ( plugin_event_handler, plugin_register_command );
143 }
144
145 void unload_sdbd_plugin()
146 {
147     if ( plugin_cmd_hashtable ) {
148         hashtable_destroy ( plugin_cmd_hashtable );
149         plugin_cmd_hashtable = NULL;
150     }
151
152     if ( g_plugin_handle ) {
153         dlclose ( g_plugin_handle );
154         g_plugin_handle = NULL;
155     }
156 }
157
158 // return 1 if plugin support given command
159 // return 0 if plugin does not support given command
160 int is_supported_by_plugin ( int cmd )
161 {
162     int ret = 0;
163
164     if ( plugin_cmd_hashtable ) {
165         int value;
166         ret = hashtable_get ( plugin_cmd_hashtable, cmd, &value );
167         D ("get from hashtable : cmd(%d), result(%d)\n", cmd, ret);
168     } else {
169         D ("hashtable is not created\n");
170     }
171
172     return ret;
173 }
174
175 int request_sync_cmd ( int cmd, parameters* in, parameters* out )
176 {
177     int ret, pr;
178
179     out->number_of_parameter = 0;
180     out->array_of_parameter = NULL;
181
182     ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
183     if ( ret == 1 ) {
184         // supported by plugin
185         ret = plugin_sync_proc ( cmd, in, out );
186         if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
187             // not supported by plugin
188             ret = default_plugin_sync_proc ( cmd, in, out );
189         }
190     } else {
191         // not supported by plugin
192         ret = default_plugin_sync_proc ( cmd, in, out );
193     }
194
195     return ret;
196 }
197
198 static void request_async_cmd ( int cmd, parameters* in, int out_fd )
199 {
200     int ret, pr;
201
202     ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
203     if ( ret == 1 ) {
204         // supported by plugin
205         ret = plugin_async_proc ( cmd, in, out_fd );
206         if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
207             // not supported by plugin
208             ret = default_plugin_async_proc ( cmd, in, out_fd );
209         }
210     } else {
211         // not supported by plugin
212         ret = default_plugin_async_proc ( cmd, in, out_fd );
213     }
214
215     release_parameters(in);
216     free(in);
217     sdb_close(out_fd);
218 }
219
220 static void *async_proc_bootstrap_func(void *x)
221 {
222     async_parameter *p = x;
223     request_async_cmd(p->cmd, p->in, p->out_fd);
224     free(p);
225     return 0;
226 }
227
228 static int create_async_proc_thread( int cmd, parameters* in )
229 {
230     async_parameter* async_param;
231     sdb_thread_t t;
232     int s[2];
233
234     if (sdb_socketpair(s)) {
235         release_parameters(in);
236         free(in);
237         D("cannot create async proc socket pair\n");
238         return -1;
239     }
240
241     async_param = (async_parameter*)malloc(sizeof(async_parameter));
242     if (async_param == NULL) {
243         release_parameters(in);
244         free(in);
245         fatal("cannot allocate async_parameter");
246         return -1;
247     }
248
249     async_param->cmd = cmd;
250     async_param->in = in;
251     async_param->out_fd = s[1];
252
253     if (sdb_thread_create(&t, async_proc_bootstrap_func, async_param)) {
254         free(async_param);
255         sdb_close(s[0]);
256         sdb_close(s[1]);
257         release_parameters(in);
258         free(in);
259         D("cannot create async proc thread\n");
260         return -1;
261     }
262
263     D("async proc thread started, %d:%d\n",s[0], s[1]);
264     return s[0];
265 }
266
267 // return 1 if succeed to get capability from plugin
268 // return 0 otherwise
269 int request_capability_to_plugin ( int cap, char* out_buf, unsigned int out_len )
270 {
271     int success = 0;
272     int ret;
273     parameters in, out;
274
275     in.number_of_parameter = 1;
276     in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
277     if (in.array_of_parameter == NULL) {
278         D("failed to allocate memory for the parameter\n");
279         return success;
280     }
281     in.array_of_parameter[0].type = type_int32;
282     in.array_of_parameter[0].v_int32 = cap;
283
284     D ("requested capability : %d\n", cap);
285
286     ret = request_sync_cmd ( PLUGIN_SYNC_CMD_CAPABILITY, &in, &out );
287     if ( ret == PLUGIN_CMD_SUCCESS ) {
288         strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
289         out_buf[out_len - 1] = '\0';
290         success = 1;
291         release_parameters ( &out );
292
293         D ("request capability success : %s\n", out_buf);
294     }
295
296     release_parameters ( &in );
297     return success;
298 }
299
300 // return 1 if allowed by plugin (valid)
301 // return 0 if disallowed by plugin (invalid)
302 int request_validity_to_plugin ( int cmd, const char* in_buf )
303 {
304     int success = 0;
305     int ret;
306     parameters in, out;
307
308     if ( in_buf != NULL ) {
309         in.number_of_parameter = 1;
310         in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
311         if (in.array_of_parameter == NULL) {
312             D("failed to allocate memory for the parameter\n");
313             return success;
314         }
315         in.array_of_parameter[0].type = type_string;
316         in.array_of_parameter[0].v_string.length = strlen ( in_buf );
317         in.array_of_parameter[0].v_string.data = strdup ( in_buf );
318     } else {
319         in.number_of_parameter = 0;
320         in.array_of_parameter = NULL;
321     }
322
323     D ("requested validity : %d, %s\n", cmd, in_buf);
324
325     ret = request_sync_cmd ( cmd, &in, &out );
326     if ( ret == PLUGIN_CMD_SUCCESS ) {
327         success = ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_VALID ) ? 1 : 0;
328         release_parameters ( &out );
329
330         D ("request validity success : %d\n", success);
331     }
332
333     release_parameters ( &in );
334     return success;
335 }
336
337 // return 1 if succeed to convert
338 // return 0 otherwise
339 int request_conversion_to_plugin ( int cmd, const char* in_buf, char* out_buf, unsigned int out_len )
340 {
341     int success = 0;
342     int ret;
343     parameters in, out;
344
345     if ( in_buf != NULL ) {
346         in.number_of_parameter = 1;
347         in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
348         if (in.array_of_parameter == NULL) {
349             D("failed to allocate memory for the parameter\n");
350             return success;
351         }
352         in.array_of_parameter[0].type = type_string;
353         in.array_of_parameter[0].v_string.length = strlen ( in_buf );
354         in.array_of_parameter[0].v_string.data = strdup ( in_buf );
355     } else {
356         in.number_of_parameter = 0;
357         in.array_of_parameter = NULL;
358     }
359
360     ret = request_sync_cmd ( cmd, &in, &out );
361     if ( ret == PLUGIN_CMD_SUCCESS ) {
362         strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
363         out_buf[out_len - 1] = '\0';
364         success = 1;
365         release_parameters ( &out );
366     }
367
368     release_parameters ( &in );
369     return success;
370 }
371
372 // return 1 if locked
373 // return 0 if unlocked
374 // return -1 if request failed
375 int request_lock_state_to_plugin ( int lock_type )
376 {
377     int result = -1;
378     int ret;
379     parameters in, out;
380
381     in.number_of_parameter = 1;
382     in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
383     if (in.array_of_parameter == NULL) {
384         D("failed to allocate memory for the parameter\n");
385         return result;
386     }
387     in.array_of_parameter[0].type = type_int32;
388     in.array_of_parameter[0].v_int32 = lock_type;
389
390     ret = request_sync_cmd ( PLUGIN_SYNC_CMD_GET_LOCK_STATE, &in, &out );
391     if ( ret == PLUGIN_CMD_SUCCESS ) {
392         if ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_ON ) {
393             result = 1;
394         } else {
395             result = 0;
396         }
397         is_pwlocked = result;
398         release_parameters ( &out );
399     }
400
401     release_parameters ( &in );
402
403     return result;
404 }
405
406 // return nonnegative integer that is a socket descriptor for communication
407 //        with async proc thread if success to create async proc thread
408 // return -1 if failed to create async proc thread
409 int request_appcmd_to_plugin ( const char* in_buf )
410 {
411     parameters* in;
412     int fd;
413
414     in = (parameters*)malloc(sizeof(parameters));
415     if (in == NULL) {
416         D("failed to allocate memory for the parameters\n");
417         return -1;
418     }
419
420     if ( in_buf != NULL ) {
421         in->number_of_parameter = 1;
422         in->array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
423         if (in->array_of_parameter == NULL) {
424             free(in);
425             D("failed to allocate memory for the parameter\n");
426             return -1;
427         }
428         in->array_of_parameter[0].type = type_string;
429         in->array_of_parameter[0].v_string.length = strlen ( in_buf );
430         in->array_of_parameter[0].v_string.data = strdup ( in_buf );
431     } else {
432         in->number_of_parameter = 0;
433         in->array_of_parameter = NULL;
434     }
435
436     fd = create_async_proc_thread( PLUGIN_ASYNC_CMD_APPCMD_SERVICE, in );
437
438     return fd;
439 }
440