Clean up some SonarQube warnings (trailing whitespace, etc).
[platform/upstream/iotivity.git] / resource / csdk / connectivity / samples / android / casample / sampleService / src / main / jni / ResourceModel.c
1 #include <jni.h>
2 #include <android/log.h>
3 #include <stdio.h>
4 #include <dlfcn.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "cainterface.h"
9 #include "cacommon.h"
10
11 #include "org_iotivity_ca_service_RMInterface.h"
12
13 #define  LOG_TAG   "JNI_INTERFACE_SAMPLE"
14 #define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
15 #define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
16
17 /**
18  * @def RS_IDENTITY
19  * @brief
20  */
21 #define IDENTITY     ("1111111111111111")
22 /* @def RS_CLIENT_PSK
23  * @brief
24  */
25 #define RS_CLIENT_PSK   ("AAAAAAAAAAAAAAAA")
26
27 #define PORT_LENGTH 5
28 #define SECURE_DEFAULT_PORT 5684
29 #define RESOURCE_URI_LENGTH 14
30 #define OPTION_INFO_LENGTH 1024
31 #define NETWORK_INFO_LENGTH 1024
32
33 typedef struct
34 {
35     char ipAddress[CA_IPADDR_SIZE];
36     uint16_t port;
37 } addressSet_t;
38
39 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo);
40 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo);
41 void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
42 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length);
43 uint32_t get_secure_information(CAPayload_t payLoad);
44 CAResult_t get_network_type(uint32_t selectedNetwork);
45 void callback(char *subject, char *receivedData);
46 CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address);
47 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
48
49 uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
50 CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP;
51 static CAToken_t g_lastRequestToken = NULL;
52 static uint8_t g_lastRequestTokenLength = 0;
53
54 static const char COAP_PREFIX[] =  "coap://";
55 static const char COAPS_PREFIX[] = "coaps://";
56 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
57 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
58
59 static const char SECURE_INFO_DATA[]
60                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
61                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
62                                      "%d}}]}";
63 static const char NORMAL_INFO_DATA[]
64                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
65                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
66
67 static jobject g_responseListenerObject = NULL;
68 static JavaVM *g_jvm;
69
70 static CAEndpoint_t *g_clientEndpoint = NULL;
71 static char *g_resourceUri = NULL;
72 static CAToken_t g_clientToken = NULL;
73 static uint8_t g_clientTokenLength = 0;
74
75 static uint16_t g_clientMsgId = 0;
76 static char *g_remoteAddress = NULL;
77
78 // init
79 JNIEXPORT void JNICALL
80 Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
81                                                                    jobject listener)
82 {
83     LOGI("setNativeResponseListener");
84     g_responseListenerObject = (*env)->NewGlobalRef(env, obj);
85 }
86
87 #ifdef __WITH_DTLS__
88 static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
89
90 void clearDtlsCredentialInfo()
91 {
92     LOGI("clearDtlsCredentialInfo IN");
93     if (pskCredsBlob)
94     {
95         // Initialize sensitive data to zeroes before freeing.
96         if (NULL != pskCredsBlob->creds)
97         {
98             memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds)*(pskCredsBlob->num));
99             free(pskCredsBlob->creds);
100         }
101
102         memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
103         free(pskCredsBlob);
104         pskCredsBlob = NULL;
105     }
106     LOGI("clearDtlsCredentialInfo OUT");
107 }
108
109 // Internal API. Invoked by OC stack to retrieve credentials from this module
110 void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
111 {
112     LOGI("CAGetDtlsPskCredentials IN");
113     *credInfo = (CADtlsPskCredsBlob_t *) malloc(sizeof(CADtlsPskCredsBlob_t));
114     if (NULL == *credInfo)
115     {
116         LOGE("Failed to allocate credential blob.");
117         return;
118     }
119
120     int16_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num);
121     (*credInfo)->creds = (OCDtlsPskCreds *) malloc(credLen);
122     if (NULL == (*credInfo)->creds)
123     {
124         LOGE("Failed to allocate crentials.");
125         free(*credInfo);
126         *credInfo = NULL;
127         return;
128     }
129
130     memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN);
131     (*credInfo)->num = pskCredsBlob->num;
132     memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen);
133
134     LOGI("CAGetDtlsPskCredentials OUT");
135 }
136
137 CAResult_t SetCredentials()
138 {
139     LOGI("SetCredentials IN");
140     pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
141     if (NULL == pskCredsBlob)
142     {
143         LOGE("Memory allocation failed!");
144         return CA_MEMORY_ALLOC_FAILED;
145     }
146     memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN);
147
148     pskCredsBlob->num = 1;
149
150     pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) *(pskCredsBlob->num));
151     if (NULL == pskCredsBlob->creds)
152     {
153         LOGE("Memory allocation failed!");
154         return CA_MEMORY_ALLOC_FAILED;
155     }
156     memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN);
157     memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
158
159     LOGI("SetCredentials OUT");
160     return CA_STATUS_OK;
161 }
162 #endif
163
164 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
165 {
166     LOGI("JNI_OnLoad");
167
168     JNIEnv* env;
169     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
170     {
171         return -1;
172     }
173     g_jvm = jvm; /* cache the JavaVM pointer */
174
175     CANativeJNISetJavaVM(g_jvm);
176
177     return JNI_VERSION_1_6;
178 }
179
180 void JNI_OnUnload(JavaVM *jvm, void *reserved)
181 {
182     LOGI("JNI_OnUnload");
183
184     JNIEnv* env;
185     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
186     {
187         return;
188     }
189     g_jvm = 0;
190     return;
191 }
192
193 JNIEXPORT void JNICALL
194 Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context)
195 {
196     LOGI("RMInitialize");
197
198     //Currently set context for Android Platform
199     CANativeJNISetContext(env, context);
200
201     CAResult_t res = CAInitialize();
202
203     if (CA_STATUS_OK != res)
204     {
205         LOGE("Could not Initialize");
206     }
207
208 #ifdef __WITH_DTLS__
209     if (CA_STATUS_OK != SetCredentials())
210     {
211         LOGE("SetCredentials failed");
212         return;
213     }
214
215     res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
216     if(CA_STATUS_OK != res)
217     {
218         LOGE("Set credential handler fail");
219         return;
220     }
221 #endif
222 }
223
224 JNIEXPORT void JNICALL
225 Java_org_iotivity_ca_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
226 {
227     LOGI("RMTerminate");
228     CADestroyToken(g_lastRequestToken);
229     CATerminate();
230 }
231
232 JNIEXPORT void JNICALL
233 Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
234 {
235     LOGI("RMStartListeningServer");
236
237     if (CA_STATUS_OK != CAStartListeningServer())
238     {
239         LOGE("Could not start Listening server");
240     }
241 }
242
243 JNIEXPORT void JNICALL
244 Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
245 {
246     LOGI("RMStartDiscoveryServer");
247
248     if (CA_STATUS_OK != CAStartDiscoveryServer())
249     {
250         LOGE("Could not start discovery server");
251     }
252 }
253
254 JNIEXPORT void JNICALL
255 Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
256 {
257     LOGI("RMRegisterHandler");
258
259     CARegisterHandler(request_handler, response_handler, error_handler);
260 }
261
262 JNIEXPORT void JNICALL
263 Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
264                                                        jstring payload, jint selectedNetwork,
265                                                        jint isSecured, jint msgType)
266 {
267     LOGI("selectedNetwork - %d", selectedNetwork);
268     CAResult_t res = get_network_type(selectedNetwork);
269     if (CA_STATUS_OK != res)
270     {
271         return;
272     }
273
274     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
275     LOGI("RMSendRequest - %s", strUri);
276
277     CATransportFlags_t flags;
278     addressSet_t address = {};
279     parsing_coap_uri(strUri, &address, &flags);
280
281     //create remote endpoint
282     CAEndpoint_t* endpoint = NULL;
283     res = CACreateEndpoint(flags, g_selectedNwType, (const char*)address.ipAddress,
284                            address.port, &endpoint);
285     if (CA_STATUS_OK != res)
286     {
287         LOGE("Could not create remote end point");
288         (*env)->ReleaseStringUTFChars(env, uri, strUri);
289         return;
290     }
291
292     CAMessageType_t messageType = msgType;
293
294     // create token
295     CAToken_t token = NULL;
296     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
297
298     res = CAGenerateToken(&token, tokenLength);
299     if ((CA_STATUS_OK != res) || (!token))
300     {
301         LOGE("token generate error!!");
302         // destroy remote endpoint
303         CADestroyEndpoint(endpoint);
304         (*env)->ReleaseStringUTFChars(env, uri, strUri);
305         return;
306     }
307
308     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
309
310     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
311     (*env)->ReleaseStringUTFChars(env, uri, strUri);
312
313     CAInfo_t requestData = { 0 };
314     requestData.token = token;
315     requestData.tokenLength = tokenLength;
316
317     if (1 == isSecured)
318     {
319         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
320         requestData.payload = (CAPayload_t) malloc(length);
321         if (NULL == requestData.payload)
322         {
323             LOGE("Memory allocation failed!");
324             // destroy token
325             CADestroyToken(token);
326             // destroy remote endpoint
327             CADestroyEndpoint(endpoint);
328             return;
329         }
330         snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
331         requestData.payloadSize = length;
332     }
333     else
334     {
335         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
336         requestData.payload = (CAPayload_t) malloc(length);
337         if (NULL == requestData.payload)
338         {
339             LOGE("Memory allocation failed!");
340             // destroy token
341             CADestroyToken(token);
342             // destroy remote endpoint
343             CADestroyEndpoint(endpoint);
344             return;
345         }
346         snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
347         requestData.payloadSize = length;
348     }
349
350     requestData.type = messageType;
351     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
352     if (NULL == requestData.resourceUri)
353     {
354         LOGE("Memory allocation failed!");
355         // destroy token
356         CADestroyToken(token);
357         // destroy remote endpoint
358         CADestroyEndpoint(endpoint);
359         free(requestData.payload);
360         return;
361     }
362     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
363
364     CARequestInfo_t requestInfo = { 0 };
365     requestInfo.method = CA_GET;
366     requestInfo.isMulticast = false;
367     requestInfo.info = requestData;
368
369     // send request
370     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
371     {
372         LOGE("Could not send request");
373     }
374
375     // destroy token
376     CADestroyToken(token);
377
378     // destroy remote endpoint
379     CADestroyEndpoint(endpoint);
380
381     free(requestData.payload);
382     free(requestData.resourceUri);
383 }
384
385 JNIEXPORT void JNICALL
386 Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
387                                                            jint selectedNetwork)
388 {
389     LOGI("selectedNetwork - %d", selectedNetwork);
390     CAResult_t res = get_network_type(selectedNetwork);
391     if (CA_STATUS_OK != res)
392     {
393         return;
394     }
395
396     // create remote endpoint
397     CAEndpoint_t *endpoint = NULL;
398     res = CACreateEndpoint(CA_IPV4, g_selectedNwType, NULL, 0, &endpoint);
399
400     if (CA_STATUS_OK != res)
401     {
402         LOGE("create remote endpoint error, error code: %d", res);
403         return;
404     }
405
406     // create token
407     CAToken_t token = NULL;
408     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
409
410     res = CAGenerateToken(&token, tokenLength);
411     if ((CA_STATUS_OK != res) || (!token))
412     {
413         LOGE("token generate error!!");
414         // destroy remote endpoint
415         CADestroyEndpoint(endpoint);
416         return;
417     }
418
419     LOGI("generated token %s", token);
420
421     CAInfo_t requestData = { 0 };
422     requestData.token = token;
423     requestData.tokenLength = tokenLength;
424     requestData.payload = (CAPayload_t) "TempJsonPayload";
425     requestData.payloadSize = strlen((const char *) requestData.payload);
426     requestData.type = CA_MSG_NONCONFIRM;
427
428     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
429     LOGI("resourceUri - %s", strUri);
430     requestData.resourceUri = (CAURI_t)strUri;
431
432     uint8_t optionNum = 2;
433     CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
434                                                              sizeof(CAHeaderOption_t) * optionNum);
435     if (NULL == headerOpt)
436     {
437         LOGE("Memory allocation failed");
438         // destroy remote endpoint
439         CADestroyEndpoint(endpoint);
440         return;
441     }
442
443     char* FirstOptionData = "Hello";
444     headerOpt[0].optionID = 3000;
445     memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
446     headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
447
448     char* SecondOptionData2 = "World";
449     headerOpt[1].optionID = 3001;
450     memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
451     headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
452
453     requestData.numOptions = optionNum;
454     requestData.options = headerOpt;
455
456     CARequestInfo_t requestInfo = { 0 };
457     requestInfo.method = CA_GET;
458     requestInfo.isMulticast = true;
459     requestInfo.info = requestData;
460
461     // send request to all
462     res = CASendRequest(endpoint, &requestInfo);
463     if (CA_STATUS_OK != res)
464     {
465         LOGE("Could not send request to all");
466         //destroy token
467         CADestroyToken(token);
468     }
469     else
470     {
471         CADestroyToken(g_lastRequestToken);
472         g_lastRequestToken = token;
473         g_lastRequestTokenLength = tokenLength;
474     }
475
476     //ReleaseStringUTFChars for strUri
477     (*env)->ReleaseStringUTFChars(env, uri, strUri);
478
479     free(headerOpt);
480
481     // destroy remote endpoint
482     CADestroyEndpoint(endpoint);
483 }
484
485 JNIEXPORT void JNICALL
486 Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
487                                                         jint selectedNetwork,
488                                                         jint isSecured, jint msgType,
489                                                         jint responseValue)
490 {
491     LOGI("RMSendResponse");
492
493     LOGI("selectedNetwork - %d", selectedNetwork);
494
495     CAResult_t res = get_network_type(selectedNetwork);
496     if (CA_STATUS_OK != res)
497     {
498         LOGE("Not supported network type");
499         return;
500     }
501
502     if (NULL == g_clientEndpoint)
503     {
504         LOGE("No Request received");
505         return;
506     }
507
508     CAMessageType_t messageType = msgType;
509
510     CAInfo_t responseData = { 0 };
511     responseData.type = messageType;
512     responseData.messageId = g_clientMsgId;
513     responseData.resourceUri = (CAURI_t)g_resourceUri;
514
515     CAResponseInfo_t responseInfo = { 0 };
516
517     if (msgType != CA_MSG_RESET)
518     {
519         responseData.token = g_clientToken;
520         responseData.tokenLength = g_clientTokenLength;
521         responseInfo.result = responseValue;
522
523         if (1 == isSecured)
524         {
525             uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
526             responseData.payload = (CAPayload_t) malloc(length);
527             sprintf(responseData.payload, SECURE_INFO_DATA, g_resourceUri,
528                     g_localSecurePort);
529             responseData.payloadSize = length;
530         }
531         else
532         {
533             uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
534             responseData.payload = (CAPayload_t) malloc(length);
535             sprintf(responseData.payload, NORMAL_INFO_DATA, g_resourceUri);
536             responseData.payloadSize = length;
537         }
538     }
539     //msgType is RESET
540     else
541     {
542         responseInfo.result = CA_EMPTY;
543     }
544
545     responseInfo.info = responseData;
546
547     // send response
548     res = CASendResponse(g_clientEndpoint, &responseInfo);
549     if (CA_STATUS_OK != res)
550     {
551         LOGE("Could not send response");
552     }
553
554     // destroy token
555     CADestroyToken(g_clientToken);
556     g_clientToken = NULL;
557     g_clientTokenLength = 0;
558
559     // destroy remote endpoint
560     CADestroyEndpoint(g_clientEndpoint);
561     g_clientEndpoint = NULL;
562 }
563
564 JNIEXPORT void JNICALL
565 Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
566                                                             jstring payload, jint selectedNetwork,
567                                                             jint isSecured, jint msgType,
568                                                             jint responseValue)
569 {
570     LOGI("selectedNetwork - %d", selectedNetwork);
571
572     CAResult_t res = get_network_type(selectedNetwork);
573     if (CA_STATUS_OK != res)
574     {
575         LOGE("Not supported network type");
576         return;
577     }
578
579     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
580     LOGI("RMSendNotification - %s", strUri);
581
582     CATransportFlags_t flags;
583     addressSet_t address = {};
584     parsing_coap_uri(strUri, &address, &flags);
585
586     //create remote endpoint
587     CAEndpoint_t* endpoint = NULL;
588     if (CA_STATUS_OK != CACreateEndpoint(flags, g_selectedNwType,
589                                          (const char*)address.ipAddress,
590                                          address.port, &endpoint))
591     {
592         //ReleaseStringUTFChars for strUri
593         (*env)->ReleaseStringUTFChars(env, uri, strUri);
594         LOGE("Could not create remote end point");
595         return;
596     }
597
598     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
599     get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
600
601     //ReleaseStringUTFChars for strUri
602     (*env)->ReleaseStringUTFChars(env, uri, strUri);
603
604     CAMessageType_t messageType = msgType;
605
606     // create token
607     CAToken_t token = NULL;
608     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
609
610     res = CAGenerateToken(&token, tokenLength);
611     if ((CA_STATUS_OK != res) || (!token))
612     {
613         LOGE("token generate error!");
614         CADestroyEndpoint(endpoint);
615         return;
616     }
617
618     CAInfo_t responseData = { 0 };
619     responseData.token = token;
620     responseData.tokenLength = tokenLength;
621     responseData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
622     if (NULL == responseData.resourceUri)
623     {
624         LOGE("Memory allocation failed!");
625         // destroy token
626         CADestroyToken(token);
627         // destroy remote endpoint
628         CADestroyEndpoint(endpoint);
629         return;
630     }
631     memcpy(responseData.resourceUri, resourceURI, sizeof(resourceURI));
632
633     if (1 == isSecured)
634     {
635         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
636         responseData.payload = (CAPayload_t) malloc(length);
637         if (NULL == responseData.payload)
638         {
639             LOGE("Memory allocation failed!");
640             // destroy token
641             CADestroyToken(token);
642             // destroy remote endpoint
643             CADestroyEndpoint(endpoint);
644
645             free(responseData.resourceUri);
646             return;
647         }
648         snprintf(responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
649     }
650     else
651     {
652         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
653         responseData.payload = (CAPayload_t) malloc(length);
654         if (NULL == responseData.payload)
655         {
656             LOGE("Memory allocation failed!");
657             // destroy token
658             CADestroyToken(token);
659             // destroy remote endpoint
660             CADestroyEndpoint(endpoint);
661
662             free(responseData.resourceUri);
663             return;
664         }
665         snprintf(responseData.payload, length, NORMAL_INFO_DATA, resourceURI);
666     }
667
668     responseData.type = messageType;
669
670     CAResponseInfo_t responseInfo = { 0 };
671     responseInfo.result = responseValue;
672     responseInfo.info = responseData;
673
674     // send notification
675     if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
676     {
677         LOGE("Could not send notification");
678     }
679
680     LOGI("Send Notification");
681
682     // destroy token
683     CADestroyToken(token);
684
685     // destroy remote endpoint
686     CADestroyEndpoint(endpoint);
687
688     free(responseData.payload);
689     free(responseData.resourceUri);
690 }
691
692 JNIEXPORT void JNICALL
693 Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
694                                                          jint networkType)
695 {
696     LOGI("RMSelectNetwork Type : %d", networkType);
697
698     if (CA_STATUS_OK != CASelectNetwork(networkType))
699     {
700         LOGE("Could not select network");
701     }
702 }
703
704 JNIEXPORT void JNICALL
705 Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
706                                                            jint networkType)
707 {
708     LOGI("RMUnSelectNetwork Type : %d", networkType);
709
710     if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
711     {
712         LOGE("Could not unselect network");
713     }
714 }
715
716 JNIEXPORT void JNICALL
717 Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
718 {
719     LOGI("RMGetNetworkInfomation");
720
721     CAEndpoint_t *tempInfo = NULL;
722     uint32_t tempSize = 0;
723
724     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
725     if (CA_STATUS_OK != res)
726     {
727         LOGE("Could not start get network information");
728         free(tempInfo);
729         return;
730     }
731
732     LOGI("################## Network Information #######################");
733     callback("######## Network Information", "#######");
734     LOGI("Network info total size is %d", tempSize);
735
736     uint32_t index;
737     for (index = 0; index < tempSize; index++)
738     {
739         res = get_remote_address(tempInfo[index].adapter, tempInfo[index].addr);
740         if (CA_STATUS_OK != res)
741         {
742             free(tempInfo);
743             return;
744         }
745         if (NULL != g_responseListenerObject)
746         {
747             char networkInfo[NETWORK_INFO_LENGTH];
748             LOGI("Type: %d", tempInfo[index].adapter);
749             sprintf(networkInfo, "%d",tempInfo[index].adapter);
750             callback("Type :", networkInfo);
751             if (CA_ADAPTER_IP == tempInfo[index].adapter)
752             {
753                 LOGI("Port: %d", tempInfo[index].port);
754                 sprintf(networkInfo, "%d",tempInfo[index].port);
755                 callback("Port: ", networkInfo);
756             }
757             LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
758             LOGI("Address: %s", g_remoteAddress);
759             callback("Address: ", g_remoteAddress);
760             free(g_remoteAddress);
761         }
762         if (tempInfo[index].flags & CA_SECURE)
763         {
764             g_localSecurePort = tempInfo[index].port;
765         }
766     }
767
768     // free
769     free(tempInfo);
770
771     LOGI("##############################################################");
772 }
773
774 JNIEXPORT void JNICALL
775 Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
776 {
777     LOGI("RMHandleRequestResponse");
778
779     if (CA_STATUS_OK != CAHandleRequestResponse())
780     {
781         LOGE("Could not handle request and response");
782     }
783 }
784
785 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
786 {
787
788     if (!object)
789     {
790         LOGE("Remote endpoint is NULL!");
791         return;
792     }
793
794     if (!requestInfo)
795     {
796         LOGE("Request info is NULL!");
797         return;
798     }
799
800     if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
801             (strncmp(g_lastRequestToken, requestInfo->info.token,
802                      requestInfo->info.tokenLength) == 0))
803     {
804         LOGI("token is same. received request of it's own. skip.. ");
805         return;
806     }
807
808     CAResult_t res = get_remote_address(object->adapter, object->addr);
809     if (CA_STATUS_OK != res)
810     {
811         return;
812     }
813
814     LOGI("##########received request from remote device #############");
815     LOGI("Remote Address: %s", g_remoteAddress);
816     LOGI("Remote Port: %d", object->port);
817     LOGI("Uri: %s", requestInfo->info.resourceUri);
818     LOGI("Data: %s", requestInfo->info.payload);
819     LOGI("Token: %s", requestInfo->info.token);
820     LOGI("Code: %d", requestInfo->method);
821     LOGI("MessageType: %d", requestInfo->info.type);
822
823     if (NULL != g_responseListenerObject)
824     {
825         char *cloneUri = NULL;
826         uint32_t len = 0;
827
828         if (NULL != requestInfo->info.resourceUri)
829         {
830             len = strlen(requestInfo->info.resourceUri);
831             cloneUri = (char *)malloc(sizeof(char) * (len + 1));
832
833             if (NULL == cloneUri)
834             {
835                 LOGE("cloneUri Out of memory");
836                 free(g_remoteAddress);
837                 return;
838             }
839
840             memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
841             callback("Uri: ", cloneUri);
842         }
843
844         len = strlen(g_remoteAddress);
845         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
846
847         if (NULL == cloneRemoteAddress)
848         {
849             LOGE("cloneRemoteAddress Out of memory");
850             free(g_remoteAddress);
851             free(cloneUri);
852             return;
853         }
854
855         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
856
857         callback("Remote Address: ", cloneRemoteAddress);
858         free(cloneRemoteAddress);
859         free(g_remoteAddress);
860
861         char portInfo[PORT_LENGTH] = { 0, };
862         sprintf(portInfo, "%d", object->port);
863         callback("Remote Port: ", portInfo);
864
865         //clone g_clientEndpoint
866         g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
867         if (NULL == g_clientEndpoint)
868         {
869             LOGE("g_clientEndpoint Out of memory");
870             free(cloneUri);
871             return;
872         }
873         memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
874
875         if (NULL != cloneUri)
876         {
877             len = strlen(cloneUri);
878             g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
879             if (NULL == g_resourceUri)
880             {
881                 LOGE("g_clientEndpoint->resourceUri Out of memory");
882                 free(g_clientEndpoint);
883                 free(cloneUri);
884                 return;
885             }
886             memcpy(g_resourceUri, cloneUri, len + 1);
887             free(cloneUri);
888         }
889         //clone g_clientToken
890         len = requestInfo->info.tokenLength;
891
892         g_clientToken = (char *) malloc(sizeof(char) * len);
893         if (NULL == g_clientToken)
894         {
895             LOGE("g_clientToken Out of memory");
896             free(g_clientEndpoint);
897             return;
898         }
899
900         if (NULL != requestInfo->info.token)
901         {
902             memcpy(g_clientToken, requestInfo->info.token, len);
903             g_clientTokenLength = len;
904
905         }
906
907         //clone g_clientMsgId
908         g_clientMsgId = requestInfo->info.messageId;
909
910         if (NULL != requestInfo->info.payload && requestInfo->info.payloadSize > 0)
911         {
912             len = requestInfo->info.payloadSize;
913             char *clonePayload = (char *) malloc(len + 1);
914             if (NULL == clonePayload)
915             {
916                 LOGE("clonePayload Out of memory");
917                 free(g_clientEndpoint);
918                 return;
919             }
920
921             memcpy(clonePayload, requestInfo->info.payload, len);
922             clonePayload[len] = '\0';
923
924             callback("Data: ", clonePayload);
925             free(clonePayload);
926         }
927     }
928
929     if (requestInfo->info.options)
930     {
931         uint32_t len = requestInfo->info.numOptions;
932         uint32_t i;
933
934         LOGI("Option count: %d", requestInfo->info.numOptions);
935
936         for (i = 0; i < len; i++)
937         {
938             LOGI("Option %d", i + 1);
939             LOGI("ID : %d", requestInfo->info.options[i].optionID);
940             LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
941                  requestInfo->info.options[i].optionData);
942
943             if (NULL != g_responseListenerObject)
944             {
945                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
946                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
947                         requestInfo->info.options[i].optionID,
948                         requestInfo->info.options[i].optionLength);
949
950                 callback("Option info: ", optionInfo);
951
952                 size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
953                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
954                 if (NULL == cloneOptionData)
955                 {
956                     LOGE("cloneOptionData Out of memory");
957                     free(g_clientEndpoint);
958                     return;
959                 }
960
961                 memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
962                        optionDataLen + 1);
963
964                 callback("Option Data: ", cloneOptionData);
965                 free(cloneOptionData);
966             }
967         }
968     }
969     LOGI("############################################################");
970
971     //Check if this has secure communication information
972     if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
973     {
974         uint32_t securePort = get_secure_information(requestInfo->info.payload);
975         if (0 < securePort) //Set the remote endpoint secure details and send response
976         {
977             LOGI("This is secure resource...");
978
979             CAEndpoint_t *endpoint = NULL;
980             if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
981                         object->adapter, object->addr, securePort, &endpoint))
982             {
983                 LOGE("Failed to create duplicate of remote endpoint!");
984                 return;
985             }
986             object = endpoint;
987         }
988     }
989 }
990
991 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
992 {
993
994     CAResult_t res = get_remote_address(object->adapter, object->addr);
995     if (CA_STATUS_OK != res)
996     {
997         return;
998     }
999
1000     LOGI("##########Received response from remote device #############");
1001     LOGI("Uri: %s", responseInfo->info.resourceUri);
1002     LOGI("Remote Address: %s", g_remoteAddress);
1003     LOGI("Remote Port: %d", object->port);
1004     LOGI("response result: %d", responseInfo->result);
1005     LOGI("Data: %s", responseInfo->info.payload);
1006     LOGI("Token: %s", responseInfo->info.token);
1007     LOGI("MessageType: %d", responseInfo->info.type);
1008
1009     if (NULL != g_responseListenerObject)
1010     {
1011         uint32_t len = 0;
1012
1013         if (NULL != responseInfo->info.resourceUri)
1014         {
1015             len = strlen(responseInfo->info.resourceUri);
1016             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1017
1018             if (NULL == cloneUri)
1019             {
1020                 LOGE("cloneUri Out of memory");
1021                 free(g_remoteAddress);
1022                 return;
1023             }
1024
1025             memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
1026
1027             callback("Uri: ", cloneUri);
1028             free(cloneUri);
1029         }
1030
1031         len = strlen(g_remoteAddress);
1032         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1033
1034         if (NULL == cloneRemoteAddress)
1035         {
1036             LOGE("cloneRemoteAddress Out of memory");
1037             free(g_remoteAddress);
1038             return;
1039         }
1040
1041         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1042
1043         callback("Remote Address: ", cloneRemoteAddress);
1044         free(cloneRemoteAddress);
1045         free(g_remoteAddress);
1046
1047         char portInfo[PORT_LENGTH] = { 0, };
1048         sprintf(portInfo, "%d", object->port);
1049         callback("Remote Port: ", portInfo);
1050
1051         if (NULL != responseInfo->info.payload && responseInfo->info.payloadSize)
1052         {
1053             len = responseInfo->info.payloadSize;
1054             char *clonePayload = (char *) malloc(len + 1);
1055             if (NULL == clonePayload)
1056             {
1057                 LOGE("clonePayload Out of memory");
1058                 return;
1059             }
1060
1061             memcpy(clonePayload, responseInfo->info.payload, len);
1062             clonePayload[len] = '\0';
1063
1064             callback("Data: ", clonePayload);
1065             free(clonePayload);
1066         }
1067     }
1068
1069     if (responseInfo->info.options)
1070     {
1071         uint32_t len = responseInfo->info.numOptions;
1072         uint32_t i;
1073         for (i = 0; i < len; i++)
1074         {
1075             LOGI("Option %d", i + 1);
1076             LOGI("ID : %d", responseInfo->info.options[i].optionID);
1077             LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1078                  responseInfo->info.options[i].optionData);
1079
1080             if (NULL != g_responseListenerObject)
1081             {
1082                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1083                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1084                         responseInfo->info.options[i].optionID,
1085                         responseInfo->info.options[i].optionLength);
1086
1087                 callback("Option info: ", optionInfo);
1088
1089                 size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1090                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1091                 if (NULL == cloneOptionData)
1092                 {
1093                     LOGE("cloneOptionData Out of memory");
1094                     return;
1095                 }
1096                 memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1097                        optionDataLen + 1);
1098                 callback("Option Data: ", cloneOptionData);
1099                 free(cloneOptionData);
1100             }
1101         }
1102     }
1103     LOGI("############################################################");
1104
1105     //Check if this has secure communication information
1106     if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1107     {
1108         uint32_t securePort = get_secure_information(responseInfo->info.payload);
1109         if (0 < securePort) //Set the remote endpoint secure details and send response
1110         {
1111             LOGI("This is secure resource...");
1112         }
1113     }
1114 }
1115
1116 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1117 {
1118     printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
1119
1120     if(errorInfo)
1121     {
1122         const CAInfo_t *info = &errorInfo->info;
1123         LOGI("Error Handler, ErrorInfo :");
1124         LOGI("Error Handler result    : %d", errorInfo->result);
1125         LOGI("Error Handler token     : %s", info->token);
1126         LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
1127         LOGI("Error Handler resourceUri : %s", info->resourceUri);
1128         LOGI("Error Handler type      : %d", info->type);
1129         LOGI("Error Handler payload   : %s", info->payload);
1130
1131         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1132         {
1133             LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
1134         }
1135         else if(CA_SEND_FAILED == errorInfo->result)
1136         {
1137             LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
1138         }
1139         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1140         {
1141             LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
1142         }
1143         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1144         {
1145             LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
1146         }
1147         else if(CA_STATUS_FAILED == errorInfo->result)
1148         {
1149             LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
1150         }
1151     }
1152     LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
1153
1154     return;
1155 }
1156
1157 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length)
1158 {
1159     const char *startPos = URI;
1160     const char *temp = strstr(URI, "://");
1161     if (NULL != temp)
1162     {
1163         startPos = strchr(temp + 3, '/');
1164         if (!startPos)
1165         {
1166             LOGE("Resource URI is missing");
1167             return;
1168         }
1169     }
1170
1171     const char *endPos = strchr(startPos, '?');
1172     if (!endPos)
1173     {
1174         endPos = URI + strlen(URI);
1175     }
1176     --endPos;
1177
1178     if (endPos - startPos <= length)
1179     {
1180         memcpy(resourceURI, startPos + 1, endPos - startPos);
1181     }
1182
1183     LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1184 }
1185
1186 uint32_t get_secure_information(CAPayload_t payLoad)
1187 {
1188     LOGI("entering get_secure_information");
1189
1190     if (!payLoad)
1191     {
1192         LOGE("Payload is NULL");
1193         return -1;
1194     }
1195
1196     const char *subString = NULL;
1197     if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
1198     {
1199         LOGE("This is not secure resource");
1200         return -1;
1201     }
1202
1203     if (NULL == (subString = strstr(payLoad, "\"port\":")))
1204     {
1205         LOGE("This secure resource does not have port information");
1206         return -1;
1207     }
1208
1209     const char *startPos = strstr(subString, ":");
1210     if (!startPos)
1211     {
1212         LOGE("Parsing failed !");
1213         return -1;
1214     }
1215
1216     const char *endPos = strstr(startPos, "}");
1217     if (!endPos)
1218     {
1219         LOGE("Parsing failed !");
1220         return -1;
1221     }
1222
1223     char portStr[6] = { 0 };
1224     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1225
1226     LOGI("secured port is: %s", portStr);
1227     return atoi(portStr);
1228 }
1229
1230 CAResult_t get_network_type(uint32_t selectedNetwork)
1231 {
1232
1233     uint32_t number = selectedNetwork;
1234
1235     if (!(number & 0xf))
1236     {
1237         return CA_NOT_SUPPORTED;
1238     }
1239     if (number & CA_ADAPTER_IP)
1240     {
1241         g_selectedNwType = CA_ADAPTER_IP;
1242         return CA_STATUS_OK;
1243     }
1244     if (number & CA_ADAPTER_RFCOMM_BTEDR)
1245     {
1246         g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
1247         return CA_STATUS_OK;
1248     }
1249     if (number & CA_ADAPTER_GATT_BTLE)
1250     {
1251         g_selectedNwType = CA_ADAPTER_GATT_BTLE;
1252         return CA_STATUS_OK;
1253     }
1254
1255     return CA_NOT_SUPPORTED;
1256 }
1257
1258 void callback(char *subject, char *receivedData)
1259 {
1260     JNIEnv* env = NULL;
1261     uint32_t status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6);
1262     uint32_t res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1263
1264     jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1265     jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1266                                         "(Ljava/lang/String;Ljava/lang/String;)V");
1267
1268     jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1269     jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1270     (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1271
1272 }
1273
1274 CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address)
1275 {
1276     uint32_t len = strlen(address);
1277
1278     g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
1279     if (NULL == g_remoteAddress)
1280     {
1281         LOGE("g_remoteAddress Out of memory");
1282         return CA_MEMORY_ALLOC_FAILED;
1283     }
1284
1285     memcpy(g_remoteAddress, address, len + 1);
1286
1287     return CA_STATUS_OK;
1288 }
1289
1290
1291 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1292 {
1293     if (NULL == uri || NULL == address)
1294     {
1295         LOGE("parameter is null");
1296         return;
1297     }
1298
1299     // parse uri
1300     // #1. check prefix
1301     uint8_t startIndex = 0;
1302     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1303     {
1304         LOGI("uri has '%s' prefix", COAPS_PREFIX);
1305         startIndex = COAPS_PREFIX_LEN;
1306         *flags = CA_SECURE;
1307     }
1308     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1309     {
1310         LOGI("uri has '%s' prefix", COAP_PREFIX);
1311         startIndex = COAP_PREFIX_LEN;
1312         *flags = CA_IPV4;
1313     }
1314
1315     // #2. copy uri for parse
1316     int32_t len = strlen(uri) - startIndex;
1317
1318     if (len <= 0)
1319     {
1320         LOGE("uri length is 0!");
1321         return;
1322     }
1323
1324     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1325     if (NULL == cloneUri)
1326     {
1327         LOGE("Out of memory");
1328         return;
1329     }
1330
1331     memcpy(cloneUri, &uri[startIndex], sizeof(char) * len);
1332     cloneUri[len] = '\0';
1333
1334     char *pAddress = cloneUri;
1335     char *pResourceUri = NULL;
1336
1337     int32_t i = 0;
1338     for (i = 0; i < len; i++)
1339     {
1340         if (cloneUri[i] == '/')
1341         {
1342             // separate
1343             cloneUri[i] = 0;
1344             pResourceUri = &cloneUri[i + 1];
1345             break;
1346         }
1347     }
1348     LOGI("pAddress : %s", pAddress);
1349
1350     int res = get_address_set(pAddress, address);
1351     if (res == -1)
1352     {
1353         LOGE("address parse error");
1354
1355         free(cloneUri);
1356         return;
1357     }
1358     return;
1359 }
1360
1361 int get_address_set(const char *pAddress, addressSet_t* outAddress)
1362 {
1363     if (NULL == pAddress || NULL == outAddress)
1364     {
1365         LOGE("parameter is null");
1366         return -1;
1367     }
1368
1369     int32_t len = strlen(pAddress);
1370     int32_t isIp = 0;
1371     int32_t ipLen = 0;
1372
1373     int32_t i = 0;
1374     for (i = 0; i < len; i++)
1375     {
1376         if (pAddress[i] == '.')
1377         {
1378             isIp = 1;
1379         }
1380
1381         // found port number start index
1382         if (isIp && pAddress[i] == ':')
1383         {
1384             ipLen = i;
1385             break;
1386         }
1387     }
1388
1389     if (isIp)
1390     {
1391         if(ipLen && ipLen < sizeof(outAddress->ipAddress))
1392         {
1393             strncpy(outAddress->ipAddress, pAddress, ipLen);
1394             outAddress->ipAddress[ipLen] = '\0';
1395         }
1396         else if (!ipLen && len < sizeof(outAddress->ipAddress))
1397         {
1398             strncpy(outAddress->ipAddress, pAddress, len);
1399             outAddress->ipAddress[len] = '\0';
1400         }
1401         else
1402         {
1403             LOGE("IP Address too long: %d", ipLen==0 ? len : ipLen);
1404             return -1;
1405         }
1406
1407         if (ipLen > 0)
1408         {
1409             outAddress->port = atoi(pAddress + ipLen + 1);
1410         }
1411     }
1412     else
1413     {
1414         strncpy(outAddress->ipAddress, pAddress, len);
1415         outAddress->ipAddress[len] = '\0';
1416     }
1417
1418     return isIp;
1419 }