Imported Upstream version 1.0.1
[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 #include <time.h>
8
9 #include "cainterface.h"
10 #include "cacommon.h"
11 #include "caadapterutils.h"
12 #include "oic_string.h"
13
14 #include "org_iotivity_ca_service_RMInterface.h"
15
16 #define  LOG_TAG   "JNI_INTERFACE_SAMPLE"
17 #define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
18 #define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
19
20 // Iotivity Device Identity.
21 const unsigned char IDENTITY[] = ("1111111111111111");
22
23 // PSK between this device and peer device.
24 const unsigned char RS_CLIENT_PSK[] = ("AAAAAAAAAAAAAAAA");
25
26 #define PORT_LENGTH 5
27 #define SECURE_DEFAULT_PORT 5684
28 #define RESOURCE_URI_LENGTH 14
29 #define OPTION_INFO_LENGTH 1024
30 #define NETWORK_INFO_LENGTH 1024
31 #define BIG_PAYLOAD_LENGTH 1024
32 #define RECEIVED_FILE_NAME_PREFIX_LENGTH 7
33 #define RECEIVED_FILE_NAME_LENGTH 14
34
35 typedef struct
36 {
37     char ipAddress[CA_IPADDR_SIZE];
38     uint16_t port;
39 } addressSet_t;
40
41 static void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo);
42 static void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo);
43 static void error_handler(const CAEndpoint_t *object, const CAErrorInfo_t* errorInfo);
44 static void get_resource_uri(const char *URI, char *resourceURI, int32_t length);
45 static uint32_t get_secure_information(CAPayload_t payLoad);
46 static CAResult_t get_network_type(uint32_t selectedNetwork);
47 static void callback(char *subject, char *receivedData);
48 static CAResult_t get_remote_address(const char *address);
49 static void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags);
50 static void delete_global_references(JNIEnv *env, jobject obj);
51 static int get_address_set(const char *pAddress, addressSet_t* outAddress);
52 bool read_file(const char* name, char** bytes, size_t* length);
53 uint32_t gettodaydate();
54 void saveFile(const char *payload, size_t payloadSize);
55
56 uint16_t g_localSecurePort = SECURE_DEFAULT_PORT;
57 CATransportAdapter_t g_selectedNwType = CA_ADAPTER_IP;
58 static CAToken_t g_lastRequestToken = NULL;
59 static uint8_t g_lastRequestTokenLength = 0;
60
61 static const char COAP_PREFIX[] =  "coap://";
62 static const char COAPS_PREFIX[] = "coaps://";
63 static const uint16_t COAP_PREFIX_LEN = sizeof(COAP_PREFIX) - 1;
64 static const uint16_t COAPS_PREFIX_LEN = sizeof(COAPS_PREFIX) - 1;
65
66 static const char RECEIVED_FILE_PATH[] = "/storage/emulated/0/Download/%d%s.txt";
67
68 static const char SECURE_INFO_DATA[]
69                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
70                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":"
71                                      "%d}}]}";
72 static const char NORMAL_INFO_DATA[]
73                                    = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
74                                      "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}";
75
76 static jobject g_responseListenerObject = NULL;
77 static JavaVM *g_jvm;
78
79 static CAEndpoint_t *g_clientEndpoint = NULL;
80 static char *g_resourceUri = NULL;
81 static CAToken_t g_clientToken = NULL;
82 static uint8_t g_clientTokenLength = 0;
83
84 static uint16_t g_clientMsgId = 0;
85 static char *g_remoteAddress = NULL;
86
87 // init
88 JNIEXPORT void JNICALL
89 Java_org_iotivity_ca_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj,
90                                                                    jobject listener)
91 {
92     LOGI("setNativeResponseListener");
93     if (!env || !obj || !listener)
94     {
95         LOGI("Invalid input parameter");
96         return;
97     }
98
99     g_responseListenerObject = (*env)->NewGlobalRef(env, listener);
100 }
101
102 #ifdef __WITH_DTLS__
103 // Internal API. Invoked by OC stack to retrieve credentials from this module
104 int32_t CAGetDtlsPskCredentials( CADtlsPskCredType_t type,
105               const unsigned char *desc, size_t desc_len,
106               unsigned char *result, size_t result_length)
107 {
108     LOGI("CAGetDtlsPskCredentials IN");
109
110     int32_t ret = -1;
111
112     if (NULL == result)
113     {
114         return ret;
115     }
116
117     switch (type)
118     {
119         case CA_DTLS_PSK_HINT:
120         case CA_DTLS_PSK_IDENTITY:
121
122             if (result_length < sizeof(IDENTITY))
123             {
124                 LOGE("ERROR : Wrong value for result for storing IDENTITY");
125                 return ret;
126             }
127
128             memcpy(result, IDENTITY, sizeof(IDENTITY));
129             ret = sizeof(IDENTITY);
130             break;
131
132         case CA_DTLS_PSK_KEY:
133
134             if ((desc_len == sizeof(IDENTITY)) &&
135                 memcmp(desc, IDENTITY, sizeof(IDENTITY)) == 0)
136             {
137                 if (result_length < sizeof(RS_CLIENT_PSK))
138                 {
139                     LOGE("ERROR : Wrong value for result for storing RS_CLIENT_PSK");
140                     return ret;
141                 }
142
143                 memcpy(result, RS_CLIENT_PSK, sizeof(RS_CLIENT_PSK));
144                 ret = sizeof(RS_CLIENT_PSK);
145             }
146             break;
147
148         default:
149
150             LOGE("Wrong value passed for PSK_CRED_TYPE.");
151             ret = -1;
152     }
153
154     LOGI("CAGetDtlsPskCredentials OUT\n");
155     return ret;
156 }
157
158 #endif
159
160 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
161 {
162     LOGI("JNI_OnLoad");
163     (void)reserved;
164
165     JNIEnv* env;
166     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
167     {
168         return -1;
169     }
170     g_jvm = jvm; /* cache the JavaVM pointer */
171
172     CANativeJNISetJavaVM(g_jvm);
173
174     return JNI_VERSION_1_6;
175 }
176
177 void JNI_OnUnload(JavaVM *jvm, void *reserved)
178 {
179     LOGI("JNI_OnUnload");
180     (void)reserved;
181
182     JNIEnv* env;
183     if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6))
184     {
185         return;
186     }
187     g_jvm = 0;
188     return;
189 }
190
191 JNIEXPORT void JNICALL
192 Java_org_iotivity_ca_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context)
193 {
194     LOGI("RMInitialize");
195     if (!env || !obj || !context)
196     {
197         LOGI("Invalid input parameter");
198         return;
199     }
200
201     //Currently set context for Android Platform
202     CANativeJNISetContext(env, context);
203
204     CAResult_t res = CAInitialize();
205
206     if (CA_STATUS_OK != res)
207     {
208         LOGE("Could not Initialize");
209     }
210
211 #ifdef __WITH_DTLS__
212     res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials);
213     if(CA_STATUS_OK != res)
214     {
215         LOGE("Set credential handler fail");
216         return;
217     }
218 #endif
219 }
220
221 JNIEXPORT void JNICALL
222 Java_org_iotivity_ca_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
223 {
224     LOGI("RMTerminate");
225     if (!env || !obj)
226     {
227         LOGI("Invalid input parameter");
228         return;
229     }
230
231     CADestroyToken(g_lastRequestToken);
232     CATerminate();
233     delete_global_references(env, obj);
234 }
235
236 JNIEXPORT void JNICALL
237 Java_org_iotivity_ca_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj)
238 {
239     LOGI("RMStartListeningServer");
240     if (!env || !obj)
241     {
242         LOGI("Invalid input parameter");
243         return;
244     }
245
246     if (CA_STATUS_OK != CAStartListeningServer())
247     {
248         LOGE("Could not start Listening server");
249     }
250 }
251
252 JNIEXPORT void JNICALL
253 Java_org_iotivity_ca_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj)
254 {
255     LOGI("RMStartDiscoveryServer");
256     if (!env || !obj)
257     {
258         LOGI("Invalid input parameter");
259         return;
260     }
261
262     if (CA_STATUS_OK != CAStartDiscoveryServer())
263     {
264         LOGE("Could not start discovery server");
265     }
266 }
267
268 JNIEXPORT void JNICALL
269 Java_org_iotivity_ca_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj)
270 {
271     LOGI("RMRegisterHandler");
272     if(!env || !obj)
273     {
274         LOGI("Invalid input parameter");
275         return;
276     }
277
278     CARegisterHandler(request_handler, response_handler, error_handler);
279 }
280
281 JNIEXPORT void JNICALL
282 Java_org_iotivity_ca_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri,
283                                                        jstring payload, jint selectedNetwork,
284                                                        jint isSecured, jint msgType,
285                                                        jboolean isBigData)
286 {
287     LOGI("selectedNetwork - %d", selectedNetwork);
288     if (!env || !obj)
289     {
290         LOGI("Invalid input parameter");
291         return;
292     }
293
294     if (!uri)
295     {
296         LOGE("Invalid input parameter : uri");
297         return;
298     }
299
300     CAResult_t res = get_network_type(selectedNetwork);
301     if (CA_STATUS_OK != res)
302     {
303         return;
304     }
305
306     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
307     LOGI("RMSendRequest - %s", strUri);
308
309     CATransportFlags_t flags;
310     addressSet_t address = {{0}, 0};
311     parsing_coap_uri(strUri, &address, &flags);
312
313     //create remote endpoint
314     CAEndpoint_t* endpoint = NULL;
315     res = CACreateEndpoint(flags, g_selectedNwType, (const char*)(address.ipAddress),
316                            address.port, &endpoint);
317     if (CA_STATUS_OK != res)
318     {
319         LOGE("Could not create remote end point");
320         (*env)->ReleaseStringUTFChars(env, uri, strUri);
321         return;
322     }
323
324     CAMessageType_t messageType = msgType;
325
326     // create token
327     CAToken_t token = NULL;
328     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
329
330     res = CAGenerateToken(&token, tokenLength);
331     if ((CA_STATUS_OK != res) || (!token))
332     {
333         LOGE("token generate error!!");
334         // destroy remote endpoint
335         CADestroyEndpoint(endpoint);
336         (*env)->ReleaseStringUTFChars(env, uri, strUri);
337         return;
338     }
339
340     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
341
342     get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH);
343     (*env)->ReleaseStringUTFChars(env, uri, strUri);
344
345     CAInfo_t requestData = { 0 };
346     requestData.token = token;
347     requestData.tokenLength = tokenLength;
348
349     size_t payloadLength = 0;
350     if (isBigData)
351     {
352         const char* path = NULL;
353         if (payload)
354         {
355             path = (*env)->GetStringUTFChars(env, payload, NULL);
356             if(path)
357             {
358                 char* bigData = NULL;
359                 bool result = read_file(path, &bigData, &payloadLength);
360                 if (!result)
361                 {
362                     LOGE("read has failed");
363                     (*env)->ReleaseStringUTFChars(env, payload, path);
364                     CADestroyToken(token);
365                     CADestroyEndpoint(endpoint);
366                     return;
367                 }
368                 (*env)->ReleaseStringUTFChars(env, payload, path);
369
370                 requestData.payload = (CAPayload_t) malloc(payloadLength);
371                 if (NULL == requestData.payload)
372                 {
373                     LOGE("Memory allocation failed!");
374                     // destroy token
375                     CADestroyToken(token);
376                     // destroy remote endpoint
377                     CADestroyEndpoint(endpoint);
378                     return;
379                 }
380                 memcpy(requestData.payload, bigData, payloadLength);
381                 requestData.payloadSize = payloadLength;
382             }
383         }
384     }
385     else
386     {
387         if (isSecured)
388         {
389             payloadLength = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
390             requestData.payload = (CAPayload_t) malloc(payloadLength);
391             if (NULL == requestData.payload)
392             {
393                 LOGE("Memory allocation failed!");
394                 // destroy token
395                 CADestroyToken(token);
396                 // destroy remote endpoint
397                 CADestroyEndpoint(endpoint);
398                 return;
399             }
400             snprintf((char *) requestData.payload, payloadLength, SECURE_INFO_DATA,
401                      resourceURI, g_localSecurePort);
402             requestData.payloadSize = payloadLength;
403         }
404         else
405         {
406             payloadLength = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
407             requestData.payload = (CAPayload_t) malloc(payloadLength);
408             if (NULL == requestData.payload)
409             {
410                 LOGE("Memory allocation failed!");
411                 // destroy token
412                 CADestroyToken(token);
413                 // destroy remote endpoint
414                 CADestroyEndpoint(endpoint);
415                 return;
416             }
417             snprintf((char *) requestData.payload, payloadLength, NORMAL_INFO_DATA, resourceURI);
418             requestData.payloadSize = payloadLength;
419         }
420     }
421
422     requestData.type = messageType;
423     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
424     if (NULL == requestData.resourceUri)
425     {
426         LOGE("Memory allocation failed!");
427         // destroy token
428         CADestroyToken(token);
429         // destroy remote endpoint
430         CADestroyEndpoint(endpoint);
431         free(requestData.payload);
432         return;
433     }
434     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
435
436     CARequestInfo_t requestInfo = { 0 };
437     requestInfo.method = CA_GET;
438     requestInfo.isMulticast = false;
439     requestInfo.info = requestData;
440
441     // send request
442     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
443     {
444         LOGE("Could not send request");
445     }
446
447     // destroy token
448     CADestroyToken(token);
449
450     // destroy remote endpoint
451     CADestroyEndpoint(endpoint);
452
453     free(requestData.payload);
454     free(requestData.resourceUri);
455 }
456
457 JNIEXPORT void JNICALL
458 Java_org_iotivity_ca_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri,
459                                                            jint selectedNetwork)
460 {
461     LOGI("selectedNetwork - %d", selectedNetwork);
462     if (!env || !obj)
463     {
464         LOGI("Invalid input parameter");
465         return;
466     }
467
468     CAResult_t res = get_network_type(selectedNetwork);
469     if (CA_STATUS_OK != res)
470     {
471         return;
472     }
473
474     // create remote endpoint
475     CAEndpoint_t *endpoint = NULL;
476     res = CACreateEndpoint(CA_IPV4, g_selectedNwType, NULL, 0, &endpoint);
477
478     if (CA_STATUS_OK != res)
479     {
480         LOGE("create remote endpoint error, error code: %d", res);
481         return;
482     }
483
484     // create token
485     CAToken_t token = NULL;
486     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
487
488     res = CAGenerateToken(&token, tokenLength);
489     if ((CA_STATUS_OK != res) || (!token))
490     {
491         LOGE("token generate error!!");
492         // destroy remote endpoint
493         CADestroyEndpoint(endpoint);
494         return;
495     }
496
497     LOGI("generated token %s", token);
498
499     CAInfo_t requestData = { 0 };
500     requestData.token = token;
501     requestData.tokenLength = tokenLength;
502     requestData.payload = (CAPayload_t) "TempJsonPayload";
503     requestData.payloadSize = strlen((const char *) requestData.payload);
504     requestData.type = CA_MSG_NONCONFIRM;
505
506     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
507     LOGI("resourceUri - %s", strUri);
508     requestData.resourceUri = (CAURI_t)strUri;
509
510     uint8_t optionNum = 2;
511     CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1,
512                                                              sizeof(CAHeaderOption_t) * optionNum);
513     if (NULL == headerOpt)
514     {
515         LOGE("Memory allocation failed");
516         // destroy remote endpoint
517         CADestroyEndpoint(endpoint);
518         return;
519     }
520
521     char* FirstOptionData = "Hello";
522     headerOpt[0].optionID = 3000;
523     memcpy(headerOpt[0].optionData, FirstOptionData, strlen(FirstOptionData));
524     headerOpt[0].optionLength = (uint16_t) strlen(FirstOptionData);
525
526     char* SecondOptionData2 = "World";
527     headerOpt[1].optionID = 3001;
528     memcpy(headerOpt[1].optionData, SecondOptionData2, strlen(SecondOptionData2));
529     headerOpt[1].optionLength = (uint16_t) strlen(SecondOptionData2);
530
531     requestData.numOptions = optionNum;
532     requestData.options = headerOpt;
533
534     CARequestInfo_t requestInfo = { 0 };
535     requestInfo.method = CA_GET;
536     requestInfo.isMulticast = true;
537     requestInfo.info = requestData;
538
539     // send request to all
540     res = CASendRequest(endpoint, &requestInfo);
541     if (CA_STATUS_OK != res)
542     {
543         LOGE("Could not send request to all");
544         //destroy token
545         CADestroyToken(token);
546     }
547     else
548     {
549         CADestroyToken(g_lastRequestToken);
550         g_lastRequestToken = token;
551         g_lastRequestTokenLength = tokenLength;
552     }
553
554     //ReleaseStringUTFChars for strUri
555     (*env)->ReleaseStringUTFChars(env, uri, strUri);
556
557     free(headerOpt);
558
559     // destroy remote endpoint
560     CADestroyEndpoint(endpoint);
561 }
562
563 JNIEXPORT void JNICALL
564 Java_org_iotivity_ca_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
565                                                         jint selectedNetwork,
566                                                         jint isSecured, jint msgType,
567                                                         jint responseValue)
568 {
569     LOGI("RMSendResponse");
570     if (!env || !obj)
571     {
572         LOGI("Invalid input parameter");
573         return;
574     }
575
576     LOGI("selectedNetwork - %d", selectedNetwork);
577
578     CAResult_t res = get_network_type(selectedNetwork);
579     if (CA_STATUS_OK != res)
580     {
581         LOGE("Not supported network type");
582         return;
583     }
584
585     if (NULL == g_clientEndpoint)
586     {
587         LOGE("No Request received");
588         return;
589     }
590
591     CAMessageType_t messageType = msgType;
592
593     CAInfo_t responseData = { 0 };
594     responseData.type = messageType;
595     responseData.messageId = g_clientMsgId;
596     responseData.resourceUri = (CAURI_t)g_resourceUri;
597
598     CAResponseInfo_t responseInfo = { 0 };
599
600     if (CA_MSG_RESET == msgType ||
601         (CA_MSG_ACKNOWLEDGE == msgType && CA_EMPTY == responseValue))
602     {
603         printf("RESET or ACK/EMPTY. there will be not payload/option\n");
604         responseInfo.result = CA_EMPTY;
605     }
606     else
607     {
608         responseData.token = g_clientToken;
609         responseData.tokenLength = g_clientTokenLength;
610         responseInfo.result = responseValue;
611
612         if (1 == isSecured)
613         {
614             uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_resourceUri) + 1;
615             responseData.payload = (CAPayload_t) malloc(length);
616             snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
617                      g_resourceUri, g_localSecurePort);
618             responseData.payloadSize = length;
619         }
620         else
621         {
622             uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_resourceUri) + 1;
623             responseData.payload = (CAPayload_t) malloc(length);
624             snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA, g_resourceUri);
625             responseData.payloadSize = length;
626         }
627     }
628
629     responseInfo.info = responseData;
630
631     // send response
632     res = CASendResponse(g_clientEndpoint, &responseInfo);
633     if (CA_STATUS_OK != res)
634     {
635         LOGE("Could not send response");
636     }
637
638     // destroy token
639     CADestroyToken(g_clientToken);
640     g_clientToken = NULL;
641     g_clientTokenLength = 0;
642
643     // destroy remote endpoint
644     CADestroyEndpoint(g_clientEndpoint);
645     g_clientEndpoint = NULL;
646     free(responseData.payload);
647 }
648
649 JNIEXPORT void JNICALL
650 Java_org_iotivity_ca_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri,
651                                                             jstring payload, jint selectedNetwork,
652                                                             jint isSecured, jint msgType)
653 {
654     LOGI("selectedNetwork - %d", selectedNetwork);
655     if (!env || !obj)
656     {
657         LOGI("Invalid input parameter");
658         return;
659     }
660
661     if (!payload)
662     {
663         LOGE("payload is NULL");
664     }
665
666     if (!uri)
667     {
668         LOGE("Invalid input parameter : uri");
669         return;
670     }
671
672     CAResult_t res = get_network_type(selectedNetwork);
673     if (CA_STATUS_OK != res)
674     {
675         LOGE("Not supported network type");
676         return;
677     }
678
679     const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
680     LOGI("RMSendNotification - %s", strUri);
681
682     CATransportFlags_t flags;
683     addressSet_t address = {{0}, 0};
684     parsing_coap_uri(strUri, &address, &flags);
685
686     //create remote endpoint
687     CAEndpoint_t* endpoint = NULL;
688     if (CA_STATUS_OK != CACreateEndpoint(flags, g_selectedNwType,
689                                          (const char*)address.ipAddress,
690                                          address.port, &endpoint))
691     {
692         //ReleaseStringUTFChars for strUri
693         (*env)->ReleaseStringUTFChars(env, uri, strUri);
694         LOGE("Could not create remote end point");
695         return;
696     }
697
698     char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 };
699     get_resource_uri(strUri, resourceURI, RESOURCE_URI_LENGTH);
700
701     //ReleaseStringUTFChars for strUri
702     (*env)->ReleaseStringUTFChars(env, uri, strUri);
703
704     CAMessageType_t messageType = msgType;
705
706     // create token
707     CAToken_t token = NULL;
708     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
709
710     res = CAGenerateToken(&token, tokenLength);
711     if ((CA_STATUS_OK != res) || (!token))
712     {
713         LOGE("token generate error!");
714         CADestroyEndpoint(endpoint);
715         return;
716     }
717
718     CAInfo_t requestData = { 0 };
719     requestData.token = token;
720     requestData.tokenLength = tokenLength;
721     requestData.resourceUri = (CAURI_t) malloc(sizeof(resourceURI));
722     if (NULL == requestData.resourceUri)
723     {
724         LOGE("Memory allocation failed!");
725         // destroy token
726         CADestroyToken(token);
727         // destroy remote endpoint
728         CADestroyEndpoint(endpoint);
729         return;
730     }
731     memcpy(requestData.resourceUri, resourceURI, sizeof(resourceURI));
732
733     if (1 == isSecured)
734     {
735         uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI);
736         requestData.payload = (CAPayload_t) malloc(length);
737         if (NULL == requestData.payload)
738         {
739             LOGE("Memory allocation failed!");
740             // destroy token
741             CADestroyToken(token);
742             // destroy remote endpoint
743             CADestroyEndpoint(endpoint);
744
745             free(requestData.resourceUri);
746             return;
747         }
748         snprintf((char *) requestData.payload, length, SECURE_INFO_DATA,
749                  resourceURI, g_localSecurePort);
750         requestData.payloadSize = length;
751     }
752     else
753     {
754         uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI);
755         requestData.payload = (CAPayload_t) malloc(length);
756         if (NULL == requestData.payload)
757         {
758             LOGE("Memory allocation failed!");
759             // destroy token
760             CADestroyToken(token);
761             // destroy remote endpoint
762             CADestroyEndpoint(endpoint);
763
764             free(requestData.resourceUri);
765             return;
766         }
767         snprintf((char *) requestData.payload, length, NORMAL_INFO_DATA, resourceURI);
768         requestData.payloadSize = length;
769     }
770
771     requestData.type = messageType;
772
773     CARequestInfo_t requestInfo = { 0 };
774     requestInfo.method = CA_GET;
775     requestInfo.info = requestData;
776
777     // send notification
778     if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
779     {
780         LOGE("Could not send notification");
781     }
782
783     LOGI("Send Notification");
784
785     // destroy token
786     CADestroyToken(token);
787
788     // destroy remote endpoint
789     CADestroyEndpoint(endpoint);
790
791     free(requestData.payload);
792     free(requestData.resourceUri);
793 }
794
795 JNIEXPORT void JNICALL
796 Java_org_iotivity_ca_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
797                                                          jint networkType)
798 {
799     LOGI("RMSelectNetwork Type : %d", networkType);
800     if (!env || !obj)
801     {
802         LOGI("Invalid input parameter");
803         return;
804     }
805
806     if (CA_STATUS_OK != CASelectNetwork(networkType))
807     {
808         LOGE("Could not select network");
809     }
810 }
811
812 JNIEXPORT void JNICALL
813 Java_org_iotivity_ca_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj,
814                                                            jint networkType)
815 {
816     LOGI("RMUnSelectNetwork Type : %d", networkType);
817     if (!env || !obj)
818     {
819         LOGI("Invalid input parameter");
820         return;
821     }
822
823     if (CA_STATUS_OK != CAUnSelectNetwork(networkType))
824     {
825         LOGE("Could not unselect network");
826     }
827 }
828
829 JNIEXPORT void JNICALL
830 Java_org_iotivity_ca_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj)
831 {
832     LOGI("RMGetNetworkInfomation");
833     if (!env || !obj)
834     {
835         LOGI("Invalid input parameter");
836         return;
837     }
838
839     CAEndpoint_t *tempInfo = NULL;
840     uint32_t tempSize = 0;
841
842     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
843     if (CA_STATUS_OK != res)
844     {
845         LOGE("Could not start get network information");
846         free(tempInfo);
847         return;
848     }
849
850     LOGI("################## Network Information #######################");
851     callback("######## Network Information", "#######");
852     LOGI("Network info total size is %d", tempSize);
853
854     uint32_t index;
855     for (index = 0; index < tempSize; index++)
856     {
857         res = get_remote_address(tempInfo[index].addr);
858         if (CA_STATUS_OK != res)
859         {
860             free(tempInfo);
861             return;
862         }
863         if (NULL != g_responseListenerObject)
864         {
865             char networkInfo[NETWORK_INFO_LENGTH];
866             LOGI("Type: %d", tempInfo[index].adapter);
867             snprintf(networkInfo, NETWORK_INFO_LENGTH, "%d",tempInfo[index].adapter);
868             callback("Type :", networkInfo);
869             if (CA_ADAPTER_IP == tempInfo[index].adapter)
870             {
871                 LOGI("Port: %d", tempInfo[index].port);
872                 snprintf(networkInfo, NETWORK_INFO_LENGTH, "%d",tempInfo[index].port);
873                 callback("Port: ", networkInfo);
874             }
875             LOGI("Secured: %d", (tempInfo[index].flags & CA_SECURE));
876             LOGI("Address: %s", g_remoteAddress);
877             callback("Address: ", g_remoteAddress);
878             free(g_remoteAddress);
879         }
880         if (tempInfo[index].flags & CA_SECURE)
881         {
882             g_localSecurePort = tempInfo[index].port;
883         }
884     }
885
886     // free
887     free(tempInfo);
888
889     LOGI("##############################################################");
890 }
891
892 JNIEXPORT void JNICALL
893 Java_org_iotivity_ca_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj)
894 {
895     LOGI("RMHandleRequestResponse");
896     if(!env || !obj)
897     {
898         LOGI("Invalid input parameter");
899         return;
900     }
901
902     if (CA_STATUS_OK != CAHandleRequestResponse())
903     {
904         LOGE("Could not handle request and response");
905     }
906 }
907
908 void request_handler(const CAEndpoint_t* object, const CARequestInfo_t* requestInfo)
909 {
910
911     if (!object)
912     {
913         LOGE("Remote endpoint is NULL!");
914         return;
915     }
916
917     if (!requestInfo)
918     {
919         LOGE("Request info is NULL!");
920         return;
921     }
922
923     if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) &&
924             (strncmp(g_lastRequestToken, requestInfo->info.token,
925                      requestInfo->info.tokenLength) == 0))
926     {
927         LOGI("token is same. received request of it's own. skip.. ");
928         return;
929     }
930
931     CAResult_t res = get_remote_address(object->addr);
932     if (CA_STATUS_OK != res)
933     {
934         return;
935     }
936
937     LOGI("##########received request from remote device #############");
938     LOGI("Remote Address: %s", g_remoteAddress);
939     LOGI("Remote Port: %d", object->port);
940     LOGI("Uri: %s", requestInfo->info.resourceUri);
941     LOGI("Data: %s", requestInfo->info.payload);
942     LOGI("Token: %s", requestInfo->info.token);
943     LOGI("Code: %d", requestInfo->method);
944     LOGI("MessageType: %d", requestInfo->info.type);
945
946     if (NULL != g_responseListenerObject)
947     {
948         char *cloneUri = NULL;
949         uint32_t len = 0;
950
951         if (NULL != requestInfo->info.resourceUri)
952         {
953             len = strlen(requestInfo->info.resourceUri);
954             cloneUri = (char *)malloc(sizeof(char) * (len + 1));
955
956             if (NULL == cloneUri)
957             {
958                 LOGE("cloneUri Out of memory");
959                 free(g_remoteAddress);
960                 return;
961             }
962
963             memcpy(cloneUri, requestInfo->info.resourceUri, len + 1);
964             callback("Uri: ", cloneUri);
965         }
966
967         len = strlen(g_remoteAddress);
968         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
969
970         if (NULL == cloneRemoteAddress)
971         {
972             LOGE("cloneRemoteAddress Out of memory");
973             free(g_remoteAddress);
974             free(cloneUri);
975             return;
976         }
977
978         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
979
980         callback("Remote Address: ", cloneRemoteAddress);
981         free(cloneRemoteAddress);
982         free(g_remoteAddress);
983
984         char portInfo[PORT_LENGTH] = { 0, };
985         snprintf(portInfo, PORT_LENGTH, "%d", object->port);
986         callback("Remote Port: ", portInfo);
987
988         //clone g_clientEndpoint
989         g_clientEndpoint = (CAEndpoint_t *) malloc(sizeof(CAEndpoint_t));
990         if (NULL == g_clientEndpoint)
991         {
992             LOGE("g_clientEndpoint Out of memory");
993             free(cloneUri);
994             return;
995         }
996         memcpy(g_clientEndpoint, object, sizeof(CAEndpoint_t));
997
998         if (NULL != cloneUri)
999         {
1000             len = strlen(cloneUri);
1001             g_resourceUri = (char *) malloc(sizeof(char) * (len + 1));
1002             if (NULL == g_resourceUri)
1003             {
1004                 LOGE("g_clientEndpoint->resourceUri Out of memory");
1005                 free(g_clientEndpoint);
1006                 free(cloneUri);
1007                 return;
1008             }
1009             memcpy(g_resourceUri, cloneUri, len + 1);
1010             free(cloneUri);
1011         }
1012         //clone g_clientToken
1013         len = requestInfo->info.tokenLength;
1014
1015         g_clientToken = (char *) malloc(sizeof(char) * len);
1016         if (NULL == g_clientToken)
1017         {
1018             LOGE("g_clientToken Out of memory");
1019             free(g_clientEndpoint);
1020             return;
1021         }
1022
1023         if (NULL != requestInfo->info.token)
1024         {
1025             memcpy(g_clientToken, requestInfo->info.token, len);
1026             g_clientTokenLength = len;
1027
1028         }
1029
1030         //clone g_clientMsgId
1031         g_clientMsgId = requestInfo->info.messageId;
1032
1033         if (NULL != requestInfo->info.payload && requestInfo->info.payloadSize > 0)
1034         {
1035             len = requestInfo->info.payloadSize;
1036             char *clonePayload = (char *) malloc(len + 1);
1037             if (NULL == clonePayload)
1038             {
1039                 LOGE("clonePayload Out of memory");
1040                 free(g_clientEndpoint);
1041                 return;
1042             }
1043
1044             memcpy(clonePayload, requestInfo->info.payload, len);
1045             clonePayload[len] = '\0';
1046
1047             if (len > BIG_PAYLOAD_LENGTH)
1048             {
1049                 saveFile(clonePayload, len);
1050             }
1051             else
1052             {
1053                 callback("Data: ", clonePayload);
1054             }
1055             free(clonePayload);
1056         }
1057     }
1058
1059     if (requestInfo->info.options)
1060     {
1061         uint32_t len = requestInfo->info.numOptions;
1062         uint32_t i;
1063
1064         LOGI("Option count: %d", requestInfo->info.numOptions);
1065
1066         for (i = 0; i < len; i++)
1067         {
1068             LOGI("Option %d", i + 1);
1069             LOGI("ID : %d", requestInfo->info.options[i].optionID);
1070             LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength,
1071                  requestInfo->info.options[i].optionData);
1072
1073             if (NULL != g_responseListenerObject)
1074             {
1075                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1076                 snprintf(optionInfo, OPTION_INFO_LENGTH,
1077                          "Num[%d] - ID : %d, Option Length : %d", i + 1,
1078                          requestInfo->info.options[i].optionID,
1079                          requestInfo->info.options[i].optionLength);
1080
1081                 callback("Option info: ", optionInfo);
1082
1083                 size_t optionDataLen = strlen(requestInfo->info.options[i].optionData);
1084                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1085                 if (NULL == cloneOptionData)
1086                 {
1087                     LOGE("cloneOptionData Out of memory");
1088                     free(g_clientEndpoint);
1089                     return;
1090                 }
1091
1092                 memcpy(cloneOptionData, requestInfo->info.options[i].optionData,
1093                        optionDataLen + 1);
1094
1095                 callback("Option Data: ", cloneOptionData);
1096                 free(cloneOptionData);
1097             }
1098         }
1099     }
1100     LOGI("############################################################");
1101
1102     //Check if this has secure communication information
1103     if (requestInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1104     {
1105         uint32_t securePort = get_secure_information(requestInfo->info.payload);
1106         if (0 < securePort) //Set the remote endpoint secure details and send response
1107         {
1108             LOGI("This is secure resource...");
1109
1110             CAEndpoint_t *endpoint = NULL;
1111             if (CA_STATUS_OK != CACreateEndpoint(CA_SECURE,
1112                         object->adapter, object->addr, securePort, &endpoint))
1113             {
1114                 LOGE("Failed to create duplicate of remote endpoint!");
1115                 return;
1116             }
1117             object = endpoint;
1118         }
1119     }
1120 }
1121
1122 void response_handler(const CAEndpoint_t* object, const CAResponseInfo_t* responseInfo)
1123 {
1124     if (!object || !responseInfo)
1125     {
1126         LOGE("Invalid input parameter");
1127         return;
1128     }
1129
1130     CAResult_t res = get_remote_address(object->addr);
1131     if (CA_STATUS_OK != res)
1132     {
1133         return;
1134     }
1135
1136     LOGI("##########Received response from remote device #############");
1137     LOGI("Uri: %s", responseInfo->info.resourceUri);
1138     LOGI("Remote Address: %s", g_remoteAddress);
1139     LOGI("Remote Port: %d", object->port);
1140     LOGI("response result: %d", responseInfo->result);
1141     LOGI("Data: %s", responseInfo->info.payload);
1142     LOGI("Token: %s", responseInfo->info.token);
1143     LOGI("MessageType: %d", responseInfo->info.type);
1144
1145     if (NULL != g_responseListenerObject)
1146     {
1147         uint32_t len = 0;
1148
1149         if (NULL != responseInfo->info.resourceUri)
1150         {
1151             len = strlen(responseInfo->info.resourceUri);
1152             char *cloneUri = (char *) malloc(sizeof(char) * (len + 1));
1153
1154             if (NULL == cloneUri)
1155             {
1156                 LOGE("cloneUri Out of memory");
1157                 free(g_remoteAddress);
1158                 return;
1159             }
1160
1161             memcpy(cloneUri, responseInfo->info.resourceUri, len + 1);
1162
1163             callback("Uri: ", cloneUri);
1164             free(cloneUri);
1165         }
1166
1167         len = strlen(g_remoteAddress);
1168         char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1));
1169
1170         if (NULL == cloneRemoteAddress)
1171         {
1172             LOGE("cloneRemoteAddress Out of memory");
1173             free(g_remoteAddress);
1174             return;
1175         }
1176
1177         memcpy(cloneRemoteAddress, g_remoteAddress, len + 1);
1178
1179         callback("Remote Address: ", cloneRemoteAddress);
1180         free(cloneRemoteAddress);
1181         free(g_remoteAddress);
1182
1183         char portInfo[PORT_LENGTH] = { 0, };
1184         snprintf(portInfo, PORT_LENGTH, "%d", object->port);
1185         callback("Remote Port: ", portInfo);
1186
1187         if (NULL != responseInfo->info.payload && responseInfo->info.payloadSize)
1188         {
1189             len = responseInfo->info.payloadSize;
1190             char *clonePayload = (char *) malloc(len + 1);
1191             if (NULL == clonePayload)
1192             {
1193                 LOGE("clonePayload Out of memory");
1194                 return;
1195             }
1196
1197             memcpy(clonePayload, responseInfo->info.payload, len);
1198             clonePayload[len] = '\0';
1199
1200             if (len > BIG_PAYLOAD_LENGTH)
1201             {
1202                 saveFile(clonePayload, len);
1203             }
1204             else
1205             {
1206                 callback("Data: ", clonePayload);
1207             }
1208             free(clonePayload);
1209         }
1210     }
1211
1212     if (responseInfo->info.options)
1213     {
1214         uint32_t len = responseInfo->info.numOptions;
1215         uint32_t i;
1216         for (i = 0; i < len; i++)
1217         {
1218             LOGI("Option %d", i + 1);
1219             LOGI("ID : %d", responseInfo->info.options[i].optionID);
1220             LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength,
1221                  responseInfo->info.options[i].optionData);
1222
1223             if (NULL != g_responseListenerObject)
1224             {
1225                 char optionInfo[OPTION_INFO_LENGTH] = { 0, };
1226                 snprintf(optionInfo, OPTION_INFO_LENGTH,
1227                          "Num[%d] - ID : %d, Option Length : %d", i + 1,
1228                          responseInfo->info.options[i].optionID,
1229                          responseInfo->info.options[i].optionLength);
1230
1231                 callback("Option info: ", optionInfo);
1232
1233                 size_t optionDataLen = strlen(responseInfo->info.options[i].optionData);
1234                 char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1));
1235                 if (NULL == cloneOptionData)
1236                 {
1237                     LOGE("cloneOptionData Out of memory");
1238                     return;
1239                 }
1240                 memcpy(cloneOptionData, responseInfo->info.options[i].optionData,
1241                        optionDataLen + 1);
1242                 callback("Option Data: ", cloneOptionData);
1243                 free(cloneOptionData);
1244             }
1245         }
1246     }
1247     LOGI("############################################################");
1248
1249     //Check if this has secure communication information
1250     if (responseInfo->info.payload && CA_ADAPTER_IP == object->adapter)
1251     {
1252         uint32_t securePort = get_secure_information(responseInfo->info.payload);
1253         if (0 < securePort) //Set the remote endpoint secure details and send response
1254         {
1255             LOGI("This is secure resource...");
1256         }
1257     }
1258 }
1259
1260 void error_handler(const CAEndpoint_t *rep, const CAErrorInfo_t* errorInfo)
1261 {
1262     LOGI("+++++++++++++++++++++++++++++++++++ErrorInfo+++++++++++++++++++++++++++++++++++");
1263
1264     if (rep)
1265     {
1266         LOGI("Error Handler, Adapter Type : %d", rep->adapter);
1267         LOGI("Error Handler, Adapter Type : %s", rep->addr);
1268     }
1269
1270     if (errorInfo)
1271     {
1272         const CAInfo_t *info = &errorInfo->info;
1273         LOGI("Error Handler, ErrorInfo :");
1274         LOGI("Error Handler result    : %d", errorInfo->result);
1275         LOGI("Error Handler token     : %s", info->token);
1276         LOGI("Error Handler messageId : %d", (uint16_t) info->messageId);
1277         LOGI("Error Handler resourceUri : %s", info->resourceUri);
1278         LOGI("Error Handler type      : %d", info->type);
1279         LOGI("Error Handler payload   : %s", info->payload);
1280
1281         if(CA_ADAPTER_NOT_ENABLED == errorInfo->result)
1282         {
1283             LOGE("CA_ADAPTER_NOT_ENABLED, enable the adapter");
1284         }
1285         else if(CA_SEND_FAILED == errorInfo->result)
1286         {
1287             LOGE("CA_SEND_FAILED, unable to send the message, check parameters");
1288         }
1289         else if(CA_MEMORY_ALLOC_FAILED == errorInfo->result)
1290         {
1291             LOGE("CA_MEMORY_ALLOC_FAILED, insufficient memory");
1292         }
1293         else if(CA_SOCKET_OPERATION_FAILED == errorInfo->result)
1294         {
1295             LOGE("CA_SOCKET_OPERATION_FAILED, socket operation failed");
1296         }
1297         else if(CA_STATUS_FAILED == errorInfo->result)
1298         {
1299             LOGE("CA_STATUS_FAILED, message could not be delivered, internal error");
1300         }
1301     }
1302     LOGI("++++++++++++++++++++++++++++++++End of ErrorInfo++++++++++++++++++++++++++++++++");
1303
1304     return;
1305 }
1306
1307 void get_resource_uri(const char *URI, char *resourceURI, int32_t length)
1308 {
1309     const char *startPos = URI;
1310     const char *temp = strstr(URI, "://");
1311     if (NULL != temp)
1312     {
1313         startPos = strchr(temp + 3, '/');
1314         if (!startPos)
1315         {
1316             LOGE("Resource URI is missing");
1317             return;
1318         }
1319     }
1320
1321     const char *endPos = strchr(startPos, '?');
1322     if (!endPos)
1323     {
1324         endPos = URI + strlen(URI);
1325     }
1326     --endPos;
1327
1328     if (endPos - startPos <= length)
1329     {
1330         memcpy(resourceURI, startPos + 1, endPos - startPos);
1331     }
1332
1333     LOGI("URI: %s, ResourceURI: %s", URI, resourceURI);
1334 }
1335
1336 uint32_t get_secure_information(CAPayload_t payLoad)
1337 {
1338     LOGI("entering get_secure_information");
1339
1340     if (!payLoad)
1341     {
1342         LOGE("Payload is NULL");
1343         return -1;
1344     }
1345
1346     const char *subString = NULL;
1347     if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
1348     {
1349         LOGE("This is not secure resource");
1350         return -1;
1351     }
1352
1353     if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
1354     {
1355         LOGE("This secure resource does not have port information");
1356         return -1;
1357     }
1358
1359     const char *startPos = strstr(subString, ":");
1360     if (!startPos)
1361     {
1362         LOGE("Parsing failed !");
1363         return -1;
1364     }
1365
1366     const char *endPos = strstr(startPos, "}");
1367     if (!endPos)
1368     {
1369         LOGE("Parsing failed !");
1370         return -1;
1371     }
1372
1373     char portStr[6] = { 0 };
1374     memcpy(portStr, startPos + 1, (endPos - 1) - startPos);
1375
1376     LOGI("secured port is: %s", portStr);
1377     return atoi(portStr);
1378 }
1379
1380 CAResult_t get_network_type(uint32_t selectedNetwork)
1381 {
1382
1383     uint32_t number = selectedNetwork;
1384
1385     if (!(number & 0xf))
1386     {
1387         return CA_NOT_SUPPORTED;
1388     }
1389     if (number & CA_ADAPTER_IP)
1390     {
1391         g_selectedNwType = CA_ADAPTER_IP;
1392         return CA_STATUS_OK;
1393     }
1394     if (number & CA_ADAPTER_RFCOMM_BTEDR)
1395     {
1396         g_selectedNwType = CA_ADAPTER_RFCOMM_BTEDR;
1397         return CA_STATUS_OK;
1398     }
1399     if (number & CA_ADAPTER_GATT_BTLE)
1400     {
1401         g_selectedNwType = CA_ADAPTER_GATT_BTLE;
1402         return CA_STATUS_OK;
1403     }
1404
1405     return CA_NOT_SUPPORTED;
1406 }
1407
1408 void callback(char *subject, char *receivedData)
1409 {
1410     bool isAttached = false;
1411     JNIEnv* env;
1412
1413     if (!g_responseListenerObject)
1414     {
1415         LOGE("g_responseListenerObject is NULL, cannot have callback");
1416         return;
1417     }
1418
1419     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1420     if (JNI_OK != res)
1421     {
1422         LOGI("Could not get JNIEnv pointer");
1423         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1424
1425         if (JNI_OK != res)
1426         {
1427             LOGE("AttachCurrentThread has failed");
1428             return;
1429         }
1430         isAttached = true;
1431     }
1432
1433     jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject);
1434     if (!cls)
1435     {
1436         LOGE("could not get class");
1437         goto detach_thread;
1438     }
1439
1440     jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived",
1441                                         "(Ljava/lang/String;Ljava/lang/String;)V");
1442     if (!mid)
1443     {
1444         LOGE("could not get Method ID");
1445         goto detach_thread;
1446     }
1447
1448     jstring jsubject = (*env)->NewStringUTF(env, (char*) subject);
1449     if (!jsubject)
1450     {
1451         LOGE("NewStringUTF failed");
1452         goto detach_thread;
1453     }
1454
1455     jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData);
1456     if (!jreceivedData)
1457     {
1458         LOGE("NewStringUTF failed");
1459         goto detach_thread;
1460     }
1461
1462     (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData);
1463
1464 detach_thread :
1465     if (isAttached)
1466     {
1467         (*g_jvm)->DetachCurrentThread(g_jvm);
1468         LOGI("DetachCurrentThread");
1469     }
1470 }
1471
1472 CAResult_t get_remote_address(const char *address)
1473 {
1474     uint32_t len = strlen(address);
1475
1476     g_remoteAddress = (char *)malloc(sizeof (char) * (len + 1));
1477     if (NULL == g_remoteAddress)
1478     {
1479         LOGE("g_remoteAddress Out of memory");
1480         return CA_MEMORY_ALLOC_FAILED;
1481     }
1482
1483     memcpy(g_remoteAddress, address, len + 1);
1484
1485     return CA_STATUS_OK;
1486 }
1487
1488
1489 void parsing_coap_uri(const char* uri, addressSet_t* address, CATransportFlags_t *flags)
1490 {
1491     if (NULL == uri || NULL == address)
1492     {
1493         LOGE("parameter is null");
1494         return;
1495     }
1496
1497     // parse uri
1498     // #1. check prefix
1499     uint8_t startIndex = 0;
1500     if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
1501     {
1502         LOGI("uri has '%s' prefix", COAPS_PREFIX);
1503         startIndex = COAPS_PREFIX_LEN;
1504         *flags = CA_SECURE;
1505     }
1506     else if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
1507     {
1508         LOGI("uri has '%s' prefix", COAP_PREFIX);
1509         startIndex = COAP_PREFIX_LEN;
1510         *flags = CA_IPV4;
1511     }
1512
1513     // #2. copy uri for parse
1514     size_t len = strlen(uri) - startIndex;
1515
1516     if (len <= 0)
1517     {
1518         LOGE("uri length is 0!");
1519         return;
1520     }
1521
1522     char *cloneUri = (char *) calloc(len + 1, sizeof(char));
1523     if (NULL == cloneUri)
1524     {
1525         LOGE("Out of memory");
1526         return;
1527     }
1528
1529     OICStrcpy(cloneUri, len+1, &uri[startIndex]);
1530
1531     char *pstr = NULL;
1532     //filter out the resource uri
1533     char *pUrl = strtok_r(cloneUri, "/", &pstr);
1534
1535     if (pUrl)
1536     {
1537         LOGI("pAddress : %s", pUrl);
1538         int res = get_address_set(pUrl, address);
1539         if (res == -1)
1540         {
1541             LOGE("address parse error");
1542
1543             return;
1544         }
1545     }
1546     else
1547     {
1548         LOGE("strtok_r error, could not get the address");
1549     }
1550
1551     return;
1552 }
1553
1554 int get_address_set(const char *pAddress, addressSet_t* outAddress)
1555 {
1556     if (NULL == pAddress || NULL == outAddress)
1557     {
1558         LOGE("parameter is null");
1559         return -1;
1560     }
1561
1562     size_t len = strlen(pAddress);
1563     int isIp = 0;
1564     size_t ipLen = 0;
1565
1566     for (size_t i = 0; i < len; i++)
1567     {
1568         if (pAddress[i] == '.')
1569         {
1570             isIp = 1;
1571         }
1572
1573         // found port number start index
1574         if (isIp && pAddress[i] == ':')
1575         {
1576             ipLen = i;
1577             break;
1578         }
1579     }
1580
1581     if (isIp)
1582     {
1583         if(ipLen && (ipLen <  sizeof(outAddress->ipAddress)))
1584         {
1585             strncpy(outAddress->ipAddress, pAddress, ipLen);
1586             outAddress->ipAddress[ipLen] = '\0';
1587         }
1588         else if (!ipLen && (len <  sizeof(outAddress->ipAddress)))
1589         {
1590             strncpy(outAddress->ipAddress, pAddress, len);
1591             outAddress->ipAddress[len] = '\0';
1592         }
1593         else
1594         {
1595             LOGE("IP Address too long: %d", ipLen==0 ? len : ipLen);
1596             return -1;
1597         }
1598
1599         if (ipLen > 0)
1600         {
1601             outAddress->port = atoi(pAddress + ipLen + 1);
1602         }
1603     }
1604     else
1605     {
1606         strncpy(outAddress->ipAddress, pAddress, len);
1607         outAddress->ipAddress[len] = '\0';
1608     }
1609
1610     return isIp;
1611 }
1612
1613 void delete_global_references(JNIEnv *env, jobject obj)
1614 {
1615     LOGI("delete_global_references");
1616     if (!env || !obj )
1617     {
1618         LOGI("Invalid input parameter");
1619         return;
1620     }
1621
1622     (*env)->DeleteGlobalRef(env, g_responseListenerObject);
1623 }
1624
1625
1626 bool read_file(const char* name, char** bytes, size_t* length)
1627 {
1628     if (NULL == name)
1629     {
1630         LOGE("parameter is null");
1631         return false;
1632     }
1633
1634     FILE* file;
1635     char* buffer;
1636     size_t fileLen;
1637
1638     // Open file
1639     file = fopen(name, "rt");
1640     if (!file)
1641     {
1642         fprintf(stderr, "Unable to open file %s", name);
1643         return false;
1644     }
1645
1646     // Get file length
1647     fseek(file, 0, SEEK_END);
1648     fileLen = ftell(file);
1649     if (-1 == fileLen)
1650     {
1651         fprintf(stderr, "Failed to read file length");
1652         fclose(file);
1653         return false;
1654     }
1655     fseek(file, 0, SEEK_SET);
1656
1657     LOGI("file size: %d", fileLen);
1658
1659     // Allocate memory
1660     buffer = calloc(1, sizeof(char) * fileLen + 1);
1661     if (!buffer)
1662     {
1663         fprintf(stderr, "Memory error!");
1664         fclose(file);
1665         return false;
1666     }
1667
1668     // Read file contents into buffer
1669     size_t ret = fread(buffer, fileLen, 1, file);
1670     if (ret != 1)
1671     {
1672         printf("Failed to read data from file, %s\n", name);
1673         fclose(file);
1674         free(buffer);
1675         return false;
1676     }
1677
1678     fclose(file);
1679
1680     LOGI("file bytes: %s", buffer);
1681
1682     *bytes = buffer;
1683     *length = fileLen;
1684
1685     return true;
1686 }
1687
1688 void saveFile(const char *payload, size_t payloadSize)
1689 {
1690     // 1. get day
1691     uint32_t day = gettodaydate();
1692
1693     // 2. get time
1694     time_t current_time;
1695     struct tm * time_info;
1696     char timeString[RECEIVED_FILE_NAME_PREFIX_LENGTH];
1697
1698     time(&current_time);
1699     time_info = localtime(&current_time);
1700
1701     strftime(timeString, sizeof(timeString), "%H%M%S", time_info);
1702
1703     uint32_t path_length = strlen(RECEIVED_FILE_PATH) + RECEIVED_FILE_NAME_LENGTH + 1;
1704     char* path = calloc(1, sizeof(char) * path_length);
1705     if (path != NULL)
1706     {
1707         snprintf(path, path_length, RECEIVED_FILE_PATH, day, timeString);
1708         LOGI("received file path: %s", path);
1709
1710         FILE *fp = fopen(path, "wt");
1711         fwrite(payload, 1, payloadSize, fp);
1712         fclose(fp);
1713
1714         callback("File Path: ", path);
1715     }
1716     else
1717     {
1718         LOGE("path Out of memory");
1719     }
1720 }
1721
1722 uint32_t gettodaydate()
1723 {
1724     uint32_t ldate;
1725     time_t clock;
1726     struct tm *date;
1727
1728     clock = time(0);
1729     date = localtime(&clock);
1730     ldate = date->tm_year * 100000;
1731     ldate += (date->tm_mon + 1) * 1000;
1732     ldate += date->tm_mday * 10;
1733     ldate += date->tm_wday;
1734     ldate += 190000000;
1735     ldate /= 10;
1736
1737     return(ldate);
1738 }