Merging security-M3 to master
[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 "cainterface.h"
27 #include "caremotehandler.h"
28 #include "camessagehandler.h"
29 #include "caprotocolmessage.h"
30 #include "canetworkconfigurator.h"
31 #include "cainterfacecontroller.h"
32 #include "logger.h"
33 #ifdef __WITH_DTLS__
34 #include "caadapternetdtls.h"
35 #endif
36
37 #define TAG PCF("CA")
38
39 static bool g_isInitialized = false;
40
41 #ifdef __WITH_DTLS__
42 // CAAdapterNetDTLS will register the callback.
43 // Taking callback all the way through adapters not the right approach, hence calling here.
44 extern void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback);
45 #endif
46
47 CAResult_t CAInitialize()
48 {
49     OIC_LOG(DEBUG, TAG, "CAInitialize");
50
51     if (!g_isInitialized)
52     {
53         CAResult_t res = CAInitializeMessageHandler();
54         if (res != CA_STATUS_OK)
55         {
56             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
57             return res;
58         }
59         g_isInitialized = true;
60     }
61     return CA_STATUS_OK;
62 }
63
64 void CATerminate()
65 {
66     OIC_LOG(DEBUG, TAG, "CATerminate");
67
68     if (g_isInitialized)
69     {
70         CATerminateMessageHandler();
71         CATerminateNetworkType();
72
73         g_isInitialized = false;
74     }
75 }
76
77 CAResult_t CAStartListeningServer()
78 {
79     OIC_LOG(DEBUG, TAG, "CAStartListeningServer");
80
81     if(!g_isInitialized)
82     {
83         return CA_STATUS_NOT_INITIALIZED;
84     }
85
86     return CAStartListeningServerAdapters();
87 }
88
89 CAResult_t CAStartDiscoveryServer()
90 {
91     OIC_LOG(DEBUG, TAG, "CAStartDiscoveryServer");
92
93     if(!g_isInitialized)
94     {
95         return CA_STATUS_NOT_INITIALIZED;
96     }
97
98     return CAStartDiscoveryServerAdapters();
99 }
100
101 void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler,
102                        CAErrorCallback ErrorHandler)
103 {
104     OIC_LOG(DEBUG, TAG, "CARegisterHandler");
105
106     if(!g_isInitialized)
107     {
108         OIC_LOG(DEBUG, TAG, "CA is not initialized");
109         return;
110     }
111
112     CASetInterfaceCallbacks(ReqHandler, RespHandler, ErrorHandler);
113 }
114
115 #ifdef __WITH_DTLS__
116 CAResult_t CARegisterDTLSCredentialsHandler(
117                                              CAGetDTLSCredentialsHandler GetDTLSCredentialsHandler)
118 {
119     OIC_LOG(DEBUG, TAG, "CARegisterDTLSCredentialsHandler");
120
121     if(!g_isInitialized)
122     {
123         return CA_STATUS_NOT_INITIALIZED;
124     }
125
126     CADTLSSetCredentialsCallback(GetDTLSCredentialsHandler);
127     return CA_STATUS_OK;
128 }
129 #endif //__WITH_DTLS__
130
131 CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, const CATransportType_t transportType,
132                                   CARemoteEndpoint_t **remoteEndpoint)
133 {
134     OIC_LOG(DEBUG, TAG, "CACreateRemoteEndpoint");
135
136     if(!g_isInitialized)
137     {
138         return CA_STATUS_NOT_INITIALIZED;
139     }
140
141     CARemoteEndpoint_t *remote = CACreateRemoteEndpointUriInternal(uri, transportType);
142
143     if (remote == NULL)
144     {
145         OIC_LOG(DEBUG, TAG, "remote is NULL!");
146         return CA_STATUS_FAILED;
147     }
148
149     *remoteEndpoint = remote;
150
151     return CA_STATUS_OK;
152 }
153
154 void CADestroyRemoteEndpoint(CARemoteEndpoint_t *rep)
155 {
156     OIC_LOG(DEBUG, TAG, "CADestroyRemoteEndpoint");
157     CADestroyRemoteEndpointInternal(rep);
158 }
159
160 CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength)
161 {
162     OIC_LOG(DEBUG, TAG, "CAGenerateToken");
163
164     if(!g_isInitialized)
165     {
166         return CA_STATUS_NOT_INITIALIZED;
167     }
168     return CAGenerateTokenInternal(token, tokenLength);
169 }
170
171 void CADestroyToken(CAToken_t token)
172 {
173     OIC_LOG(DEBUG, TAG, "CADestroyToken");
174     CADestroyTokenInternal(token);
175 }
176
177 CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size)
178 {
179     OIC_LOG(DEBUG, TAG, "CAGetNetworkInformation");
180
181     if(!g_isInitialized)
182     {
183         return CA_STATUS_NOT_INITIALIZED;
184     }
185
186     return CAGetNetworkInformationInternal(info, size);
187 }
188
189 CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token, uint8_t tokenLength)
190 {
191     OIC_LOG(DEBUG, TAG, "CAFindResource");
192
193     if(!g_isInitialized)
194     {
195         return CA_STATUS_NOT_INITIALIZED;
196     }
197     return CADetachMessageResourceUri(resourceUri, token, tokenLength, NULL, 0);
198
199 }
200
201 CAResult_t CASendRequest(const CARemoteEndpoint_t *object,const CARequestInfo_t *requestInfo)
202 {
203     OIC_LOG(DEBUG, TAG, "CASendGetRequest");
204
205     if(!g_isInitialized)
206     {
207         return CA_STATUS_NOT_INITIALIZED;
208     }
209
210     return CADetachRequestMessage(object, requestInfo);
211 }
212
213 CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object,
214                               const CARequestInfo_t *requestInfo)
215 {
216     OIC_LOG(DEBUG, TAG, "CASendRequestToAll");
217
218     if(!g_isInitialized)
219     {
220         return CA_STATUS_NOT_INITIALIZED;
221     }
222
223     return CADetachRequestToAllMessage(object, requestInfo);
224 }
225
226 CAResult_t CASendNotification(const CARemoteEndpoint_t *object,
227     const CAResponseInfo_t *responseInfo)
228 {
229     OIC_LOG(DEBUG, TAG, "CASendNotification");
230
231     if(!g_isInitialized)
232     {
233         return CA_STATUS_NOT_INITIALIZED;
234     }
235
236     return CADetachResponseMessage(object, responseInfo);
237
238 }
239
240 CAResult_t CASendResponse(const CARemoteEndpoint_t *object,
241     const CAResponseInfo_t *responseInfo)
242 {
243     OIC_LOG(DEBUG, TAG, "CASendResponse");
244
245     if(!g_isInitialized)
246     {
247         return CA_STATUS_NOT_INITIALIZED;
248     }
249
250     return CADetachResponseMessage(object, responseInfo);
251
252 }
253
254 CAResult_t CAAdvertiseResource(const CAURI_t resourceUri,const CAToken_t token,
255                                uint8_t tokenLength, const CAHeaderOption_t *options,
256                                const uint8_t numOptions)
257 {
258     OIC_LOG(DEBUG, TAG, "CAAdvertiseResource");
259
260     if(!g_isInitialized)
261     {
262         return CA_STATUS_NOT_INITIALIZED;
263     }
264     return CADetachMessageResourceUri(resourceUri, token, tokenLength, options, numOptions);
265
266 }
267
268 CAResult_t CASelectNetwork(const uint32_t interestedNetwork)
269 {
270     OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
271
272     if(!g_isInitialized)
273     {
274         return CA_STATUS_NOT_INITIALIZED;
275     }
276
277     if (!(interestedNetwork & 0xf))
278     {
279         return CA_NOT_SUPPORTED;
280     }
281
282     CAResult_t res = CA_STATUS_OK;
283
284     if (interestedNetwork & CA_IPV4)
285     {
286         res = CAAddNetworkType(CA_IPV4);
287         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_IPV4) function returns error : %d", res);
288     }
289
290     if (interestedNetwork & CA_EDR)
291     {
292         res = CAAddNetworkType(CA_EDR);
293         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_EDR) function returns error : %d", res);
294     }
295
296     if (interestedNetwork & CA_LE)
297     {
298         res = CAAddNetworkType(CA_LE);
299         OIC_LOG_V(ERROR, TAG, "CAAddNetworkType(CA_LE) function returns error : %d", res);
300     }
301
302     return res;
303 }
304
305 CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork)
306 {
307     OIC_LOG_V(DEBUG, TAG, "unselected network : %d", nonInterestedNetwork);
308
309     if(!g_isInitialized)
310     {
311         return CA_STATUS_NOT_INITIALIZED;
312     }
313
314     if (!(nonInterestedNetwork & 0xf))
315     {
316         return CA_NOT_SUPPORTED;
317     }
318
319     CAResult_t res = CA_STATUS_OK;
320
321     if (nonInterestedNetwork & CA_IPV4)
322     {
323         res = CARemoveNetworkType(CA_IPV4);
324         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_IPV4) function returns error : %d", res);
325     }
326
327     if (nonInterestedNetwork & CA_EDR)
328     {
329         res = CARemoveNetworkType(CA_EDR);
330         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_EDR) function returns error : %d", res);
331     }
332
333     if (nonInterestedNetwork & CA_LE)
334     {
335         res = CARemoveNetworkType(CA_LE);
336         OIC_LOG_V(ERROR, TAG, "CARemoveNetworkType(CA_LE) function returns error : %d", res);
337     }
338
339     return res;
340 }
341
342 CAResult_t CAHandleRequestResponse()
343 {
344     OIC_LOG(DEBUG, TAG, "CAHandleRequestResponse");
345
346     if (!g_isInitialized)
347     {
348         OIC_LOG(ERROR, TAG, "not initialized");
349         return CA_STATUS_NOT_INITIALIZED;
350     }
351
352     CAHandleRequestResponseCallbacks();
353
354     return CA_STATUS_OK;
355 }
356
357 #ifdef __WITH_DTLS__
358
359 CAResult_t CASelectCipherSuite(const uint16_t cipher)
360 {
361     OIC_LOG_V(DEBUG, TAG, "CASelectCipherSuite");
362
363     return CADtlsSelectCipherSuite(cipher);
364 }
365
366 CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
367 {
368     OIC_LOG_V(DEBUG, TAG, "CAEnableAnonECDHCipherSuite");
369
370     return CADtlsEnableAnonECDHCipherSuite(enable);
371 }
372
373 CAResult_t CAGenerateOwnerPSK(const CAAddress_t* addrInfo,
374                     const CATransportType_t transportType,
375                     const uint8_t* label, const size_t labelLen,
376                     const uint8_t* rsrcServerDeviceID, const size_t rsrcServerDeviceIDLen,
377                     const uint8_t* provServerDeviceID, const size_t provServerDeviceIDLen,
378                     uint8_t* ownerPSK, const size_t ownerPSKSize)
379 {
380     OIC_LOG_V(DEBUG, TAG, "IN : CAGenerateOwnerPSK");
381
382     CAResult_t res = CA_STATUS_OK;
383
384     //newOwnerLabel and prevOwnerLabe can be NULL
385     if(!addrInfo || !label || 0 == labelLen || !ownerPSK || 0 == ownerPSKSize)
386     {
387         return CA_STATUS_INVALID_PARAM;
388     }
389
390     res = CADtlsGenerateOwnerPSK(addrInfo, transportType, label, labelLen,
391                                   rsrcServerDeviceID, rsrcServerDeviceIDLen,
392                                   provServerDeviceID, provServerDeviceIDLen,
393                                   ownerPSK, ownerPSKSize);
394     if(CA_STATUS_OK != res)
395     {
396         OIC_LOG_V(ERROR, TAG, "Failed to CAGenerateOwnerPSK : %d", res);
397     }
398
399     OIC_LOG_V(DEBUG, TAG, "OUT : CAGenerateOwnerPSK");
400
401     return res;
402 }
403
404 CAResult_t CAInitiateHandshake(const CAAddress_t* addrInfo,
405                                const CATransportType_t transportType)
406 {
407     OIC_LOG_V(DEBUG, TAG, "IN : CAInitiateHandshake");
408     CAResult_t res = CA_STATUS_OK;
409
410     if(!addrInfo)
411     {
412         return CA_STATUS_INVALID_PARAM;
413     }
414
415     res = CADtlsInitiateHandshake(addrInfo, transportType);
416     if(CA_STATUS_OK != res)
417     {
418         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsInitiateHandshake : %d", res);
419     }
420
421     OIC_LOG_V(DEBUG, TAG, "OUT : CAInitiateHandshake");
422
423     return res;
424 }
425
426 CAResult_t CACloseDtlsSession(const CAAddress_t* addrInfo,
427                               const CATransportType_t transportType)
428 {
429     OIC_LOG_V(DEBUG, TAG, "IN : CACloseDtlsSession");
430     CAResult_t res = CA_STATUS_OK;
431
432     if(!addrInfo)
433     {
434         return CA_STATUS_INVALID_PARAM;
435     }
436
437     res = CADtlsClose(addrInfo, transportType);
438     if(CA_STATUS_OK != res)
439     {
440         OIC_LOG_V(ERROR, TAG, "Failed to CADtlsClose : %d", res);
441     }
442
443     OIC_LOG_V(DEBUG, TAG, "OUT : CACloseDtlsSession");
444
445     return res;
446 }
447
448 #endif /* __WITH_DTLS__ */