2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <CommonsJavaScript/Converter.h>
19 #include <CommonsJavaScript/Validator.h>
20 #include <Commons/Exception.h>
21 #include <CommonsJavaScript/PrivateObject.h>
22 #include <CommonsJavaScript/JSUtils.h>
23 #include <CommonsJavaScript/JSCallbackManager.h>
24 #include <CommonsJavaScript/Utils.h>
25 #include <JSWebAPIErrorFactory.h>
26 #include <SecurityExceptions.h>
27 #include <ArgumentValidator.h>
28 #include "SEFactory.h"
29 #include "SEResponseDispatcher.h"
30 #include "JSSESession.h"
31 #include "SEConverter.h"
32 #include "SEAsyncCallbackManager.h"
33 #include "plugin_config.h"
36 using namespace DeviceAPI::Common;
37 using namespace WrtDeviceApis::Commons;
38 using namespace WrtDeviceApis::CommonsJavaScript;
41 #define TIZEN_SESESSION_ATTRIBUTENAME "Session"
42 #define TIZEN_SESESSION_ISCLOSED "isClosed"
45 namespace SecureElement {
47 JSClassDefinition JSSESession::m_classInfo =
50 kJSClassAttributeNone,
51 TIZEN_SESESSION_ATTRIBUTENAME,
60 NULL, //DeleteProperty,
61 NULL, //GetPropertyNames,
62 NULL, //CallAsFunction,
63 NULL, //CallAsConstructor,
64 hasInstance, //HasInstance,
68 JSStaticFunction JSSESession::m_function[] = {
69 {"openBasicChannel", JSSESession::openBasicChannel, kJSPropertyAttributeNone},
70 {"openLogicalChannel", JSSESession::openLogicalChannel, kJSPropertyAttributeNone},
71 {"getATR", JSSESession::getATR, kJSPropertyAttributeNone},
72 {"close", JSSESession::close, kJSPropertyAttributeNone},
73 {"closeChannels", JSSESession::closeChannels, kJSPropertyAttributeNone},
77 JSStaticValue JSSESession::m_property[] =
79 {TIZEN_SESESSION_ISCLOSED, getProperty, NULL, kJSPropertyAttributeReadOnly},
82 JSClassRef JSSESession::m_jsClassRef = JSClassCreate(JSSESession::getClassInfo());
84 JSValueRef JSSESession::getProperty(JSContextRef context, JSObjectRef object,
85 JSStringRef propertyName, JSValueRef* exception)
90 Converter convert(context);
92 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_SESESSION_ISCLOSED)) {
93 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(object));
94 if (NULL == privateObject) {
95 ThrowMsg(NullPointerException, "Private object not set.");
97 ISESessionPtr seSession = privateObject->getObject();
99 return convert.toJSValueRef(seSession->isClosed());
101 } Catch (ConversionException) {
102 LoggerE("ConversionException: " << _rethrown_exception.GetMessage());
103 } Catch (NullPointerException) {
104 LoggerE("NullPointerException: " << _rethrown_exception.GetMessage());
105 } Catch (WrtDeviceApis::Commons::UnknownException) {
106 LoggerE("UnknownExceptionException: " << _rethrown_exception.GetMessage());
107 } Catch (PlatformException) {
108 LoggerE("PlatformExceptionException: " << _rethrown_exception.GetMessage());
109 } Catch (WrtDeviceApis::Commons::Exception) {
110 LoggerE("Exception: " << _rethrown_exception.GetMessage());
113 return JSValueMakeUndefined(context);
116 JSObjectRef JSSESession::createJSObject(JSContextRef context, void *session) {
119 ISESessionPtr seSession = SEFactory::getInstance().createSESessionObject(session);
121 SESessionPrivObject *priv = new SESessionPrivObject(context, seSession);
124 ThrowMsg(NullPointerException, "Can not new a SecureElement object");
127 return JSObjectMake(context, getClassRef(), priv);
130 void JSSESession::initialize(JSContextRef context, JSObjectRef object)
134 void JSSESession::finalize(JSObjectRef object)
136 LoggerD( "entered" );
137 SESessionPrivObject *priv = static_cast<SESessionPrivObject*>( JSObjectGetPrivate( object ) ) ;
138 JSObjectSetPrivate(object, NULL);
139 LoggerD("Deleting SecureElement object");
144 const JSClassRef JSSESession::getClassRef()
147 m_jsClassRef = JSClassCreate(&m_classInfo);
152 const JSClassDefinition* JSSESession::getClassInfo()
157 bool JSSESession::hasInstance(JSContextRef context,
158 JSObjectRef constructor,
159 JSValueRef possibleInstance,
160 JSValueRef* exception)
162 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
165 JSValueRef JSSESession::getATR(JSContextRef context,
167 JSObjectRef thisObject,
168 size_t argumentCount,
169 const JSValueRef arguments[],
170 JSValueRef* exception)
172 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
173 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
176 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
177 if (NULL == privateObject) {
178 LoggerE("private object is null");
179 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
182 ISESessionPtr seSession(privateObject->getObject());
183 SEConverter convert(context);
184 return convert.toJSValueRef(seSession->getATR());
185 } Catch (WrtDeviceApis::Commons::Exception) {
186 LoggerE("Exception: " << _rethrown_exception.GetMessage());
188 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
191 JSValueRef JSSESession::close(JSContextRef context,
193 JSObjectRef thisObject,
194 size_t argumentCount,
195 const JSValueRef arguments[],
196 JSValueRef* exception)
198 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
199 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
202 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
203 if (NULL == privateObject) {
204 LoggerE("private object is null");
205 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
208 ISESessionPtr seSession(privateObject->getObject());
210 return JSValueMakeUndefined(context);
211 } Catch (WrtDeviceApis::Commons::Exception) {
212 LoggerE("Exception: " << _rethrown_exception.GetMessage());
214 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
217 JSValueRef JSSESession::closeChannels(JSContextRef context,
219 JSObjectRef thisObject,
220 size_t argumentCount,
221 const JSValueRef arguments[],
222 JSValueRef* exception)
224 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
225 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
228 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
229 if (NULL == privateObject) {
230 LoggerE("private object is null");
231 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
234 ISESessionPtr seSession(privateObject->getObject());
235 seSession->closeChannels();
236 return JSValueMakeUndefined(context);
237 } Catch (WrtDeviceApis::Commons::Exception) {
238 LoggerE("Exception: " << _rethrown_exception.GetMessage());
240 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::UNKNOWN_ERROR, "Unknown Error");
243 JSValueRef JSSESession::openBasicChannel(JSContextRef context,
245 JSObjectRef thisObject,
246 size_t argumentCount,
247 const JSValueRef arguments[],
248 JSValueRef* exception)
252 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
253 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
255 if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
256 /* 1st argument is mandatory. And 1st argument must be Array. */
257 LoggerE("AID TypeMismatchException!");
258 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
261 JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
263 ArgumentValidator validator(context, argumentCount, arguments);
265 JSObjectRef successCallbackObj = validator.toFunction(1);
266 if (successCallbackObj) {
267 onSuccessForCbm = arguments[1];
270 JSObjectRef errorCallbackObj = validator.toFunction(2, true);
271 if (errorCallbackObj) {
272 onErrorForCbm = arguments[2];
274 } catch (const BasePlatformException &err) {
275 LoggerE(err.getName() << ": " << err.getMessage());
276 return JSWebAPIErrorFactory::postException(context, exception, err);
279 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
280 if (NULL == privateObject) {
281 LoggerE("private object is null");
282 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
285 ISESessionPtr seSession(privateObject->getObject());
286 Converter convert(context);
287 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
289 std::vector<unsigned char> aid = convert.toVectorOfUChars(arguments[0]);
290 if ((aid.size() < 5) || (aid.size() > 16)) {
291 LoggerE("wrong aid length : " << aid.size());
292 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Wrong AID length");
294 EventSEOpenChannelPtr event(new EventSEOpenChannel(aid, true));
295 event->setPrivateData( DPL::StaticPointerCast<IEventPrivateData>(callbackManager) );
296 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
298 seSession->openChannel(event);
300 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
302 return JSValueMakeUndefined(context);
303 } Catch (ConversionException) {
304 LoggerE("ConversionException");
305 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
306 } Catch (WrtDeviceApis::Commons::UnknownException) {
307 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
308 } Catch (WrtDeviceApis::Commons::Exception) {
309 LoggerE("Exception: " << _rethrown_exception.GetMessage());
312 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR,"Unknown Error"));
313 return JSValueMakeUndefined(context);
316 JSValueRef JSSESession::openLogicalChannel(JSContextRef context,
318 JSObjectRef thisObject,
319 size_t argumentCount,
320 const JSValueRef arguments[],
321 JSValueRef* exception)
325 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
326 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
328 if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
329 /* 1st argument is mandatory. And 1st argument must be Array. */
330 LoggerE("AID TypeMismatchException!");
331 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
334 JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
336 ArgumentValidator validator(context, argumentCount, arguments);
338 JSObjectRef successCallbackObj = validator.toFunction(1);
339 if (successCallbackObj) {
340 onSuccessForCbm = arguments[1];
343 JSObjectRef errorCallbackObj = validator.toFunction(2, true);
344 if (errorCallbackObj) {
345 onErrorForCbm = arguments[2];
347 } catch (const BasePlatformException &err) {
348 LoggerE(err.getName() << ": " << err.getMessage());
349 return JSWebAPIErrorFactory::postException(context, exception, err);
352 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
353 if (NULL == privateObject) {
354 LoggerE("private object is null");
355 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
358 ISESessionPtr seSession(privateObject->getObject());
359 Converter convert(context);
360 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
362 std::vector<unsigned char> aid = convert.toVectorOfUChars(arguments[0]);
363 if ((aid.size() < 5) || (aid.size() > 16)) {
364 LoggerE("wrong aid length : " << aid.size());
365 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "Wrong AID length");
367 EventSEOpenChannelPtr event(new EventSEOpenChannel(aid, false));
368 event->setPrivateData( DPL::StaticPointerCast<IEventPrivateData>(callbackManager) );
369 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
371 seSession->openChannel(event);
373 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
375 return JSValueMakeUndefined(context);
376 } Catch (ConversionException) {
377 LoggerE("ConversionException");
378 return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Type Mismatch");
379 } Catch (WrtDeviceApis::Commons::UnknownException) {
380 LoggerE("UnknownException: " << _rethrown_exception.GetMessage());
381 } Catch (WrtDeviceApis::Commons::Exception) {
382 LoggerE("Exception: " << _rethrown_exception.GetMessage());
385 callbackManager->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, JSWebAPIErrorFactory::UNKNOWN_ERROR,"Unknown Error"));
386 return JSValueMakeUndefined(context);