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 hashtable_put ( plugin_cmd_hashtable, command, cmd_priority );
81 // return 0 if fail to load sdbd plugin (use default plugin)
82 // return 1 if succeed to load sdbd plugin and get function pointer of plugin_init
83 static int load_plugin_not_default()
85 plugin_init_proc = NULL;
86 plugin_sync_proc = NULL;
87 plugin_async_proc = NULL;
89 plugin_handle = dlopen ( PLUGIN_PATH, RTLD_NOW );
90 if ( plugin_handle == NULL ) {
91 D ( "failed to dlopen(%s). error: %s\n", PLUGIN_PATH, dlerror() );
95 plugin_init_proc = dlsym ( plugin_handle, PLUGIN_PROC_NAME_INIT );
96 if ( plugin_init_proc == NULL ) {
97 D ( "failed to get the sdbd plugin init function. error: %s\n", dlerror() );
98 dlclose ( plugin_handle );
103 // if there is no implementation of plugin_sync_proc and plugin_async_proc,
104 // then use default_plugin_sync_proc and default_plugin_async_proc
105 plugin_sync_proc = dlsym ( plugin_handle, PLUGIN_PROC_NAME_SYNC_CMD );
106 if ( plugin_sync_proc == NULL ) {
107 plugin_sync_proc = default_plugin_sync_proc;
110 plugin_async_proc = dlsym ( plugin_handle, PLUGIN_PROC_NAME_ASYNC_CMD );
111 if ( plugin_async_proc == NULL ) {
112 plugin_async_proc = default_plugin_async_proc;
118 void load_sdbd_plugin()
122 plugin_cmd_hashtable = hashtable_create ( ht_size_31 );
124 ret = load_plugin_not_default();
126 // use default plugin
127 plugin_init_proc = default_plugin_init;
128 plugin_sync_proc = default_plugin_sync_proc;
129 plugin_async_proc = default_plugin_async_proc;
131 D ( "using default plugin interface.\n" );
133 D ( "using sdbd plugin interface.(%s)\n", PLUGIN_PATH );
135 plugin_init_proc ( plugin_event_handler, plugin_register_command );
138 // use default plugin feature for the commands or events that are not supported by plugin
139 default_plugin_init ( plugin_event_handler, plugin_register_command );
142 void unload_sdbd_plugin()
144 if ( plugin_cmd_hashtable ) {
145 hashtable_destroy ( plugin_cmd_hashtable );
146 plugin_cmd_hashtable = NULL;
149 if ( plugin_handle ) {
150 dlclose ( plugin_handle );
151 plugin_handle = NULL;
155 // return 1 if plugin support given command
156 // return 0 if plugin does not support given command
157 int is_supported_by_plugin ( int cmd )
161 if ( plugin_cmd_hashtable ) {
163 ret = hashtable_get ( plugin_cmd_hashtable, cmd, &value );
169 static int request_sync_cmd ( int cmd, parameters* in, parameters* out )
173 out->number_of_parameter = 0;
174 out->array_of_parameter = NULL;
176 ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
178 // supported by plugin
179 ret = plugin_sync_proc ( cmd, in, out );
180 if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
181 // not supported by plugin
182 ret = default_plugin_sync_proc ( cmd, in, out );
185 // not supported by plugin
186 ret = default_plugin_sync_proc ( cmd, in, out );
192 static void request_async_cmd ( int cmd, parameters* in, int out_fd )
196 ret = hashtable_get ( plugin_cmd_hashtable, cmd, &pr );
198 // supported by plugin
199 ret = plugin_async_proc ( cmd, in, out_fd );
200 if ( ret == PLUGIN_CMD_NOT_SUPPORT ) {
201 // not supported by plugin
202 ret = default_plugin_async_proc ( cmd, in, out_fd );
205 // not supported by plugin
206 ret = default_plugin_async_proc ( cmd, in, out_fd );
209 release_parameters ( in );
216 static void *async_proc_bootstrap_func(void *x)
218 async_parameter *p = x;
219 request_async_cmd(p->cmd, p->in, p->out_fd);
224 static int create_async_proc_thread( int cmd, parameters* in )
226 async_parameter* async_param;
230 if( sdb_socketpair(s) ) {
231 D("cannot create async proc socket pair\n");
235 async_param = ( async_parameter* ) malloc(sizeof(async_parameter));
236 if( async_param == NULL ) fatal("cannot allocate async_parameter");
237 async_param->cmd = cmd;
238 async_param->in = in;
239 async_param->out_fd = s[1];
241 if(sdb_thread_create( &t, async_proc_bootstrap_func, async_param)){
245 D("cannot create async proc thread\n");
249 D("async proc thread started, %d:%d\n",s[0], s[1]);
253 // return 1 if succeed to get capability from plugin
254 // return 0 otherwise
255 int request_capability_to_plugin ( int cap, char* out_buf, unsigned int out_len )
261 in.number_of_parameter = 1;
262 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
263 in.array_of_parameter[0].type = type_int32;
264 in.array_of_parameter[0].v_int32 = cap;
266 ret = request_sync_cmd ( PLUGIN_SYNC_CMD_CAPABILITY, &in, &out );
267 if ( ret == PLUGIN_CMD_SUCCESS ) {
268 strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
269 out_buf[out_len - 1] = '\0';
271 release_parameters ( &out );
274 release_parameters ( &in );
278 // return 1 if allowed by plugin (valid)
279 // return 0 if disallowed by plugin (invalid)
280 int request_validity_to_plugin ( int cmd, const char* in_buf )
286 if ( in_buf != NULL ) {
287 in.number_of_parameter = 1;
288 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
289 in.array_of_parameter[0].type = type_string;
290 in.array_of_parameter[0].v_string.length = strlen ( in_buf );
291 in.array_of_parameter[0].v_string.data = strdup ( in_buf );
293 in.number_of_parameter = 0;
294 in.array_of_parameter = NULL;
297 ret = request_sync_cmd ( cmd, &in, &out );
298 if ( ret == PLUGIN_CMD_SUCCESS ) {
299 success = ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_VALID ) ? 1 : 0;
300 release_parameters ( &out );
303 release_parameters ( &in );
307 // return 1 if succeed to convert
308 // return 0 otherwise
309 int request_conversion_to_plugin ( int cmd, const char* in_buf, char* out_buf, unsigned int out_len )
315 in.number_of_parameter = 1;
316 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
317 in.array_of_parameter[0].type = type_string;
318 in.array_of_parameter[0].v_string.length = strlen ( in_buf );
319 in.array_of_parameter[0].v_string.data = strdup ( in_buf );
321 ret = request_sync_cmd ( cmd, &in, &out );
322 if ( ret == PLUGIN_CMD_SUCCESS ) {
323 strncpy ( out_buf, out.array_of_parameter[0].v_string.data, out_len - 1 );
324 out_buf[out_len - 1] = '\0';
326 release_parameters ( &out );
329 release_parameters ( &in );
333 // return 1 if locked
334 // return 0 if unlocked
335 // return -1 if request failed
336 int request_lock_state_to_plugin ( int lock_type )
342 in.number_of_parameter = 1;
343 in.array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
344 in.array_of_parameter[0].type = type_int32;
345 in.array_of_parameter[0].v_int32 = lock_type;
347 ret = request_sync_cmd ( PLUGIN_SYNC_CMD_GET_LOCK_STATE, &in, &out );
348 if ( ret == PLUGIN_CMD_SUCCESS ) {
349 if ( out.array_of_parameter[0].v_int32 == PLUGIN_RET_ON ) {
354 is_pwlocked = result;
355 release_parameters ( &out );
358 release_parameters ( &in );
363 // return nonnegative integer that is a socket descriptor for communication
364 // with async proc thread if success to create async proc thread
365 // return -1 if failed to create async proc thread
366 int request_appcmd_to_plugin ( const char* in_buf )
371 in = ( parameters* ) malloc ( sizeof ( parameters ) );
372 if ( in_buf != NULL ) {
373 in->number_of_parameter = 1;
374 in->array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
375 in->array_of_parameter[0].type = type_string;
376 in->array_of_parameter[0].v_string.length = strlen ( in_buf );
377 in->array_of_parameter[0].v_string.data = strdup ( in_buf );
379 in->number_of_parameter = 0;
380 in->array_of_parameter = NULL;
383 fd = create_async_proc_thread( PLUGIN_ASYNC_CMD_APPCMD_SERVICE, in );