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 static void* 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 plugin_handle = dlopen ( PLUGIN_PATH, RTLD_NOW );
93 if ( plugin_handle == NULL ) {
94 D ( "failed to dlopen(%s). error: %s\n", PLUGIN_PATH, dlerror() );
98 plugin_init_proc = dlsym ( 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 ( plugin_handle );
102 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 ( 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 ( 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 ( plugin_handle ) {
153 dlclose ( plugin_handle );
154 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 static 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 );
222 static void *async_proc_bootstrap_func(void *x)
224 async_parameter *p = x;
225 request_async_cmd(p->cmd, p->in, p->out_fd);
230 static int create_async_proc_thread( int cmd, parameters* in )
232 async_parameter* async_param;
236 if( sdb_socketpair(s) ) {
237 D("cannot create async proc socket pair\n");
241 async_param = ( async_parameter* ) malloc(sizeof(async_parameter));
242 if( async_param == NULL ) fatal("cannot allocate async_parameter");
243 async_param->cmd = cmd;
244 async_param->in = in;
245 async_param->out_fd = s[1];
247 if(sdb_thread_create( &t, async_proc_bootstrap_func, async_param)){
251 D("cannot create async proc thread\n");
255 D("async proc thread started, %d:%d\n",s[0], s[1]);
259 // return 1 if succeed to get capability from plugin
260 // return 0 otherwise
261 int request_capability_to_plugin ( int cap, char* out_buf, unsigned int out_len )
267 in.number_of_parameter = 1;
268 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
269 in.array_of_parameter[0].type = type_int32;
270 in.array_of_parameter[0].v_int32 = cap;
272 D ("requested capability : %d\n", cap);
274 ret = request_sync_cmd ( PLUGIN_SYNC_CMD_CAPABILITY, &in, &out );
275 if ( ret == PLUGIN_CMD_SUCCESS ) {
276 strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
277 out_buf[out_len - 1] = '\0';
279 release_parameters ( &out );
281 D ("request capability success : %s\n", out_buf);
284 release_parameters ( &in );
288 // return 1 if allowed by plugin (valid)
289 // return 0 if disallowed by plugin (invalid)
290 int request_validity_to_plugin ( int cmd, const char* in_buf )
296 if ( in_buf != NULL ) {
297 in.number_of_parameter = 1;
298 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
299 in.array_of_parameter[0].type = type_string;
300 in.array_of_parameter[0].v_string.length = strlen ( in_buf );
301 in.array_of_parameter[0].v_string.data = strdup ( in_buf );
303 in.number_of_parameter = 0;
304 in.array_of_parameter = NULL;
307 D ("requested validity : %d, %s\n", cmd, in_buf);
309 ret = request_sync_cmd ( cmd, &in, &out );
310 if ( ret == PLUGIN_CMD_SUCCESS ) {
311 success = ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_VALID ) ? 1 : 0;
312 release_parameters ( &out );
314 D ("request validity success : %d\n", out.array_of_parameter[0].v_int32);
317 release_parameters ( &in );
321 // return 1 if succeed to convert
322 // return 0 otherwise
323 int request_conversion_to_plugin ( int cmd, const char* in_buf, char* out_buf, unsigned int out_len )
329 in.number_of_parameter = 1;
330 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
331 in.array_of_parameter[0].type = type_string;
332 in.array_of_parameter[0].v_string.length = strlen ( in_buf );
333 in.array_of_parameter[0].v_string.data = strdup ( in_buf );
335 ret = request_sync_cmd ( cmd, &in, &out );
336 if ( ret == PLUGIN_CMD_SUCCESS ) {
337 strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
338 out_buf[out_len - 1] = '\0';
340 release_parameters ( &out );
343 release_parameters ( &in );
347 // return 1 if locked
348 // return 0 if unlocked
349 // return -1 if request failed
350 int request_lock_state_to_plugin ( int lock_type )
356 in.number_of_parameter = 1;
357 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
358 in.array_of_parameter[0].type = type_int32;
359 in.array_of_parameter[0].v_int32 = lock_type;
361 ret = request_sync_cmd ( PLUGIN_SYNC_CMD_GET_LOCK_STATE, &in, &out );
362 if ( ret == PLUGIN_CMD_SUCCESS ) {
363 if ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_ON ) {
368 is_pwlocked = result;
369 release_parameters ( &out );
372 release_parameters ( &in );
377 // return nonnegative integer that is a socket descriptor for communication
378 // with async proc thread if success to create async proc thread
379 // return -1 if failed to create async proc thread
380 int request_appcmd_to_plugin ( const char* in_buf )
385 in = ( parameters* ) malloc ( sizeof ( parameters ) );
386 if ( in_buf != NULL ) {
387 in->number_of_parameter = 1;
388 in->array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
389 in->array_of_parameter[0].type = type_string;
390 in->array_of_parameter[0].v_string.length = strlen ( in_buf );
391 in->array_of_parameter[0].v_string.data = strdup ( in_buf );
393 in->number_of_parameter = 0;
394 in->array_of_parameter = NULL;
397 fd = create_async_proc_thread( PLUGIN_ASYNC_CMD_APPCMD_SERVICE, in );