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.
20 #include <SecurityExceptions.h>
22 #include <JSWebAPIException.h>
23 #include <ArgumentValidator.h>
24 #include <GlobalContextManager.h>
25 #include <PlatformException.h>
26 #include <MultiCallbackUserData.h>
28 #include "plugin_config.h"
29 #include "JSBluetoothSocket.h"
30 #include "BluetoothSocket.h"
31 #include "BluetoothAdapter.h"
33 #include <TimeTracer.h>
36 using namespace WrtDeviceApis::Commons;
37 using namespace DeviceAPI::Common;
42 JSClassDefinition JSBluetoothSocket::m_classInfo = {
44 kJSClassAttributeNone,
47 m_property, //StaticValues
48 m_function, //StaticFunctions
49 initialize, //Initialize
54 NULL, //DeleteProperty,
55 NULL, //GetPropertyNames,
56 NULL, //CallAsFunction,
57 NULL, //CallAsConstructor,
62 JSStaticValue JSBluetoothSocket::m_property[] = {
63 { BLUETOOTH_SOCKET_UUID, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
64 { BLUETOOTH_SOCKET_STATE, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
65 { BLUETOOTH_SOCKET_PEER, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
66 { BLUETOOTH_SOCKET_ONMESSAGE, getProperty, setProperty, kJSPropertyAttributeNone|kJSPropertyAttributeDontDelete },
67 { BLUETOOTH_SOCKET_ONCLOSE, getProperty, setProperty, kJSPropertyAttributeNone|kJSPropertyAttributeDontDelete },
68 { BLUETOOTH_SOCKET_ONERROR, getProperty, setProperty, kJSPropertyAttributeNone|kJSPropertyAttributeDontDelete },
72 JSStaticFunction JSBluetoothSocket::m_function[] = {
73 { BLUETOOTH_SOCKET_API_WRITE_DATA, writeData, kJSPropertyAttributeNone },
74 { BLUETOOTH_SOCKET_API_READ_DATA, readData, kJSPropertyAttributeNone },
75 { BLUETOOTH_SOCKET_API_CLOSE, close, kJSPropertyAttributeNone },
79 JSClassRef JSBluetoothSocket::m_jsClassRef = JSClassCreate(JSBluetoothSocket::getClassInfo());
81 const JSClassRef JSBluetoothSocket::getClassRef()
84 m_jsClassRef = JSClassCreate(&m_classInfo);
89 const JSClassDefinition* JSBluetoothSocket::getClassInfo()
94 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketPtr socket)
96 return JSObjectMake(context, getClassRef(), static_cast<void*>(socket));
99 void JSBluetoothSocket::initialize(JSContextRef context, JSObjectRef object)
101 LoggerD("Enter"); // do nothing
104 void JSBluetoothSocket::finalize(JSObjectRef object)
106 BluetoothSocketPtr priv = static_cast<BluetoothSocketPtr>(JSObjectGetPrivate(object));
108 JSObjectSetPrivate(object, NULL);
113 JSValueRef JSBluetoothSocket::getProperty(JSContextRef context,
115 JSStringRef propertyName,
116 JSValueRef* exception)
121 BluetoothSocketPtr priv = static_cast<BluetoothSocketPtr>(JSObjectGetPrivate(object));
123 throw TypeMismatchException("Private object is NULL");
126 if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_UUID)) {
127 return JSUtil::toJSValueRef(context, priv->getUUID());
129 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_STATE)) {
130 LoggerD("get state");
132 if(priv->getConnectionState()) {
138 LoggerD("state: " << state);
139 return JSUtil::toJSValueRef(context, state);
141 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_PEER)) {
142 return priv->getPeer(context);
144 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_ONMESSAGE)) {
145 return priv->getOnMessage(context);
147 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_ONCLOSE)) {
148 return priv->getOnClose(context);
150 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_ONERROR)) {
151 return priv->getOnError(context);
153 } catch (const BasePlatformException &err) {
154 LoggerW("Getting property is failed: " << err.getMessage().c_str());
160 bool JSBluetoothSocket::setProperty(JSContextRef context,
162 JSStringRef propertyName,
164 JSValueRef* exception)
167 BluetoothSocketPtr priv = static_cast<BluetoothSocketPtr>(JSObjectGetPrivate(object));
169 throw TypeMismatchException("Private object is NULL");
172 if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_ONMESSAGE)) {
173 JSObjectRef object = NULL;
174 if(!JSValueIsNull(context, value)) {
175 if(!JSValueIsObject(context, value)) {
176 throw TypeMismatchException("Value is not Object");
180 object = JSValueToObject(context, value, &ex);
182 throw TypeMismatchException("Can't convert to Object");
185 if(!JSObjectIsFunction(context, object)) {
186 throw TypeMismatchException("Not function");
190 LoggerD("onmessage() is NULL");
193 return priv->setOnMessage(context, object);
195 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_ONCLOSE)) {
196 JSObjectRef object = NULL;
197 if(!JSValueIsNull(context, value)) {
198 if(!JSValueIsObject(context, value)) {
199 throw TypeMismatchException("Value is not Object");
203 object = JSValueToObject(context, value, &ex);
205 throw TypeMismatchException("Can't convert to Object");
208 if(!JSObjectIsFunction(context, object)) {
209 throw TypeMismatchException("Not function");
213 LoggerD("onclose() is NULL");
216 return priv->setOnClose(context, object);
218 else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_SOCKET_ONERROR)) {
219 JSObjectRef object = NULL;
220 if(!JSValueIsNull(context, value)) {
221 if(!JSValueIsObject(context, value)) {
222 throw TypeMismatchException("Value is not Object");
226 object = JSValueToObject(context, value, &ex);
228 throw TypeMismatchException("Can't convert to Object");
231 if(!JSObjectIsFunction(context, object)) {
232 throw TypeMismatchException("Not function");
236 LoggerD("onerror() is NULL");
239 return priv->setOnError(context, object);
241 } catch (const BasePlatformException &err) {
242 JSWebAPIException::throwException(context, exception, err);
248 JSValueRef JSBluetoothSocket::writeData(JSContextRef context,
250 JSObjectRef thisObject,
251 size_t argumentCount,
252 const JSValueRef arguments[],
253 JSValueRef* exception)
256 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
259 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_SOCKET_API_WRITE_DATA);
260 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
263 // Check whether Bluetooth is supported or not
264 if(!BluetoothAdapter::isBluetoothSupported()) {
265 throw DeviceAPI::Common::NotSupportedException("Bluetooth is not supported");
269 BluetoothSocketPtr priv = static_cast<BluetoothSocketPtr>(JSObjectGetPrivate(thisObject));
271 throw DeviceAPI::Common::UnknownException("Private object is NULL.");
274 ArgumentValidator validator(context, argumentCount, arguments);
276 JSObjectRef dataArrayObj = validator.toArrayObject(0); // data
277 size_t size = JSGetArrayLength(context, dataArrayObj);
278 char *buffer = new char[size];
279 for(size_t i = 0; i < size; ++i) {
280 JSValueRef element = JSGetArrayElement(context, dataArrayObj, i);
281 buffer[i] = static_cast<char>(JSUtil::JSValueToByte(context, element));
283 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
285 return JSUtil::toJSValueRef(context, priv->writeData(buffer, size));
286 } catch (const BasePlatformException &err) {
287 return JSWebAPIException::throwException(context, exception, err);
289 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothSocket.writeData().");
290 return JSWebAPIException::throwException(context, exception, err);
294 JSValueRef JSBluetoothSocket::readData(JSContextRef context,
296 JSObjectRef thisObject,
297 size_t argumentCount,
298 const JSValueRef arguments[],
299 JSValueRef* exception)
302 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
305 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_SOCKET_API_READ_DATA);
306 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
309 // Check whether Bluetooth is supported or not
310 if(!BluetoothAdapter::isBluetoothSupported()) {
311 throw DeviceAPI::Common::NotSupportedException("Bluetooth is not supported");
315 BluetoothSocketPtr priv = static_cast<BluetoothSocketPtr>(JSObjectGetPrivate(thisObject));
317 throw DeviceAPI::Common::UnknownException("Private object is NULL.");
320 std::vector<signed char> data = priv->readData();
321 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
323 return JSUtil::toJSValueRef_(context, data);
324 } catch (const BasePlatformException &err) {
325 return JSWebAPIException::throwException(context, exception, err);
327 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothSocket.readData().");
328 return JSWebAPIException::throwException(context, exception, err);
332 JSValueRef JSBluetoothSocket::close(JSContextRef context,
334 JSObjectRef thisObject,
335 size_t argumentCount,
336 const JSValueRef arguments[],
337 JSValueRef* exception)
340 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
343 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_SOCKET_API_CLOSE);
344 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
347 // Check whether Bluetooth is supported or not
348 if(!BluetoothAdapter::isBluetoothSupported()) {
349 throw DeviceAPI::Common::NotSupportedException("Bluetooth is not supported");
353 BluetoothSocketPtr priv = static_cast<BluetoothSocketPtr>(JSObjectGetPrivate(thisObject));
355 throw DeviceAPI::Common::UnknownException("Private object is NULL.");
359 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
361 return JSValueMakeUndefined(context);
362 } catch (const BasePlatformException &err) {
363 return JSWebAPIException::throwException(context, exception, err);
365 DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothSocket.close().");
366 return JSWebAPIException::throwException(context, exception, err);