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