f8ee78958b381241c19761d10037fd970bdd5037
[platform/upstream/iotivity.git] / service / notification / android / notification-service / src / main / jni / provider / JniNotificationProvider.cpp
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "JniNotificationProvider.h"
22 #include "NSProviderService.h"
23
24 static JavaVM *g_jvm = NULL;
25
26 static jobject g_obj_subscriptionListener = NULL;
27 static jobject g_obj_syncListener = NULL;
28
29 jclass g_cls_Message;
30 jclass g_cls_Message_Type;
31 jclass g_cls_Consumer;
32 jclass g_cls_SyncInfo;
33 jclass g_cls_SyncType;
34 jclass g_cls_MediaContents;
35 jclass g_cls_Topic;
36 jclass g_cls_TopicsList;
37 jclass g_cls_TopicState;
38
39 static JNIEnv *GetJNIEnv(jint *ret)
40 {
41     JNIEnv *env = NULL;
42
43     *ret = g_jvm->GetEnv((void **) &env, JNI_CURRENT_VERSION);
44     switch (*ret)
45     {
46         case JNI_OK:
47             return env;
48         case JNI_EDETACHED:
49             if (g_jvm->AttachCurrentThread(&env, NULL) != JNI_OK)
50             {
51                 LOGE ("Failed to get the environment");
52                 return NULL;
53             }
54             else
55             {
56                 return env;
57             }
58         case JNI_EVERSION:
59             LOGE ("JNI version is not supported");
60         default:
61             LOGE ("Failed to get the environment");
62             return NULL;
63     }
64 }
65
66 OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
67 {
68     LOGD("JNIProviderService: getMessage - IN");
69
70     jclass cls = env->GetObjectClass( jMsg);
71
72     // Message type
73     jclass cls_messageType = (jclass) (env->NewLocalRef(g_cls_Message_Type));
74     if (!cls_messageType)
75     {
76         LOGE ("Failed to Get ObjectClass for Message Type");
77         return nullptr;
78     }
79     jmethodID mid = env->GetMethodID(cls_messageType, "ordinal", "()I");
80     jfieldID fid_type = env->GetFieldID( cls, "mType",
81                                          "Lorg/iotivity/service/ns/common/Message$MessageType;");
82     if (fid_type == NULL)
83     {
84         LOGE("Error: jfieldID for message type  is null");
85         return nullptr;
86     }
87     jobject jobj = env->GetObjectField( jMsg, fid_type);
88     if (jobj == NULL)
89     {
90         LOGE("Error: object of field  Message Type is null");
91         return nullptr;
92     }
93     jint jtype = env->CallIntMethod(jobj, mid);
94     OIC::Service::NSMessage::NSMessageType  type = (OIC::Service::NSMessage::NSMessageType) jtype;
95
96     LOGD("Message Type: %ld\n", (long )type);
97
98     // Message Time
99     jfieldID fid_tm = env->GetFieldID( cls, "mTime", "Ljava/lang/String;");
100     if (fid_tm == NULL)
101     {
102         LOGE("Error: jfieldID for message time is null");
103         return nullptr;
104     }
105     jstring jtime = (jstring)env->GetObjectField( jMsg, fid_tm);
106     const char *time = "";
107     if (jtime)
108     {
109         time = env->GetStringUTFChars( jtime, NULL);
110     }
111     else
112     {
113         LOGD("Info: messageTitle is null");
114     }
115     LOGD("Message Time: %s\n", time);
116
117     // Message TTL
118     jfieldID fid_ttl = env->GetFieldID( cls, "mTTL", "J");
119     if (fid_ttl == NULL)
120     {
121         LOGE("Error: jfieldID for message ttl is null");
122         return nullptr;
123     }
124     jlong jttl = (jlong) env->GetObjectField( jMsg, fid_ttl);
125     uint64_t  ttl = jttl;
126
127     LOGD("Message ID: %lld\n", ttl);
128
129     // Message Title
130     jfieldID fid_title = env->GetFieldID( cls, "mTitle", "Ljava/lang/String;");
131     if (fid_title == NULL)
132     {
133         LOGE("Error: jfieldID for message title is null");
134         return nullptr;
135     }
136     jstring jmsgTitle = (jstring)env->GetObjectField( jMsg, fid_title);
137     const char *messageTitle = "";
138     if (jmsgTitle)
139     {
140         messageTitle = env->GetStringUTFChars( jmsgTitle, NULL);
141     }
142     else
143     {
144         LOGD("Info: messageTitle is null");
145     }
146     LOGD("Message Title: %s\n", messageTitle);
147
148     // Message Content Text
149     jfieldID fid_body = env->GetFieldID( cls, "mContentText", "Ljava/lang/String;");
150     if (fid_body == NULL)
151     {
152         LOGE("Error: jfieldID for message context Text is null");
153         return nullptr;
154     }
155     jstring jmsgBody = (jstring)env->GetObjectField( jMsg, fid_body);
156     const char *messageBody = "";
157     if (jmsgBody)
158     {
159         messageBody = env->GetStringUTFChars( jmsgBody, NULL);
160     }
161     else
162     {
163         LOGD("Info: messageBody is null");
164     }
165     LOGD("Message Body: %s\n", messageBody);
166
167     // Message Source
168     jfieldID fid_source = env->GetFieldID( cls, "mSourceName", "Ljava/lang/String;");
169     if (fid_source == NULL)
170     {
171         LOGE("Error: jfieldID for message source is null");
172         return nullptr;
173     }
174     jstring jmsgSource = (jstring)env->GetObjectField( jMsg, fid_source);
175     const char *messageSource = "";
176     if (jmsgSource)
177     {
178         messageSource = env->GetStringUTFChars( jmsgSource, NULL);
179     }
180     else
181     {
182         LOGD("Info: messageSource is null");
183     }
184     LOGD("Message Source: %s\n", messageSource);
185
186     // Message Topic
187     jfieldID fid_topic = env->GetFieldID( cls, "mTopic", "Ljava/lang/String;");
188     if (fid_topic == NULL)
189     {
190         LOGE("Error: jfieldID for topic  is null");
191         return nullptr;
192     }
193     jstring jtopic = (jstring)env->GetObjectField( jMsg, fid_topic);
194     const char *topic = "";
195     if (jtopic)
196     {
197         topic = env->GetStringUTFChars( jtopic, NULL);
198     }
199     else
200     {
201         LOGD("Info: topic is null");
202     }
203     LOGD("Topic : %s\n", topic);
204
205     // Message MediaContents
206     jfieldID fid_media = env->GetFieldID( cls, "mMediaContents",
207                                           "Lorg/iotivity/service/ns/common/MediaContents;");
208     if (fid_media == NULL)
209     {
210         LOGE("Error: jfieldID for MediaContents is null");
211         return nullptr;
212     }
213     jobject jmedia = env->GetObjectField( jMsg, fid_media);
214     if (jmedia == NULL)
215     {
216         LOGE("Error: jmedia object of MediaContents inside Message is null");
217         return nullptr;
218     }
219     jclass cls_MediaContents = (jclass) (env->NewLocalRef(g_cls_MediaContents));
220     if (!cls_MediaContents)
221     {
222         LOGE ("Failed to Get ObjectClass for class MediaContents");
223         return nullptr;
224     }
225     jfieldID fid_icon = env->GetFieldID( cls_MediaContents, "mIconImage", "Ljava/lang/String;");
226     if (fid_icon == NULL)
227     {
228         LOGE("Error: jfieldID for iconImage is null");
229         return nullptr;
230     }
231     jstring jiconImage = (jstring)env->GetObjectField( jmedia, fid_icon);
232     const char *iconImage = "";
233     if (jiconImage)
234     {
235         iconImage = env->GetStringUTFChars( jiconImage, NULL);
236     }
237     else
238     {
239         LOGD("Info: iconImage is null");
240     }
241
242     LOGD("iconImage: %s\n", iconImage);
243
244     OIC::Service::NSMediaContents *media = new OIC::Service::NSMediaContents(std::string(iconImage));
245     OIC::Service::NSMessage *nsMsg = OIC::Service::NSProviderService::getInstance()->CreateMessage();
246
247     nsMsg->setType(type);
248     nsMsg->setTime(std::string(time));
249     nsMsg->setTTL(ttl);
250     nsMsg->setTitle(std::string(messageTitle));
251     nsMsg->setContentText(std::string(messageBody));
252     nsMsg->setSourceName(std::string(messageSource));
253     nsMsg->setMediaContents(media);
254     nsMsg->setTopic(std::string(topic));
255
256     env->DeleteLocalRef(cls_messageType);
257     env->DeleteLocalRef(cls_MediaContents);
258
259     if (jtime)
260     {
261         env->ReleaseStringUTFChars(jtime, time);
262     }
263     if (jmsgTitle)
264     {
265         env->ReleaseStringUTFChars(jmsgTitle, messageTitle);
266     }
267     if (jmsgBody)
268     {
269         env->ReleaseStringUTFChars(jmsgBody, messageBody);
270     }
271     if (jmsgSource)
272     {
273         env->ReleaseStringUTFChars(jmsgSource, messageSource);
274     }
275     if (jtopic)
276     {
277         env->ReleaseStringUTFChars(jtopic, topic);
278     }
279     if (jiconImage)
280     {
281         env->ReleaseStringUTFChars(jiconImage, iconImage);
282     }
283
284     LOGD("JNIProviderService: getMessage - OUT");
285     return nsMsg;
286
287 }
288
289 jobject getJavaTopicState(JNIEnv *env, OIC::Service::NSTopic::NSTopicState nsState)
290 {
291     LOGD("JNIProviderService: getJavaTopicState - IN");
292
293     // TopicState
294     jclass cls_topicState = (jclass) (env->NewLocalRef(g_cls_TopicState));
295     if (!cls_topicState)
296     {
297         LOGE ("Failed to Get ObjectClass for TopicState Type");
298         return NULL;
299     }
300
301     jobject obj_topicState;
302     switch (nsState)
303     {
304         case OIC::Service::NSTopic::NSTopicState::UNSUBSCRIBED:
305             {
306                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,
307                                           "UNSUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");
308                 obj_topicState = env->GetStaticObjectField(cls_topicState, fieldID);
309             }
310         case OIC::Service::NSTopic::NSTopicState::SUBSCRIBED:
311             {
312                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,
313                                           "SUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");
314                 obj_topicState = env->GetStaticObjectField(cls_topicState, fieldID);
315             }
316
317     }
318     if (obj_topicState == NULL)
319     {
320         LOGE("Error: object of field  TopicState  is null");
321     }
322     env->DeleteLocalRef(cls_topicState);
323     LOGD("JNIProviderService: getJavaTopicState - OUT");
324     return obj_topicState;
325 }
326
327 jobject getJavaTopicsList(JNIEnv *env, OIC::Service::NSTopicsList *topicList)
328 {
329     LOGD("JNIProviderService: getJavaTopicsList - IN");
330     jclass cls_topicList = (jclass) (env->NewLocalRef(g_cls_TopicsList));
331     if (!cls_topicList)
332     {
333         LOGE ("Failed to Get ObjectClass for TopicsList");
334         return NULL;
335     }
336     jmethodID mid_topicList = env->GetMethodID(cls_topicList, "<init>", "()V");
337     if (!mid_topicList)
338     {
339         LOGE ("Failed to Get MethodID for TopicsList<init>");
340         return NULL;
341     }
342     jobject obj_topicList = env->NewObject(cls_topicList, mid_topicList);
343     if (!obj_topicList)
344     {
345         LOGE ("Failed to Get object for TopicsList");
346         return NULL;
347     }
348     jmethodID mid_addTopic = env->GetMethodID(cls_topicList, "addTopic",
349                              "(Ljava/lang/String;Lorg/iotivity/service/ns/common/Topic$TopicState;)V");
350     if (!mid_addTopic)
351     {
352         LOGE ("Failed to Get MethodID for addTopic");
353         return NULL;
354     }
355     for (auto it : topicList->getTopicsList())
356     {
357         jobject jState = getJavaTopicState(env, it->getState());
358         std::string topicName = it->getTopicName();
359         jstring jTopicName = env->NewStringUTF(topicName.c_str());
360         env->CallVoidMethod(obj_topicList, mid_addTopic, jTopicName, jState);
361     }
362     env->DeleteLocalRef(cls_topicList);
363     LOGD("JNIProviderService: getJavaTopicsList - OUT");
364     return obj_topicList;
365 }
366
367 jobject getJavaSyncType(JNIEnv *env, OIC::Service::NSSyncInfo::NSSyncType nsType)
368 {
369     LOGD ("JNIProviderService: getJavaSyncType - IN");
370
371     // SyncType
372     jclass cls_SyncType = (jclass) (env->NewLocalRef(g_cls_SyncType));
373     if (!cls_SyncType)
374     {
375         LOGE ("Failed to Get ObjectClass for SyncType");
376         return NULL;
377     }
378     jobject syncType;
379     switch (nsType)
380     {
381         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_UNREAD:
382             {
383                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
384                                           "UNREAD", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
385                 syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
386             }
387         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ :
388             {
389                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
390                                           "READ", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
391                 syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
392             }
393         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED :
394             {
395                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
396                                           "DELETED", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
397                 syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
398             }
399
400     }
401
402     if (syncType == NULL)
403     {
404         LOGE("Error: object of field  Synctype  is null");
405     }
406
407     env->DeleteLocalRef(cls_SyncType);
408     LOGD ("JNIProviderService: getJavaSyncType - OUT");
409     return syncType;
410 }
411
412
413 void onSubscribeListenerCb(OIC::Service::NSConsumer *consumer)
414 {
415     LOGD("JNIProviderService_onSubscribeListenerCb - IN");
416
417     jint envRet;
418     JNIEnv *env = GetJNIEnv(&envRet);
419     if (NULL == env) return ;
420
421     jobject jSubscriptionListener = (jobject) env->NewLocalRef(g_obj_subscriptionListener);
422     if (!jSubscriptionListener)
423     {
424         LOGE ("Failed to Get jSubscriptionListener");
425         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
426         return ;
427     }
428
429     LOGD("consumer ID : %s\n", consumer->getConsumerId().c_str());
430
431     jstring jConsumerId = env->NewStringUTF( consumer->getConsumerId().c_str());
432
433     jclass cls_consumer = (jclass) (env->NewLocalRef(g_cls_Consumer));
434     if (!cls_consumer)
435     {
436         LOGE ("Failed to Get ObjectClass for Consumer");
437         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
438         return ;
439     }
440
441     jmethodID mid_consumer = env->GetMethodID(
442                                  cls_consumer,
443                                  "<init>",
444                                  "(Ljava/lang/String;)V");
445     if (!mid_consumer)
446     {
447         LOGE ("Failed to Get MethodID for Consumer<init>");
448         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
449         return ;
450     }
451     jobject obj_consumer = env->NewObject( cls_consumer, mid_consumer, jConsumerId);
452
453     jclass cls = env->GetObjectClass( jSubscriptionListener);
454     if (!cls)
455     {
456         LOGE("Failed to Get ObjectClass of jSubscriptionListener");
457         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
458         return;
459     }
460     jmethodID mid = env->GetMethodID(
461                         cls,
462                         "onConsumerSubscribed",
463                         "(Lorg/iotivity/service/ns/provider/Consumer;)V");
464     if (!mid)
465     {
466         LOGE("Failed to Get MethodID of onConsumerSubscribed");
467         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
468         return;
469     }
470
471     env->CallVoidMethod( jSubscriptionListener, mid, obj_consumer);
472     env->DeleteLocalRef(jSubscriptionListener);
473     env->DeleteLocalRef(cls_consumer);
474     if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
475     LOGD("JNIProviderService_onSubscribeListenerCb - OUT");
476     return;
477 }
478
479 void onSyncInfoListenerCb(OIC::Service::NSSyncInfo *sync)
480 {
481     LOGD("JNIProviderService_onSyncInfoListenerCb - IN");
482
483     jint envRet;
484     JNIEnv *env = GetJNIEnv(&envRet);
485     if (NULL == env) return ;
486
487     jobject jSyncListener = (jobject) env->NewLocalRef(g_obj_syncListener);
488     if (!jSyncListener)
489     {
490         LOGE ("Failed to Get jSyncListener");
491         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
492         return ;
493     }
494
495     LOGD("Sync ID : %ld\n", (long) sync->getMessageId());
496     LOGD("Sync STATE : %d\n", (int) sync->getState());
497
498     jlong jMessageId = (long)  sync->getMessageId();
499     jstring jProviderId = env->NewStringUTF(sync->getProviderId().c_str());
500     jobject syncType = getJavaSyncType(env, sync->getState());
501     if (!syncType)
502     {
503         LOGE ("Failed to Get syncType for SyncInfo");
504         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
505         return ;
506     }
507     jclass cls_SyncInfo = (jclass) (env->NewLocalRef(g_cls_SyncInfo));
508     if (!cls_SyncInfo)
509     {
510         LOGE ("Failed to Get ObjectClass for SyncInfo");
511         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
512         return ;
513     }
514     jmethodID mid_syncInfo = env->GetMethodID(
515                                  cls_SyncInfo,
516                                  "<init>",
517                                  "(JLjava/lang/String;Lorg/iotivity/service/ns/common/SyncInfo$SyncType;)V");
518     if (!mid_syncInfo)
519     {
520         LOGE ("Failed to Get MethodID for SyncInfo");
521         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
522         return ;
523     }
524
525     jobject obj_syncInfo = env->NewObject( cls_SyncInfo, mid_syncInfo,
526                                            jMessageId, jProviderId, syncType);
527     if (!obj_syncInfo)
528     {
529         LOGE ("Failed to Get Object for SyncInfo");
530         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
531         return ;
532     }
533
534     jclass cls = env->GetObjectClass( jSyncListener);
535     if (!cls)
536     {
537         LOGE("Failed to Get ObjectClass");
538         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
539         return;
540     }
541     jmethodID mid = env->GetMethodID(
542                         cls,
543                         "onSyncInfoReceived",
544                         "(Lorg/iotivity/service/ns/common/SyncInfo;)V");
545     if (!mid)
546     {
547         LOGE("Failed to Get MethodID");
548         if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
549         return;
550     }
551     env->CallVoidMethod( jSyncListener, mid, obj_syncInfo);
552
553     env->DeleteLocalRef(jSyncListener);
554     env->DeleteLocalRef(cls_SyncInfo);
555     if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread();
556
557     LOGD("JNIProviderService: OnSyncInfoListenerCb - OUT");
558     return;
559
560 }
561
562 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStart(
563     JNIEnv *env, jobject jObj, jboolean jPolicy, jobject jSubscriptionListener,
564     jobject jSyncListener)
565 {
566     LOGD("JNIProviderService: nativeStart - IN");
567     if (!jSubscriptionListener || !jSyncListener)
568     {
569         LOGE("Fail to set listeners");
570         ThrowNSException(NS_ERROR, "Listener cannot be null");
571         return (jint) OIC::Service::NSResult::ERROR;
572     }
573
574     if (g_obj_subscriptionListener != NULL)
575     {
576         env->DeleteGlobalRef(g_obj_subscriptionListener);
577     }
578     if (g_obj_syncListener != NULL)
579     {
580         env->DeleteGlobalRef(g_obj_syncListener);
581     }
582
583     g_obj_subscriptionListener = (jobject)  env->NewGlobalRef(jSubscriptionListener);
584     g_obj_syncListener = (jobject)  env->NewGlobalRef(jSyncListener);
585
586     // check access policy
587
588     OIC::Service::NSProviderService::ProviderConfig cfg;
589     cfg.m_subscribeRequestCb =  onSubscribeListenerCb;
590     cfg.m_syncInfoCb =  onSyncInfoListenerCb;
591     cfg.policy = (bool) jPolicy;
592
593     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->Start(cfg);
594     if (result != OIC::Service::NSResult::OK)
595     {
596         LOGE("Fail to start NSProviderService");
597
598     }
599
600     LOGD("JNIProviderService: nativeStart - OUT");
601     return (jint) result;
602 }
603
604 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStop(
605     JNIEnv *env, jobject jObj)
606 {
607     LOGD("JNIProviderService: nativeStop - IN");
608
609     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->Stop();
610     if (result !=  OIC::Service::NSResult::OK)
611     {
612         LOGD("Fail to stop NSProvider service");
613         return (jint) result;
614     }
615
616     env->DeleteGlobalRef( g_obj_subscriptionListener);
617     env->DeleteGlobalRef( g_obj_syncListener);
618     g_obj_subscriptionListener = NULL;
619     g_obj_syncListener = NULL;
620
621     LOGD("JNIProviderService: nativeStop - OUT");
622     return (jint) result;
623 }
624
625 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendMessage(
626     JNIEnv *env, jobject jObj, jobject jMsg)
627 {
628     LOGD("JNIProviderService: nativeSendMessage - IN");
629     if (!jMsg)
630     {
631         LOGD("Fail to send notification - Message is null");
632         ThrowNSException(NS_ERROR, "Message cannot be null");
633         return (jint) OIC::Service::NSResult::ERROR;
634     }
635     OIC::Service::NSMessage *nsMsg = getNativeMessage(env, jMsg);
636     if (nsMsg == nullptr)
637     {
638         ThrowNSException(NS_ERROR, "Message didn't have a field ID ");
639         return (jint) OIC::Service::NSResult::ERROR;
640     }
641
642     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->SendMessage(nsMsg);
643     if (result !=  OIC::Service::NSResult::OK)
644     {
645         LOGD("Fail to send NSProvider Message");
646     }
647     LOGD("JNIProviderService: nativeSendMessage - OUT");
648     return (jint) result;
649 }
650
651 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendSyncInfo(
652     JNIEnv *env, jobject jObj, jlong messageId , jint syncState)
653 {
654     LOGD("JNIProviderService: nativeSendSyncInfo - IN");
655     OIC::Service::NSProviderService::getInstance()->SendSyncInfo( messageId,
656             (OIC::Service::NSSyncInfo::NSSyncType) syncState);
657     LOGD("JNIProviderService: nativeSendSyncInfo - OUT");
658     return;
659 }
660
661 JNIEXPORT jint JNICALL
662 Java_org_iotivity_service_ns_provider_ProviderService_nativeEnableRemoteService(JNIEnv *env,
663         jobject jObj, jstring jstr)
664 {
665     LOGD("JNIProviderService: nativeEnableRemoteService - IN");
666     if (!jstr)
667     {
668         ThrowNSException(NS_ERROR, "Server Address Can't be NULL");
669         return (jint) OIC::Service::NSResult::ERROR;
670     }
671
672     const char *address = env->GetStringUTFChars( jstr, NULL);
673     std::string servAddress(address);
674     OIC::Service::NSResult result  =
675         OIC::Service::NSProviderService::getInstance()->EnableRemoteService(
676             servAddress);
677     if (result !=  OIC::Service::NSResult::OK)
678     {
679         LOGE("Fail to Enable Remote Service");
680     }
681     env->ReleaseStringUTFChars(jstr, address);
682     LOGD("JNIProviderService: nativeEnableRemoteService - OUT");
683     return (jint) result;
684 }
685
686 JNIEXPORT jint JNICALL
687 Java_org_iotivity_service_ns_provider_ProviderService_nativeDisableRemoteService(JNIEnv *env,
688         jobject jObj, jstring jstr)
689 {
690     LOGD("JNIProviderService: nativeDisableRemoteService - IN");
691     if (!jstr)
692     {
693         ThrowNSException(NS_ERROR, "Server Address Can't be NULL");
694         return (jint) OIC::Service::NSResult::ERROR;
695     }
696
697     const char *address = env->GetStringUTFChars( jstr, NULL);
698     std::string servAddress(address);
699     OIC::Service::NSResult result  =
700         OIC::Service::NSProviderService::getInstance()->DisableRemoteService(
701             servAddress);
702     if (result !=  OIC::Service::NSResult::OK)
703     {
704         LOGE("Fail to Disable Remote Service");
705     }
706     env->ReleaseStringUTFChars(jstr, address);
707     LOGD("JNIProviderService: nativeDisableRemoteService - OUT");
708     return (jint) result;
709 }
710
711 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeAddTopic
712 (JNIEnv *env, jobject jObj, jstring jTopicName)
713 {
714     LOGD("JNIProviderService: nativeAddTopic - IN");
715     if (!jTopicName)
716     {
717         ThrowNSException(NS_ERROR, "Topic Name Can't be NULL");
718         return (jint) OIC::Service::NSResult::ERROR;
719     }
720     const char *name = env->GetStringUTFChars( jTopicName, NULL);
721     std::string topicName(name);
722     OIC::Service::NSResult result  = OIC::Service::NSProviderService::getInstance()->AddTopic(
723                                          topicName);
724     if (result !=  OIC::Service::NSResult::OK)
725     {
726         LOGE("Fail to Add Topic");
727     }
728     env->ReleaseStringUTFChars(jTopicName, name);
729     LOGD("JNIProviderService: nativeAddTopic - OUT");
730     return (jint) result;
731 }
732 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeDeleteTopic
733 (JNIEnv *env, jobject jObj, jstring jTopicName)
734 {
735     LOGD("JNIProviderService: nativeDeleteTopic - IN");
736     if (!jTopicName)
737     {
738         ThrowNSException(NS_ERROR, "Topic Name Can't be NULL");
739         return (jint) OIC::Service::NSResult::ERROR;
740     }
741     const char *name = env->GetStringUTFChars( jTopicName, NULL);
742     std::string topicName(name);
743     OIC::Service::NSResult result  = OIC::Service::NSProviderService::getInstance()->DeleteTopic(
744                                          topicName);
745     if (result !=  OIC::Service::NSResult::OK)
746     {
747         LOGE("Fail to Add Topic");
748     }
749     env->ReleaseStringUTFChars(jTopicName, name);
750     LOGD("JNIProviderService: nativeDeleteTopic - OUT");
751     return (jint) result;
752 }
753
754 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeGetTopics
755 (JNIEnv *env, jobject jObj)
756 {
757     LOGD("JNIProviderService: nativeGetTopics - IN");
758
759     OIC::Service::NSTopicsList *topicList  =
760         OIC::Service::NSProviderService::getInstance()->GetTopics();
761     if (topicList == nullptr)
762     {
763         ThrowNSException(NS_ERROR, "Topic List doesn't exist");
764         return NULL;
765     }
766
767     jobject obj_topicList = getJavaTopicsList(env, topicList);
768
769     LOGD("JNIProviderService: nativeGetTopics - OUT");
770     return obj_topicList;
771 }
772
773 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeAcceptSubscription(
774     JNIEnv *env,  jobject jObj, jobject jConsumer, jboolean jAccepted)
775 {
776     LOGD("JNIProviderService: nativeAcceptSubscription - IN");
777
778     jclass consumerClass =  env->GetObjectClass( jConsumer);
779     if (!consumerClass)
780     {
781         ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Consumer");
782         return (jint) OIC::Service::NSResult::ERROR;
783     }
784
785     // Consumer ID
786     jfieldID fid_id =  env->GetFieldID(consumerClass, "mConsumerId",  "Ljava/lang/String;");
787     if (fid_id == NULL)
788     {
789         LOGE("Error: jfieldID for mConsumerId  is null");
790         ThrowNSException(NS_ERROR, "ConsumerId not found");
791         return (jint) OIC::Service::NSResult::ERROR;
792     }
793
794     jstring jconId = (jstring)env->GetObjectField( jConsumer, fid_id);
795     if (!jconId)
796     {
797         ThrowNSException(NS_ERROR, "ProviderId cannot be null");
798         return (jint) OIC::Service::NSResult::ERROR;
799     }
800     const char *conId = env->GetStringUTFChars( jconId, NULL);
801     std::string consumerId(conId);
802     env->ReleaseStringUTFChars(jconId, conId);
803
804     LOGD("Consumer ID: %s\n", consumerId.c_str());
805
806     OIC::Service::NSConsumer *consumer =
807         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
808     if (consumer)
809         return (jint) consumer->acceptSubscription(consumer,  (bool)jAccepted);
810
811     LOGE("Couldn't find consumer");
812     LOGD("JNIProviderService: nativeAcceptSubscription - OUT");
813     return (jint) OIC::Service::NSResult::ERROR;
814 }
815 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeSelectTopic
816 (JNIEnv *env, jobject jObj, jstring jConsumerId, jstring jTopicName)
817 {
818     LOGD("JNIProviderService: nativeSelectTopic - IN");
819     if (!jConsumerId || !jTopicName)
820     {
821         ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
822         return (jint) OIC::Service::NSResult::ERROR;
823     }
824     const char *name = env->GetStringUTFChars( jTopicName, NULL);
825     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
826     std::string topicName(name);
827     std::string consumerId(id);
828     OIC::Service::NSConsumer *nsConsumer =
829         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
830     if (!nsConsumer)
831     {
832         ThrowNSException(NS_ERROR, "Consumer does exists");
833         return (jint) OIC::Service::NSResult::ERROR;
834     }
835     OIC::Service::NSResult result  = nsConsumer->selectTopic(topicName);
836
837     if (result !=  OIC::Service::NSResult::OK)
838     {
839         LOGD("Fail to Select Topic");
840     }
841     env->ReleaseStringUTFChars(jTopicName, name);
842     env->ReleaseStringUTFChars(jConsumerId, id);
843     LOGD("JNIProviderService: nativeSelectTopic - OUT");
844     return (jint) result;
845 }
846 JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeUnselectTopic
847 (JNIEnv *env, jobject jObj, jstring jConsumerId, jstring jTopicName)
848 {
849     LOGD("JNIProviderService: nativeUnselectTopic - IN");
850     if (!jConsumerId || !jTopicName)
851     {
852         ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
853         return (jint) OIC::Service::NSResult::ERROR;
854     }
855     const char *name = env->GetStringUTFChars( jTopicName, NULL);
856     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
857     std::string topicName(name);
858     std::string consumerId(id);
859     OIC::Service::NSConsumer *nsConsumer =
860         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
861     if (!nsConsumer)
862     {
863         ThrowNSException(NS_ERROR, "Consumer does exists");
864         return (jint) OIC::Service::NSResult::ERROR;
865     }
866     OIC::Service::NSResult result  = nsConsumer->unselectTopic(topicName);
867
868     if (result !=  OIC::Service::NSResult::OK)
869     {
870         LOGE("Fail to Unselect Topic");
871     }
872     env->ReleaseStringUTFChars(jTopicName, name);
873     env->ReleaseStringUTFChars(jConsumerId, id);
874     LOGD("JNIProviderService: nativeUnselectTopic - OUT");
875     return (jint) result;
876 }
877
878 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeGetConsumerTopics
879 (JNIEnv *env, jobject jObj, jstring jConsumerId)
880 {
881     LOGD("JNIProviderService: nativeGetConsumerTopics - IN");
882     if (!jConsumerId)
883     {
884         ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
885         return NULL;
886     }
887     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
888     std::string consumerId(id);
889     OIC::Service::NSConsumer *nsConsumer =
890         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
891     if (!nsConsumer)
892     {
893         ThrowNSException(NS_ERROR, "Consumer does exists");
894         return NULL;
895     }
896     env->ReleaseStringUTFChars(jConsumerId, id);
897     OIC::Service::NSTopicsList *topicList  = nsConsumer->getConsumerTopics();
898     if (topicList == nullptr)
899     {
900         ThrowNSException(NS_ERROR, "Topic List doesn't exist");
901         return NULL;
902     }
903     jobject obj_topicList = getJavaTopicsList(env, topicList);
904     LOGD("JNIProviderService: nativeGetConsumerTopics - OUT");
905     return obj_topicList;
906 }
907
908 // JNI OnLoad
909 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
910 {
911     LOGD("ProviderService_JNI_OnLoad");
912     g_jvm = jvm;
913
914     JNIEnv *env;
915     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)
916     {
917         LOGE("Failed to get the environment using GetEnv()");
918         return JNI_ERR;
919     }
920
921     jclass localMessage = env->FindClass(
922                               "org/iotivity/service/ns/common/Message");
923     if (!localMessage)
924     {
925         LOGE("Failed to get local Message class");
926         return JNI_ERR;
927     }
928     g_cls_Message = (jclass) (env->NewGlobalRef(localMessage));
929     if (!g_cls_Message)
930     {
931         LOGE("Failed to set Global Message reference");
932         return JNI_ERR;
933     }
934
935     jclass localMessageType = env->FindClass(
936                                   "org/iotivity/service/ns/common/Message$MessageType");
937     if (!localMessageType)
938     {
939         LOGE("Failed to get local Message Type class");
940         return JNI_ERR;
941     }
942     g_cls_Message_Type = (jclass) (env->NewGlobalRef(localMessageType));
943     if (!g_cls_Message_Type)
944     {
945         LOGE("Failed to set Global Message Type reference");
946         return JNI_ERR;
947     }
948
949     jclass localConsumer = env->FindClass(
950                                "org/iotivity/service/ns/provider/Consumer");
951     if (!localConsumer)
952     {
953         LOGE("Failed to get local Provider class");
954         return JNI_ERR;
955     }
956     g_cls_Consumer = (jclass) (env->NewGlobalRef(localConsumer));
957     if (!g_cls_Consumer)
958     {
959         LOGE("Failed to set Global Provider reference");
960         return JNI_ERR;
961     }
962
963     jclass localSyncInfo = env->FindClass(
964                                "org/iotivity/service/ns/common/SyncInfo");
965     if (!localSyncInfo)
966     {
967         LOGE("Failed to get local SyncInfo class");
968         return JNI_ERR;
969     }
970     g_cls_SyncInfo = (jclass) (env->NewGlobalRef(localSyncInfo));
971     if (!g_cls_SyncInfo)
972     {
973         LOGE("Failed to set Global SyncInfo reference");
974         return JNI_ERR;
975     }
976
977     jclass localSyncType = env->FindClass(
978                                "org/iotivity/service/ns/common/SyncInfo$SyncType");
979     if (!localSyncType)
980     {
981         LOGE("Failed to get local SyncType enum");
982         return JNI_ERR;
983     }
984     g_cls_SyncType = (jclass) (env->NewGlobalRef(localSyncType));
985     if (!g_cls_SyncType)
986     {
987         LOGE("Failed to set Global SyncType reference");
988         return JNI_ERR;
989     }
990
991     jclass localMediaContents = env->FindClass(
992                                     "org/iotivity/service/ns/common/MediaContents");
993     if (!localMediaContents)
994     {
995         LOGE("Failed to get local MediaContents class");
996         return JNI_ERR;
997     }
998     g_cls_MediaContents = (jclass) (env->NewGlobalRef(localMediaContents));
999     if (!g_cls_MediaContents)
1000     {
1001         LOGE("Failed to set Global MediaContents reference");
1002         return JNI_ERR;
1003     }
1004
1005     jclass localTopic = env->FindClass(
1006                             "org/iotivity/service/ns/common/Topic");
1007     if (!localTopic)
1008     {
1009         LOGE("Failed to get local Topic class");
1010         return JNI_ERR;
1011     }
1012     g_cls_Topic = (jclass) (env->NewGlobalRef(localTopic));
1013     if (!g_cls_Topic)
1014     {
1015         LOGE("Failed to set Global Topic reference");
1016         return JNI_ERR;
1017     }
1018
1019     jclass localTopicsList = env->FindClass(
1020                                  "org/iotivity/service/ns/common/TopicsList");
1021     if (!localTopicsList)
1022     {
1023         LOGE("Failed to get local Topic class");
1024         return JNI_ERR;
1025     }
1026     g_cls_TopicsList = (jclass) (env->NewGlobalRef(localTopicsList));
1027     if (!g_cls_TopicsList)
1028     {
1029         LOGE("Failed to set Global TopicsList reference");
1030         return JNI_ERR;
1031     }
1032
1033     jclass localTopicState = env->FindClass(
1034                                  "org/iotivity/service/ns/common/Topic$TopicState");
1035     if (!localTopicState)
1036     {
1037         LOGE("Failed to get local TopicState enum");
1038         return JNI_ERR;
1039     }
1040     g_cls_TopicState = (jclass) (env->NewGlobalRef(localTopicState));
1041     if (!g_cls_TopicState)
1042     {
1043         LOGE("Failed to set Global TopicState reference");
1044         return JNI_ERR;
1045     }
1046
1047     env->DeleteLocalRef(localMessage);
1048     env->DeleteLocalRef(localMessageType);
1049     env->DeleteLocalRef(localConsumer);
1050     env->DeleteLocalRef(localSyncInfo);
1051     env->DeleteLocalRef(localSyncType);
1052     env->DeleteLocalRef(localMediaContents);
1053     env->DeleteLocalRef(localTopic);
1054     env->DeleteLocalRef(localTopicsList);
1055     env->DeleteLocalRef(localTopicState);
1056
1057     return NSExceptionInit(env);
1058 }
1059
1060 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)
1061 {
1062     LOGD("ProviderService_JNI_OnUnload");
1063     JNIEnv *env;
1064
1065     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)
1066     {
1067         LOGE("Failed to get the environment using GetEnv()");
1068         return ;
1069     }
1070
1071     env->DeleteGlobalRef(g_cls_Message);
1072     env->DeleteGlobalRef(g_cls_Consumer);
1073     env->DeleteGlobalRef(g_cls_SyncInfo);
1074     env->DeleteGlobalRef(g_cls_SyncType);
1075     env->DeleteGlobalRef(g_cls_MediaContents);
1076     env->DeleteGlobalRef(g_cls_Message_Type);
1077     env->DeleteGlobalRef(g_cls_Topic);
1078     env->DeleteGlobalRef(g_cls_TopicsList);
1079     env->DeleteGlobalRef(g_cls_TopicState);
1080 }