keepalive for coap over tcp
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / caconnectivitymanager.c
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 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25
26 #include "ocrandom.h"
27 #include "cainterface.h"
28 #include "caremotehandler.h"
29 #include "camessagehandler.h"
30 #include "caprotocolmessage.h"
31 #include "canetworkconfigurator.h"
32 #include "cainterfacecontroller.h"
33 #include "logger.h"
34 #ifdef __WITH_DTLS__
35 #include "caadapternetdtls.h"
36 #endif
37
38 #ifdef TCP_ADAPTER
39 #include "catcpadapter.h"
40 #endif
41
42 CAGlobals_t caglobals = { .clientFlags = 0,
43                           .serverFlags = 0, };
44
45 #define TAG "OIC_CA_CONN_MGR"
46
47 static bool g_isInitialized = false;
48
49 #ifdef __WITH_DTLS__
50 // CAAdapterNetDTLS will register the callback.
51 // Taking callback all the way through adapters not the right approach, hence calling here.
52 extern void CADTLSSetCredentialsCallback(CAGetDTLSPskCredentialsHandler credCallback);
53 #endif
54
55 #ifdef __WITH_X509__
56 // CAAdapterNetDTLS will register the callback.
57 // Taking callback all the way through adapters not the right approach, hence calling here.
58 extern void CADTLSSetX509CredentialsCallback(CAGetDTLSX509CredentialsHandler credCallback);
59 extern void CADTLSSetCrlCallback(CAGetDTLSCrlHandler crlCallback);
60 #endif
61
62 CAResult_t CAInitialize()
63 {
64     OIC_LOG(DEBUG, TAG, "CAInitialize");
65
66     if (!g_isInitialized)
67     {
68         if (0 != OCSeedRandom())
69         {
70             OIC_LOG(ERROR, TAG, "Seed Random Failed");
71         }
72
73         CAResult_t res = CAInitializeMessageHandler();
74         if (res != CA_STATUS_OK)
75         {
76             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
77             return res;
78         }
79         g_isInitialized = true;
80     }
81
82     return CA_STATUS_OK;
83 }
84
85 void CATerminate()
86 {
87     OIC_LOG(DEBUG, TAG, "CATerminate");
88
89     if (g_isInitialized)
90     {
91         CATerminateMessageHandler();
92         CATerminateNetworkType();
93
94         g_isInitialized = false;
95     }
96 }
97
98 CAResult_t CAStartListeningServer()
99 {
100     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
101
102     if(!g_isInitialized)
103     {
104         return CA_STATUS_NOT_INITIALIZED;
105     }
106
107     return CAStartListeningServerAdapters();
108 }
109
110 CAResult_t CAStopListeningServer()
111 {
112     OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
113
114     if(!g_isInitialized)
115     {
116         return CA_STATUS_NOT_INITIALIZED;
117     }
118
119     return CAStopListeningServerAdapters();
120 }
121
122 CAResult_t CAStartDiscoveryServer()
123 {
124     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
125
126     if(!g_isInitialized)
127     {
128         return CA_STATUS_NOT_INITIALIZED;
129     }
130
131     return CAStartDiscoveryServerAdapters();
132 }
133
134 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
135                        CAErrorCallback ErrorHandler)
136 {
137     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
138
139     if(!g_isInitialized)
140     {
141         OIC_LOG(DEBUG, TAG, "CA is not initialized");
142         return;
143     }
144
145     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
146 }
147
148 #ifdef __WITH_DTLS__
149 CAResult_t CARegisterDTLSHandshakeCallback(CAErrorCallback dtlsHandshakeCallback)
150 {
151     OIC_LOG(DEBUG, TAG, "CARegisterDTLSHandshakeCallback");
152
153     if(!g_isInitialized)
154     {
155         return CA_STATUS_NOT_INITIALIZED;
156     }
157
158     CADTLSSetHandshakeCallback(dtlsHandshakeCallback);
159
160     return CA_STATUS_OK;
161 }
162
163 CAResult_t CARegisterDTLSCredentialsHandler(CAGetDTLSPskCredentialsHandler GetDTLSCredentialsHandler)
164 {
165     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
166
167     if(!g_isInitialized)
168     {
169         return CA_STATUS_NOT_INITIALIZED;
170     }
171
172     CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
173     return CA_STATUS_OK;
174 }
175 #endif //__WITH_DTLS__
176
177 #ifdef __WITH_X509__
178 CAResult_t CARegisterDTLSX509CredentialsHandler(CAGetDTLSX509CredentialsHandler GetDTLSX509CredentialsHandler)
179 {
180     OIC_LOG(DEBUG, TAG, "CARegisterDTLSX509CredentialsHandler");
181
182     if(!g_isInitialized)
183     {
184         return CA_STATUS_NOT_INITIALIZED;
185     }
186
187     CADTLSSetX509CredentialsCallback(GetDTLSX509CredentialsHandler);
188     return CA_STATUS_OK;
189 }
190
191 CAResult_t CARegisterDTLSCrlHandler(CAGetDTLSCrlHandler GetDTLSCrlHandler)
192 {
193     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCrlHandler");
194
195     if(!g_isInitialized)
196     {
197         return CA_STATUS_NOT_INITIALIZED;
198     }
199
200     CADTLSSetCrlCallback(GetDTLSCrlHandler);
201     return CA_STATUS_OK;
202 }
203 #endif //__WITH_X509__
204
205 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
206                             CATransportAdapter_t adapter,
207                             const char *addr,
208                             uint16_t port,
209                             CAEndpoint_t **object)
210 {
211     if (!object)
212     {
213         OIC_LOG(ERROR, TAG, "Invalid Parameter");
214         return CA_STATUS_INVALID_PARAM;
215     }
216
217     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
218     if (!endpoint)
219     {
220         return CA_STATUS_FAILED;
221     }
222     *object = endpoint;
223     return CA_STATUS_OK;
224 }
225
226 void CADestroyEndpoint(CAEndpoint_t *rep)
227 {
228     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
229
230     CAFreeEndpoint(rep);
231 }
232
233 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
234 {
235     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
236
237     return CAGenerateTokenInternal(token, tokenLength);
238 }
239
240 void CADestroyToken(CAToken_t token)
241 {
242     OIC_LOG(DEBUG, TAG, "CADestroyToken");
243
244     CADestroyTokenInternal(token);
245
246     OIC_LOG(DEBUG, TAG, "OUT");
247 }
248
249 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, uint32_t *size)
250 {
251     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
252
253     if(!g_isInitialized)
254     {
255         return CA_STATUS_NOT_INITIALIZED;
256     }
257
258     return CAGetNetworkInformationInternal(info, size);
259 }
260
261 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
262 {
263     OIC_LOG(DEBUG, TAG, "CASendRequest");
264
265     if(!g_isInitialized)
266     {
267         return CA_STATUS_NOT_INITIALIZED;
268     }
269
270     return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
271 }
272
273 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
274 {
275     OIC_LOG(DEBUG, TAG, "CASendResponse");
276
277     if(!g_isInitialized)
278     {
279         return CA_STATUS_NOT_INITIALIZED;
280     }
281
282     return CADetachSendMessage(object, responseInfo, CA_RESPONSE_DATA);
283 }
284
285 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
286 {
287     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
288
289     if(!g_isInitialized)
290     {
291         return CA_STATUS_NOT_INITIALIZED;
292     }
293
294     CAResult_t res = CA_STATUS_OK;
295
296     if (interestedNetwork & CA_ADAPTER_IP)
297     {
298         res = CAAddNetworkType(CA_ADAPTER_IP);
299         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
300     }
301     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
302     {
303         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
304         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
305     }
306     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
307     {
308         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
309         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
310     }
311
312 #ifdef RA_ADAPTER
313     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
314     {
315         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
316         OIC_LOG_V(DEBUG, TAG,
317                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
318     }
319 #endif
320
321 #ifdef TCP_ADAPTER
322     else if (interestedNetwork & CA_ADAPTER_TCP)
323     {
324         res = CAAddNetworkType(CA_ADAPTER_TCP);
325         OIC_LOG_V(DEBUG, TAG,
326                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
327     }
328 #endif
329
330     else
331     {
332         res = CA_NOT_SUPPORTED;
333     }
334     return res;
335 }
336
337 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
338 {
339     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
340
341     if(!g_isInitialized)
342     {
343         return CA_STATUS_NOT_INITIALIZED;
344     }
345
346     CAResult_t res = CA_STATUS_OK;
347
348     if (nonInterestedNetwork & CA_ADAPTER_IP)
349     {
350         res = CARemoveNetworkType(CA_ADAPTER_IP);
351         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
352     }
353     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
354     {
355         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
356         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
357     }
358     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
359     {
360         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
361         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
362     }
363 #ifdef RA_ADAPTER
364     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
365     {
366         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
367         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
368                   res);
369     }
370 #endif
371
372
373 #ifdef TCP_ADAPTER
374     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
375     {
376         res = CARemoveNetworkType(CA_ADAPTER_TCP);
377         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
378                   res);
379     }
380 #endif
381
382     else
383     {
384         res = CA_STATUS_FAILED;
385     }
386     return res;
387 }
388
389 CAResult_t CAHandleRequestResponse()
390 {
391     if (!g_isInitialized)
392     {
393         OIC_LOG(ERROR, TAG, "not initialized");
394         return CA_STATUS_NOT_INITIALIZED;
395     }
396
397     CAHandleRequestResponseCallbacks();
398
399     return CA_STATUS_OK;
400 }
401
402 #ifdef __WITH_DTLS__
403 CAResult_t CASelectCipherSuite(const uint16_t cipher)
404 {
405     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
406
407     return CADtlsSelectCipherSuite(cipher);
408 }
409
410 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
411 {
412     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
413
414     return CADtlsEnableAnonECDHCipherSuite(enable);
415 }
416
417 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
418                     const uint8_t* label, const size_t labelLen,
419                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
420                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
421                     uint8_t* ownerPSK, const size_t ownerPSKSize)
422 {
423     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
424
425     CAResult_t res = CA_STATUS_OK;
426
427     //newOwnerLabel and prevOwnerLabe can be NULL
428     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
429     {
430         return CA_STATUS_INVALID_PARAM;
431     }
432
433     res = CADtlsGenerateOwnerPSK(endpoint, label, labelLen,
434                                   rsrcServerDeviceID, rsrcServerDeviceIDLen,
435                                   provServerDeviceID, provServerDeviceIDLen,
436                                   ownerPSK, ownerPSKSize);
437     if (CA_STATUS_OK != res)
438     {
439         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
440     }
441
442     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
443
444     return res;
445 }
446
447 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
448 {
449     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
450     CAResult_t res = CA_STATUS_OK;
451
452     if (!endpoint)
453     {
454         return CA_STATUS_INVALID_PARAM;
455     }
456
457     res = CADtlsInitiateHandshake(endpoint);
458     if (CA_STATUS_OK != res)
459     {
460         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
461     }
462
463     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
464
465     return res;
466 }
467
468 CAResult_t CACloseDtlsSession(const CAEndpoint_t *endpoint)
469 {
470     OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
471     CAResult_t res = CA_STATUS_OK;
472
473     if (!endpoint)
474     {
475         return CA_STATUS_INVALID_PARAM;
476     }
477
478     res = CADtlsClose(endpoint);
479     if (CA_STATUS_OK != res)
480     {
481         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
482     }
483
484     OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
485
486     return res;
487 }
488
489 #endif /* __WITH_DTLS__ */
490
491 #ifdef TCP_ADAPTER
492 void CARegisterKeepAliveHandler(CAKeepAliveConnectedCallback ConnHandler,
493                                 CAKeepAliveDisconnectedCallback DisconnHandler)
494 {
495     CATCPSetKeepAliveCallbacks(ConnHandler, DisconnHandler);
496 }
497 #endif