206f46c7b2d9eef64bb347889c7991fe1b6e9917
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / calestate.c
1 /******************************************************************
2  *
3  * Copyright 2017 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 #include <stdio.h>
22 #include <string.h>
23 #include <jni.h>
24 #include <unistd.h>
25
26 #include "calestate.h"
27 #include "caleinterface.h"
28 #include "caadapterutils.h"
29 #include "caleutils.h"
30
31 #include "logger.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34 #include "cathreadpool.h" /* for thread pool */
35 #include "octhread.h"
36 #include "uarraylist.h"
37
38 #define TAG PCF("OIC_CA_LE_STATE")
39
40 CAResult_t CALEUpdateDeviceState(const char* address,
41                                  uint16_t state_type,
42                                  uint16_t target_state,
43                                  u_arraylist_t *deviceList,
44                                  oc_mutex deviceListMutex)
45 {
46     VERIFY_NON_NULL(address, TAG, "address is null");
47     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
48
49     oc_mutex_lock(deviceListMutex);
50
51     if (CALEIsDeviceInList(address, deviceList))
52     {
53         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
54         if(!curState)
55         {
56             OIC_LOG(ERROR, TAG, "curState is null");
57             oc_mutex_unlock(deviceListMutex);
58             return CA_STATUS_FAILED;
59         }
60
61         switch(state_type)
62         {
63             case CA_LE_CONNECTION_STATE:
64                 curState->connectedState = target_state;
65                 break;
66             case CA_LE_SEND_STATE:
67                 curState->sendState = target_state;
68                 break;
69             default:
70                 break;
71         }
72         OIC_LOG_V(INFO, TAG, "update state - addr: %s, conn: %d, send: %d, ACFlag: %d, mtu: %d",
73                   curState->address, curState->connectedState, curState->sendState,
74                   curState->autoConnectFlag, curState->mtuSize);
75     }
76     else /** state is added newly **/
77     {
78         if (strlen(address) > CA_MACADDR_SIZE)
79         {
80             OIC_LOG(ERROR, TAG, "address is not proper");
81             oc_mutex_unlock(deviceListMutex);
82             return CA_STATUS_INVALID_PARAM;
83         }
84
85         CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
86         if (!newstate)
87         {
88             OIC_LOG(ERROR, TAG, "out of memory");
89             oc_mutex_unlock(deviceListMutex);
90             return CA_MEMORY_ALLOC_FAILED;
91         }
92
93         OICStrcpy(newstate->address, sizeof(newstate->address), address);
94         newstate->mtuSize = CA_DEFAULT_BLE_MTU_SIZE;
95         switch(state_type)
96         {
97             case CA_LE_CONNECTION_STATE:
98                 newstate->connectedState = target_state;
99                 newstate->sendState = STATE_SEND_NONE;
100                 break;
101             case CA_LE_SEND_STATE:
102                 newstate->connectedState = STATE_DISCONNECTED;
103                 newstate->sendState = target_state;
104                 break;
105             default:
106                 break;
107         }
108         OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
109                   "conn : %d, send : %d, ACFlag : %d",
110                   newstate->address, newstate->connectedState, newstate->sendState,
111                   newstate->autoConnectFlag);
112         u_arraylist_add(deviceList, newstate); // update new state
113     }
114     oc_mutex_unlock(deviceListMutex);
115
116     return CA_STATUS_OK;
117 }
118
119 bool CALEIsDeviceInList(const char* remoteAddress,
120                         u_arraylist_t *deviceList)
121 {
122     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
123     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", false);
124
125     uint32_t length = u_arraylist_length(deviceList);
126     for (uint32_t index = 0; index < length; index++)
127     {
128         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
129         if (!state)
130         {
131             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
132             return false;
133         }
134
135         if (!strcmp(remoteAddress, state->address))
136         {
137             OIC_LOG(DEBUG, TAG, "the device is already set");
138             return true;
139         }
140         else
141         {
142             continue;
143         }
144     }
145
146     OIC_LOG(DEBUG, TAG, "there are no the device in list.");
147     return false;
148 }
149
150 CAResult_t CALERemoveAllDeviceState(u_arraylist_t *deviceList,
151                                     oc_mutex deviceListMutex)
152 {
153     OIC_LOG(DEBUG, TAG, "CALERemoveAllDeviceState");
154     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
155
156     oc_mutex_lock(deviceListMutex);
157     uint32_t length = u_arraylist_length(deviceList);
158     for (uint32_t index = 0; index < length; index++)
159     {
160         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
161         if (!state)
162         {
163             OIC_LOG(ERROR, TAG, "jarrayObj is null");
164             continue;
165         }
166         OICFree(state);
167     }
168
169     OICFree(deviceList);
170     deviceList = NULL;
171     oc_mutex_unlock(deviceListMutex);
172
173     return CA_STATUS_OK;
174 }
175
176 CAResult_t CALEResetDeviceStateForAll(u_arraylist_t *deviceList,
177                                       oc_mutex deviceListMutex)
178 {
179     OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
180     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
181
182     oc_mutex_lock(deviceListMutex);
183     size_t length = u_arraylist_length(deviceList);
184     for (size_t index = 0; index < length; index++)
185     {
186         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
187         if (!state)
188         {
189             OIC_LOG(ERROR, TAG, "jarrayObj is null");
190             continue;
191         }
192
193         // autoConnectFlag value will be not changed,
194         // since it has reset only termination case.
195         state->connectedState = STATE_DISCONNECTED;
196         state->sendState = STATE_SEND_NONE;
197     }
198     oc_mutex_unlock(deviceListMutex);
199
200     return CA_STATUS_OK;
201 }
202
203 CAResult_t CALERemoveDeviceState(const char* remoteAddress,
204                                  u_arraylist_t *deviceList)
205 {
206     OIC_LOG(DEBUG, TAG, "CALERemoveDeviceState");
207     VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
208     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
209
210     uint32_t length = u_arraylist_length(deviceList);
211     for (uint32_t index = 0; index < length; index++)
212     {
213         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
214         if (!state)
215         {
216             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
217             continue;
218         }
219
220         if (!strcmp(state->address, remoteAddress))
221         {
222             OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
223
224             CALEState_t* targetState  = (CALEState_t*)u_arraylist_remove(deviceList,
225                                                                          index);
226             if (NULL == targetState)
227             {
228                 OIC_LOG(ERROR, TAG, "List removal failed.");
229                 return CA_STATUS_FAILED;
230             }
231
232             OICFree(targetState);
233             return CA_STATUS_OK;
234         }
235     }
236     return CA_STATUS_OK;
237 }
238
239 CALEState_t* CALEGetStateInfo(const char* remoteAddress,
240                               u_arraylist_t *deviceList)
241 {
242     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
243     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", NULL);
244
245     uint32_t length = u_arraylist_length(deviceList);
246     OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
247     OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
248
249     for (uint32_t index = 0; index < length; index++)
250     {
251         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
252         if (!state)
253         {
254             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
255             continue;
256         }
257
258         OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
259
260         if (!strcmp(state->address, remoteAddress))
261         {
262             OIC_LOG(DEBUG, TAG, "found state");
263             return state;
264         }
265     }
266
267     OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
268     return NULL;
269 }
270
271 bool CALEIsValidState(const char* remoteAddress,
272                       uint16_t state_type,
273                       uint16_t target_state,
274                       u_arraylist_t *deviceList,
275                       oc_mutex deviceListMutex)
276 {
277     OIC_LOG_V(DEBUG, TAG, "CALEIsValidState : type[%d], target state[%d]",
278               state_type, target_state);
279     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
280     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", false);
281
282     oc_mutex_lock(deviceListMutex);
283     CALEState_t* state = CALEGetStateInfo(remoteAddress, deviceList);
284     if (NULL == state)
285     {
286         OIC_LOG(DEBUG, TAG, "state is not updated yet");
287         oc_mutex_unlock(deviceListMutex);
288         return false;
289     }
290
291     uint16_t curValue = 0;
292     switch(state_type)
293     {
294         case CA_LE_CONNECTION_STATE:
295             curValue = state->connectedState;
296             break;
297         case CA_LE_SEND_STATE:
298             curValue = state->sendState;
299             break;
300         default:
301             break;
302     }
303
304     if (target_state == curValue)
305     {
306         oc_mutex_unlock(deviceListMutex);
307         return true;
308     }
309     else
310     {
311         oc_mutex_unlock(deviceListMutex);
312         return false;
313     }
314
315     oc_mutex_unlock(deviceListMutex);
316     return false;
317 }
318
319
320 CAResult_t CALESetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag,
321                               u_arraylist_t *deviceList, oc_mutex deviceListMutex)
322 {
323     OIC_LOG(DEBUG, TAG, "IN - CALESetFlagToState");
324     VERIFY_NON_NULL(env, TAG, "env");
325     VERIFY_NON_NULL(jni_address, TAG, "jni_address");
326     VERIFY_NON_NULL(deviceList, TAG, "deviceList");
327
328     oc_mutex_lock(deviceListMutex);
329
330     char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
331     if (!address)
332     {
333         OIC_LOG(ERROR, TAG, "address is not available");
334         CACheckJNIException(env);
335         return CA_STATUS_FAILED;
336     }
337
338     if (CALEIsDeviceInList(address, deviceList))
339     {
340         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
341         if(!curState)
342         {
343             OIC_LOG(ERROR, TAG, "curState is null");
344             (*env)->ReleaseStringUTFChars(env, jni_address, address);
345             oc_mutex_unlock(deviceListMutex);
346             return CA_STATUS_FAILED;
347         }
348         OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
349
350         switch(state_idx)
351         {
352             case CA_LE_AUTO_CONNECT_FLAG:
353                 curState->autoConnectFlag = flag;
354                 break;
355             case CA_LE_DESCRIPTOR_FOUND:
356                 curState->isDescriptorFound = flag;
357                 break;
358             default:
359                 break;
360         }
361     }
362
363     (*env)->ReleaseStringUTFChars(env, jni_address, address);
364     oc_mutex_unlock(deviceListMutex);
365     OIC_LOG(DEBUG, TAG, "OUT - CALESetFlagToState");
366     return CA_STATUS_OK;
367 }
368
369 jboolean CALEGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx,
370                               u_arraylist_t *deviceList, oc_mutex deviceListMutex)
371 {
372     OIC_LOG(DEBUG, TAG, "IN - CALEGetFlagFromState");
373     VERIFY_NON_NULL_RET(env, TAG, "env", false);
374     VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
375     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList", false);
376
377     oc_mutex_lock(deviceListMutex);
378
379     char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
380     if (!address)
381     {
382         OIC_LOG(ERROR, TAG, "address is not available");
383         CACheckJNIException(env);
384         oc_mutex_unlock(deviceListMutex);
385         return JNI_FALSE;
386     }
387
388     CALEState_t* curState = CALEGetStateInfo(address, deviceList);
389     (*env)->ReleaseStringUTFChars(env, jni_address, address);
390     if(!curState)
391     {
392         OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
393         oc_mutex_unlock(deviceListMutex);
394         return JNI_FALSE;
395     }
396
397     jboolean ret = JNI_FALSE;
398     switch(state_idx)
399     {
400         case CA_LE_AUTO_CONNECT_FLAG:
401             ret = curState->autoConnectFlag;
402             break;
403         case CA_LE_DESCRIPTOR_FOUND:
404             ret = curState->isDescriptorFound;
405             break;
406         default:
407             break;
408     }
409     oc_mutex_unlock(deviceListMutex);
410
411     OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
412     OIC_LOG(DEBUG, TAG, "OUT - CALEGetFlagFromState");
413     return ret;
414 }
415
416 CAResult_t CALESetMtuSize(const char* address, uint16_t mtuSize,
417                           u_arraylist_t *deviceList, oc_mutex deviceListMutex)
418
419 {
420     VERIFY_NON_NULL(address, TAG, "address is null");
421     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
422
423     oc_mutex_lock(deviceListMutex);
424     if (CALEIsDeviceInList(address, deviceList))
425     {
426         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
427         if(!curState)
428         {
429             OIC_LOG(ERROR, TAG, "curState is null");
430             oc_mutex_unlock(deviceListMutex);
431             return CA_STATUS_FAILED;
432         }
433
434         curState->mtuSize = mtuSize;
435         OIC_LOG_V(INFO, TAG, "update state - addr: %s, mtu: %d",
436                   curState->address, curState->mtuSize);
437     }
438     else
439     {
440         OIC_LOG(ERROR, TAG, "there is no state info in the list");
441     }
442     oc_mutex_unlock(deviceListMutex);
443     return CA_STATUS_OK;
444 }
445
446 uint16_t CALEGetMtuSize(const char* address, u_arraylist_t *deviceList, oc_mutex deviceListMutex)
447 {
448     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
449     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", CA_DEFAULT_BLE_MTU_SIZE);
450
451     oc_mutex_lock(deviceListMutex);
452     if (CALEIsDeviceInList(address, deviceList))
453     {
454         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
455         if(!curState)
456         {
457             OIC_LOG(ERROR, TAG, "curState is null");
458             oc_mutex_unlock(deviceListMutex);
459             return CA_DEFAULT_BLE_MTU_SIZE;
460         }
461
462         OIC_LOG_V(INFO, TAG, "state - addr: %s, mtu: %d",
463                   curState->address, curState->mtuSize);
464         oc_mutex_unlock(deviceListMutex);
465         return curState->mtuSize;
466     }
467
468     oc_mutex_unlock(deviceListMutex);
469     return CA_DEFAULT_BLE_MTU_SIZE;
470 }