Add changelog
[platform/core/connectivity/smartcard-service.git] / server / ServerSEService.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 /* standard library header */
19 #include <stdio.h>
20 #include <string.h>
21 #include <dirent.h>
22 #include <dlfcn.h>
23 #include <errno.h>
24
25 /* SLP library header */
26
27 /* local header */
28 #include "Debug.h"
29 #include "Message.h"
30 #include "TerminalInterface.h"
31 #include "ServerSEService.h"
32 #include "ServerResource.h"
33
34 namespace smartcard_service_api
35 {
36 #define OMAPI_SE_PATH "/usr/lib/se"
37
38         ServerSEService::ServerSEService():SEServiceHelper()
39         {
40         }
41
42         ServerSEService::~ServerSEService()
43         {
44         }
45
46         ServerSEService &ServerSEService::getInstance()
47         {
48                 static ServerSEService seService;
49
50                 return seService;
51         }
52
53         Terminal *ServerSEService::createInstance(void *library)
54         {
55                 Terminal *terminal = NULL;
56                 terminal_create_instance_fn createInstance = NULL;
57
58                 /* create se instance */
59                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
60                 if (createInstance != NULL)
61                 {
62                         terminal = (Terminal *)createInstance();
63                         if (terminal != NULL)
64                         {
65                                 SCARD_DEBUG("terminal [%p]", terminal);
66                         }
67                         else
68                         {
69                                 SCARD_DEBUG_ERR("terminal is null");
70                         }
71                 }
72                 else
73                 {
74                         SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
75                 }
76
77                 return terminal;
78         }
79
80         bool ServerSEService::appendSELibrary(char *library)
81         {
82                 void *libHandle = NULL;
83                 bool result = false;
84
85                 libHandle = dlopen(library, RTLD_LAZY);
86                 if (libHandle != NULL)
87                 {
88                         Terminal *terminal = NULL;
89
90                         terminal = createInstance(libHandle);
91                         if (terminal != NULL)
92                         {
93                                 SCARD_DEBUG("SE info : [%s] [%s]", library, terminal->getName());
94
95                                 libraries.push_back(libHandle);
96
97                                 pair<char *, Terminal *> newPair(terminal->getName(), terminal);
98                                 mapTerminals.insert(newPair);
99
100                                 if (terminal->isSecureElementPresence() == true)
101                                 {
102                                         ServerReader *reader = new ServerReader(this, terminal->getName(), terminal);
103                                         if (reader != NULL)
104                                         {
105                                                 SCARD_DEBUG("register success [%s]", terminal->getName());
106
107                                                 readers.push_back(reader);
108                                         }
109                                         else
110                                         {
111                                                 SCARD_DEBUG_ERR("ServerReader alloc failed [%s]", terminal->getName());
112                                                 /* throw exception */
113                                         }
114                                 }
115                                 else
116                                 {
117                                         SCARD_DEBUG("SE is not ready [%s]", terminal->getName());
118                                 }
119
120                                 result = true;
121                         }
122                         else
123                         {
124                                 SCARD_DEBUG_ERR("createInstance failed [%s]", library);
125
126                                 dlclose(libHandle);
127                         }
128                 }
129                 else
130                 {
131                         SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
132                 }
133
134                 return result;
135         }
136
137         int ServerSEService::openSELibraries()
138         {
139                 int result;
140                 void *libHandle;
141                 DIR *dir = NULL;
142                 struct dirent *entry = NULL;
143
144                 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
145                 {
146                         while ((entry = readdir(dir)) != NULL)
147                         {
148                                 if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
149                                 {
150                                         char fullPath[1024] = { 0, };
151
152                                         /* need additional name rule :) */
153                                         /* open each files */
154                                         libHandle = NULL;
155
156                                         snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
157
158                                         SCARD_DEBUG("se name [%s]", fullPath);
159
160                                         result = appendSELibrary(fullPath);
161                                 }
162                         }
163
164                         closedir(dir);
165
166                         result = 0;
167                 }
168                 else
169                 {
170                         result = -1;
171                 }
172
173                 return result;
174         }
175
176         void ServerSEService::closeSELibraries()
177         {
178                 if (libraries.size() > 0)
179                 {
180                         size_t i;
181
182                         for (i = 0; i < libraries.size(); i++)
183                         {
184                                 if (libraries[i] != NULL)
185                                         dlclose(libraries[i]);
186                         }
187                 }
188         }
189
190         bool ServerSEService::dispatcherCallback(void *message, int socket)
191         {
192                 int count;
193                 ByteArray info;
194                 Message *msg = (Message *)message;
195                 Message response(*msg);
196                 ServerResource &resource = ServerResource::getInstance();
197
198                 if (resource.createService(socket, msg->error) != NULL)
199                 {
200                         SCARD_DEBUG_ERR("client added : pid [%d]", msg->error);
201
202                         response.error = SCARD_ERROR_OK;
203
204                         if ((count = resource.getReadersInformation(info)) > 0)
205                         {
206                                 response.param1 = count;
207                                 response.data = info;
208                         }
209                         else
210                         {
211                                 SCARD_DEBUG("no secure elements");
212                                 response.param1 = 0;
213                         }
214                 }
215                 else
216                 {
217                         SCARD_DEBUG_ERR("createClient failed");
218
219                         response.error = SCARD_ERROR_OUT_OF_MEMORY;
220                 }
221
222                 /* response to client */
223                 ServerIPC::getInstance()->sendMessage(socket, &response);
224
225                 return false;
226         }
227
228         void ServerSEService::terminalCallback(void *terminal, int event, int error, void *user_param)
229         {
230                 Message msg;
231 //              Terminal *term = NULL;
232
233                 switch (event)
234                 {
235                 case Terminal::NOTIFY_SE_AVAILABLE :
236                         /* send all client to refresh reader */
237                         msg.message = msg.MSG_NOTIFY_SE_INSERTED;
238                         msg.data.setBuffer((unsigned char *)terminal,
239                                 strlen((char *)terminal) + 1);
240
241                         ServerResource::getInstance().sendMessageToAllClients(msg);
242                         break;
243
244                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
245                         /* send all client to refresh reader */
246                         msg.message = msg.MSG_NOTIFY_SE_REMOVED;
247                         msg.data.setBuffer((unsigned char *)terminal,
248                                 strlen((char *)terminal) + 1);
249
250                         ServerResource::getInstance().sendMessageToAllClients(msg);
251                         break;
252
253                 default :
254                         break;
255                 }
256         }
257
258 } /* namespace smartcard_service_api */