1f6c14fbd3724e55cf4d67aed5bbcdac465c666f
[framework/system/smartcard-service.git] / test-client / test-client.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 #include <stdio.h>
18 #include <string.h>
19 #include <glib.h>
20
21 #include "Debug.h"
22 #include "SEService.h"
23 #include "Reader.h"
24 #include "Session.h"
25 #include "APDUHelper.h"
26
27 using namespace smartcard_service_api;
28
29 typedef struct _user_context_t
30 {
31         Session *clientSession;
32         SEServiceHelper *clientService;
33         Channel *clientChannel;
34 }
35 user_context_t;
36
37 /* global variable */
38 GMainLoop *loop = NULL;
39 user_context_t user_context = { 0, };
40
41 void testCloseCallback(int error, void *userData);
42 void testTransmitCallback(unsigned char *buffer, unsigned int length, int error, void *userData);
43 void testOpenChannelCallback(Channel *channel, int error, void *userData);
44 void testGetATRCallback(unsigned char *atr, unsigned int length, int error, void *userData);
45 void testCloseSessionCallback(int error, void *userData);
46 void testOpenSessionCallback(SessionHelper *session, int error, void *userData);
47 void testConnectedCallback(SEServiceHelper *service, void *context);
48
49 class TestEventHandler : public SEServiceListener
50 {
51         void serviceConnected(SEServiceHelper *service, void *userData)
52         {
53                 SCARD_BEGIN();
54                 testConnectedCallback(service, userData);
55                 SCARD_END();
56         }
57
58         void eventHandler(SEServiceHelper *service, char *seName, int event, void *userData)
59         {
60 //              user_context_t *context = (user_context_t *)userData;
61                 vector<ReaderHelper *> readers;
62                 size_t i;
63
64                 SCARD_BEGIN();
65
66                 SCARD_DEBUG("event occured service [%p], seName[%s], event [%d], userData [%p]", service, seName, event, userData);
67
68                 readers = service->getReaders();
69
70                 for (i = 0; i < readers.size(); i++)
71                 {
72                         SCARD_DEBUG("Reader[%d] : name [%s], %s", i, readers[i]->getName(), readers[i]->isSecureElementPresent() ? "available" : "unavailable");
73                 }
74
75                 if (event == 1)
76                 {
77                         testConnectedCallback(service, userData);
78                 }
79
80                 SCARD_END();
81         }
82
83         void errorHandler(SEServiceHelper *service, int error, void *userData)
84         {
85                 SCARD_BEGIN();
86
87                 SCARD_DEBUG("error occured service [%p], error [%d]", service, error);
88
89                 SCARD_END();
90         }
91 };
92
93 TestEventHandler testEventHandler;
94
95 void testCloseCallback(int error, void *userData)
96 {
97         user_context_t *context = (user_context_t *)userData;
98
99         SCARD_DEBUG("result [%d], userData [%p]", error, userData);
100
101         context->clientService->shutdown();
102 }
103
104 void testTransmitCallback(unsigned char *buffer, unsigned int length, int error, void *userData)
105 {
106         ByteArray response(buffer, length);
107         user_context_t *context = (user_context_t *)userData;
108
109         SCARD_DEBUG("buffer [%p], length [%d], error [%d], userData [%p]", buffer, length, error, userData);
110
111         context->clientChannel->close(testCloseCallback, userData);
112 }
113
114 void testOpenChannelCallback(Channel *channel, int error, void *userData)
115 {
116         SCARD_DEBUG("channel [%p]", channel);
117
118         if (error == 0 && channel != NULL)
119         {
120                 ByteArray response;
121                 ByteArray data, command;
122                 int fid = 0x00003150;
123                 user_context_t *context = (user_context_t *)userData;
124
125                 context->clientChannel = channel;
126
127                 response = channel->getSelectResponse();
128
129                 SCARD_DEBUG("response : %s", response.toString());
130
131                 SCARD_DEBUG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
132                 SCARD_DEBUG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
133
134                 data.setBuffer((unsigned char *)&fid, 2);
135                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, data);
136                 context->clientChannel->transmit(command, testTransmitCallback, userData);
137         }
138         else
139         {
140                 SCARD_DEBUG_ERR("openBasicChannel failed");
141         }
142 }
143
144 void testGetATRCallback(unsigned char *atr, unsigned int length, int error, void *userData)
145 {
146 //      unsigned char MF[] = { 0x3F, 0x00 };
147         unsigned char MF[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
148         ByteArray aid, result(atr, length);
149         user_context_t *context = (user_context_t *)userData;
150
151         SCARD_DEBUG("atr[%d] : %s", result.getLength(), result.toString());
152
153         aid.setBuffer(MF, sizeof(MF));
154         context->clientSession->openLogicalChannel(aid, testOpenChannelCallback, userData);
155 }
156
157 void testCloseSessionCallback(int error, void *userData)
158 {
159
160 }
161
162 void testOpenSessionCallback(SessionHelper *session, int error, void *userData)
163 {
164         SCARD_DEBUG("session [%p]", session);
165
166         if (session != NULL)
167         {
168                 user_context_t *context = (user_context_t *)userData;
169
170                 context->clientSession = (Session *)session;
171                 context->clientSession->getATR(testGetATRCallback, userData);
172         }
173         else
174         {
175                 SCARD_DEBUG_ERR("openSession failed");
176         }
177 }
178
179 void testConnectedCallback(SEServiceHelper *service, void *userData)
180 {
181         vector<ReaderHelper *> readers;
182         user_context_t *context = (user_context_t *)userData;
183
184         SCARD_BEGIN();
185
186         if (service != NULL)
187         {
188                 SCARD_DEBUG("callback called, service [%p]", service);
189
190                 context->clientService = service;
191
192                 readers = service->getReaders();
193
194                 if (readers.size() > 0)
195                 {
196                         Reader *reader = NULL;
197
198                         reader = (Reader *)readers[0];
199
200                         SCARD_DEBUG("reader [%p]", reader);
201
202                         reader->openSession(testOpenSessionCallback, userData);
203                 }
204                 else
205                 {
206                         SCARD_DEBUG_ERR("reader is empty");
207                 }
208         }
209         else
210         {
211                 SCARD_DEBUG_ERR("service is NULL");
212         }
213
214         SCARD_END();
215 }
216
217 int main(int argv, char *args[])
218 {
219         SEService *service = new SEService((void *)&user_context, &testEventHandler);
220
221         loop = g_main_new(TRUE);
222         g_main_loop_run(loop);
223
224         if (service != NULL)
225                 delete service;
226
227         return 0;
228 }