Support Signaling Message for CoAP over TCP
[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 "experimental/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 "experimental/logger.h"
34
35 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
36 #include "ca_adapter_net_ssl.h"
37 #endif // __WITH_DTLS__ or __WITH_TLS__
38
39 #ifdef TCP_ADAPTER
40 #include "catcpadapter.h"
41 #endif
42
43 CAGlobals_t caglobals = { .clientFlags = 0,
44                           .serverFlags = 0, };
45
46 #define TAG "OIC_CA_CONN_MGR"
47
48 static bool g_isInitialized = false;
49
50 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
51 // Taking callback all the way through adapters not the right approach, hence calling here.
52 extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
53 extern void CAsetPskCredentialsCallback(CAgetPskCredentialsHandler credCallback);
54 extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
55 #endif // __WITH_DTLS__ or __WITH_TLS__
56
57
58 CAResult_t CAInitialize(CATransportAdapter_t transportType)
59 {
60     OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
61
62     if (!g_isInitialized)
63     {
64         CAResult_t res = CAInitializeMessageHandler(transportType);
65         if (res != CA_STATUS_OK)
66         {
67             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
68             CATerminateMessageHandler();
69             return res;
70         }
71         g_isInitialized = true;
72     }
73
74     return CA_STATUS_OK;
75 }
76
77 void CATerminate()
78 {
79     OIC_LOG(DEBUG, TAG, "CATerminate");
80
81     if (g_isInitialized)
82     {
83         CATerminateMessageHandler();
84         CATerminateNetworkType();
85
86         g_isInitialized = false;
87     }
88 }
89
90 CAResult_t CAStartListeningServer()
91 {
92     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
93
94     if (!g_isInitialized)
95     {
96         return CA_STATUS_NOT_INITIALIZED;
97     }
98
99     return CAStartListeningServerAdapters();
100 }
101
102 CAResult_t CAStopListeningServer()
103 {
104     OIC_LOG(DEBUG, TAG, "CAStopListeningServer");
105
106     if (!g_isInitialized)
107     {
108         return CA_STATUS_NOT_INITIALIZED;
109     }
110
111     return CAStopListeningServerAdapters();
112 }
113
114 CAResult_t CAStartDiscoveryServer()
115 {
116     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
117
118     if (!g_isInitialized)
119     {
120         return CA_STATUS_NOT_INITIALIZED;
121     }
122
123     return CAStartDiscoveryServerAdapters();
124 }
125
126 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
127                        CAErrorCallback ErrorHandler)
128 {
129     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
130
131     if (!g_isInitialized)
132     {
133         OIC_LOG(DEBUG, TAG, "CA is not initialized");
134         return;
135     }
136
137     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
138 }
139
140 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
141
142 CAResult_t CAGetSecureEndpointData(const CAEndpoint_t *peer, CASecureEndpoint_t *sep)
143 {
144     OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
145
146     if (!g_isInitialized)
147     {
148         OIC_LOG(DEBUG, TAG, "CA is not initialized");
149         return CA_STATUS_NOT_INITIALIZED;
150     }
151
152     OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
153     return GetCASecureEndpointData(peer, sep);
154 }
155
156 bool CASetSecureEndpointAttribute(const CAEndpoint_t* peer, uint32_t attribute)
157 {
158     bool success = false;
159     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
160
161     if (!g_isInitialized)
162     {
163         OIC_LOG(DEBUG, TAG, "CA is not initialized");
164     }
165     else
166     {
167         success = SetCASecureEndpointAttribute(peer, attribute);
168     }
169
170     OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
171     return success;
172 }
173
174 bool CAGetSecureEndpointAttributes(const CAEndpoint_t* peer, uint32_t* attributes)
175 {
176     bool success = false;
177     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
178
179     if (!g_isInitialized)
180     {
181         OIC_LOG(DEBUG, TAG, "CA is not initialized");
182     }
183     else
184     {
185         success = GetCASecureEndpointAttributes(peer, attributes);
186     }
187
188     OIC_LOG_V(DEBUG, TAG, "Out %s -> %u", __func__, (uint32_t)success);
189     return success;
190 }
191
192 CAResult_t CAregisterSslHandshakeCallback(CAHandshakeErrorCallback tlsHandshakeCallback)
193 {
194     OIC_LOG(DEBUG, TAG, "CAregisterSslHandshakeCallback");
195
196     if(!g_isInitialized)
197     {
198         return CA_STATUS_NOT_INITIALIZED;
199     }
200
201     CAsetSslHandshakeCallback(tlsHandshakeCallback);
202     return CA_STATUS_OK;
203 }
204
205 CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCredentialsHandler)
206 {
207     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
208
209     if (!g_isInitialized)
210     {
211         return CA_STATUS_NOT_INITIALIZED;
212     }
213     CAsetPskCredentialsCallback(getTlsCredentialsHandler);
214     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
215     return CA_STATUS_OK;
216 }
217
218 CAResult_t CAregisterPkixInfoHandler(CAgetPkixInfoHandler getPkixInfoHandler)
219 {
220     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
221
222     if (!g_isInitialized)
223     {
224         return CA_STATUS_NOT_INITIALIZED;
225     }
226     CAsetPkixInfoCallback(getPkixInfoHandler);
227     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
228     return CA_STATUS_OK;
229 }
230
231 CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCredTypesHandler)
232 {
233     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
234
235     if (!g_isInitialized)
236     {
237         return CA_STATUS_NOT_INITIALIZED;
238     }
239     CAsetCredentialTypesCallback(getCredTypesHandler);
240     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
241     return CA_STATUS_OK;
242 }
243 #endif // __WITH_DTLS__ or __WITH_TLS__
244
245 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
246                             CATransportAdapter_t adapter,
247                             const char *addr,
248                             uint16_t port,
249                             CAEndpoint_t **object)
250 {
251     if (!object)
252     {
253         OIC_LOG(ERROR, TAG, "Invalid Parameter");
254         return CA_STATUS_INVALID_PARAM;
255     }
256
257     CAEndpoint_t *endpoint = CACreateEndpointObject(flags, adapter, addr, port);
258     if (!endpoint)
259     {
260         return CA_STATUS_FAILED;
261     }
262     *object = endpoint;
263     return CA_STATUS_OK;
264 }
265
266 void CADestroyEndpoint(CAEndpoint_t *rep)
267 {
268     OIC_LOG(DEBUG, TAG, "CADestroyEndpoint");
269
270     CAFreeEndpoint(rep);
271 }
272
273 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
274 {
275     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
276
277     return CAGenerateTokenInternal(token, tokenLength);
278 }
279
280 void CADestroyToken(CAToken_t token)
281 {
282     OIC_LOG(DEBUG, TAG, "CADestroyToken");
283
284     CADestroyTokenInternal(token);
285
286     OIC_LOG(DEBUG, TAG, "OUT");
287 }
288
289 CAResult_t CAGetNetworkInformation(CAEndpoint_t **info, size_t *size)
290 {
291     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
292
293     if (!g_isInitialized)
294     {
295         return CA_STATUS_NOT_INITIALIZED;
296     }
297
298     return CAGetNetworkInformationInternal(info, size);
299 }
300
301 static CAResult_t CASendMessageMultiAdapter(const CAEndpoint_t *object, const void *sendMsg,
302                                             CADataType_t dataType)
303 {
304     OIC_LOG(DEBUG, TAG, "CASendMessageMultipleAdapter");
305
306     CATransportAdapter_t connTypes[] = {
307             CA_ADAPTER_IP
308 #ifdef LE_ADAPTER
309             ,CA_ADAPTER_GATT_BTLE
310 #endif
311 #ifdef EDR_ADAPTER
312             ,CA_ADAPTER_RFCOMM_BTEDR
313 #endif
314 #ifdef NFC_ADAPTER
315             ,CA_ADAPTER_NFC
316 #endif
317 #ifdef RA_ADAPTER
318             ,CA_ADAPTER_REMOTE_ACCESS
319 #endif
320         };
321
322     CAEndpoint_t *cloneEp = CACloneEndpoint(object);
323     if (!cloneEp)
324     {
325         OIC_LOG(ERROR, TAG, "Failed to clone CAEndpoint");
326         return CA_MEMORY_ALLOC_FAILED;
327     }
328
329     CAResult_t ret = CA_STATUS_OK;
330     size_t numConnTypes = sizeof(connTypes) / sizeof(connTypes[0]);
331
332     for (size_t i = 0; i < numConnTypes && ret == CA_STATUS_OK; i++)
333     {
334         cloneEp->adapter = connTypes[i];
335         ret = CADetachSendMessage(cloneEp, sendMsg, dataType);
336     }
337     CAFreeEndpoint(cloneEp);
338     return ret;
339 }
340
341 CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requestInfo)
342 {
343     OIC_LOG(DEBUG, TAG, "CASendRequest");
344
345     if (!g_isInitialized)
346     {
347         return CA_STATUS_NOT_INITIALIZED;
348     }
349
350     if (requestInfo && requestInfo->isMulticast &&
351             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
352     {
353         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
354     }
355     else
356     {
357         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
358     }
359 }
360
361 CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *responseInfo)
362 {
363     OIC_LOG(DEBUG, TAG, "CASendResponse");
364
365     if (!g_isInitialized)
366     {
367         return CA_STATUS_NOT_INITIALIZED;
368     }
369
370     if (!responseInfo || !object)
371     {
372         return CA_STATUS_INVALID_PARAM;
373     }
374
375     if (responseInfo->isMulticast &&
376             (object->adapter == CA_DEFAULT_ADAPTER || object->adapter == CA_ALL_ADAPTERS))
377     {
378         return CASendMessageMultiAdapter(object, responseInfo, responseInfo->info.dataType);
379     }
380     else
381     {
382         return CADetachSendMessage(object, responseInfo, responseInfo->info.dataType);
383     }
384 }
385
386 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
387 {
388     if (!g_isInitialized)
389     {
390         return CA_STATUS_NOT_INITIALIZED;
391     }
392
393     CAResult_t res = CA_STATUS_OK;
394
395     if (interestedNetwork & CA_ADAPTER_IP)
396     {
397         res = CAAddNetworkType(CA_ADAPTER_IP);
398         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_IP_ADAPTER) function returns result: %d", res);
399     }
400     else if (interestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
401     {
402         res = CAAddNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
403         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
404     }
405     else if (interestedNetwork & CA_ADAPTER_GATT_BTLE)
406     {
407         res = CAAddNetworkType(CA_ADAPTER_GATT_BTLE);
408         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
409     }
410
411 #ifdef RA_ADAPTER
412     else if (interestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
413     {
414         res = CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS);
415         OIC_LOG_V(DEBUG, TAG,
416                   "CAAddNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d", res);
417     }
418 #endif
419
420 #ifdef TCP_ADAPTER
421     else if (interestedNetwork & CA_ADAPTER_TCP)
422     {
423         res = CAAddNetworkType(CA_ADAPTER_TCP);
424         OIC_LOG_V(DEBUG, TAG,
425                   "CAAddNetworkType(CA_ADAPTER_TCP) function returns result : %d", res);
426     }
427 #endif
428     else if (interestedNetwork & CA_ADAPTER_NFC)
429     {
430         res = CAAddNetworkType(CA_ADAPTER_NFC);
431         OIC_LOG_V(DEBUG, TAG, "CAAddNetworkType(CA_ADAPTER_NFC) function returns result : %d", res);
432     }
433     else
434     {
435         res = CA_NOT_SUPPORTED;
436     }
437     return res;
438 }
439
440 CAResult_t CAUnSelectNetwork(CATransportAdapter_t nonInterestedNetwork)
441 {
442     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
443
444     if (!g_isInitialized)
445     {
446         return CA_STATUS_NOT_INITIALIZED;
447     }
448
449     CAResult_t res = CA_STATUS_OK;
450
451     if (nonInterestedNetwork & CA_ADAPTER_IP)
452     {
453         res = CARemoveNetworkType(CA_ADAPTER_IP);
454         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_IP_ADAPTER) function returns result : %d", res);
455     }
456     else if (nonInterestedNetwork & CA_ADAPTER_RFCOMM_BTEDR)
457     {
458         res = CARemoveNetworkType(CA_ADAPTER_RFCOMM_BTEDR);
459         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_RFCOMM_ADAPTER) function returns result : %d", res);
460     }
461     else if (nonInterestedNetwork & CA_ADAPTER_GATT_BTLE)
462     {
463         res = CARemoveNetworkType(CA_ADAPTER_GATT_BTLE);
464         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_GATT_ADAPTER) function returns result : %d", res);
465     }
466 #ifdef RA_ADAPTER
467     else if (nonInterestedNetwork & CA_ADAPTER_REMOTE_ACCESS)
468     {
469         res = CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS);
470         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_REMOTE_ACCESS) function returns result : %d",
471                   res);
472     }
473 #endif
474
475
476 #ifdef TCP_ADAPTER
477     else if (nonInterestedNetwork & CA_ADAPTER_TCP)
478     {
479         res = CARemoveNetworkType(CA_ADAPTER_TCP);
480         OIC_LOG_V(DEBUG, TAG, "CARemoveNetworkType(CA_ADAPTER_TCP) function returns result : %d",
481                   res);
482     }
483 #endif
484
485     else
486     {
487         res = CA_STATUS_FAILED;
488     }
489     return res;
490 }
491
492 CAResult_t CAHandleRequestResponse()
493 {
494     if (!g_isInitialized)
495     {
496         OIC_LOG(ERROR, TAG, "not initialized");
497         return CA_STATUS_NOT_INITIALIZED;
498     }
499
500     CAHandleRequestResponseCallbacks();
501
502     return CA_STATUS_OK;
503 }
504
505 CAResult_t CASelectCipherSuite(const uint16_t cipher, CATransportAdapter_t adapter)
506 {
507     (void)(adapter); // prevent unused-parameter warning when building release variant
508     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
509     OIC_LOG_V(DEBUG, TAG, "cipher : %d , CATransportAdapter : %d", cipher, adapter);
510     CAResult_t res = CA_STATUS_FAILED;
511 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
512     res = CAsetTlsCipherSuite(cipher);
513     if (CA_STATUS_OK != res)
514     {
515         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
516     }
517 #else
518     (void)(cipher); // prevent unused-parameter warning
519     OIC_LOG(ERROR, TAG, "Method not supported");
520 #endif
521     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
522     return res;
523 }
524
525 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
526 {
527     OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
528     CAResult_t res = CA_STATUS_FAILED;
529 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
530     // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
531     res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
532     if (CA_STATUS_OK != res)
533     {
534         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
535     }
536 #else
537     (void)(enable); // prevent unused-parameter compiler warning
538     OIC_LOG(ERROR, TAG, "Method not supported");
539 #endif
540     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
541     return res;
542 }
543
544 CAResult_t CAGenerateOwnerPSK(const CAEndpoint_t* endpoint,
545                     const uint8_t* label, const size_t labelLen,
546                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
547                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
548                     uint8_t* ownerPSK, const size_t ownerPskSize)
549 {
550     OIC_LOG(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
551     CAResult_t res = CA_STATUS_FAILED;
552 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
553     //newOwnerLabel and prevOwnerLabe can be NULL
554     if (!endpoint || !label || 0 == labelLen || !ownerPSK || 0 == ownerPskSize)
555     {
556         return CA_STATUS_INVALID_PARAM;
557     }
558
559     res = CAsslGenerateOwnerPsk(endpoint, label, labelLen,
560                                       rsrcServerDeviceID, rsrcServerDeviceIDLen,
561                                       provServerDeviceID, provServerDeviceIDLen,
562                                       ownerPSK, ownerPskSize);
563     if (CA_STATUS_OK != res)
564     {
565         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
566     }
567 #else
568     (void)(endpoint); // prevent unused-parameter compiler warnings
569     (void)(label);
570     (void)(labelLen);
571     (void)(rsrcServerDeviceID);
572     (void)(rsrcServerDeviceIDLen);
573     (void)(provServerDeviceID);
574     (void)(provServerDeviceIDLen);
575     (void)(ownerPSK);
576     (void)(ownerPskSize);
577     OIC_LOG(ERROR, TAG, "Method not supported");
578 #endif
579     OIC_LOG(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
580     return res;
581 }
582
583 CAResult_t CAInitiateHandshake(const CAEndpoint_t *endpoint)
584 {
585     OIC_LOG(DEBUG, TAG, "IN : CAInitiateHandshake");
586     CAResult_t res = CA_STATUS_FAILED;
587 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
588     if (!endpoint)
589     {
590         return CA_STATUS_INVALID_PARAM;
591     }
592
593     res = CAinitiateSslHandshake(endpoint);
594     if (CA_STATUS_OK != res)
595     {
596         OIC_LOG_V(ERROR, TAG, "Failed to CAinitiateSslHandshake : %d", res);
597     }
598 #else
599     (void)(endpoint); // prevent unused-parameter compiler warning
600     OIC_LOG(ERROR, TAG, "Method not supported");
601 #endif
602     OIC_LOG(DEBUG, TAG, "OUT : CAInitiateHandshake");
603     return res;
604 }
605
606 CAResult_t CAcloseSslSession(const CAEndpoint_t *endpoint)
607 {
608     OIC_LOG(DEBUG, TAG, "IN : CAcloseSslSession");
609     CAResult_t res = CA_STATUS_FAILED;
610 #if defined (__WITH_DTLS__) || defined(__WITH_TLS__)
611     if (!endpoint)
612     {
613         return CA_STATUS_INVALID_PARAM;
614     }
615
616     res = CAcloseSslConnection(endpoint);
617     if (CA_STATUS_OK != res)
618     {
619         OIC_LOG_V(ERROR, TAG, "Failed to CAsslClose : %d", res);
620     }
621 #else
622     (void)(endpoint); // prevent unused-parameter compiler warning
623     OIC_LOG(ERROR, TAG, "Method not supported");
624 #endif
625     OIC_LOG(DEBUG, TAG, "OUT : CAcloseSslSession");
626     return res;
627 }
628
629 #ifdef TCP_ADAPTER
630 void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler)
631 {
632     CATCPSetKeepAliveCallbacks(ConnHandler);
633 }
634 #endif