remove unnecessary code in caipserver
[platform/upstream/iotivity.git] / resource / csdk / connectivity / samples / android / sample_service / 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 uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
34
35 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo);
36 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo);
37 void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
38 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length);
39 uint32_t get_secure_information(CAPayload_t payLoad);
40 CAResult_t get_network_type(uint32_t selectedNetwork);
41 void callback(char *subject, char *receivedData);
42 CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address);
43
44 CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP;
45 static CAToken_t g_lastRequestToken = NULL;
46 static uint8_t g_lastRequestTokenLength = 0;
47
48 static const char COAP_PREFIX[] =  "coap://";
49 static const char COAPS_PREFIX[] = "coaps://";
50 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
51 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
52
53 static const char SECURE_INFO_DATA[]
54                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
55                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
56                                      "%d}}]}";
57 static const char NORMAL_INFO_DATA[]
58                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
59                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
60
61 static jobject g_responseListenerObject = NULL;
62 static JavaVM *g_jvm;
63
64 static CAEndpoint_t *g_clientEndpoint = NULL;
65 static char *g_resourceUri = NULL;
66 static CAToken_t g_clientToken = NULL;
67 static uint8_t g_clientTokenLength = 0;
68
69 static uint16_t g_clientMsgId = 0;
70 static char *g_remoteAddress = NULL;
71
72 typedef struct
73 {
74     char ipAddress[CA_IPADDR_SIZE];
75     uint16_t port;
76 } addressSet_t;
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     addressSet_t address = {};
278     parsing_coap_uri(strUri, &address);
279
280     //create remote endpoint
281     CAEndpoint_t* endpoint = NULL;
282     res = CACreateEndpoint(CA_DEFAULT_FLAGS, g_selectedNwType, (const char*)address.ipAddress,
283                            address.port, &endpoint);
284     if (CA_STATUS_OK != res)
285     {
286         LOGE("Could not create remote end point");
287         (*env)->ReleaseStringUTFChars(env, uri, strUri);
288         return;
289     }
290
291     CAMessageType_t messageType = msgType;
292
293     // create token
294     CAToken_t token = NULL;
295     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
296
297     res = CAGenerateToken(&token, tokenLength);
298     if ((CA_STATUS_OK != res) || (!token))
299     {
300         LOGE("token generate error!!");
301         // destroy remote endpoint
302         CADestroyEndpoint(endpoint);
303         (*env)->ReleaseStringUTFChars(env, uri, strUri);
304         return;
305     }
306
307     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
308
309     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
310     (*env)->ReleaseStringUTFChars(env, uri, strUri);
311
312     CAInfo_t requestData = { 0 };
313     requestData.token = token;
314     requestData.tokenLength = tokenLength;
315
316     if (1 == isSecured)
317     {
318         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
319         requestData.payload = (CAPayload_t) malloc(length);
320         if (NULL == requestData.payload)
321         {
322             LOGE("Memory allocation failed!");
323             // destroy token
324             CADestroyToken(token);
325             // destroy remote endpoint
326             CADestroyEndpoint(endpoint);
327             return;
328         }
329         snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
330     }
331     else
332     {
333         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
334         requestData.payload = (CAPayload_t) malloc(length);
335         if (NULL == requestData.payload)
336         {
337             LOGE("Memory allocation failed!");
338             // destroy token
339             CADestroyToken(token);
340             // destroy remote endpoint
341             CADestroyEndpoint(endpoint);
342             return;
343         }
344         snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
345     }
346
347     requestData.type = messageType;
348     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
349     if (NULL == requestData.resourceUri)
350     {
351         LOGE("Memory allocation failed!");
352         // destroy token
353         CADestroyToken(token);
354         // destroy remote endpoint
355         CADestroyEndpoint(endpoint);
356         free(requestData.payload);
357         return;
358     }
359     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
360
361     CARequestInfo_t requestInfo = { 0 };
362     requestInfo.method = CA_GET;
363     requestInfo.isMulticast = false;
364     requestInfo.info = requestData;
365
366     // send request
367     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
368     {
369         LOGE("Could not send request");
370     }
371
372     // destroy token
373     CADestroyToken(token);
374
375     // destroy remote endpoint
376     CADestroyEndpoint(endpoint);
377
378     free(requestData.payload);
379     free(requestData.resourceUri);
380 }
381
382 JNIEXPORT void JNICALL
383 Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
384                                                            jint selectedNetwork)
385 {
386     LOGI("selectedNetwork - %d", selectedNetwork);
387     CAResult_t res = get_network_type(selectedNetwork);
388     if (CA_STATUS_OK != res)
389     {
390         return;
391     }
392
393     // create remote endpoint
394     CAEndpoint_t *endpoint = NULL;
395     res = CACreateEndpoint(CA_DEFAULT_FLAGS, g_selectedNwType, NULL, 0, &endpoint);
396
397     if (CA_STATUS_OK != res)
398     {
399         LOGE("create remote endpoint error, error code: %d", res);
400         return;
401     }
402
403     // create token
404     CAToken_t token = NULL;
405     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
406
407     res = CAGenerateToken(&token, tokenLength);
408     if ((CA_STATUS_OK != res) || (!token))
409     {
410         LOGE("token generate error!!");
411         // destroy remote endpoint
412         CADestroyEndpoint(endpoint);
413         return;
414     }
415
416     LOGI("generated token %s", token);
417
418     CAInfo_t requestData = { 0 };
419     requestData.token = token;
420     requestData.tokenLength = tokenLength;
421     requestData.payload = "Temp Json Payload";
422     requestData.type = CA_MSG_NONCONFIRM;
423
424     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
425     LOGI("resourceUri - %s", strUri);
426     requestData.resourceUri = (CAURI_t)strUri;
427
428     uint8_t optionNum = 2;
429     CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
430                                                              sizeof(CAHeaderOption_t) * optionNum);
431     if (NULL == headerOpt)
432     {
433         LOGE("Memory allocation failed");
434         return;
435     }
436
437     char* FirstOptionData = "Hello";
438     headerOpt[0].optionID = 3000;
439     memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
440     headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
441
442     char* SecondOptionData2 = "World";
443     headerOpt[1].optionID = 3001;
444     memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
445     headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
446
447     requestData.numOptions = optionNum;
448     requestData.options = headerOpt;
449
450     CARequestInfo_t requestInfo = { 0 };
451     requestInfo.method = CA_GET;
452     requestInfo.isMulticast = true;
453     requestInfo.info = requestData;
454
455     // send request to all
456     res = CASendRequest(endpoint, &requestInfo);
457     if (CA_STATUS_OK != res)
458     {
459         LOGE("Could not send request to all");
460         //destroy token
461         CADestroyToken(token);
462     }
463     else
464     {
465         CADestroyToken(g_lastRequestToken);
466         g_lastRequestToken = token;
467         g_lastRequestTokenLength = tokenLength;
468     }
469
470     //ReleaseStringUTFChars for strUri
471     (*env)->ReleaseStringUTFChars(env, uri, strUri);
472
473     free(headerOpt);
474
475     // destroy remote endpoint
476     CADestroyEndpoint(endpoint);
477 }
478
479 JNIEXPORT void JNICALL
480 Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
481                                                         jint selectedNetwork,
482                                                         jint isSecured, jint msgType,
483                                                         jint responseValue)
484 {
485     LOGI("RMSendResponse");
486
487     LOGI("selectedNetwork - %d", selectedNetwork);
488
489     CAResult_t res = get_network_type(selectedNetwork);
490     if (CA_STATUS_OK != res)
491     {
492         LOGE("Not supported network type");
493         return;
494     }
495
496     if (NULL == g_clientEndpoint)
497     {
498         LOGE("No Request received");
499         return;
500     }
501
502     CAMessageType_t messageType = msgType;
503
504     CAInfo_t responseData = { 0 };
505     responseData.type = messageType;
506     responseData.messageId = g_clientMsgId;
507     responseData.resourceUri = (CAURI_t)g_resourceUri;
508
509     CAResponseInfo_t responseInfo = { 0 };
510
511     if (msgType != CA_MSG_RESET)
512     {
513         responseData.token = g_clientToken;
514         responseData.tokenLength = g_clientTokenLength;
515         responseInfo.result = responseValue;
516
517         if (1 == isSecured)
518         {
519             uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
520             responseData.payload = (CAPayload_t) malloc(length);
521             sprintf(responseData.payload, SECURE_INFO_DATA, g_resourceUri,
522                     g_localSecurePort);
523         }
524         else
525         {
526             uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
527             responseData.payload = (CAPayload_t) malloc(length);
528             sprintf(responseData.payload, NORMAL_INFO_DATA, g_resourceUri);
529         }
530     }
531     //msgType is RESET
532     else
533     {
534         responseInfo.result = CA_EMPTY;
535     }
536
537     responseInfo.info = responseData;
538
539     // send response
540     res = CASendResponse(g_clientEndpoint, &responseInfo);
541     if (CA_STATUS_OK != res)
542     {
543         LOGE("Could not send response");
544     }
545
546     // destroy token
547     CADestroyToken(g_clientToken);
548     g_clientToken = NULL;
549     g_clientTokenLength = 0;
550
551     // destroy remote endpoint
552     CADestroyEndpoint(g_clientEndpoint);
553     g_clientEndpoint = NULL;
554 }
555
556 JNIEXPORT void JNICALL
557 Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
558                                                             jstring payload, jint selectedNetwork,
559                                                             jint isSecured, jint msgType,
560                                                             jint responseValue)
561 {
562     LOGI("selectedNetwork - %d", selectedNetwork);
563
564     CAResult_t res = get_network_type(selectedNetwork);
565     if (CA_STATUS_OK != res)
566     {
567         LOGE("Not supported network type");
568         return;
569     }
570
571     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
572     LOGI("RMSendNotification - %s", strUri);
573
574     addressSet_t address = {};
575     parsing_coap_uri(strUri, &address);
576
577     //create remote endpoint
578     CAEndpoint_t* endpoint = NULL;
579     if (CA_STATUS_OK != CACreateEndpoint(CA_DEFAULT_FLAGS, g_selectedNwType,
580                                          (const char*)address.ipAddress,
581                                          address.port, &endpoint))
582     {
583         //ReleaseStringUTFChars for strUri
584         (*env)->ReleaseStringUTFChars(env, uri, strUri);
585         LOGE("Could not create remote end point");
586         return;
587     }
588
589     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
590     get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
591
592     //ReleaseStringUTFChars for strUri
593     (*env)->ReleaseStringUTFChars(env, uri, strUri);
594
595     CAMessageType_t messageType = msgType;
596
597     // create token
598     CAToken_t token = NULL;
599     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
600
601     res = CAGenerateToken(&token, tokenLength);
602     if ((CA_STATUS_OK != res) || (!token))
603     {
604         LOGE("token generate error!");
605         CADestroyEndpoint(endpoint);
606         return;
607     }
608
609     CAInfo_t responseData = { 0 };
610     responseData.token = token;
611     responseData.tokenLength = tokenLength;
612     responseData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
613     if (NULL == responseData.resourceUri)
614     {
615         LOGE("Memory allocation failed!");
616         // destroy token
617         CADestroyToken(token);
618         // destroy remote endpoint
619         CADestroyEndpoint(endpoint);
620         return;
621     }
622     memcpy(responseData.resourceUri, resourceURI, sizeof(resourceURI));
623
624     if (1 == isSecured)
625     {
626         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
627         responseData.payload = (CAPayload_t) malloc(length);
628         if (NULL == responseData.payload)
629         {
630             LOGE("Memory allocation failed!");
631             // destroy token
632             CADestroyToken(token);
633             // destroy remote endpoint
634             CADestroyEndpoint(endpoint);
635
636             free(responseData.resourceUri);
637             return;
638         }
639         snprintf(responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort);
640     }
641     else
642     {
643         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
644         responseData.payload = (CAPayload_t) malloc(length);
645         if (NULL == responseData.payload)
646         {
647             LOGE("Memory allocation failed!");
648             // destroy token
649             CADestroyToken(token);
650             // destroy remote endpoint
651             CADestroyEndpoint(endpoint);
652
653             free(responseData.resourceUri);
654             return;
655         }
656         snprintf(responseData.payload, length, NORMAL_INFO_DATA, resourceURI);
657     }
658
659     responseData.type = messageType;
660
661     CAResponseInfo_t responseInfo = { 0 };
662     responseInfo.result = responseValue;
663     responseInfo.info = responseData;
664
665     // send notification
666     if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
667     {
668         LOGE("Could not send notification");
669     }
670
671     LOGI("Send Notification");
672
673     // destroy token
674     CADestroyToken(token);
675
676     // destroy remote endpoint
677     CADestroyEndpoint(endpoint);
678
679     free(responseData.payload);
680     free(responseData.resourceUri);
681 }
682
683 JNIEXPORT void JNICALL
684 Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
685                                                          jint networkType)
686 {
687     LOGI("RMSelectNetwork Type : %d", networkType);
688
689     if (CA_STATUS_OK != CASelectNetwork(networkType))
690     {
691         LOGE("Could not select network");
692     }
693 }
694
695 JNIEXPORT void JNICALL
696 Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
697                                                            jint networkType)
698 {
699     LOGI("RMUnSelectNetwork Type : %d", networkType);
700
701     if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
702     {
703         LOGE("Could not unselect network");
704     }
705 }
706
707 JNIEXPORT void JNICALL
708 Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
709 {
710     LOGI("RMGetNetworkInfomation");
711
712     CAEndpoint_t *tempInfo = NULL;
713     uint32_t tempSize = 0;
714
715     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
716     if (CA_STATUS_OK != res)
717     {
718         LOGE("Could not start get network information");
719         free(tempInfo);
720         return;
721     }
722
723     LOGI("################## Network Information #######################");
724     callback("######## Network Information", "#######");
725     LOGI("Network info total size is %d", tempSize);
726
727     uint32_t index;
728     for (index = 0; index < tempSize; index++)
729     {
730         res = get_remote_address(tempInfo[index].adapter, tempInfo[index].addr);
731         if (CA_STATUS_OK != res)
732         {
733             free(tempInfo);
734             return;
735         }
736         if (NULL != g_responseListenerObject)
737         {
738             char networkInfo[NETWORK_INFO_LENGTH];
739             LOGI("Type: %d", tempInfo[index].adapter);
740             sprintf(networkInfo, "%d",tempInfo[index].adapter);
741             callback("Type :", networkInfo);
742             if (CA_ADAPTER_IP == tempInfo[index].adapter)
743             {
744                 LOGI("Port: %d", tempInfo[index].port);
745                 sprintf(networkInfo, "%d",tempInfo[index].port);
746                 callback("Port: ", networkInfo);
747             }
748             LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
749             LOGI("Address: %s", g_remoteAddress);
750             callback("Address: ", g_remoteAddress);
751             free(g_remoteAddress);
752         }
753         if (tempInfo[index].flags & CA_SECURE)
754         {
755             g_localSecurePort = tempInfo[index].port;
756         }
757     }
758
759     // free
760     free(tempInfo);
761
762     LOGI("##############################################################");
763 }
764
765 JNIEXPORT void JNICALL
766 Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
767 {
768     LOGI("RMHandleRequestResponse");
769
770     if (CA_STATUS_OK != CAHandleRequestResponse())
771     {
772         LOGE("Could not handle request and response");
773     }
774 }
775
776 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
777 {
778
779     if (!object)
780     {
781         LOGE("Remote endpoint is NULL!");
782         return;
783     }
784
785     if (!requestInfo)
786     {
787         LOGE("Request info is NULL!");
788         return;
789     }
790
791     if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
792             (strncmp(g_lastRequestToken, requestInfo->info.token,
793                      requestInfo->info.tokenLength) == 0))
794     {
795         LOGI("token is same. received request of it's own. skip.. ");
796         return;
797     }
798
799     CAResult_t res = get_remote_address(object->adapter, object->addr);
800     if (CA_STATUS_OK != res)
801     {
802         return;
803     }
804
805     LOGI("##########received request from remote device #############");
806     LOGI("Remote Address: %s", g_remoteAddress);
807     LOGI("Uri: %s", requestInfo->info.resourceUri);
808     LOGI("Data: %s", requestInfo->info.payload);
809     LOGI("Token: %s", requestInfo->info.token);
810     LOGI("Code: %d", requestInfo->method);
811     LOGI("MessageType: %d", requestInfo->info.type);
812
813     if (NULL != g_responseListenerObject)
814     {
815         callback("received request from remote device", "#######");
816         char *cloneUri = NULL;
817         uint32_t len = 0;
818
819         if (NULL != requestInfo->info.resourceUri)
820         {
821             len = strlen(requestInfo->info.resourceUri);
822             cloneUri = (char *)malloc(sizeof(char) * (len + 1));
823
824             if (NULL == cloneUri)
825             {
826                 LOGE("cloneUri Out of memory");
827                 free(g_remoteAddress);
828                 return;
829             }
830
831             memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
832             callback("Uri: ", cloneUri);
833         }
834
835         len = strlen(g_remoteAddress);
836         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
837
838         if (NULL == cloneRemoteAddress)
839         {
840             LOGE("cloneRemoteAddress Out of memory");
841             free(g_remoteAddress);
842             free(cloneUri);
843             return;
844         }
845
846         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
847
848         callback("Remote Address: ", cloneRemoteAddress);
849         free(cloneRemoteAddress);
850         free(g_remoteAddress);
851
852         //clone g_clientEndpoint
853         g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
854         if (NULL == g_clientEndpoint)
855         {
856             LOGE("g_clientEndpoint Out of memory");
857             free(cloneUri);
858             return;
859         }
860         memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
861
862         if (NULL != cloneUri)
863         {
864             len = strlen(cloneUri);
865             g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
866             if (NULL == g_resourceUri)
867             {
868                 LOGE("g_clientEndpoint->resourceUri Out of memory");
869                 free(g_clientEndpoint);
870                 free(cloneUri);
871                 return;
872             }
873             memcpy(g_resourceUri, cloneUri, len + 1);
874             free(cloneUri);
875         }
876         //clone g_clientToken
877         len = requestInfo->info.tokenLength;
878
879         g_clientToken = (char *) malloc(sizeof(char) * len);
880         if (NULL == g_clientToken)
881         {
882             LOGE("g_clientToken Out of memory");
883             free(g_clientEndpoint);
884             return;
885         }
886
887         if (NULL != requestInfo->info.token)
888         {
889             memcpy(g_clientToken, requestInfo->info.token, len);
890             g_clientTokenLength = len;
891
892         }
893
894         //clone g_clientMsgId
895         g_clientMsgId = requestInfo->info.messageId;
896
897         if (NULL != requestInfo->info.payload)
898         {
899             len = strlen(requestInfo->info.payload);
900             char *clonePayload = (char *) malloc(sizeof(char) * (len + 1));
901
902             if (NULL == clonePayload)
903             {
904                 LOGE("clonePayload Out of memory");
905                 free(g_clientEndpoint);
906                 return;
907             }
908
909             memcpy(clonePayload, requestInfo->info.payload, len + 1);
910
911             callback("Data: ", clonePayload);
912             free(clonePayload);
913         }
914     }
915
916     if (requestInfo->info.options)
917     {
918         uint32_t len = requestInfo->info.numOptions;
919         uint32_t i;
920
921         LOGI("Option count: %d", requestInfo->info.numOptions);
922
923         for (i = 0; i < len; i++)
924         {
925             LOGI("Option %d", i + 1);
926             LOGI("ID : %d", requestInfo->info.options[i].optionID);
927             LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
928                  requestInfo->info.options[i].optionData);
929
930             if (NULL != g_responseListenerObject)
931             {
932                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
933                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
934                         requestInfo->info.options[i].optionID,
935                         requestInfo->info.options[i].optionLength);
936
937                 callback("Option info: ", optionInfo);
938
939                 size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
940                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
941                 if (NULL == cloneOptionData)
942                 {
943                     LOGE("cloneOptionData Out of memory");
944                     free(g_clientEndpoint);
945                     return;
946                 }
947
948                 memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
949                        optionDataLen + 1);
950
951                 callback("Option Data: ", cloneOptionData);
952                 free(cloneOptionData);
953             }
954         }
955     }
956     LOGI("############################################################");
957
958     //Check if this has secure communication information
959     if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
960     {
961         uint32_t securePort = get_secure_information(requestInfo->info.payload);
962         if (0 < securePort) //Set the remote endpoint secure details and send response
963         {
964             LOGI("This is secure resource...");
965             char *uri = NULL;
966             uint32_t length = 0;
967
968             length = COAPS_PREFIX_LEN; //length of "coaps://"
969             // length of "ipaddress:port"
970             length += strlen(object->addr) + PORT_LENGTH;
971             length += strlen(requestInfo->info.resourceUri) + 1;
972
973             uri = calloc(1, sizeof(char) * length);
974             if (!uri)
975             {
976                 LOGE("Failed to create new uri");
977                 free(uri);
978                 return;
979             }
980             sprintf(uri, "%s%s:%d/%s", COAPS_PREFIX, object->addr,
981                     securePort, requestInfo->info.resourceUri);
982
983             CAEndpoint_t *endpoint = NULL;
984             if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
985                         object->adapter, object->addr, securePort, &endpoint))
986             {
987                 LOGE("Failed to create duplicate of remote endpoint!");
988                 free(uri);
989                 return;
990             }
991             object = endpoint;
992
993             free(uri);
994         }
995     }
996 }
997
998 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
999 {
1000
1001     CAResult_t res = get_remote_address(object->adapter, object->addr);
1002     if (CA_STATUS_OK != res)
1003     {
1004         return;
1005     }
1006
1007     LOGI("##########Received response from remote device #############");
1008     LOGI("Uri: %s", responseInfo->info.resourceUri);
1009     LOGI("Remote Address: %s", g_remoteAddress);
1010     LOGI("response result: %d", responseInfo->result);
1011     LOGI("Data: %s", responseInfo->info.payload);
1012     LOGI("Token: %s", responseInfo->info.token);
1013     LOGI("MessageType: %d", responseInfo->info.type);
1014
1015     if (NULL != g_responseListenerObject)
1016     {
1017         uint32_t len = 0;
1018
1019         if (NULL != responseInfo->info.resourceUri)
1020         {
1021             len = strlen(responseInfo->info.resourceUri);
1022             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1023
1024             if (NULL == cloneUri)
1025             {
1026                 LOGE("cloneUri Out of memory");
1027                 free(g_remoteAddress);
1028                 return;
1029             }
1030
1031             memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
1032
1033             callback("Uri: ", cloneUri);
1034             free(cloneUri);
1035         }
1036
1037         len = strlen(g_remoteAddress);
1038         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1039
1040         if (NULL == cloneRemoteAddress)
1041         {
1042             LOGE("cloneRemoteAddress Out of memory");
1043             free(g_remoteAddress);
1044             return;
1045         }
1046
1047         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1048
1049         callback("Remote Address: ", cloneRemoteAddress);
1050         free(cloneRemoteAddress);
1051         free(g_remoteAddress);
1052
1053         if (NULL != responseInfo->info.payload)
1054         {
1055             len = strlen(responseInfo->info.payload);
1056             char *clonePayload = (char *) malloc(sizeof(char) * (len + 1));
1057
1058             if (NULL == clonePayload)
1059             {
1060                 LOGE("clonePayload Out of memory");
1061                 return;
1062             }
1063
1064             memcpy(clonePayload, responseInfo->info.payload, len + 1);
1065
1066             callback("Data: ", clonePayload);
1067             free(clonePayload);
1068         }
1069     }
1070
1071     if (responseInfo->info.options)
1072     {
1073         uint32_t len = responseInfo->info.numOptions;
1074         uint32_t i;
1075         for (i = 0; i < len; i++)
1076         {
1077             LOGI("Option %d", i + 1);
1078             LOGI("ID : %d", responseInfo->info.options[i].optionID);
1079             LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1080                  responseInfo->info.options[i].optionData);
1081
1082             if (NULL != g_responseListenerObject)
1083             {
1084                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1085                 sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1,
1086                         responseInfo->info.options[i].optionID,
1087                         responseInfo->info.options[i].optionLength);
1088
1089                 callback("Option info: ", optionInfo);
1090
1091                 size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1092                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1093                 if (NULL == cloneOptionData)
1094                 {
1095                     LOGE("cloneOptionData Out of memory");
1096                     return;
1097                 }
1098                 memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1099                        optionDataLen + 1);
1100                 callback("Option Data: ", cloneOptionData);
1101                 free(cloneOptionData);
1102             }
1103         }
1104     }
1105     LOGI("############################################################");
1106
1107     //Check if this has secure communication information
1108     if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1109     {
1110         uint32_t securePort = get_secure_information(responseInfo->info.payload);
1111         if (0 < securePort) //Set the remote endpoint secure details and send response
1112         {
1113             LOGI("This is secure resource...");
1114         }
1115     }
1116 }
1117
1118 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1119 {
1120     printf("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
1121
1122     if(errorInfo)
1123     {
1124         const CAInfo_t *info = &errorInfo->info;
1125         LOGI("Error Handler, ErrorInfo :");
1126         LOGI("Error Handler result    : %d", errorInfo->result);
1127         LOGI("Error Handler token     : %s", info->token);
1128         LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
1129         LOGI("Error Handler resourceUri : %s", info->resourceUri);
1130         LOGI("Error Handler type      : %d", info->type);
1131         LOGI("Error Handler payload   : %s", info->payload);
1132
1133         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1134         {
1135             LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
1136         }
1137         else if(CA_SEND_FAILED == errorInfo->result)
1138         {
1139             LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
1140         }
1141         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1142         {
1143             LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
1144         }
1145         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1146         {
1147             LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
1148         }
1149         else if(CA_STATUS_FAILED == errorInfo->result)
1150         {
1151             LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
1152         }
1153     }
1154     LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
1155
1156     return;
1157 }
1158
1159 void get_resource_uri(const char *URI, char *resourceURI, uint32_t length)
1160 {
1161     const char *startPos = URI;
1162     const char *temp = strstr(URI, "://");
1163     if (NULL != temp)
1164     {
1165         startPos = strchr(temp + 3, '/');
1166         if (!startPos)
1167         {
1168             LOGE("Resource URI is missing");
1169             return;
1170         }
1171     }
1172
1173     const char *endPos = strchr(startPos, '?');
1174     if (!endPos)
1175     {
1176         endPos = URI + strlen(URI);
1177     }
1178     --endPos;
1179
1180     if (endPos - startPos <= length)
1181     {
1182         memcpy(resourceURI, startPos + 1, endPos - startPos);
1183     }
1184
1185     LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1186 }
1187
1188 uint32_t get_secure_information(CAPayload_t payLoad)
1189 {
1190     LOGI("entering get_secure_information");
1191
1192     if (!payLoad)
1193     {
1194         LOGE("Payload is NULL");
1195         return -1;
1196     }
1197
1198     const char *subString = NULL;
1199     if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
1200     {
1201         LOGE("This is not secure resource");
1202         return -1;
1203     }
1204
1205     if (NULL == (subString = strstr(payLoad, "\"port\":")))
1206     {
1207         LOGE("This secure resource does not have port information");
1208         return -1;
1209     }
1210
1211     const char *startPos = strstr(subString, ":");
1212     if (!startPos)
1213     {
1214         LOGE("Parsing failed !");
1215         return -1;
1216     }
1217
1218     const char *endPos = strstr(startPos, "}");
1219     if (!endPos)
1220     {
1221         LOGE("Parsing failed !");
1222         return -1;
1223     }
1224
1225     char portStr[6] = { 0 };
1226     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1227
1228     LOGI("secured port is: %s", portStr);
1229     return atoi(portStr);
1230 }
1231
1232 CAResult_t get_network_type(uint32_t selectedNetwork)
1233 {
1234
1235     uint32_t number = selectedNetwork;
1236
1237     if (!(number & 0xf))
1238     {
1239         return CA_NOT_SUPPORTED;
1240     }
1241     if (number & CA_ADAPTER_IP)
1242     {
1243         g_selectedNwType = CA_ADAPTER_IP;
1244         return CA_STATUS_OK;
1245     }
1246     if (number & CA_ADAPTER_RFCOMM_BTEDR)
1247     {
1248         g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
1249         return CA_STATUS_OK;
1250     }
1251     if (number & CA_ADAPTER_GATT_BTLE)
1252     {
1253         g_selectedNwType = CA_ADAPTER_GATT_BTLE;
1254         return CA_STATUS_OK;
1255     }
1256
1257     return CA_NOT_SUPPORTED;
1258 }
1259
1260 void callback(char *subject, char *receivedData)
1261 {
1262     JNIEnv* env = NULL;
1263     uint32_t status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6);
1264     uint32_t res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1265
1266     jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1267     jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1268                                         "(Ljava/lang/String;Ljava/lang/String;)V");
1269
1270     jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1271     jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1272     (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1273
1274 }
1275
1276 CAResult_t get_remote_address(CATransportAdapter_t transportType, const char *address)
1277 {
1278     uint32_t len = strlen(address);
1279
1280     g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
1281     if (NULL == g_remoteAddress)
1282     {
1283         LOGE("g_remoteAddress Out of memory");
1284         return CA_MEMORY_ALLOC_FAILED;
1285     }
1286
1287     memcpy(g_remoteAddress, address, len + 1);
1288
1289     return CA_STATUS_OK;
1290 }
1291
1292
1293 void parsing_coap_uri(const char* uri, addressSet_t* address)
1294 {
1295     if (NULL == uri || NULL == address)
1296     {
1297         LOGE("parameter is null");
1298         return;
1299     }
1300
1301     // parse uri
1302     // #1. check prefix
1303     uint8_t startIndex = 0;
1304     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1305     {
1306         LOGI("uri has '%s' prefix", COAPS_PREFIX);
1307         startIndex = COAPS_PREFIX_LEN;
1308     }
1309     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1310     {
1311         LOGI("uri has '%s' prefix", COAP_PREFIX);
1312         startIndex = COAP_PREFIX_LEN;
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 }