blob: 97fc89ff601953264b015d0eecb4882274266304 [file] [log] [blame]
Patrick Benavoli68a91282011-08-31 11:23:23 +02001/* <auto_header>
2 * <FILENAME>
3 *
4 * INTEL CONFIDENTIAL
5 * Copyright © 2011 Intel
6 * Corporation All Rights Reserved.
7 *
8 * The source code contained or described herein and all documents related to
9 * the source code ("Material") are owned by Intel Corporation or its suppliers
10 * or licensors. Title to the Material remains with Intel Corporation or its
11 * suppliers and licensors. The Material contains trade secrets and proprietary
12 * and confidential information of Intel or its suppliers and licensors. The
13 * Material is protected by worldwide copyright and trade secret laws and
14 * treaty provisions. No part of the Material may be used, copied, reproduced,
15 * modified, published, uploaded, posted, transmitted, distributed, or
16 * disclosed in any way without Intel’s prior express written permission.
17 *
18 * No license under any patent, copyright, trade secret or other intellectual
19 * property right is granted to or conferred upon you by disclosure or delivery
20 * of the Materials, either expressly, by implication, inducement, estoppel or
21 * otherwise. Any license under such intellectual property rights must be
22 * express and approved by Intel in writing.
23 *
24 * AUTHOR: Patrick Benavoli (patrickx.benavoli@intel.com)
25 * CREATED: 2011-06-01
26 * UPDATED: 2011-07-27
27 *
28 *
29 * </auto_header>
30 */
31#include <dlfcn.h>
32#include <dirent.h>
Patrick Benavoliec0f84e2011-10-27 14:34:38 +020033#include <algorithm>
34#include <ctype.h>
Patrick Benavoli68a91282011-08-31 11:23:23 +020035#include "SystemClass.h"
36#include "SubsystemLibrary.h"
37#include "AutoLog.h"
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +010038#include "VirtualSubsystem.h"
39#include "NamedElementBuilderTemplate.h"
Patrick Benavoli68a91282011-08-31 11:23:23 +020040
41#define base CConfigurableElement
42
Patrick Benavoliec0f84e2011-10-27 14:34:38 +020043// A plugin file name is of the form:
44// lib<type>-subsystem.so
45// The plugin symbol is of the form:
46// get<TYPE>SusbystemBuilder
47
48// Plugin file naming
49const char* gpcPluginPattern = "-subsystem.so";
50const char* gpcLibraryPrefix = "lib";
51
52// Plugin symbol naming
53const char* gpcPluginSymbolPrefix = "get";
54const char* gpcPluginSymbolSuffix = "SusbystemBuilder";
55
Patrick Benavoli68a91282011-08-31 11:23:23 +020056// Used by subsystem plugins
57typedef void (*GetSusbystemBuilder)(CSubsystemLibrary*);
58
Patrick Benavoli95ac0342011-11-07 20:32:51 +010059CSystemClass::CSystemClass() : _pSubsystemLibrary(new CSubsystemLibrary)
Patrick Benavoli68a91282011-08-31 11:23:23 +020060{
61}
62
63CSystemClass::~CSystemClass()
64{
65 delete _pSubsystemLibrary;
66}
67
68bool CSystemClass::childrenAreDynamic() const
69{
70 return true;
71}
72
73string CSystemClass::getKind() const
74{
75 return "SystemClass";
76}
77
78bool CSystemClass::loadSubsystems(string& strError, const vector<string>& astrPluginFolderPaths)
79{
80 CAutoLog autoLlog(this, "Loading subsystem plugins");
81
82 // Plugin list
83 vector<string> astrPluginFiles;
84
85 uint32_t uiFolderLocation;
86
87 for (uiFolderLocation = 0; uiFolderLocation < astrPluginFolderPaths.size(); uiFolderLocation++) {
88
89 // Folder for current SystemClass
Patrick Benavoli95ac0342011-11-07 20:32:51 +010090 string strPluginPath = astrPluginFolderPaths[uiFolderLocation] + "/";
Patrick Benavoli68a91282011-08-31 11:23:23 +020091
92 // Get plugin list
93 getPluginFiles(strPluginPath, astrPluginFiles);
94 }
95 // Check at least one subsystem plugin available
96 if (!astrPluginFiles.size()) {
97
98 // No plugin found?
99 strError = "No subsystem plugin found";
Patrick Benavoli1387bda2011-08-31 11:23:24 +0200100
101 return false;
Patrick Benavoli68a91282011-08-31 11:23:23 +0200102 }
103
104 // Actually load plugins
105 uint32_t uiPlugin;
106 // Start clean
107 _pSubsystemLibrary->clean();
108
109 for (uiPlugin = 0; uiPlugin < astrPluginFiles.size(); uiPlugin++) {
110
111 string strPluginFileName = astrPluginFiles[uiPlugin];
112
113 log("Loading subsystem plugin path \"%s\"", strPluginFileName.c_str());
114
115 void* lib_handle = dlopen(strPluginFileName.c_str(), RTLD_LAZY);
116
117 if (!lib_handle) {
118
119 // Return error
120 const char* pcError = dlerror();
121
122 if (pcError) {
123
124 strError = pcError;
125 } else {
126
127 strError = "Unable to load subsystem plugin " + strPluginFileName;
128 }
129
130 _pSubsystemLibrary->clean();
131
132 return false;
133 }
134
Patrick Benavoliec0f84e2011-10-27 14:34:38 +0200135 // Extract plugin type out of file name
136 string strPluginPattern = gpcPluginPattern;
137 string strLibraryPrefix = gpcLibraryPrefix;
138 // Remove folder
139 int32_t iSlashPos = strPluginFileName.rfind('/') + 1 + strLibraryPrefix.length();
140 // Get type
141 string strPluginType = strPluginFileName.substr(iSlashPos, strPluginFileName.length() - iSlashPos - strPluginPattern.length());
142
143 // Make it upper case
144 std::transform(strPluginType.begin(), strPluginType.end(), strPluginType.begin(), ::toupper);
145
146 // Get plugin symbol
147 string strPluginSymbol = gpcPluginSymbolPrefix + strPluginType + gpcPluginSymbolSuffix;
148
149 // Load symbol from library
150 GetSusbystemBuilder pfnGetSusbystemBuilder = (GetSusbystemBuilder)dlsym(lib_handle, strPluginSymbol.c_str());
Patrick Benavoli68a91282011-08-31 11:23:23 +0200151
152 if (!pfnGetSusbystemBuilder) {
153
Patrick Benavoliec0f84e2011-10-27 14:34:38 +0200154 strError = "Subsystem plugin " + strPluginFileName + " does not contain " + strPluginSymbol + " symbol.";
Patrick Benavoli68a91282011-08-31 11:23:23 +0200155
156 _pSubsystemLibrary->clean();
157
158 return false;
159 }
160
161 // Fill library
162 pfnGetSusbystemBuilder(_pSubsystemLibrary);
163 }
164
Patrick Benavoli6ccab9d2011-11-10 23:21:01 +0100165 // Add virtual subsystem builder
166 _pSubsystemLibrary->addElementBuilder(new TNamedElementBuilderTemplate<CVirtualSubsystem>("Virtual"));
167
Patrick Benavoli68a91282011-08-31 11:23:23 +0200168 return true;
169}
170
171bool CSystemClass::getPluginFiles(const string& strPluginPath, vector<string>& astrPluginFiles) const
172{
173 log("Seeking subsystem plugins from folder \"%s\"", strPluginPath.c_str());
174
175 DIR *dirp;
176 struct dirent *dp;
177
178 if ((dirp = opendir(strPluginPath.c_str())) == NULL) {
179
180 return false;
181 }
182
Patrick Benavoliec0f84e2011-10-27 14:34:38 +0200183 const string strPluginPattern(gpcPluginPattern);
Patrick Benavoli68a91282011-08-31 11:23:23 +0200184
185 // Parse it and load plugins
186 while ((dp = readdir(dirp)) != NULL) {
187
188 string strFileName(dp->d_name);
189
Patrick Benavoliec0f84e2011-10-27 14:34:38 +0200190 // Check file name ends with pattern
Patrick Benavoli68a91282011-08-31 11:23:23 +0200191 size_t uiPatternPos = strFileName.rfind(strPluginPattern, -1);
192
193 if (uiPatternPos != (size_t)-1 && uiPatternPos == strFileName.size() - strPluginPattern.size()) {
194 // Found plugin
195 astrPluginFiles.push_back(strPluginPath + strFileName);
196 }
197 }
198
199 // Close plugin folder
200 closedir(dirp);
201
202 return true;
203}
204
205const CSubsystemLibrary* CSystemClass::getSubsystemLibrary() const
206{
207 return _pSubsystemLibrary;
208}
209
210bool CSystemClass::init(string& strError)
211{
212 return base::init(strError);
213}
214