Merge test folder of test branch
[iotivity.git] / test / src / testapp / ca / c_cpp / src / sample_server.c
1 /******************************************************************
2 *
3 * Copyright 2016 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 #define MAX_BUF_LEN 2048
22 #define IDENTITY     ("1111111111111111")
23 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
24
25 #include "casimulator.h"
26 #include "cacommon.h"
27 #include "cainterface.h"
28 #include "cautilinterface.h"
29 #include "casecurityinterface.h"
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #ifdef __LINUX__
36 #include <unistd.h>
37 #endif
38
39 #ifdef __WITH_DTLS__
40 #include "ca_adapter_net_ssl.h"
41 #include "ssl_ciphersuites.h"
42 #endif
43
44 #ifdef TIZEN
45 #include <glib.h>
46 #include <pthread.h>
47
48 static GMainLoop *g_mainloop = NULL;
49 pthread_t thread;
50 #endif
51
52 int g_selectedNetwork = 0;
53 size_t g_identityLegth;
54 size_t g_pskLength;
55
56 void getString(char a[], char str[], int length)
57 {
58     int i;
59
60     for(i = 0; i < length; i++)
61     {
62         str[i] = a[i];
63     }
64
65     printf("\n");
66
67     str[length] = 0;
68 }
69
70 #ifdef __WITH_DTLS__
71
72 CAResult_t dtlsHandshakeCb(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
73 {
74     if (NULL == endpoint)
75     {
76       printf("endpoint is null");
77       return CA_STATUS_FAILED;
78     }
79
80     if (NULL == info)
81     {
82         printf("ErrorInfo: %d", info->result);
83         return CA_STATUS_FAILED;
84     }
85     printf("Remote device Address %s:%d:", endpoint->addr, endpoint->port);
86     printf("ErrorInfo is null");
87     return CA_STATUS_OK;
88 }
89
90 void initCipherSuiteList(bool * list, const char* deviceId)
91 {
92     (void) deviceId;
93
94     printf("%s In\n", __func__);
95
96     if (NULL == list)
97     {
98         printf("Out %s", __func__);
99         printf("NULL list param");
100         return;
101     }
102
103     list[0] = true;
104     list[1] = true;
105
106     printf("%s Out\n", __func__);
107 }
108
109 int32_t getDtlsPskCredentials( CADtlsPskCredType_t type, const unsigned char *desc,
110         size_t desc_len, unsigned char *result, size_t result_length)
111 {
112     printf("getDtlsPskCredentials in\n");
113
114     int32_t ret = -1;
115
116     if (NULL == result)
117     {
118         return ret;
119     }
120
121     switch (type)
122     {
123         case CA_DTLS_PSK_HINT:
124         case CA_DTLS_PSK_IDENTITY:
125         printf("CAGetDtlsPskCredentials CA_DTLS_PSK_IDENTITY\n");
126         if (result_length < g_identityLegth)
127         {
128             printf("ERROR : Wrong value for result for storing IDENTITY\n");
129             return ret;
130         }
131
132         memcpy(result, IDENTITY, g_identityLegth);
133         ret = g_identityLegth;
134         break;
135
136         case CA_DTLS_PSK_KEY:
137         printf("CAGetDtlsPskCredentials CA_DTLS_PSK_KEY\n");
138         if ((desc_len == g_identityLegth) &&
139                 memcmp(desc, IDENTITY, g_identityLegth) == 0)
140         {
141             if (result_length < g_pskLength)
142             {
143                 printf("ERROR : Wrong value for result for storing RS_CLIENT_PSK\n");
144                 return ret;
145             }
146
147             memcpy(result, RS_CLIENT_PSK, g_pskLength);
148             ret = g_pskLength;
149         }
150         break;
151
152         default:
153
154         printf("Wrong value passed for PSK_CRED_TYPE.\n");
155         ret = -1;
156     }
157
158     printf("getDtlsPskCredentials out\n");
159
160     return ret;
161 }
162
163 int setupSecurity(int selectedTransport)
164 {
165     g_identityLegth = strlen(IDENTITY);
166     g_pskLength = strlen(RS_CLIENT_PSK);
167
168     int result = CAregisterPskCredentialsHandler(getDtlsPskCredentials);
169     if (result != CA_STATUS_OK)
170     {
171         printf("CAregisterPskCredentialsHandler failed. return value is %d\n", result);
172         return 0;
173     }
174
175     if(selectedTransport == CA_ADAPTER_TCP)
176     {
177         result = CAregisterSslHandshakeCallback(dtlsHandshakeCb);
178         if (result != CA_STATUS_OK)
179         {
180             printf("CAregisterSslHandshakeCallback failed. return value is %d\n", result);
181             return 0;
182         }
183     }
184
185     CAsetCredentialTypesCallback(initCipherSuiteList);
186
187     if(selectedTransport == CA_ADAPTER_IP)
188     {
189         result = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, (CATransportAdapter_t)selectedTransport);
190     }
191     else if(selectedTransport == CA_ADAPTER_TCP)
192     {
193         result = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
194     }
195
196     if (result != CA_STATUS_OK)
197     {
198         printf("CACipherSuite failed. return value is %d\n", result);
199         return 0;
200     }
201
202     return 1;
203 }
204
205 #endif
206
207 int returnResponse(const CAEndpoint_t* endPoint, char* resourceUri, char* payload, int payloadSize,
208         CAMessageType_t type, CAResponseResult_t responseCode, uint16_t messageId, CAToken_t token,
209         uint8_t tokenLength, CAHeaderOption_t *options, uint8_t numOptions)
210 {
211     printf("[returnResponse] in\n");
212
213     CAInfo_t responseData;
214
215     responseData.payload = (CAPayload_t)payload;
216
217     if(payload != NULL)
218     {
219         responseData.payloadSize = payloadSize;
220     }
221     else
222     {
223         responseData.payloadSize = 0;
224     }
225
226     responseData.type = type;
227     responseData.messageId = messageId;
228     responseData.resourceUri = resourceUri;
229     responseData.token = token;
230     responseData.tokenLength = tokenLength;
231     responseData.options = options;
232     responseData.numOptions = numOptions;
233     responseData.dataType = CA_RESPONSE_DATA;
234     responseData.payloadFormat = CA_FORMAT_UNDEFINED;
235     responseData.acceptFormat = CA_FORMAT_UNDEFINED;
236
237     CAResponseInfo_t responseInfo;
238     responseInfo.result = responseCode;
239     responseInfo.info = responseData;
240
241     printf("Sending response....\n");
242
243     CAResult_t res = CASendResponse(endPoint, &responseInfo);
244
245     printf("Response Send....\n");
246
247     if (res != CA_STATUS_OK)
248     {
249         printf("send response error\n");
250     }
251     else
252     {
253         printf("send response success\n");
254     }
255
256     printf("[returnResponse] out\n");
257
258     return 1;
259 }
260
261 void requestHandler(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
262 {
263     char *payload = NULL;
264     CAMessageType_t messageType = CA_MSG_ACKNOWLEDGE;
265
266     printf("requestHandler in\n");
267
268     if(!endPoint)
269     {
270         printf("endPoint is NULL\n");
271         return;
272     }
273
274     if(!requestInfo)
275     {
276         printf("requestInfo is NULL\n");
277         return;
278     }
279
280     printf("IP %s, Port %d\n", endPoint->addr, endPoint->port);
281     printf("Message Id: %d\n", requestInfo->info.messageId);
282
283     if (requestInfo->info.options)
284     {
285         printf("Header Option Found\n");
286
287         uint32_t len = requestInfo->info.numOptions;
288         uint32_t i;
289         for (i = 0; i < len; i++)
290         {
291             printf("Option ID : %d\n", requestInfo->info.options[i].optionID);
292             printf("Option Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
293                    requestInfo->info.options[i].optionData);
294         }
295     }
296     else
297     {
298         printf("No Header Option Found\n");
299     }
300
301     printf("PayloadSize: %d\n", requestInfo->info.payloadSize);
302
303     if(requestInfo->info.payload)
304     {
305         char str[MAX_BUF_LEN];
306         getString((char*)requestInfo->info.payload, str, requestInfo->info.payloadSize);
307         payload = str;
308         printf("Payload: %s\n", payload);
309     }
310     else
311     {
312         printf("Payload is NULL\n");
313     }
314
315     if(!requestInfo->info.resourceUri)
316     {
317         printf("ResourceUri is NULL\n");
318         return;
319     }
320
321     printf("ResourceUri: %s\n", requestInfo->info.resourceUri);
322
323     returnResponse(endPoint, requestInfo->info.resourceUri,
324         (char*)requestInfo->info.payload, requestInfo->info.payloadSize, messageType, CA_VALID,
325         requestInfo->info.messageId, requestInfo->info.token, requestInfo->info.tokenLength,
326         requestInfo->info.options, requestInfo->info.numOptions);
327
328     printf("requestHandler out\n");
329 }
330
331 void responseHandler(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
332 {
333
334 }
335
336 void errorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t* errorInfo)
337 {
338     printf("errorHandler in\n");
339
340     printf("errorHandler out\n");
341 }
342
343 int main()
344 {
345     CAResult_t result;
346     int number;
347     char command[100];
348
349 #ifdef TIZEN
350     g_mainloop = g_main_loop_new(NULL, FALSE);
351     if(!g_mainloop)
352     {
353        printf("g_main_loop_new failed\n");
354        return -1;
355     }
356
357     if (pthread_create(&thread, NULL, (void *) &GMainLoopThread, NULL) < 0)
358     {
359        printf("pthread_create failed in initialize\n");
360        return -1;
361     }
362 #endif
363
364     result = CAInitialize(CA_ADAPTER_TCP);
365     if (result != CA_STATUS_OK)
366     {
367         printf("CAInitialize failed. return value is %d", result);
368         return -1;
369     }
370
371     CARegisterHandler(requestHandler, responseHandler, errorHandler);
372
373     printf("\tSelect Network\n");
374     printf("IP     : 0\n");
375     printf("TCP    : 4\n");
376     printf("Select : ");
377
378     scanf("%d", &number);
379     g_selectedNetwork = 1 << number;
380
381     result = CASelectNetwork((CATransportAdapter_t)g_selectedNetwork);
382     if (result != CA_STATUS_OK)
383     {
384         printf("CASelectNetwork failed. return value is %d", result);
385         return -1;
386     }
387
388     result = CAStartListeningServer();
389     if (result != CA_STATUS_OK)
390     {
391         printf("CAStartListeningServer failed. return value is %d", result);
392         return -1;
393     }
394
395 #ifdef __WITH_DTLS__
396     if(!setupSecurity(g_selectedNetwork))
397     {
398         return -1;
399     }
400 #endif
401
402     if(g_selectedNetwork == CA_ADAPTER_IP)
403     {
404         printf("Unsecured Port: %d;\n", CAGetAssignedPortNumber(CA_ADAPTER_IP, CA_IPV4));
405 #ifdef __WITH_DTLS__
406         printf("Secured Port: %d;\n", CAGetAssignedPortNumber(CA_ADAPTER_IP, (CATransportFlags_t)(CA_SECURE|CA_IPV4)));
407 #endif
408     }
409     else if(g_selectedNetwork == CA_ADAPTER_TCP)
410     {
411         printf("Unsecured Port: %d;\n", CAGetAssignedPortNumber(CA_ADAPTER_TCP, CA_IPV4));
412 #ifdef __WITH_DTLS__
413         printf("Secured Port: %d;\n", CAGetAssignedPortNumber(CA_ADAPTER_TCP, (CATransportFlags_t)(CA_SECURE|CA_IPV4)));
414 #endif
415     }
416
417     printf("press 'h' to call CAHandleRequestResponse and 'q' to quit\n");
418
419     while(scanf("%s", command) == 1)
420     {
421         printf("press 'h' to call CAHandleRequestResponse and 'q' to quit\n");
422         if(command[0] == 'q')
423         {
424             break;
425         }
426         if(command[0] == 'h')
427         {
428             result = CAHandleRequestResponse();
429             if (result != CA_STATUS_OK)
430             {
431                 printf("CAHandleRequestResponse failed. return value is %d", result);
432                 return -1;
433             }
434         }
435     }
436 }
437