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