tizen 2.3.1 release
[framework/web/wearable/wrt-plugins-tizen.git] / src / Bluetooth / BluetoothGATTBase.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 #include "BluetoothGATTBase.h"
18 #include <PlatformException.h>
19 #include <MultiCallbackUserData.h>
20 #include <Logger.h>
21 #include <JSUtil.h>
22 #include <JSWebAPIErrorFactory.h>
23 #include <bits/unique_ptr.h>
24 #include "BluetoothUtil.h"
25
26 namespace DeviceAPI {
27 namespace Bluetooth {
28
29 BluetoothGATTBase::BluetoothGATTBase(bt_gatt_h _handle) :m_handle(_handle) {
30
31 }
32
33 BluetoothGATTBase::~BluetoothGATTBase() {
34
35 }
36
37 struct ReadValueData {
38     Common::MultiCallbackUserData* pCallback;
39     JSObjectRef errorobj;
40 };
41
42 void BluetoothGATTBase::readValue(Common::MultiCallbackUserData* pCallback) {
43     LOGD("Entered");
44     int ret = bt_gatt_client_read_value(m_handle,
45         readNativeCallback, static_cast<void*>(pCallback));
46     if(ret != BT_ERROR_NONE) {
47         if (ret == BT_ERROR_NOT_ENABLED) {
48             LOGE("LE is currently not enabled");
49             throw Common::InvalidStateException("LE is currently not enabled");
50         }
51         LOGE("Couldn't register callback for read value");
52         postError(pCallback, ret);
53     }
54 }
55
56 void BluetoothGATTBase::postError(Common::MultiCallbackUserData* _pCallback, int _errorCode) {
57     JSObjectRef errorobj = Common::JSWebAPIErrorFactory::makeErrorObject(
58         _pCallback->getContext(),
59         Common::JSWebAPIErrorFactory::UNKNOWN_ERROR,
60         BluetoothUtil::getBluetoothErrorMessage(_errorCode));
61     JSValueProtect(_pCallback->getContext(), errorobj);
62     ReadValueData* pData = new ReadValueData();
63     pData->pCallback = _pCallback;
64     pData->errorobj = errorobj;
65
66     guint error = g_idle_add( asyncError, static_cast<void*>(pData));
67     if(error == 0) {
68         LOGE("Failed to add error callback to idle");
69         delete pData;
70         delete _pCallback;
71     }
72 }
73
74 gboolean BluetoothGATTBase::asyncError(gpointer _pUserData) {
75     auto pReadValueData = static_cast<ReadValueData*>(_pUserData);
76     pReadValueData->pCallback->invokeCallback("error", pReadValueData->errorobj);
77     JSValueUnprotect(pReadValueData->pCallback->getContext(), pReadValueData->errorobj);
78     delete pReadValueData->pCallback;
79     delete pReadValueData;
80     return G_SOURCE_REMOVE;
81 }
82
83 void BluetoothGATTBase::readNativeCallback(int result,
84     bt_gatt_h request_handle, void *user_data) {
85     LOGD("Entered");
86     auto pCallback = static_cast<Common::MultiCallbackUserData*>(user_data);
87     if(result != BT_ERROR_NONE) {
88         postError(pCallback, result);
89     }
90     else {
91         char *value = NULL;
92         int length = 0;
93         int ret = bt_gatt_get_value(request_handle, &value, &length);
94         if(ret != BT_ERROR_NONE) {
95             postError(pCallback, ret);
96             return;
97         }
98         std::vector<signed char> valueVect;
99         for(int i = 0; i < length; ++i) {
100             valueVect.push_back(value[i]);
101         }
102         JSValueRef jsResult = Common::JSUtil::toJSValueRef_<signed char>(pCallback->getContext(),valueVect);
103         pCallback->invokeCallback("onread", jsResult);
104         g_free(value);
105         delete pCallback;
106     }
107 }
108
109 void BluetoothGATTBase::writeNativeCallback(int result,
110     bt_gatt_h request_handle, void *user_data) {
111
112     auto pCallback = static_cast<Common::MultiCallbackUserData*>(user_data);
113     if(result == BT_ERROR_NONE) {
114         pCallback->invokeCallback("onsuccess");
115         delete pCallback;
116     }
117     else {
118         postError(pCallback, result);
119     }
120 }
121
122 void BluetoothGATTBase::writeValue(std::unique_ptr<char[]> data, int dataSize, Common::MultiCallbackUserData* pCallback) {
123     LOGD("Entered");
124
125     int ret = bt_gatt_set_value(m_handle, data.get(), dataSize);
126
127     if(ret != BT_ERROR_NONE){
128         if (ret == BT_ERROR_NOT_ENABLED) {
129             LOGE("LE is currently not enabled");
130             throw Common::InvalidStateException("LE is currently not enabled");
131         }
132         LOGE("Set value failed with %d", ret);
133         postError(pCallback, ret);
134         return;
135     }
136
137     int check = bt_gatt_client_write_value(m_handle,
138         writeNativeCallback, static_cast<void*>(pCallback));
139     if(check != BT_ERROR_NONE) {
140         LOGE("Could not write value %d", check);
141         postError(pCallback, check);
142     }
143 }
144
145 } // namespace Bluetooth
146 } // namespace DeviceAPI
147