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.
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 #include "plugin_config.h"
38 using namespace DeviceAPI::Common;
39 using namespace WrtDeviceApis::Commons;
40 using namespace WrtDeviceApis::CommonsJavaScript;
43 #define TIZEN_SESESSION_ATTRIBUTENAME "Session"
44 #define TIZEN_SESESSION_ISCLOSED "isClosed"
47 namespace SecureElement {
49 JSClassDefinition JSSESession::m_classInfo =
52 kJSClassAttributeNone,
53 TIZEN_SESESSION_ATTRIBUTENAME,
62 NULL, //DeleteProperty,
63 NULL, //GetPropertyNames,
64 NULL, //CallAsFunction,
65 NULL, //CallAsConstructor,
66 hasInstance, //HasInstance,
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},
79 JSStaticValue JSSESession::m_property[] =
81 {TIZEN_SESESSION_ISCLOSED, getProperty, NULL, kJSPropertyAttributeReadOnly},
84 JSClassRef JSSESession::m_jsClassRef = JSClassCreate(JSSESession::getClassInfo());
86 JSValueRef JSSESession::getProperty(JSContextRef context, JSObjectRef object,
87 JSStringRef propertyName, JSValueRef* exception)
92 Converter convert(context);
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.");
99 ISESessionPtr seSession = privateObject->getObject();
101 return convert.toJSValueRef(seSession->isClosed());
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());
115 return JSValueMakeUndefined(context);
118 JSObjectRef JSSESession::createJSObject(JSContextRef context, void *session) {
121 ISESessionPtr seSession = SEFactory::getInstance().createSESessionObject(session);
123 SESessionPrivObject *priv = new SESessionPrivObject(context, seSession);
126 ThrowMsg(NullPointerException, "Can not new a SecureElement object");
129 return JSObjectMake(context, getClassRef(), priv);
132 void JSSESession::initialize(JSContextRef context, JSObjectRef object)
136 void JSSESession::finalize(JSObjectRef object)
138 LogDebug( "entered" );
139 SESessionPrivObject *priv = static_cast<SESessionPrivObject*>( JSObjectGetPrivate( object ) ) ;
140 JSObjectSetPrivate(object, NULL);
141 LogDebug("Deleting SecureElement object");
146 const JSClassRef JSSESession::getClassRef()
149 m_jsClassRef = JSClassCreate(&m_classInfo);
154 const JSClassDefinition* JSSESession::getClassInfo()
159 bool JSSESession::hasInstance(JSContextRef context,
160 JSObjectRef constructor,
161 JSValueRef possibleInstance,
162 JSValueRef* exception)
164 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
167 JSValueRef JSSESession::getATR(JSContextRef context,
169 JSObjectRef thisObject,
170 size_t argumentCount,
171 const JSValueRef arguments[],
172 JSValueRef* exception)
174 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
175 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
178 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
179 if (NULL == privateObject) {
180 LogError("private object is null");
181 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
184 ISESessionPtr seSession(privateObject->getObject());
185 SEConverter convert(context);
186 return convert.toJSValueRef(seSession->getATR());
187 } Catch (WrtDeviceApis::Commons::Exception) {
188 LogError("Exception: " << _rethrown_exception.GetMessage());
190 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
193 JSValueRef JSSESession::close(JSContextRef context,
195 JSObjectRef thisObject,
196 size_t argumentCount,
197 const JSValueRef arguments[],
198 JSValueRef* exception)
200 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
201 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
204 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
205 if (NULL == privateObject) {
206 LogError("private object is null");
207 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
210 ISESessionPtr seSession(privateObject->getObject());
212 return JSValueMakeUndefined(context);
213 } Catch (WrtDeviceApis::Commons::Exception) {
214 LogError("Exception: " << _rethrown_exception.GetMessage());
216 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
219 JSValueRef JSSESession::closeChannels(JSContextRef context,
221 JSObjectRef thisObject,
222 size_t argumentCount,
223 const JSValueRef arguments[],
224 JSValueRef* exception)
226 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
227 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
230 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
231 if (NULL == privateObject) {
232 LogError("private object is null");
233 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
236 ISESessionPtr seSession(privateObject->getObject());
237 seSession->closeChannels();
238 return JSValueMakeUndefined(context);
239 } Catch (WrtDeviceApis::Commons::Exception) {
240 LogError("Exception: " << _rethrown_exception.GetMessage());
242 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::UNKNOWN_ERROR, "Unknown Error");
245 JSValueRef JSSESession::openBasicChannel(JSContextRef context,
247 JSObjectRef thisObject,
248 size_t argumentCount,
249 const JSValueRef arguments[],
250 JSValueRef* exception)
252 LogDebug("Entered ");
254 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
255 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
257 Validator validator(context, exception);
259 if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
260 /* 1st argument is mandatory. And 1st argument must be Array. */
261 LogError("AID TypeMismatchException!");
262 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
265 if (JSValueIsNull(context, arguments[1]) || JSValueIsUndefined(context, arguments[1]) || !validator.isCallback(arguments[1])) {
266 /* 2st argument is mandatory. And 1st argument must be Array. */
267 LogError("SEChannelSuccessCallback TypeMismatchException!");
268 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
271 if ((argumentCount > 2) && !JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
272 if (!validator.isCallback(arguments[2])) {
273 /* 3nd argument must be Callback. */
274 LogError("ErrorCallback TypeMismatchException!");
275 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
279 JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
280 if (validator.isCallback(arguments[1])) {
281 onSuccessForCbm = arguments[1];
284 if ((argumentCount > 2) && validator.isCallback(arguments[2])) {
285 onErrorForCbm = arguments[2];
288 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
289 if (NULL == privateObject) {
290 LogError("private object is null");
291 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
294 ISESessionPtr seSession(privateObject->getObject());
295 Converter convert(context);
296 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
298 std::vector<unsigned char> aid = convert.toVectorOfUChars(arguments[0]);
299 if ((aid.size() < 5) || (aid.size() > 16)) {
300 LogError("wrong aid length : " << aid.size());
301 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Wrong AID length");
303 EventSEOpenChannelPtr event(new EventSEOpenChannel(aid, true));
304 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
305 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
307 seSession->openChannel(event);
309 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
311 return JSValueMakeUndefined(context);
312 } Catch (ConversionException) {
313 LogError("ConversionException");
314 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
315 } Catch (UnknownException) {
316 LogError("UnknownException: " << _rethrown_exception.GetMessage());
317 } Catch (WrtDeviceApis::Commons::Exception) {
318 LogError("Exception: " << _rethrown_exception.GetMessage());
321 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
322 return JSValueMakeUndefined(context);
325 JSValueRef JSSESession::openLogicalChannel(JSContextRef context,
327 JSObjectRef thisObject,
328 size_t argumentCount,
329 const JSValueRef arguments[],
330 JSValueRef* exception)
332 LogDebug("Entered ");
334 AceSecurityStatus status = SECURE_ELEMENT_CHECK_ACCESS(SECUREELEMENT_FUNCTION_API_FUNCS);
335 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
337 Validator validator(context, exception);
339 if ((argumentCount < 2) || JSValueIsNull(context, arguments[0]) || JSValueIsUndefined(context, arguments[0]) || !JSIsArrayValue(context, arguments[0])) {
340 /* 1st argument is mandatory. And 1st argument must be Array. */
341 LogError("AID TypeMismatchException!");
342 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
345 if (JSValueIsNull(context, arguments[1]) || JSValueIsUndefined(context, arguments[1]) || !validator.isCallback(arguments[1])) {
346 /* 2st argument is mandatory. And 1st argument must be Array. */
347 LogError("SEChannelSuccessCallback TypeMismatchException!");
348 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
351 if ((argumentCount > 2) && !JSValueIsNull(context, arguments[2]) && !JSValueIsUndefined(context, arguments[2])) {
352 if (!validator.isCallback(arguments[2])) {
353 /* 3nd argument must be Callback. */
354 LogError("ErrorCallback TypeMismatchException!");
355 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
359 JSValueRef onSuccessForCbm = NULL, onErrorForCbm = NULL;
360 if (validator.isCallback(arguments[1])) {
361 onSuccessForCbm = arguments[1];
364 if ((argumentCount > 2) && validator.isCallback(arguments[2])) {
365 onErrorForCbm = arguments[2];
368 SESessionPrivObject* privateObject = static_cast<SESessionPrivObject*>(JSObjectGetPrivate(thisObject));
369 if (NULL == privateObject) {
370 LogError("private object is null");
371 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
374 ISESessionPtr seSession(privateObject->getObject());
375 Converter convert(context);
376 JSCallbackManagerPtr callbackManager = JSCallbackManager::createObject(privateObject->getContext(), onSuccessForCbm, onErrorForCbm, true, true);
378 std::vector<unsigned char> aid = convert.toVectorOfUChars(arguments[0]);
379 if ((aid.size() < 5) || (aid.size() > 16)) {
380 LogError("wrong aid length : " << aid.size());
381 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::INVALID_VALUES_ERROR, "Wrong AID length");
383 EventSEOpenChannelPtr event(new EventSEOpenChannel(aid, false));
384 event->setPrivateData( StaticPointerCast<IEventPrivateData>(callbackManager) );
385 event->setForAsynchronousCall(&SEResponseDispatcher::getInstance());
387 seSession->openChannel(event);
389 SEAsyncCallbackManagerSingleton::Instance().registerCallbackManager(callbackManager, privateObject->getContext());
391 return JSValueMakeUndefined(context);
392 } Catch (ConversionException) {
393 LogError("ConversionException");
394 return JSTizenExceptionFactory::postException(context, exception, JSTizenException::TYPE_MISMATCH_ERROR, "Type Mismatch");
395 } Catch (UnknownException) {
396 LogError("UnknownException: " << _rethrown_exception.GetMessage());
397 } Catch (WrtDeviceApis::Commons::Exception) {
398 LogError("Exception: " << _rethrown_exception.GetMessage());
401 callbackManager->callOnError(JSTizenExceptionFactory::makeErrorObject(context, JSTizenException::UNKNOWN_ERROR,"Unknown Error"));
402 return JSValueMakeUndefined(context);