221d792b1f95034324c67ebafc8c3a412448c209
[framework/web/wrt-plugins-tizen.git] / src / Bluetooth / JSBluetoothAdapter.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 #include <SecurityExceptions.h>
19
20 #include <JSUtil.h>
21 #include <ArgumentValidator.h>
22 #include <GlobalContextManager.h>
23
24 #include "plugin_config.h"
25 #include "JSBluetoothAdapter.h"
26 #include "BluetoothAdapter.h"
27
28 #include <TimeTracer.h>
29 #include <Logger.h>
30
31 using namespace WrtDeviceApis::Commons;
32 using namespace DeviceAPI::Common;
33
34 namespace DeviceAPI {
35 namespace Bluetooth {
36
37 JSClassDefinition JSBluetoothAdapter::m_classInfo = {
38     0,
39     kJSClassAttributeNone,
40     "BluetoothAdapter",
41     NULL, //ParentClass
42     m_property, //StaticValues
43     m_function, //StaticFunctions
44     initialize, //Initialize
45     finalize, //Finalize
46     NULL, //HasProperty,
47     NULL, //GetProperty,
48     NULL, //SetProperty,
49     NULL, //DeleteProperty,
50     NULL, //GetPropertyNames,
51     NULL, //CallAsFunction,
52     NULL, //CallAsConstructor,
53     NULL, //HasInstance,
54     NULL //ConvertToType
55 };
56
57 JSStaticValue JSBluetoothAdapter::m_property[] = {
58     { BLUETOOTH_ADAPTER_NAME, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
59     { BLUETOOTH_ADAPTER_POWERED, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
60     { BLUETOOTH_ADAPTER_VISIBLE, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
61     { BLUETOOTH_ADAPTER_ADDRESS, getProperty, NULL, kJSPropertyAttributeNone|kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontDelete },
62     { 0, 0, 0, 0 }
63 };
64
65 JSStaticFunction JSBluetoothAdapter::m_function[] = {
66     { BLUETOOTH_ADAPTER_API_SET_NAME, setName, kJSPropertyAttributeNone },
67     { BLUETOOTH_ADAPTER_API_SET_POWERED, setPowered, kJSPropertyAttributeNone },
68     { BLUETOOTH_ADAPTER_API_SET_VISIBLE, setVisible, kJSPropertyAttributeNone },
69     { BLUETOOTH_ADAPTER_API_DISCOVER_DEVICES, discoverDevices, kJSPropertyAttributeNone },
70     { BLUETOOTH_ADAPTER_API_STOP_DISCOVERY, stopDiscovery, kJSPropertyAttributeNone },
71     { BLUETOOTH_ADAPTER_API_GET_KNOWN_DEVICES, getKnownDevices, kJSPropertyAttributeNone },
72     { BLUETOOTH_ADAPTER_API_GET_DEVICE, getDevice, kJSPropertyAttributeNone },
73     { BLUETOOTH_ADAPTER_API_CREATE_BONDING, createBonding, kJSPropertyAttributeNone },
74     { BLUETOOTH_ADAPTER_API_DESTROY_BONDING, destroyBonding, kJSPropertyAttributeNone },
75     { BLUETOOTH_ADAPTER_API_REGISTER_RFCOMMSERVICE_BY_UUID, registerRFCOMMServiceByUUID, kJSPropertyAttributeNone },
76     { 0, 0, 0 }
77 };
78
79 JSClassRef JSBluetoothAdapter::m_jsClassRef = JSClassCreate(JSBluetoothAdapter::getClassInfo());
80
81 const JSClassRef JSBluetoothAdapter::getClassRef()
82 {
83     if (!m_jsClassRef) {
84         m_jsClassRef = JSClassCreate(&m_classInfo);
85     }
86     return m_jsClassRef;
87 }
88
89 const JSClassDefinition* JSBluetoothAdapter::getClassInfo()
90 {
91     return &m_classInfo;
92 }
93
94 JSObjectRef JSBluetoothAdapter::createJSObject(JSContextRef context)
95 {
96     return JSObjectMake(context, getClassRef(), NULL);
97 }
98
99 void JSBluetoothAdapter::initialize(JSContextRef context, JSObjectRef object)
100 {
101     // do nothing
102 }
103
104
105 void JSBluetoothAdapter::finalize(JSObjectRef object)
106 {
107     // do nothing
108 }
109
110 JSValueRef JSBluetoothAdapter::getProperty(JSContextRef context,
111         JSObjectRef object,
112         JSStringRef propertyName,
113         JSValueRef* exception)
114 {
115     try {
116         if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_NAME)) {
117             std::string name = BluetoothAdapter::getInstance()->getName();
118             return JSUtil::toJSValueRef(context, name);
119         }
120         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_POWERED)) {
121             return JSUtil::toJSValueRef(context, BluetoothAdapter::getInstance()->getPowered());
122         }
123         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_ADAPTER_VISIBLE)) {
124             return JSUtil::toJSValueRef(context, BluetoothAdapter::getInstance()->getVisible());
125         }
126         else if (JSStringIsEqualToUTF8CString(propertyName, BLUETOOTH_DEVICE_ADDRESS)) {
127             std::string address = BluetoothAdapter::getInstance()->getAddress();
128             return JSUtil::toJSValueRef(context, address);
129         }
130     } catch (const BasePlatformException &err) {
131         LoggerW("Getting property is failed" << err.getMessage().c_str());
132     }
133
134     return NULL;
135 }
136
137 JSValueRef JSBluetoothAdapter::setName(JSContextRef context,
138         JSObjectRef object,
139         JSObjectRef thisObject,
140         size_t argumentCount,
141         const JSValueRef arguments[],
142         JSValueRef* exception)
143 {
144     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
145     
146     // Access Check
147     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_NAME);
148     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
149
150     try {
151         ArgumentValidator validator(context, argumentCount, arguments);        
152         std::string name = validator.toString(0);  // name
153         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
154         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
155
156         // perform
157         MultiCallbackUserDataPtr callback(
158                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
159         if(!callback){
160             LoggerW("Can't create MultiCallbackUserData");
161         }
162         else {
163             callback->setCallback("success", successCallback);
164             callback->setCallback("error", errorCallback);
165         }      
166         
167         BluetoothAdapter::getInstance()->setName(name, callback);        
168         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
169         
170         return JSValueMakeUndefined(context);
171     } catch (const BasePlatformException &err) {
172         return JSWebAPIErrorFactory::postException(context, exception, err);
173     } catch (...) {
174         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setName().");
175         return JSWebAPIErrorFactory::postException(context, exception, err);
176     }
177 }
178
179 JSValueRef JSBluetoothAdapter::setPowered(JSContextRef context,
180         JSObjectRef object,
181         JSObjectRef thisObject,
182         size_t argumentCount,
183         const JSValueRef arguments[],
184         JSValueRef* exception)
185 {
186     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
187     
188     // Access Check
189     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_POWERED);
190     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
191
192     try {
193         // Validate arguments
194         ArgumentValidator validator(context, argumentCount, arguments);
195         bool state = validator.toBool(0);  // state
196         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
197         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
198
199         // perform
200         MultiCallbackUserDataPtr callback(
201                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
202         if(!callback){
203             LoggerW("Can't create MultiCallbackUserData");
204         }
205         else {
206             callback->setCallback("success", successCallback);
207             callback->setCallback("error", errorCallback);        
208         }
209         
210         BluetoothAdapter::getInstance()->setPowered(state, callback);
211         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
212         
213         return JSValueMakeUndefined(context);
214     } catch (const BasePlatformException &err) {
215         return JSWebAPIErrorFactory::postException(context, exception, err);
216     } catch (...) {
217         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setPowered().");
218         return JSWebAPIErrorFactory::postException(context, exception, err);
219     }
220 }
221
222 JSValueRef JSBluetoothAdapter::setVisible(JSContextRef context,
223         JSObjectRef object,
224         JSObjectRef thisObject,
225         size_t argumentCount,
226         const JSValueRef arguments[],
227         JSValueRef* exception)
228 {
229     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
230
231     // Access Check
232     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_SET_VISIBLE);
233     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
234
235     try {    
236         // Validate arguments
237         ArgumentValidator validator(context, argumentCount, arguments);
238         bool mode = validator.toBool(0);  // mode
239         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
240         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
241         unsigned long timeout = validator.toULong(3, true);  // timeout 
242         if(timeout > 65535)
243             timeout = 180;
244
245         // perform
246         MultiCallbackUserDataPtr callback(
247                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
248         if(!callback){
249             LoggerW("Can't create MultiCallbackUserData");
250         }
251         else {
252             callback->setCallback("success", successCallback);
253             callback->setCallback("error", errorCallback);            
254         }
255         
256         BluetoothAdapter::getInstance()->setVisible(mode, timeout, callback);
257         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
258         
259         return JSValueMakeUndefined(context);
260     } catch (const BasePlatformException &err) {
261         return JSWebAPIErrorFactory::postException(context, exception, err);
262     } catch (...) {
263         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.setVisible().");
264         return JSWebAPIErrorFactory::postException(context, exception, err);
265     }
266 }
267
268 JSValueRef JSBluetoothAdapter::discoverDevices(JSContextRef context,
269         JSObjectRef object,
270         JSObjectRef thisObject,
271         size_t argumentCount,
272         const JSValueRef arguments[],
273         JSValueRef* exception)
274 {
275     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
276
277     // Access Check
278     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_DISCOVER_DEVICES);
279     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
280
281     try {    
282         // Validate arguments
283         ArgumentValidator validator(context, argumentCount, arguments);
284
285         // successCallback
286         JSObjectRef successCallback = validator.toCallbackObject(0, false, "onstarted", "ondevicefound", "ondevicedisappeared", "onfinished", NULL);
287
288         // errorCallback
289         JSObjectRef errorCallback = validator.toFunction(1, true);
290
291         MultiCallbackUserDataPtr callback(
292                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
293         if(!callback){
294             LoggerW("Can't create MultiMultiCallbackUserData");
295         }
296         else {
297             // onstarted
298             JSValueRef onstartedValue = JSUtil::getProperty(context , successCallback, "onstarted");
299             if(!JSValueIsUndefined(context, onstartedValue)) {
300                 LoggerD("There is a onstarted()");
301                 callback->setCallback("onstarted", JSUtil::JSValueToObject(context, onstartedValue));
302             }
303             
304             // ondevicefound
305             JSValueRef ondevicefoundValue = JSUtil::getProperty(context , successCallback, "ondevicefound");
306             if(!JSValueIsUndefined(context, ondevicefoundValue)) {
307                 LoggerD("There is a ondevicefound()");
308                 callback->setCallback("ondevicefound", JSUtil::JSValueToObject(context, ondevicefoundValue));
309             }
310             
311             // ondevicedisappeared
312             JSValueRef ondevicedisappearedValue = JSUtil::getProperty(context , successCallback, "ondevicedisappeared");
313             if(!JSValueIsUndefined(context, ondevicedisappearedValue)) {
314                 LoggerD("There is a ondevicedisappeared()");
315                 callback->setCallback("ondevicedisappeared", JSUtil::JSValueToObject(context, ondevicedisappearedValue));
316             }
317             
318             // onfinished
319             JSValueRef onfinishedValue = JSUtil::getProperty(context , successCallback, "onfinished");
320             if(!JSValueIsUndefined(context, onfinishedValue)) {
321                 LoggerD("There is a onfinished()");
322                 callback->setCallback("onfinished", JSUtil::JSValueToObject(context, onfinishedValue));
323             }      
324             
325             callback->setCallback("error", errorCallback);        
326         }
327         
328         // perform       
329         BluetoothAdapter::getInstance()->discoverDevices(callback);
330         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
331         
332         return JSValueMakeUndefined(context);
333     } catch (const BasePlatformException &err) {
334         return JSWebAPIErrorFactory::postException(context, exception, err);
335     } catch (...) {
336         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.discoverDevices().");
337         return JSWebAPIErrorFactory::postException(context, exception, err);
338     }
339 }
340
341 JSValueRef JSBluetoothAdapter::stopDiscovery(JSContextRef context,
342         JSObjectRef object,
343         JSObjectRef thisObject,
344         size_t argumentCount,
345         const JSValueRef arguments[],
346         JSValueRef* exception)
347 {
348     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
349
350     // Access Check
351     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_STOP_DISCOVERY);
352     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
353
354     try {
355         // Validate arguments
356         ArgumentValidator validator(context, argumentCount, arguments);
357         JSObjectRef successCallback = validator.toFunction(0, true);  // successCallback  
358         JSObjectRef errorCallback = validator.toFunction(1, true);  // errorCallback
359
360         // perform
361         MultiCallbackUserDataPtr callback(
362                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
363         if(!callback){
364             LoggerW("Can't create MultiCallbackUserData");
365         }
366         else {
367             callback->setCallback("success", successCallback);
368             callback->setCallback("error", errorCallback);        
369         }
370         
371         BluetoothAdapter::getInstance()->stopDiscovery(callback);
372         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
373
374         return JSValueMakeUndefined(context);
375     } catch (const BasePlatformException &err) {
376         return JSWebAPIErrorFactory::postException(context, exception, err);
377     } catch (...) {
378         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.stopDiscovery().");
379         return JSWebAPIErrorFactory::postException(context, exception, err);
380     }
381 }
382
383 JSValueRef JSBluetoothAdapter::getKnownDevices(JSContextRef context,
384         JSObjectRef object,
385         JSObjectRef thisObject,
386         size_t argumentCount,
387         const JSValueRef arguments[],
388         JSValueRef* exception)
389 {
390     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
391
392     // Access Check
393     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_GET_KNOWN_DEVICES);
394     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
395
396     try {
397         // Validate arguments
398         ArgumentValidator validator(context, argumentCount, arguments);
399         JSObjectRef successCallback = validator.toFunction(0);  // successCallback  
400         JSObjectRef errorCallback = validator.toFunction(1, true);  // errorCallback
401
402         // perform
403         MultiCallbackUserDataPtr callback(
404                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
405         if(!callback){
406             LoggerW("Can't create MultiCallbackUserData");
407         }
408         else {
409             callback->setCallback("success", successCallback);
410             callback->setCallback("error", errorCallback);        
411         }
412         
413         BluetoothAdapter::getInstance()->getKnownDevices(callback);
414         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
415         
416         return JSValueMakeUndefined(context);
417     } catch (const BasePlatformException &err) {
418         return JSWebAPIErrorFactory::postException(context, exception, err);
419     } catch (...) {
420         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.getKnownDevices().");
421         return JSWebAPIErrorFactory::postException(context, exception, err);
422     }
423 }
424
425 JSValueRef JSBluetoothAdapter::getDevice(JSContextRef context,
426         JSObjectRef object,
427         JSObjectRef thisObject,
428         size_t argumentCount,
429         const JSValueRef arguments[],
430         JSValueRef* exception)
431 {
432     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
433
434     // Access Check
435     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_GET_DEVICE);
436     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
437
438     try {
439         // Validate arguments
440         ArgumentValidator validator(context, argumentCount, arguments);
441         std::string address = validator.toString(0);  // address
442         JSObjectRef successCallback = validator.toFunction(1);  // successCallback  
443         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
444
445         // perform
446         MultiCallbackUserDataPtr callback(
447                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
448         if(!callback){
449             LoggerW("Can't create MultiCallbackUserData");
450         }
451         else {
452             callback->setCallback("success", successCallback);
453             callback->setCallback("error", errorCallback);        
454         }
455         
456         BluetoothAdapter::getInstance()->getDevice(address, callback);
457         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
458         
459         return JSValueMakeUndefined(context);
460     } catch (const BasePlatformException &err) {
461         return JSWebAPIErrorFactory::postException(context, exception, err);
462     } catch (...) {
463         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.getDevice().");
464         return JSWebAPIErrorFactory::postException(context, exception, err);
465     }
466 }
467
468 JSValueRef JSBluetoothAdapter::createBonding(JSContextRef context,
469         JSObjectRef object,
470         JSObjectRef thisObject,
471         size_t argumentCount,
472         const JSValueRef arguments[],
473         JSValueRef* exception)
474 {
475     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
476
477     // Access Check
478     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_CREATE_BONDING);
479     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
480
481     try {
482         // Validate arguments
483         ArgumentValidator validator(context, argumentCount, arguments);
484         std::string address = validator.toString(0);  // address
485         JSObjectRef successCallback = validator.toFunction(1);  // successCallback  
486         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
487
488         // perform
489         MultiCallbackUserDataPtr callback(
490                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
491         if(!callback){
492             LoggerW("Can't create MultiCallbackUserData");
493         }
494         else {
495             callback->setCallback("success", successCallback);
496             callback->setCallback("error", errorCallback);        
497         }
498         
499         BluetoothAdapter::getInstance()->createBonding(address, callback);
500         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
501         
502         return JSValueMakeUndefined(context);
503     } catch (const BasePlatformException &err) {
504         return JSWebAPIErrorFactory::postException(context, exception, err);
505     } catch (...) {
506         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.createBonding().");
507         return JSWebAPIErrorFactory::postException(context, exception, err);
508     }
509 }
510
511 JSValueRef JSBluetoothAdapter::destroyBonding(JSContextRef context,
512         JSObjectRef object,
513         JSObjectRef thisObject,
514         size_t argumentCount,
515         const JSValueRef arguments[],
516         JSValueRef* exception)
517 {
518     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
519
520     // Access Check
521     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_DESTROY_BONDING);
522     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
523
524     try {
525         // Validate arguments
526         ArgumentValidator validator(context, argumentCount, arguments);
527         std::string address = validator.toString(0);  // address
528         JSObjectRef successCallback = validator.toFunction(1, true);  // successCallback  
529         JSObjectRef errorCallback = validator.toFunction(2, true);  // errorCallback
530
531         // perform
532         MultiCallbackUserDataPtr callback(
533                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
534         if(!callback){
535             LoggerW("Can't create MultiCallbackUserData");
536         }
537         else {
538             callback->setCallback("success", successCallback);
539             callback->setCallback("error", errorCallback);        
540         }
541         
542         BluetoothAdapter::getInstance()->destroyBonding(address, callback);
543         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
544         
545         return JSValueMakeUndefined(context);
546     } catch (const BasePlatformException &err) {
547         return JSWebAPIErrorFactory::postException(context, exception, err);
548     } catch (...) {
549         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.destroyBonding().");
550         return JSWebAPIErrorFactory::postException(context, exception, err);
551     }
552 }
553
554 JSValueRef JSBluetoothAdapter::registerRFCOMMServiceByUUID(JSContextRef context,
555         JSObjectRef object,
556         JSObjectRef thisObject,
557         size_t argumentCount,
558         const JSValueRef arguments[],
559         JSValueRef* exception)
560 {
561     TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
562
563     // Access Check
564     AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(BLUETOOTH_ADAPTER_API_REGISTER_RFCOMMSERVICE_BY_UUID);
565     TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
566
567     try {
568         // Validate arguments
569         ArgumentValidator validator(context, argumentCount, arguments);
570         std::string uuid = validator.toString(0);  // uuid
571         std::string name = validator.toString(1);  // name
572         JSObjectRef successCallback = validator.toFunction(2);  // successCallback  
573         JSObjectRef errorCallback = validator.toFunction(3, true);  // errorCallback
574
575         // perform
576         MultiCallbackUserDataPtr callback(
577                 new MultiCallbackUserData(GlobalContextManager::getInstance()->getGlobalContext(context)));
578         if(!callback){
579             LoggerW("Can't create MultiCallbackUserData");
580         }
581         else {
582             callback->setCallback("success", successCallback);
583             callback->setCallback("error", errorCallback);        
584         }
585         
586         BluetoothAdapter::getInstance()->registerRFCOMMServiceByUUID(uuid, name, callback);
587         TIME_TRACER_ITEM_END(__FUNCTION__, 0);
588         
589         return JSValueMakeUndefined(context);
590     } catch (const BasePlatformException &err) {
591         return JSWebAPIErrorFactory::postException(context, exception, err);
592     } catch (...) {
593         DeviceAPI::Common::UnknownException err("Unknown Error in BluetoothAdapter.registerRFCOMMServiceByUUID().");
594         return JSWebAPIErrorFactory::postException(context, exception, err);
595     }
596 }
597
598
599 } // Bluetooth
600 } // DeviceAPI