2f8e1497ee04db4f69859d00ad4f884e95f9c939
[framework/web/wrt-plugins-tizen.git] / src / SecureElement / JSSESession.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18
19 #include <dpl/log/log.h>
20 #include <CommonsJavaScript/Converter.h>
21 #include <CommonsJavaScript/Validator.h>
22 #include <Commons/Exception.h>
23 #include <CommonsJavaScript/PrivateObject.h>
24 #include <CommonsJavaScript/JSUtils.h>
25 #include <CommonsJavaScript/JSCallbackManager.h>
26 #include <CommonsJavaScript/Utils.h>
27 #include <JSTizenExceptionFactory.h>
28 #include <JSTizenException.h>
29 #include <SecurityExceptions.h>
30 #include "SEFactory.h"
31 #include "SEResponseDispatcher.h"
32 #include "JSSESession.h"
33 #include "SEConverter.h"
34 #include "SEAsyncCallbackManager.h"
35
36
37
38 using namespace DeviceAPI::Common;
39 using namespace WrtDeviceApis::Commons;
40 using namespace WrtDeviceApis::CommonsJavaScript;
41 using namespace DPL;
42
43 #define TIZEN_SESESSION_ATTRIBUTENAME "Session"
44 #define TIZEN_SESESSION_ISCLOSED "isClosed"
45
46 namespace DeviceAPI {
47 namespace SecureElement {
48
49  JSClassDefinition JSSESession::m_classInfo =
50 {
51     0,
52     kJSClassAttributeNone,
53     TIZEN_SESESSION_ATTRIBUTENAME,
54     0,
55     m_property,
56     m_function,
57     initialize,
58     finalize,
59     NULL, //hasProperty,
60     NULL,
61     NULL, //setProperty,
62     NULL, //DeleteProperty,
63     NULL, //GetPropertyNames,
64     NULL, //CallAsFunction,
65     NULL, //CallAsConstructor,
66     hasInstance, //HasInstance,
67     NULL  //ConvertToType
68 };
69
70 JSStaticFunction JSSESession::m_function[] = {
71     {"openBasicChannel", JSSESession::openBasicChannel, kJSPropertyAttributeNone},
72     {"openLogicalChannel", JSSESession::openLogicalChannel, kJSPropertyAttributeNone},
73     {"getATR", JSSESession::getATR, kJSPropertyAttributeNone},
74     {"close", JSSESession::close, kJSPropertyAttributeNone},
75     {"closeChannels", JSSESession::closeChannels, kJSPropertyAttributeNone},
76     { 0, 0, 0}
77 };
78
79 JSStaticValue JSSESession::m_property[] =
80 {
81         {TIZEN_SESESSION_ISCLOSED,  getProperty, NULL, kJSPropertyAttributeReadOnly},
82         { 0, 0, 0, 0 }
83 };
84 JSClassRef JSSESession::m_jsClassRef = JSClassCreate(JSSESession::getClassInfo());
85
86 JSValueRef JSSESession::getProperty(JSContextRef context, JSObjectRef object,
87         JSStringRef propertyName, JSValueRef* exception)
88 {
89         LogDebug("Enter");
90
91         Try     {
92                 Converter convert(context);
93
94                 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_SESESSION_ISCLOSED)) {
95                         SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(object));
96                         if (NULL == privateObject) {
97                                 ThrowMsg(NullPointerException, "Private object not set.");
98                         }
99                         ISESessionPtr seSession = privateObject->getObject();
100                         
101                         return convert.toJSValueRef(seSession->isClosed());
102                 }
103         } Catch (ConversionException) {
104                 LogError("ConversionException: " << _rethrown_exception.GetMessage());
105         } Catch (NullPointerException) {
106                 LogError("NullPointerException: " << _rethrown_exception.GetMessage());
107         } Catch (UnknownException) {
108                 LogError("UnknownExceptionException: " << _rethrown_exception.GetMessage());
109         } Catch (PlatformException) {
110                 LogError("PlatformExceptionException: " << _rethrown_exception.GetMessage());
111         } Catch (WrtDeviceApis::Commons::Exception) {
112                 LogError("Exception: " << _rethrown_exception.GetMessage());
113         }
114
115     return JSValueMakeUndefined(context);
116 }
117
118 JSObjectRef JSSESession::createJSObject(JSContextRef context, void *session) {
119         LogDebug("entered");
120
121         ISESessionPtr seSession = SEFactory::getInstance().createSESessionObject(session);
122         
123         SESessionPrivObject *priv = new SESessionPrivObject(context, seSession);
124
125         if (!priv) {
126                 ThrowMsg(NullPointerException, "Can not new a SecureElement object");
127         }
128
129         return JSObjectMake(context, getClassRef(), priv);
130 }
131
132 void JSSESession::initialize(JSContextRef context, JSObjectRef object)
133 {
134 }
135
136 void JSSESession::finalize(JSObjectRef object)
137 {
138         LogDebug( "entered" );
139         SESessionPrivObject *priv = static_cast<SESessionPrivObject*>( JSObjectGetPrivate( object ) ) ;
140         JSObjectSetPrivate(object, NULL);
141         LogDebug("Deleting SecureElement object");
142         delete priv;
143 }
144
145
146 const JSClassRef JSSESession::getClassRef()
147 {
148         if (!m_jsClassRef) {
149                 m_jsClassRef = JSClassCreate(&m_classInfo);
150         }
151         return m_jsClassRef;
152 }
153
154 const JSClassDefinition* JSSESession::getClassInfo()
155 {
156         return &m_classInfo;
157 }
158
159 bool JSSESession::hasInstance(JSContextRef context,
160         JSObjectRef constructor,
161         JSValueRef possibleInstance,
162         JSValueRef* exception)
163 {
164     return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
165 }
166
167 JSValueRef JSSESession::getATR(JSContextRef context,
168         JSObjectRef object,
169         JSObjectRef thisObject,
170         size_t argumentCount,
171         const JSValueRef arguments[],
172         JSValueRef* exception)
173 {
174         SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
175         if (NULL == privateObject) {
176                 LogError("private object is null");
177                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
178         }
179
180         ISESessionPtr seSession(privateObject->getObject());
181         SEConverter convert(context);
182         return convert.toJSValueRef(seSession->getATR());
183 }
184
185 JSValueRef JSSESession::close(JSContextRef context,
186         JSObjectRef object,
187         JSObjectRef thisObject,
188         size_t argumentCount,
189         const JSValueRef arguments[],
190         JSValueRef* exception)
191 {
192         SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
193         if (NULL == privateObject) {
194                 LogError("private object is null");
195                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
196         }
197
198         ISESessionPtr seSession(privateObject->getObject());
199         seSession->close();
200         return JSValueMakeUndefined(context);
201 }
202
203 JSValueRef JSSESession::closeChannels(JSContextRef context,
204         JSObjectRef object,
205         JSObjectRef thisObject,
206         size_t argumentCount,
207         const JSValueRef arguments[],
208         JSValueRef* exception)
209 {
210         SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
211         if (NULL == privateObject) {
212                 LogError("private object is null");
213                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
214         }
215
216         ISESessionPtr seSession(privateObject->getObject());
217         seSession->closeChannels();
218         return JSValueMakeUndefined(context);
219 }
220
221 JSValueRef JSSESession::openBasicChannel(JSContextRef context,
222         JSObjectRef object,
223         JSObjectRef thisObject,
224         size_t argumentCount,
225         const JSValueRef arguments[],
226         JSValueRef* exception)
227 {
228         LogDebug("Entered ");
229
230         Validator validator(context, exception);
231
232         if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
233                 /* 1st argument is mandatory. And 1st argument must be Array. */
234                 LogError("AID TypeMismatchException!");
235                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
236         }
237
238         if (JSValueIsNull(context, arguments[1]) || JSValueIsUndefined(context, arguments[1]) || !validator.isCallback(arguments[1])) {
239                 /* 2st argument is mandatory. And 1st argument must be Array. */
240                 LogError("SEChannelSuccessCallback TypeMismatchException!");
241                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
242         }
243
244         if ((argumentCount > 2) && !JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
245                 if (!validator.isCallback(arguments[2])) {
246                         /* 3nd argument must be Callback. */
247                         LogError("ErrorCallback TypeMismatchException!");
248                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
249                 }
250         }
251
252         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
253         if (validator.isCallback(arguments[1])) {
254                 onSuccessForCbm = arguments[1];
255         }
256
257         if ((argumentCount > 2) && validator.isCallback(arguments[2])) {
258                 onErrorForCbm = arguments[2];
259         }
260
261         SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
262         if (NULL == privateObject) {
263                 LogError("private object is null");
264                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
265         }
266
267         ISESessionPtr seSession(privateObject->getObject());
268         Converter convert(context);
269         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
270         Try {
271                 EventSEOpenChannelPtr event(new EventSEOpenChannel(convert.toVectorOfUChars(arguments[0]), true));
272                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
273                 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
274
275                 seSession->openChannel(event);
276
277                 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
278
279                 return JSValueMakeUndefined(context);
280         } Catch (ConversionException) {
281                 LogError("ConversionException");
282                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
283         } Catch (InvalidArgumentException) {
284                 LogError("InvalidArgumentException");
285                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values"));
286                 return JSValueMakeUndefined(context);
287         } Catch (PlatformException) {
288                 LogError("PlatformException: " << _rethrown_exception.GetMessage());
289                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available"));
290                 return JSValueMakeUndefined(context);
291         } Catch (UnknownException) {
292                 LogError("UnknownException: " << _rethrown_exception.GetMessage());
293         } Catch (WrtDeviceApis::Commons::Exception) {
294                 LogError("Exception: " << _rethrown_exception.GetMessage());
295         }
296
297         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
298         return JSValueMakeUndefined(context);
299 }
300
301 JSValueRef JSSESession::openLogicalChannel(JSContextRef context,
302         JSObjectRef object,
303         JSObjectRef thisObject,
304         size_t argumentCount,
305         const JSValueRef arguments[],
306         JSValueRef* exception)
307 {
308         LogDebug("Entered ");
309
310         Validator validator(context, exception);
311
312         if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
313                 /* 1st argument is mandatory. And 1st argument must be Array. */
314                 LogError("AID TypeMismatchException!");
315                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
316         }
317
318         if (JSValueIsNull(context, arguments[1]) || JSValueIsUndefined(context, arguments[1]) || !validator.isCallback(arguments[1])) {
319                 /* 2st argument is mandatory. And 1st argument must be Array. */
320                 LogError("SEChannelSuccessCallback TypeMismatchException!");
321                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
322         }
323
324         if ((argumentCount > 2) && !JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
325                 if (!validator.isCallback(arguments[2])) {
326                         /* 3nd argument must be Callback. */
327                         LogError("ErrorCallback TypeMismatchException!");
328                         return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
329                 }
330         }
331
332         JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
333         if (validator.isCallback(arguments[1])) {
334                 onSuccessForCbm = arguments[1];
335         }
336
337         if ((argumentCount > 2) && validator.isCallback(arguments[2])) {
338                 onErrorForCbm = arguments[2];
339         }
340
341         SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
342         if (NULL == privateObject) {
343                 LogError("private object is null");
344                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
345         }
346
347         ISESessionPtr seSession(privateObject->getObject());
348         Converter convert(context);
349         JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
350         Try {
351                 EventSEOpenChannelPtr event(new EventSEOpenChannel(convert.toVectorOfUChars(arguments[0]), false));
352                 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
353                 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
354
355                 seSession->openChannel(event);
356
357                 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
358
359                 return JSValueMakeUndefined(context);
360         } Catch (ConversionException) {
361                 LogError("ConversionException");
362                 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
363         } Catch (InvalidArgumentException) {
364                 LogError("InvalidArgumentException");
365                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::INVALID_VALUES_ERROR, "Invalid Values"));
366                 return JSValueMakeUndefined(context);
367         } Catch (PlatformException) {
368                 LogError("PlatformException: " << _rethrown_exception.GetMessage());
369                 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::SERVICE_NOT_AVAILABLE, "Service Not Available"));
370                 return JSValueMakeUndefined(context);
371         } Catch (UnknownException) {
372                 LogError("UnknownException: " << _rethrown_exception.GetMessage());
373         } Catch (WrtDeviceApis::Commons::Exception) {
374                 LogError("Exception: " << _rethrown_exception.GetMessage());
375         }
376
377         callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
378         return JSValueMakeUndefined(context);
379 }
380
381 }
382 }