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 <CommonsJavaScript/JSUtils.h>
21 #include <CommonsJavaScript/JSCallbackManager.h>
22 #include <CommonsJavaScript/Utils.h>
23 #include <JSTizenExceptionFactory.h>
24 #include <JSTizenException.h>
25 #include <SecurityExceptions.h>
26 #include "BluetoothFactory.h"
27 #include "BluetoothProperty.h"
28 #include <dpl/scoped_array.h>
29 #include <dpl/scoped_free.h>
30 #include "BluetoothSocketListener.h"
31 #include "JSBluetoothSocket.h"
32 #include "JSBluetoothDevice.h"
33 #include "BluetoothMultiCallback.h"
34 #include "BluetoothConverter.h"
35 #include <bluetooth.h>
36 #include "plugin_config.h"
41 using namespace DeviceAPI::Common;
48 JSClassDefinition JSBluetoothSocket::m_classInfo =
51 kJSClassAttributeNone,
69 JSStaticValue JSBluetoothSocket::m_properties[] =
71 {"uuid", getProperty, NULL, kJSPropertyAttributeReadOnly},
72 // {"protocol", getProperty, NULL, kJSPropertyAttributeReadOnly},
73 {"state", getProperty, NULL, kJSPropertyAttributeReadOnly},
74 {"onerror", getCallback, setProperty, kJSPropertyAttributeNone},
75 {"onmessage", getCallback, setProperty, kJSPropertyAttributeNone},
76 {"onclose", getCallback, setProperty, kJSPropertyAttributeNone},
81 JSStaticFunction JSBluetoothSocket::m_function[] =
83 { "writeData", JSBluetoothSocket::writeData, kJSPropertyAttributeNone },
84 { "readData", JSBluetoothSocket::readData, kJSPropertyAttributeNone },
85 { "close", JSBluetoothSocket::close, kJSPropertyAttributeNone },
89 const JSClassRef JSBluetoothSocket::getClassRef()
93 m_jsClassRef = JSClassCreate(&m_classInfo);
98 const JSClassDefinition* JSBluetoothSocket::getClassInfo()
103 JSClassRef JSBluetoothSocket::m_jsClassRef = JSClassCreate(JSBluetoothSocket::getClassInfo());
105 bool JSBluetoothSocket::setProperty(JSContextRef context,
107 JSStringRef propertyName,
109 JSValueRef* exception)
115 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
118 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "private object is null");
121 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
122 BluetoothConverter converter(priv->getContext());
123 if (BluetoothSocketManager == NULL)
125 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
128 EventBTSocketNotificationEmitterPtr emitter = BluetoothSocketManager->getSocketNotifier();
131 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "emitter is NULL");
134 BluetoothSocketNotifierPrivateDataPtr privData =
135 DPL::DynamicPointerCast<BluetoothSocketNotifierPrivateData>(emitter->getEventPrivateData());
137 if (privData == NULL)
139 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothSocketNotifierPrivateData is NULL");
142 if(JSValueIsNull(context, value) ||
143 JSObjectIsFunction(context, converter.toJSObjectRef(value)) )
145 LogDebug("Callable or null");
146 converter.setBluetoothSocketNotifierCallback(propertyName, value, object, privData);
150 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Non callable object");
153 emitter->setListener(&BluetoothSocketListener::getInstance());
154 emitter->setEventPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privData));
158 catch (const WrtDeviceApis::Commons::ConversionException& ex)
160 LogError("Exception: " << ex.GetMessage());
161 *exception = JSTizenExceptionFactory::makeErrorObject(context,
162 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
164 catch (WrtDeviceApis::Commons::Exception& ex)
166 LogWarning("Exception: " << ex.GetMessage());
172 void JSBluetoothSocket::initialize(JSContextRef context, JSObjectRef object)
174 LogDebug("JSBluetoothSocket::initialize ");
175 setAttributesIntoJSObject(context, object);
178 void JSBluetoothSocket::finalize(JSObjectRef object)
180 LogDebug("JSBluetoothSocket::Finalrize");
182 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
187 JSObjectSetPrivate(object, NULL);
191 bool JSBluetoothSocket::hasInstance(JSContextRef context, JSObjectRef constructor,
192 JSValueRef possibleInstance, JSValueRef* exception)
194 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
197 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketData socketData)
199 IBluetoothSocketManagerPtr BluetoothSocketManager(BluetoothFactory::getInstance().getBluetoothSocketManager());
200 JSBluetoothSocketPriv* priv = new JSBluetoothSocketPriv( context, BluetoothSocketManager);
201 BluetoothSocketManager->setSocketData(socketData);
205 if (BluetoothSocketManager == NULL || priv == NULL)
207 LogError("BluetoothManager or event or listener NULL");
208 Throw(WrtDeviceApis::Commons::UnknownException);
211 BluetoothConverter converter(priv->getContext());
212 EventBTSocketNotificationEmitterPtr emitter(new EventBTSocketNotificationEmitter);
214 BluetoothSocketNotifierPrivateDataPtr privData(converter.getInitalBluetoothSocketNotifierPrivateData());
215 emitter->setListener(&BluetoothSocketListener::getInstance());
216 emitter->setEventPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privData));
218 if (BluetoothSocketManager->setSocketNotifier(emitter) != BT_ERROR_NONE)
220 LogError("callback set error");
221 Throw(WrtDeviceApis::Commons::UnknownException);
224 return JSObjectMake(context, getClassRef(), priv);
226 catch (WrtDeviceApis::Commons::Exception& ex)
228 LogError("Exception: " << ex.GetMessage());
230 switch (ex.getCode())
232 case WrtDeviceApis::Commons::ExceptionCodes::ConversionException:
233 return JSTizenExceptionFactory::makeErrorObject(context,
234 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
235 case WrtDeviceApis::Commons::ExceptionCodes::InvalidArgumentException:
236 return JSTizenExceptionFactory::makeErrorObject(context,
237 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
238 case WrtDeviceApis::Commons::ExceptionCodes::Exception:
240 return JSTizenExceptionFactory::makeErrorObject(context,
241 JSTizenException::UNKNOWN_ERROR, "Unkown error");
248 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketData socketData, EventBTReadDataType readData)
250 IBluetoothSocketManagerPtr BluetoothSocketManager(BluetoothFactory::getInstance().getBluetoothSocketManager());
251 JSBluetoothSocketPriv* priv = new JSBluetoothSocketPriv( context, BluetoothSocketManager);
252 BluetoothSocketManager->setSocketData(socketData);
253 BluetoothSocketManager->setReadData(readData);
254 return JSObjectMake(context, getClassRef(), priv);
257 JSValueRef JSBluetoothSocket::getProperty(JSContextRef context,
259 JSStringRef propertyName,
260 JSValueRef* exception)
267 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
270 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "private object null");
273 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
274 BluetoothConverter converter(priv->getContext());
275 if (BluetoothSocketManager == NULL)
277 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
280 if(JSStringIsEqualToUTF8CString(propertyName, "uuid"))
282 std::string uuid = BluetoothSocketManager->getUUID();
283 return converter.toJSValueRef(uuid);
285 else if(JSStringIsEqualToUTF8CString(propertyName, "state"))
287 unsigned short int state = BluetoothSocketManager->getState();
288 return converter.toBluetoothStateJSValue(state);
291 Catch(WrtDeviceApis::Commons::Exception)
293 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
296 return JSValueMakeUndefined(context);
299 JSValueRef JSBluetoothSocket::getCallback(JSContextRef context,
301 JSStringRef propertyName,
302 JSValueRef* exception)
308 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
311 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "private object null");
314 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
315 BluetoothConverter converter(priv->getContext());
316 if (BluetoothSocketManager == NULL)
318 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
321 EventBTSocketNotificationEmitterPtr emitter = BluetoothSocketManager->getSocketNotifier();
324 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "emitter is NULL");
327 BluetoothSocketNotifierPrivateDataPtr privData =
328 DPL::DynamicPointerCast<BluetoothSocketNotifierPrivateData>(emitter->getEventPrivateData());
330 if (privData == NULL)
332 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "privData NULL");
335 if(JSStringIsEqualToUTF8CString(propertyName, "onmessage"))
337 JSValueRef callback = privData->getOnMessage()->getOnSuccess();
340 LogDebug("callback is NULL");
344 LogDebug("callback is not NULL");
348 else if(JSStringIsEqualToUTF8CString(propertyName, "onclose"))
350 JSValueRef callback = privData->getOnClose()->getOnSuccess();
353 LogDebug("callback is NULL");
357 LogDebug("callback is not NULL");
361 else if(JSStringIsEqualToUTF8CString(propertyName, "onerror"))
363 JSValueRef callback = privData->getOnError()->getOnSuccess();
366 LogDebug("callback is NULL");
370 LogDebug("callback is not NULL");
375 Catch(WrtDeviceApis::Commons::Exception)
377 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
380 return JSValueMakeNull(context);
384 JSValueRef JSBluetoothSocket::writeData(JSContextRef context, JSObjectRef object,
385 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
386 JSValueRef* exception)
388 LogDebug("JSBluetoothSocket");
389 Converter converter(context);
392 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
396 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
399 if (argumentCount < 1)
401 LogError("argument wrong");
402 Throw(WrtDeviceApis::Commons::ConversionException);
405 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
406 bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_WRITE_DATA]);
408 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
410 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
411 std::vector<char> data = converter.toVectorOfChars(arguments[0]);
412 unsigned int index = 0;
414 if (data.size() == 0)
416 LogError("size 0 array passed");
417 Throw(WrtDeviceApis::Commons::ConversionException);
420 DPL::ScopedArray<char> buffer(new char[data.size()]);
422 for (index = 0; index < data.size(); index++)
424 buffer[index] = data[index];
427 if (BluetoothSocketManager->writeData(buffer.Get(), data.size()) != BT_ERROR_NONE)
429 LogError("BluetoothSocket Write Error");
430 Throw(WrtDeviceApis::Commons::UnknownException);
433 return converter.toJSValueRef(data.size());
435 Catch (WrtDeviceApis::Commons::SecurityException)
437 LogError("permission denied error");
438 return JSTizenExceptionFactory::postException(context, exception,
439 JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");
441 Catch (WrtDeviceApis::Commons::ConversionException)
443 LogError("ConversionException");
444 return JSTizenExceptionFactory::postException(context, exception,
445 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
448 Catch(WrtDeviceApis::Commons::UnsupportedException)
450 LogError("UnsupportException");
451 return JSTizenExceptionFactory::postException(context, exception,
452 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
454 Catch (WrtDeviceApis::Commons::Exception)
456 LogError("Exception");
457 return JSTizenExceptionFactory::postException(context, exception,
458 JSTizenException::UNKNOWN_ERROR, "unknown error");
463 JSValueRef JSBluetoothSocket::readData(JSContextRef context, JSObjectRef object,
464 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
465 JSValueRef* exception)
469 LogDebug("JSBluetoothSocket");
473 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
475 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
477 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
479 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
480 bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_READ_DATA]);
482 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
485 EventBTReadDataType data = BluetoothSocketManager->readData();
486 int length = data.size();
487 LogDebug("size" << length);
488 BluetoothConverter converter(priv->getContext());
492 LogError("BluetoothSocket Read Error");
493 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
497 JSObjectRef result = converter.toBluetoothByteArray(data);
500 Catch (WrtDeviceApis::Commons::SecurityException)
502 LogError("permission denied error");
503 return JSTizenExceptionFactory::postException(context, exception,
504 JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");
506 Catch(WrtDeviceApis::Commons::UnsupportedException)
508 LogError("UnsupportException");
509 return JSTizenExceptionFactory::postException(context, exception,
510 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
512 Catch (WrtDeviceApis::Commons::Exception)
514 LogError("Exception");
515 return JSTizenExceptionFactory::postException(context, exception,
516 JSTizenException::UNKNOWN_ERROR, "unknown error");
521 JSValueRef JSBluetoothSocket::close(JSContextRef context, JSObjectRef object,
522 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
523 JSValueRef* exception)
525 LogDebug("JSBluetoothSocket");
529 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
531 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
533 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
535 LogDebug(bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_CLOSE]);
537 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
538 bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_CLOSE]);
541 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
543 if (BluetoothSocketManager->close() != BT_ERROR_NONE)
545 Throw(WrtDeviceApis::Commons::UnknownException);
548 return JSValueMakeNull(context);
551 Catch (WrtDeviceApis::Commons::SecurityException)
553 LogError("permission denied error");
554 return JSTizenExceptionFactory::postException(context, exception,
555 JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");
557 Catch(WrtDeviceApis::Commons::UnsupportedException)
559 LogError("UnsupportException");
560 return JSTizenExceptionFactory::postException(context, exception,
561 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
563 Catch (WrtDeviceApis::Commons::Exception)
565 LogError("Exception");
566 return JSTizenExceptionFactory::postException(context, exception,
567 JSTizenException::UNKNOWN_ERROR, "unknown error");
571 void JSBluetoothSocket::setAttributesIntoJSObject(JSContextRef context, JSObjectRef object)
576 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
579 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "private object null");
582 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
583 BluetoothConverter converter(priv->getContext());
584 if (BluetoothSocketManager == NULL)
586 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
589 BluetoothDeviceData device = BluetoothSocketManager->getPeer();
590 JSUtil::setProperty(context, object, "peer",
591 JSBluetoothDevice::createJSObject(priv->getContext(), device), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete);
593 Catch(WrtDeviceApis::Commons::Exception)
595 LogWarning("Exception"<<_rethrown_exception.GetMessage());