Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / standards / Tizen / Bluetooth / JSBluetoothSocket.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/JSTizenExceptionFactory.h>
23 #include <Tizen/Common/JSTizenException.h>
24 #include <Tizen/Common/SecurityExceptions.h>
25 #include <API/Bluetooth/BluetoothFactory.h>
26 #include <API/Bluetooth/BluetoothProperty.h>
27 #include <dpl/scoped_array.h>
28 #include <dpl/scoped_free.h>
29 #include "BluetoothSocketListener.h"
30 #include "JSBluetoothSocket.h"
31 #include "JSBluetoothDevice.h"
32 #include "BluetoothMultiCallback.h"
33 #include "BluetoothConverter.h"
34 #include <bluetooth.h>
35 #include "plugin_config.h"
36
37 using namespace std;
38 using namespace DPL;
39 using namespace TizenApis::Api;
40 using namespace TizenApis::Api::Bluetooth;
41 using namespace TizenApis::Commons;
42
43
44 namespace TizenApis {
45 namespace Tizen1_0 {
46
47
48 JSClassDefinition JSBluetoothSocket::m_classInfo =
49 {
50         0,
51         kJSClassAttributeNone,
52         "BluetoothSocket",
53         NULL,
54         m_properties,
55         m_function,
56         initialize,
57         finalize,
58         NULL, 
59         NULL, 
60         NULL, 
61         NULL, 
62         NULL, 
63         NULL,
64         NULL,
65         hasInstance,
66         NULL
67 };
68
69 JSStaticValue JSBluetoothSocket::m_properties[] = 
70 {
71         {"uuid", getProperty, NULL, kJSPropertyAttributeReadOnly},
72         {"protocol", getProperty, NULL, kJSPropertyAttributeReadOnly},
73         {"state", getProperty, NULL, kJSPropertyAttributeReadOnly},
74         {"peer", getProperty, NULL, kJSPropertyAttributeReadOnly},
75         {"onError", NULL, setProperty, kJSPropertyAttributeNone},
76         {"onMessage", NULL, setProperty, kJSPropertyAttributeNone},
77         {"onClose", NULL, setProperty, kJSPropertyAttributeNone},
78         {0, 0, 0, 0}
79 };
80
81
82 JSStaticFunction JSBluetoothSocket::m_function[] =
83 {
84         { "writeData", JSBluetoothSocket::writeData, kJSPropertyAttributeNone },
85         { "readData", JSBluetoothSocket::readData, kJSPropertyAttributeNone },
86         { "close", JSBluetoothSocket::close, kJSPropertyAttributeNone },        
87         { 0, 0, 0 }
88 };
89
90 const JSClassRef JSBluetoothSocket::getClassRef() 
91 {
92         if (!m_jsClassRef) 
93         {
94                 m_jsClassRef = JSClassCreate(&m_classInfo);
95         }
96         return m_jsClassRef;
97 }
98
99 const JSClassDefinition* JSBluetoothSocket::getClassInfo() 
100 {
101         return &m_classInfo;
102 }
103
104 JSClassRef JSBluetoothSocket::m_jsClassRef = JSClassCreate(JSBluetoothSocket::getClassInfo());
105
106 bool JSBluetoothSocket::setProperty(JSContextRef context, 
107                                         JSObjectRef object,
108                                         JSStringRef propertyName,
109                                         JSValueRef value,
110                                         JSValueRef* exception)
111 {
112         LogDebug("OK");
113         
114         try 
115         {
116                 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
117                 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
118                 BluetoothConverter converter(priv->getContext());
119                 
120                 if (priv == NULL)
121                 {
122                         ThrowMsg(ConversionException, "private object null");
123                 }
124
125                 EventBTSocketNotificationEmitterPtr emitter = BluetoothSocketManager->getSocketNotifier();
126         
127                 if (BluetoothSocketManager == NULL || emitter == NULL)
128                 {
129                         LogError("BluetoothManager or event or listener NULL");
130                         Throw(WrtDeviceApis::Commons::UnknownException);        
131                 }
132                 
133                 BluetoothSocketNotifierPrivateDataPtr privData = 
134                                 DPL::DynamicPointerCast<BluetoothSocketNotifierPrivateData>(emitter->getEventPrivateData());
135
136                 if (privData == NULL)
137                 {
138                         LogError("privData NULL");
139                         Throw(WrtDeviceApis::Commons::UnknownException);        
140                 }
141                 
142                 converter.setBluetoothSocketNotifierCallback(propertyName, value, object, privData);
143                 emitter->setListener(&BluetoothSocketListener::getInstance());
144                 emitter->setEventPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privData));
145
146                 return true;
147         }
148         catch (WrtDeviceApis::Commons::Exception& ex) 
149         {
150                 LogError("Exception: " << ex.GetMessage());
151
152                 switch (ex.getCode())
153                 {
154                 case WrtDeviceApis::Commons::ExceptionCodes::ConversionException:
155                         JSTizenExceptionFactory::postException(context, exception,
156                                 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
157                         break;
158                 case WrtDeviceApis::Commons::ExceptionCodes::InvalidArgumentException:
159                         JSTizenExceptionFactory::postException(context, exception,
160                                 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
161                         break;
162                 case WrtDeviceApis::Commons::ExceptionCodes::Exception:
163                 default:
164                         JSTizenExceptionFactory::postException(context, exception,
165                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
166                 }
167         }       
168         return false;
169
170 }
171
172 void JSBluetoothSocket::initialize(JSContextRef context, JSObjectRef object) 
173 {
174         LogDebug("JSBluetoothSocket::initialize ");
175         
176 }
177
178 void JSBluetoothSocket::finalize(JSObjectRef object) 
179 {
180         LogDebug("JSBluetoothSocket::Finalrize");
181
182         JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
183
184         if (priv != NULL)
185         {
186                 delete priv;
187                 JSObjectSetPrivate(object, NULL);
188         }
189 }
190
191 bool JSBluetoothSocket::hasInstance(JSContextRef context, JSObjectRef constructor,
192                 JSValueRef possibleInstance, JSValueRef* exception) 
193 {
194         return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
195 }
196
197 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketData socketData)
198 {
199         IBluetoothSocketManagerPtr BluetoothSocketManager(BluetoothFactory::getInstance().getBluetoothSocketManager());
200         JSBluetoothSocketPriv* priv = new JSBluetoothSocketPriv( context, BluetoothSocketManager);
201         BluetoothSocketManager->setSocketData(socketData);
202
203         try 
204         {
205                 if (BluetoothSocketManager == NULL || priv == NULL)
206                 {
207                         LogError("BluetoothManager or event or listener NULL");
208                         Throw(WrtDeviceApis::Commons::UnknownException);        
209                 }
210
211                 BluetoothConverter converter(priv->getContext());
212                 EventBTSocketNotificationEmitterPtr emitter(new EventBTSocketNotificationEmitter);
213
214                 BluetoothSocketNotifierPrivateDataPtr privData(converter.getInitalBluetoothSocketNotifierPrivateData());
215                 emitter->setListener(&BluetoothSocketListener::getInstance());
216                 emitter->setEventPrivateData(DPL::StaticPointerCast<WrtDeviceApis::Commons::IEventPrivateData>(privData));
217                 
218                 if (BluetoothSocketManager->setSocketNotifier(emitter) != BT_ERROR_NONE)
219                 {
220                         LogError("callback set error");
221                         Throw(WrtDeviceApis::Commons::UnknownException);        
222                 }
223                 
224                 return JSObjectMake(context, getClassRef(), priv);
225         }
226         catch (WrtDeviceApis::Commons::Exception& ex) 
227         {
228                 LogError("Exception: " << ex.GetMessage());
229
230                 switch (ex.getCode())
231                 {
232                 case WrtDeviceApis::Commons::ExceptionCodes::ConversionException:
233                         return JSTizenExceptionFactory::makeErrorObject(context,
234                                 JSTizenException::TYPE_MISMATCH_ERROR, "type mismatch error");
235                 case WrtDeviceApis::Commons::ExceptionCodes::InvalidArgumentException:
236                         return JSTizenExceptionFactory::makeErrorObject(context,
237                                 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
238                 case WrtDeviceApis::Commons::ExceptionCodes::Exception:
239                 default:
240                         return JSTizenExceptionFactory::makeErrorObject(context,
241                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
242                 }
243         }               
244
245         
246 }
247
248 JSObjectRef JSBluetoothSocket::createJSObject(JSContextRef context, BluetoothSocketData socketData, EventBTReadDataType readData)
249 {
250         IBluetoothSocketManagerPtr BluetoothSocketManager(BluetoothFactory::getInstance().getBluetoothSocketManager());
251         JSBluetoothSocketPriv* priv = new JSBluetoothSocketPriv( context, BluetoothSocketManager);
252         BluetoothSocketManager->setSocketData(socketData);
253         BluetoothSocketManager->setReadData(readData);
254         return JSObjectMake(context, getClassRef(), priv);
255 }
256 JSValueRef JSBluetoothSocket::getProperty(JSContextRef context,
257                                                         JSObjectRef object,
258                                                         JSStringRef propertyName,
259                                                         JSValueRef* exception)
260 {
261         LogDebug("OK"); 
262
263         
264         try 
265         {
266                 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(object));
267                 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
268                 BluetoothConverter converter(priv->getContext());
269
270                 if (priv == NULL)
271                 {
272                         LogError("priv null");
273                         Throw(WrtDeviceApis::Commons::UnknownException);        
274                 }
275
276                 if(JSStringIsEqualToUTF8CString(propertyName, "uuid")) 
277                 {
278                         std::string uuid = BluetoothSocketManager->getUUID();
279                         return converter.toJSValueRef(uuid);
280                 }
281                 else if(JSStringIsEqualToUTF8CString(propertyName, "protocol")) 
282                 {
283                         unsigned short int protocol = BluetoothSocketManager->getProtocol();
284                         return converter.toBluetoothProtocolJSValue(protocol);
285
286                 }
287                 else if(JSStringIsEqualToUTF8CString(propertyName, "state")) 
288                 {
289                         unsigned short int state = BluetoothSocketManager->getState();
290                         return converter.toBluetoothStateJSValue(state);
291                 }
292                 else if(JSStringIsEqualToUTF8CString(propertyName, "peer")) 
293                 {
294                         BluetoothDeviceData device = BluetoothSocketManager->getPeer();
295                         JSObjectRef adapterObject = JSBluetoothDevice::createJSObject(priv->getContext(), device);
296                         return adapterObject;
297                 }
298         }
299         
300         Catch (WrtDeviceApis::Commons::SecurityException) 
301         {
302                 LogError("permission denied error");
303                 return JSTizenExceptionFactory::postException(context, exception, 
304                         JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");  
305
306         }
307         Catch (WrtDeviceApis::Commons::ConversionException)
308         {
309                 LogError("ConversionException");
310                 return JSTizenExceptionFactory::postException(context, exception,
311                                 JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
312         }
313         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
314         {
315                 LogError("InvalidArgumentException");
316                 return JSTizenExceptionFactory::postException(context, exception,
317                                 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
318         }
319         Catch (WrtDeviceApis::Commons::UnknownException) 
320         {
321                 return JSTizenExceptionFactory::postException(context, exception,
322                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
323         }
324         Catch(WrtDeviceApis::Commons::Exception) 
325         {
326                 LogError("UnkownException");
327                 return JSTizenExceptionFactory::postException(context, exception,
328                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
329         }       
330
331         return JSValueMakeUndefined(context);
332 }
333
334
335 JSValueRef JSBluetoothSocket::writeData(JSContextRef context, JSObjectRef object,
336                 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
337                 JSValueRef* exception) 
338 {
339         LogDebug("JSBluetoothSocket");
340         Converter converter(context);   
341         Try     
342         {
343                 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
344
345                 if (priv == NULL) 
346                 {
347                         LogError("priv null");
348                         Throw(WrtDeviceApis::Commons::UnknownException);                                
349                 }
350
351                 if (argumentCount < 1 || JSValueIsNull(context, arguments[0]) == true)
352                 {
353                         LogError("argument wrong");
354                         Throw(WrtDeviceApis::Commons::InvalidArgumentException);                                
355                 }
356
357                 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
358                         priv->getContext(),
359                         bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_WRITE_DATA]);
360
361                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
362
363                 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
364                 std::vector<char> data = converter.toVectorOfChars(arguments[0]);
365                 unsigned int index = 0;
366                 
367                 if (data.size() == 0)
368                 {
369                         LogError("size 0 array passed");
370                         Throw(WrtDeviceApis::Commons::InvalidArgumentException);                                
371                 }
372
373         DPL::ScopedArray<char> buffer(new char[data.size()]);
374
375                 for (index = 0; index < data.size(); index++)
376                 {
377                         buffer[index] = data[index];
378                 }
379                 
380                 if (BluetoothSocketManager->writeData(buffer.Get(), data.size()) != BT_ERROR_NONE)
381                 {
382                         LogError("BluetoothSocket Write Error");
383                         Throw(WrtDeviceApis::Commons::UnknownException);        
384                 }
385                 
386                 return converter.toJSValueRef(data.size());
387         }
388         Catch (WrtDeviceApis::Commons::SecurityException) 
389         {
390                 LogError("permission denied error");
391                 return JSTizenExceptionFactory::postException(context, exception, 
392                         JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");  
393
394         }
395         Catch (WrtDeviceApis::Commons::ConversionException)
396         {
397                 LogError("ConversionException");
398                 return JSTizenExceptionFactory::postException(context, exception,
399                                 JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
400         }
401         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
402         {
403                 LogError("InvalidArgumentException");
404                 return JSTizenExceptionFactory::postException(context, exception,
405                                 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
406         }
407         Catch (WrtDeviceApis::Commons::UnknownException) 
408         {
409                 return JSTizenExceptionFactory::postException(context, exception,
410                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
411         }
412         Catch(WrtDeviceApis::Commons::Exception) 
413         {
414                 LogError("UnkownException");
415                 return JSTizenExceptionFactory::postException(context, exception,
416                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
417         }
418         
419         return converter.toJSValueRef(0);
420 }
421
422
423 JSValueRef JSBluetoothSocket::readData(JSContextRef context, JSObjectRef object,
424                 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
425                 JSValueRef* exception) 
426 {
427
428
429         LogDebug("JSBluetoothSocket");
430
431         Try     
432         {
433                 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
434                 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
435
436                 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
437                         priv->getContext(),
438                         bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_READ_DATA]);
439                 
440                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
441                 
442
443                 EventBTReadDataType     data = BluetoothSocketManager->readData();
444                 int length = data.size();
445                 LogDebug("size" << length);
446                 BluetoothConverter converter(priv->getContext());
447
448                 if (length == 0)
449                 {
450                         LogError("BluetoothSocket Read Error");
451                         Throw(WrtDeviceApis::Commons::InvalidArgumentException);        
452                 }
453
454
455                 JSObjectRef result = converter.toBluetoothByteArray(data);
456                 return result;
457         }
458         Catch (WrtDeviceApis::Commons::SecurityException) 
459         {
460                 LogError("permission denied error");
461                 return JSTizenExceptionFactory::postException(context, exception, 
462                         JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");  
463
464         }
465         Catch (WrtDeviceApis::Commons::ConversionException)
466         {
467                 LogError("ConversionException");
468                 return JSTizenExceptionFactory::postException(context, exception,
469                                 JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
470         }
471         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
472         {
473                 LogError("InvalidArgumentException");
474                 return JSTizenExceptionFactory::postException(context, exception,
475                                 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
476         }
477         Catch(WrtDeviceApis::Commons::Exception) 
478         {
479                 LogError("UnkownException");
480                 return JSTizenExceptionFactory::postException(context, exception,
481                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
482         }
483                 
484         return JSValueMakeUndefined(context);
485 }
486
487
488 JSValueRef JSBluetoothSocket::close(JSContextRef context, JSObjectRef object,
489                 JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[],
490                 JSValueRef* exception) 
491 {
492         LogDebug("JSBluetoothSocket");
493
494         Try     
495         {
496                 JSBluetoothSocketPriv *priv = static_cast<JSBluetoothSocketPriv*>(JSObjectGetPrivate(thisObject));
497
498                 IBluetoothSocketManagerPtr BluetoothSocketManager(priv->getObject());
499
500                 LogDebug(bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_CLOSE]);
501
502                 AceSecurityStatus status = BLUETOOTH_CHECK_ACCESS(
503                         priv->getContext(),
504                         bluetoothExportedNames[BLUETOOTH_FUNCTION_API_SOCKET_CLOSE]);
505
506
507                 TIZEN_SYNC_ACCESS_HANDLER(status, context, exception);
508
509         }
510         Catch (WrtDeviceApis::Commons::SecurityException) 
511         {
512                 LogError("permission denied error");
513                 return JSTizenExceptionFactory::postException(context, exception, 
514                         JSTizenException::PERMISSION_DENIED_ERROR, "permission denied error");  
515
516         }
517         Catch (WrtDeviceApis::Commons::ConversionException)
518         {
519                 LogError("ConversionException");
520                 return JSTizenExceptionFactory::postException(context, exception,
521                                 JSTizenException::INVALID_VALUES_ERROR, "invalid value error");
522         }
523         Catch (WrtDeviceApis::Commons::InvalidArgumentException) 
524         {
525                 LogError("InvalidArgumentException");
526                 return JSTizenExceptionFactory::postException(context, exception,
527                                 JSTizenException::INVALID_VALUES_ERROR, "invalid parameter error");
528         }
529         Catch(WrtDeviceApis::Commons::Exception) 
530         {
531                 LogError("UnkownException");
532                 return JSTizenExceptionFactory::postException(context, exception,
533                                 JSTizenException::UNKNOWN_ERROR, "Unkown error");
534         }
535
536                 
537         return JSValueMakeUndefined(context);
538
539 }
540 }
541 }
542