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"
40 using namespace DeviceAPI::Common;
47 JSClassDefinition JSBluetoothSocket::m_classInfo =
50 kJSClassAttributeNone,
68 JSStaticValue JSBluetoothSocket::m_properties[] =
70 {"uuid", getProperty, NULL, kJSPropertyAttributeReadOnly},
71 // {"protocol", getProperty, NULL, kJSPropertyAttributeReadOnly},
72 {"state", getProperty, NULL, kJSPropertyAttributeReadOnly},
73 {"peer", 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 JSObjectRef JSBluetoothSocket::m_peer = NULL;
107 bool JSBluetoothSocket::setProperty(JSContextRef context,
109 JSStringRef propertyName,
111 JSValueRef* exception)
117 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
120 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "private object is null");
123 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
124 BluetoothConverter converter(priv->getContext());
125 if (BluetoothSocketManager == NULL)
127 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
130 EventBTSocketNotificationEmitterPtr emitter = BluetoothSocketManager->getSocketNotifier();
133 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "emitter is NULL");
136 BluetoothSocketNotifierPrivateDataPtr privData =
137 DPL::DynamicPointerCast<BluetoothSocketNotifierPrivateData>(emitter->getEventPrivateData());
139 if (privData == NULL)
141 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothSocketNotifierPrivateData is NULL");
144 if(JSValueIsNull(context, value) ||
145 JSObjectIsFunction(context, converter.toJSObjectRef(value)) )
147 LogDebug("Callable or null");
148 converter.setBluetoothSocketNotifierCallback(propertyName, value, object, privData);
152 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Non callable object");
155 emitter->setListener(&BluetoothSocketListener::getInstance());
156 emitter->setEventPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privData));
160 catch (const WrtDeviceApis::Commons::ConversionException& ex)
162 LogError("Exception: " << ex.GetMessage());
163 *exception = JSTizenExceptionFactory::makeErrorObject(context,
164 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
166 catch (WrtDeviceApis::Commons::Exception& ex)
168 LogWarning("Exception: " << ex.GetMessage());
174 void JSBluetoothSocket::initialize(JSContextRef context, JSObjectRef object)
176 LogDebug("JSBluetoothSocket::initialize ");
180 void JSBluetoothSocket::finalize(JSObjectRef object)
182 LogDebug("JSBluetoothSocket::Finalrize");
184 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
189 JSObjectSetPrivate(object, NULL);
193 bool JSBluetoothSocket::hasInstance(JSContextRef context, JSObjectRef constructor,
194 JSValueRef possibleInstance, JSValueRef* exception)
196 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
199 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketData socketData)
201 IBluetoothSocketManagerPtr BluetoothSocketManager(BluetoothFactory::getInstance().getBluetoothSocketManager());
202 JSBluetoothSocketPriv* priv = new JSBluetoothSocketPriv( context, BluetoothSocketManager);
203 BluetoothSocketManager->setSocketData(socketData);
207 if (BluetoothSocketManager == NULL || priv == NULL)
209 LogError("BluetoothManager or event or listener NULL");
210 Throw(WrtDeviceApis::Commons::UnknownException);
213 BluetoothConverter converter(priv->getContext());
214 EventBTSocketNotificationEmitterPtr emitter(new EventBTSocketNotificationEmitter);
216 BluetoothSocketNotifierPrivateDataPtr privData(converter.getInitalBluetoothSocketNotifierPrivateData());
217 emitter->setListener(&BluetoothSocketListener::getInstance());
218 emitter->setEventPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privData));
220 if (BluetoothSocketManager->setSocketNotifier(emitter) != BT_ERROR_NONE)
222 LogError("callback set error");
223 Throw(WrtDeviceApis::Commons::UnknownException);
226 return JSObjectMake(context, getClassRef(), priv);
228 catch (WrtDeviceApis::Commons::Exception& ex)
230 LogError("Exception: " << ex.GetMessage());
232 switch (ex.getCode())
234 case WrtDeviceApis::Commons::ExceptionCodes::ConversionException:
235 return JSTizenExceptionFactory::makeErrorObject(context,
236 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
237 case WrtDeviceApis::Commons::ExceptionCodes::InvalidArgumentException:
238 return JSTizenExceptionFactory::makeErrorObject(context,
239 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
240 case WrtDeviceApis::Commons::ExceptionCodes::Exception:
242 return JSTizenExceptionFactory::makeErrorObject(context,
243 JSTizenException::UNKNOWN_ERROR, "Unkown error");
250 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketData socketData, EventBTReadDataType readData)
252 IBluetoothSocketManagerPtr BluetoothSocketManager(BluetoothFactory::getInstance().getBluetoothSocketManager());
253 JSBluetoothSocketPriv* priv = new JSBluetoothSocketPriv( context, BluetoothSocketManager);
254 BluetoothSocketManager->setSocketData(socketData);
255 BluetoothSocketManager->setReadData(readData);
256 return JSObjectMake(context, getClassRef(), priv);
259 JSValueRef JSBluetoothSocket::getProperty(JSContextRef context,
261 JSStringRef propertyName,
262 JSValueRef* exception)
269 if(JSStringIsEqualToUTF8CString(propertyName, "peer") && m_peer != NULL)
272 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
275 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "private object null");
278 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
279 BluetoothConverter converter(priv->getContext());
280 if (BluetoothSocketManager == NULL)
282 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
285 if(JSStringIsEqualToUTF8CString(propertyName, "uuid"))
287 std::string uuid = BluetoothSocketManager->getUUID();
288 return converter.toJSValueRef(uuid);
290 else if(JSStringIsEqualToUTF8CString(propertyName, "state"))
292 unsigned short int state = BluetoothSocketManager->getState();
293 return converter.toBluetoothStateJSValue(state);
297 BluetoothDeviceData device = BluetoothSocketManager->getPeer();
298 m_peer = JSBluetoothDevice::createJSObject(priv->getContext(), device);
302 Catch(WrtDeviceApis::Commons::Exception)
304 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
307 return JSValueMakeUndefined(context);
310 JSValueRef JSBluetoothSocket::getCallback(JSContextRef context,
312 JSStringRef propertyName,
313 JSValueRef* exception)
319 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
322 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "private object null");
325 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
326 BluetoothConverter converter(priv->getContext());
327 if (BluetoothSocketManager == NULL)
329 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "BluetoothManager is NULL");
332 EventBTSocketNotificationEmitterPtr emitter = BluetoothSocketManager->getSocketNotifier();
335 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "emitter is NULL");
338 BluetoothSocketNotifierPrivateDataPtr privData =
339 DPL::DynamicPointerCast<BluetoothSocketNotifierPrivateData>(emitter->getEventPrivateData());
341 if (privData == NULL)
343 ThrowMsg(WrtDeviceApis::Commons::UnknownException, "privData NULL");
346 if(JSStringIsEqualToUTF8CString(propertyName, "onmessage"))
348 JSValueRef callback = privData->getOnMessage()->getOnSuccess();
351 LogDebug("callback is NULL");
355 LogDebug("callback is not NULL");
359 else if(JSStringIsEqualToUTF8CString(propertyName, "onclose"))
361 JSValueRef callback = privData->getOnClose()->getOnSuccess();
364 LogDebug("callback is NULL");
368 LogDebug("callback is not NULL");
372 else if(JSStringIsEqualToUTF8CString(propertyName, "onerror"))
374 JSValueRef callback = privData->getOnError()->getOnSuccess();
377 LogDebug("callback is NULL");
381 LogDebug("callback is not NULL");
386 Catch(WrtDeviceApis::Commons::Exception)
388 LogWarning("Exception: "<<_rethrown_exception.GetMessage());
391 return JSValueMakeNull(context);
395 JSValueRef JSBluetoothSocket::writeData(JSContextRef context, JSObjectRef object,
396 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
397 JSValueRef* exception)
399 LogDebug("JSBluetoothSocket");
400 Converter converter(context);
403 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
407 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
410 if (argumentCount < 1)
412 LogError("argument wrong");
413 Throw(WrtDeviceApis::Commons::ConversionException);
416 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
417 bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_WRITE_DATA]);
419 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
421 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
422 std::vector<char> data = converter.toVectorOfChars(arguments[0]);
423 unsigned int index = 0;
425 if (data.size() == 0)
427 LogError("size 0 array passed");
428 Throw(WrtDeviceApis::Commons::ConversionException);
431 DPL::ScopedArray<char> buffer(new char[data.size()]);
433 for (index = 0; index < data.size(); index++)
435 buffer[index] = data[index];
438 if (BluetoothSocketManager->writeData(buffer.Get(), data.size()) != BT_ERROR_NONE)
440 LogError("BluetoothSocket Write Error");
441 Throw(WrtDeviceApis::Commons::UnknownException);
444 return converter.toJSValueRef(data.size());
446 Catch (WrtDeviceApis::Commons::SecurityException)
448 LogError("permission denied error");
449 return JSTizenExceptionFactory::postException(context, exception,
450 JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");
452 Catch (WrtDeviceApis::Commons::ConversionException)
454 LogError("ConversionException");
455 return JSTizenExceptionFactory::postException(context, exception,
456 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
459 Catch(WrtDeviceApis::Commons::UnsupportedException)
461 LogError("UnsupportException");
462 return JSTizenExceptionFactory::postException(context, exception,
463 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
465 Catch (WrtDeviceApis::Commons::Exception)
467 LogError("Exception");
468 return JSTizenExceptionFactory::postException(context, exception,
469 JSTizenException::UNKNOWN_ERROR, "unknown error");
474 JSValueRef JSBluetoothSocket::readData(JSContextRef context, JSObjectRef object,
475 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
476 JSValueRef* exception)
480 LogDebug("JSBluetoothSocket");
484 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
486 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
488 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
490 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
491 bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_READ_DATA]);
493 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
496 EventBTReadDataType data = BluetoothSocketManager->readData();
497 int length = data.size();
498 LogDebug("size" << length);
499 BluetoothConverter converter(priv->getContext());
503 LogError("BluetoothSocket Read Error");
504 Throw(WrtDeviceApis::Commons::InvalidArgumentException);
508 JSObjectRef result = converter.toBluetoothByteArray(data);
511 Catch (WrtDeviceApis::Commons::SecurityException)
513 LogError("permission denied error");
514 return JSTizenExceptionFactory::postException(context, exception,
515 JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");
517 Catch(WrtDeviceApis::Commons::UnsupportedException)
519 LogError("UnsupportException");
520 return JSTizenExceptionFactory::postException(context, exception,
521 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
523 Catch (WrtDeviceApis::Commons::Exception)
525 LogError("Exception");
526 return JSTizenExceptionFactory::postException(context, exception,
527 JSTizenException::UNKNOWN_ERROR, "unknown error");
532 JSValueRef JSBluetoothSocket::close(JSContextRef context, JSObjectRef object,
533 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
534 JSValueRef* exception)
536 LogDebug("JSBluetoothSocket");
540 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
542 ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
544 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
546 LogDebug(bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_CLOSE]);
548 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
549 bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_CLOSE]);
552 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
554 if (BluetoothSocketManager->close() != BT_ERROR_NONE)
556 Throw(WrtDeviceApis::Commons::UnknownException);
559 return JSValueMakeNull(context);
562 Catch (WrtDeviceApis::Commons::SecurityException)
564 LogError("permission denied error");
565 return JSTizenExceptionFactory::postException(context, exception,
566 JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");
568 Catch(WrtDeviceApis::Commons::UnsupportedException)
570 LogError("UnsupportException");
571 return JSTizenExceptionFactory::postException(context, exception,
572 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
574 Catch (WrtDeviceApis::Commons::Exception)
576 LogError("Exception");
577 return JSTizenExceptionFactory::postException(context, exception,
578 JSTizenException::UNKNOWN_ERROR, "unknown error");