Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / arduino / cableserver.cpp
1 /******************************************************************
2 *
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
4 *
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************/
20
21
22 //logger.h included first to avoid conflict with RBL library PROGMEM attribute
23 #include "logger.h"
24
25 #include "cableserver.h"
26
27 #include <Arduino.h>
28 #include <SPI.h>
29 #include <boards.h>
30 #include <RBL_nRF8001.h>
31
32 #include "caleinterface.h"
33 #include "oic_malloc.h"
34 #include "caadapterutils.h"
35 #include "cafragmentation.h"
36
37 #define TAG "LES"
38
39 /**
40  * @var    g_bleServerDataReceivedCallback
41  * @brief  Maintains the callback to be notified on receival of network packets from other
42  *           BLE devices
43  */
44 static CABLEServerDataReceivedCallback g_bleServerDataReceivedCallback = NULL;
45
46 /**
47  * @def MAX_EVENT_COUNT
48  * @brief Maximum number of tries to get the event on BLE Shield address.
49  */
50 #define MAX_EVENT_COUNT 20
51
52 static bool g_serverRunning = false;
53 static char *g_coapBuffer = NULL;
54
55 /**
56  * @var g_receivedDataLen
57  * @brief Actual length of data received.
58  */
59 static uint32_t g_receivedDataLen = 0;
60
61 /**
62  * @var g_packetDataLen
63  * @brief Total Length of data that is being fragmented.
64  */
65 static uint32_t g_packetDataLen = 0;
66
67 void CACheckLEDataInternal()
68 {
69     CALEDoEvents();
70
71     if (CAIsLEDataAvailable())
72     {
73         // Allocate Memory for COAP Buffer and do ParseHeader
74         if (NULL == g_coapBuffer)
75         {
76             OIC_LOG(DEBUG, TAG, "IN");
77             char headerArray[CA_HEADER_LENGTH] = "";
78             while (CAIsLEDataAvailable() && g_receivedDataLen < CA_HEADER_LENGTH)
79             {
80                 headerArray[g_receivedDataLen++] = CALEReadData();
81             }
82
83             g_packetDataLen = CAParseHeader(headerArray);
84
85             if (g_packetDataLen > COAP_MAX_PDU_SIZE)
86             {
87                 OIC_LOG(ERROR, TAG, "len > pdu_size");
88                 return;
89             }
90
91             g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
92             if (NULL == g_coapBuffer)
93             {
94                 OIC_LOG(ERROR, TAG, "malloc");
95                 return;
96             }
97
98             OIC_LOG(DEBUG, TAG, "OUT");
99             g_receivedDataLen = 0;
100         }
101
102         OIC_LOG(DEBUG, TAG, "IN");
103         while (CAIsLEDataAvailable())
104         {
105             OIC_LOG(DEBUG, TAG, "In While loop");
106             g_coapBuffer[g_receivedDataLen++] = CALEReadData();
107             if (g_receivedDataLen == g_packetDataLen)
108             {
109                 OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
110                 g_coapBuffer[g_receivedDataLen] = '\0';
111                 if (g_receivedDataLen > 0)
112                 {
113                     OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_receivedDataLen);
114                     uint32_t sentLength = 0;
115                     // g_coapBuffer getting freed by CAMesssageHandler
116                     g_bleServerDataReceivedCallback("", "", g_coapBuffer,
117                                                     g_receivedDataLen, &sentLength);
118                 }
119
120                 g_receivedDataLen = 0;
121                 g_coapBuffer = NULL;
122                 break;
123             }
124         }
125         OIC_LOG(DEBUG, TAG, "OUT");
126     }
127     else
128     {
129         OIC_LOG(DEBUG, TAG, "NoData");
130     }
131     return;
132 }
133
134 CAResult_t CALEInitialize()
135 {
136     OIC_LOG(DEBUG, TAG, "IN");
137
138     // Set your BLE Shield name here, max. length 10
139     ble_set_name(__OIC_DEVICE_NAME__);
140
141     OIC_LOG(DEBUG, TAG, "LEName Set");
142
143     ble_begin();
144
145     OIC_LOG(DEBUG, TAG, "OUT");
146     return CA_STATUS_OK;
147 }
148
149 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
150 {
151     OIC_LOG(DEBUG, TAG, "IN");
152     OIC_LOG(DEBUG, TAG, "OUT");
153 }
154
155 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
156 {
157     OIC_LOG(DEBUG, TAG, "IN");
158     OIC_LOG(DEBUG, TAG, "OUT");
159 }
160
161 unsigned char CAIsLEDataAvailable()
162 {
163     return ble_available();
164 }
165
166 unsigned char CAIsLEConnected()
167 {
168     return ble_connected();
169 }
170 char CALEReadData()
171 {
172     return (char)ble_read();
173 }
174
175 CAResult_t CALEDoEvents()
176 {
177     ble_do_events();
178     return CA_STATUS_OK;
179 }
180
181 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *char_value,
182                                                    uint32_t valueLength)
183 {
184     // ble_write_bytes() api can send only max of 255 bytes at a time
185     // This function shall never be called to send more than 255 bytes by the fragmentation logic.
186     // Currently ble_write_bytes api returns void.
187     ble_write_bytes((unsigned char *)char_value, (unsigned char)valueLength);
188     return CA_STATUS_OK;
189 }
190
191 void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
192 {
193     OIC_LOG(DEBUG, TAG, "IN");
194     g_bleServerDataReceivedCallback = callback;
195     OIC_LOG(DEBUG, TAG, "OUT");
196 }
197
198 CAResult_t CAStartLEGattServer()
199 {
200     OIC_LOG(DEBUG, TAG, "IN");
201     CAResult_t result = CALEInitialize();
202     if (CA_STATUS_OK != result)
203     {
204         OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
205         return CA_STATUS_FAILED;
206     }
207     /**
208      * Below for loop is to process the BLE Events received from BLE Shield.
209      * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
210      */
211     for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
212     {
213         CACheckLEDataInternal();
214     }
215
216     g_serverRunning = true;
217     OIC_LOG(DEBUG, TAG, "OUT");
218     return CA_STATUS_OK;
219 }
220
221 CAResult_t CAStopLEGattServer()
222 {
223     OIC_LOG(DEBUG, TAG, "IN");
224     // There is no server running to stop.
225     OIC_LOG(DEBUG, TAG, "OUT");
226     return CA_STATUS_OK;
227 }
228
229 void CATerminateLEGattServer()
230 {
231     OIC_LOG(DEBUG, TAG, "IN");
232     ble_radio_reset();
233     g_serverRunning = false;
234     OIC_LOG(DEBUG, TAG, "OUT");
235     return;
236 }
237
238 void CACheckLEData()
239 {
240     if (false == g_serverRunning)
241     {
242         OIC_LOG(ERROR, TAG, "Server is not running");
243         return;
244     }
245     CACheckLEDataInternal();
246 }