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