Update snapshot(2018-01-04)
[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(DEBUG, 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(DEBUG, 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 (!strcasecmp(remoteAddress, state->address))
136         {
137             return true;
138         }
139         else
140         {
141             continue;
142         }
143     }
144
145     OIC_LOG(INFO, TAG, "there are no the device in list.");
146     return false;
147 }
148
149 CAResult_t CALERemoveAllDeviceState(u_arraylist_t *deviceList,
150                                     oc_mutex deviceListMutex)
151 {
152     OIC_LOG(DEBUG, TAG, "CALERemoveAllDeviceState");
153     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
154
155     oc_mutex_lock(deviceListMutex);
156     uint32_t length = u_arraylist_length(deviceList);
157     for (uint32_t index = 0; index < length; index++)
158     {
159         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
160         if (!state)
161         {
162             OIC_LOG(ERROR, TAG, "jarrayObj is null");
163             continue;
164         }
165         OICFree(state);
166     }
167
168     oc_mutex_unlock(deviceListMutex);
169
170     return CA_STATUS_OK;
171 }
172
173 CAResult_t CALEResetDeviceStateForAll(u_arraylist_t *deviceList,
174                                       oc_mutex deviceListMutex)
175 {
176     OIC_LOG(DEBUG, TAG, "CALEResetDeviceStateForAll");
177     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
178
179     oc_mutex_lock(deviceListMutex);
180     size_t length = u_arraylist_length(deviceList);
181     for (size_t index = 0; index < length; index++)
182     {
183         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
184         if (!state)
185         {
186             OIC_LOG(ERROR, TAG, "jarrayObj is null");
187             continue;
188         }
189
190         // autoConnectFlag value will be not changed,
191         // since it has reset only termination case.
192         state->connectedState = STATE_DISCONNECTED;
193         state->sendState = STATE_SEND_NONE;
194     }
195     oc_mutex_unlock(deviceListMutex);
196
197     return CA_STATUS_OK;
198 }
199
200 CAResult_t CALERemoveDeviceState(const char* remoteAddress,
201                                  u_arraylist_t *deviceList)
202 {
203     OIC_LOG(DEBUG, TAG, "CALERemoveDeviceState");
204     VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
205     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
206
207     uint32_t length = u_arraylist_length(deviceList);
208     for (uint32_t index = 0; index < length; index++)
209     {
210         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
211         if (!state)
212         {
213             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
214             continue;
215         }
216
217         if (!strcasecmp(state->address, remoteAddress))
218         {
219             OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
220
221             CALEState_t* targetState  = (CALEState_t*)u_arraylist_remove(deviceList,
222                                                                          index);
223             if (NULL == targetState)
224             {
225                 OIC_LOG(ERROR, TAG, "List removal failed.");
226                 return CA_STATUS_FAILED;
227             }
228
229             OICFree(targetState);
230             return CA_STATUS_OK;
231         }
232     }
233     return CA_STATUS_OK;
234 }
235
236 CALEState_t* CALEGetStateInfo(const char* remoteAddress,
237                               u_arraylist_t *deviceList)
238 {
239     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
240     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", NULL);
241
242     uint32_t length = u_arraylist_length(deviceList);
243
244     for (uint32_t index = 0; index < length; index++)
245     {
246         CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
247         if (!state)
248         {
249             OIC_LOG(ERROR, TAG, "CALEState_t object is null");
250             continue;
251         }
252
253         if (!strcasecmp(state->address, remoteAddress))
254         {
255             return state;
256         }
257         OIC_LOG_V(DEBUG, TAG, "state addr[%s, %d]", state->address, index);
258     }
259
260     OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress, length);
261     return NULL;
262 }
263
264 bool CALEIsValidState(const char* remoteAddress,
265                       uint16_t state_type,
266                       uint16_t target_state,
267                       u_arraylist_t *deviceList,
268                       oc_mutex deviceListMutex)
269 {
270     OIC_LOG_V(DEBUG, TAG, "CALEIsValidState : type[%d], target state[%d]",
271               state_type, target_state);
272     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
273     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", false);
274
275     oc_mutex_lock(deviceListMutex);
276     CALEState_t* state = CALEGetStateInfo(remoteAddress, deviceList);
277     if (NULL == state)
278     {
279         OIC_LOG(DEBUG, TAG, "state is not updated yet");
280         oc_mutex_unlock(deviceListMutex);
281         return false;
282     }
283
284     uint16_t curValue = 0;
285     switch(state_type)
286     {
287         case CA_LE_CONNECTION_STATE:
288             curValue = state->connectedState;
289             break;
290         case CA_LE_SEND_STATE:
291             curValue = state->sendState;
292             break;
293         default:
294             break;
295     }
296
297     if (target_state == curValue)
298     {
299         oc_mutex_unlock(deviceListMutex);
300         return true;
301     }
302     else
303     {
304         oc_mutex_unlock(deviceListMutex);
305         return false;
306     }
307
308     oc_mutex_unlock(deviceListMutex);
309     return false;
310 }
311
312
313 CAResult_t CALESetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag,
314                               u_arraylist_t *deviceList, oc_mutex deviceListMutex)
315 {
316     OIC_LOG(DEBUG, TAG, "IN - CALESetFlagToState");
317     VERIFY_NON_NULL(env, TAG, "env");
318     VERIFY_NON_NULL(jni_address, TAG, "jni_address");
319     VERIFY_NON_NULL(deviceList, TAG, "deviceList");
320
321     oc_mutex_lock(deviceListMutex);
322
323     char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
324     if (!address)
325     {
326         OIC_LOG(ERROR, TAG, "address is not available");
327         CACheckJNIException(env);
328         return CA_STATUS_FAILED;
329     }
330
331     if (CALEIsDeviceInList(address, deviceList))
332     {
333         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
334         if(!curState)
335         {
336             OIC_LOG(ERROR, TAG, "curState is null");
337             (*env)->ReleaseStringUTFChars(env, jni_address, address);
338             oc_mutex_unlock(deviceListMutex);
339             return CA_STATUS_FAILED;
340         }
341         OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
342
343         switch(state_idx)
344         {
345             case CA_LE_AUTO_CONNECT_FLAG:
346                 curState->autoConnectFlag = flag;
347                 break;
348             case CA_LE_DESCRIPTOR_FOUND:
349                 curState->isDescriptorFound = flag;
350                 break;
351             default:
352                 break;
353         }
354     }
355
356     (*env)->ReleaseStringUTFChars(env, jni_address, address);
357     oc_mutex_unlock(deviceListMutex);
358     OIC_LOG(DEBUG, TAG, "OUT - CALESetFlagToState");
359     return CA_STATUS_OK;
360 }
361
362 jboolean CALEGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx,
363                               u_arraylist_t *deviceList, oc_mutex deviceListMutex)
364 {
365     OIC_LOG(DEBUG, TAG, "IN - CALEGetFlagFromState");
366     VERIFY_NON_NULL_RET(env, TAG, "env", false);
367     VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
368     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList", false);
369
370     oc_mutex_lock(deviceListMutex);
371
372     char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
373     if (!address)
374     {
375         OIC_LOG(ERROR, TAG, "address is not available");
376         CACheckJNIException(env);
377         oc_mutex_unlock(deviceListMutex);
378         return JNI_FALSE;
379     }
380
381     CALEState_t* curState = CALEGetStateInfo(address, deviceList);
382     (*env)->ReleaseStringUTFChars(env, jni_address, address);
383     if(!curState)
384     {
385         OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
386         oc_mutex_unlock(deviceListMutex);
387         return JNI_FALSE;
388     }
389
390     jboolean ret = JNI_FALSE;
391     switch(state_idx)
392     {
393         case CA_LE_AUTO_CONNECT_FLAG:
394             ret = curState->autoConnectFlag;
395             break;
396         case CA_LE_DESCRIPTOR_FOUND:
397             ret = curState->isDescriptorFound;
398             break;
399         default:
400             break;
401     }
402     oc_mutex_unlock(deviceListMutex);
403
404     OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
405     OIC_LOG(DEBUG, TAG, "OUT - CALEGetFlagFromState");
406     return ret;
407 }
408
409 CAResult_t CALESetMtuSize(const char* address, uint16_t mtuSize,
410                           u_arraylist_t *deviceList, oc_mutex deviceListMutex)
411
412 {
413     VERIFY_NON_NULL(address, TAG, "address is null");
414     VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
415
416     oc_mutex_lock(deviceListMutex);
417     if (CALEIsDeviceInList(address, deviceList))
418     {
419         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
420         if(!curState)
421         {
422             OIC_LOG(ERROR, TAG, "curState is null");
423             oc_mutex_unlock(deviceListMutex);
424             return CA_STATUS_FAILED;
425         }
426
427         curState->mtuSize = mtuSize;
428         OIC_LOG_V(DEBUG, TAG, "update state - addr: %s, mtu: %d",
429                   curState->address, curState->mtuSize);
430     }
431     else
432     {
433         OIC_LOG(ERROR, TAG, "there is no state info in the list");
434     }
435     oc_mutex_unlock(deviceListMutex);
436     return CA_STATUS_OK;
437 }
438
439 uint16_t CALEGetMtuSize(const char* address, u_arraylist_t *deviceList, oc_mutex deviceListMutex)
440 {
441     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
442     VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", CA_DEFAULT_BLE_MTU_SIZE);
443
444     oc_mutex_lock(deviceListMutex);
445     if (CALEIsDeviceInList(address, deviceList))
446     {
447         CALEState_t* curState = CALEGetStateInfo(address, deviceList);
448         if(!curState)
449         {
450             OIC_LOG(ERROR, TAG, "curState is null");
451             oc_mutex_unlock(deviceListMutex);
452             return CA_DEFAULT_BLE_MTU_SIZE;
453         }
454
455         OIC_LOG_V(DEBUG, TAG, "state - addr: %s, mtu: %d",
456                   curState->address, curState->mtuSize);
457         oc_mutex_unlock(deviceListMutex);
458         return curState->mtuSize;
459     }
460
461     oc_mutex_unlock(deviceListMutex);
462     return CA_DEFAULT_BLE_MTU_SIZE;
463 }