replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / util / src / camanager / bt_le_manager / ios / caleautoconnector.m
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 "cacommon.h"
22 #include "caleclient.h"
23 #include "camanagerleutil.h"
24 #include "camanagerdevice.h"
25 #include "caleautoconnector.h"
26 #include "cacommonutil.h"
27 #include "logger.h"
28 #include "octhread.h"
29
30 #define TAG "OIC_CA_LE_AUTO_CONN"
31
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;
35
36 static oc_mutex g_connectRetryMutex = NULL;
37 static oc_cond g_connectRetryCond = NULL;
38
39 static oc_mutex g_recoveryMutex = NULL;
40 static oc_cond g_recoveryCond = NULL;
41
42 CAResult_t CAManagerInitLEAutoConnection()
43 {
44     if (NULL == g_connectRetryMutex)
45     {
46         g_connectRetryMutex = oc_mutex_new();
47         if (NULL == g_connectRetryMutex)
48         {
49             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
50             return CA_STATUS_FAILED;
51         }
52     }
53
54     if (NULL == g_connectRetryCond)
55     {
56         g_connectRetryCond = oc_cond_new();
57         if (NULL == g_connectRetryCond)
58         {
59             OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
60             return CA_STATUS_FAILED;
61         }
62     }
63
64     if (NULL == g_recoveryMutex)
65     {
66         g_recoveryMutex = oc_mutex_new();
67         if (NULL == g_recoveryMutex)
68         {
69             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
70             return CA_STATUS_FAILED;
71         }
72     }
73
74     if (NULL == g_recoveryCond)
75     {
76         g_recoveryCond = oc_cond_new();
77         if (NULL == g_recoveryCond)
78         {
79             OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
80             return CA_STATUS_FAILED;
81         }
82     }
83
84     return CA_STATUS_OK;
85 }
86
87 void CAManagerTerminateLEAutoConnection()
88 {
89     if (g_connectRetryCond)
90     {
91         oc_cond_signal(g_connectRetryCond);
92         oc_cond_free(g_connectRetryCond);
93         g_connectRetryCond = NULL;
94     }
95
96     if (g_connectRetryMutex)
97     {
98         oc_mutex_free(g_connectRetryMutex);
99         g_connectRetryMutex = NULL;
100     }
101
102     if (g_recoveryCond)
103     {
104         oc_cond_signal(g_recoveryCond);
105         oc_cond_free(g_recoveryCond);
106         g_recoveryCond = NULL;
107     }
108
109     if (g_recoveryMutex)
110     {
111         oc_mutex_free(g_recoveryMutex);
112         g_recoveryMutex = NULL;
113     }
114 }
115
116 CAResult_t CAManagerStartAutoConnection(const char *remote_le_address)
117 {
118     VERIFY_NON_NULL(remote_le_address, TAG, "remote_le_address is null");
119
120     OIC_LOG(DEBUG, TAG, "IN - CAManagerStartAutoConnection");
121
122     if (true == CAManagerGetAutoConnectionFlag(remote_le_address))
123     {
124         OIC_LOG(INFO, TAG, "auto connecting.");
125         return CA_STATUS_FAILED;
126     }
127
128     oc_mutex_lock(g_connectRetryMutex);
129
130     CBPeripheral *peripheral = CAManagerGetValueConnectedDeviceAddress(remote_le_address);
131     if (!peripheral) {
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;
135     }
136
137     for (size_t retry_cnt = 0 ; retry_cnt < MAX_RETRY_COUNT ; retry_cnt++)
138     {
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);
142
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;
147         }
148
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)
152         {
153             OIC_LOG(INFO, TAG, "request to connect gatt is done");
154             //CALEClientSetAutoConnectFlag(remote_le_address, false);
155             oc_mutex_unlock(g_connectRetryMutex);
156             return CA_STATUS_OK;
157         }
158         // time out. retry connection
159         CALEClientConnectCancel(peripheral);
160     }
161     oc_mutex_unlock(g_connectRetryMutex);
162     OIC_LOG(DEBUG, TAG, "OUT - CAManagerStartAutoConnection");
163     return CA_STATUS_OK;
164 }
165
166 CAResult_t CAManagerConnectGatt(const char *remote_le_address)
167 {
168     VERIFY_NON_NULL_RET(remote_le_address, TAG, "remote_le_address", NULL);
169
170     OIC_LOG(DEBUG, TAG, "IN - CAManagerConnectGatt");
171
172     CBPeripheral *peripheral = CAManagerGetValueConnectedDeviceAddress(remote_le_address);
173
174     if (!peripheral) {
175         OIC_LOG_V(ERROR, TAG, "address : %s is not valid one", remote_le_address);
176         return CA_STATUS_FAILED;
177     }
178
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)
183     {
184         OIC_LOG(INFO, TAG, "re-connection will be started");
185         return CA_STATUS_FAILED;
186     }
187
188     // set flag auto connection is requested.
189     CAManagerSetAutoConnectionFlag(remote_le_address, true);
190
191     OIC_LOG(DEBUG, TAG, "OUT - CAManagerConnectGatt");
192     return CA_STATUS_OK;
193 }
194
195 CAResult_t CAManagerProcessRecovery(uint16_t adapter_state)
196 {
197     OIC_LOG(DEBUG, TAG, "IN - CAManagerProcessRecovery");
198
199     oc_mutex_lock(g_recoveryMutex);
200     CAResult_t res = CA_STATUS_OK;
201
202     oc_mutex_unlock(g_recoveryMutex);
203     OIC_LOG(DEBUG, TAG, "OUT - CAManagerProcessRecovery");
204
205     return res;
206 }
207
208 void CAManagerSignalToRetryCond(const char* address)
209 {
210     OIC_LOG(DEBUG, TAG, "CAManagerSignalToRetryCond");
211     if(true == CALEClientGetAutoConnectFlag(address))
212     {
213         if(g_connectRetryCond)
214         {
215             OIC_LOG(DEBUG, TAG, "signaling!");
216             oc_mutex_lock(g_connectRetryMutex);
217             oc_cond_signal(g_connectRetryCond);
218             oc_mutex_unlock(g_connectRetryMutex);
219
220         }
221     }
222 }