4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
30 #include "include/mm_sound_plugin.h"
34 static char* __strcatdup(const char *str1, const char *str2);
35 static int _MMSoundPluginGetList(const char *plugdir ,char ***list);
36 static int _MMSoundPluginDestroyList(char **list);
38 char* MMSoundPluginGetTypeName(int type)
40 static char *typename[] = {
46 if (type < MM_SOUND_PLUGIN_TYPE_LAST && type > -1)
47 return typename[type];
49 return "Unknown"; /* error condition */
52 int MMSoundPluginScan(const char *plugindir, const int type, MMSoundPluginType **pluginlist)
55 int err = MM_ERROR_NONE;
58 MMSoundPluginType plugin[100];
63 debug_msg(" Plugin dir :: %s \n", plugindir);
64 err = _MMSoundPluginGetList(plugindir, &list);
65 if (err != MM_ERROR_NONE)
68 while((item = list[index++]) != NULL) {
69 if(MMSoundPluginOpen(item, &plugin[plugin_index]) != MM_ERROR_NONE) {
70 debug_warning("%s is not sound plugin\n", item);
73 if (plugin[plugin_index].type != type)
74 MMSoundPluginClose(&plugin[plugin_index]);
79 _MMSoundPluginDestroyList(list);
81 *pluginlist = (MMSoundPluginType*) malloc(sizeof(MMSoundPluginType) * (plugin_index+1));
82 if ((*pluginlist) == NULL) {
83 debug_critical("Memory allocation fail\n");
84 /* Occur segmentation fault */
85 *pluginlist = (void*)1;
88 memcpy(*pluginlist, plugin, sizeof(MMSoundPluginType) * (plugin_index+1));
89 /* Marking end of array */
90 (*pluginlist)[plugin_index].type = MM_SOUND_PLUGIN_TYPE_NONE;
91 (*pluginlist)[plugin_index].module = NULL;
98 int MMSoundPluginRelease(MMSoundPluginType *pluginlist)
104 while (pluginlist[loop].type != MM_SOUND_PLUGIN_TYPE_NONE) {
105 MMSoundPluginClose(&pluginlist[loop++]);
112 return MM_ERROR_NONE;
115 int MMSoundPluginOpen(char *file, MMSoundPluginType *plugin)
118 int (*func)(void) = NULL;
123 pdll = dlopen(file, RTLD_NOW|RTLD_GLOBAL);
126 debug_error("%s\n", dlerror());
127 return MM_ERROR_SOUND_INVALID_FILE;
130 func = (int (*)(void))dlsym(pdll, "MMSoundGetPluginType");
133 debug_error("Cannot find symbol : MMSoundGetPluginType\n");
134 return MM_ERROR_SOUND_INVALID_FILE;
138 debug_msg("%s is %s\n", file,
139 t == MM_SOUND_PLUGIN_TYPE_CODEC ? "CODEC":
140 t == MM_SOUND_PLUGIN_TYPE_RUN ? "RUN" : "Unknown");
143 case MM_SOUND_PLUGIN_TYPE_CODEC:
144 case MM_SOUND_PLUGIN_TYPE_RUN:
146 plugin->module = pdll;
149 debug_error("Type is %d\n",t);
151 return MM_ERROR_SOUND_INVALID_FILE;
156 return MM_ERROR_NONE;
159 int MMSoundPluginClose(MMSoundPluginType *plugin)
164 dlclose(plugin->module);
165 plugin->type = MM_SOUND_PLUGIN_TYPE_NONE;
166 plugin->module = NULL;
169 return MM_ERROR_NONE;
172 int MMSoundPluginGetSymbol(MMSoundPluginType *plugin, const char *symbol, void **func)
178 if (plugin->module == NULL)
179 return MM_ERROR_SOUND_INVALID_FILE;
180 fn = dlsym(plugin->module, symbol);
182 return MM_ERROR_SOUND_INVALID_FILE;
186 return MM_ERROR_NONE;
188 #define MAX_PATH_SIZE 256
189 static int _MMSoundPluginGetList(const char *plugdir ,char ***list)
191 struct dirent **entry = NULL;
196 static char curdir[MAX_PATH_SIZE];
198 int ret = MM_ERROR_NONE;
200 items = scandir(plugdir, &entry, NULL, alphasort);
201 debug_msg("Items %d\n", items);
204 return MM_ERROR_INVALID_ARGUMENT;
206 temp = (char **)malloc(sizeof(char *) * (items + 1));
208 ret = MM_ERROR_OUT_OF_MEMORY;
211 memset(temp, 0, sizeof(char*) * (items + 1));
212 memset(curdir, '\0', sizeof(curdir));
213 if(NULL == getcwd(curdir, sizeof(curdir)-1)) {
218 ret = MM_ERROR_OUT_OF_STORAGE;
221 /* FIXME : need to handle error case */
222 if (chdir(plugdir) != 0) {
223 debug_error("chdir error\n");
228 ret = MM_ERROR_INVALID_ARGUMENT;
232 for(item_idx = items; item_idx--; ) {
233 if(stat(entry[item_idx]->d_name, &finfo) < 0) {
234 debug_error("Stat error\n");
239 ret = MM_ERROR_INVALID_ARGUMENT;
243 debug_log("item %d is %s\n", item_idx, entry[item_idx]->d_name);
245 if (S_ISREG(finfo.st_mode)) {
246 temp[tn++] = __strcatdup(plugdir, entry[item_idx]->d_name);
251 for(item_idx = 0; item_idx < items; item_idx++) {
252 free(entry[item_idx]);
258 static int _MMSoundPluginDestroyList(char **list)
265 return MM_ERROR_NONE;
268 static char* __strcatdup(const char *str1, const char *str2)
272 len = strlen(str1) + strlen(str2) + 1;
273 dest = (char*) malloc(len*sizeof(char));
276 strncpy(dest, str1, len-1);
277 strncat(dest, str2, len-1);