2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #define TRACE_TAG TRACE_SDB
25 #include "hashtable.h"
26 #include "parameter.h"
28 #include "sdbd_plugin.h"
30 void* g_plugin_handle = NULL;
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;
36 hashtable* plugin_cmd_hashtable = NULL;
38 typedef struct _async_parameter {
44 // handler of event to be detected by plugin
45 int plugin_event_handler ( int event_type, parameters* data )
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 ) {
52 if ( data->array_of_parameter[0].v_int32 == PLUGIN_RET_ON ) {
63 release_parameters ( data );
72 // register commands that are supported by plugin
73 static int plugin_register_command ( int command, priority cmd_priority )
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);
79 D ("hashtable is not created\n");
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()
88 plugin_init_proc = NULL;
89 plugin_sync_proc = NULL;
90 plugin_async_proc = NULL;
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() );
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;
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;
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;
121 void load_sdbd_plugin()
125 plugin_cmd_hashtable = hashtable_create ( ht_size_31 );
127 ret = load_plugin_not_default();
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;
134 D ( "using default plugin interface.\n" );
136 D ( "using sdbd plugin interface.(%s)\n", PLUGIN_PATH );
138 plugin_init_proc ( plugin_event_handler, plugin_register_command );
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 );
145 void unload_sdbd_plugin()
147 if ( plugin_cmd_hashtable ) {
148 hashtable_destroy ( plugin_cmd_hashtable );
149 plugin_cmd_hashtable = NULL;
152 if ( g_plugin_handle ) {
153 dlclose ( g_plugin_handle );
154 g_plugin_handle = NULL;
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 )
164 if ( plugin_cmd_hashtable ) {
166 ret = hashtable_get ( plugin_cmd_hashtable, cmd, &value );
167 D ("get from hashtable : cmd(%d), result(%d)\n", cmd, ret);
169 D ("hashtable is not created\n");
175 int request_sync_cmd ( int cmd, parameters* in, parameters* out )
179 out->number_of_parameter = 0;
180 out->array_of_parameter = NULL;
182 ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
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 );
191 // not supported by plugin
192 ret = default_plugin_sync_proc ( cmd, in, out );
198 static void request_async_cmd ( int cmd, parameters* in, int out_fd )
202 ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
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 );
211 // not supported by plugin
212 ret = default_plugin_async_proc ( cmd, in, out_fd );
215 release_parameters(in);
220 static void *async_proc_bootstrap_func(void *x)
222 async_parameter *p = x;
223 request_async_cmd(p->cmd, p->in, p->out_fd);
228 static int create_async_proc_thread( int cmd, parameters* in )
230 async_parameter* async_param;
234 if (sdb_socketpair(s)) {
235 release_parameters(in);
237 D("cannot create async proc socket pair\n");
241 async_param = (async_parameter*)malloc(sizeof(async_parameter));
242 if (async_param == NULL) {
243 release_parameters(in);
245 fatal("cannot allocate async_parameter");
249 async_param->cmd = cmd;
250 async_param->in = in;
251 async_param->out_fd = s[1];
253 if (sdb_thread_create(&t, async_proc_bootstrap_func, async_param)) {
257 release_parameters(in);
259 D("cannot create async proc thread\n");
263 D("async proc thread started, %d:%d\n",s[0], s[1]);
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 )
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");
281 in.array_of_parameter[0].type = type_int32;
282 in.array_of_parameter[0].v_int32 = cap;
284 D ("requested capability : %d\n", cap);
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';
291 release_parameters ( &out );
293 D ("request capability success : %s\n", out_buf);
296 release_parameters ( &in );
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 )
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");
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 );
319 in.number_of_parameter = 0;
320 in.array_of_parameter = NULL;
323 D ("requested validity : %d, %s\n", cmd, in_buf);
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 );
330 D ("request validity success : %d\n", success);
333 release_parameters ( &in );
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 )
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");
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 );
356 in.number_of_parameter = 0;
357 in.array_of_parameter = NULL;
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';
365 release_parameters ( &out );
368 release_parameters ( &in );
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 )
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");
387 in.array_of_parameter[0].type = type_int32;
388 in.array_of_parameter[0].v_int32 = lock_type;
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 ) {
397 is_pwlocked = result;
398 release_parameters ( &out );
401 release_parameters ( &in );
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 )
414 in = (parameters*)malloc(sizeof(parameters));
416 D("failed to allocate memory for the parameters\n");
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) {
425 D("failed to allocate memory for the parameter\n");
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 );
432 in->number_of_parameter = 0;
433 in->array_of_parameter = NULL;
436 fd = create_async_proc_thread( PLUGIN_ASYNC_CMD_APPCMD_SERVICE, in );