Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Bluetooth / JSBluetoothDevice.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. 
15  */
16
17 #include <CommonsJavaScript/Converter.h>
18 #include <CommonsJavaScript/Validator.h>
19 #include <CommonsJavaScript/JSUtils.h>
20 #include <CommonsJavaScript/JSCallbackManager.h>
21 #include <CommonsJavaScript/Utils.h>
22 #include <Tizen/Common/SecurityExceptions.h>
23 #include <Tizen/Common/JSTizenExceptionFactory.h>
24 #include <Tizen/Common/JSTizenException.h>
25 #include "JSBluetoothDevice.h"
26 #include <API/Bluetooth/IBluetoothDeviceManager.h>
27 #include <API/Bluetooth/BluetoothFactory.h>
28 #include "BluetoothDeviceManagerListener.h"
29 #include <API/Bluetooth/BluetoothProperty.h>
30 #include "JSBluetoothClass.h"
31 #include "BluetoothConverter.h"
32 #include "plugin_config.h"
33
34 using namespace std;
35 using namespace DPL;
36 using namespace WrtDeviceApis;
37 using namespace TizenApis::Commons;
38
39 namespace TizenApis {
40 namespace Tizen1_0 {
41
42
43 JSClassDefinition JSBluetoothDevice::m_classInfo =
44 {
45         0,
46         kJSClassAttributeNone,
47         "BluetoothDevice",
48         NULL,
49         m_properties,
50         m_function,
51         initialize,
52         finalize,
53         NULL, 
54         NULL, 
55         NULL, 
56         NULL, 
57         NULL, 
58         NULL,
59         NULL,
60         hasInstance,
61         NULL
62 };
63
64 JSStaticFunction JSBluetoothDevice::m_function[] =
65 {
66         { "connectToServiceByUUID", JSBluetoothDevice::connectToServiceByUUID, kJSPropertyAttributeNone },
67         { 0, 0, 0 }
68 };
69
70 JSStaticValue JSBluetoothDevice::m_properties[] = {
71         {"name", getName, NULL, kJSPropertyAttributeReadOnly},
72         {"address", getAddress, NULL, kJSPropertyAttributeReadOnly},
73         {"deviceClass", getDeviceClass, NULL, kJSPropertyAttributeReadOnly},
74         {"isBonded", getBondProperty, NULL, kJSPropertyAttributeReadOnly},
75         {"isTrusted", getTrustProperty, NULL, kJSPropertyAttributeReadOnly},
76         {"isConnected", getConnectProperty, NULL, kJSPropertyAttributeReadOnly},
77         {"uuids", getUuids, NULL, kJSPropertyAttributeReadOnly},        
78         {0, 0, 0, 0}
79 };
80
81 const JSClassRef JSBluetoothDevice::getClassRef() 
82 {
83         if (!m_jsClassRef) {
84                 m_jsClassRef = JSClassCreate(&m_classInfo);
85         }
86         return m_jsClassRef;
87 }
88
89 const JSClassDefinition* JSBluetoothDevice::getClassInfo() 
90 {
91         return &m_classInfo;
92 }
93
94 JSClassRef JSBluetoothDevice::m_jsClassRef = JSClassCreate(JSBluetoothDevice::getClassInfo());
95
96 void JSBluetoothDevice::initialize(JSContextRef context, JSObjectRef object) 
97 {
98         LogDebug("initialize ");
99
100         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
101
102         if (priv == NULL)
103         {
104                 IBluetoothDeviceManagerPtr BluetoothManager(BluetoothFactory::getInstance().getBluetoothDeviceManager());
105                 priv = new JSBluetoothDevicePriv( context, BluetoothManager);
106                 
107                 if(!JSObjectSetPrivate(object, static_cast<void*>(priv))) 
108                 {
109                         LogError("Object can't store private data.");
110                         delete priv;
111                 }
112         }
113         else
114         {
115                 LogDebug("already exist");
116         }
117
118
119 }
120
121 void JSBluetoothDevice::finalize(JSObjectRef object) 
122 {
123         LogDebug("Finalrize");
124
125         JSBluetoothDevicePriv* priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
126
127         if (priv != NULL)
128         {
129                 JSObjectSetPrivate(object, NULL);
130                 LogDebug("Deleting BluetoothManager");
131                 delete priv;
132         }
133 }
134
135
136 bool JSBluetoothDevice::hasInstance(JSContextRef context, JSObjectRef constructor,
137                 JSValueRef possibleInstance, JSValueRef* exception) 
138 {
139         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
140 }
141
142
143 JSObjectRef JSBluetoothDevice::createJSObject(JSContextRef context, BluetoothDeviceData device)
144 {
145         IBluetoothDeviceManagerPtr BluetoothManager(BluetoothFactory::getInstance().getBluetoothDeviceManager());
146         BluetoothManager->setDevice(device);
147         
148         JSBluetoothDevicePriv* priv = new JSBluetoothDevicePriv( context, BluetoothManager);
149         return JSObjectMake(context, getClassRef(), priv);
150 }
151
152
153
154 JSValueRef JSBluetoothDevice::getName(JSContextRef context,
155                                                                                 JSObjectRef object,
156                                                                                 JSStringRef propertyName,
157                                                                                 JSValueRef* exception)
158 {
159         LogDebug("Enter");      
160
161         Converter converter(context);
162         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
163
164         Try 
165         {
166                 if (priv == NULL)
167                 {
168                         Throw(UnknownException);
169                 }
170
171                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
172                 std::string name = BluetoothDeviceManager->getNameProperty();
173                 LogDebug("name" << name);       
174                 return converter.toJSValueRef(name);
175         }
176         Catch (WrtDeviceApis::Commons::ConversionException)
177         {
178                 LogError("WrtDeviceApis::Commons::ConversionException");
179                 return JSTizenExceptionFactory::postException(context, 
180                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
181         }
182         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
183         {
184                 LogError("InvalidArgumentException");
185                 return JSTizenExceptionFactory::postException(context, 
186                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
187         }
188         Catch (WrtDeviceApis::Commons::Exception) 
189         {
190                 LogError("hasInstance Exception");
191                 return JSTizenExceptionFactory::postException(context, exception,
192                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
193         }
194         return JSValueMakeUndefined(context);
195 }
196
197 JSValueRef JSBluetoothDevice::getAddress(JSContextRef context,
198                                                         JSObjectRef object,
199                                                         JSStringRef propertyName,
200                                                         JSValueRef* exception)
201 {
202         LogDebug("Enter");      
203
204         Converter converter(context);
205         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
206
207         Try 
208         {
209                 if (priv == NULL)
210                 {
211                         Throw(UnknownException);
212                 }
213
214                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
215                 std::string address = BluetoothDeviceManager->getAddressProperty();
216
217                 LogDebug("address" << address); 
218                 return converter.toJSValueRef(address);
219         }
220         Catch (WrtDeviceApis::Commons::ConversionException)
221         {
222                 LogError("ConversationException");
223                 return JSTizenExceptionFactory::postException(context, exception, 
224                         JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
225         }
226         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
227         {
228                 LogError("InvalidArgumentException");
229                 return JSTizenExceptionFactory::postException(context, exception, 
230                         JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
231         }
232         Catch(WrtDeviceApis::Commons::Exception) 
233         {
234                 LogError("hasInstance Exception");
235                 return JSTizenExceptionFactory::postException(context, exception, 
236                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
237         }
238         return JSValueMakeUndefined(context);
239 }
240 JSValueRef JSBluetoothDevice::getDeviceClass(JSContextRef context,
241                                                         JSObjectRef object,
242                                                         JSStringRef propertyName,
243                                                         JSValueRef* exception)
244 {
245         LogDebug("Enter");      
246
247         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
248
249         Try 
250         {
251                 if (priv == NULL)
252                 {
253                         Throw(UnknownException);
254                 }
255                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
256                 BluetoothDeviceDataClass devClass = BluetoothDeviceManager->getClass();
257                 
258                 LogDebug("Major:" << std::hex << devClass.major << "Minor:" << std::hex << devClass.minor << "Service Mask:" << std::hex <<  devClass.majorServiceMask);        
259                 
260                 JSObjectRef adapterObject = JSBluetoothClass::createJSObject(priv->getContext(), devClass);
261                 return adapterObject;
262         }
263         Catch (WrtDeviceApis::Commons::ConversionException)
264         {
265                 LogError("ConversationException");
266                 return JSTizenExceptionFactory::postException(context, 
267                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
268         }
269         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
270         {
271                 LogError("InvalidArgumentException");
272                 return JSTizenExceptionFactory::postException(context, 
273                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
274         }
275         Catch(WrtDeviceApis::Commons::Exception) 
276         {
277                 LogError("hasInstance Exception");
278                 return JSTizenExceptionFactory::postException(context, exception,
279                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
280         }
281         return JSValueMakeUndefined(context);
282
283 }
284 JSValueRef JSBluetoothDevice::getBondProperty(JSContextRef context,
285                                                         JSObjectRef object,
286                                                         JSStringRef propertyName,
287                                                         JSValueRef* exception)
288 {
289         LogDebug("Enter");      
290
291         Converter converter(context);
292         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
293
294         Try 
295         {
296                 if (priv == NULL)
297                 {
298                         Throw(UnknownException);
299                 }
300
301                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
302                 bool isBonded = BluetoothDeviceManager->getBondProperty();
303
304                 LogDebug("isBonded " << isBonded);      
305                 
306                 return converter.toJSValueRef(isBonded);
307         }
308         Catch (WrtDeviceApis::Commons::ConversionException)
309         {
310                 LogError("ConversationException");
311                 return JSTizenExceptionFactory::postException(context, 
312                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid value error");;
313         }
314         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
315         {
316                 LogError("InvalidArgumentException");
317                 return JSTizenExceptionFactory::postException(context, 
318                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
319         }
320         Catch(WrtDeviceApis::Commons::Exception) 
321         {
322                 LogError("hasInstance Exception");
323                 return JSTizenExceptionFactory::postException(context, exception, 
324                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
325         }
326         return JSValueMakeUndefined(context);
327 }
328 JSValueRef JSBluetoothDevice::getTrustProperty(JSContextRef context,
329                                                         JSObjectRef object,
330                                                         JSStringRef propertyName,
331                                                         JSValueRef* exception)
332 {
333         LogDebug("Enter");      
334
335         Converter converter(context);
336         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
337
338         Try 
339         {
340                 if (priv == NULL)
341                 {
342                         Throw(UnknownException);
343                 }
344
345                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
346                 bool isTrusted = BluetoothDeviceManager->getTrustProperty();
347
348                 LogDebug("isTrusted " << isTrusted);    
349                 return converter.toJSValueRef(isTrusted);
350         }
351         Catch (WrtDeviceApis::Commons::ConversionException)
352         {
353                 LogError("ConversationException");
354                 return JSTizenExceptionFactory::postException(context, 
355                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid value error");;
356         }
357         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
358         {
359                 LogError("InvalidArgumentException");
360                 return JSTizenExceptionFactory::postException(context, 
361                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
362         }
363         Catch(WrtDeviceApis::Commons::Exception) 
364         {
365                 LogError("hasInstance Exception");
366                 return JSTizenExceptionFactory::postException(context, exception, 
367                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
368         }
369         return JSValueMakeUndefined(context);   
370 }
371 JSValueRef JSBluetoothDevice::getConnectProperty(JSContextRef context,
372                                                         JSObjectRef object,
373                                                         JSStringRef propertyName,
374                                                         JSValueRef* exception)
375 {
376         LogDebug("Enter");      
377
378         Converter converter(context);
379         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
380
381         Try 
382         {
383                 if (priv == NULL)
384                 {
385                         Throw(UnknownException);
386                 }
387                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
388                 bool isConnected = BluetoothDeviceManager->getConnectProperty();
389
390                 LogDebug("isConnected " << isConnected);        
391                 return converter.toJSValueRef(isConnected);
392         }
393         Catch (WrtDeviceApis::Commons::ConversionException)
394         {
395                 LogError("ConversationException");
396                 return JSTizenExceptionFactory::postException(context, 
397                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid value error");;
398         }
399         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
400         {
401                 LogError("InvalidArgumentException");
402                 return JSTizenExceptionFactory::postException(context, 
403                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
404         }
405         Catch(WrtDeviceApis::Commons::Exception) 
406         {
407                 LogError("hasInstance Exception");
408                 return JSTizenExceptionFactory::postException(context, exception, 
409                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
410         }
411         return JSValueMakeUndefined(context);   
412         
413 }
414
415 JSValueRef JSBluetoothDevice::getUuids(JSContextRef context,
416                                                         JSObjectRef object,
417                                                         JSStringRef propertyName,
418                                                         JSValueRef* exception)
419 {
420         LogDebug("Enter");      
421
422         Converter converter(context);
423         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(object));
424
425         Try 
426         {
427                 if (priv == NULL)
428                 {
429                         Throw(UnknownException);
430                 }
431                 
432                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
433                 std::vector<std::string> uuids = BluetoothDeviceManager->getUuidsProperty();
434                 JSObjectRef result = JSCreateArrayObject(context, 0, NULL);
435                 int length = uuids.size();
436                 
437                 if (!result) 
438                 {
439                         return converter.toJSValueRef("");
440                 }
441
442                 for (int i = 0; i < length; ++i) 
443                 {
444                         JSValueRef value = converter.toJSValueRef(uuids[i]);
445
446                         if (!JSSetArrayElement(context, result, i, value)) 
447                         {
448                                 return converter.toJSValueRef("");
449                         }
450                 }
451
452                 return result;
453         }
454         Catch (WrtDeviceApis::Commons::ConversionException)
455         {
456                 LogError("ConversationException");
457                 return JSTizenExceptionFactory::postException(context, 
458                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid value error");;
459         }
460         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
461         {
462                 LogError("InvalidArgumentException");
463                 return JSTizenExceptionFactory::postException(context, 
464                         exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
465         }
466         Catch(WrtDeviceApis::Commons::Exception) 
467         {
468                 LogError("hasInstance Exception");
469                 return JSTizenExceptionFactory::postException(context, exception, 
470                         JSTizenException::UNKNOWN_ERROR, "Unkown error");
471         }
472         return JSValueMakeUndefined(context);   
473         
474 }
475
476
477         
478
479 JSValueRef JSBluetoothDevice::connectToServiceByUUID(JSContextRef context, JSObjectRef object,
480                 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
481                 JSValueRef* exception) {
482
483         LogDebug("connectToServiceByUUID");
484
485         JSBluetoothDevicePriv *priv = static_cast<JSBluetoothDevicePriv*>(JSObjectGetPrivate(thisObject));
486         JSValueRef successCallback = NULL;
487         JSValueRef errorCallBack = NULL;
488
489
490         Try     {
491
492
493                 if (priv == NULL)
494                 {
495                         LogError("priv null");
496                         Throw(UnknownException);        
497                 }
498
499                 LogDebug(bluetoothExportedNames[BLUETOOTH_FUNCTION_API_DEVICE_CONNECT_TO_SERVICE]);
500
501                 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
502                         priv->getContext(),
503                         bluetoothExportedNames[BLUETOOTH_FUNCTION_API_DEVICE_CONNECT_TO_SERVICE]);
504
505                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
506
507                 if (argumentCount < 2 || argumentCount > 4)
508                 {
509                         LogError("InvalidArgumentException");
510                         return JSTizenExceptionFactory::postException(context, 
511                                 exception, JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
512
513                 }
514                 if (JSValueIsNull(context, arguments[0]) == true || JSValueIsString(context, arguments[0]) == false)
515                 {
516                         LogError("hasInstance TypeMismatchException");
517                         return JSTizenExceptionFactory::postException(context, 
518                                 exception, JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
519                 }
520                 
521                 BluetoothConverter converter(context);
522                 successCallback = converter.toFunction(arguments[1]);
523                 
524                 if (argumentCount >= 3)
525                 {
526                         errorCallBack = converter.toFunctionOrNull(arguments[2]);
527                 }
528                 
529                 JSCallbackManagerPtr cbm = JSCallbackManager::createObject(priv->getContext(), NULL, NULL);
530
531                 if (cbm == NULL)
532                 {
533                         return JSValueMakeUndefined(context);
534                 }
535                 cbm->setOnSuccess(successCallback);
536                 cbm->setOnError(errorCallBack);
537
538                 IBluetoothDeviceManagerPtr BluetoothDeviceManager(priv->getObject());
539                 EventBTConnectToServiceByUUIDPtr event(new EventBTConnectToServiceByUUID);
540                 BluetoothSocketData socketData;
541                 socketData.uuid = converter.toString(arguments[0]);
542                 socketData.protocol  = PROTOCOL_TYPE_RFCOMM_VALUE_INT;
543
544                 if (argumentCount >= 4)
545                 {
546                         if (JSValueIsNull(context, arguments[3]) == true)
547                         {
548                                 socketData.protocol  = PROTOCOL_TYPE_RFCOMM_VALUE_INT;
549                         }
550                         else 
551                         {
552                                 if (JSValueIsString(context, arguments[3]) == false)
553                                 {
554                                         
555                                         LogError("InvalidArgumentException");
556                                         return JSTizenExceptionFactory::postException(context, 
557                                                 exception, JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
558                                 }
559
560                                 std::string protocol = converter.toString(arguments[3]);
561                                 LogDebug(protocol.c_str());
562
563                                 if (strcmp(protocol.c_str(), PROTOCOL_TYPE_RFCOMM_VALUE) == 0)
564                                 {
565                                         socketData.protocol  = PROTOCOL_TYPE_RFCOMM_VALUE_INT;
566                                 }
567                                 else                    
568                                 {
569                                         LogError("BluetoothDeviceManager or event or listener NULL");
570                                         Throw(WrtDeviceApis::Commons::UnsupportedException);    
571                                 }
572
573                         }
574                 }
575                 
576                 if (BluetoothDeviceManager == NULL || event == NULL)
577                 {
578                         LogError("BluetoothDeviceManager or event or listener NULL");
579                         Throw(WrtDeviceApis::Commons::UnknownException);        
580                 }
581
582                 event->setPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData > (cbm));
583
584                 event->setForAsynchronousCall(&BluetoothDeviceManagerListener::getInstance());
585                 event->setSocketData(socketData);
586                 BluetoothDeviceManager->connectToServiceByUUID(event);
587
588                 return JSValueMakeNull(context);
589         }
590         
591         Catch (WrtDeviceApis::Commons::UnsupportedException) 
592         {
593                 LogError("UnsupportedException");
594                 return JSTizenExceptionFactory::postException(context, exception, 
595                                         JSTizenException::NOT_SUPPORTED_ERROR, "not support error");
596
597         }
598         Catch (WrtDeviceApis::Commons::ConversionException)
599         {
600                 LogError("ConversionException");
601                 return JSTizenExceptionFactory::postException(context, exception, 
602                                         JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
603
604         }               
605         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
606         {
607                 LogError("InvalidArgumentException");
608                 return JSTizenExceptionFactory::postException(context, exception, 
609                         JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
610
611         }
612         Catch (WrtDeviceApis::Commons::Exception) 
613         {
614                 LogError("Exception");
615                 return JSTizenExceptionFactory::postException(context, exception, 
616                         JSTizenException::UNKNOWN_ERROR, "unknown error");
617
618         }
619
620         return JSValueMakeUndefined(context);
621 }
622
623
624 }
625 }
626