1 /* ****************************************************************
3 * Copyright 2017 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
22 #include "caleclient.h"
23 #include "camanagerleutil.h"
24 #include "camanagerdevice.h"
25 #include "caleautoconnector.h"
26 #include "cacommonutil.h"
30 #define TAG "OIC_CA_LE_AUTO_CONN"
32 static const size_t MAX_RETRY_COUNT = 1;
33 static const size_t TIMEOUT = 30000000; //30sec
34 static const size_t WAITING_TIME = 500000;
36 static oc_mutex g_connectRetryMutex = NULL;
37 static oc_cond g_connectRetryCond = NULL;
39 static oc_mutex g_recoveryMutex = NULL;
40 static oc_cond g_recoveryCond = NULL;
42 CAResult_t CAManagerInitLEAutoConnection()
44 if (NULL == g_connectRetryMutex)
46 g_connectRetryMutex = oc_mutex_new();
47 if (NULL == g_connectRetryMutex)
49 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
50 return CA_STATUS_FAILED;
54 if (NULL == g_connectRetryCond)
56 g_connectRetryCond = oc_cond_new();
57 if (NULL == g_connectRetryCond)
59 OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
60 return CA_STATUS_FAILED;
64 if (NULL == g_recoveryMutex)
66 g_recoveryMutex = oc_mutex_new();
67 if (NULL == g_recoveryMutex)
69 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
70 return CA_STATUS_FAILED;
74 if (NULL == g_recoveryCond)
76 g_recoveryCond = oc_cond_new();
77 if (NULL == g_recoveryCond)
79 OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
80 return CA_STATUS_FAILED;
87 void CAManagerTerminateLEAutoConnection()
89 if (g_connectRetryCond)
91 oc_cond_signal(g_connectRetryCond);
92 oc_cond_free(g_connectRetryCond);
93 g_connectRetryCond = NULL;
96 if (g_connectRetryMutex)
98 oc_mutex_free(g_connectRetryMutex);
99 g_connectRetryMutex = NULL;
104 oc_cond_signal(g_recoveryCond);
105 oc_cond_free(g_recoveryCond);
106 g_recoveryCond = NULL;
111 oc_mutex_free(g_recoveryMutex);
112 g_recoveryMutex = NULL;
116 CAResult_t CAManagerStartAutoConnection(const char *remote_le_address)
118 VERIFY_NON_NULL(remote_le_address, TAG, "remote_le_address is null");
120 OIC_LOG(DEBUG, TAG, "IN - CAManagerStartAutoConnection");
122 if (true == CAManagerGetAutoConnectionFlag(remote_le_address))
124 OIC_LOG(INFO, TAG, "auto connecting.");
125 return CA_STATUS_FAILED;
128 oc_mutex_lock(g_connectRetryMutex);
130 CBPeripheral *peripheral = CAManagerGetValueConnectedDeviceAddress(remote_le_address);
132 OIC_LOG_V(ERROR, TAG, "address : %s is not valid one", remote_le_address);
133 oc_mutex_unlock(g_connectRetryMutex);
134 return CA_STATUS_FAILED;
137 for (size_t retry_cnt = 0 ; retry_cnt < MAX_RETRY_COUNT ; retry_cnt++)
139 // there is retry logic 5 times when connectGatt call has failed
140 // because BT adapter might be not ready yet.
141 CAResult_t ret = CAManagerConnectGatt(remote_le_address);
143 if (ret != CA_STATUS_OK) {
144 OIC_LOG_V(ERROR, TAG, "CAManagerConnectGatt fail!!");
145 oc_mutex_unlock(g_connectRetryMutex);
146 return CA_STATUS_FAILED;
149 OIC_LOG_V(INFO, TAG, "retry will be started at least %d times after delay 30sec",
150 MAX_RETRY_COUNT - retry_cnt - 1);
151 if (oc_cond_wait_for(g_connectRetryCond, g_connectRetryMutex, TIMEOUT) == 0)
153 OIC_LOG(INFO, TAG, "request to connect gatt is done");
154 //CALEClientSetAutoConnectFlag(remote_le_address, false);
155 oc_mutex_unlock(g_connectRetryMutex);
158 // time out. retry connection
159 CALEClientConnectCancel(peripheral);
161 oc_mutex_unlock(g_connectRetryMutex);
162 OIC_LOG(DEBUG, TAG, "OUT - CAManagerStartAutoConnection");
166 CAResult_t CAManagerConnectGatt(const char *remote_le_address)
168 VERIFY_NON_NULL_RET(remote_le_address, TAG, "remote_le_address", NULL);
170 OIC_LOG(DEBUG, TAG, "IN - CAManagerConnectGatt");
172 CBPeripheral *peripheral = CAManagerGetValueConnectedDeviceAddress(remote_le_address);
175 OIC_LOG_V(ERROR, TAG, "address : %s is not valid one", remote_le_address);
176 return CA_STATUS_FAILED;
179 // request to connection with AutoConnection Flag
180 OIC_LOG(INFO, TAG, "request to gatt connection for auto connection");
181 CAResult_t res = CALEClientConnect(peripheral, true);
182 if (CA_STATUS_FAILED == res)
184 OIC_LOG(INFO, TAG, "re-connection will be started");
185 return CA_STATUS_FAILED;
188 // set flag auto connection is requested.
189 CAManagerSetAutoConnectionFlag(remote_le_address, true);
191 OIC_LOG(DEBUG, TAG, "OUT - CAManagerConnectGatt");
195 CAResult_t CAManagerProcessRecovery(uint16_t adapter_state)
197 OIC_LOG(DEBUG, TAG, "IN - CAManagerProcessRecovery");
199 oc_mutex_lock(g_recoveryMutex);
200 CAResult_t res = CA_STATUS_OK;
202 oc_mutex_unlock(g_recoveryMutex);
203 OIC_LOG(DEBUG, TAG, "OUT - CAManagerProcessRecovery");
208 void CAManagerSignalToRetryCond(const char* address)
210 OIC_LOG(DEBUG, TAG, "CAManagerSignalToRetryCond");
211 if(true == CALEClientGetAutoConnectFlag(address))
213 if(g_connectRetryCond)
215 OIC_LOG(DEBUG, TAG, "signaling!");
216 oc_mutex_lock(g_connectRetryMutex);
217 oc_cond_signal(g_connectRetryCond);
218 oc_mutex_unlock(g_connectRetryMutex);