Update change log and spec for wrt-plugins-tizen_0.4.13
[framework/web/wrt-plugins-tizen.git] / src / Bluetooth / JSBluetoothDevice.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18
19 #include <CommonsJavaScript/Converter.h>
20 #include <CommonsJavaScript/Validator.h>
21 #include <CommonsJavaScript/JSUtils.h>
22 #include <CommonsJavaScript/JSCallbackManager.h>
23 #include <CommonsJavaScript/Utils.h>
24 #include <SecurityExceptions.h>
25 #include <JSTizenExceptionFactory.h>
26 #include <JSTizenException.h>
27 #include "JSBluetoothDevice.h"
28 #include "IBluetoothDeviceManager.h"
29 #include "BluetoothFactory.h"
30 #include "BluetoothDeviceManagerListener.h"
31 #include "BluetoothProperty.h"
32 #include "JSBluetoothClass.h"
33 #include "BluetoothConverter.h"
34 #include "plugin_config.h"
35 #include "JSUtil.h"
36
37 using namespace std;
38 using namespace DPL;
39 using namespace WrtDeviceApis;
40 using namespace DeviceAPI::Common;
41
42 namespace DeviceAPI {
43 namespace Bluetooth {
44
45 JSClassDefinition JSBluetoothDevice::m_classInfo =
46 {
47         0,
48         kJSClassAttributeNone,
49         "BluetoothDevice",
50         NULL,
51         m_properties,
52         m_function,
53         initialize,
54         finalize,
55         NULL, 
56         NULL, 
57         NULL, 
58         NULL, 
59         NULL, 
60         NULL,
61         NULL,
62         hasInstance,
63         NULL
64 };
65
66 JSStaticFunction JSBluetoothDevice::m_function[] =
67 {
68         { "connectToServiceByUUID", JSBluetoothDevice::connectToServiceByUUID, kJSPropertyAttributeNone },
69         { 0, 0, 0 }
70 };
71
72 JSStaticValue JSBluetoothDevice::m_properties[] = {
73         {"name", getName, NULL, kJSPropertyAttributeReadOnly},
74         {"address", getAddress, NULL, kJSPropertyAttributeReadOnly},
75         {"isBonded", getBondProperty, NULL, kJSPropertyAttributeReadOnly},
76         {"isTrusted", getTrustProperty, NULL, kJSPropertyAttributeReadOnly},
77         {"isConnected", getConnectProperty, NULL, kJSPropertyAttributeReadOnly},
78         {"uuids", getUuids, NULL, kJSPropertyAttributeReadOnly},        
79         {0, 0, 0, 0}
80 };
81
82 const JSClassRef JSBluetoothDevice::getClassRef() 
83 {
84         if (!m_jsClassRef) {
85                 m_jsClassRef = JSClassCreate(&m_classInfo);
86         }
87         return m_jsClassRef;
88 }
89
90 const JSClassDefinition* JSBluetoothDevice::getClassInfo() 
91 {
92         return &m_classInfo;
93 }
94
95 JSClassRef JSBluetoothDevice::m_jsClassRef = JSClassCreate(JSBluetoothDevice::getClassInfo());
96
97 void JSBluetoothDevice::initialize(JSContextRef context, JSObjectRef object) 
98 {
99         LogDebug("initialize ");
100
101         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
102
103         if (priv == NULL)
104         {
105                 IBluetoothDeviceManagerPtr BluetoothManager(BluetoothFactory::getInstance().getBluetoothDeviceManager());
106                 priv = new JSBluetoothDevicePriv( context, BluetoothManager);
107                 
108                 if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) 
109                 {
110                         LogError("Object can't store private data.");
111                         delete priv;
112                 }
113         }
114         else
115         {
116                 LogDebug("already exist");              
117         }
118
119         setAttributesIntoJSObject(context, object);     
120 }
121
122 void JSBluetoothDevice::finalize(JSObjectRef object) 
123 {
124         LogDebug("Finalrize");
125
126         JSBluetoothDevicePriv* priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
127
128         if (priv != NULL)
129         {
130                 JSObjectSetPrivate(object, NULL);
131                 LogDebug("Deleting BluetoothManager");
132                 delete priv;
133         }
134 }
135
136
137 bool JSBluetoothDevice::hasInstance(JSContextRef context, JSObjectRef constructor,
138                 JSValueRef possibleInstance, JSValueRef* exception) 
139 {
140         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
141 }
142
143
144 JSObjectRef JSBluetoothDevice::createJSObject(JSContextRef context, BluetoothDeviceData device)
145 {
146         IBluetoothDeviceManagerPtr BluetoothManager(BluetoothFactory::getInstance().getBluetoothDeviceManager());
147         BluetoothManager->setDevice(device);
148         
149         JSBluetoothDevicePriv* priv = new JSBluetoothDevicePriv( context, BluetoothManager);
150         return JSObjectMake(context, getClassRef(), priv);
151 }
152
153
154
155 JSValueRef JSBluetoothDevice::getName(JSContextRef context,
156                                                                                 JSObjectRef object,
157                                                                                 JSStringRef propertyName,
158                                                                                 JSValueRef* exception)
159 {
160         LogDebug("Enter");      
161
162         Converter converter(context);
163         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
164
165         Try 
166         {
167                 if (priv == NULL)
168                 {
169                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
170                 }
171
172                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
173                 std::string name = BluetoothDeviceManager->getNameProperty();
174                 LogDebug("name" << name);       
175                 return converter.toJSValueRef(name);
176         }
177         Catch (WrtDeviceApis::Commons::Exception) 
178         {
179                 LogWarning("Exception"<<_rethrown_exception.GetMessage());
180         }
181         
182         return NULL;
183 }
184
185 JSValueRef JSBluetoothDevice::getAddress(JSContextRef context,
186                                                         JSObjectRef object,
187                                                         JSStringRef propertyName,
188                                                         JSValueRef* exception)
189 {
190         LogDebug("Enter");      
191
192         Converter converter(context);
193         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
194
195         Try 
196         {
197                 if (priv == NULL)
198                 {
199                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
200                 }
201
202                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
203                 std::string address = BluetoothDeviceManager->getAddressProperty();
204
205                 LogDebug("address" << address); 
206                 return converter.toJSValueRef(address);
207         }
208         Catch(WrtDeviceApis::Commons::Exception) 
209         {
210                 LogWarning("Exception"<<_rethrown_exception.GetMessage());
211         }
212         
213         return NULL;
214 }
215 JSValueRef JSBluetoothDevice::getBondProperty(JSContextRef context,
216                                                         JSObjectRef object,
217                                                         JSStringRef propertyName,
218                                                         JSValueRef* exception)
219 {
220         LogDebug("Enter");      
221
222         Converter converter(context);
223         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
224
225         Try 
226         {
227                 if (priv == NULL)
228                 {
229                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
230                 }
231
232                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
233                 bool isBonded = BluetoothDeviceManager->getBondProperty();
234
235                 LogDebug("isBonded " << isBonded);      
236                 
237                 return converter.toJSValueRef(isBonded);
238         }
239         Catch(WrtDeviceApis::Commons::Exception) 
240         {
241                 LogWarning("Exception"<<_rethrown_exception.GetMessage());
242         }
243         
244         return JSValueMakeUndefined(context);
245 }
246 JSValueRef JSBluetoothDevice::getTrustProperty(JSContextRef context,
247                                                         JSObjectRef object,
248                                                         JSStringRef propertyName,
249                                                         JSValueRef* exception)
250 {
251         LogDebug("Enter");      
252
253         Converter converter(context);
254         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
255
256         Try 
257         {
258                 if (priv == NULL)
259                 {
260                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
261                 }
262
263                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
264                 bool isTrusted = BluetoothDeviceManager->getTrustProperty();
265
266                 LogDebug("isTrusted " << isTrusted);    
267                 return converter.toJSValueRef(isTrusted);
268         }
269         Catch(WrtDeviceApis::Commons::Exception) 
270         {
271                 LogWarning("Exception"<<_rethrown_exception.GetMessage());
272         }
273         
274         return JSValueMakeUndefined(context);
275 }
276 JSValueRef JSBluetoothDevice::getConnectProperty(JSContextRef context,
277                                                         JSObjectRef object,
278                                                         JSStringRef propertyName,
279                                                         JSValueRef* exception)
280 {
281         LogDebug("Enter");      
282
283         Converter converter(context);
284         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
285
286         Try 
287         {
288                 if (priv == NULL)
289                 {
290                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
291                 }
292                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
293                 bool isConnected = BluetoothDeviceManager->getConnectProperty();
294
295                 LogDebug("isConnected " << isConnected);        
296                 return converter.toJSValueRef(isConnected);
297         }
298         Catch(WrtDeviceApis::Commons::Exception) 
299         {
300                 LogWarning("Exception"<<_rethrown_exception.GetMessage());
301         }
302         
303         return JSValueMakeUndefined(context);
304 }
305
306 JSValueRef JSBluetoothDevice::getUuids(JSContextRef context,
307                                                         JSObjectRef object,
308                                                         JSStringRef propertyName,
309                                                         JSValueRef* exception)
310 {
311         LogDebug("Enter");      
312
313         Converter converter(context);
314         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
315
316         Try 
317         {
318                 if (priv == NULL)
319                 {
320                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
321                 }
322                 
323                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
324                 std::vector<std::string> uuids = BluetoothDeviceManager->getUuidsProperty();
325                 JSObjectRef result = JSCreateArrayObject(context, 0, NULL);
326                 int length = uuids.size();
327                 
328                 if (!result) 
329                 {
330                         return converter.toJSValueRef("");
331                 }
332
333                 for (int i = 0; i < length; ++i) 
334                 {
335                         JSValueRef value = converter.toJSValueRef(uuids[i]);
336
337                         if (!JSSetArrayElement(context, result, i, value)) 
338                         {
339                                 return converter.toJSValueRef("");
340                         }
341                 }
342
343                 return result;
344         }
345         Catch(WrtDeviceApis::Commons::Exception) 
346         {
347                 LogWarning("Exception"<<_rethrown_exception.GetMessage());
348         }
349         
350         return JSValueMakeUndefined(context);
351 }
352
353
354         
355
356 JSValueRef JSBluetoothDevice::connectToServiceByUUID(JSContextRef context, JSObjectRef object,
357                 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
358                 JSValueRef* exception) {
359
360         LogDebug("connectToServiceByUUID");
361
362         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(thisObject));
363         JSValueRef successCallback = NULL;
364         JSValueRef errorCallBack = NULL;
365         size_t index = 0;
366         JSValueRef reserveArguments[3];
367
368         if (priv == NULL)
369         {
370                 return JSTizenExceptionFactory::postException(context, exception, 
371                         JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
372         }
373                 
374         JSCallbackManagerPtr cbm = JSCallbackManager::createObject(priv->getContext(), NULL, NULL);
375
376         Try     {
377
378                 for (index = 0; index < 3; index++)
379                 {
380                         if (index < argumentCount)
381                                 reserveArguments[index] = arguments[index];
382                         else 
383                                 reserveArguments[index] = JSValueMakeNull(context);
384                         
385                 }
386
387                 LogDebug(bluetoothExportedNames[BLUETOOTH_FUNCTION_API_DEVICE_CONNECT_TO_SERVICE]);
388
389                 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
390                         bluetoothExportedNames[BLUETOOTH_FUNCTION_API_DEVICE_CONNECT_TO_SERVICE]);
391
392                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
393
394                 
395                 BluetoothConverter converter(context);
396                 successCallback = converter.toFunction(reserveArguments[1]);
397                 errorCallBack = converter.toFunctionOrNull(reserveArguments[2]);
398                 
399
400                 if (cbm == NULL)
401                 {
402                         return JSValueMakeUndefined(context);
403                 }
404                 cbm->setOnSuccess(successCallback);
405                 cbm->setOnError(errorCallBack);
406
407                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
408                 EventBTConnectToServiceByUUIDPtr event(new EventBTConnectToServiceByUUID);
409                 BluetoothSocketData socketData;
410                 socketData.uuid = converter.toBluetoothUUIDString(reserveArguments[0]);
411                 socketData.protocol  = PROTOCOL_TYPE_RFCOMM_VALUE_INT;
412
413 /*              if (argumentCount >= 4)
414                 {
415                         socketData.protocol = converter.toBluetoothProtocolInt(reserveArguments[3]);
416                 }*/
417                 
418                 
419                 if (BluetoothDeviceManager == NULL || event == NULL)
420                 {
421                         LogError("BluetoothDeviceManager or event or listener NULL");
422                         Throw(WrtDeviceApis::Commons::UnknownException);        
423                 }
424
425                 event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData > (cbm));
426
427                 event->setForAsynchronousCall(&BluetoothDeviceManagerListener::getInstance());
428                 event->setSocketData(socketData);
429                 BluetoothDeviceManager->connectToServiceByUUID(event);
430         }
431         Catch (WrtDeviceApis::Commons::ConversionException)
432         {
433                 LogError("ConversionException");
434                 return JSTizenExceptionFactory::postException(context, exception, 
435                                         JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
436
437         }
438         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
439         {
440                 LogError("InvalidArgumentException");
441                 return JSTizenExceptionFactory::postException(context, exception,
442                                 JSTizenException::TYPE_MISMATCH_ERROR, "invalid value error");
443         }
444         Catch(WrtDeviceApis::Commons::UnsupportedException)
445         {
446                 LogError("UnsupportException");
447                 return JSTizenExceptionFactory::postException(context, exception,
448                                 JSTizenException::NOT_SUPPORTED_ERROR, "Unsupport Exception");
449         }
450         
451         Catch (WrtDeviceApis::Commons::AlreadyInUseException)
452         {
453                 LogError("AlreadyInUseException");
454                 cbm->callOnError(JSTizenExceptionFactory::makeErrorObject(priv->getContext(), 
455                                 JSTizenException::SERVICE_NOT_AVAILABLE, "already connected"));         
456         }
457         Catch (WrtDeviceApis::Commons::Exception) 
458         {
459                 LogError("Exception");
460                 return JSTizenExceptionFactory::postException(context, exception, 
461                         JSTizenException::UNKNOWN_ERROR, "unknown error");
462         }
463
464         return JSValueMakeUndefined(context);
465 }
466
467 void JSBluetoothDevice::setAttributesIntoJSObject(JSContextRef context, JSObjectRef object)
468 {
469         // deviceClass
470         Try
471         {       
472                 JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
473                 if (priv == NULL)
474                 {
475                         ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Private object is NULL.");
476                 }
477                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
478                 BluetoothDeviceDataClass devClass = BluetoothDeviceManager->getClass();
479
480                 LogDebug("Major:" << std::hex << devClass.major << "Minor:" << std::hex << devClass.minor << "Service Mask:" << std::hex <<  devClass.majorServiceMask);
481                 
482                 JSUtil::setProperty(context, object, "deviceClass",
483                                 JSBluetoothClass::createJSObject(priv->getContext(), devClass), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete);
484         }
485         Catch(WrtDeviceApis::Commons::Exception)
486         {
487                 LogWarning("Exception"<<_rethrown_exception.GetMessage());              
488         }
489 }
490
491 }
492 }
493