Merge branch 'master' into notification-service
authorHun-je Yeon <hunje.yeon@samsung.com>
Wed, 20 Jul 2016 04:56:17 +0000 (13:56 +0900)
committerHun-je Yeon <hunje.yeon@samsung.com>
Wed, 20 Jul 2016 04:57:08 +0000 (13:57 +0900)
Update sync with master in which cloud interface branch is merged.

Change-Id: Ib79964b58bb4253337524d5fb18278cc66943363
Signed-off-by: Hun-je Yeon <hunje.yeon@samsung.com>
116 files changed:
.gitignore
service/SConscript
service/notification/SConscript [new file with mode: 0644]
service/notification/android/SConscript [new file with mode: 0644]
service/notification/android/android_api.iml [new file with mode: 0644]
service/notification/android/build.gradle [new file with mode: 0644]
service/notification/android/gradle.properties [new file with mode: 0644]
service/notification/android/gradlew [new file with mode: 0644]
service/notification/android/gradlew.bat [new file with mode: 0644]
service/notification/android/notification-service/base.iml [new file with mode: 0644]
service/notification/android/notification-service/build.gradle [new file with mode: 0644]
service/notification/android/notification-service/proguard-rules.pro [new file with mode: 0644]
service/notification/android/notification-service/src/main/AndroidManifest.xml [new file with mode: 0644]
service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/IoTNotification.java [new file with mode: 0644]
service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSConsumer.java [new file with mode: 0644]
service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSMessage.java [new file with mode: 0644]
service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSSync.java [new file with mode: 0644]
service/notification/android/notification-service/src/main/jni/Android.mk [new file with mode: 0644]
service/notification/android/notification-service/src/main/jni/Application.mk [new file with mode: 0644]
service/notification/android/notification-service/src/main/jni/notificationProvider.c [new file with mode: 0644]
service/notification/android/notification-service/src/main/jni/notificationProvider.h [new file with mode: 0644]
service/notification/android/settings.gradle [new file with mode: 0644]
service/notification/examples/SConscript [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.gitignore [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/.name [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/compiler.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/copyright/profiles_settings.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/gradle.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/inspectionProfiles/Project_Default.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/inspectionProfiles/profiles_settings.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/misc.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/modules.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/runConfigurations.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/.idea/vcs.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/.gitignore [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/build.gradle [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/proguard-rules.pro [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/AndroidManifest.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/NotiListener.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderProxy.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_main.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-hdpi/ic_launcher.png [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-mdpi/ic_launcher.png [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xhdpi/ic_launcher.png [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values-w820dp/dimens.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values/colors.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values/dimens.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values/strings.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values/styles.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/test/java/com/sec/notiproviderexample/ExampleUnitTest.java [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/build.gradle [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/gradlew.bat [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/iotivity-armeabi-notification-service-release/build.gradle [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/iotivity-base-armeabi-release/build.gradle [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/settings.gradle [new file with mode: 0644]
service/notification/examples/linux/SConscript [new file with mode: 0644]
service/notification/examples/linux/cloud_connector.c [new file with mode: 0644]
service/notification/examples/linux/cloud_connector.h [new file with mode: 0644]
service/notification/examples/linux/notificationconsumer.c [new file with mode: 0644]
service/notification/examples/linux/notificationprovider.c [new file with mode: 0644]
service/notification/include/NSCommon.h [new file with mode: 0644]
service/notification/include/NSConsumerInterface.h [new file with mode: 0644]
service/notification/include/NSProviderInterface.h [new file with mode: 0644]
service/notification/src/common/NSCloudConnector.c [new file with mode: 0644]
service/notification/src/common/NSCloudConnector.h [new file with mode: 0644]
service/notification/src/common/NSConstants.h [new file with mode: 0644]
service/notification/src/common/NSStorageAdapter.h [new file with mode: 0644]
service/notification/src/common/NSStructs.h [new file with mode: 0644]
service/notification/src/common/NSUtil.c [new file with mode: 0755]
service/notification/src/common/NSUtil.h [new file with mode: 0755]
service/notification/src/consumer/NSConsumerCommon.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerCommon.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerCommunication.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerCommunication.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerDiscovery.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerDiscovery.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerInterface.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerInternalTaskController.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerInternalTaskController.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerNetworkEventListener.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerNetworkEventListener.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerQueue.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerQueue.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerScheduler.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerScheduler.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerSystem.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerSystem.h [new file with mode: 0644]
service/notification/src/consumer/NSThread.c [new file with mode: 0644]
service/notification/src/consumer/NSThread.h [new file with mode: 0644]
service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.c [new file with mode: 0644]
service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.h [new file with mode: 0644]
service/notification/src/provider/NSProviderDiscovery.c [new file with mode: 0644]
service/notification/src/provider/NSProviderDiscovery.h [new file with mode: 0644]
service/notification/src/provider/NSProviderInterface.c [new file with mode: 0644]
service/notification/src/provider/NSProviderListener.c [new file with mode: 0644]
service/notification/src/provider/NSProviderListener.h [new file with mode: 0644]
service/notification/src/provider/NSProviderNotification.c [new file with mode: 0644]
service/notification/src/provider/NSProviderNotification.h [new file with mode: 0644]
service/notification/src/provider/NSProviderResource.c [new file with mode: 0644]
service/notification/src/provider/NSProviderResource.h [new file with mode: 0644]
service/notification/src/provider/NSProviderScheduler.c [new file with mode: 0755]
service/notification/src/provider/NSProviderScheduler.h [new file with mode: 0755]
service/notification/src/provider/NSProviderSubscription.c [new file with mode: 0644]
service/notification/src/provider/NSProviderSubscription.h [new file with mode: 0644]
service/notification/src/provider/NSProviderSystem.c [new file with mode: 0644]
service/notification/src/provider/NSProviderSystem.h [new file with mode: 0644]
service/notification/src/provider/cache/linux/NSProviderMemoryCache.c [new file with mode: 0755]
service/notification/src/provider/cache/linux/NSProviderMemoryCache.h [new file with mode: 0755]
service/notification/unittest/NSConsumerSimulator.h [new file with mode: 0644]
service/notification/unittest/NSConsumerTest.cpp [new file with mode: 0644]
service/notification/unittest/NSProviderSimulator.h [new file with mode: 0644]
service/notification/unittest/NSProviderTest.cpp [new file with mode: 0644]
service/notification/unittest/SConscript [new file with mode: 0644]

index 7d0ce16..62afd32 100644 (file)
@@ -49,6 +49,11 @@ service/things-manager/build/linux/release
 service/things-manager/build/linux/debug
 service/things-manager/sdk/build/linux/
 
+service/notification/android/.gradle/
+service/notification/android/build/
+service/notification/android/notification-service/build/
+service/notification/android/notification-service/src/main/obj/
+
 # Ignore any object files
 *.o
 *.os
@@ -84,6 +89,7 @@ config.log
 os
 out/
 platform
+iotivity.pc
 
 # Ignore downloaded dependencies
 extlibs/gtest/gtest-*
@@ -111,6 +117,9 @@ extlibs/bluez/bluez
 *~
 *#*#
 *.orig
+.cproject
+.gradle/
+.project
 
 # Ignore byte-compiled Python scripts
 *.pyc
index 114be6e..8c956e0 100755 (executable)
@@ -30,7 +30,7 @@ if target_os not in ['arduino','darwin', 'ios', 'windows']:
     # Build things manager project
     SConscript('things-manager/SConscript')
 
-    # Build notification manager project
+    # Build resource-hosting project
     SConscript('resource-hosting/SConscript')
 
     # Build resource-encapsulation project
@@ -43,6 +43,10 @@ if target_os not in ['arduino','darwin', 'ios', 'windows']:
     if target_os in ['linux']:
         SConscript('scene-manager/SConscript')
 
+    # Build notification-service project    
+    if target_os in ['linux','android']:
+        SConscript('notification/SConscript')
+
     # Build simulator module
     if target_os in ['linux'] and env.get('SIMULATOR', False):
         SConscript('simulator/SConscript')
diff --git a/service/notification/SConscript b/service/notification/SConscript
new file mode 100644 (file)
index 0000000..75397e0
--- /dev/null
@@ -0,0 +1,138 @@
+#******************************************************************
+#
+# Copyright 2016 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# Notification Service build script
+##
+
+import platform
+Import('env')
+
+if env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+notification_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+notification_env.AppendUnique(CPPPATH = ['include'])
+notification_env.AppendUnique(CPPPATH = ['src/common'])
+notification_env.AppendUnique(CPPPATH = ['src/provider'])
+notification_env.AppendUnique(CPPPATH = ['src/consumer'])
+notification_env.AppendUnique(CPPPATH = ['../../resource/csdk/stack/include'])
+notification_env.AppendUnique(CPPPATH = ['../../resource/csdk/connectivity/api'])
+
+if target_os == 'linux':
+    notification_env.AppendUnique(CPPPATH = ['src/provider/cache/linux'])
+    notification_env.AppendUnique(CPPPATH = ['src/consumer/cache/linux'])
+
+# [TO-DO] change to android DB. 
+if target_os == 'android': 
+    notification_env.AppendUnique(CPPPATH = ['src/provider/cache/linux'])
+    notification_env.AppendUnique(CPPPATH = ['src/consumer/cache/linux'])
+
+notification_env.PrependUnique(LIBS = [
+       'octbstack',
+       'oc_logger',
+       'connectivity_abstraction',
+       'libcoap'
+       ])
+
+if target_os not in ['windows', 'winrt']:
+       notification_env.AppendUnique(CCFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0'])
+
+if target_os not in ['darwin', 'ios', 'windows', 'winrt']:
+       notification_env.AppendUnique(LINKFLAGS = ['-Wl,--no-undefined'])
+
+if target_os == 'linux':
+       notification_env.AppendUnique(LIBS = ['pthread'])
+
+if target_os == 'android':
+       notification_env.AppendUnique(CCFLAGS = ['-frtti', '-fexceptions'])
+       notification_env.AppendUnique(LIBS = ['gnustl_shared','log'])
+       notification_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libnotification_provider.so'])
+
+       if not env.get('RELEASE'):
+               notification_env.AppendUnique(LIBS = ['log'])
+
+if not env.get('RELEASE'):
+    notification_env.PrependUnique(LIBS = ['gcov'])
+    notification_env.AppendUnique(CCFLAGS = ['--coverage'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+
+if target_os == 'linux':
+    PROVIDER_CACHE = File('src/provider/cache/linux/NSProviderMemoryCache.c')
+    CONSUMER_CACHE = File('src/consumer/cache/linux/NSConsumerMemoryCache.c')
+
+if target_os == 'android':
+    PROVIDER_CACHE = File('src/provider/cache/linux/NSProviderMemoryCache.c')
+    CONSUMER_CACHE = File('src/consumer/cache/linux/NSConsumerMemoryCache.c')
+
+notification_provider_src = [
+       env.Glob('src/provider/*.c'),
+       env.Glob('src/common/*.c'), PROVIDER_CACHE]
+notification_consumer_src = [
+       env.Glob('src/consumer/*.c'),
+       env.Glob('src/common/*.c'), CONSUMER_CACHE]
+
+providersdk = notification_env.SharedLibrary('notification_provider', notification_provider_src)
+notification_env.InstallTarget(providersdk, 'libnotification_provider')
+notification_env.UserInstallTargetLib(providersdk, 'libnotification_provider')
+
+consumersdk = notification_env.SharedLibrary('notification_consumer', notification_consumer_src)
+notification_env.InstallTarget(consumersdk, 'libnotification_consumer')
+notification_env.UserInstallTargetLib(consumersdk, 'libnotification_consumer')
+
+providersdk = notification_env.StaticLibrary('notification_provider', notification_provider_src)
+notification_env.InstallTarget(providersdk, 'libnotification_provider')
+notification_env.UserInstallTargetLib(providersdk, 'libnotification_provider')
+
+consumersdk = notification_env.StaticLibrary('notification_consumer', notification_consumer_src)
+notification_env.InstallTarget(consumersdk, 'libnotification_consumer')
+notification_env.UserInstallTargetLib(consumersdk, 'libnotification_consumer')
+
+notification_env.UserInstallTargetHeader('include/NSProviderInterface.h',\
+       'service/notification', 'NSProviderInterface.h')
+notification_env.UserInstallTargetHeader('include/NSConsumerInterface.h',\
+       'service/notification', 'NSConsumerInterface.h')
+
+# Go to build Unit test
+# if target_os == 'linux':
+#      SConscript('unittest/SConscript')
+
+# Go to build sample apps
+SConscript('examples/SConscript')
+
+# Go to build jni
+if target_os == 'android':
+    SConscript('android/SConscript')
diff --git a/service/notification/android/SConscript b/service/notification/android/SConscript
new file mode 100644 (file)
index 0000000..701b1a6
--- /dev/null
@@ -0,0 +1,55 @@
+import os
+import platform
+Import('env')
+
+android_home = env.get('ANDROID_HOME')
+
+ANDROID_TARGET_ARCH = env.get('TARGET_ARCH')
+if env.get('RELEASE'):
+       ANDROID_RELEASE="release"
+else:
+       ANDROID_RELEASE="debug"
+
+os.environ['ANDROID_HOME'] = env.get('ANDROID_HOME')
+os.environ['ANDROID_NDK_HOME'] = env.get('ANDROID_NDK')
+
+if not os.path.exists(android_home + '/platforms/android-21') or not os.path.exists(android_home + '/build-tools/20.0.0'):
+    print '''
+***************************************** Info ********************************
+*   Either 'Android API 21' is not installed or 'Android SDK Build Tools      *
+*   20.0.0' is not installed. The Android SDK Manager will now open. Please   *
+*   be sure to deselect all options, then select the following 2 packages:    *
+*       1. Under "Tools" select "Android SDK Build-tools" Revision 20.        *
+*       2. Under "Android 5.0.1 (API 21)" select "SDK Platform"               *
+*       3. Continue by selecting "Install 2 Packages"                         *
+*                                                                             *
+*   NOTE: If you have an http proxy, please press ctrl+c now and edit/create  *
+*         the following file in your $HOME directory as follows:              *
+*                                                                             *
+* Edit/Create file: "$HOME/.android/androidtool.cfg"                          *
+*                                                                             *
+*    http.proxyPort=<YOUR_PORT_NUMBER>                                        *
+*    sdkman.monitor.density=108                                               *
+*    http.proxyHost=<YOUR_HTTP_PROXY_ADDRESS>                                 *
+*    sdkman.show.update.only=true                                             *
+*    sdkman.ask.adb.restart=false                                             *
+*    sdkman.force.http=true                                                   *
+*    sdkman.show.updateonly=true                                              *
+*                                                                             *
+*******************************************************************************
+
+...Opening Android SDK Manager now. Once you are finished, the build will continue.
+'''
+    os.system(android_home + '/tools/android')
+
+
+def ensure_libs(target, source, env):
+    return target, [source, env.get('BUILD_DIR') + 'liboc.so', env.get('BUILD_DIR') + 'liboc_logger.so']
+
+jdk_env = Environment(ENV=os.environ)
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + 
+    ' build -bservice/notification/android/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE),
+    emitter = ensure_libs)
+jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
+jdk_env.Gradle(target="notification-service/objs", 
+    source="notification-service/src/main/java/org/iotivity/service/notification/IoTNotification.java")
diff --git a/service/notification/android/android_api.iml b/service/notification/android/android_api.iml
new file mode 100644 (file)
index 0000000..0bb6048
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/service/notification/android/build.gradle b/service/notification/android/build.gradle
new file mode 100644 (file)
index 0000000..cbfddfd
--- /dev/null
@@ -0,0 +1,40 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.3.0'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter {
+            url "http://jcenter.bintray.com/"
+        }
+    }
+}
diff --git a/service/notification/android/gradle.properties b/service/notification/android/gradle.properties
new file mode 100644 (file)
index 0000000..dff37f4
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# //******************************************************************
+# //
+# // Copyright 2015 Intel Corporation.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+# //
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/service/notification/android/gradlew b/service/notification/android/gradlew
new file mode 100644 (file)
index 0000000..91a7e26
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/service/notification/android/gradlew.bat b/service/notification/android/gradlew.bat
new file mode 100644 (file)
index 0000000..8a0b282
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/service/notification/android/notification-service/base.iml b/service/notification/android/notification-service/base.iml
new file mode 100644 (file)
index 0000000..3bf0877
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="android_api" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":base" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+        <option name="LIBRARY_PROJECT" value="true" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/native-libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/service/notification/android/notification-service/build.gradle b/service/notification/android/notification-service/build.gradle
new file mode 100644 (file)
index 0000000..50c7205
--- /dev/null
@@ -0,0 +1,107 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "20.0.0"
+    archivesBaseName = "iotivity"
+
+    libraryVariants.all { variant ->
+        variant.outputs.each { output ->
+            def outputFile = output.outputFile
+            if (outputFile != null && outputFile.name.endsWith('.aar')) {
+                def fileName = "${archivesBaseName}-${TARGET_ARCH}-${outputFile.name}"
+                output.outputFile = new File(outputFile.parent, fileName)
+            }
+        }
+    }
+
+    defaultConfig {
+        minSdkVersion 21
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    lintOptions {
+       abortOnError false
+    }
+
+    sourceSets {
+        main {
+            manifest.srcFile 'src/main/AndroidManifest.xml'
+            jni.srcDirs = [] //disable automatic ndk-build call
+            jniLibs.srcDir new File(buildDir, 'native-libs')
+        }
+        androidTest.setRoot('src/androidTest')
+    }
+}
+
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+
+    androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'
+    androidTestCompile 'com.google.dexmaker:dexmaker:1.0'
+    androidTestCompile 'org.mockito:mockito-core:1.10.19'
+}
+
+////////////////
+////NDK Support
+////////////////
+//If using this, Android studio will fail run the following to set the environment variable for android studio:
+//launchctl setenv ANDROID_NDK_HOME
+//otherwise remove the dependsOn part and run ./gradlew buildNative from the command line
+task copyNativeLibs(type: Copy, dependsOn: 'buildNative') {
+    dependsOn 'buildNative'
+    from(new File('src/main/libs')) { include '**/*.so' exclude '**/libgnustl_shared.so' }
+    into new File(buildDir, 'native-libs')
+}
+
+tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn copyNativeLibs }
+
+clean.dependsOn 'cleanCopyNativeLibs'
+
+tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
+    pkgTask ->
+    pkgTask.jniFolders = new HashSet<File>()
+    pkgTask.jniFolders.add(new File(buildDir, 'native-libs'))
+}
+
+task buildNative(type: Exec) {
+    if (System.env.ANDROID_NDK_HOME != null) {
+        //for windows use 'ndk-build.cmd'
+        //def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd')
+        def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build')
+        commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", '-C', file('src/main').absolutePath
+    } else {
+        println '##################'
+        println 'Skipping NDK build'
+        println 'Reason: ANDROID_NDK_HOME not set.'
+        println '##################'
+    }
+}
diff --git a/service/notification/android/notification-service/proguard-rules.pro b/service/notification/android/notification-service/proguard-rules.pro
new file mode 100644 (file)
index 0000000..c5f9a5b
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in C:/android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/service/notification/android/notification-service/src/main/AndroidManifest.xml b/service/notification/android/notification-service/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..5274599
--- /dev/null
@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.service.notification" />
\ No newline at end of file
diff --git a/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/IoTNotification.java b/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/IoTNotification.java
new file mode 100644 (file)
index 0000000..e5a1fe6
--- /dev/null
@@ -0,0 +1,35 @@
+package org.iotivity.service.notification;
+
+import android.util.Log;
+import org.iotivity.service.notification.NSMessage;
+import org.iotivity.service.notification.NSConsumer;
+import org.iotivity.service.notification.NSSync;
+
+public class IoTNotification
+{
+    public IoTNotification()
+    {
+    }
+
+    static
+    {
+        System.loadLibrary("notification_provider_jni");
+    }
+
+    public native int NSStartProvider(boolean access,
+        NSSubscriptionListner subscriptionListener,
+        NSSynchListner syncListener);
+    public native int NSStopProvider();
+    public native int NSSendNotification(NSMessage message);
+    public native int NSProviderReadCheck(NSMessage message);
+    public native int NSAccept(NSConsumer consumer, boolean accepted);
+
+    public interface NSSubscriptionListner {
+        public void OnNSSubscribedEvent(String consumerId);
+    }
+
+    public interface NSSynchListner {
+       public void OnNSSynchronizedEvent(String messageId, int syncState);
+    }
+}
+
diff --git a/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSConsumer.java b/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSConsumer.java
new file mode 100644 (file)
index 0000000..cbb75be
--- /dev/null
@@ -0,0 +1,26 @@
+package org.iotivity.service.notification;\r
+\r
+import android.util.Log;\r
+\r
+public class NSConsumer {\r
+       \r
+       String mId = null;\r
+       String mAddress = null;\r
+       \r
+       public NSConsumer(String id) {\r
+           this.mId = id;\r
+       }\r
+\r
+       public String getId() {\r
+           return mId;\r
+       }\r
+\r
+       public String getAddress() {\r
+           return mAddress;\r
+       }\r
+\r
+       public void setAddress(String address) {\r
+           this.mAddress = address;\r
+       }\r
+\r
+}\r
diff --git a/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSMessage.java b/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSMessage.java
new file mode 100644 (file)
index 0000000..c2d0343
--- /dev/null
@@ -0,0 +1,71 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+package org.iotivity.service.notification;\r
+\r
+import android.util.Log;\r
+\r
+public class NSMessage\r
+{\r
+    String id = null;\r
+    String title = null;\r
+    String body = null;\r
+    String source = null;\r
+\r
+    public NSMessage(String id)\r
+    {\r
+        this.id = id;\r
+    }\r
+\r
+    public String getId()\r
+    {\r
+        return id;\r
+    }\r
+\r
+    public String getTitle()\r
+    {\r
+        return title;\r
+    }\r
+\r
+    public void setTitle(String title)\r
+    {\r
+        this.title = title;\r
+    }\r
+\r
+    public String getBody()\r
+    {\r
+        return body;\r
+    }\r
+\r
+    public void setBody(String body)\r
+    {\r
+        this.body = body;\r
+    }\r
+\r
+    public String getSource()\r
+    {\r
+        return source;\r
+    }\r
+\r
+    public void setSource(String source)\r
+    {\r
+        this.source = source;\r
+    }\r
+}\r
diff --git a/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSSync.java b/service/notification/android/notification-service/src/main/java/org/iotivity/service/notification/NSSync.java
new file mode 100644 (file)
index 0000000..d958840
--- /dev/null
@@ -0,0 +1,35 @@
+package org.iotivity.service.notification;
+
+import android.util.Log;
+
+public class NSSync {
+
+       String mMessageId = null;
+       String mDeviceId = null;
+       String mSourceId = null;
+
+       public NSSync(String id) {
+           this.mMessageId = id;
+       }
+
+       public String getMessageId() {
+           return mMessageId;
+       }
+
+       public String getDeviceId() {
+           return mDeviceId;
+       }
+
+       public void setDeviceId(String id) {
+           this.mDeviceId = id;
+       }
+
+       public String getSourceId() {
+           return mSourceId;
+       }
+
+       public void setSourceId(String id) {
+           this.mSourceId = id;
+       }
+
+}
diff --git a/service/notification/android/notification-service/src/main/jni/Android.mk b/service/notification/android/notification-service/src/main/jni/Android.mk
new file mode 100644 (file)
index 0000000..1db4c3e
--- /dev/null
@@ -0,0 +1,40 @@
+LOCAL_PATH := $(call my-dir)
+
+ROOT_PATH := ../../../../../../..
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := $(ROOT_PATH)/out/android/$(TARGET_ARCH_ABI)/$(APP_OPTIM)
+LOCAL_MODULE := notification_provider
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libnotification_provider.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := notification_provider_jni
+LOCAL_CPPFLAGS := -std=c++0x -frtti -fexceptions
+
+LOCAL_STATIC_LIBRARIES := ca_interface
+LOCAL_STATIC_LIBRARIES += ca
+LOCAL_STATIC_LIBRARIES += oc_logger_core
+LOCAL_STATIC_LIBRARIES += oc_logger
+LOCAL_STATIC_LIBRARIES += octbstack
+LOCAL_STATIC_LIBRARIES += oc
+LOCAL_STATIC_LIBRARIES += ocstack-jni
+LOCAL_STATIC_LIBRARIES += notification_provider
+
+OIC_SRC_DIR := ../../../../../..
+
+LOCAL_C_INCLUDES := $(OIC_SRC_DIR)/resource/csdk/stack/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/csdk/logger/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/c_common
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/oc_logger/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/notification/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/notification/src/common
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/notification/src/provider
+                    
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/extlibs/
+
+LOCAL_SRC_FILES := notificationProvider.c
+LOCAL_LDLIBS := -llog
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/service/notification/android/notification-service/src/main/jni/Application.mk b/service/notification/android/notification-service/src/main/jni/Application.mk
new file mode 100644 (file)
index 0000000..3baa444
--- /dev/null
@@ -0,0 +1,2 @@
+APP_STL:=gnustl_shared
+NDK_TOOLCHAIN_VERSION := 4.9
diff --git a/service/notification/android/notification-service/src/main/jni/notificationProvider.c b/service/notification/android/notification-service/src/main/jni/notificationProvider.c
new file mode 100644 (file)
index 0000000..1567393
--- /dev/null
@@ -0,0 +1,312 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include <android/log.h>\r
+#include <stdio.h>\r
+#include "notificationProvider.h"\r
+\r
+#define  LOG_TAG   "JNI_NS_INTERFACE"\r
+#define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)\r
+#define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)\r
+\r
+static JavaVM *g_jvm = NULL;\r
+static jobject g_obj_subscriptionListener = NULL;\r
+static jobject g_obj_syncListener = NULL;\r
+\r
+JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)\r
+{\r
+    LOGI("Initialize NSInterface");\r
+    g_jvm = jvm;\r
+\r
+    return JNI_VERSION_1_6;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSStartProvider(\r
+        JNIEnv * env, jobject jObj, jboolean jAccess, jobject jSubscriptionListener,\r
+        jobject jSyncListener)\r
+{\r
+    LOGI("NSStartProvider...");\r
+\r
+    if (!jSubscriptionListener || !jSyncListener)\r
+    {\r
+        LOGI("Fail to set listeners");\r
+    }\r
+\r
+    g_obj_subscriptionListener = (jobject) (*env)->NewGlobalRef(env, jSubscriptionListener);\r
+    g_obj_syncListener = (jobject) (*env)->NewGlobalRef(env, jSyncListener);\r
+\r
+    // check access policy\r
+    NSAccessPolicy access = NS_ACCESS_ALLOW;\r
+\r
+    if (NSStartProvider(access, NSSubscribeRequestCb, NSSyncCb) != NS_OK)\r
+    {\r
+        LOGE("Fail to start NSProvider service");\r
+        return (jint) NS_ERROR;\r
+    }\r
+\r
+    return (jint) NS_OK;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSStopProvider(\r
+        JNIEnv * env, jobject jObj)\r
+{\r
+    LOGI("NSStopProvider");\r
+\r
+    (*env)->DeleteGlobalRef(env, g_obj_subscriptionListener);\r
+    (*env)->DeleteGlobalRef(env, g_obj_syncListener);\r
+\r
+    if (NSStopProvider() != NS_OK)\r
+    {\r
+        LOGE("Fail to stop NSProvider service");\r
+        return (jint) NS_ERROR;\r
+    }\r
+\r
+    return (jint) NS_OK;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSSendNotification(\r
+        JNIEnv * env, jobject jObj, jobject jMsg)\r
+{\r
+    LOGI("NSSendNotification");\r
+\r
+    if (!jMsg)\r
+    {\r
+        LOGI("Fail to send notification - Message is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+\r
+    NSMessage * nsMsg = NSGetMessage(env, jMsg);\r
+\r
+    LOGI("JNI TEST - NSSendNotification");\r
+    NSSendNotification(nsMsg);\r
+\r
+    return (jint) NS_OK;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSProviderReadCheck(\r
+        JNIEnv * env, jobject jObj, jobject jMsg)\r
+{\r
+    LOGI("NSReasCheck");\r
+    return 0;\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSAccept(JNIEnv * env,\r
+        jobject jObj, jobject jConsumer, jboolean jAccepted)\r
+{\r
+    if (jAccepted)\r
+    {\r
+        LOGI("Accepted");\r
+        //NSAccept(consumer, true);\r
+    }\r
+    else\r
+    {\r
+        LOGI("Denied");\r
+        //NSAccept(consumer, false);\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+void NSSubscribeRequestCb(NSConsumer *consumer)\r
+{\r
+    LOGI("Subscription requested by consumer");\r
+\r
+    JNIEnv * env;\r
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
+    if (JNI_OK != res)\r
+    {\r
+        if (res == JNI_EDETACHED)\r
+        {\r
+            if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK)\r
+            {\r
+                LOGE("Failed to get the environment");\r
+                return;\r
+            }\r
+            else\r
+            {\r
+                LOGE("Success to get the environment");\r
+            }\r
+        }\r
+        else\r
+        {\r
+            LOGE("Failed to get the environment using GetEnv()");\r
+            return;\r
+        }\r
+    }\r
+\r
+    LOGI("consumer ID : %s\n", consumer->consumerId);\r
+    jstring consumerId = (*env)->NewStringUTF(env, consumer->consumerId);\r
+\r
+    jclass cls = (*env)->GetObjectClass(env, g_obj_subscriptionListener);\r
+    if (!cls)\r
+    {\r
+        LOGE("Failed to Get ObjectClass");\r
+        return;\r
+    }\r
+    jmethodID mid = (*env)->GetMethodID(env, cls, "OnNSSubscribedEvent", "(Ljava/lang/String;)V");\r
+    if (!mid)\r
+    {\r
+        LOGE("Failed to Get MethodID");\r
+        return;\r
+    }\r
+\r
+    (*env)->CallVoidMethod(env, g_obj_subscriptionListener, mid, consumerId);\r
+\r
+    (*g_jvm)->DetachCurrentThread(g_jvm);\r
+\r
+    NSAccept(consumer, true);\r
+\r
+    return;\r
+}\r
+\r
+void NSSyncCb(NSSyncInfo *sync)\r
+{\r
+    LOGI("Sync requested");\r
+\r
+    JNIEnv * env;\r
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
+    if (JNI_OK != res)\r
+    {\r
+        if (JNI_EDETACHED)\r
+        {\r
+            if ((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) < 0)\r
+            {\r
+                LOGE("Failed to get the environment");\r
+                return;\r
+            }\r
+            else\r
+            {\r
+                LOGE("Success to get the environment");\r
+            }\r
+        }\r
+        else\r
+        {\r
+            LOGE("Failed to get the environment using GetEnv()");\r
+            return;\r
+        }\r
+    }\r
+\r
+    LOGI("Sync ID : %s\n", sync->messageId);\r
+    LOGI("Sync STATE : %d\n", sync->state);\r
+\r
+    jstring strMessageId = (*env)->NewStringUTF(env, sync->messageId);\r
+\r
+    jclass cls = (*env)->GetObjectClass(env, g_obj_syncListener);\r
+    if (!cls)\r
+    {\r
+        LOGE("Failed to Get ObjectClass");\r
+        return;\r
+    }\r
+    jmethodID mid = (*env)->GetMethodID(env, cls, "OnNSSynchronizedEvent",\r
+            "(Ljava/lang/String;I)V");\r
+    if (!mid)\r
+    {\r
+        LOGE("Failed to Get MethodID");\r
+        return;\r
+    }\r
+\r
+    (*env)->CallVoidMethod(env, g_obj_syncListener, mid, strMessageId, (jint) sync->state);\r
+\r
+    (*g_jvm)->DetachCurrentThread(g_jvm);\r
+\r
+    return;\r
+\r
+}\r
+\r
+NSMessage * NSGetMessage(JNIEnv * env, jobject jMsg)\r
+{\r
+    LOGI("NSGetMessage");\r
+\r
+    jclass cls = (*env)->GetObjectClass(env, jMsg);\r
+\r
+    // Message ID\r
+    jfieldID fid_id = (*env)->GetFieldID(env, cls, "id", "Ljava/lang/String;");\r
+    if (fid_id == NULL)\r
+    {\r
+        LOGE("Error: jfieldID for message id is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    jstring jmsgId = (*env)->GetObjectField(env, jMsg, fid_id);\r
+    const char * messageId = (*env)->GetStringUTFChars(env, jmsgId, NULL);\r
+    if (messageId == NULL)\r
+    {\r
+        LOGE("Error: messageId is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    LOGI("Message ID: %s\n", messageId);\r
+\r
+    // Message Title\r
+    jfieldID fid_title = (*env)->GetFieldID(env, cls, "title", "Ljava/lang/String;");\r
+    if (fid_title == NULL)\r
+    {\r
+        LOGE("Error: jfieldID for message id is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    jstring jmsgTitle = (*env)->GetObjectField(env, jMsg, fid_title);\r
+    const char * messageTitle = (*env)->GetStringUTFChars(env, jmsgTitle, NULL);\r
+    if (messageTitle == NULL)\r
+    {\r
+        LOGE("Error: messageTitle is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    LOGI("Message Title: %s\n", messageTitle);\r
+\r
+    // Message Body\r
+    jfieldID fid_body = (*env)->GetFieldID(env, cls, "body", "Ljava/lang/String;");\r
+    if (fid_body == NULL)\r
+    {\r
+        LOGE("Error: jfieldID for message id is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    jstring jmsgBody = (*env)->GetObjectField(env, jMsg, fid_body);\r
+    const char * messageBody = (*env)->GetStringUTFChars(env, jmsgBody, NULL);\r
+    if (messageBody == NULL)\r
+    {\r
+        LOGE("Error: messageBody is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    LOGI("Message Body: %s\n", messageBody);\r
+\r
+    // Message Source\r
+    jfieldID fid_source = (*env)->GetFieldID(env, cls, "source", "Ljava/lang/String;");\r
+    if (fid_source == NULL)\r
+    {\r
+        LOGE("Error: jfieldID for message source is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    jstring jmsgSource = (*env)->GetObjectField(env, jMsg, fid_source);\r
+    const char * messageSource = (*env)->GetStringUTFChars(env, jmsgSource, NULL);\r
+    if (messageSource == NULL)\r
+    {\r
+        LOGE("Error: messageSource is null");\r
+        return (jint) NS_ERROR;\r
+    }\r
+    LOGI("Message Source: %s\n", messageSource);\r
+\r
+    NSMessage * nsMsg = (NSMessage *) malloc(sizeof(NSMessage));\r
+\r
+    nsMsg->messageId = strdup(messageId);\r
+    nsMsg->title = strdup(messageTitle);\r
+    nsMsg->contentText = strdup(messageBody);\r
+    nsMsg->sourceName = strdup(messageSource);\r
+\r
+    return nsMsg;\r
+\r
+}\r
diff --git a/service/notification/android/notification-service/src/main/jni/notificationProvider.h b/service/notification/android/notification-service/src/main/jni/notificationProvider.h
new file mode 100644 (file)
index 0000000..ffafb5c
--- /dev/null
@@ -0,0 +1,56 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include <jni.h>\r
+#include "NSProviderInterface.h"\r
+#include "NSCommon.h"\r
+\r
+#ifndef NOTIFICATION_JNI_H\r
+#define NOTIFICATION_JNI_H\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+    JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSStartProvider(\r
+            JNIEnv *, jobject, jboolean, jobject, jobject);\r
+\r
+    JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSStopProvider(\r
+            JNIEnv *, jobject);\r
+\r
+    JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSSendNotification(\r
+            JNIEnv *, jobject, jobject);\r
+\r
+    JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSProviderReadCheck(\r
+            JNIEnv *, jobject, jobject);\r
+\r
+    JNIEXPORT jint JNICALL Java_org_iotivity_service_notification_IoTNotification_NSAccept(JNIEnv *,\r
+            jobject, jobject, jboolean);\r
+\r
+    void NSSubscribeRequestCb(NSConsumer*);\r
+\r
+    void NSSyncCb(NSSyncInfo*);\r
+\r
+    NSMessage * NSGetMessage(JNIEnv *, jobject);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif\r
diff --git a/service/notification/android/settings.gradle b/service/notification/android/settings.gradle
new file mode 100644 (file)
index 0000000..60ffa33
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 Intel Corporation.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * //      http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+include ':notification-service'
diff --git a/service/notification/examples/SConscript b/service/notification/examples/SConscript
new file mode 100644 (file)
index 0000000..c51a751
--- /dev/null
@@ -0,0 +1,10 @@
+##
+# Examples build script
+##
+Import('env')
+
+target_os = env.get('TARGET_OS')
+if target_os == 'linux':
+       SConscript('linux/SConscript')
+elif target_os == 'android':
+       SConscript('android/SConscript')
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.gitignore b/service/notification/examples/android/NotiProviderExample/.gitignore
new file mode 100644 (file)
index 0000000..4c9e2c6
--- /dev/null
@@ -0,0 +1,8 @@
+*.iml\r
+.gradle\r
+/local.properties\r
+/.idea/workspace.xml\r
+/.idea/libraries\r
+.DS_Store\r
+/build\r
+/captures\r
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/.name b/service/notification/examples/android/NotiProviderExample/.idea/.name
new file mode 100644 (file)
index 0000000..28684b4
--- /dev/null
@@ -0,0 +1 @@
+NotiProviderExample
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/compiler.xml b/service/notification/examples/android/NotiProviderExample/.idea/compiler.xml
new file mode 100644 (file)
index 0000000..96cc43e
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+      <entry name="!?*.aj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/copyright/profiles_settings.xml b/service/notification/examples/android/NotiProviderExample/.idea/copyright/profiles_settings.xml
new file mode 100644 (file)
index 0000000..e7bedf3
--- /dev/null
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+  <settings default="" />
+</component>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/gradle.xml b/service/notification/examples/android/NotiProviderExample/.idea/gradle.xml
new file mode 100644 (file)
index 0000000..5dd336e
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleJvm" value="1.8" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/iotivity-armeabi-notification-service-release" />
+            <option value="$PROJECT_DIR$/iotivity-base-armeabi-release" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/inspectionProfiles/Project_Default.xml b/service/notification/examples/android/NotiProviderExample/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644 (file)
index 0000000..a950918
--- /dev/null
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="AndroidLintHandlerLeak" enabled="false" level="WARNING" enabled_by_default="false" />
+  </profile>
+</component>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/inspectionProfiles/profiles_settings.xml b/service/notification/examples/android/NotiProviderExample/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644 (file)
index 0000000..3b31283
--- /dev/null
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_PROFILE" value="true" />
+    <version value="1.0" />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/misc.xml b/service/notification/examples/android/NotiProviderExample/.idea/misc.xml
new file mode 100644 (file)
index 0000000..5d19981
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="NullableNotNullManager">
+    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
+    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
+    <option name="myNullables">
+      <value>
+        <list size="4">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+        </list>
+      </value>
+    </option>
+    <option name="myNotNulls">
+      <value>
+        <list size="4">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+        </list>
+      </value>
+    </option>
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/modules.xml b/service/notification/examples/android/NotiProviderExample/.idea/modules.xml
new file mode 100644 (file)
index 0000000..20c9fec
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/NotiProviderExample.iml" filepath="$PROJECT_DIR$/NotiProviderExample.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
+      <module fileurl="file://$PROJECT_DIR$/iotivity-armeabi-notification-service-debug/iotivity-armeabi-notification-service-debug.iml" filepath="$PROJECT_DIR$/iotivity-armeabi-notification-service-debug/iotivity-armeabi-notification-service-debug.iml" />
+      <module fileurl="file://$PROJECT_DIR$/iotivity-armeabi-notification-service-release/iotivity-armeabi-notification-service-release.iml" filepath="$PROJECT_DIR$/iotivity-armeabi-notification-service-release/iotivity-armeabi-notification-service-release.iml" />
+      <module fileurl="file://$PROJECT_DIR$/iotivity-base-armeabi-debug/iotivity-base-armeabi-debug.iml" filepath="$PROJECT_DIR$/iotivity-base-armeabi-debug/iotivity-base-armeabi-debug.iml" />
+      <module fileurl="file://$PROJECT_DIR$/iotivity-base-armeabi-release/iotivity-base-armeabi-release.iml" filepath="$PROJECT_DIR$/iotivity-base-armeabi-release/iotivity-base-armeabi-release.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/runConfigurations.xml b/service/notification/examples/android/NotiProviderExample/.idea/runConfigurations.xml
new file mode 100644 (file)
index 0000000..7f68460
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/.idea/vcs.xml b/service/notification/examples/android/NotiProviderExample/.idea/vcs.xml
new file mode 100644 (file)
index 0000000..b082f7b
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../../../../../../.." vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/app/.gitignore b/service/notification/examples/android/NotiProviderExample/app/.gitignore
new file mode 100644 (file)
index 0000000..3543521
--- /dev/null
@@ -0,0 +1 @@
+/build\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/build.gradle b/service/notification/examples/android/NotiProviderExample/app/build.gradle
new file mode 100644 (file)
index 0000000..79f0bf3
--- /dev/null
@@ -0,0 +1,21 @@
+apply plugin: 'com.android.application'\r
+\r
+android {\r
+    compileSdkVersion 23\r
+    buildToolsVersion "23.0.1"\r
+\r
+    defaultConfig {\r
+        applicationId "sample.notification.service.iotivity.org.notificationsample"\r
+        minSdkVersion 23\r
+        targetSdkVersion 23\r
+        versionCode 1\r
+        versionName "1.0"\r
+    }\r
+}\r
+\r
+dependencies {\r
+    compile fileTree(include: ['*.jar'], dir: 'libs')\r
+    compile 'com.android.support:appcompat-v7:23.0.1'\r
+    compile project(':iotivity-base-armeabi-release')\r
+    compile project(':iotivity-armeabi-notification-service-release')\r
+}\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/proguard-rules.pro b/service/notification/examples/android/NotiProviderExample/app/proguard-rules.pro
new file mode 100644 (file)
index 0000000..371f4af
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.\r
+# By default, the flags in this file are appended to flags specified\r
+# in D:\adt-bundle-windows-x86_64-20140321\sdk/tools/proguard/proguard-android.txt\r
+# You can edit the include path and order by changing the proguardFiles\r
+# directive in build.gradle.\r
+#\r
+# For more details, see\r
+#   http://developer.android.com/guide/developing/tools/proguard.html\r
+\r
+# Add any project specific keep options here:\r
+\r
+# If your project uses WebView with JS, uncomment the following\r
+# and specify the fully qualified class name to the JavaScript interface\r
+# class:\r
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\r
+#   public *;\r
+#}\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/AndroidManifest.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..bc14e47
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+    package="com.sec.notiproviderexample">\r
+\r
+    <uses-feature android:name="android.hardware.nfc" />\r
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />\r
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />\r
+    <uses-permission android:name="android.permission.BLUETOOTH"/>\r
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>\r
+    <uses-permission android:name="android.permission.INTERNET"/>\r
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>\r
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>\r
+    <uses-permission android:name="android.permission.NFC" />\r
+\r
+    <application\r
+        android:allowBackup="true"\r
+        android:icon="@mipmap/ic_launcher"\r
+        android:label="@string/app_name"\r
+        android:supportsRtl="true"\r
+        android:theme="@style/AppTheme">\r
+        <activity android:name=".MainActivity">\r
+            <intent-filter>\r
+                <action android:name="android.intent.action.MAIN" />\r
+\r
+                <category android:name="android.intent.category.LAUNCHER" />\r
+            </intent-filter>\r
+        </activity>\r
+\r
+        <service\r
+            android:name="com.sec.notiproviderexample.NotiListener"\r
+            android:label="@string/app_name"\r
+            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">\r
+\r
+            <intent-filter>\r
+                <action android:name="android.service.notification.NotificationListenerService" />\r
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />\r
+            </intent-filter>\r
+        </service>\r
+    </application>\r
+\r
+</manifest>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java
new file mode 100755 (executable)
index 0000000..fc9998e
--- /dev/null
@@ -0,0 +1,234 @@
+/*\r
+ *******************************************************************\r
+ *\r
+ * Copyright 2015 Intel Corporation.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ */\r
+\r
+package com.sec.notiproviderexample;\r
+\r
+import android.app.Notification;\r
+import android.app.NotificationManager;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.os.Message;\r
+import android.support.v7.app.AppCompatActivity;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.widget.Button;\r
+import android.widget.EditText;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+\r
+public class MainActivity extends AppCompatActivity {\r
+\r
+    private final String TAG = "NS_MAIN_ACTIVITY";\r
+    private static final int MESSAGE_SUBSCRIPTION = 1;\r
+    private static final int MESSAGE_SYNC = 2;\r
+    private static final int MESSAGE_NOTIFICATION = 3;\r
+\r
+    private Button btnTitle;\r
+    private Button btnBody;\r
+    private Button btnSend;\r
+    private Button btnStart;\r
+    private Button btnStop;\r
+    private Button btnAccept;\r
+    private Button btnSync;\r
+    private EditText editTextTitle;\r
+    private EditText editTextBody;\r
+    private static TextView TvLog;\r
+\r
+    private static int notiId = 100;\r
+    private static int subCnt = 0;\r
+    private boolean isStarted = false;\r
+    private String consumerId;\r
+\r
+    private NotiListener mNotiListener = null;\r
+    private ProviderProxy mProviderProxy = null;\r
+\r
+    public static Handler mHandler = new Handler() {\r
+        @Override\r
+        public void handleMessage(Message msg) {\r
+            switch (msg.what) {\r
+                case MESSAGE_SUBSCRIPTION:\r
+                    String subscriber = (String) msg.obj;\r
+                    if(subscriber != null)\r
+                        TvLog.append("Subscriber IP(" + ++subCnt + "): " + subscriber + "\n");\r
+                    break;\r
+\r
+                case MESSAGE_SYNC:\r
+                    String sync = (String) msg.obj;\r
+                    if(sync != null)\r
+                        TvLog.append("Sync-Read(Msg ID: " + sync + ")\n");\r
+                    break;\r
+\r
+                default:\r
+                    break;\r
+            }\r
+        }\r
+    };\r
+\r
+    public void showToast(final String toast)\r
+    {\r
+        runOnUiThread(new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();\r
+            }\r
+        });\r
+    }\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        setContentView(R.layout.activity_main);\r
+\r
+        btnTitle = (Button) findViewById(R.id.BtnTitle);\r
+        btnBody = (Button) findViewById(R.id.BtnBody);\r
+        btnSend = (Button) findViewById(R.id.BtnCreateNoti);\r
+\r
+        btnStart = (Button) findViewById(R.id.BtnStart);\r
+        btnAccept = (Button) findViewById(R.id.BtnAccept);\r
+        btnSync = (Button) findViewById(R.id.BtnSync);\r
+        btnStop = (Button) findViewById(R.id.BtnStop);\r
+\r
+        editTextTitle = (EditText) findViewById(R.id.EditTextTitle);\r
+        editTextBody = (EditText) findViewById(R.id.EditTextBody);\r
+\r
+        TvLog = (TextView) findViewById(R.id.TvLog);\r
+\r
+        btnTitle.setEnabled(false);\r
+        btnBody.setEnabled(false);\r
+\r
+        btnSend.setOnClickListener(mClickListener);\r
+\r
+        btnStart.setOnClickListener(mClickListener);\r
+\r
+        btnAccept.setOnClickListener(mClickListener);\r
+        btnAccept.setVisibility(View.INVISIBLE);\r
+\r
+        btnSync.setOnClickListener(mClickListener);\r
+        btnSync.setVisibility(View.INVISIBLE);\r
+\r
+        btnStop.setOnClickListener(mClickListener);\r
+\r
+        mProviderProxy = new ProviderProxy(getApplicationContext());\r
+        mProviderProxy.setHandler(mHandler);\r
+\r
+        mNotiListener = new NotiListener(this);\r
+\r
+        Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");\r
+        startActivity(intent);\r
+    }\r
+\r
+    @Override\r
+    protected void onDestroy() {\r
+        super.onDestroy();\r
+    }\r
+\r
+    public ProviderProxy getProviderProxy()\r
+    {\r
+        return mProviderProxy;\r
+    }\r
+\r
+    Button.OnClickListener mClickListener = new View.OnClickListener() {\r
+        public void onClick(View v) {\r
+            switch (v.getId()) {\r
+\r
+                case R.id.BtnStart: {\r
+                    if (isStarted == false) {\r
+                        Log.i(TAG, "Start NS Provider Service");\r
+\r
+                        TvLog.setText("Start NS-Provider\n");\r
+\r
+                        boolean access = true; // ptovider controls the acceptance of consumers\r
+                        mProviderProxy.startNotificationServer(access);\r
+                        isStarted = true;\r
+                    } else {\r
+                        Log.e(TAG, "NS Provider Service had already started");\r
+                    }\r
+                }\r
+                break;\r
+\r
+                case R.id.BtnAccept: {\r
+                    if(isStarted == false)\r
+                    {\r
+                        Log.e(TAG, "Fail to request Accept");\r
+                        break;\r
+                    }\r
+                    mProviderProxy.accept("#consumerid", true);\r
+                }\r
+                break;\r
+\r
+                case R.id.BtnCreateNoti: {\r
+\r
+                    String id = Integer.toString(notiId); // generate notificaion ID\r
+                    String title = editTextTitle.getText().toString();\r
+                    String body = editTextBody.getText().toString();\r
+\r
+                    if(isStarted == false)\r
+                    {\r
+                        Log.e(TAG, "Fail to send NSMessage");\r
+                        break;\r
+                    }\r
+\r
+                    // Build android noti object and send it to Notification service receiver\r
+                    Notification.Builder notiBuilder = new Notification.Builder(getApplicationContext());\r
+                    notiBuilder.setContentTitle(title);\r
+                    notiBuilder.setContentText(body);\r
+                    notiBuilder.setPriority(Notification.PRIORITY_MAX);\r
+                    notiBuilder.setDefaults(Notification.DEFAULT_ALL);\r
+                    notiBuilder.setSmallIcon(R.mipmap.ic_launcher);\r
+                    NotificationManager notiMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
+                    notiMgr.notify(notiId, notiBuilder.build());\r
+\r
+                    Log.i(TAG, "#" + notiId + " notified ..");\r
+                    TvLog.append("Send Notitication(Msg ID: " + notiId + ")\n");\r
+                    notiId++;\r
+                }\r
+                break;\r
+\r
+                case R.id.BtnSync: {\r
+                    if(isStarted == false)\r
+                    {\r
+                        Log.e(TAG, "Fail to send sync");\r
+                        break;\r
+                    }\r
+                    //mProviderProxy.readCheck(LastMessageId);\r
+                }\r
+                break;\r
+\r
+                case R.id.BtnStop: {\r
+                    if(isStarted == false)\r
+                    {\r
+                        Log.e(TAG, "Fail to stop service");\r
+                        break;\r
+                    }\r
+\r
+                    mProviderProxy.stopNotificationServer();\r
+                    isStarted = false;\r
+\r
+                    TvLog.append("Stop NS-Provider\n");\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    };\r
+}\r
+\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/NotiListener.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/NotiListener.java
new file mode 100755 (executable)
index 0000000..4492799
--- /dev/null
@@ -0,0 +1,133 @@
+/*\r
+ *******************************************************************\r
+ *\r
+ * Copyright 2015 Intel Corporation.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ */\r
+\r
+package com.sec.notiproviderexample;\r
+\r
+import android.app.Notification;\r
+import android.os.Bundle;\r
+import android.service.notification.NotificationListenerService;\r
+import android.service.notification.StatusBarNotification;\r
+import android.util.Log;\r
+import java.util.ArrayList;\r
+\r
+public class NotiListener extends NotificationListenerService {\r
+\r
+    private final String TAG = "NS_JNI_NOTI_LISTENER";\r
+    private static ProviderProxy mProviderProxy = null;\r
+    private MainActivity mActivity = null;\r
+    ArrayList mBlackSourceList = new ArrayList<String>();\r
+\r
+    public NotiListener() {\r
+\r
+        Log.i(TAG, "Create NotiListener");\r
+    }\r
+\r
+    public NotiListener(MainActivity activity) {\r
+\r
+        Log.i(TAG, "Create NotiListener with MainActivity");\r
+\r
+        this.mActivity = activity;\r
+        this.mProviderProxy = mActivity.getProviderProxy();\r
+\r
+        setBlackSourceList();\r
+\r
+        if(mProviderProxy == null) {\r
+            Log.i(TAG, "Fail to get providerProxy instance");\r
+        }\r
+    }\r
+\r
+    public void setBlackSourceList() {\r
+\r
+        // set blacklist of app package name not to receive notification\r
+        mBlackSourceList.add("android");\r
+        mBlackSourceList.add("com.android.systemui");\r
+    }\r
+\r
+    @Override\r
+    public void onNotificationPosted(StatusBarNotification sbn) {\r
+        super.onNotificationPosted(sbn);\r
+\r
+        Bundle bundle = sbn.getNotification().extras;\r
+        String source = null;\r
+\r
+        // prevent not to send notification\r
+        for(int i = 0; i < mBlackSourceList.size(); ++i)\r
+        {\r
+            if (sbn.getPackageName().equals(mBlackSourceList.get(i)))\r
+            {\r
+                return;\r
+            }\r
+        }\r
+\r
+        // filter exception case : Some notification are generated twice\r
+        if(sbn.getId() > 10000 || sbn.getId() < 0)\r
+            return;\r
+\r
+        // Temporary protocol code to display ICON on consumer app.\r
+        // For example, consumer app shows KAKAOTALK Icon when receiving Notification with SOURCE\r
+        // that is set to KAKAO, otherwise it displays OCF Icon on current sample app.\r
+        if(sbn.getPackageName().equals("com.kakao.talk"))\r
+            source = "KAKAO";\r
+        else\r
+            source = "OCF";\r
+\r
+        Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());\r
+        Log.i(TAG, "Noti. ID : " + sbn.getId());\r
+\r
+        String id = Integer.toString(sbn.getId());\r
+        String title = bundle.getString(Notification.EXTRA_TITLE, "");\r
+        String body = bundle.getString(Notification.EXTRA_TEXT, "");\r
+\r
+        Log.i(TAG, "onNotificationPosted .. ");\r
+        Log.i(TAG, "source : " + source);\r
+        Log.i(TAG, "Id : " + id);\r
+        Log.i(TAG, "Title : " + title);\r
+        Log.i(TAG, "Body : " + body);\r
+\r
+        if (mProviderProxy != null) {\r
+            mProviderProxy.sendNSMessage(id, title, body, source);\r
+        } else {\r
+            Log.i(TAG, "providerExample is NULL");\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void onNotificationRemoved(StatusBarNotification sbn) {\r
+        super.onNotificationRemoved(sbn);\r
+\r
+        Bundle bundle = sbn.getNotification().extras;\r
+\r
+        if (sbn.getPackageName().equals("android"))\r
+            return;\r
+\r
+        Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());\r
+        Log.i(TAG, "Noti. ID : " + sbn.getId());\r
+\r
+        if(mProviderProxy.getMsgMap().containsKey(sbn.getId()))\r
+        {\r
+            if(mProviderProxy.getMsgMap().get(sbn.getId()) == 2)\r
+            {\r
+                mProviderProxy.readCheck(Integer.toString(sbn.getId()));\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderProxy.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderProxy.java
new file mode 100755 (executable)
index 0000000..9fe6a26
--- /dev/null
@@ -0,0 +1,186 @@
+/*\r
+ *******************************************************************\r
+ *\r
+ * Copyright 2015 Intel Corporation.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+ */\r
+\r
+package com.sec.notiproviderexample;\r
+\r
+import android.app.NotificationManager;\r
+import android.content.Context;\r
+import android.os.Handler;\r
+import android.os.Message;\r
+import android.util.Log;\r
+import android.widget.Toast;\r
+\r
+import org.iotivity.base.ModeType;\r
+import org.iotivity.base.OcPlatform;\r
+import org.iotivity.base.OcResourceHandle;\r
+import org.iotivity.base.PlatformConfig;\r
+import org.iotivity.base.QualityOfService;\r
+import org.iotivity.base.ServiceType;\r
+import org.iotivity.service.notification.IoTNotification;\r
+import org.iotivity.service.notification.NSConsumer;\r
+import org.iotivity.service.notification.NSMessage;\r
+\r
+import java.util.HashMap;\r
+\r
+public class ProviderProxy\r
+        implements IoTNotification.NSSubscriptionListner, IoTNotification.NSSynchListner{\r
+\r
+    private static final String TAG = "NS_PROVIDER_PROXY";\r
+\r
+    private Context mContext = null;\r
+    private OcResourceHandle mResourceHandle;   //resource handle\r
+    private IoTNotification ioTNotification = null;\r
+    private HashMap<String, Integer> msgMap;\r
+\r
+    private Handler mHandler = null;\r
+\r
+    private static final int MESSAGE_SUBSCRIPTION = 1;\r
+    private static final int MESSAGE_SYNC = 2;\r
+\r
+    private static final int SYNC_READ = 0;\r
+    private static final int SYNC_DISMISS = 1;\r
+    private static final int SYNC_UNREAD = 2;\r
+\r
+    public ProviderProxy(Context context) {\r
+        Log.i(TAG, "Create providerProxy Instance");\r
+\r
+        this.msgMap = new HashMap<>();\r
+        this.mContext = context;\r
+        ioTNotification = new IoTNotification();\r
+    }\r
+\r
+    public void setHandler(Handler handler)\r
+    {\r
+        this.mHandler = handler;\r
+    }\r
+\r
+    private void configurePlatform() {\r
+\r
+        PlatformConfig platformConfig = new PlatformConfig(\r
+                mContext,\r
+                ServiceType.IN_PROC,\r
+                ModeType.CLIENT_SERVER,\r
+                "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces\r
+                0,         // Uses randomly available port\r
+                QualityOfService.LOW\r
+        );\r
+\r
+        Log.i(TAG, "Configuring platform.");\r
+        OcPlatform.Configure(platformConfig);\r
+        try {\r
+            OcPlatform.stopPresence(); // Initialize OcPlatform\r
+        } catch(Exception e) {\r
+            Log.e(TAG, "Exception: stopping presence when configuration step: " + e);\r
+        }\r
+        Log.i(TAG, "Configuration done Successfully");\r
+    }\r
+\r
+    public void startNotificationServer(boolean access)\r
+    {\r
+        configurePlatform();\r
+        ioTNotification.NSStartProvider(access, this, this);\r
+    }\r
+\r
+    public void stopNotificationServer() {\r
+\r
+        try {\r
+            OcPlatform.stopPresence();\r
+        } catch (Exception e) {\r
+            Log.e(TAG, "Exception: stopping presence when terminating NS server: " + e);\r
+        }\r
+\r
+        ioTNotification.NSStopProvider();\r
+    }\r
+\r
+    public void sendNSMessage(String id, String title, String body, String source) {\r
+\r
+        NSMessage notiMessage = new NSMessage(id);\r
+        notiMessage.setTitle(title);\r
+        notiMessage.setBody(body);\r
+        notiMessage.setSource(source);\r
+        msgMap.put(id, SYNC_UNREAD);\r
+        ioTNotification.NSSendNotification(notiMessage);\r
+\r
+        mHandler.post(new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                Toast.makeText(mContext, "Notification sent", Toast.LENGTH_SHORT).show();\r
+            }\r
+        });\r
+    }\r
+\r
+    public void readCheck(String messageId) {\r
+        if(msgMap.containsKey(messageId)) {\r
+            if(msgMap.get(messageId) == SYNC_UNREAD)\r
+            {\r
+                NSMessage notiMessage = new NSMessage(messageId);\r
+                ioTNotification.NSProviderReadCheck(notiMessage);\r
+                msgMap.put(messageId, SYNC_READ);\r
+            }\r
+        }\r
+    }\r
+\r
+    public void accept(String consumerId, boolean accepted)\r
+    {\r
+        NSConsumer consumer = new NSConsumer(consumerId);\r
+        ioTNotification.NSAccept(consumer, accepted);\r
+    }\r
+\r
+    @Override\r
+    public void OnNSSubscribedEvent(String consumerId) {\r
+        Log.i(TAG, "OnNSSubscribedEvent");\r
+\r
+        Log.i(TAG, "Consumer: " + consumerId);\r
+        Message msg = mHandler.obtainMessage(MESSAGE_SUBSCRIPTION, consumerId);\r
+        mHandler.sendMessage(msg);\r
+    }\r
+\r
+    @Override\r
+    public void OnNSSynchronizedEvent(String messageId, int syncState) {\r
+        Log.i(TAG, "OnNSSynchronizedEvent");\r
+\r
+        Log.i(TAG, "Message Id: " + messageId);\r
+        Log.i(TAG, "Sync state: " + syncState);\r
+\r
+        Message msg = mHandler.obtainMessage(MESSAGE_SYNC, messageId + " / Sync State: " + syncState);\r
+        mHandler.sendMessage(msg);\r
+\r
+        NotificationManager manager = (NotificationManager)mContext\r
+                .getSystemService(Context.NOTIFICATION_SERVICE);\r
+\r
+        if(messageId != null)\r
+            try\r
+            {\r
+                manager.cancel(Integer.valueOf(messageId));\r
+            }\r
+            catch (Exception e)\r
+            {\r
+                Log.e(TAG, "Handle exception for invalid message id" + e);\r
+            }\r
+        else\r
+            Log.i(TAG, "message id is null");\r
+    }\r
+\r
+    public HashMap<String, Integer> getMsgMap() {\r
+        return msgMap;\r
+    }\r
+}\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_main.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..2365c5c
--- /dev/null
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    xmlns:tools="http://schemas.android.com/tools"\r
+    android:layout_width="match_parent"\r
+    android:layout_height="match_parent"\r
+    android:paddingBottom="@dimen/activity_vertical_margin"\r
+    android:paddingLeft="@dimen/activity_horizontal_margin"\r
+    android:paddingRight="@dimen/activity_horizontal_margin"\r
+    android:paddingTop="@dimen/activity_vertical_margin"\r
+    tools:context="com.sec.notificationexample.MainActivity">\r
+\r
+    <LinearLayout\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:paddingLeft="16dp"\r
+        android:paddingRight="16dp"\r
+        android:orientation="vertical" >\r
+\r
+        <View\r
+            android:layout_width="match_parent"\r
+            android:layout_height="1dp"\r
+            android:layout_alignParentBottom="true"\r
+            android:background="@android:color/darker_gray"/>\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="10dp">\r
+        </LinearLayout>\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal" >\r
+\r
+            <Button\r
+                android:layout_gravity="center_vertical|center_horizontal"\r
+                android:layout_height="60dp"\r
+                android:layout_width="match_parent"\r
+                android:id="@+id/BtnStart"\r
+                android:text="START"/>\r
+        </LinearLayout>\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal" >\r
+\r
+            <Button\r
+\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/BtnAccept"\r
+                android:text="ACCEPT"/>\r
+\r
+            <Button\r
+\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/BtnSync"\r
+                android:text="SYNC"/>\r
+        </LinearLayout>\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal" >\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="wrap_content"\r
+                android:id="@+id/BtnTitle"\r
+                android:text="@string/btn_title"\r
+                android:onClick="selfDestruct" />\r
+\r
+            <EditText\r
+                android:id="@+id/EditTextTitle"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="wrap_content"\r
+                android:windowSoftInputMode="stateHidden"\r
+                android:hint="글자를 입력하세요" />\r
+        </LinearLayout>\r
+\r
+        <LinearLayout\r
+            android:id="@+id/LinearBody"\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal" >\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="wrap_content"\r
+                android:id="@+id/BtnBody"\r
+                android:text="@string/btn_body"\r
+                android:onClick="selfDestruct" />\r
+\r
+            <EditText\r
+                android:id="@+id/EditTextBody"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="wrap_content"\r
+                android:windowSoftInputMode="stateHidden"\r
+                android:hint="글자를 입력하세요" />\r
+        </LinearLayout>\r
+\r
+        <Button\r
+            android:layout_gravity="center_vertical|center_horizontal"\r
+            android:layout_height="60dp"\r
+            android:layout_width="match_parent"\r
+            android:id="@+id/BtnCreateNoti"\r
+            android:text="@string/btn_create_noti"\r
+            />\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="10dp">\r
+        </LinearLayout>\r
+\r
+        <ScrollView\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:fillViewport="true">\r
+\r
+            <LinearLayout\r
+                android:layout_width="match_parent"\r
+                android:layout_height="150dp"\r
+                android:paddingLeft="5dp"\r
+                android:paddingRight="5dp"\r
+                android:orientation="horizontal" >\r
+\r
+                <TextView\r
+                    android:layout_gravity="center_vertical|center_horizontal"\r
+                    android:layout_height="150dp"\r
+                    android:layout_width="match_parent"\r
+                    android:scrollbars="vertical"\r
+                    android:id="@+id/TvLog"\r
+                    android:text="Log.."/>\r
+            </LinearLayout>\r
+\r
+        </ScrollView>\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal" >\r
+\r
+            <Button\r
+                android:layout_gravity="center_vertical|center_horizontal"\r
+                android:layout_height="60dp"\r
+                android:layout_width="match_parent"\r
+                android:id="@+id/BtnStop"\r
+                android:text="STOP"/>\r
+        </LinearLayout>\r
+\r
+        <View\r
+            android:layout_width="match_parent"\r
+            android:layout_height="1dp"\r
+            android:layout_alignParentBottom="true"\r
+            android:background="@android:color/darker_gray"/>\r
+\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="20dp">\r
+        </LinearLayout>\r
+\r
+    </LinearLayout>\r
+\r
+\r
+</RelativeLayout>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-hdpi/ic_launcher.png b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..cde69bc
Binary files /dev/null and b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-mdpi/ic_launcher.png b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..c133a0c
Binary files /dev/null and b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..bfa42f0
Binary files /dev/null and b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..324e72c
Binary files /dev/null and b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..aee44e1
Binary files /dev/null and b/service/notification/examples/android/NotiProviderExample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/values-w820dp/dimens.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..62df187
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>\r
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\r
+         (such as screen margins) for screens with more than 820dp of available width. This\r
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->\r
+    <dimen name="activity_horizontal_margin">64dp</dimen>\r
+</resources>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/colors.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/colors.xml
new file mode 100644 (file)
index 0000000..2a12c47
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<resources>\r
+    <color name="colorPrimary">#3F51B5</color>\r
+    <color name="colorPrimaryDark">#303F9F</color>\r
+    <color name="colorAccent">#FF4081</color>\r
+</resources>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/dimens.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..295b5a9
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>\r
+    <!-- Default screen margins, per the Android Design guidelines. -->\r
+    <dimen name="activity_horizontal_margin">16dp</dimen>\r
+    <dimen name="activity_vertical_margin">16dp</dimen>\r
+</resources>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/strings.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..b762eec
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>\r
+    <string name="app_name">NotificationProviderExample</string>\r
+    <string name="btn_title">Title</string>\r
+    <string name="btn_body">Body</string>\r
+    <string name="btn_send">Send Notification</string>\r
+    <string name="btn_create_noti">Create Notification</string>\r
+</resources>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/styles.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..6f19b47
--- /dev/null
@@ -0,0 +1,11 @@
+<resources>\r
+\r
+    <!-- Base application theme. -->\r
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">\r
+        <!-- Customize your theme here. -->\r
+        <item name="colorPrimary">@color/colorPrimary</item>\r
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>\r
+        <item name="colorAccent">@color/colorAccent</item>\r
+    </style>\r
+\r
+</resources>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/test/java/com/sec/notiproviderexample/ExampleUnitTest.java b/service/notification/examples/android/NotiProviderExample/app/src/test/java/com/sec/notiproviderexample/ExampleUnitTest.java
new file mode 100644 (file)
index 0000000..f69c509
--- /dev/null
@@ -0,0 +1,15 @@
+package com.sec.notiproviderexample;\r
+\r
+import org.junit.Test;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+/**\r
+ * To work on unit tests, switch the Test Artifact in the Build Variants view.\r
+ */\r
+public class ExampleUnitTest {\r
+    @Test\r
+    public void addition_isCorrect() throws Exception {\r
+        assertEquals(4, 2 + 2);\r
+    }\r
+}
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/build.gradle b/service/notification/examples/android/NotiProviderExample/build.gradle
new file mode 100644 (file)
index 0000000..a1f101c
--- /dev/null
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.\r
+\r
+buildscript {\r
+    repositories {\r
+        jcenter()\r
+    }\r
+    dependencies {\r
+        classpath 'com.android.tools.build:gradle:1.5.0'\r
+\r
+        // NOTE: Do not place your application dependencies here; they belong\r
+        // in the individual module build.gradle files\r
+    }\r
+}\r
+\r
+allprojects {\r
+    repositories {\r
+        jcenter()\r
+    }\r
+}\r
+\r
+task clean(type: Delete) {\r
+    delete rootProject.buildDir\r
+}\r
diff --git a/service/notification/examples/android/NotiProviderExample/gradlew.bat b/service/notification/examples/android/NotiProviderExample/gradlew.bat
new file mode 100644 (file)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/service/notification/examples/android/NotiProviderExample/iotivity-armeabi-notification-service-release/build.gradle b/service/notification/examples/android/NotiProviderExample/iotivity-armeabi-notification-service-release/build.gradle
new file mode 100644 (file)
index 0000000..f7c5895
--- /dev/null
@@ -0,0 +1,2 @@
+configurations.create("default")
+artifacts.add("default", file('iotivity-armeabi-notification-service-release.aar'))
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/iotivity-base-armeabi-release/build.gradle b/service/notification/examples/android/NotiProviderExample/iotivity-base-armeabi-release/build.gradle
new file mode 100644 (file)
index 0000000..44cd131
--- /dev/null
@@ -0,0 +1,2 @@
+configurations.create("default")
+artifacts.add("default", file('iotivity-base-armeabi-release.aar'))
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/settings.gradle b/service/notification/examples/android/NotiProviderExample/settings.gradle
new file mode 100644 (file)
index 0000000..1d296f6
--- /dev/null
@@ -0,0 +1 @@
+include ':app', ':iotivity-armeabi-notification-service-release', ':iotivity-base-armeabi-release'\r
diff --git a/service/notification/examples/linux/SConscript b/service/notification/examples/linux/SConscript
new file mode 100644 (file)
index 0000000..5a8eb31
--- /dev/null
@@ -0,0 +1,69 @@
+##
+# Notification build script
+##
+
+Import('env')
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+notification_sample_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+notification_sample_env.AppendUnique(CPPPATH = ['../../include'])
+notification_sample_env.AppendUnique(CPPPATH = ['../../src/common'])
+notification_sample_env.AppendUnique(CPPPATH = ['../../src/provider'])
+notification_sample_env.AppendUnique(CPPPATH = ['../../../../resource/csdk/stack/include'])
+notification_sample_env.AppendUnique(CPPPATH = ['../../../../resource/csdk/connectivity/api'])
+
+notification_sample_env.PrependUnique(LIBS = [
+       'octbstack',
+       'oc_logger',
+       'connectivity_abstraction',
+       'libcoap'
+       ])
+
+if target_os not in ['windows', 'winrt']:
+       notification_sample_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+if target_os not in ['darwin', 'ios', 'windows', 'winrt']:
+       notification_sample_env.AppendUnique(LINKFLAGS = ['-Wl,--no-undefined'])
+
+if target_os == 'linux':
+       notification_sample_env.AppendUnique(LIBS = ['pthread'])
+
+if target_os == 'android':
+       notification_sample_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+       notification_sample_env.AppendUnique(LIBS = ['gnustl_shared','log'])
+
+       if not env.get('RELEASE'):
+               notification_sample_env.AppendUnique(LIBS = ['log'])
+
+notification_sample_consumer_src = 'notificationconsumer.c'
+
+if env.get('WITH_CLOUD') == True:
+       notification_sample_env.AppendUnique(CPPPATH = ['../../src/consumer'])
+       notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+       CONSUMER_CLOUD = File('cloud_connector.c')
+       notification_sample_consumer_src = ['notificationconsumer.c', CONSUMER_CLOUD]
+
+if env.get('WITH_TCP') == True:
+       notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_TCP'])
+
+
+
+####################################################################
+# Source files and Targets
+######################################################################
+notification_sample_provider_env = notification_sample_env.Clone()
+
+notification_sample_provider_env.AppendUnique(LIBS = 'libnotification_provider')
+notificationprovider = notification_sample_provider_env.Program('notificationprovider', 'notificationprovider.c')
+i_notificationprovider = notification_sample_provider_env.Install(env.get('BUILD_DIR'), notificationprovider)
+
+notification_sample_consumer_env = notification_sample_env.Clone()
+notification_sample_consumer_env.AppendUnique(LIBS = 'libnotification_consumer')
+notificationconsumer = notification_sample_consumer_env.Program('notificationconsumer', notification_sample_consumer_src)
+i_notificationprovider = notification_sample_consumer_env.Install(env.get('BUILD_DIR'), notificationconsumer)
diff --git a/service/notification/examples/linux/cloud_connector.c b/service/notification/examples/linux/cloud_connector.c
new file mode 100644 (file)
index 0000000..1312ff3
--- /dev/null
@@ -0,0 +1,292 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include "cloud_connector.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+#include "ocpayload.h"
+
+#include "rdpayload.h"
+
+#define OC_RD_PUBLISH_TTL 86400
+#define DEFAULT_CONTEXT_VALUE 0x99
+
+#define DEFAULT_COAP_TCP_HOST "coap+tcp://"
+#define DEFAULT_COAP_TCP_PORT 5683
+
+#define DEFAULT_COAP_TCP_SECURE_HOST "coaps+tcp://"
+#define DEFAULT_COAP_TCP_SECURE_PORT 5864
+
+#define DEFAULT_AUTH_REGISTER_LOGIN "/oic/auth/?reqtype=register"
+#define DEFAULT_AUTH_LOGIN "/oic/auth/?reqtype=login"
+#define DEFAULT_AUTH_LOGOUT "/oic/auth/?reqtype=logout"
+
+static OCStackResult createStringLL(uint8_t numElements, OCResourceHandle handle,
+                                    const char *(*getValue)(OCResourceHandle handle, uint8_t i), OCStringLL **stringLL)
+{
+    for (uint8_t i = 0; i < numElements; ++i)
+    {
+        const char *value = getValue(handle, i);
+        if (!*stringLL)
+        {
+            *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!*stringLL)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+            (*stringLL)->value = OICStrdup(value);
+            if (!(*stringLL)->value)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+        else
+        {
+            OCStringLL *cur = *stringLL;
+            while (cur->next)
+            {
+                cur = cur->next;
+            }
+            cur->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!cur->next)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+            cur->next->value = OICStrdup(value);
+            if (!cur->next->value)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider,
+                                   const char *auth_code, OCClientResponseHandler response)
+{
+    char    targetUri[MAX_URI_LENGTH * 2] = { 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, DEFAULT_AUTH_REGISTER_LOGIN);
+
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+    OCRepPayload *registerPayload = OCRepPayloadCreate();
+    if (!registerPayload)
+    {
+        goto no_memory;
+    }
+
+    OCRepPayloadSetPropString(registerPayload, "authprovider", auth_provider);
+    OCRepPayloadSetPropString(registerPayload, "authcode", auth_code);
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)registerPayload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+no_memory:
+    OCRepPayloadDestroy(registerPayload);
+    return OC_STACK_NO_MEMORY;
+}
+
+OCStackResult OCCloudLoginout(const char *host, const char *query, const char *auth_session,
+                              OCClientResponseHandler response)
+{
+    char    targetUri[MAX_URI_LENGTH * 2] = { 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
+
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+    OCRepPayload *loginoutPayload = OCRepPayloadCreate();
+    if (!loginoutPayload)
+    {
+        goto no_memory;
+    }
+
+    OCRepPayloadSetPropString(loginoutPayload, "session", auth_session);
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)loginoutPayload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+no_memory:
+    OCRepPayloadDestroy(loginoutPayload);
+    return OC_STACK_NO_MEMORY;
+}
+
+
+OCStackResult OCCloudLogin(const char *host, const char *auth_session,
+                           OCClientResponseHandler response)
+{
+    return OCCloudLoginout(host, DEFAULT_AUTH_LOGIN, auth_session, response);
+}
+
+OCStackResult OCCloudLogout(const char *host, const char *auth_session,
+                            OCClientResponseHandler response)
+{
+    return OCCloudLoginout(host, DEFAULT_AUTH_LOGOUT, auth_session, response);
+}
+
+OCStackResult OCCloudPublish(const char *host, const char *query,
+                             OCClientResponseHandler response, int numArg, ...)
+{
+    char    targetUri[MAX_URI_LENGTH * 2] = { 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
+
+    // Gather all resources locally and do publish
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+    OCTagsPayload *tagsPayload = NULL;
+    OCLinksPayload *linksPayload = NULL;
+    OCStringLL *rt = NULL;
+    OCStringLL *itf = NULL;
+    OCStringLL *mt = NULL;
+
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
+    if (!rdPayload)
+    {
+        goto no_memory;
+    }
+
+    const unsigned char *id = (unsigned char *)OCGetServerInstanceIDString();
+    tagsPayload = OCCopyTagsResources(NULL, id,
+                                      NULL, OC_DISCOVERABLE, 0, 0, NULL, NULL, OC_RD_PUBLISH_TTL);
+    if (!tagsPayload)
+    {
+        goto no_memory;
+    }
+
+    va_list arguments;
+    va_start(arguments, numArg);
+
+    for (int j = 0; j < numArg; j++)
+    {
+        OCResourceHandle handle = va_arg(arguments, OCResourceHandle);
+        if (handle)
+        {
+            rt = itf = mt = NULL;
+            const char *uri = OCGetResourceUri(handle);
+            uint8_t numElement;
+            if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
+            {
+                OCStackResult res = createStringLL(numElement, handle, OCGetResourceTypeName, &rt);
+                if (res != OC_STACK_OK || !rt)
+                {
+                    goto no_memory;
+                }
+            }
+
+            if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement))
+            {
+                OCStackResult res = createStringLL(numElement, handle, OCGetResourceInterfaceName, &itf);
+                if (res != OC_STACK_OK || !itf)
+                {
+                    goto no_memory;
+                }
+            }
+
+            mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!mt)
+            {
+                goto no_memory;
+            }
+            mt->value = OICStrdup("application/cbor");
+            if (!mt->value)
+            {
+                goto no_memory;
+            }
+
+            if (!linksPayload)
+            {
+                linksPayload = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL,
+                                                    NULL, j, mt);;
+                if (!linksPayload)
+                {
+                    goto no_memory;
+                }
+            }
+            else
+            {
+                OCLinksPayload *temp = linksPayload;
+                while (temp->next)
+                {
+                    temp = temp->next;
+                }
+                temp->next = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL,
+                                                  NULL, j, mt);
+                if (!temp->next)
+                {
+                    goto no_memory;
+                }
+            }
+            OCFreeOCStringLL(rt);
+            OCFreeOCStringLL(itf);
+            OCFreeOCStringLL(mt);
+        }
+    }
+    va_end(arguments);
+
+    rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
+    if (!rdPayload->rdPublish)
+    {
+        goto no_memory;
+    }
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+no_memory:
+    va_end(arguments);
+    if (rt)
+    {
+        OCFreeOCStringLL(rt);
+    }
+    if (itf)
+    {
+        OCFreeOCStringLL(itf);
+    }
+    if (mt)
+    {
+        OCFreeOCStringLL(mt);
+    }
+    if (tagsPayload)
+    {
+        OCFreeTagsResource(tagsPayload);
+    }
+    if (linksPayload)
+    {
+        OCFreeLinksResource(linksPayload);
+    }
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_NO_MEMORY;
+}
diff --git a/service/notification/examples/linux/cloud_connector.h b/service/notification/examples/linux/cloud_connector.h
new file mode 100644 (file)
index 0000000..fbb8821
--- /dev/null
@@ -0,0 +1,40 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+#include "ocstack.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider,
+                                   const char *auth_code, OCClientResponseHandler response);
+OCStackResult OCCloudLogin(const char *host, const char *auth_session,
+                           OCClientResponseHandler response);
+OCStackResult OCCloudLogout(const char *host, const char *auth_session,
+                            OCClientResponseHandler response);
+OCStackResult OCCloudPublish(const char *host, const char *query,
+                             OCClientResponseHandler response, int numArg, ...);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
diff --git a/service/notification/examples/linux/notificationconsumer.c b/service/notification/examples/linux/notificationconsumer.c
new file mode 100644 (file)
index 0000000..9d526e7
--- /dev/null
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#include "ocstack.h"
+#include "NSCommon.h"
+#include "NSConsumerInterface.h"
+
+#ifdef WITH_CLOUD
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+#include "cloud_connector.h"
+#include "oic_malloc.h"
+
+#define CLOUD_CONTEXT_VALUE 0x99
+#define CLOUD_PRESENCE_SUBSCRIBE_QUERY ""          // refer to IoTivity Cloud Module Sample
+
+#define CLOUD_HOST_ADDRESS ""                      // refer to IoTivity Cloud Module Sample
+#define CLOUD_IOTIVITYNS_SESSION ""                // refer to IoTivity Cloud Module Sample
+#endif
+
+void onDiscoverNotification(NSProvider * provider)
+{
+    printf("notification resource discovered\n");
+    printf("subscribe result %d\n", NSSubscribe(provider));
+    printf("startSubscribing\n");
+}
+
+void onSubscriptionAccepted(NSProvider * provider)
+{
+    printf("Subscription accepted\n");
+    printf("subscribed provider Id : %s\n", provider->providerId);
+}
+
+void onNotificationPosted(NSMessage * notification)
+{
+    printf("id : %lld\n", notification->messageId);
+    printf("title : %s\n", notification->title);
+    printf("content : %s\n", notification->contentText);
+    printf("source : %s\n", notification->sourceName);
+    NSConsumerSendSyncInfo(notification->providerId, notification->messageId, NS_SYNC_READ);
+}
+
+void onNotificationSync(NSSyncInfo * sync)
+{
+    printf("Sync ID : %lld\n", sync->messageId);
+    printf("Sync STATE : %d\n", sync->state);
+}
+
+#ifdef WITH_CLOUD
+OCStackApplicationResult handleLoginoutCB(void *ctx,
+        OCDoHandle handle,
+        OCClientResponse *clientResponse)
+{
+    (void)handle;
+    if (ctx != (void *)CLOUD_CONTEXT_VALUE)
+    {
+        NS_LOG(DEBUG, "Invalid Login/out callback received");
+    }
+
+    NS_LOG(DEBUG, "Login/out response received");
+
+    if (clientResponse->payload != NULL &&
+        clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
+    {
+        NS_LOG(DEBUG, "PAYLOAD_TYPE_REPRESENTATION received");
+
+        OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;
+
+        while (val)
+        {
+            val = val->next;
+        }
+        NS_LOG(DEBUG, "Get payload values");
+
+        OCDevAddr * addr = NULL;
+        addr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
+        memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
+
+        NSTask * task = NSMakeTask(TASK_EVENT_CONNECTED_TCP, addr);
+
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, OC_STACK_KEEP_TRANSACTION, NSOICFree(addr));
+        NSConsumerPushEvent(task);
+    }
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+#endif
+
+int main(void)
+{
+
+    printf("start Iotivity\n");
+    if (OCInit1(OC_CLIENT, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)
+    {
+        printf("OCInit fail\n");
+        return 0;
+    }
+
+    NSConsumerConfig cfg;
+    cfg.discoverCb = onDiscoverNotification;
+    cfg.acceptedCb = onSubscriptionAccepted;
+    cfg.messageCb = onNotificationPosted;
+    cfg.syncInfoCb = onNotificationSync;
+
+
+    printf("start notification consumer service\n");
+    NSResult ret = NSStartConsumer(cfg);
+    if(ret != NS_OK)
+    {
+        printf("error discoverNoti %d\n", ret);
+    }
+
+#ifdef WITH_CLOUD
+    NS_LOG(DEBUG, "process OCCloudLogin...");
+    OCCloudLogin(CLOUD_HOST_ADDRESS, CLOUD_IOTIVITYNS_SESSION, handleLoginoutCB);
+    NS_LOG(DEBUG, "OCCloudLogin return");
+#endif
+
+    while (true)
+    {
+        usleep(2000);
+        if(OCProcess() != OC_STACK_OK)
+        {
+            OCStop();
+            break;
+        }
+    }
+
+    return 0;
+}
diff --git a/service/notification/examples/linux/notificationprovider.c b/service/notification/examples/linux/notificationprovider.c
new file mode 100644 (file)
index 0000000..f4313e1
--- /dev/null
@@ -0,0 +1,233 @@
+/******************************************************************\r
+ *\r
+ * Copyright 2015 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include "NSCommon.h"\r
+#include "NSProviderInterface.h"\r
+#include "logger.h"\r
+#include "octypes.h"\r
+#include "pthread.h"\r
+#include "oic_string.h"\r
+#include "oic_malloc.h"\r
+\r
+#define TAG "NSProviderExample"\r
+\r
+extern char *strdup(const char *s);\r
+\r
+bool isExit = false;\r
+\r
+int id;\r
+\r
+void* OCProcessThread(void * ptr)\r
+{\r
+    (void) ptr;\r
+    while (!isExit)\r
+    {\r
+        if (OCProcess() != OC_STACK_OK)\r
+        {\r
+            OIC_LOG(ERROR, TAG, "OCStack process error");\r
+            return NULL;\r
+        }\r
+    }\r
+\r
+    return NULL;\r
+}\r
+\r
+void subscribeRequestCallback(NSConsumer *consumer)\r
+{\r
+    OIC_LOG(INFO, TAG, "consumer requested to subscribe");\r
+\r
+    printf("NS_APP Consumer Device ID: %s\n", consumer->consumerId);\r
+\r
+    NSAccept(consumer, true);\r
+}\r
+\r
+void syncCallback(NSSyncInfo *sync)\r
+{\r
+    OIC_LOG(INFO, TAG, "sync requested");\r
+\r
+    printf("NS_APP Sync State: %d\n", sync->state);\r
+}\r
+\r
+OCStackApplicationResult CloudLoginoutCallback(void *ctx,\r
+        OCDoHandle handle, OCClientResponse *clientResponse)\r
+{\r
+    int CtxValue = 0x99;\r
+    if (ctx != (void *)CtxValue)\r
+    {\r
+        OIC_LOG(INFO, TAG, "Invalid Cloud Login/out callback received");\r
+    }\r
+\r
+    OIC_LOG(INFO, TAG, "Login/out response received");\r
+\r
+    if (clientResponse->payload != NULL &&\r
+            clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)\r
+    {\r
+        OIC_LOG(INFO, TAG, "PAYLOAD_TYPE_REPRESENTATION received");\r
+\r
+        OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;\r
+\r
+        OIC_LOG(INFO, TAG, "Get payload values");\r
+        while (val)\r
+        {\r
+            OIC_LOG_V(INFO, TAG, "key: %s / Value: %s", val->name, val->str);\r
+            val = val->next;\r
+        }\r
+\r
+        char *serverAddress = "coap+tcp://52.69.149.85:5683";\r
+        NSProviderEnableRemoteService(serverAddress);\r
+    }\r
+\r
+    return OC_STACK_KEEP_TRANSACTION;\r
+}\r
+\r
+FILE* server_fopen(const char *path, const char *mode)\r
+{\r
+    (void)path;\r
+    return fopen("oic_ns_provider_db.dat", mode);\r
+}\r
+\r
+int main()\r
+{\r
+    int num;\r
+    pthread_t processThread;\r
+\r
+    // cloud host address\r
+    const char *host = "coap+tcp://52.69.149.85:5683";\r
+    // cloud auth session\r
+    const char *auth_session = "gZDRuDyYapZXIcrs";\r
+\r
+\r
+    OIC_LOG(INFO, TAG, "NSStartProvider()");\r
+\r
+    // open oic_db\r
+    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};\r
+    OCRegisterPersistentStorageHandler(&ps);\r
+\r
+    if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)\r
+    {\r
+        OIC_LOG(INFO, TAG, "OCStack init error");\r
+        return 0;\r
+    }\r
+\r
+    pthread_create(&processThread, NULL, OCProcessThread, unlink);\r
+\r
+    while (!isExit)\r
+    {\r
+        char dummy;\r
+\r
+        printf("1. NSStartProvider(Accepter: Provider) \n");\r
+        printf("2. NSStartProvider(Accepter: Consumer) \n");\r
+        printf("3. NSSendNotification() \n");\r
+        printf("4. NSRead \n");\r
+        printf("5. NSStopProvider() \n");\r
+        printf("6. NSGetConsumerList \n");\r
+        printf("11. NSCloudLogin \n");\r
+        printf("12. NSCloudLogout \n");\r
+        printf("0. Exit() \n");\r
+\r
+        printf("input : ");\r
+\r
+        scanf("%d", &num);\r
+        fflush(stdin);\r
+        scanf("%c", &dummy);\r
+        fflush(stdin);\r
+\r
+        switch (num)\r
+        {\r
+            case 1:\r
+                OIC_LOG(INFO, TAG, "NSStartProvider(Accepter: Provider)");\r
+                NSStartProvider(NS_ACCESS_ALLOW, subscribeRequestCallback, syncCallback);\r
+                break;\r
+            case 2:\r
+                OIC_LOG(INFO, TAG, "NSStartProvider(Accepter: Consumer)");\r
+                NSStartProvider(NS_ACCESS_DENY, subscribeRequestCallback, syncCallback);\r
+                break;\r
+            case 3:\r
+                OIC_LOG(INFO, TAG, "NSSendNotification()");\r
+\r
+                char title[100];\r
+                char body[100];\r
+\r
+                printf("id : %d\n", ++id);\r
+                printf("title : ");\r
+\r
+                gets(title);\r
+\r
+                printf("body : ");\r
+                gets(body);\r
+\r
+                printf("app - mTitle : %s \n", title);\r
+                printf("app - mContentText : %s \n", body);\r
+\r
+                NSMessage * msg = NSCreateMessage();\r
+\r
+                msg->title = OICStrdup(title);\r
+                msg->contentText = OICStrdup(body);\r
+                msg->sourceName = OICStrdup("OCF");\r
+\r
+                NSSendMessage(msg);\r
+\r
+                break;\r
+\r
+            case 4:\r
+                OIC_LOG(INFO, TAG, "NSRead");\r
+                NSSyncInfo * sync = (NSSyncInfo*) OICMalloc(sizeof(NSSyncInfo));\r
+\r
+                sync->messageId = OICStrdup("dev_001");\r
+                sync->state = 1;\r
+\r
+                break;\r
+\r
+            case 5:\r
+                NSStopProvider();\r
+                break;\r
+            case 6:\r
+                OIC_LOG(INFO, TAG, "NSGetConsumerList");\r
+                break;\r
+            case 11:\r
+                OIC_LOG(INFO, TAG, "NSCloudLogin");\r
+\r
+                NSCloudLogin(host, auth_session, CloudLoginoutCallback);\r
+                OIC_LOG(INFO, TAG, "OCCloudLogin requested");\r
+                break;\r
+            case 12:\r
+                OIC_LOG(INFO, TAG, "NSCloudLogout");\r
+\r
+                NSCloudLogout(host, auth_session, CloudLoginoutCallback);\r
+                OIC_LOG(INFO, TAG, "OCCloudLogout requested");\r
+                break;\r
+            case 0:\r
+                NSStopProvider();\r
+                isExit = true;\r
+                break;\r
+            default:\r
+                OIC_LOG(INFO, TAG, "Under Construction");\r
+                break;\r
+        }\r
+\r
+        printf("\n");\r
+    }\r
+\r
+    return 0;\r
+}\r
diff --git a/service/notification/include/NSCommon.h b/service/notification/include/NSCommon.h
new file mode 100644 (file)
index 0000000..1a28092
--- /dev/null
@@ -0,0 +1,155 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file provides APIs of Notification Service for common functions.
+ */
+
+#ifndef _NS_COMMON_H_
+#define _NS_COMMON_H_
+
+#include <ocstack.h>
+
+#define NS_ATTRIBUTE_POLICY "ACCEPTER"
+#define NS_ATTRIBUTE_MESSAGE "MESSAGE_URI"
+#define NS_ATTRIBUTE_SYNC "SYNC_URI"
+#define NS_ATTRIBUTE_ACCPETANCE "ACCEPTANCE"
+#define NS_ATTRIBUTE_MESSAGE_ID "MESSAGE_ID"
+#define NS_ATTRIBUTE_PROVIDER_ID "PROVIDER_ID"
+#define NS_ATTRIBUTE_TITLE "TITLE"
+#define NS_ATTRIBUTE_TEXT "CONTENTTEXT"
+#define NS_ATTRIBUTE_SOURCE "SOURCE"
+#define NS_ATTRIBUTE_STATE "STATE"
+#define NS_ATTRIBUTE_DEVICE "DEVICE"
+#define NS_ATTRIBUTE_TYPE "TYPE"
+#define NS_ATTRIBUTE_DATETIME "DATE_TIME"
+#define NS_ATTRIBUTE_TTL "TTL"
+
+/**
+ * Result code of notification service
+ */
+typedef enum eResult
+{
+    NS_OK = 100,
+    NS_ERROR = 200,
+    NS_SUCCESS = 300,
+    NS_FAIL = 400,
+    NS_ALLOW = 500,
+    NS_DENY = 600,
+
+} NSResult;
+
+/**
+ * Access policy exchanged between provider and consumer during subscription process
+ */
+typedef enum eAccessPolicy
+{
+    NS_ACCESS_ALLOW = 0,
+    NS_ACCESS_DENY = 1,
+} NSAccessPolicy;
+
+/**
+ * Notification message status to synchronize
+ */
+typedef enum
+{
+    NS_SYNC_UNREAD = 0,
+    NS_SYNC_READ = 1,
+    NS_SYNC_DELETED = 2,
+} NSSyncType;
+
+/**
+ * Notification Message Type
+ * Alert mean is High / critical
+ * Notice mean is low / critical
+ * Event mean is High / Normal
+ * Information mean is Low / Normal
+ */
+typedef enum
+{
+    NS_MESSAGE_ALERT = 1,
+    NS_MESSAGE_NOTICE = 2,
+    NS_MESSAGE_EVENT = 3,
+    NS_MESSAGE_INFO = 4,
+
+} NSMessageType;
+
+/**
+ *  Consumer information
+ */
+typedef struct
+{
+    char consumerId[37];
+
+} NSConsumer;
+
+/**
+ *  Provider information
+ */
+typedef struct
+{
+    char providerId[37];
+
+} NSProvider;
+
+/**
+ *  Media Contents of Notification Message (Optional)
+ */
+typedef struct
+{
+    char * iconImage;
+
+} NSMediaContents;
+
+/**
+ *  Notification Message
+ */
+typedef struct
+{
+    //Mandatory
+    uint64_t messageId;
+    char providerId[37];
+
+    //optional
+    NSMessageType type;
+    char * dateTime;
+    uint64_t ttl;
+    char * title;
+    char * contentText;
+    char * sourceName;
+    NSMediaContents * mediaContents;
+
+} NSMessage;
+
+/**
+ *  Synchronization information of the notification message
+ */
+typedef struct
+{
+    uint64_t messageId;
+    char providerId[37];
+    NSSyncType state;
+
+} NSSyncInfo;
+
+#endif /* _NS_COMMON_H_ */
+
diff --git a/service/notification/include/NSConsumerInterface.h b/service/notification/include/NSConsumerInterface.h
new file mode 100644 (file)
index 0000000..d7caaef
--- /dev/null
@@ -0,0 +1,123 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+ * @file
+ *
+ * This file provides APIs of Notification Service for Consumer.
+ */
+
+#ifndef _NS_CONSUMER_INTERFACE_H_
+#define _NS_CONSUMER_INTERFACE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+#include "NSCommon.h"
+
+/**
+ * Consumer uses this callback function to receive the discovered providers
+ * @param[in] provider        Provider who has the notification resource
+ */
+typedef void (* NSProviderDiscoveredCallback)(NSProvider *);
+
+typedef void (* NSSubscriptionAcceptedCallback)(NSProvider *);
+
+/**
+ * Consumer use this callback function to receive notification message from provider
+ * synchronization
+ * @param[in] provider    Provider who sends notification message
+ * @param[in] message     Notification message
+ */
+typedef void (* NSMessageReceivedCallback)(NSMessage *);
+
+/**
+ * Provider and consumer use this callback function to receive the status of the message
+ * synchronization
+ * @param[in] provider    Provider who requests synchronization with the status
+ * @param[in] sync        Synchronization information of the notification message
+ */
+typedef void (* NSSyncInfoReceivedCallback)(NSSyncInfo *);
+
+typedef struct
+{
+    NSProviderDiscoveredCallback discoverCb;
+    NSSubscriptionAcceptedCallback acceptedCb;
+    NSMessageReceivedCallback messageCb;
+    NSSyncInfoReceivedCallback syncInfoCb;
+
+} NSConsumerConfig;
+
+/**
+ * Initialize notification service for consumer
+ * @param[in]  providerDiscoveredCallback   Callback function to discover notification providers
+ * @param[in]  notificationReceivedCallback   Callback function to receive notification messages
+ * @param[in]  syncCallback   Callback function to receive synchronization status of notification
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSStartConsumer(NSConsumerConfig config);
+
+/**
+ * Terminate notification service for consumer
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSStopConsumer();
+
+/**
+ * Request to discover to remote address as parameter.
+ * @param[in]  server address combined with IP address and port number using delimiter :
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSConsumerEnableRemoteService(char *serverAddress);
+
+/**
+ * Request discovery manually
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSRescanProvider();
+
+/**
+ * Request to subscribe notification message resource of provider
+ * @param[in]  provider  Provider who send the notification message
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSSubscribe(NSProvider *provider);
+
+/**
+ * Request to unsubscribe in order not to receive notification message from provider
+ * @param[in]  provider  Provider who send the notification message
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSUnsubscribe(NSProvider *provider);
+
+NSResult NSConsumerSendSyncInfo(
+        const char * providerId, uint64_t messageId, NSSyncType type);
+
+NSProvider * NSConsumerGetProvider(const char * providerId);
+
+NSMessage * NSConsumerGetMessage(uint64_t messageId);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_INTERFACE_H_
diff --git a/service/notification/include/NSProviderInterface.h b/service/notification/include/NSProviderInterface.h
new file mode 100644 (file)
index 0000000..ebe6091
--- /dev/null
@@ -0,0 +1,125 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * This file provides APIs of Notification Service for Provider.\r
+ */\r
+\r
+#ifndef _NS_PROVIDER_INTERFACE_H_\r
+#define _NS_PROVIDER_INTERFACE_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif // __cplusplus\r
+\r
+#include "NSCommon.h"\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+\r
+/**\r
+ * Provider uses this callback function to receive subscription request of consumer\r
+ * @param[in] consumer        Consumer who subscribes the resource\r
+ */\r
+typedef void (*NSSubscribeRequestCallback)(NSConsumer *);\r
+\r
+/**\r
+ * Provider use this callback function to receive the status of the message\r
+ * synchronization\r
+ * @param[in] sync        Synchronization information of the notification message\r
+ */\r
+typedef void (*NSProviderSyncInfoCallback)(NSSyncInfo *);\r
+\r
+/**\r
+ * Initialize notification service for provider\r
+ * @param[in]  policy   Accepter\r
+ * @param[in]  subscribeRequestCallback   Callback function to register for receiving\r
+ * subscription request from consumer\r
+ * @param[in]  syncCallback   Callback function to register for receiving  sync data\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSStartProvider(NSAccessPolicy policy, NSSubscribeRequestCallback subscribeRequestCb,\r
+        NSProviderSyncInfoCallback syncCb);\r
+\r
+/**\r
+ * Terminate notification service for provider\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSStopProvider();\r
+\r
+/**\r
+ * Request to publish resource to cloud server\r
+ * @param[in]  server address combined with IP address and port number using delimiter :\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSProviderEnableRemoteService(char *serverAddress);\r
+\r
+/**\r
+ * Request to cancel remote service using cloud server\r
+ * @param[in]  server address combined with IP address and port number using delimiter :\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSProviderDisableRemoteService(char *serverAddress);\r
+\r
+/**\r
+ * Send notification message to all subscribers\r
+ * @param[in]  message  Notification message including id, title, contentText\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSSendMessage(NSMessage *msg);\r
+\r
+/**\r
+ * Send acceptance to consumer who subscribes the resource of notification message\r
+ * @param[in]  consumer  Consumer who subscribes the resource\r
+ * @param[in]  accepted  the result of acceptance; Allow or Deny\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSAccept(NSConsumer *consumer, bool accepted);\r
+\r
+/**\r
+ * Get consumer list that is stored in the cache of notification service\r
+ * @param[in]  list  Consumer list\r
+ * @param[in]  size  the number of consumers stored in the cache\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+// NSResult NSGetConsumerList(uint8_t *list, uint32_t size);\r
+\r
+/**\r
+ * Send read-check to provider in order to synchronize notification status with other consumers\r
+ * @param[in]  message  Notification message to synchronize the status\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSProviderSendSyncInfo(uint64_t messageId, NSSyncType type);\r
+\r
+\r
+/**\r
+ * Initialize NSMessage struct, our service set message id and provider(device) id\r
+ * @return ::NSMessage *\r
+ */\r
+NSMessage * NSCreateMessage();\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif /* _NS_PROVIDER_INTERFACE_H_ */\r
+\r
diff --git a/service/notification/src/common/NSCloudConnector.c b/service/notification/src/common/NSCloudConnector.c
new file mode 100644 (file)
index 0000000..34c122c
--- /dev/null
@@ -0,0 +1,296 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include "NSCloudConnector.h"
+#include "NSUtil.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+#include "ocpayload.h"
+
+#include "rdpayload.h"
+/*
+#define OC_RD_PUBLISH_TTL 86400
+#define DEFAULT_CONTEXT_VALUE 0x99
+
+#define DEFAULT_COAP_TCP_HOST "coap+tcp://"
+#define DEFAULT_COAP_TCP_PORT 5683
+
+#define DEFAULT_COAP_TCP_SECURE_HOST "coaps+tcp://"
+#define DEFAULT_COAP_TCP_SECURE_PORT 5864
+
+#define DEFAULT_AUTH_REGISTER_LOGIN "/oic/auth/?reqtype=register"
+#define DEFAULT_AUTH_LOGIN "/oic/auth/?reqtype=login"
+#define DEFAULT_AUTH_LOGOUT "/oic/auth/?reqtype=logout"
+*/
+static OCStackResult createStringLL(uint8_t numElements, OCResourceHandle handle,
+                                    const char *(*getValue)(OCResourceHandle handle, uint8_t i), OCStringLL **stringLL)
+{
+    for (uint8_t i = 0; i < numElements; ++i)
+    {
+        const char *value = getValue(handle, i);
+        if (!*stringLL)
+        {
+            *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!*stringLL)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+            (*stringLL)->value = OICStrdup(value);
+            if (!(*stringLL)->value)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+        else
+        {
+            OCStringLL *cur = *stringLL;
+            while (cur->next)
+            {
+                cur = cur->next;
+            }
+            cur->next = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!cur->next)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+            cur->next->value = OICStrdup(value);
+            if (!cur->next->value)
+            {
+                return OC_STACK_NO_MEMORY;
+            }
+        }
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult NSCloudRegisterLogin(const char *host, const char *auth_provider,
+                                   const char *auth_code, OCClientResponseHandler response)
+{
+    char    targetUri[MAX_URI_LENGTH * 2] = { 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, DEFAULT_AUTH_REGISTER_LOGIN);
+
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+    OCRepPayload *registerPayload = OCRepPayloadCreate();
+    if (!registerPayload)
+    {
+        goto no_memory;
+    }
+
+    OCRepPayloadSetPropString(registerPayload, "authprovider", auth_provider);
+    OCRepPayloadSetPropString(registerPayload, "authcode", auth_code);
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)registerPayload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+no_memory:
+    OCRepPayloadDestroy(registerPayload);
+    return OC_STACK_NO_MEMORY;
+}
+
+OCStackResult NSCloudLoginout(const char *host, const char *query, const char *auth_session,
+                              OCClientResponseHandler response)
+{
+    char    targetUri[MAX_URI_LENGTH * 2] = { 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
+
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+    OCRepPayload *loginoutPayload = OCRepPayloadCreate();
+    if (!loginoutPayload)
+    {
+        goto no_memory;
+    }
+
+    OCRepPayloadSetPropString(loginoutPayload, "session", auth_session);
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)loginoutPayload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+no_memory:
+    OCRepPayloadDestroy(loginoutPayload);
+    return OC_STACK_NO_MEMORY;
+}
+
+
+OCStackResult NSCloudLogin(const char *host, const char *auth_session,
+                           OCClientResponseHandler response)
+{
+    return NSCloudLoginout(host, DEFAULT_AUTH_LOGIN, auth_session, response);
+}
+
+OCStackResult NSCloudLogout(const char *host, const char *auth_session,
+                            OCClientResponseHandler response)
+{
+    return NSCloudLoginout(host, DEFAULT_AUTH_LOGOUT, auth_session, response);
+}
+
+
+static unsigned char gInstanceId[37] = {0, };
+OCStackResult NSCloudPublish(const char *host, const char *query,
+                             OCClientResponseHandler response, int numArg, ...)
+{
+    char    targetUri[MAX_URI_LENGTH * 2] = { 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
+
+    // Gather all resources locally and do publish
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+
+    OCTagsPayload *tagsPayload = NULL;
+    OCLinksPayload *linksPayload = NULL;
+    OCStringLL *rt = NULL;
+    OCStringLL *itf = NULL;
+    OCStringLL *mt = NULL;
+
+    OCRDPayload *rdPayload = OCRDPayloadCreate();
+    if (!rdPayload)
+    {
+        goto no_memory;
+    }
+
+    const unsigned char *id = (unsigned char *)OCGetServerInstanceIDString();
+    NS_LOG_V(DEBUG, "DeviceID: %s", id);
+    tagsPayload = OCCopyTagsResources(NULL, id,
+                                      NULL, OC_DISCOVERABLE, 0, 0, NULL, NULL, OC_RD_PUBLISH_TTL);
+    if (!tagsPayload)
+    {
+        goto no_memory;
+    }
+
+    va_list arguments;
+    va_start(arguments, numArg);
+
+    for (int j = 0; j < numArg; j++)
+    {
+        OCResourceHandle handle = va_arg(arguments, OCResourceHandle);
+        if (handle)
+        {
+            rt = itf = mt = NULL;
+            const char *uri = OCGetResourceUri(handle);
+            uint8_t numElement;
+            if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
+            {
+                OCStackResult res = createStringLL(numElement, handle, OCGetResourceTypeName, &rt);
+                if (res != OC_STACK_OK || !rt)
+                {
+                    goto no_memory;
+                }
+            }
+
+            if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement))
+            {
+                OCStackResult res = createStringLL(numElement, handle, OCGetResourceInterfaceName, &itf);
+                if (res != OC_STACK_OK || !itf)
+                {
+                    goto no_memory;
+                }
+            }
+
+            mt = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
+            if (!mt)
+            {
+                goto no_memory;
+            }
+            mt->value = OICStrdup("application/cbor");
+            if (!mt->value)
+            {
+                goto no_memory;
+            }
+
+            if (!linksPayload)
+            {
+                linksPayload = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL,
+                                                    NULL, j, mt);;
+                if (!linksPayload)
+                {
+                    goto no_memory;
+                }
+            }
+            else
+            {
+                OCLinksPayload *temp = linksPayload;
+                while (temp->next)
+                {
+                    temp = temp->next;
+                }
+                temp->next = OCCopyLinksResources(uri, rt, itf, NULL, 0, NULL,
+                                                  NULL, j, mt);
+                if (!temp->next)
+                {
+                    goto no_memory;
+                }
+            }
+            OCFreeOCStringLL(rt);
+            OCFreeOCStringLL(itf);
+            OCFreeOCStringLL(mt);
+        }
+    }
+    va_end(arguments);
+
+    rdPayload->rdPublish = OCCopyCollectionResource(tagsPayload, linksPayload);
+    if (!rdPayload->rdPublish)
+    {
+        goto no_memory;
+    }
+
+    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+no_memory:
+    va_end(arguments);
+    if (rt)
+    {
+        OCFreeOCStringLL(rt);
+    }
+    if (itf)
+    {
+        OCFreeOCStringLL(itf);
+    }
+    if (mt)
+    {
+        OCFreeOCStringLL(mt);
+    }
+    if (tagsPayload)
+    {
+        OCFreeTagsResource(tagsPayload);
+    }
+    if (linksPayload)
+    {
+        OCFreeLinksResource(linksPayload);
+    }
+    OCRDPayloadDestroy(rdPayload);
+    return OC_STACK_NO_MEMORY;
+}
diff --git a/service/notification/src/common/NSCloudConnector.h b/service/notification/src/common/NSCloudConnector.h
new file mode 100644 (file)
index 0000000..8988f76
--- /dev/null
@@ -0,0 +1,59 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _CLOUD_CONNECTOR_H_
+#define _CLOUD_CONNECTOR_H_
+
+#include "ocstack.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#define CLOUD_IP "52.69.149.85"
+#define CLOUD_PORT "5683"
+
+#define OC_RD_PUBLISH_TTL 86400
+#define DEFAULT_CONTEXT_VALUE 0x99
+
+#define DEFAULT_COAP_TCP_HOST "coap+tcp://"
+#define DEFAULT_COAP_TCP_PORT 5683
+
+#define DEFAULT_COAP_TCP_SECURE_HOST "coaps+tcp://"
+#define DEFAULT_COAP_TCP_SECURE_PORT 5864
+
+#define DEFAULT_AUTH_REGISTER_LOGIN "/oic/auth/?reqtype=register"
+#define DEFAULT_AUTH_LOGIN "/oic/auth/?reqtype=login"
+#define DEFAULT_AUTH_LOGOUT "/oic/auth/?reqtype=logout"
+
+OCStackResult NSCloudRegisterLogin(const char *host, const char *auth_provider,
+                                   const char *auth_code, OCClientResponseHandler response);
+OCStackResult NSCloudLogin(const char *host, const char *auth_session,
+                           OCClientResponseHandler response);
+OCStackResult NSCloudLogout(const char *host, const char *auth_session,
+                            OCClientResponseHandler response);
+OCStackResult NSCloudPublish(const char *host, const char *query,
+                             OCClientResponseHandler response, int numArg, ...);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif
diff --git a/service/notification/src/common/NSConstants.h b/service/notification/src/common/NSConstants.h
new file mode 100644 (file)
index 0000000..fc1f04a
--- /dev/null
@@ -0,0 +1,169 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSTANTS_H_
+#define _NS_CONSTANTS_H_
+
+#define __NS_FILE__ ( strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__ )
+
+#ifdef TB_LOG
+#include "logger.h"
+#define NS_LOG_V(level, format, ...) (OIC_LOG_V((level), __NS_FILE__, (format), __VA_ARGS__))
+#define NS_LOG(level, msg) (OIC_LOG((level), __NS_FILE__, (msg)))
+#else
+#include "logger.h"
+#define NS_CONVERT_LEVEL(level) ( \
+        ((level) == 0) ? "DEBUG" : \
+        ((level) == 1) ? "INFO" : \
+        ((level) == 2) ? "WARNING" : \
+    ((level) == 3) ? "ERROR" : "FATAL")
+#define NS_LOG_V(level, format, ...) \
+    { \
+        printf("%s: %s ", NS_CONVERT_LEVEL(level), __NS_FILE__); \
+        printf((format), __VA_ARGS__); \
+        printf("\n"); \
+    }
+#define NS_LOG(level, msg) \
+    { \
+        printf("%s: %s ", NS_CONVERT_LEVEL(level), __NS_FILE__); \
+        printf((msg)); \
+        printf("\n"); \
+    }
+#endif
+
+#define NS_TAG                     "IOT_NOTI"
+
+// SCHEDULE //
+#define THREAD_COUNT               4
+
+// NOTIOBJ // 
+#define NOTIOBJ_TITLE_KEY          "title"
+#define NOTIOBJ_ID_KEY             "id"
+#define NOTOOBJ_CONTENT_KEY        "contentText"
+
+#define DISCOVERY_TAG              "NS_PROVIDER_DISCOVERY"
+#define SUBSCRIPTION_TAG           "NS_PROVIDER_SUBSCRIPTION"
+#define INTERFACE_TAG              "NS_PROVIDER_INTERFACE"
+#define NOTIFICATION_TAG           "NS_PROVIDER_NOTIFICATION"
+#define SCHEDULER_TAG              "NS_PROVIDER_SCHEDULER"
+#define LISTENER_TAG               "NS_PROVIDER_LISTENER"
+#define RESOURCE_TAG               "NS_PROVIDER_RESOURCE"
+
+#define NS_ROOT_TYPE               "oic.r.notification"
+#define NS_COLLECTION_MESSAGE_TYPE "oic.r.notification.message"
+#define NS_COLLECTION_SYNC_TYPE    "oic.r.notification.sync"
+
+#define NS_DEFAULT_INTERFACE       "oic.if.baseline"
+
+#define NS_ROOT_URI                "/notification"
+#define NS_COLLECTION_MESSAGE_URI  "/notification/message"
+#define NS_COLLECTION_SYNC_URI     "/notification/sync"
+
+#define NS_QUERY_SEPARATOR         "&;"
+#define NS_KEY_VALUE_DELIMITER     "="
+
+#define NS_QUERY_CONSUMER_ID       "consumerid"
+#define NS_QUERY_PROVIDER_ID       "providerid"
+
+#define NS_QUERY_ID_SIZE           10
+
+typedef enum eConnectionState
+{
+    DISCONNECTED = 0,
+    CONNECTED = 1,
+
+} NSConnectionState;
+
+typedef enum eSchedulerType
+{
+    INTERFACE_SCHEDULER = 0,
+    DISCOVERY_SCHEDULER = 1,
+    SUBSCRIPTION_SCHEDULER = 2,
+    NOTIFICATION_SCHEDULER = 3,
+} NSSchedulerType;
+
+typedef enum eTaskType
+{
+    TASK_REGISTER_RESOURCE = 1000,
+    TASK_PUBLISH_RESOURCE = 1001,
+
+    TASK_START_PRESENCE = 2000,
+    TASK_STOP_PRESENCE = 2001,
+
+    TASK_RECV_SUBSCRIPTION = 3000,
+    TASK_RECV_UNSUBSCRIPTION = 3001,
+    TASK_SEND_POLICY = 3002,
+    TASK_SEND_ALLOW = 3003,
+    TASK_SEND_DENY = 3004,
+    TASK_SYNC_SUBSCRIPTION = 3005,
+
+    TASK_SEND_NOTIFICATION = 4000,
+    TASK_SEND_PENDING_NOTI = 4001,
+
+    TASK_RECV_SYNCINFO = 5000,
+    TASK_RECV_READ = 5001,
+    TASK_RECV_DISMISS = 5003,
+    TASK_SEND_SYNCINFO = 5099,
+    TASK_MAKE_SYNCINFO = 5100,
+    TASK_SEND_READ = 5101,
+    TASK_SEND_DISMISS = 5102,
+
+    TASK_CONSUMER_REQ_DISCOVER = 8001,
+    TASK_CONSUMER_REQ_SUBSCRIBE = 8002,
+    TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL = 8003,
+    TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED = 8004,
+    TASK_CONSUMER_RECV_MESSAGE = 8101,
+
+    TASK_CONSUMER_PROVIDER_DISCOVERED = 8201,
+    TASK_CONSUMER_PROVIDER_DELETED = 8202,
+    TASK_CONSUMER_RECV_CONFIRM = 8206,
+
+    TASK_EVENT_CONNECTED = 9000,
+    TASK_EVENT_CONNECTED_TCP = 9001,
+    TASK_EVENT_DISCONNECTED = 9002,
+
+    TASK_CB_SUBSCRIPTION = 10000,
+    TASK_CB_SYNC = 10001,
+
+} NSTaskType;
+
+typedef enum eCache
+{
+    NS_CONSUMER_BLACKLIST = 0,
+    NS_CONSUMER_WHITELIST = 1,
+
+} NSCache;
+
+typedef enum eCacheType
+{
+    NS_PROVIDER_CACHE_SUBSCRIBER = 1000,
+    NS_PROVIDER_CACHE_MESSAGE = 1001,
+
+    NS_CONSUMER_CACHE_PROVIDER = 2000,
+    NS_CONSUMER_CACHE_MESSAGE = 2001,
+} NSCacheType;
+
+typedef enum eResourceType
+{
+    NS_RESOURCE_MESSAGE = 1000,
+    NS_RESOURCE_SYNC = 1001,
+} NSResourceType;
+
+#endif /* _NS_CONSTANTS_H_ */
diff --git a/service/notification/src/common/NSStorageAdapter.h b/service/notification/src/common/NSStorageAdapter.h
new file mode 100644 (file)
index 0000000..27aff40
--- /dev/null
@@ -0,0 +1,38 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_STORAGEADAPTER__H_\r
+#define _NS_STORAGEADAPTER__H_\r
+\r
+#include "logger.h"\r
+#include <octypes.h>\r
+#include <stdbool.h>\r
+#include "ocstack.h"\r
+#include "ocpayload.h"\r
+#include "NSStructs.h"\r
+#include "NSConstants.h"\r
+\r
+NSCacheList * NSStorageCreate();\r
+NSCacheElement * NSStorageRead(NSCacheList * list, const char * findId);\r
+NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj);\r
+NSResult NSStorageDelete(NSCacheList * list, const char * delId);\r
+NSResult NSStorageDestroy(NSCacheList * list);\r
+\r
+#endif /* _NS_STORAGEADAPTER__H_ */\r
diff --git a/service/notification/src/common/NSStructs.h b/service/notification/src/common/NSStructs.h
new file mode 100644 (file)
index 0000000..e51f4ff
--- /dev/null
@@ -0,0 +1,106 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_STRUCTS_H_\r
+#define _NS_STRUCTS_H_\r
+\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include "NSCommon.h"\r
+#include "NSConstants.h"\r
+\r
+typedef struct _nsTask\r
+{\r
+    NSTaskType taskType;\r
+    void * taskData;\r
+    struct _nsTask * nextTask;\r
+} NSTask;\r
+\r
+typedef void * NSCacheData;\r
+\r
+typedef struct _NSCacheElement\r
+{\r
+    NSCacheData * data;\r
+    struct _NSCacheElement * next;\r
+} NSCacheElement;\r
+\r
+typedef struct\r
+{\r
+    NSCacheType cacheType;\r
+    NSCacheElement * head;\r
+    NSCacheElement * tail;\r
+} NSCacheList;\r
+\r
+typedef struct\r
+{\r
+    char id[37]; // ip\r
+    int syncObId;\r
+    int messageObId;\r
+    bool isWhite;\r
+} NSCacheSubData;\r
+\r
+typedef struct\r
+{\r
+    char * id; // ip ? ? ?\r
+    int messageType; // noti = 1, read = 2, dismiss = 3\r
+    NSMessage * nsMessage;\r
+} NSCacheMsgData;\r
+\r
+typedef struct\r
+{\r
+    OCResourceHandle handle;\r
+    int accepter;\r
+    char * message_uri;\r
+    char * sync_uri;\r
+} NSNotificationResource;\r
+\r
+typedef struct\r
+{\r
+    OCResourceHandle handle;\r
+\r
+    uint64_t messageId;\r
+    char providerId[37];\r
+\r
+    //optional\r
+    NSMessageType type;\r
+    char * dateTime;\r
+    uint64_t ttl;\r
+    char * title;\r
+    char * contentText;\r
+    char * sourceName;\r
+    NSMediaContents * mediaContents;\r
+} NSMessageResource;\r
+\r
+typedef struct\r
+{\r
+    OCResourceHandle handle;\r
+    char * id;\r
+    char * state;\r
+} NSSyncResource;\r
+\r
+typedef struct\r
+{\r
+  char providerId[37];\r
+  char * providerName;\r
+} NSProviderInfo;\r
+\r
+#endif /* _NS_STRUCTS_H_ */\r
diff --git a/service/notification/src/common/NSUtil.c b/service/notification/src/common/NSUtil.c
new file mode 100755 (executable)
index 0000000..8ed546f
--- /dev/null
@@ -0,0 +1,400 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSUtil.h"
+
+OCEntityHandlerRequest *NSCopyOCEntityHandlerRequest(OCEntityHandlerRequest *entityHandlerRequest)
+{
+    NS_LOG(DEBUG, "NSCopyOCEntityHandlerRequest - IN");
+
+    OCEntityHandlerRequest *copyOfRequest =
+            (OCEntityHandlerRequest *)OICMalloc(sizeof(OCEntityHandlerRequest));
+
+    if (copyOfRequest)
+    {
+        // Do shallow copy
+        memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
+
+        if (copyOfRequest->query)
+        {
+            copyOfRequest->query = OICStrdup(entityHandlerRequest->query);
+            if(!copyOfRequest->query)
+            {
+                NS_LOG(ERROR, "Copy failed due to allocation failure");
+                OICFree(copyOfRequest);
+                return NULL;
+            }
+        }
+
+        if (entityHandlerRequest->payload)
+        {
+            copyOfRequest->payload = (OCPayload *)
+                    (OCRepPayloadClone ((OCRepPayload*) entityHandlerRequest->payload));
+        }
+
+        // Ignore vendor specific header options for example
+        copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
+        copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
+    }
+
+    if (copyOfRequest)
+    {
+        NS_LOG(DEBUG, "Copied client request");
+    }
+    else
+    {
+        NS_LOG(DEBUG, "Error copying client request");
+    }
+
+    NS_LOG(DEBUG, "NSCopyOCEntityHandlerRequest - OUT");
+    return copyOfRequest;
+}
+
+NSResult NSFreeOCEntityHandlerRequest(OCEntityHandlerRequest * entityHandlerRequest)
+{
+    NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest - IN");
+
+    OICFree(entityHandlerRequest->query);
+    OCPayloadDestroy(entityHandlerRequest->payload);
+    OICFree(entityHandlerRequest);
+
+    NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest - OUT");
+
+    return NS_OK;
+}
+
+NSResult NSFreeMessage(NSMessage * obj)
+{
+    if (!obj)
+    {
+        return NS_ERROR;
+    }
+
+    obj->messageId = 0;
+    (obj->providerId)[0] = '\0';
+
+    NSFreeMalloc(&(obj->dateTime));
+    obj->ttl = 0;
+    NSFreeMalloc(&(obj->title));
+    NSFreeMalloc(&(obj->contentText));
+    NSFreeMalloc(&(obj->sourceName));
+    NSFreeMediaContents(obj->mediaContents);
+
+    OICFree(obj);
+
+    return NS_OK;
+}
+
+NSMessage * NSDuplicateMessage(NSMessage * copyMsg)
+{
+    NSMessage * newMsg = NULL;
+
+    if(copyMsg == NULL)
+    {
+        NS_LOG(ERROR, "Copy Msg is NULL");
+        return NULL;
+    }
+
+    newMsg = NSInitializeMessage();
+
+    newMsg->messageId = copyMsg->messageId;
+    OICStrcpy(newMsg->providerId, UUID_STRING_SIZE, copyMsg->providerId);
+
+    if(copyMsg->dateTime)
+    {
+        newMsg->dateTime = OICStrdup(copyMsg->dateTime);
+    }
+
+    newMsg->ttl = copyMsg->ttl;
+
+    if (copyMsg->title)
+    {
+        newMsg->title = OICStrdup(copyMsg->title);
+    }
+
+    if (copyMsg->contentText)
+    {
+        newMsg->contentText = OICStrdup(copyMsg->contentText);
+    }
+
+    if (copyMsg->sourceName)
+    {
+       newMsg->sourceName = OICStrdup(copyMsg->sourceName);
+    }
+
+    if (copyMsg->mediaContents)
+    {
+       newMsg->mediaContents = NSDuplicateMediaContents(copyMsg->mediaContents);
+    }
+
+    return newMsg;
+}
+
+NSResult NSFreeSync(NSSyncInfo * obj)
+{
+    if (!obj)
+    {
+        return NS_ERROR;
+    }
+
+    OICFree(obj);
+
+    return NS_OK;
+}
+
+NSSyncInfo* NSDuplicateSync(NSSyncInfo * copyMsg)
+{
+    NSSyncInfo * newMsg = NULL;
+
+    if(copyMsg == NULL)
+    {
+        NS_LOG(ERROR, "Copy Msg is NULL");
+        return NULL;
+    }
+
+    newMsg = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+
+    newMsg->messageId = copyMsg->messageId;
+    OICStrcpy(newMsg->providerId, UUID_STRING_SIZE, copyMsg->providerId);
+    newMsg->state = copyMsg->state;
+
+    return newMsg;
+}
+
+NSResult NSFreeConsumer(NSConsumer * obj)
+{
+    if (!obj)
+    {
+        return NS_ERROR;
+    }
+
+    (obj->consumerId)[0] = '\0';
+
+    OICFree(obj);
+    obj = NULL;
+
+    return NS_OK;
+}
+
+NSConsumer* NSDuplicateConsumer(NSConsumer * copyMsg)
+{
+    NSConsumer * newMsg = NULL;
+
+    if(copyMsg == NULL)
+    {
+        NS_LOG(ERROR, "Copy Msg is NULL");
+        return NULL;
+    }
+
+    newMsg = (NSConsumer *)OICMalloc(sizeof(NSConsumer));
+    (newMsg->consumerId)[0] = '\0';
+
+    OICStrcpy(newMsg->consumerId, UUID_STRING_SIZE, copyMsg->consumerId);
+
+    return newMsg;
+}
+
+void NSDuplicateSetPropertyString(OCRepPayload** msgPayload, const char * name,
+        const char * copyString)
+{
+    if(copyString)
+    {
+        OCRepPayloadSetPropString(*msgPayload, name, copyString);
+    }
+}
+
+void NSDuplicateSetPropertyInt(OCRepPayload** msgPayload, const char * name,
+        int64_t value)
+{
+    if(value)
+    {
+        OCRepPayloadSetPropInt(*msgPayload, name, value);
+    }
+}
+
+NSSyncInfo * NSGetSyncInfo(OCPayload * payload)
+{
+    NS_LOG(DEBUG, "NSGetSyncInfo - IN");
+    char * providerId = NULL;
+    int64_t state;
+
+    if(!payload)
+    {
+        return NULL;
+    }
+    NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+    if (!retSync)
+    {
+        return NULL;
+    }
+
+    retSync->messageId = 0;
+    retSync->state = NS_SYNC_READ;
+
+    OCRepPayload * repPayload = (OCRepPayload *)payload;
+    if (!OCRepPayloadGetPropInt(repPayload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&retSync->messageId))
+    {
+        OICFree(retSync);
+        return NULL;
+    }
+
+    if (!OCRepPayloadGetPropString(repPayload, NS_ATTRIBUTE_PROVIDER_ID, &providerId))
+    {
+        OICFree(retSync);
+        return NULL;
+    }
+
+    if (!OCRepPayloadGetPropInt(repPayload, NS_ATTRIBUTE_STATE, &state))
+    {
+        OICFree(retSync);
+        return NULL;
+    }
+
+    retSync->state = (NSSyncType) state;
+    OICStrcpy(retSync->providerId, UUID_STRING_SIZE, providerId);
+    OICFree(providerId);
+
+    NS_LOG_V(DEBUG, "Provider ID : %s", retSync->providerId);
+    NS_LOG_V(DEBUG, "Sync ID : %lu", retSync->messageId);
+    NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
+
+    NS_LOG(DEBUG, "NSGetSyncInfo - OUT");
+
+    return retSync;
+}
+
+NSResult NSGenerateUUIDStr(char uuidStr[UUID_STRING_SIZE])
+{
+    uint8_t uuid[UUID_SIZE] = { 0, };
+
+    if (RAND_UUID_OK == OCGenerateUuid(uuid))
+    {
+        if (RAND_UUID_OK == OCConvertUuidToString(uuid, uuidStr))
+        {
+            return NS_OK;
+        }
+    }
+    return NS_ERROR;
+}
+
+char * NSGetValueFromQuery(char *query, char * compareKey)
+{
+    char *key = NULL;
+    char *value = NULL;
+    char *restOfQuery = NULL;
+    int numKeyValuePairsParsed = 0;
+
+    NS_LOG_V(INFO, "NS Query Params = %s", query);
+
+    if(!query || query[0] == '\0' || !strlen(query))
+    {
+        NS_LOG(ERROR, "query is null or \\0 or size is 0");
+        return NULL;
+    }
+
+    char *keyValuePair = strtok_r (query, NS_QUERY_SEPARATOR, &restOfQuery);
+
+    while(keyValuePair)
+    {
+        if (numKeyValuePairsParsed >= 2)
+        {
+            NS_LOG(ERROR, "More than 2 queries params in URI.");
+            return NULL;
+        }
+
+        key = strtok_r(keyValuePair, NS_KEY_VALUE_DELIMITER, &value);
+
+        if (!key || !value)
+        {
+            NS_LOG(ERROR, "More than 2 queries params in URI.");
+            return NULL;
+        }
+
+        if (strcmp(key, compareKey) == 0)
+        {
+            NS_LOG_V(DEBUG, "found Key : [%s] - Value : [%s] = ", key, value);
+            return value;
+        }
+
+        ++numKeyValuePairsParsed;
+
+        keyValuePair = strtok_r(NULL, NS_QUERY_SEPARATOR, &restOfQuery);
+    }
+
+    return NULL;
+}
+
+NSResult NSFreeMalloc(char ** obj)
+{
+    if(*obj)
+    {
+        OICFree(*obj);
+        *obj = NULL;
+        return NS_OK;
+    }
+
+    return NS_FAIL;
+}
+
+NSMediaContents * NSDuplicateMediaContents(NSMediaContents * copyObj)
+{
+    if(!copyObj)
+    {
+        return NULL;
+    }
+
+    NSMediaContents * newObj = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
+
+    if(copyObj->iconImage)
+    {
+        newObj->iconImage = OICStrdup(copyObj->iconImage);
+    }
+
+    return newObj;
+}
+
+NSResult NSFreeMediaContents(NSMediaContents * obj)
+{
+    if(!obj)
+    {
+        return NS_OK;
+    }
+
+    NSFreeMalloc(&(obj->iconImage));
+    OICFree(obj);
+
+    return NS_OK;
+}
+
+NSMessage * NSInitializeMessage()
+{
+    NSMessage * msg = (NSMessage *)OICMalloc(sizeof(NSMessage));
+    msg->messageId = OICGetCurrentTime(TIME_IN_MS);
+    (msg->providerId)[0] = '\0';
+    msg->type = 0;
+    msg->dateTime = NULL;
+    msg->ttl = 0;
+    msg->title = NULL;
+    msg->contentText = NULL;
+    msg->sourceName = NULL;
+    msg->mediaContents = NULL;
+
+    return msg;
+}
diff --git a/service/notification/src/common/NSUtil.h b/service/notification/src/common/NSUtil.h
new file mode 100755 (executable)
index 0000000..06f0cd7
--- /dev/null
@@ -0,0 +1,62 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_UTIL__H_\r
+#define _NS_UTIL__H_\r
+\r
+#include "logger.h"\r
+#include <octypes.h>\r
+#include <stdbool.h>\r
+#include "ocstack.h"\r
+#include "ocpayload.h"\r
+#include "octypes.h"\r
+#include "NSStructs.h"\r
+#include "NSConstants.h"\r
+#include "oic_malloc.h"\r
+#include "oic_string.h"\r
+#include "ocrandom.h"\r
+#include "oic_time.h"\r
+#include "NSProviderSystem.h"\r
+\r
+OCEntityHandlerRequest *NSCopyOCEntityHandlerRequest(OCEntityHandlerRequest *);\r
+NSResult NSFreeOCEntityHandlerRequest(OCEntityHandlerRequest *);\r
+\r
+NSMessage * NSInitializeMessage();\r
+NSResult NSFreeMessage(NSMessage *);\r
+NSMessage * NSDuplicateMessage(NSMessage *);\r
+\r
+NSResult NSFreeSync(NSSyncInfo *);\r
+NSSyncInfo * NSDuplicateSync(NSSyncInfo *);\r
+NSSyncInfo * NSGetSyncInfo(OCPayload * payload);\r
+\r
+NSResult NSFreeConsumer(NSConsumer *);\r
+NSConsumer * NSDuplicateConsumer(NSConsumer *);\r
+\r
+void NSDuplicateSetPropertyString(OCRepPayload **, const char *, const char *);\r
+void NSDuplicateSetPropertyInt(OCRepPayload ** msgPayload, const char * name, int64_t value);\r
+NSResult NSGenerateUUIDStr(char uuidStr[UUID_STRING_SIZE]);\r
+\r
+char * NSGetValueFromQuery(char *query, char * compareKey);\r
+NSResult NSFreeMalloc(char ** obj);\r
+\r
+NSResult NSFreeMediaContents(NSMediaContents * obj);\r
+NSMediaContents * NSDuplicateMediaContents(NSMediaContents * copyObj);\r
+\r
+#endif /* _NS_UTIL__H_ */\r
diff --git a/service/notification/src/consumer/NSConsumerCommon.c b/service/notification/src/consumer/NSConsumerCommon.c
new file mode 100644 (file)
index 0000000..d9da4e0
--- /dev/null
@@ -0,0 +1,361 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerCommon.h"
+#include "NSConstants.h"
+#include "NSThread.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#include <pthread.h>
+
+#define NS_QUERY_CONSUMER_ID "consumerid"
+
+pthread_mutex_t ** NSGetStackMutex()
+{
+    static pthread_mutex_t * g_stackMutext = NULL;
+    if (g_stackMutext == NULL)
+    {
+        g_stackMutext = (pthread_mutex_t *)OICMalloc(sizeof(pthread_mutex_t));
+        NS_VERIFY_NOT_NULL(g_stackMutext, NULL);
+        pthread_mutex_init(g_stackMutext, NULL);
+    }
+
+    return & g_stackMutext;
+}
+
+char ** NSGetConsumerId()
+{
+    static char * g_consumerId = NULL;
+    return & g_consumerId;
+}
+
+void NSSetConsumerId(char * cId)
+{
+    NS_VERIFY_NOT_NULL_V(cId);
+    char ** consumerId = NSGetConsumerId();
+    NSOICFree(*consumerId);
+    *consumerId = (char *)OICMalloc(sizeof(char) * NS_DEVICE_ID_LENGTH);
+    NS_VERIFY_NOT_NULL_V(*consumerId);
+
+    OICStrcpy(*consumerId, sizeof(char) * NS_DEVICE_ID_LENGTH, cId);
+}
+
+char * NSMakeRequestUriWithConsumerId(const char * uri)
+{
+    NS_VERIFY_NOT_NULL(uri, NULL);
+
+    char * consumerId = OICStrdup(*NSGetConsumerId());
+    NS_VERIFY_NOT_NULL(consumerId, NULL);
+
+    size_t uriLen = strlen(uri) + 1;
+    size_t qKeyLen = sizeof(NS_QUERY_CONSUMER_ID);
+    size_t queryLen = NS_DEVICE_ID_LENGTH + uriLen + qKeyLen + 2;
+
+    char * retQuery = (char *)OICMalloc(sizeof(char) * queryLen);
+    NS_VERIFY_NOT_NULL(retQuery, NULL);
+
+    size_t index = 0;
+    OICStrcpy((retQuery + index), uriLen, uri);
+    index += uriLen - 1;
+    OICStrcpy((retQuery + index), 2, "?");
+    index += 1;
+    OICStrcpy((retQuery + index), qKeyLen, NS_QUERY_CONSUMER_ID);
+    index += qKeyLen - 1;
+    OICStrcpy((retQuery + index), 2, "=");
+    index += 1;
+    OICStrcpy((retQuery + index), NS_DEVICE_ID_LENGTH, consumerId);
+
+    NSOICFree(consumerId);
+
+    return retQuery;
+}
+
+bool * NSGetBoneIsStartedConsumer()
+{
+    static bool g_isStartedConsumer = false;
+
+    return & g_isStartedConsumer;
+}
+
+void NSSetIsStartedConsumer(bool setValue)
+{
+    * NSGetBoneIsStartedConsumer() = setValue;
+}
+
+bool NSIsStartedConsumer()
+{
+    return * NSGetBoneIsStartedConsumer();
+}
+
+NSProviderDiscoveredCallback * NSGetBoneDiscoverCb()
+{
+    static NSProviderDiscoveredCallback g_discoverCb = NULL;
+
+    return & g_discoverCb;
+}
+
+void NSSetDiscoverProviderCb(NSProviderDiscoveredCallback cb)
+{
+    * NSGetBoneDiscoverCb() = cb;
+}
+
+NSProviderDiscoveredCallback NSGetDiscoverCb()
+{
+    return * NSGetBoneDiscoverCb();
+}
+
+void * NSDiscoveredProviderFunc(void * provider)
+{
+    NSGetDiscoverCb()((NSProvider *) provider);
+
+    return NULL;
+}
+
+void NSDiscoveredProvider(NSProvider * provider)
+{
+    NSConsumerThread * thread = NSThreadInit(NSDiscoveredProviderFunc, (void *) provider);
+    NS_VERIFY_NOT_NULL_V(thread);
+}
+
+NSSubscriptionAcceptedCallback * NSGetSubscriptionAcceptedCb()
+{
+    static NSSubscriptionAcceptedCallback g_acceptCb = NULL;
+
+    return & g_acceptCb;
+}
+
+void NSSetSubscriptionAcceptedCb(NSSubscriptionAcceptedCallback cb)
+{
+    *(NSGetSubscriptionAcceptedCb()) = cb;
+}
+
+void NSSubscriptionAccepted(NSProvider * provider)
+{
+    (*(NSGetSubscriptionAcceptedCb()))(provider);
+}
+
+NSSyncInfoReceivedCallback * NSGetBoneNotificationSyncCb()
+{
+    static NSSyncInfoReceivedCallback g_syncCb = NULL;
+
+    return & g_syncCb;
+}
+
+void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb)
+{
+    * NSGetBoneNotificationSyncCb() = cb;
+}
+
+void * NSNotificationSyncFunc(void * obj)
+{
+    (* NSGetBoneNotificationSyncCb())((NSSyncInfo *) obj);
+    return NULL;
+}
+
+void NSNotificationSync(NSSyncInfo * sync)
+{
+    NS_VERIFY_NOT_NULL_V(sync);
+    NSConsumerThread * thread = NSThreadInit(NSNotificationSyncFunc, (void *) sync);
+    NS_VERIFY_NOT_NULL_V(thread);
+}
+
+NSMessageReceivedCallback  * NSGetBoneMessagePostedCb()
+{
+    static NSMessageReceivedCallback  g_postCb = NULL;
+
+    return & g_postCb;
+}
+
+void NSSetMessagePostedCb(NSMessageReceivedCallback  cb)
+{
+    * NSGetBoneMessagePostedCb() = cb;
+}
+
+NSMessageReceivedCallback  NSGetMessagePostedCb()
+{
+    return * NSGetBoneMessagePostedCb();
+}
+
+void * NSMessagePostFunc(void * obj)
+{
+    NSGetMessagePostedCb()((NSMessage *) obj);
+    return NULL;
+}
+
+void NSMessagePost(NSMessage * msg)
+{
+    NS_VERIFY_NOT_NULL_V(msg);
+    NSConsumerThread * thread = NSThreadInit(NSMessagePostFunc, (void *) msg);
+    NS_VERIFY_NOT_NULL_V(thread);
+}
+
+NSTask * NSMakeTask(NSTaskType type, void * data)
+{
+    NSTask * retTask = OICMalloc(sizeof(NSTask));
+    NS_VERIFY_NOT_NULL(retTask, NULL);
+
+    retTask->taskType = type;
+    retTask->taskData = data;
+    retTask->nextTask = NULL;
+
+    return retTask;
+}
+
+NSMessage_consumer * NSCopyMessage(NSMessage_consumer * msg)
+{
+    NS_VERIFY_NOT_NULL(msg, NULL);
+
+    NSMessage_consumer * newMsg = (NSMessage_consumer *)OICMalloc(sizeof(NSMessage_consumer));
+    NS_VERIFY_NOT_NULL(newMsg, NULL);
+
+    OICStrcpy(newMsg->providerId, NS_DEVICE_ID_LENGTH, msg->providerId);
+    newMsg->i_addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newMsg, NULL, OICFree(newMsg));
+    memcpy(newMsg->i_addr, msg->i_addr, sizeof(OCDevAddr));
+
+    newMsg->messageId = msg->messageId;
+    newMsg->title = OICStrdup(msg->title);
+    newMsg->contentText = OICStrdup(msg->contentText);
+    newMsg->sourceName = OICStrdup(msg->sourceName);
+
+    return newMsg;
+}
+void NSRemoveMessage(NSMessage_consumer * msg)
+{
+    msg->messageId = 0;
+    NSOICFree(msg->title);
+    NSOICFree(msg->contentText);
+    NSOICFree(msg->sourceName);
+    NSOICFree(msg->i_addr);
+
+    NSOICFree(msg);
+}
+
+void NSRemoveConnections(NSProviderConnectionInfo * connections)
+{
+    NSProviderConnectionInfo * tmp = connections;
+
+    while(tmp)
+    {
+        tmp->messageHandle = NULL;
+        tmp->syncHandle = NULL;
+        NSOICFree(tmp->addr);
+        tmp = tmp->next;
+    }
+
+    NSOICFree(connections);
+}
+
+NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr)
+{
+    NSProviderConnectionInfo * connections
+        = (NSProviderConnectionInfo *)OICMalloc(sizeof(NSProviderConnectionInfo));
+    NS_VERIFY_NOT_NULL(connections, NULL);
+
+    connections->addr = NULL;
+    connections->messageHandle = NULL;
+    connections->syncHandle = NULL;
+    connections->isCloudConnection = false;
+    connections->next = NULL;
+
+    if (inAddr)
+    {
+        connections->addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(connections->addr, NULL, NSRemoveConnections(connections));
+        memcpy(connections->addr, inAddr, sizeof(OCDevAddr));
+    }
+
+    return connections;
+}
+
+NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn)
+{
+    NS_VERIFY_NOT_NULL(conn, NULL);
+    NSProviderConnectionInfo * tmp = conn;
+
+    NSProviderConnectionInfo * retInfo = NSCreateProviderConnections(tmp->addr);
+    tmp = tmp->next;
+    NSProviderConnectionInfo * copyInfo = retInfo;
+
+    while(tmp)
+    {
+        copyInfo = NSCreateProviderConnections(tmp->addr);
+        NS_VERIFY_NOT_NULL(copyInfo, NULL);
+
+        copyInfo->messageHandle = tmp->messageHandle;
+        copyInfo->syncHandle = tmp->syncHandle;
+        copyInfo->isCloudConnection = tmp->isCloudConnection;
+        tmp = tmp->next;
+        copyInfo = copyInfo->next;
+    }
+
+    return retInfo;
+}
+
+NSProvider_internal * NSCopyProvider(NSProvider_internal * prov)
+{
+    NS_VERIFY_NOT_NULL(prov, NULL);
+
+    NSProviderConnectionInfo * connections = NSCopyProviderConnections(prov->connection);
+    NS_VERIFY_NOT_NULL(connections, NULL);
+
+    NSProvider_internal * newProv = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProv, NULL, NSRemoveConnections(connections));
+
+    newProv->connection = connections;
+    OICStrcpy(newProv->providerId, NS_DEVICE_ID_LENGTH, prov->providerId);
+    newProv->messageUri = OICStrdup(prov->messageUri);
+    newProv->syncUri = OICStrdup(prov->syncUri);
+    newProv->accessPolicy = prov->accessPolicy;
+
+    return newProv;
+}
+void NSRemoveProvider(NSProvider_internal * prov)
+{
+    NSOICFree(prov->messageUri);
+    NSOICFree(prov->syncUri);
+    NSRemoveConnections(prov->connection);
+
+    NSOICFree(prov);
+}
+
+OCStackResult NSInvokeRequest(OCDoHandle * handle,
+        OCMethod method, const OCDevAddr * addr,
+        const char * queryUrl, OCPayload * payload,
+        void * callbackFunc, void * callbackData, OCConnectivityType type)
+{
+    int mutexRet = pthread_mutex_lock(*(NSGetStackMutex()));
+    NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
+
+    OCCallbackData cbdata = { 0, };
+
+    cbdata.cb = callbackFunc;
+    cbdata.context = callbackData;
+    cbdata.cd = NULL;
+
+    OCStackResult ret = OCDoResource(handle, method, queryUrl, addr,
+                                     payload, type, NS_QOS, &cbdata, NULL, 0);
+
+    mutexRet = pthread_mutex_unlock(*(NSGetStackMutex()));
+    NS_VERIFY_NOT_NULL(mutexRet != 0 ? NULL : (void *)1, OC_STACK_ERROR);
+
+    return ret;
+}
diff --git a/service/notification/src/consumer/NSConsumerCommon.h b/service/notification/src/consumer/NSConsumerCommon.h
new file mode 100644 (file)
index 0000000..d84e01b
--- /dev/null
@@ -0,0 +1,232 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_CONSTANTS_H_
+#define _NS_CONSUMER_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "NSConsumerInterface.h"
+#include "NSStructs.h"
+#include "ocstack.h"
+
+#define NS_QOS OC_LOW_QOS
+#define NS_RESOURCE_TYPE "oic.r.notification"
+#define NS_RESOURCE_URI "/notification"
+#define NS_INTERFACE_BASELINE "oic.if.baseline"
+#define NS_INTERFACE_NOTIFICATION "oic.if.notification"
+#define NS_RESOURCE_QUERY "/oic/res"
+
+#define NS_DISCOVER_QUERY "/oic/res?rt=oic.r.notification"
+#define NS_DEVICE_ID_LENGTH 37
+
+#define NS_VERIFY_NOT_NULL_V(obj) \
+    { \
+        if ((obj) == NULL) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is null", __func__, #obj); \
+            return; \
+        } \
+    }
+
+#define NS_VERIFY_NOT_NULL(obj, retVal) \
+    { \
+        if ((obj) == NULL) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is null", __func__, #obj); \
+            return (retVal); \
+        } \
+    }
+
+#define NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(obj, func) \
+    { \
+        if ((obj) == NULL) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is null", __func__, #obj); \
+            NS_LOG(ERROR, "execute deletion"); \
+            (func); \
+            return; \
+        } \
+    }
+
+#define NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, retVal, func) \
+    { \
+        if ((obj) == NULL) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is null", __func__, #obj); \
+            NS_LOG(ERROR, "execute deletion"); \
+            (func); \
+            return (retVal); \
+        } \
+    }
+
+#define NS_VERIFY_STACK_OK_V(obj) \
+    { \
+        OCStackResult _ret = (obj); \
+        if ( _ret != OC_STACK_OK) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is not OC_STACK_OK : %d", __func__, #obj, _ret); \
+            return; \
+        } \
+    }
+
+#define NS_VERIFY_STACK_OK(obj, retVal) \
+    { \
+        OCStackResult _ret = (obj); \
+        if ( _ret != OC_STACK_OK) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is not OC_STACK_OK : %d", __func__, #obj, _ret); \
+            return (retVal); \
+        } \
+    }
+
+#define NS_VERIFY_STACK_OK_WITH_POST_CLEANING(obj, retVal, func) \
+    { \
+        OCStackResult _ret = (obj); \
+        if ( _ret != OC_STACK_OK) \
+        { \
+            NS_LOG_V(ERROR, "%s : %s is not OC_STACK_OK : %d", __func__, #obj, _ret); \
+            (func); \
+            return (retVal); \
+        } \
+    }
+
+#define NSOICFree(obj) \
+    { \
+        if ((obj)) \
+        { \
+            OICFree((obj)); \
+            (obj) = NULL; \
+            NS_LOG_V(DEBUG, "%s : %s Removed", __func__, #obj); \
+        } \
+    }
+
+typedef enum
+{
+    NS_DISCOVER_DEFAULT, // will work for adapter_ip.
+    NS_DISCOVER_UDP,
+    NS_DISCOVER_TCP,
+    NS_DISCOVER_CLOUD
+} NSConsumerDiscoverType;
+
+typedef struct NSProviderConnectionInfo
+{
+    OCDevAddr * addr;
+
+    OCDoHandle messageHandle;
+    OCDoHandle syncHandle;
+
+    bool isCloudConnection;
+
+    struct NSProviderConnectionInfo * next;
+
+} NSProviderConnectionInfo;
+
+typedef struct
+{
+    char providerId[NS_DEVICE_ID_LENGTH];
+
+    char * messageUri;
+    char * syncUri;
+
+    NSAccessPolicy accessPolicy;
+
+    NSProviderConnectionInfo * connection;
+
+} NSProvider_internal;
+
+typedef struct
+{
+    uint64_t messageId;
+    char providerId[NS_DEVICE_ID_LENGTH];
+    NSSyncType state;
+
+    NSProviderConnectionInfo * connection;
+
+} NSSyncInfo_internal;
+
+typedef struct
+{
+    // Mandatory
+    uint64_t messageId;
+    char providerId[NS_DEVICE_ID_LENGTH];
+
+    //optional
+    NSMessageType type;
+    char * dateTime;
+    uint64_t ttl;
+    char * title;
+    char * contentText;
+    char * sourceName;
+    NSMediaContents mediaContents;
+
+    OCDevAddr * i_addr;
+    NSSyncType i_messageTypes;
+} NSMessage_consumer;
+
+bool NSIsStartedConsumer();
+void NSSetIsStartedConsumer(bool setValue);
+
+void NSSetDiscoverProviderCb(NSProviderDiscoveredCallback cb);
+void NSDiscoveredProvider(NSProvider * provider);
+
+void NSSetSubscriptionAcceptedCb(NSSubscriptionAcceptedCallback cb);
+void NSSubscriptionAccepted(NSProvider * provider);
+
+void NSSetMessagePostedCb(NSMessageReceivedCallback  cb);
+void NSMessagePost(NSMessage * obj);
+
+void NSSetNotificationSyncCb(NSSyncInfoReceivedCallback cb);
+void NSNotificationSync(NSSyncInfo * sync);
+
+char ** NSGetConsumerId();
+void NSSetConsumerId(char * cId);
+
+char * NSMakeRequestUriWithConsumerId(const char * uri);
+
+NSTask * NSMakeTask(NSTaskType, void *);
+
+NSResult NSConsumerPushEvent(NSTask *);
+
+NSMessage_consumer * NSCopyMessage(NSMessage_consumer *);
+void NSRemoveMessage(NSMessage_consumer *);
+
+NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr * inAddr);
+NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo * conn);
+void NSRemoveConnections(NSProviderConnectionInfo * connections);
+
+NSProvider_internal * NSCopyProvider(NSProvider_internal *);
+void NSRemoveProvider(NSProvider_internal *);
+
+OCStackResult NSInvokeRequest(OCDoHandle * handle,
+        OCMethod method, const OCDevAddr * addr,
+        const char * queryUrl, OCPayload * payload,
+        void * callbackFunc, void * callbackData, OCConnectivityType type);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_CONSTANTS_H_
diff --git a/service/notification/src/consumer/NSConsumerCommunication.c b/service/notification/src/consumer/NSConsumerCommunication.c
new file mode 100644 (file)
index 0000000..3e0cf04
--- /dev/null
@@ -0,0 +1,378 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+#include "NSConsumerCommunication.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
+
+#define NS_SYNC_URI "/notification/sync"
+
+unsigned long NS_MESSAGE_ACCEPTANCE = 1;
+
+NSMessage_consumer * NSCreateMessage_internal(uint64_t msgId, const char * providerId);
+NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state);
+
+NSMessage_consumer * NSGetMessage(OCClientResponse * clientResponse);
+NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
+
+char * NSGetCloudUri(const char * providerId, char * uri);
+
+NSResult NSConsumerSubscribeProvider(NSProvider * provider)
+{
+    NSProvider_internal * provider_internal = (NSProvider_internal *) provider;
+    NS_VERIFY_NOT_NULL(provider_internal, NS_ERROR);
+
+    NSProviderConnectionInfo * connections = provider_internal->connection;
+    while(connections)
+    {
+        if (connections->messageHandle)
+        {
+            continue;
+        }
+
+        char * msgUri = OICStrdup(provider_internal->messageUri);
+        char * syncUri = OICStrdup(provider_internal->syncUri);
+
+        OCConnectivityType type = CT_DEFAULT;
+        if (connections->addr->adapter == OC_ADAPTER_TCP)
+        {
+            type = CT_ADAPTER_TCP;
+            if (connections->isCloudConnection == true)
+            {
+                msgUri = NSGetCloudUri(provider_internal->providerId, msgUri);
+                syncUri = NSGetCloudUri(provider_internal->providerId, syncUri);
+            }
+        }
+
+        NS_LOG(DEBUG, "get subscribe message query");
+        char * query = NULL;
+        query = NSMakeRequestUriWithConsumerId(msgUri);
+        NS_VERIFY_NOT_NULL(query, NS_ERROR);
+
+        NS_LOG(DEBUG, "subscribe message");
+        NS_LOG_V(DEBUG, "subscribe query : %s", query);
+        OCStackResult ret = NSInvokeRequest(&(connections->messageHandle),
+                              OC_REST_OBSERVE, connections->addr, query, NULL,
+                              NSConsumerMessageListener, NULL, type);
+        NS_VERIFY_STACK_OK_WITH_POST_CLEANING(ret, NS_ERROR, NSOICFree(query));
+        NSOICFree(query);
+        NSOICFree(msgUri);
+
+        NS_LOG(DEBUG, "get subscribe sync query");
+        query = NSMakeRequestUriWithConsumerId(syncUri);
+        NS_VERIFY_NOT_NULL(query, NS_ERROR);
+
+        NS_LOG(DEBUG, "subscribe sync");
+        NS_LOG_V(DEBUG, "subscribe query : %s", query);
+        ret = NSInvokeRequest(&(connections->syncHandle),
+                              OC_REST_OBSERVE, connections->addr, query, NULL,
+                              NSConsumerSyncInfoListener, NULL, type);
+        NS_VERIFY_STACK_OK_WITH_POST_CLEANING(ret, NS_ERROR, NSOICFree(query));
+        NSOICFree(query);
+        NSOICFree(syncUri);
+
+        connections = connections->next;
+    }
+
+    return NS_OK;
+}
+
+OCStackApplicationResult NSConsumerCheckPostResult(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) ctx;
+    (void) handle;
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+void NSRemoveSyncInfoObj(NSSyncInfo * sync)
+{
+    NSOICFree(sync);
+}
+
+OCStackApplicationResult NSConsumerSyncInfoListener(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) ctx;
+    (void) handle;
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG(DEBUG, "get NSSyncInfo");
+    NSSyncInfo * newSync = NSGetSyncInfoc(clientResponse);
+    NS_VERIFY_NOT_NULL(newSync, OC_STACK_KEEP_TRANSACTION);
+
+    NSTaskType taskType = TASK_RECV_SYNCINFO;
+
+    NS_LOG(DEBUG, "build NSTask");
+    NSTask * task = NSMakeTask(taskType, (void *) newSync);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task,
+               OC_STACK_KEEP_TRANSACTION, NSRemoveSyncInfoObj(newSync));
+
+    NSConsumerPushEvent(task);
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult NSConsumerMessageListener(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) ctx;
+    (void) handle;
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG(DEBUG, "build NSMessage");
+    NSMessage_consumer * newNoti = NSGetMessage(clientResponse);
+    NS_VERIFY_NOT_NULL(newNoti, OC_STACK_KEEP_TRANSACTION);
+
+    NSTaskType type = TASK_CONSUMER_RECV_MESSAGE;
+
+    if (newNoti->messageId == NS_MESSAGE_ACCEPTANCE)
+    {
+        NS_LOG(DEBUG, "Receive Subscribe confirm");
+        type = TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED;
+    }
+    else
+    {
+        NS_LOG(DEBUG, "Receive new message");
+    }
+
+    NS_LOG(DEBUG, "build NSTask");
+    NSTask * task = NSMakeTask(type, (void *) newNoti);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveMessage(newNoti));
+
+    NSConsumerPushEvent(task);
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+void NSGetMessagePostClean(char * pId, OCDevAddr * addr)
+{
+    NSOICFree(pId);
+    NSOICFree(addr);
+}
+
+NSMessage_consumer * NSGetMessage(OCClientResponse * clientResponse)
+{
+    NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
+    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
+
+    NS_LOG(DEBUG, "get msg id");
+    uint64_t id = NULL;
+    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get provider id");
+    char * pId = NULL;
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
+    NS_LOG_V (DEBUG, "provider id: %s", pId);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get provider address");
+    OCDevAddr * addr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(addr, NULL, NSGetMessagePostClean(pId, addr));
+    memcpy(addr, clientResponse->addr, sizeof(OCDevAddr));
+
+    NS_LOG(DEBUG, "create NSMessage");
+    NSMessage_consumer * retMsg = NSCreateMessage_internal(id, pId);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSGetMessagePostClean(pId, addr));
+    NSOICFree(pId);
+
+    retMsg->i_addr = addr;
+    retMsg->i_messageTypes = NS_SYNC_UNREAD;
+
+    NS_LOG(DEBUG, "get msg optional field");
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
+
+    OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
+    OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
+
+    NS_LOG_V(DEBUG, "Msg Address : %s", retMsg->i_addr->addr);
+    NS_LOG_V(DEBUG, "Msg ID      : %lu", retMsg->messageId);
+    NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
+    NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
+    NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
+    NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
+    NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
+    NS_LOG_V(DEBUG, "Msg ttl     : %lu", retMsg->ttl);
+
+    return retMsg;
+}
+
+NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
+{
+    NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
+
+    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
+
+    NS_LOG(DEBUG, "get msg id");
+    uint64_t id = NULL;
+    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get provider id");
+    char * pId = NULL;
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get state");
+    int64_t state = 0;
+    getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_STATE, & state);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "create NSSyncInfo");
+    NSSyncInfo * retSync = NSCreateSyncInfo_consumer(id, pId, (NSSyncType)state);
+    NS_VERIFY_NOT_NULL(retSync, NULL);
+
+    NS_LOG_V(DEBUG, "Sync ID : %lu", retSync->messageId);
+    NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
+    NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
+
+    return retSync;
+}
+
+NSMessage_consumer * NSCreateMessage_internal(uint64_t id, const char * providerId)
+{
+    NSMessage_consumer * retMsg = (NSMessage_consumer *)OICMalloc(sizeof(NSMessage_consumer));
+    NS_VERIFY_NOT_NULL(retMsg, NULL);
+
+    retMsg->messageId = id;
+    OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
+    retMsg->title = NULL;
+    retMsg->contentText = NULL;
+    retMsg->sourceName = NULL;
+    retMsg->type = NS_MESSAGE_INFO;
+    retMsg->dateTime = NULL;
+    retMsg->ttl = 0;
+    retMsg->i_addr = NULL;
+
+    return retMsg;
+}
+
+NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state)
+{
+    NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+    NS_VERIFY_NOT_NULL(retSync, NULL);
+
+    retSync->messageId = msgId;
+    retSync->state = state;
+    OICStrcpy(retSync->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
+
+    return retSync;
+}
+
+OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
+{
+    OCRepPayload * payload = OCRepPayloadCreate();
+    NS_VERIFY_NOT_NULL(payload, OC_STACK_ERROR);
+
+    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t)syncInfo->messageId);
+    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, syncInfo->state);
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, syncInfo->providerId);
+
+    char * uri = (char*)OICStrdup(NS_SYNC_URI);
+    OCConnectivityType type = CT_DEFAULT;
+    if(addr->adapter == OC_ADAPTER_TCP)
+    {
+        type = CT_ADAPTER_TCP;
+        uri = NSGetCloudUri(syncInfo->providerId, uri);
+    }
+
+    OCStackResult ret = NSInvokeRequest(NULL, OC_REST_POST, addr,
+                            uri, (OCPayload*)payload,
+                            NSConsumerCheckPostResult, NULL, type);
+    NSOICFree(uri);
+
+    return ret;
+}
+
+char * NSGetCloudUri(const char * providerId, char * uri)
+{
+    size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1;
+    char * retUri = (char *)OICMalloc(uriLen);
+    snprintf(retUri, uriLen, "/%s%s", providerId, uri);
+    NSOICFree(uri);
+    NS_LOG_V(DEBUG, "TCP uri : %s", retUri);
+
+    return retUri;
+}
+
+void NSConsumerCommunicationTaskProcessing(NSTask * task)
+{
+    NS_VERIFY_NOT_NULL_V(task);
+
+    NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
+    if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE)
+    {
+        NS_VERIFY_NOT_NULL_V(task->taskData);
+        NS_LOG(DEBUG, "Request Subscribe");
+        NSResult ret = NSConsumerSubscribeProvider((NSProvider *)task->taskData);
+        NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
+    }
+    else if (task->taskType == TASK_SEND_SYNCINFO)
+    {
+        NS_VERIFY_NOT_NULL_V(task->taskData);
+        NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)task->taskData;
+        NSProviderConnectionInfo * info = syncInfo->connection;
+
+        while(info)
+        {
+            OCStackResult ret = NSSendSyncInfo((NSSyncInfo *)(task->taskData), info->addr);
+            if (ret != OC_STACK_OK)
+            {
+                NS_LOG_V(ERROR, "send sync info fail : %d", info->addr->adapter);
+            }
+
+            info = info->next;
+        }
+
+        NSRemoveConnections(syncInfo->connection);
+        NSOICFree(syncInfo);
+    }
+    else if (task->taskType == TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL)
+    {
+        NSProvider_internal * provider = (NSProvider_internal *)task->taskData;
+
+        NSProviderConnectionInfo * connections = provider->connection;
+        while(connections)
+        {
+            OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
+            OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
+            connections = connections->next;
+        }
+    }
+    else
+    {
+        NS_LOG(ERROR, "Unknown type message");
+    }
+}
diff --git a/service/notification/src/consumer/NSConsumerCommunication.h b/service/notification/src/consumer/NSConsumerCommunication.h
new file mode 100644 (file)
index 0000000..31ddfb7
--- /dev/null
@@ -0,0 +1,46 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_NOTIFICATION_H_
+#define _NS_CONSUMER_NOTIFICATION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdlib.h>
+
+#include "NSCommon.h"
+#include "NSStructs.h"
+#include "ocstack.h"
+
+void NSConsumerCommunicationTaskProcessing(NSTask *);
+
+NSResult NSConsumerSubscribeProvider(NSProvider *);
+
+OCStackApplicationResult NSConsumerMessageListener(void *, OCDoHandle, OCClientResponse *);
+
+OCStackApplicationResult NSConsumerSyncInfoListener(void *, OCDoHandle, OCClientResponse *);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_NOTIFICATION_H_
diff --git a/service/notification/src/consumer/NSConsumerDiscovery.c b/service/notification/src/consumer/NSConsumerDiscovery.c
new file mode 100644 (file)
index 0000000..2918b2a
--- /dev/null
@@ -0,0 +1,356 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerDiscovery.h"
+
+#include <string.h>
+#include "NSCommon.h"
+#include "NSConsumerCommon.h"
+#include "NSConstants.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#define NS_DISCOVER_QUERY "/oic/res?rt=oic.r.notification"
+#define NS_PRESENCE_SUBSCRIBE_QUERY "coap://224.0.1.187:5683/oic/ad?rt=oic.r.notification"
+#define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=oic.r.notification"
+#define NS_GET_INFORMATION_QUERY "/notification?if=oic.if.notification"
+
+NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
+
+OCDevAddr * NSChangeAddress(const char * address);
+
+OCStackApplicationResult NSConsumerPresenceListener(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) ctx;
+    (void) handle;
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG_V(DEBUG, "Presence income : %s:%d",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+    NS_LOG_V(DEBUG, "Presence result : %d",
+            clientResponse->result);
+    NS_LOG_V(DEBUG, "Presence sequenceNum : %d",
+            clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "Presence Transport Type : %d",
+                clientResponse->devAddr.adapter);
+
+    if (!NSIsStartedConsumer())
+    {
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCPresencePayload * payload = (OCPresencePayload *)clientResponse->payload;
+    if (payload->trigger == OC_PRESENCE_TRIGGER_DELETE ||
+            clientResponse->result == OC_STACK_PRESENCE_STOPPED)
+    {
+        // TODO find request and cancel
+        NS_LOG(DEBUG, "stopped presence or resource is deleted.");
+        //OCCancel(handle, NS_QOS, NULL, 0);
+    }
+
+    else if (payload->trigger == OC_PRESENCE_TRIGGER_CREATE)
+    {
+        NS_LOG(DEBUG, "started presence or resource is created.");
+        NSInvokeRequest(NULL, OC_REST_DISCOVER, clientResponse->addr,
+            NS_DISCOVER_QUERY, NULL, NSProviderDiscoverListener, NULL,
+            clientResponse->addr->adapter);
+    }
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult NSProviderDiscoverListener(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) handle;
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG_V(DEBUG, "Discover income : %s:%d",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+    NS_LOG_V(DEBUG, "Discover result : %d",
+            clientResponse->result);
+    NS_LOG_V(DEBUG, "Discover sequenceNum : %d",
+            clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "Discover Transport Type : %d",
+                    clientResponse->devAddr.adapter);
+
+    if (!NSIsStartedConsumer())
+    {
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
+    while (resource)
+    {
+        if (strstr(resource->uri, NS_RESOURCE_URI))
+        {
+            OCConnectivityType type = CT_DEFAULT;
+            if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
+            {
+                type = CT_ADAPTER_TCP;
+            }
+
+            NSInvokeRequest(NULL, OC_REST_GET, clientResponse->addr,
+                    resource->uri, NULL, NSIntrospectProvider, ctx,
+                    type);
+        }
+        resource = resource->next;
+    }
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+void NSRemoveProviderObj(NSProvider_internal * provider)
+{
+    NSOICFree(provider->messageUri);
+    NSOICFree(provider->syncUri);
+
+    NSRemoveConnections(provider->connection);
+    NSOICFree(provider);
+}
+
+OCStackApplicationResult NSIntrospectProvider(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) handle;
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_OK(clientResponse->result, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG_V(DEBUG, "GET response income : %s:%d",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+    NS_LOG_V(DEBUG, "GET response result : %d",
+            clientResponse->result);
+    NS_LOG_V(DEBUG, "GET response sequenceNum : %d",
+            clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "GET response resource uri : %s",
+            clientResponse->resourceUri);
+    NS_LOG_V(DEBUG, "GET response Transport Type : %d",
+                    clientResponse->devAddr.adapter);
+
+    if (!NSIsStartedConsumer())
+    {
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    NSProvider_internal * newProvider = NSGetProvider(clientResponse);
+    NS_VERIFY_NOT_NULL(newProvider, OC_STACK_KEEP_TRANSACTION);
+    if (ctx && *((NSConsumerDiscoverType *)ctx) == NS_DISCOVER_CLOUD )
+    {
+        newProvider->connection->isCloudConnection = true;
+        NSOICFree(ctx);
+    }
+
+    NS_LOG(DEBUG, "build NSTask");
+    NSTask * task = NSMakeTask(TASK_CONSUMER_PROVIDER_DISCOVERED, (void *) newProvider);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, NS_ERROR, NSRemoveProviderObj(newProvider));
+
+    NSConsumerPushEvent(task);
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+void NSGetProviderPostClean(
+        char * pId, char * mUri, char * sUri, NSProviderConnectionInfo * connection)
+{
+    NSOICFree(pId);
+    NSOICFree(mUri);
+    NSOICFree(sUri);
+    NSRemoveConnections(connection);
+}
+
+NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
+{
+    NS_LOG(DEBUG, "create NSProvider");
+    NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
+
+    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
+    while (payload)
+    {
+        NS_LOG_V(DEBUG, "Payload Key : %s", payload->values->name);
+        payload = payload->next;
+    }
+
+    payload = (OCRepPayload *)clientResponse->payload;
+
+    char * providerId = NULL;
+    char * messageUri = NULL;
+    char * syncUri = NULL;
+    int64_t accepter = 0;
+    NSProviderConnectionInfo * connection = NULL;
+
+    NS_LOG(DEBUG, "get information of accepter");
+    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & accepter);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get provider ID");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get message URI");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
+            NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
+
+    NS_LOG(DEBUG, "get sync URI");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
+            NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
+
+    NS_LOG(DEBUG, "get provider connection information");
+    NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
+    connection = NSCreateProviderConnections(clientResponse->addr);
+    NS_VERIFY_NOT_NULL(connection, NULL);
+
+    NSProvider_internal * newProvider
+        = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
+          NSGetProviderPostClean(providerId, messageUri, syncUri, connection));
+
+    OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
+    NSOICFree(providerId);
+    newProvider->messageUri = messageUri;
+    newProvider->syncUri = syncUri;
+    newProvider->accessPolicy = (NSAccessPolicy)accepter;
+    newProvider->connection = connection;
+
+    return newProvider;
+}
+
+OCDevAddr * NSChangeAddress(const char * address)
+{
+    NS_VERIFY_NOT_NULL(address, NULL);
+    OCDevAddr * retAddr = NULL;
+
+    int index = 0;
+    while(address[index] != '\0')
+    {
+        if (address[index] == ':')
+        {
+            break;
+        }
+        index++;
+    }
+
+    if (address[index] == '\0')
+    {
+        return NULL;
+    }
+
+    int tmp = index + 1;
+    uint16_t port = address[tmp++];
+
+    while(address[tmp] != '\0')
+    {
+        port *= 10;
+        port += address[tmp++] - '0';
+    }
+
+    retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
+    NS_VERIFY_NOT_NULL(retAddr, NULL);
+
+    retAddr->adapter = OC_ADAPTER_TCP;
+    OICStrcpy(retAddr->addr, index - 1, address);
+    retAddr->addr[index] = '\0';
+    retAddr->port = port;
+
+    return retAddr;
+}
+
+void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
+{
+    OCConnectivityType type = CT_DEFAULT;
+    NSConsumerDiscoverType * callbackData = NULL;
+
+    if (address)
+    {
+        if (address->adapter == OC_ADAPTER_IP)
+        {
+            type = CT_ADAPTER_IP;
+            NS_LOG(DEBUG, "Request discover [UDP]");
+        }
+        else if (address->adapter == OC_ADAPTER_TCP)
+        {
+            type = CT_ADAPTER_TCP;
+            NS_LOG(DEBUG, "Request discover and subscribe presence [TCP]");
+            NS_LOG(DEBUG, "Subscribe presence [TCP]");
+            NSInvokeRequest(NULL, OC_REST_PRESENCE, address, NS_PRESENCE_SUBSCRIBE_QUERY_TCP,
+                    NULL, NSConsumerPresenceListener, NULL, type);
+
+            if (rType == NS_DISCOVER_CLOUD)
+            {
+                callbackData = (NSConsumerDiscoverType *)OICMalloc(sizeof(NSConsumerDiscoverType));
+                *callbackData = NS_DISCOVER_CLOUD;
+            }
+        }
+        else
+        {
+            NS_LOG_V(DEBUG, "Request discover But Adapter is not IP : %d", address->adapter);
+        }
+    }
+    else
+    {
+        NS_LOG(DEBUG, "Request Multicast discover [UDP]");
+    }
+
+    NSInvokeRequest(NULL, OC_REST_DISCOVER, address, NS_DISCOVER_QUERY,
+            NULL, NSProviderDiscoverListener, (void *)callbackData, type);
+}
+
+void NSConsumerDiscoveryTaskProcessing(NSTask * task)
+{
+    NS_VERIFY_NOT_NULL_V(task);
+
+    NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
+    if (task->taskType == TASK_CONSUMER_REQ_DISCOVER)
+    {
+        char * address = (char *) task->taskData;
+        NSConsumerDiscoverType dType = NS_DISCOVER_DEFAULT;
+
+        OCDevAddr * addr = NULL;
+        if (address)
+        {
+            addr = NSChangeAddress(address);
+            dType = NS_DISCOVER_CLOUD;
+        }
+
+        NSConsumerHandleRequestDiscover(addr, dType);
+        NSOICFree(task->taskData);
+        NSOICFree(addr);
+    }
+    else if (task->taskType == TASK_EVENT_CONNECTED || task->taskType == TASK_EVENT_CONNECTED_TCP)
+    {
+        NSConsumerHandleRequestDiscover((OCDevAddr *) task->taskData, NS_DISCOVER_DEFAULT);
+        NSOICFree(task->taskData);
+    }
+    else
+    {
+        NS_LOG(ERROR, "Unknown type message");
+    }
+
+    NSOICFree(task);
+}
diff --git a/service/notification/src/consumer/NSConsumerDiscovery.h b/service/notification/src/consumer/NSConsumerDiscovery.h
new file mode 100644 (file)
index 0000000..01b3a25
--- /dev/null
@@ -0,0 +1,47 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_DISCOVERY_H_
+#define _NS_CONSUMER_DISCOVERY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdlib.h>
+
+#include "ocstack.h"
+#include "NSStructs.h"
+
+void NSConsumerDiscoveryTaskProcessing(NSTask *);
+
+OCStackApplicationResult NSConsumerPresenceListener(void *, OCDoHandle, OCClientResponse *);
+
+// for discover result
+OCStackApplicationResult NSProviderDiscoverListener(void *, OCDoHandle, OCClientResponse *);
+
+// for checking Permission
+OCStackApplicationResult NSIntrospectProvider(void *, OCDoHandle, OCClientResponse *);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_DISCOVERY_H_
diff --git a/service/notification/src/consumer/NSConsumerInterface.c b/service/notification/src/consumer/NSConsumerInterface.c
new file mode 100644 (file)
index 0000000..70f1dc3
--- /dev/null
@@ -0,0 +1,143 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerInterface.h"
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "NSCommon.h"
+#include "NSConsumerCommon.h"
+#include "NSConstants.h"
+#include "NSConsumerScheduler.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+// Public APIs
+NSResult NSStartConsumer(NSConsumerConfig config)
+{
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == false ? (void *) 1 : NULL, NS_OK);
+
+    NS_VERIFY_NOT_NULL(config.discoverCb, NS_ERROR);
+    NS_VERIFY_NOT_NULL(config.messageCb, NS_ERROR);
+    NS_VERIFY_NOT_NULL(config.syncInfoCb, NS_ERROR);
+    NS_VERIFY_NOT_NULL(config.acceptedCb, NS_ERROR);
+
+    NSSetDiscoverProviderCb(config.discoverCb);
+    NSSetMessagePostedCb(config.messageCb);
+    NSSetNotificationSyncCb(config.syncInfoCb);
+    NSSetSubscriptionAcceptedCb(config.acceptedCb);
+    NSSetIsStartedConsumer(true);
+
+    NSResult ret = NSConsumerMessageHandlerInit();
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
+            NS_ERROR, NSStopConsumer());
+
+    return NS_OK;
+}
+
+NSResult NSStopConsumer()
+{
+    NSSetDiscoverProviderCb(NULL);
+    NSSetMessagePostedCb(NULL);
+    NSSetNotificationSyncCb(NULL);
+    NSSetSubscriptionAcceptedCb(NULL);
+    NSSetIsStartedConsumer(false);
+
+    NSConsumerMessageHandlerExit();
+
+    return NS_OK;
+}
+
+NSResult NSConsumerEnableRemoteService(char *serverAddress)
+{
+    NSTask * discoverTask = NSMakeTask(TASK_CONSUMER_REQ_DISCOVER, (void *)serverAddress);
+    NS_VERIFY_NOT_NULL(discoverTask, NS_ERROR);
+
+    return NSConsumerPushEvent(discoverTask);
+}
+
+NSResult NSSubscribe(NSProvider * provider)
+{
+    NSTask * subscribeTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) provider);
+    NS_VERIFY_NOT_NULL(subscribeTask, NS_ERROR);
+
+    return NSConsumerPushEvent(subscribeTask);
+}
+
+NSResult NSUnsubscribe(NSProvider * provider)
+{
+    NSTask * unsubscribeTask = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL, (void *) provider);
+    NS_VERIFY_NOT_NULL(unsubscribeTask, NS_ERROR);
+
+    return NSConsumerPushEvent(unsubscribeTask);
+}
+
+NSResult NSConsumerSendSyncInfo(const char * providerId, uint64_t messageId, NSSyncType type)
+{
+    NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+    NS_VERIFY_NOT_NULL(syncInfo, NS_ERROR);
+
+    OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
+    syncInfo->messageId = messageId;
+    syncInfo->state = type;
+
+    NSTask * syncTask = NSMakeTask(TASK_MAKE_SYNCINFO, (void *) syncInfo);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncTask, NS_ERROR, NSOICFree(syncInfo));
+
+    return NSConsumerPushEvent(syncTask);
+}
+
+NSResult NSRescanProvider()
+{
+    NSTask * discoverTask = NSMakeTask(TASK_CONSUMER_REQ_DISCOVER, NULL);
+    NS_VERIFY_NOT_NULL(discoverTask, NS_ERROR);
+
+    return NSConsumerPushEvent(discoverTask);
+}
+
+NSProvider * NSConsumerGetProvider(const char * providerId)
+{
+    NS_VERIFY_NOT_NULL(providerId, NULL);
+
+    return (NSProvider *) NSConsumerFindNSProvider(providerId);
+}
+
+NSMessage * NSConsumerGetMessage(uint64_t messageId)
+{
+    char msgId[NS_DEVICE_ID_LENGTH] = { 0, };
+    snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lu", messageId);
+
+    return (NSMessage *) NSConsumerFindNSMessage(msgId);
+}
+
+NSResult NSDropNSMessage(NSMessage * obj)
+{
+    NS_VERIFY_NOT_NULL(obj, NS_ERROR);
+
+    obj->messageId = 0;
+    NSOICFree(obj->title);
+    NSOICFree(obj->contentText);
+    NSOICFree(obj->sourceName);
+    NSOICFree(obj);
+
+    return NS_OK;
+}
diff --git a/service/notification/src/consumer/NSConsumerInternalTaskController.c b/service/notification/src/consumer/NSConsumerInternalTaskController.c
new file mode 100644 (file)
index 0000000..bb9479f
--- /dev/null
@@ -0,0 +1,342 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+#include "NSConsumerInternalTaskController.h"
+#include "NSStructs.h"
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+NSCacheList ** NSGetMessageCacheList()
+{
+    static NSCacheList * messageCache = NULL;
+    return & messageCache;
+}
+
+void NSSetMessageCacheList(NSCacheList * cache)
+{
+    *(NSGetMessageCacheList()) = cache;
+}
+
+NSCacheList ** NSGetProviderCacheList()
+{
+    static NSCacheList * providerCache = NULL;
+    return & providerCache;
+}
+
+void NSSetProviderCacheList(NSCacheList * cache)
+{
+    *(NSGetProviderCacheList()) = cache;
+}
+
+void NSDestroyMessageCacheList()
+{
+    NSCacheList * cache = *(NSGetMessageCacheList());
+    if (cache)
+    {
+        NSStorageDestroy(cache);
+    }
+}
+
+void NSDestroyProviderCacheList()
+{
+    NSCacheList * cache = *(NSGetProviderCacheList());
+    if (cache)
+    {
+        NSStorageDestroy(cache);
+    }
+}
+
+NSMessage_consumer * NSMessageCacheFind(const char * messageId)
+{
+    NS_VERIFY_NOT_NULL(messageId, NULL);
+
+    NSCacheList * MessageCache = *(NSGetMessageCacheList());
+    if (!MessageCache)
+    {
+        NS_LOG(DEBUG, "Message Cache Init");
+        MessageCache = NSStorageCreate();
+        NS_VERIFY_NOT_NULL(MessageCache, NULL);
+
+        MessageCache->cacheType = NS_CONSUMER_CACHE_MESSAGE;
+        NSSetMessageCacheList(MessageCache);
+    }
+
+    NSCacheElement * cacheElement = NSStorageRead(MessageCache, messageId);
+
+    return (NSMessage_consumer *) cacheElement->data;
+}
+
+NSProvider_internal * NSProviderCacheFind(const char * providerId)
+{
+    NS_VERIFY_NOT_NULL(providerId, NULL);
+
+    NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+    if (!ProviderCache)
+    {
+        NS_LOG(DEBUG, "Provider Cache Init");
+        ProviderCache = NSStorageCreate();
+        NS_VERIFY_NOT_NULL(ProviderCache, NULL);
+
+        ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
+        NSSetProviderCacheList(ProviderCache);
+    }
+
+    NSCacheElement * cacheElement = NSStorageRead(ProviderCache, providerId);
+    NS_VERIFY_NOT_NULL(cacheElement, NULL);
+
+    return (NSProvider_internal *) cacheElement->data;
+}
+
+
+NSResult NSMessageCacheUpdate(NSMessage_consumer * msg, NSSyncType type)
+{
+    NSCacheList * MessageCache = *(NSGetMessageCacheList());
+    if (!MessageCache)
+    {
+        NS_LOG(DEBUG, "Message Cache Init");
+        MessageCache = NSStorageCreate();
+        NS_VERIFY_NOT_NULL(MessageCache, NS_ERROR);
+
+        MessageCache->cacheType = NS_CONSUMER_CACHE_MESSAGE;
+        NSSetMessageCacheList(MessageCache);
+    }
+
+    NS_VERIFY_NOT_NULL(msg, NS_ERROR);
+
+    msg->type = type;
+
+    NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
+    NS_VERIFY_NOT_NULL(obj, NS_ERROR);
+
+    obj->data = (NSCacheData *) msg;
+    obj->next = NULL;
+
+    NS_LOG(DEBUG, "try to write to storage");
+    NSResult ret = NSStorageWrite(MessageCache, obj);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
+            NS_ERROR, NSRemoveMessage(msg));
+
+    NSOICFree(obj);
+
+    return NS_OK;
+}
+
+NSResult NSProviderCacheUpdate(NSProvider_internal * provider)
+{
+    NSCacheList * ProviderCache = *(NSGetProviderCacheList());
+    if (!ProviderCache)
+    {
+        NS_LOG(DEBUG, "Provider Cache Init");
+        ProviderCache = NSStorageCreate();
+        NS_VERIFY_NOT_NULL(ProviderCache, NS_ERROR);
+
+        ProviderCache->cacheType = NS_CONSUMER_CACHE_PROVIDER;
+        NSSetProviderCacheList(ProviderCache);
+    }
+
+    NS_VERIFY_NOT_NULL(provider, NS_ERROR);
+
+    NSCacheElement * obj = (NSCacheElement *)OICMalloc(sizeof(NSCacheElement));
+    NS_VERIFY_NOT_NULL(obj, NS_ERROR);
+
+    obj->data = (NSCacheData *) provider;
+    obj->next = NULL;
+
+    NS_LOG(DEBUG, "try to write to storage");
+    NSResult ret = NSStorageWrite(ProviderCache, obj);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(ret == NS_OK ? (void *) 1 : NULL,
+            NS_ERROR, NSRemoveProvider(provider));
+
+    NSOICFree(obj);
+
+    return NS_OK;
+}
+
+void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
+{
+    NS_VERIFY_NOT_NULL_V(provider);
+
+    bool isAdded = true;
+    NSProvider_internal * providerCacheData = NSProviderCacheFind(provider->providerId);
+    //NS_VERIFY_NOT_NULL_V(providerCacheData == NULL ? (void *)1 : NULL);
+    if (providerCacheData == NULL)
+    {
+        isAdded = false;
+    }
+    else
+    {
+        NSProviderConnectionInfo * infos = providerCacheData->connection;
+        OCTransportAdapter newAdapter = provider->connection->addr->adapter;
+        while(infos)
+        {
+            if (infos->addr->adapter == newAdapter)
+            {
+                NS_LOG(DEBUG, "This provider already discovered.");
+                return;
+            }
+            infos = infos->next;
+        }
+    }
+
+    NSResult ret = NSProviderCacheUpdate(provider);
+    NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
+
+    if (isAdded == false)
+    {
+        NS_LOG(DEBUG, "New provider is discovered");
+    }
+    else
+    {
+        provider = providerCacheData;
+        NS_LOG(DEBUG, "provider's connection is updated.");
+    }
+
+
+    if (provider->accessPolicy == NS_ACCESS_DENY && isAdded == false)
+    {
+        NS_LOG(DEBUG, "accepter is NS_ACCEPTER_CONSUMER, Callback to user");
+        NSDiscoveredProvider((NSProvider *) provider);
+    }
+    else
+    {
+        NS_LOG(DEBUG, "accepter is NS_ACCEPTER_PROVIDER, request subscribe");
+        NSTask * task = NSMakeTask(TASK_CONSUMER_REQ_SUBSCRIBE, (void *) provider);
+        NS_VERIFY_NOT_NULL_V(task);
+
+        NSConsumerPushEvent(task);
+    }
+}
+
+void NSConsumerHandleRecvSubscriptionConfirmed(NSMessage_consumer * msg)
+{
+    NS_VERIFY_NOT_NULL_V(msg);
+
+    NSProvider_internal * provider = NSProviderCacheFind(msg->providerId);
+    NS_VERIFY_NOT_NULL_V(provider);
+
+    if (provider->connection->next == NULL)
+    {
+        NSSubscriptionAccepted((NSProvider *) provider);
+    }
+}
+
+void NSConsumerHandleRecvMessage(NSMessage_consumer * msg)
+{
+    NS_VERIFY_NOT_NULL_V(msg);
+
+    NSResult ret = NSMessageCacheUpdate(msg, NS_SYNC_UNREAD);
+    NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
+
+    NSMessagePost((NSMessage *) msg);
+}
+
+void NSConsumerHandleRecvSyncInfo(NSSyncInfo * sync)
+{
+    NS_VERIFY_NOT_NULL_V(sync);
+
+    NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
+    NS_VERIFY_NOT_NULL_V(provider);
+
+    char msgId[NS_DEVICE_ID_LENGTH] = { 0, };
+    snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lu", sync->messageId);
+
+    NSMessage_consumer * msg = NSMessageCacheFind(msgId);
+    NS_VERIFY_NOT_NULL_V(msg);
+
+    NSResult ret = NSMessageCacheUpdate(msg, sync->state);
+    NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *) 1 : NULL);
+
+    NSNotificationSync(sync);
+}
+
+void NSConsumerHandleMakeSyncInfo(NSSyncInfo * sync)
+{
+    NS_VERIFY_NOT_NULL_V(sync);
+
+    NSProvider_internal * provider = NSProviderCacheFind(sync->providerId);
+    NS_VERIFY_NOT_NULL_V (provider);
+
+    NSProviderConnectionInfo * connections = NSCopyProviderConnections(provider->connection);
+    NS_VERIFY_NOT_NULL_V (connections);
+
+    NSSyncInfo_internal * syncInfo = (NSSyncInfo_internal *)OICMalloc(sizeof(NSSyncInfo_internal));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncInfo, NSRemoveConnections(connections));
+
+    OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, sync->providerId);
+    syncInfo->messageId = sync->messageId;
+    syncInfo->state = sync->state;
+    syncInfo->connection = connections;
+
+    NSTask * syncTask = NSMakeTask(TASK_SEND_SYNCINFO, (void *) syncInfo);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(syncTask, NSOICFree(syncInfo));
+
+    NSConsumerPushEvent(syncTask);
+
+    NSOICFree(sync);
+}
+
+void NSConsumerInternalTaskProcessing(NSTask * task)
+{
+    NS_VERIFY_NOT_NULL_V(task);
+
+    NS_LOG_V(DEBUG, "Receive Event : %d", (int)task->taskType);
+    switch (task->taskType)
+    {
+        case TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED:
+        {
+            NS_LOG(DEBUG, "Receive Subscribe confirm from provider.");
+            NSConsumerHandleRecvSubscriptionConfirmed((NSMessage_consumer *)task->taskData);
+            break;
+        }
+        case TASK_CONSUMER_RECV_MESSAGE:
+        {
+            NS_LOG(DEBUG, "Receive New Notification");
+            NSConsumerHandleRecvMessage((NSMessage_consumer *)task->taskData);
+
+            break;
+        }
+        case TASK_CONSUMER_PROVIDER_DISCOVERED:
+        {
+            NS_LOG(DEBUG, "Receive New Provider is discovered.");
+            NSConsumerHandleProviderDiscovered((NSProvider_internal *)task->taskData);
+            break;
+        }
+        case TASK_RECV_SYNCINFO:
+        {
+            NS_LOG(DEBUG, "Receive SyncInfo.");
+            NSConsumerHandleRecvSyncInfo((NSSyncInfo *)task->taskData);
+            break;
+        }
+        case TASK_MAKE_SYNCINFO:
+        {
+            NS_LOG(DEBUG, "Make SyncInfo, get Provider's Addr");
+            NSConsumerHandleMakeSyncInfo((NSSyncInfo *)task->taskData);
+            break;
+        }
+        default :
+        {
+            NS_LOG(ERROR, "Unknown TASK Type");
+            return ;
+        }
+    }
+}
diff --git a/service/notification/src/consumer/NSConsumerInternalTaskController.h b/service/notification/src/consumer/NSConsumerInternalTaskController.h
new file mode 100644 (file)
index 0000000..0be9f17
--- /dev/null
@@ -0,0 +1,54 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_INTERNAL_TASK_CONTROLLER_H_
+#define _NS_CONSUMER_INTERNAL_TASK_CONTROLLER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include "NSStructs.h"
+#include "NSStorageAdapter.h"
+#include "NSConsumerCommunication.h"
+
+NSCacheList ** NSGetMessageCacheList();
+
+void NSSetMessageCacheList(NSCacheList *);
+
+NSCacheList ** NSGetProviderCacheList();
+
+void NSSetProviderCacheList(NSCacheList *);
+
+void NSDestroyMessageCacheList();
+
+void NSDestroyProviderCacheList();
+
+NSMessage_consumer * NSMessageCacheFind(const char *);
+
+NSProvider_internal * NSProviderCacheFind(const char *);
+
+void NSConsumerInternalTaskProcessing(NSTask *);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_INTERNAL_TASK_CONTROLLER_H_
diff --git a/service/notification/src/consumer/NSConsumerNetworkEventListener.c b/service/notification/src/consumer/NSConsumerNetworkEventListener.c
new file mode 100644 (file)
index 0000000..b43749b
--- /dev/null
@@ -0,0 +1,126 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <memory.h>
+#include <string.h>
+
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+#include "cautilinterface.h"
+#include "oic_malloc.h"
+
+#include "NSConsumerDiscovery.h"
+#include "NSConsumerNetworkEventListener.h"
+
+#define NS_PRESENCE_SUBSCRIBE_QUERY "coap://224.0.1.187:5683/oic/ad?rt=oic.r.notification"
+
+void NSConnectionStateListener(const CAEndpoint_t * info, bool isConnected);
+
+void NSAdapterStateListener(CATransportAdapter_t adapter, bool enabled);
+
+OCDoHandle * getPresenceHandle()
+{
+    static OCDoHandle g_PresenceHandle = NULL;
+
+    return & g_PresenceHandle;
+}
+
+
+NSResult NSConsumerListenerInit()
+{
+    // TODO replace with comment lines when enable network monitor of IP Adapter
+    CARegisterNetworkMonitorHandler(NSAdapterStateListener, NSConnectionStateListener);
+//    if (CARegisterNetworkMonitorHandler(NSAdapterStateListener, NSConnectionStateListener)
+//            != CA_STATUS_OK)
+//    {
+//        return NS_ERROR;
+//    }
+
+    NS_LOG(DEBUG, "Request to subscribe presence");
+    OCStackResult stackResult = NSInvokeRequest(getPresenceHandle(), OC_REST_PRESENCE, NULL,
+                        NS_PRESENCE_SUBSCRIBE_QUERY, NULL, NSConsumerPresenceListener,
+                        NULL, CT_DEFAULT);
+    NS_VERIFY_STACK_OK(stackResult, NS_ERROR);
+
+    NS_LOG(DEBUG, "Request to discover provider");
+    stackResult = NSInvokeRequest(NULL, OC_REST_DISCOVER, NULL,
+                      NS_DISCOVER_QUERY, NULL, NSProviderDiscoverListener,
+                      NULL, CT_DEFAULT);
+    NS_VERIFY_STACK_OK(stackResult, NS_ERROR);
+
+    return NS_OK;
+}
+
+void NSConsumerListenerTermiate()
+{
+    CARegisterNetworkMonitorHandler(NULL, NULL);
+    OCCancel(*getPresenceHandle(), NS_QOS, NULL, 0);
+}
+
+void NSConnectionStateListener(const CAEndpoint_t * info, bool connected)
+{
+    NS_VERIFY_NOT_NULL_V(info);
+
+    NS_LOG_V(DEBUG, "adapter : %d", info->adapter);
+    NS_LOG_V(DEBUG, "remote_address : %s:%d", info->addr, info->port);
+    NS_LOG_V(DEBUG, "isConnect : %d", connected);
+
+    NSTaskType type = TASK_EVENT_CONNECTED;
+    OCDevAddr * addr = NULL;
+    if (connected)
+    {
+        if (info->adapter == CA_ADAPTER_TCP)
+        {
+            type = TASK_EVENT_CONNECTED_TCP;
+            NS_LOG(DEBUG, "try to discover notification provider : TCP.");
+            // TODO convet to OCDevAddr;
+            // addr = .....
+        }
+        else if (info->adapter == CA_ADAPTER_IP)
+        {
+            NS_LOG(DEBUG, "try to discover notification provider.");
+            // TODO convet to OCDevAddr;
+            // addr = .....
+        }
+
+        NSTask * task = NSMakeTask(type, addr);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(task, NSOICFree(addr));
+
+        NSConsumerPushEvent(task);
+    }
+}
+
+void NSAdapterStateListener(CATransportAdapter_t adapter, bool enabled)
+{
+    NS_LOG_V(DEBUG, "adapter : %d", adapter);
+    NS_LOG_V(DEBUG, "isEnabled : %d", enabled);
+
+    (void) adapter;
+
+    if (enabled)
+    {
+        NS_LOG(DEBUG, "try to discover notification provider.");
+
+        NSTask * task = NSMakeTask(TASK_EVENT_CONNECTED, NULL);
+        NS_VERIFY_NOT_NULL_V(task);
+
+        NSConsumerPushEvent(task);
+    }
+}
diff --git a/service/notification/src/consumer/NSConsumerNetworkEventListener.h b/service/notification/src/consumer/NSConsumerNetworkEventListener.h
new file mode 100644 (file)
index 0000000..fb1f55a
--- /dev/null
@@ -0,0 +1,42 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_LISTENER_H_
+#define _NS_CONSUMER_LISTENER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "NSCommon.h"
+#include "ocstack.h"
+
+NSResult NSConsumerListenerInit();
+
+void NSConsumerListenerTermiate();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_LISTENER_H_
diff --git a/service/notification/src/consumer/NSConsumerQueue.c b/service/notification/src/consumer/NSConsumerQueue.c
new file mode 100644 (file)
index 0000000..ae6cd2e
--- /dev/null
@@ -0,0 +1,105 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerQueue.h"
+
+#include "NSConstants.h"
+#include "oic_malloc.h"
+#include "NSConsumerCommon.h"
+
+NSConsumerQueue * NSCreateQueue()
+{
+    NSConsumerQueue * newQueue = (NSConsumerQueue *)OICMalloc(sizeof(NSConsumerQueue));
+    NS_VERIFY_NOT_NULL(newQueue, NULL);
+
+    newQueue->size = 0;
+    newQueue->head = NULL;
+    newQueue->tail = NULL;
+
+    return newQueue;
+}
+
+void NSDestroyQueue(NSConsumerQueue * queue)
+{
+    NSConsumerQueueObject * node = NSPopQueue(queue);
+    while(node)
+    {
+        node = (NSConsumerQueueObject *)node->next;
+        OICFree(node->data);
+        OICFree(node);
+    }
+
+    OICFree(queue);
+}
+
+bool NSPushQueue(NSConsumerQueue * queue, NSConsumerQueueObject * object)
+{
+    NS_VERIFY_NOT_NULL(queue, false);
+    NS_VERIFY_NOT_NULL(object, false);
+
+    if (!(queue->head))
+    {
+        queue->head = object;
+    }
+    else
+    {
+        (queue->tail)->next = object;
+    }
+
+    queue->tail = object;
+    queue->size++;
+
+    return true;
+}
+
+NSConsumerQueueObject * NSPopQueue(NSConsumerQueue * queue)
+{
+    NSConsumerQueueObject * retObject = NULL;
+
+    NS_VERIFY_NOT_NULL(queue, NULL);
+    NS_VERIFY_NOT_NULL(queue->head, NULL);
+
+    if (queue->size <= 0)
+    {
+        return NULL;
+    }
+
+    retObject = queue->head;
+
+    queue->head = (NSConsumerQueueObject *)(retObject->next);
+    if (!(queue->head))
+    {
+        queue->tail = NULL;
+    }
+    retObject->next = NULL;
+    queue->size--;
+
+    return retObject;
+}
+
+int NSGetQueueSize(NSConsumerQueue * queue)
+{
+    return queue->size;
+}
+
+bool NSIsQueueEmpty(NSConsumerQueue * queue)
+{
+    return (queue->size <= 0);
+}
diff --git a/service/notification/src/consumer/NSConsumerQueue.h b/service/notification/src/consumer/NSConsumerQueue.h
new file mode 100644 (file)
index 0000000..55c9223
--- /dev/null
@@ -0,0 +1,59 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_QUEUE_H_
+#define _NS_CONSUMER_QUEUE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdbool.h>
+
+typedef struct _NSConsumerQueueObject
+{
+    void * data;
+    struct _NSConsumerQueueObject * next;
+} NSConsumerQueueObject;
+
+typedef struct
+{
+    int size;
+    NSConsumerQueueObject * head;
+    NSConsumerQueueObject * tail;
+} NSConsumerQueue;
+
+NSConsumerQueue * NSCreateQueue();
+
+void NSDestroyQueue(NSConsumerQueue *);
+
+bool NSPushQueue(NSConsumerQueue *, NSConsumerQueueObject *);
+
+NSConsumerQueueObject * NSPopQueue(NSConsumerQueue *);
+
+int NSGetQueueSize(NSConsumerQueue *);
+
+bool NSIsQueueEmpty(NSConsumerQueue *);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_QUEUE_H_
diff --git a/service/notification/src/consumer/NSConsumerScheduler.c b/service/notification/src/consumer/NSConsumerScheduler.c
new file mode 100644 (file)
index 0000000..64a5196
--- /dev/null
@@ -0,0 +1,247 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerScheduler.h"
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocrandom.h"
+
+#include "NSStructs.h"
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+#include "NSConsumerCommunication.h"
+
+#include "NSThread.h"
+#include "NSConsumerQueue.h"
+
+#include "NSConsumerDiscovery.h"
+#include "NSConsumerInternalTaskController.h"
+#include "NSConsumerNetworkEventListener.h"
+#include "NSConsumerSystem.h"
+
+void * NSConsumerMsgHandleThreadFunc(void * handle);
+
+void * NSConsumerMsgPushThreadFunc(void * data);
+
+void NSConsumerTaskProcessing(NSTask * task);
+
+NSConsumerThread ** NSGetMsgHandleThreadHandle()
+{
+    static NSConsumerThread * handle = NULL;
+    return & handle;
+}
+
+void NSSetMsgHandleThreadHandle(NSConsumerThread * handle)
+{
+   *(NSGetMsgHandleThreadHandle()) = handle;
+}
+
+NSConsumerQueue ** NSGetMsgHandleQueue()
+{
+    static NSConsumerQueue * queue = NULL;
+    return & queue;
+}
+
+void NSSetMsgHandleQueue(NSConsumerQueue * queue)
+{
+   *(NSGetMsgHandleQueue()) = queue;
+}
+
+NSResult NSConsumerMessageHandlerInit()
+{
+    NSConsumerThread * handle = NULL;
+    NSConsumerQueue * queue = NULL;
+
+    uint8_t uuid[UUID_SIZE];
+    char uuidString[UUID_STRING_SIZE];
+    OCGenerateUuid(uuid);
+    OCConvertUuidToString(uuid, uuidString);
+    NSSetConsumerId(uuidString);
+    NS_LOG_V(DEBUG, "Consumer ID : %s", *NSGetConsumerId());
+
+    NS_LOG(DEBUG, "listener init");
+    NSResult ret = NSConsumerListenerInit();
+    NS_VERIFY_NOT_NULL(ret == NS_OK ? (void *) 1 : NULL, NS_ERROR);
+
+    NS_LOG(DEBUG, "system init");
+    ret = NSConsumerSystemInit();
+    NS_VERIFY_NOT_NULL(ret == NS_OK ? (void *) 1 : NULL, NS_ERROR);
+
+    NS_LOG(DEBUG, "queue thread init");
+    handle = NSThreadInit(NSConsumerMsgHandleThreadFunc, NULL);
+    NS_VERIFY_NOT_NULL(handle, NS_ERROR);
+    NSSetMsgHandleThreadHandle(handle);
+
+    NS_LOG(DEBUG, "create queue");
+    queue = NSCreateQueue();
+    NS_VERIFY_NOT_NULL(queue, NS_ERROR);
+    NSSetMsgHandleQueue(queue);
+
+    return NS_OK;
+}
+
+NSResult NSConsumerPushEvent(NSTask * task)
+{
+    NSConsumerThread * thread = NSThreadInit(NSConsumerMsgPushThreadFunc, (void *) task);
+    NS_VERIFY_NOT_NULL(thread, NS_ERROR);
+
+    return NS_OK;
+}
+
+void NSConsumerMessageHandlerExit()
+{
+    NSDestroyMessageCacheList();
+    NSDestroyProviderCacheList();
+    NSConsumerListenerTermiate();
+    NSThreadStop(*(NSGetMsgHandleThreadHandle()));
+    NSDestroyQueue(*(NSGetMsgHandleQueue()));
+}
+
+void * NSConsumerMsgHandleThreadFunc(void * threadHandle)
+{
+    NSConsumerQueue * queue = NULL;
+    NSConsumerQueueObject * obj = NULL;
+
+    NS_LOG(DEBUG, "create thread for consumer message handle");
+    NSConsumerThread * queueHandleThread = (NSConsumerThread *) threadHandle;
+    NS_VERIFY_NOT_NULL(queueHandleThread, NULL);
+
+    while (true)
+    {
+        if (!queueHandleThread->isStarted)
+        {
+            NS_LOG(ERROR, "msg handler thread will be terminated");
+            break;
+        }
+
+        queue = *(NSGetMsgHandleQueue());
+        if (!queue)
+        {
+            continue;
+        }
+
+        if (NSIsQueueEmpty(queue))
+        {
+            usleep(2000);
+            continue;
+        }
+
+        NSThreadLock(queueHandleThread);
+        NS_LOG(DEBUG, "msg handler working");
+        obj = NSPopQueue(queue);
+
+        if (obj)
+        {
+            NSConsumerTaskProcessing((NSTask *)(obj->data));
+        }
+
+        NSThreadUnlock(queueHandleThread);
+
+    }
+
+    return NULL;
+}
+
+void * NSConsumerMsgPushThreadFunc(void * data)
+{
+    NSConsumerQueueObject * obj = NULL;
+    NSConsumerQueue * queue = NULL;
+
+    NS_LOG(DEBUG, "get queueThread handle");
+    NSConsumerThread * msgHandleThread = *(NSGetMsgHandleThreadHandle());
+    NS_VERIFY_NOT_NULL(msgHandleThread, NULL);
+
+    NS_LOG(DEBUG, "create queue object");
+    obj = (NSConsumerQueueObject *)OICMalloc(sizeof(NSConsumerQueueObject));
+    NS_VERIFY_NOT_NULL(obj, NULL);
+
+    obj->data = data;
+    obj->next = NULL;
+
+    NSThreadLock(msgHandleThread);
+
+    queue = *(NSGetMsgHandleQueue());
+    if (!queue)
+    {
+        NS_LOG(ERROR, "NSQueue is null. can not insert to queue");
+        OICFree(data);
+        OICFree(obj);
+    }
+    else
+    {
+        NSPushQueue(queue, obj);
+    }
+
+    NSThreadUnlock(msgHandleThread);
+
+    return NULL;
+}
+
+void NSConsumerTaskProcessing(NSTask * task)
+{
+    switch (task->taskType)
+    {
+    case TASK_EVENT_CONNECTED:
+    case TASK_EVENT_CONNECTED_TCP:
+    case TASK_CONSUMER_REQ_DISCOVER:
+    {
+        NSConsumerDiscoveryTaskProcessing(task);
+        break;
+    }
+    case TASK_CONSUMER_REQ_SUBSCRIBE:
+    case TASK_CONSUMER_REQ_SUBSCRIBE_CANCEL:
+    case TASK_SEND_SYNCINFO:
+    {
+        NSConsumerCommunicationTaskProcessing(task);
+        break;
+    }
+    case TASK_RECV_SYNCINFO:
+    case TASK_CONSUMER_RECV_MESSAGE:
+    case TASK_CONSUMER_PROVIDER_DISCOVERED:
+    case TASK_CONSUMER_RECV_SUBSCRIBE_CONFIRMED:
+    case TASK_MAKE_SYNCINFO:
+    {
+        NSConsumerInternalTaskProcessing(task);
+        break;
+    }
+    default:
+        NS_LOG(ERROR, "Unknown type of task");
+        break;
+    }
+}
+
+NSMessage_consumer * NSConsumerFindNSMessage(const char* messageId)
+{
+    NS_VERIFY_NOT_NULL(messageId, NULL);
+
+    return NSMessageCacheFind(messageId);
+}
+
+NSProvider_internal * NSConsumerFindNSProvider(const char * providerId)
+{
+    NS_VERIFY_NOT_NULL(providerId, NULL);
+
+    return NSProviderCacheFind(providerId);
+}
diff --git a/service/notification/src/consumer/NSConsumerScheduler.h b/service/notification/src/consumer/NSConsumerScheduler.h
new file mode 100644 (file)
index 0000000..af20bd2
--- /dev/null
@@ -0,0 +1,50 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_MESSAGEHANDLER_H_
+#define _NS_CONSUMER_MESSAGEHANDLER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "ocstack.h"
+#include "NSCommon.h"
+#include "NSStructs.h"
+#include "NSConsumerCommon.h"
+
+NSResult NSConsumerMessageHandlerInit();
+
+void NSConsumerMessageHandlerExit();
+
+extern NSResult NSConsumerPushEvent(NSTask *);
+
+NSMessage_consumer * NSConsumerFindNSMessage(const char *);
+
+NSProvider_internal * NSConsumerFindNSProvider(const char *);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_MESSAGEHANDLER_H_
diff --git a/service/notification/src/consumer/NSConsumerSystem.c b/service/notification/src/consumer/NSConsumerSystem.c
new file mode 100644 (file)
index 0000000..d132b1c
--- /dev/null
@@ -0,0 +1,29 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerSystem.h"
+
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+
+NSResult NSConsumerSystemInit()
+{
+    return NS_OK;
+}
diff --git a/service/notification/src/consumer/NSConsumerSystem.h b/service/notification/src/consumer/NSConsumerSystem.h
new file mode 100644 (file)
index 0000000..942580a
--- /dev/null
@@ -0,0 +1,36 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_SYSTEM_H_
+#define _NS_CONSUMER_SYSTEM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include "NSCommon.h"
+
+NSResult NSConsumerSystemInit();
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_SYSTEM_H_
diff --git a/service/notification/src/consumer/NSThread.c b/service/notification/src/consumer/NSThread.c
new file mode 100644 (file)
index 0000000..9dbf64b
--- /dev/null
@@ -0,0 +1,100 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSThread.h"
+
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+
+#include <memory.h>
+#include "oic_malloc.h"
+
+static pthread_mutex_t g_create_mutex;
+
+void NSDestroyThreadHandle(NSConsumerThread *);
+
+NSConsumerThread * NSThreadInit(NSThreadFunc func, void * data)
+{
+    NS_VERIFY_NOT_NULL(func, NULL);
+
+    pthread_mutex_init(&g_create_mutex, NULL);
+
+    NSConsumerThread * handle = (NSConsumerThread *)OICMalloc(sizeof(NSConsumerThread));
+    NS_VERIFY_NOT_NULL(handle, NULL);
+
+    memset(handle, 0, sizeof(NSConsumerThread));
+
+    pthread_mutexattr_init(&(handle->mutex_attr));
+
+    int pthreadResult = pthread_mutexattr_settype(&(handle->mutex_attr), PTHREAD_MUTEX_RECURSIVE);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(pthreadResult == 0 ? (void *)1 : NULL,
+            NULL, NSDestroyThreadHandle(handle));
+
+    pthreadResult = pthread_mutex_init(&(handle->mutex), &(handle->mutex_attr));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(pthreadResult == 0 ? (void *)1 : NULL,
+            NULL, NSDestroyThreadHandle(handle));
+
+    pthread_mutex_lock(&g_create_mutex);
+
+    handle->isStarted = true;
+
+    pthreadResult = pthread_create(&(handle->thread_id), NULL, func,
+                           (data == NULL) ? (void *) handle : (void *)data);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(pthreadResult == 0 ? (void *)1 : NULL,
+            NULL, NSDestroyThreadHandle(handle));
+
+    pthread_mutex_unlock(&g_create_mutex);
+
+    return handle;
+}
+
+void NSThreadLock(NSConsumerThread * handle)
+{
+    pthread_mutex_lock(&(handle->mutex));
+}
+
+void NSThreadUnlock(NSConsumerThread * handle)
+{
+    pthread_mutex_unlock(&(handle->mutex));
+}
+
+void NSThreadStop(NSConsumerThread * handle)
+{
+    NSDestroyThreadHandle(handle);
+}
+
+void NSThreadJoin(NSConsumerThread * handle)
+{
+    if (handle->thread_id)
+    {
+        pthread_join(handle->thread_id, NULL);
+    }
+}
+
+void NSDestroyThreadHandle(NSConsumerThread * handle)
+{
+    handle->isStarted = false;
+
+    NSThreadJoin(handle);
+
+    pthread_mutex_destroy(&(handle->mutex));
+    pthread_mutexattr_destroy(&(handle->mutex_attr));
+}
+
diff --git a/service/notification/src/consumer/NSThread.h b/service/notification/src/consumer/NSThread.h
new file mode 100644 (file)
index 0000000..1e1d7bb
--- /dev/null
@@ -0,0 +1,66 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_THREAD_H_
+#define _NS_THREAD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdbool.h>
+
+typedef enum
+{
+    pthread
+} NS_THREAD_MODEL;
+
+#define NS_THREAD pthread
+
+#if (NS_THREAD == pthread)
+#include <pthread.h>
+
+typedef struct
+{
+    bool isStarted;
+    pthread_t thread_id;
+    pthread_mutex_t mutex;
+    pthread_mutexattr_t mutex_attr;
+} NSConsumerThread;
+
+#endif
+
+typedef void *(*NSThreadFunc)(void *);
+
+NSConsumerThread * NSThreadInit(NSThreadFunc, void *);
+
+void NSThreadLock(NSConsumerThread *);
+
+void NSThreadUnlock(NSConsumerThread *);
+
+void NSThreadJoin(NSConsumerThread *);
+
+void NSThreadStop(NSConsumerThread *);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_THREAD_H_
diff --git a/service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.c b/service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.c
new file mode 100644 (file)
index 0000000..75b26bb
--- /dev/null
@@ -0,0 +1,444 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSConsumerMemoryCache.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+pthread_mutex_t * NSGetCacheMutex()
+{
+    static pthread_mutex_t NSCacheMutex;
+    return & NSCacheMutex;
+}
+
+void NSSetCacheMutex(pthread_mutex_t mutex)
+{
+    *(NSGetCacheMutex()) = mutex;
+}
+
+NSCacheList * NSStorageCreate()
+{
+    pthread_mutex_t * mutex = (pthread_mutex_t *) OICMalloc(sizeof(pthread_mutex_t));
+    pthread_mutex_init(mutex, NULL);
+    NSSetCacheMutex(*mutex);
+    mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));
+    if (!newList)
+    {
+        pthread_mutex_unlock(mutex);
+        NS_LOG (ERROR, "Failed to Create Cache");
+        return NULL;
+    }
+
+    newList->head = newList->tail = NULL;
+
+    pthread_mutex_unlock(mutex);
+
+    return newList;
+}
+
+NSCacheElement * NSStorageRead(NSCacheList * list, const char * findId)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NSCacheElement * iter = list->head;
+    NSCacheElement * next = NULL;
+    NSCacheType type = list->cacheType;
+
+    while (iter)
+    {
+        next = iter->next;
+
+        pthread_mutex_unlock(mutex);
+
+        if (NSConsumerCompareIdCacheData(type, iter->data, findId))
+        {
+            pthread_mutex_unlock(mutex);
+
+            return iter;
+        }
+
+        iter = next;
+    }
+
+    pthread_mutex_unlock(mutex);
+    NS_LOG (DEBUG, "No Cache Element");
+    return NULL;
+}
+
+NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NSCacheType type = list->cacheType;
+
+    if (!newObj)
+    {
+        pthread_mutex_unlock(mutex);
+        NS_LOG (ERROR, "Failed to Write Cache");
+        return NS_ERROR;
+    }
+
+    NS_LOG_V(DEBUG, "cache type : %d", type);
+    if (type == NS_CONSUMER_CACHE_MESSAGE)
+    {
+        pthread_mutex_unlock(mutex);
+
+        return NSConsumerCacheWriteMessage(list, newObj);
+    }
+    else if (type == NS_CONSUMER_CACHE_PROVIDER)
+    {
+        pthread_mutex_unlock(mutex);
+
+        return NSConsumerCacheWriteProvider(list, newObj);
+    }
+
+    NS_LOG (ERROR, "Not Supported Type");
+    pthread_mutex_unlock(mutex);
+
+    return NS_ERROR;
+}
+
+NSResult NSStorageDelete(NSCacheList * list, const char * delId)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NSCacheType type = list->cacheType;
+
+    if (!delId)
+    {
+        pthread_mutex_unlock(mutex);
+        NS_LOG (ERROR, "Failed to Delete Cache");
+        return NS_ERROR;
+    }
+
+    NSCacheElement * prev = list->head;
+    NSCacheElement * del = list->head;
+
+    if (NSConsumerCompareIdCacheData(type, del->data, delId))
+    {
+        if (del == list->head)
+        {
+            if (del == list->tail)
+                list->tail = del->next;
+            list->head = del->next;
+
+            if (type == NS_CONSUMER_CACHE_MESSAGE)
+            {
+                NSRemoveMessage((NSMessage_consumer *) del->data);
+            }
+            else if (type == NS_CONSUMER_CACHE_PROVIDER)
+            {
+                NSRemoveProvider((NSProvider_internal *) del->data);
+            }
+            NSOICFree(del);
+            pthread_mutex_unlock(mutex);
+
+            return NS_OK;
+        }
+    }
+
+    del = del->next;
+    while (del)
+    {
+        if (NSConsumerCompareIdCacheData(type, del->data, delId))
+        {
+            if (del == list->tail)
+                list->tail = prev;
+
+            prev->next = del->next;
+            if (type == NS_CONSUMER_CACHE_MESSAGE)
+            {
+                NSRemoveMessage((NSMessage_consumer *) del->data);
+            }
+            else if (type == NS_CONSUMER_CACHE_PROVIDER)
+            {
+                NSRemoveProvider((NSProvider_internal *) del->data);
+            }
+            NSOICFree(del);
+            pthread_mutex_unlock(mutex);
+
+            return NS_OK;
+        }
+
+        prev = del;
+        del = del->next;
+    }
+    pthread_mutex_unlock(mutex);
+    return NS_OK;
+}
+
+NSResult NSConsumerCacheWriteMessage(NSCacheList * list, NSCacheElement * newObj)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    if (!newObj)
+    {
+        pthread_mutex_unlock(mutex);
+        NS_LOG (ERROR, "Failed to Write Message Cache");
+        return NS_ERROR;
+    }
+
+    NSMessage_consumer * newMsgObj = (NSMessage_consumer *) newObj->data;
+
+    pthread_mutex_unlock(mutex);
+    char msgId[NS_DEVICE_ID_LENGTH] = {0, };
+    snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lu", newMsgObj->messageId);
+    NSCacheElement * it = NSStorageRead(list, msgId);
+    pthread_mutex_lock(mutex);
+
+    if (it)
+    {
+        NSMessage_consumer * msgObj = (NSMessage_consumer *) it->data;
+        it->data = (void *) NSCopyMessage(newMsgObj);
+        if (!it->data)
+        {
+            NS_LOG (ERROR, "Failed to CopyMessage");
+            it->data = (void *) msgObj;
+            pthread_mutex_unlock(mutex);
+
+            return NS_ERROR;
+        }
+        NSRemoveMessage(msgObj);
+        pthread_mutex_unlock(mutex);
+
+        return NS_OK;
+    }
+
+    NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
+    if (!obj)
+    {
+        NS_LOG(ERROR, "Fail to Create New Object");
+        pthread_mutex_unlock(mutex);
+
+        return NS_ERROR;
+    }
+    obj->data = (void *) NSCopyMessage(newMsgObj);
+    if (!obj->data)
+    {
+        NS_LOG (ERROR, "Failed to CopyMessage");
+        pthread_mutex_unlock(mutex);
+
+        return NS_ERROR;
+    }
+    obj->next = NULL;
+
+    if (!list->head)
+    {
+        list->head = obj;
+        list->tail = obj;
+        pthread_mutex_unlock(mutex);
+
+        return NS_OK;
+    }
+
+    (list->tail)->next = obj;
+    list->tail = obj;
+    pthread_mutex_unlock(mutex);
+
+    return NS_OK;
+}
+
+NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
+    NSProvider_internal * prov = (NSProvider_internal *)newObj->data;
+    NS_LOG_V (DEBUG, "%s", prov->providerId);
+    NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
+
+    if (!newObj)
+    {
+        pthread_mutex_unlock(mutex);
+        NS_LOG (ERROR, "Failed to Write Provider Cache");
+        return NS_ERROR;
+    }
+
+    NSProvider_internal * newProvObj = (NSProvider_internal *) newObj->data;
+
+    pthread_mutex_unlock(mutex);
+    NSCacheElement * it = NSStorageRead(list, newProvObj->providerId);
+    pthread_mutex_lock(mutex);
+
+    if (it)
+    {
+        NSProvider_internal * provObj = (NSProvider_internal *) it->data;
+
+        NSProviderConnectionInfo * infos = provObj->connection;
+        NSProviderConnectionInfo * lastConn = infos->next;
+        while(lastConn)
+        {
+            infos = lastConn;
+            lastConn = lastConn->next;
+        }
+        infos->next = NSCopyProviderConnections(newProvObj->connection);
+
+        NSRemoveProvider(newProvObj);
+        pthread_mutex_unlock(mutex);
+
+        return NS_OK;
+    }
+
+    NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
+    if (!obj)
+    {
+        NS_LOG(ERROR, "Fail to Create New Object");
+        pthread_mutex_unlock(mutex);
+
+        return NS_ERROR;
+    }
+    NS_LOG_V(DEBUG, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
+    obj->data = (void *) NSCopyProvider(newProvObj);
+
+    NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
+    prov = (NSProvider_internal *)obj->data;
+    NS_LOG_V (DEBUG, "%s", prov->providerId);
+    NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
+
+    if (!obj->data)
+    {
+        NS_LOG (ERROR, "Failed to CopyProvider");
+        pthread_mutex_unlock(mutex);
+
+        return NS_ERROR;
+    }
+    obj->next = NULL;
+
+    if (!list->head)
+    {
+        list->head = obj;
+        list->tail = obj;
+
+        NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
+        prov = (NSProvider_internal *)list->tail->data;
+        NS_LOG_V (DEBUG, "%s", prov->providerId);
+        NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
+
+        pthread_mutex_unlock(mutex);
+
+        return NS_OK;
+    }
+
+    (list->tail)->next = obj;
+    list->tail = obj;
+
+    NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4");
+    prov = (NSProvider_internal *)list->tail->data;
+    NS_LOG_V (DEBUG, "%s", prov->providerId);
+    NS_LOG (DEBUG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!4");
+
+    pthread_mutex_unlock(mutex);
+
+    return NS_OK;
+}
+
+NSResult NSStorageDestroy(NSCacheList * list)
+{
+    pthread_mutex_t * mutex = NSGetCacheMutex();
+
+    pthread_mutex_lock(mutex);
+
+    NSCacheElement * iter = list->head;
+    NSCacheElement * next = NULL;
+
+    NSCacheType type = list->cacheType;
+
+    if (type == NS_CONSUMER_CACHE_MESSAGE)
+    {
+        while (iter)
+        {
+            next = (NSCacheElement *) iter->next;
+
+            NSRemoveMessage((NSMessage_consumer *) iter->data);
+            NSOICFree(iter);
+
+            iter = next;
+        }
+
+        NSOICFree(list);
+    }
+    else if (type == NS_CONSUMER_CACHE_PROVIDER)
+    {
+        while (iter)
+        {
+            next = (NSCacheElement *) iter->next;
+
+            NSRemoveProvider((NSProvider_internal *) iter->data);
+            NSOICFree(iter);
+
+            iter = next;
+        }
+
+        NSOICFree(list);
+    }
+
+    pthread_mutex_unlock(mutex);
+
+    return NS_OK;
+}
+
+bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id)
+{
+    if (data == NULL)
+    {
+        return false;
+    }
+
+    if (type == NS_CONSUMER_CACHE_MESSAGE)
+    {
+        NSMessage_consumer * msg = (NSMessage_consumer *) data;
+
+        char msgId[NS_DEVICE_ID_LENGTH] = {0, };
+        snprintf(msgId, NS_DEVICE_ID_LENGTH, "%lu", msg->messageId);
+        if (!strcmp(msgId, id))
+        {
+            return true;
+        }
+
+        return false;
+    }
+    else if (type == NS_CONSUMER_CACHE_PROVIDER)
+    {
+        NSProvider_internal * prov = (NSProvider_internal *) data;
+
+        if (!strcmp(prov->providerId, id))
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    return false;
+}
diff --git a/service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.h b/service/notification/src/consumer/cache/linux/NSConsumerMemoryCache.h
new file mode 100644 (file)
index 0000000..9cc47f3
--- /dev/null
@@ -0,0 +1,43 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_MEMORY_CACHE_H_
+#define _NS_CONSUMER_MEMORY_CACHE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include "NSStorageAdapter.h"
+#include "NSConsumerCommon.h"
+
+
+bool NSConsumerCompareIdCacheData(NSCacheType type, void * data, const char * id);
+NSResult NSConsumerCacheWriteMessage(NSCacheList * list, NSCacheElement * newObj);
+NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newObj);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_MEMORY_CACHE_H_
diff --git a/service/notification/src/provider/NSProviderDiscovery.c b/service/notification/src/provider/NSProviderDiscovery.c
new file mode 100644 (file)
index 0000000..37855be
--- /dev/null
@@ -0,0 +1,98 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "NSProviderDiscovery.h"\r
+\r
+NSResult NSStartPresence()\r
+{\r
+    NS_LOG(DEBUG, "NSStartPresence()");\r
+\r
+    if (OCStartPresence(0) != OC_STACK_OK)\r
+    {\r
+        NS_LOG(DEBUG, "NSStartPresence() NS_ERROR");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSStartPresence() NS_OK");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSStopPresence()\r
+{\r
+    NS_LOG(DEBUG, "NSStopPresence()");\r
+\r
+    if (OCStopPresence() != OC_STACK_OK)\r
+    {\r
+        NS_LOG(DEBUG, "NSStopPresence() NS_ERROR");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSStopPresence() NS_OK");\r
+    return NS_OK;\r
+}\r
+\r
+void * NSDiscoverySchedule(void * ptr)\r
+{\r
+    if (ptr == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "Create NSDiscoverySchedule");\r
+    }\r
+\r
+    while (NSIsRunning[DISCOVERY_SCHEDULER])\r
+    {\r
+        sem_wait(&NSSemaphore[DISCOVERY_SCHEDULER]);\r
+        pthread_mutex_lock(&NSMutex[DISCOVERY_SCHEDULER]);\r
+\r
+        if (NSHeadMsg[DISCOVERY_SCHEDULER] != NULL)\r
+        {\r
+            NSTask *node = NSHeadMsg[DISCOVERY_SCHEDULER];\r
+            NSHeadMsg[DISCOVERY_SCHEDULER] = node->nextTask;\r
+\r
+            switch (node->taskType)\r
+            {\r
+                case TASK_START_PRESENCE:\r
+                    NS_LOG(DEBUG, "CASE TASK_START_PRESENCE : ");\r
+                    NSStartPresence();\r
+                    break;\r
+                case TASK_STOP_PRESENCE:\r
+                    NS_LOG(DEBUG, "CASE TASK_STOP_PRESENCE : ");\r
+                    NSStopPresence();\r
+                    break;\r
+                case TASK_REGISTER_RESOURCE:\r
+                    NS_LOG(DEBUG, "CASE TASK_REGISTER_RESOURCE : ");\r
+                    NSRegisterResource();\r
+                    break;\r
+                case TASK_PUBLISH_RESOURCE:\r
+                    NS_LOG(DEBUG, "CASE TASK_PUBLISH_PESOURCE : ");\r
+                    NSPublishResourceToCloud((char*)node->taskData);\r
+                    break;\r
+                default:\r
+                    break;\r
+            }\r
+\r
+            OICFree(node);\r
+        }\r
+\r
+        pthread_mutex_unlock(&NSMutex[DISCOVERY_SCHEDULER]);\r
+    }\r
+\r
+    NS_LOG(DEBUG, "Destroy NSDiscoverySchedule");\r
+    return NULL;\r
+}\r
diff --git a/service/notification/src/provider/NSProviderDiscovery.h b/service/notification/src/provider/NSProviderDiscovery.h
new file mode 100644 (file)
index 0000000..c020ecb
--- /dev/null
@@ -0,0 +1,32 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_PROVIDER_DISCOVERY_H_\r
+#define _NS_PROVIDER_DISCOVERY_H_\r
+\r
+#include "NSCommon.h"\r
+#include "NSStructs.h"\r
+#include "NSProviderScheduler.h"\r
+#include "NSProviderResource.h"\r
+\r
+NSResult NSStartPresence();\r
+NSResult NSStopPresence();\r
+\r
+#endif /* _NS_PROVIDER_DISCOVERY_H_ */\r
diff --git a/service/notification/src/provider/NSProviderInterface.c b/service/notification/src/provider/NSProviderInterface.c
new file mode 100644 (file)
index 0000000..6fa5967
--- /dev/null
@@ -0,0 +1,315 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "NSProviderInterface.h"\r
+#include "NSProviderScheduler.h"\r
+#include "NSProviderListener.h"\r
+#include "NSProviderSubscription.h"\r
+#include "NSProviderNotification.h"\r
+#include "NSStorageAdapter.h"\r
+#include "NSProviderMemoryCache.h"\r
+#include "oic_malloc.h"\r
+#include "oic_string.h"\r
+#include "cautilinterface.h"\r
+#include "NSProviderSystem.h"\r
+#include "oic_time.h"\r
+\r
+bool initProvider = false;\r
+static NSSubscribeRequestCallback g_subscribeRequestCb = NULL;\r
+static NSProviderSyncInfoCallback g_syncCb = NULL;\r
+\r
+pthread_mutex_t nsInitMutex;\r
+\r
+void initializeMutex()\r
+{\r
+    static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;\r
+    nsInitMutex = initMutex;\r
+}\r
+\r
+void NSRegisterSubscribeRequestCb(NSSubscribeRequestCallback subscribeRequestCb)\r
+{\r
+    NS_LOG(DEBUG, "NSRegisterSubscribeRequestCb - IN");\r
+    g_subscribeRequestCb = subscribeRequestCb;\r
+    NS_LOG(DEBUG, "NSRegisterSubscribeRequestCb - OUT");\r
+}\r
+\r
+void  NSRegisterSyncCb(NSProviderSyncInfoCallback syncCb)\r
+{\r
+    NS_LOG(DEBUG, "NSRegisterSyncCb - IN");\r
+    g_syncCb = syncCb;\r
+    NS_LOG(DEBUG, "NSRegisterSyncCb - OUT");\r
+}\r
+\r
+void NSSubscribeRequestCb(NSConsumer *consumer)\r
+{\r
+    NS_LOG(DEBUG, "NSSubscribeRequestCb - IN");\r
+    g_subscribeRequestCb(consumer);\r
+    NS_LOG(DEBUG, "NSSubscribeRequestCb - OUT");\r
+}\r
+\r
+void NSSyncCb(NSSyncInfo *sync)\r
+{\r
+    NS_LOG(DEBUG, "NSSyncCb - IN");\r
+    g_syncCb(sync);\r
+    NS_LOG(DEBUG, "NSSyncCb - OUT");\r
+}\r
+\r
+NSResult NSStartProvider(NSAccessPolicy policy, NSSubscribeRequestCallback subscribeRequestCb,\r
+        NSProviderSyncInfoCallback syncCb)\r
+{\r
+    NS_LOG(DEBUG, "NSStartProvider - IN");\r
+\r
+    initializeMutex();\r
+\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    if (!initProvider)\r
+    {\r
+        NS_LOG(DEBUG, "Init Provider");\r
+        initProvider = true;\r
+        NSInitProviderInfo();\r
+        NSSetSubscriptionAccessPolicy(policy);\r
+        NSRegisterSubscribeRequestCb(subscribeRequestCb);\r
+        NSRegisterSyncCb(syncCb);\r
+        CARegisterNetworkMonitorHandler(NSProviderAdapterStateListener,\r
+                NSProviderConnectionStateListener);\r
+\r
+        NSSetList();\r
+        NSInitScheduler();\r
+        NSStartScheduler();\r
+\r
+        NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
+        NSPushQueue(DISCOVERY_SCHEDULER, TASK_REGISTER_RESOURCE, NULL);\r
+    }\r
+    else\r
+    {\r
+        NS_LOG(DEBUG, "Already started Notification Provider");\r
+    }\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+\r
+    NS_LOG(DEBUG, "NSStartProvider - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+void NSSetList()\r
+{\r
+    NS_LOG(DEBUG, "NSSetList - IN");\r
+    pthread_mutex_init(&NSCacheMutex, NULL);\r
+    NSInitSubscriptionList();\r
+    NSInitMessageList();\r
+    NS_LOG(DEBUG, "NSSetList - OUT");\r
+}\r
+\r
+NSResult NSStopProvider()\r
+{\r
+    NS_LOG(DEBUG, "NSStopProvider - IN");\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    if(initProvider)\r
+    {\r
+        NSDeinitProviderInfo();\r
+        NSUnRegisterResource();\r
+        NSRegisterSubscribeRequestCb((NSSubscribeRequestCallback)NULL);\r
+        NSRegisterSyncCb((NSProviderSyncInfoCallback)NULL);\r
+        NSStopScheduler();\r
+        NSStorageDestroy(consumerSubList);\r
+        NSStorageDestroy(messageList);\r
+\r
+        initProvider = false;\r
+    }\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+    NS_LOG(DEBUG, "NSStopProvider - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSProviderEnableRemoteService(char *serverAddress)\r
+{\r
+    NS_LOG(DEBUG, "NSProviderEnableRemoteService - IN");\r
+    pthread_mutex_lock(&nsInitMutex);\r
\r
+    if(!initProvider)\r
+    {\r
+        NS_LOG(DEBUG, "Provider service has not been started yet");\r
+        return NS_FAIL;\r
+    }\r
+\r
+    NS_LOG_V(DEBUG, "Remote server address: %s", serverAddress);\r
+    NSPushQueue(DISCOVERY_SCHEDULER, TASK_PUBLISH_RESOURCE, serverAddress);\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+    NS_LOG(DEBUG, "NSProviderEnableRemoteService - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSProviderDisableRemoteService(char *serverAddress)\r
+{\r
+    NS_LOG(DEBUG, "NSProviderDisableRemoteService - IN");\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    if(!initProvider)\r
+    {\r
+        NS_LOG(DEBUG, "Provider service has not been started yet");\r
+        return NS_FAIL;\r
+    }\r
+    NS_LOG_V(DEBUG, "Remote server address: %s", serverAddress);\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+    NS_LOG(DEBUG, "NSProviderDisableRemoteService - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSSendMessage(NSMessage *msg)\r
+{\r
+    NS_LOG(DEBUG, "NSSendNotification - IN");\r
+\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    if(msg == NULL)\r
+    {\r
+        NS_LOG(ERROR, "Msg is NULL");\r
+        pthread_mutex_unlock(&nsInitMutex);\r
+        return NS_ERROR;\r
+    }\r
+\r
+    NSMessage * newMsg = NSDuplicateMessage(msg);\r
+    NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_NOTIFICATION, newMsg);\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+\r
+    NS_LOG(DEBUG, "NSSendNotification - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSProviderSendSyncInfo(uint64_t messageId, NSSyncType type)\r
+{\r
+    NS_LOG(DEBUG, "NSProviderReadCheck - IN");\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));\r
+    OICStrcpy(syncInfo->providerId, UUID_STRING_SIZE, NSGetProviderInfo()->providerId);\r
+    syncInfo->messageId = messageId;\r
+    syncInfo->state = type;\r
+    NSPushQueue(NOTIFICATION_SCHEDULER, TASK_SEND_READ, syncInfo);\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+    NS_LOG(DEBUG, "NSProviderReadCheck - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSAccept(NSConsumer *consumer, bool accepted)\r
+{\r
+    NS_LOG(DEBUG, "NSAccept - IN");\r
+\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    NSConsumer * newConsumer = NSDuplicateConsumer(consumer);\r
+\r
+    if(accepted)\r
+    {\r
+        NS_LOG(DEBUG, "accepted is true - ALLOW");\r
+        NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_ALLOW, newConsumer);\r
+    }\r
+    else\r
+    {\r
+        NS_LOG(DEBUG, "accepted is false - DENY");\r
+        NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_DENY, newConsumer);\r
+    }\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+    NS_LOG(DEBUG, "NSAccept - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSMessage * NSCreateMessage()\r
+{\r
+    NS_LOG(DEBUG, "NSCreateMessage - IN");\r
+    pthread_mutex_lock(&nsInitMutex);\r
+\r
+    NSMessage * msg = NSInitializeMessage();\r
+    OICStrcpy(msg->providerId, UUID_STRING_SIZE, NSGetProviderInfo()->providerId);\r
+\r
+    pthread_mutex_unlock(&nsInitMutex);\r
+    NS_LOG(DEBUG, "NSCreateMessage - OUT");\r
+    return msg;\r
+}\r
+\r
+void * NSInterfaceSchedule(void * ptr)\r
+{\r
+    if (ptr == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "Create NSReponseSchedule");\r
+    }\r
+\r
+    while (NSIsRunning[INTERFACE_SCHEDULER])\r
+    {\r
+        sem_wait(&NSSemaphore[INTERFACE_SCHEDULER]);\r
+        pthread_mutex_lock(&NSMutex[INTERFACE_SCHEDULER]);\r
+\r
+        if (NSHeadMsg[INTERFACE_SCHEDULER] != NULL)\r
+        {\r
+            NSTask *node = NSHeadMsg[INTERFACE_SCHEDULER];\r
+            NSHeadMsg[INTERFACE_SCHEDULER] = node->nextTask;\r
+\r
+            switch (node->taskType)\r
+            {\r
+                case TASK_CB_SUBSCRIPTION:\r
+                {\r
+                    NS_LOG(DEBUG, "CASE TASK_CB_SUBSCRIPTION : ");\r
+\r
+                    OCEntityHandlerRequest * request = (OCEntityHandlerRequest*)node->taskData;\r
+                    NSConsumer * consumer = (NSConsumer *)OICMalloc(sizeof(NSConsumer));\r
+\r
+                    char * consumerId = NSGetValueFromQuery(OICStrdup(request->query),\r
+                            NS_QUERY_CONSUMER_ID);\r
+\r
+                    if(consumerId)\r
+                    {\r
+                        OICStrcpy(consumer->consumerId, UUID_STRING_SIZE, consumerId);\r
+                        NSSubscribeRequestCb(consumer);\r
+                    }\r
+\r
+                    NSFreeConsumer(consumer);\r
+                    NSFreeOCEntityHandlerRequest(request);\r
+\r
+                    break;\r
+                }\r
+                case TASK_CB_SYNC:\r
+                {\r
+                    NS_LOG(DEBUG, "CASE TASK_CB_SYNC : ");\r
+                    NSSyncInfo * sync = (NSSyncInfo*)node->taskData;\r
+                    NSSyncCb(NSDuplicateSync(sync));\r
+                    NSFreeSync(sync);\r
+                    break;\r
+                }\r
+                default:\r
+                    NS_LOG(DEBUG, "No Task Type");\r
+                    break;\r
+            }\r
+            OICFree(node);\r
+        }\r
+\r
+        pthread_mutex_unlock(&NSMutex[INTERFACE_SCHEDULER]);\r
+    }\r
+\r
+    NS_LOG(DEBUG, "Destroy NSResponseSchedule");\r
+    return NULL;\r
+}\r
+\r
diff --git a/service/notification/src/provider/NSProviderListener.c b/service/notification/src/provider/NSProviderListener.c
new file mode 100644 (file)
index 0000000..ac67a94
--- /dev/null
@@ -0,0 +1,461 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "NSProviderListener.h"\r
+\r
+OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,\r
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
+{\r
+    NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - IN");\r
+\r
+    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResponse response =\r
+    { 0, 0, OC_EH_ERROR, 0, 0,\r
+    { },\r
+    { 0 }, false };\r
+\r
+    (void)callback;\r
+\r
+    // Validate pointer\r
+    if (!entityHandlerRequest)\r
+    {\r
+        NS_LOG(ERROR, "Invalid request pointer");\r
+        return OC_EH_ERROR;\r
+    }\r
+\r
+    // Initialize certain response fields\r
+    response.numSendVendorSpecificHeaderOptions = 0;\r
+    memset(response.sendVendorSpecificHeaderOptions, 0,\r
+            sizeof response.sendVendorSpecificHeaderOptions);\r
+    memset(response.resourceUri, 0, sizeof response.resourceUri);\r
+    OCRepPayload* payload = NULL;\r
+\r
+    if (flag & OC_REQUEST_FLAG)\r
+    {\r
+        NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
+\r
+        if (OC_REST_GET == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_GET");\r
+\r
+            NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_POLICY,\r
+                    NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
+            ehResult = OC_EH_OK;\r
+\r
+        }\r
+        else if (OC_REST_PUT == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_PUT");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_POST == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_POST");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_DELETE == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OC_REST_DELETE");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else\r
+        {\r
+            NS_LOG_V (DEBUG, "Received unsupported method %d from client",\r
+                    entityHandlerRequest->method);\r
+            ehResult = OC_EH_OK;\r
+        }\r
+\r
+        // If the result isn't an error or forbidden, send response\r
+        if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))\r
+        {\r
+            // Format the response.  Note this requires some info about the request\r
+            response.requestHandle = entityHandlerRequest->requestHandle;\r
+            response.resourceHandle = entityHandlerRequest->resource;\r
+            response.ehResult = ehResult;\r
+            //response.payload = reinterpret_cast<OCPayload*>(payload);\r
+            response.payload = (OCPayload*) payload;\r
+            // Indicate that response is NOT in a persistent buffer\r
+            response.persistentBufferFlag = 0;\r
+\r
+            // Handle vendor specific options\r
+            if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions\r
+                    && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)\r
+            {\r
+                NS_LOG (DEBUG, "Received vendor specific options");\r
+                uint8_t i = 0;\r
+                OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;\r
+                for (i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)\r
+                {\r
+                    if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)\r
+                    {\r
+                        OIC_LOG_V(DEBUG, LISTENER_TAG, "Received option with OC_COAP_ID and ID %u with",\r
+                                ((OCHeaderOption)rcvdOptions[i]).optionID );\r
+\r
+                        OIC_LOG_BUFFER(DEBUG, LISTENER_TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,\r
+                                MAX_HEADER_OPTION_DATA_LENGTH);\r
+                    }\r
+                }\r
+                OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;\r
+                uint8_t option2[] =\r
+                { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };\r
+                uint8_t option3[] =\r
+                { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };\r
+                sendOptions[0].protocolID = OC_COAP_ID;\r
+                sendOptions[0].optionID = 2248;\r
+                memcpy(sendOptions[0].optionData, option2, sizeof(option2));\r
+                sendOptions[0].optionLength = 10;\r
+                sendOptions[1].protocolID = OC_COAP_ID;\r
+                sendOptions[1].optionID = 2600;\r
+                memcpy(sendOptions[1].optionData, option3, sizeof(option3));\r
+                sendOptions[1].optionLength = 10;\r
+                response.numSendVendorSpecificHeaderOptions = 2;\r
+            }\r
+        }\r
+    }\r
+\r
+    OCPayloadDestroy(response.payload);\r
+    NS_LOG(DEBUG, "NSEntityHandlerNotificationCb - OUT");\r
+    return ehResult;\r
+}\r
+\r
+OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,\r
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
+{\r
+    NS_LOG(DEBUG, "NSEntityHandlerMessageCb - IN");\r
+\r
+    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResponse response =\r
+    { 0, 0, OC_EH_ERROR, 0, 0,\r
+    { },\r
+    { 0 }, false };\r
+\r
+    (void)callback;\r
+\r
+    // Validate pointer\r
+    if (!entityHandlerRequest)\r
+    {\r
+        NS_LOG (ERROR,"Invalid request pointer");\r
+        return OC_EH_ERROR;\r
+    }\r
+\r
+    // Initialize certain response fields\r
+    response.numSendVendorSpecificHeaderOptions = 0;\r
+    memset(response.sendVendorSpecificHeaderOptions, 0,\r
+            sizeof response.sendVendorSpecificHeaderOptions);\r
+    memset(response.resourceUri, 0, sizeof response.resourceUri);\r
+    OCRepPayload* payload = NULL;\r
+\r
+    if (flag & OC_REQUEST_FLAG)\r
+    {\r
+        NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
+\r
+        if (OC_REST_GET == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_GET");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_PUT == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_PUT");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_POST == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_POST");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_DELETE == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_REST_DELETE");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else\r
+        {\r
+            NS_LOG_V(DEBUG, "Received unsupported method %d from client",\r
+                    entityHandlerRequest->method);\r
+            ehResult = OC_EH_OK;\r
+        }\r
+\r
+        // If the result isn't an error or forbidden, send response\r
+        if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))\r
+        {\r
+            // Format the response.  Note this requires some info about the request\r
+            response.requestHandle = entityHandlerRequest->requestHandle;\r
+            response.resourceHandle = entityHandlerRequest->resource;\r
+            response.ehResult = ehResult;\r
+            //response.payload = reinterpret_cast<OCPayload*>(payload);\r
+            response.payload = (OCPayload*) payload;\r
+            // Indicate that response is NOT in a persistent buffer\r
+            response.persistentBufferFlag = 0;\r
+\r
+            // Handle vendor specific options\r
+            if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions\r
+                    && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)\r
+            {\r
+                NS_LOG(DEBUG, "Received vendor specific options");\r
+                uint8_t i = 0;\r
+                OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;\r
+                for (i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)\r
+                {\r
+                    if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)\r
+                    {\r
+                        OIC_LOG_V(DEBUG, LISTENER_TAG, "Received option with OC_COAP_ID and ID %u with",\r
+                                ((OCHeaderOption)rcvdOptions[i]).optionID );\r
+\r
+                        OIC_LOG_BUFFER(DEBUG, LISTENER_TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,\r
+                                MAX_HEADER_OPTION_DATA_LENGTH);\r
+                    }\r
+                }\r
+                OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;\r
+                uint8_t option2[] =\r
+                { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };\r
+                uint8_t option3[] =\r
+                { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };\r
+                sendOptions[0].protocolID = OC_COAP_ID;\r
+                sendOptions[0].optionID = 2248;\r
+                memcpy(sendOptions[0].optionData, option2, sizeof(option2));\r
+                sendOptions[0].optionLength = 10;\r
+                sendOptions[1].protocolID = OC_COAP_ID;\r
+                sendOptions[1].optionID = 2600;\r
+                memcpy(sendOptions[1].optionData, option3, sizeof(option3));\r
+                sendOptions[1].optionLength = 10;\r
+                response.numSendVendorSpecificHeaderOptions = 2;\r
+            }\r
+        }\r
+    }\r
+\r
+    if (flag & OC_OBSERVE_FLAG)\r
+    {\r
+        NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_FLAG");\r
+\r
+        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_REGISTER");\r
+            NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n"\r
+                    "Register message observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
+            NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_RECV_SUBSCRIPTION,\r
+                    NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
+        }\r
+    }\r
+\r
+    OCPayloadDestroy(response.payload);\r
+    NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OUT");\r
+    return ehResult;\r
+}\r
+\r
+OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,\r
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback)\r
+{\r
+    NS_LOG(DEBUG, "NSEntityHandlerSyncCb - IN");\r
+    OCEntityHandlerResult ehResult = OC_EH_OK;\r
+    OCEntityHandlerResponse response =\r
+    { 0, 0, OC_EH_ERROR, 0, 0,\r
+    { },\r
+    { 0 }, false };\r
+\r
+    (void)callback;\r
+\r
+    // Validate pointer\r
+    if (!entityHandlerRequest)\r
+    {\r
+        NS_LOG(ERROR, "Invalid request pointer");\r
+        return OC_EH_ERROR;\r
+    }\r
+\r
+    // Initialize certain response fields\r
+    response.numSendVendorSpecificHeaderOptions = 0;\r
+    memset(response.sendVendorSpecificHeaderOptions, 0,\r
+            sizeof response.sendVendorSpecificHeaderOptions);\r
+    memset(response.resourceUri, 0, sizeof response.resourceUri);\r
+    OCRepPayload* payload = NULL;\r
+\r
+    if (flag & OC_REQUEST_FLAG)\r
+    {\r
+        NS_LOG(DEBUG, "Flag includes OC_REQUEST_FLAG");\r
+\r
+        if (OC_REST_GET == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_GET");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_PUT == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_PUT");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_POST == entityHandlerRequest->method)\r
+        {\r
+            /** Receive sync data from consumer which read or dismiss notification message.\r
+                           And broadcast the sync data to all subscribers including provider app\r
+                           to synchronize the notification message status. */\r
+\r
+            NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_POST");\r
+\r
+            NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
+                    NSGetSyncInfo(entityHandlerRequest->payload));\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else if (OC_REST_DELETE == entityHandlerRequest->method)\r
+        {\r
+            NS_LOG(DEBUG, "Received OC_REST_DELETE from client");\r
+            ehResult = OC_EH_OK;\r
+        }\r
+        else\r
+        {\r
+            NS_LOG_V(DEBUG, "Received unsupported method %d from client",\r
+                    entityHandlerRequest->method);\r
+            ehResult = OC_EH_OK;\r
+        }\r
+\r
+        // If the result isn't an error or forbidden, send response\r
+        if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))\r
+        {\r
+            // Format the response.  Note this requires some info about the request\r
+            response.requestHandle = entityHandlerRequest->requestHandle;\r
+            response.resourceHandle = entityHandlerRequest->resource;\r
+            response.ehResult = ehResult;\r
+            //response.payload = reinterpret_cast<OCPayload*>(payload);\r
+            response.payload = (OCPayload*) payload;\r
+            // Indicate that response is NOT in a persistent buffer\r
+            response.persistentBufferFlag = 0;\r
+\r
+            // Handle vendor specific options\r
+            if (entityHandlerRequest->rcvdVendorSpecificHeaderOptions\r
+                    && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions)\r
+            {\r
+                NS_LOG(DEBUG, "Received vendor specific options");\r
+                uint8_t i = 0;\r
+                OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions;\r
+                for (i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++)\r
+                {\r
+                    if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID)\r
+                    {\r
+                        OIC_LOG_V(DEBUG, LISTENER_TAG, "Received option with OC_COAP_ID and ID %u with",\r
+                                ((OCHeaderOption)rcvdOptions[i]).optionID );\r
+\r
+                        OIC_LOG_BUFFER(DEBUG, LISTENER_TAG, ((OCHeaderOption)rcvdOptions[i]).optionData,\r
+                                MAX_HEADER_OPTION_DATA_LENGTH);\r
+                    }\r
+                }\r
+                OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions;\r
+                uint8_t option2[] =\r
+                { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };\r
+                uint8_t option3[] =\r
+                { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };\r
+                sendOptions[0].protocolID = OC_COAP_ID;\r
+                sendOptions[0].optionID = 2248;\r
+                memcpy(sendOptions[0].optionData, option2, sizeof(option2));\r
+                sendOptions[0].optionLength = 10;\r
+                sendOptions[1].protocolID = OC_COAP_ID;\r
+                sendOptions[1].optionID = 2600;\r
+                memcpy(sendOptions[1].optionData, option3, sizeof(option3));\r
+                sendOptions[1].optionLength = 10;\r
+                response.numSendVendorSpecificHeaderOptions = 2;\r
+            }\r
+        }\r
+    }\r
+\r
+    if (flag & OC_OBSERVE_FLAG)\r
+    {\r
+        /** Requested by consumers to synchronize notification message status.\r
+            Store the observer IDs to storage or cache */\r
+\r
+        NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_FLAG");\r
+\r
+        if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)\r
+        {\r
+            NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_REGISTER");\r
+            NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
+                    "Register Sync observerID : %d\n", entityHandlerRequest->obsInfo.obsId);\r
+            NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SYNC_SUBSCRIPTION,\r
+                    NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
+        }\r
+    }\r
+\r
+    OCPayloadDestroy(response.payload);\r
+    NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OUT");\r
+    return ehResult;\r
+}\r
+\r
+void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected)\r
+{\r
+\r
+    NS_LOG(DEBUG, "NSProviderConnectionStateListener - IN");\r
+\r
+    if (connected)\r
+    {\r
+        NS_LOG(DEBUG, "CONNECTED");\r
+\r
+        // Set Connection State\r
+        NSSetProviderConnectionState(CONNECTED);\r
+\r
+        // Start Presence\r
+        NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
+\r
+        if(info->adapter == CA_ADAPTER_TCP)\r
+        {\r
+            NS_LOG_V(DEBUG, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
+        }\r
+    }\r
+    else\r
+    {\r
+\r
+        NS_LOG(DEBUG, "DISCONNECTED");\r
+\r
+        // Set Connection State\r
+        NSSetProviderConnectionState(DISCONNECTED);\r
+\r
+        if(info->adapter == CA_ADAPTER_TCP)\r
+        {\r
+            NS_LOG_V(DEBUG, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
+        }\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSProviderConnectionStateListener - OUT");\r
+}\r
+\r
+void NSProviderAdapterStateListener(CATransportAdapter_t adapter, bool enabled)\r
+{\r
+    (void)adapter;\r
+\r
+    NS_LOG(DEBUG, "NSProviderAdapterStateListener - IN");\r
+\r
+    if (enabled)\r
+    {\r
+        NS_LOG(DEBUG, "CONNECTED");\r
+\r
+        // Set Connection State\r
+        NSSetProviderConnectionState(CONNECTED);\r
+\r
+        // Start Presence\r
+        NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
+    }\r
+    else\r
+    {\r
+\r
+        NS_LOG(DEBUG, "DISCONNECTED");\r
+\r
+        // Set Connection State\r
+        NSSetProviderConnectionState(DISCONNECTED);\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSProviderAdapterStateListener - OUT");\r
+}\r
+\r
diff --git a/service/notification/src/provider/NSProviderListener.h b/service/notification/src/provider/NSProviderListener.h
new file mode 100644 (file)
index 0000000..e07c8e1
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_PROVIDER_LISTENER__H_\r
+#define _NS_PROVIDER_LISTENER__H_\r
+\r
+#include <octypes.h>\r
+#include "ocstack.h"\r
+#include "logger.h"\r
+#include "ocpayload.h"\r
+#include "NSStructs.h"\r
+#include "NSConstants.h"\r
+#include "NSProviderSystem.h"\r
+#include "NSProviderScheduler.h"\r
+#include "cautilinterface.h"\r
+#include "oic_string.h"\r
+#include "oic_malloc.h"\r
+#include "NSUtil.h"\r
+#include "NSStorageAdapter.h"\r
+#include "NSCloudConnector.h"\r
+\r
+OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,\r
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback);\r
+\r
+OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,\r
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback);\r
+\r
+OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,\r
+        OCEntityHandlerRequest *entityHandlerRequest, void* callback);\r
+\r
+void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool isConnected);\r
+\r
+void NSProviderAdapterStateListener(CATransportAdapter_t adapter, bool enabled);\r
+\r
+#endif /* _NS_PROVIDER_LISTENER__H_ */\r
diff --git a/service/notification/src/provider/NSProviderNotification.c b/service/notification/src/provider/NSProviderNotification.c
new file mode 100644 (file)
index 0000000..b3fd1f8
--- /dev/null
@@ -0,0 +1,269 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSProviderNotification.h"
+
+NSResult NSInitMessageList()
+{
+    NS_LOG(DEBUG, "NSInitMessageList - IN");
+
+    messageList = NSStorageCreate();
+    messageList->cacheType = NS_PROVIDER_CACHE_MESSAGE;
+
+    NS_LOG(DEBUG, "NSInitMessageList - OUT");
+    return NS_OK;
+}
+
+NSResult NSSetMessagePayload(NSMessage *msg, OCRepPayload** msgPayload)
+{
+    NS_LOG(DEBUG, "NSSetMessagePayload - IN");
+
+    *msgPayload = OCRepPayloadCreate();
+
+    if (!*msgPayload)
+    {
+        NS_LOG(ERROR, "Failed to allocate payload");
+        return NS_ERROR;
+    }
+
+    OCRepPayloadSetUri(*msgPayload, NS_COLLECTION_MESSAGE_URI);
+    OCRepPayloadSetPropInt(*msgPayload, NS_ATTRIBUTE_MESSAGE_ID, msg->messageId);
+    OCRepPayloadSetPropString(*msgPayload, NS_ATTRIBUTE_PROVIDER_ID, msg->providerId);
+
+    NSDuplicateSetPropertyInt(msgPayload, NS_ATTRIBUTE_TYPE, msg->type);
+    NSDuplicateSetPropertyInt(msgPayload, NS_ATTRIBUTE_MESSAGE_ID, msg->ttl);
+    NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_DATETIME, msg->dateTime);
+    NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_TITLE, msg->title);
+    NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_TEXT, msg->contentText);
+    NSDuplicateSetPropertyString(msgPayload, NS_ATTRIBUTE_SOURCE, msg->sourceName);
+
+    NS_LOG(DEBUG, "NSSetMessagePayload - OUT");
+    return NS_OK;
+}
+
+NSResult NSSetSyncPayload(NSSyncInfo *sync, OCRepPayload** syncPayload)
+{
+    NS_LOG(DEBUG, "NSSetSyncPayload - IN");
+
+    *syncPayload = OCRepPayloadCreate();
+
+    if (!*syncPayload)
+    {
+        NS_LOG(ERROR, "Failed to allocate payload");
+        return NS_ERROR;
+    }
+
+    OCRepPayloadSetUri(*syncPayload, NS_COLLECTION_SYNC_URI);
+
+    OCRepPayloadSetPropString(*syncPayload, NS_ATTRIBUTE_PROVIDER_ID, sync->providerId);
+    OCRepPayloadSetPropInt(*syncPayload, NS_ATTRIBUTE_MESSAGE_ID, sync->messageId);
+    OCRepPayloadSetPropInt(*syncPayload, NS_ATTRIBUTE_STATE, sync->state);
+
+    NS_LOG(DEBUG, "NSSetSyncPayload - OUT");
+    return NS_OK;
+}
+
+NSResult NSSendNotification(NSMessage *msg)
+{
+    NS_LOG(DEBUG, "NSSendMessage - IN");
+
+    OCResourceHandle rHandle;
+    OCObservationId obArray[255] = { 0, };
+    int obCount = 0, i;
+
+    if (NSPutMessageResource(msg, &rHandle) != NS_OK)
+    {
+        NS_LOG(ERROR, "fail to Put notification resource");
+        return NS_ERROR;
+    }
+
+    if (consumerSubList->head == NULL)
+    {
+        NS_LOG(ERROR, "SubList->head is NULL, empty SubList");
+        return NS_ERROR;
+    }
+
+    OCRepPayload* payload;
+
+    if (NSSetMessagePayload(msg, &payload) != NS_OK)
+    {
+        NS_LOG(ERROR, "fail to Get message payload");
+        return NS_ERROR;
+    }
+
+    NSCacheElement * it = consumerSubList->head;
+
+    while (it)
+    {
+        NSCacheSubData * subData = (NSCacheSubData *) it->data;
+        NS_LOG_V(DEBUG, "subData->id = %s", subData->id);
+        NS_LOG_V(DEBUG, "subData->messageId = %d", subData->messageObId);
+        NS_LOG_V(DEBUG, "subData->obID = %d", subData->syncObId);
+        NS_LOG_V(DEBUG, "subData->isWhite = %d", subData->isWhite);
+
+        if (subData->isWhite)
+        {
+            obArray[obCount++] = subData->messageObId;
+        }
+        it = it->next;
+    }
+
+    for (i = 0; i < obCount; ++i)
+    {
+        NS_LOG(DEBUG, "-------------------------------------------------------message\n");
+        NS_LOG_V(DEBUG, "SubScription WhiteList[%d] = %d", i, obArray[i]);
+        NS_LOG(DEBUG, "-------------------------------------------------------message\n");
+    }
+
+    if(!obCount)
+    {
+        NS_LOG(ERROR, "observer count is zero");
+        return NS_ERROR;
+    }
+
+    OCStackResult ocstackResult = OCNotifyListOfObservers(rHandle, obArray, obCount, payload,
+            OC_LOW_QOS);
+
+    NS_LOG_V(DEBUG, "Message ocstackResult = %d", ocstackResult);
+
+    if (ocstackResult != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "fail to send message");
+        OCRepPayloadDestroy(payload);
+        return NS_ERROR;
+    }
+    OCRepPayloadDestroy(payload);
+    NSFreeMessage(msg);
+
+    NS_LOG(DEBUG, "NSSendMessage - OUT");
+
+    return NS_OK;
+}
+
+NSResult NSSendSync(NSSyncInfo *sync)
+{
+    NS_LOG(DEBUG, "NSSendSync - IN");
+
+    OCObservationId obArray[255] = { 0, };
+    int obCount = 0;
+    int i;
+
+    OCResourceHandle rHandle;
+    if (NSPutSyncResource(sync, &rHandle) != NS_OK)
+    {
+        NS_LOG(ERROR, PCF("Fail to put sync resource"));
+        return NS_ERROR;
+    }
+
+    NSCacheElement * it = consumerSubList->head;
+
+    while (it)
+    {
+        NSCacheSubData * subData = (NSCacheSubData *) it->data;
+        if (subData->isWhite)
+        {
+            obArray[obCount++] = subData->syncObId;
+        }
+        it = it->next;
+    }
+
+    OCRepPayload* payload;
+    if (NSSetSyncPayload(sync, &payload) != NS_OK)
+    {
+        NS_LOG(ERROR, "Failed to allocate payload");
+        return NS_ERROR;
+    }
+
+    for (i = 0; i < obCount; ++i)
+    {
+        NS_LOG(DEBUG, "-------------------------------------------------------message\n");
+        NS_LOG_V(DEBUG, "Sync WhiteList[%d] = %d", i, obArray[i]);
+        NS_LOG(DEBUG, "-------------------------------------------------------message\n");
+    }
+
+    OCStackResult ocstackResult = OCNotifyListOfObservers(rHandle, obArray,
+            obCount, payload, OC_LOW_QOS);
+
+    NS_LOG_V(DEBUG, "Sync ocstackResult = %d", ocstackResult);
+
+    if (ocstackResult != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "fail to send Sync");
+        OCRepPayloadDestroy(payload);
+        return NS_ERROR;
+    }
+
+    OCRepPayloadDestroy(payload);
+
+    NS_LOG(DEBUG, "NSSendSync - OUT");
+    return NS_OK;
+}
+
+void * NSNotificationSchedule(void *ptr)
+{
+    if (ptr == NULL)
+    {
+        NS_LOG(DEBUG, "Create NSNotifiactionSchedule");
+    }
+
+    while (NSIsRunning[NOTIFICATION_SCHEDULER])
+    {
+        sem_wait(&NSSemaphore[NOTIFICATION_SCHEDULER]);
+        pthread_mutex_lock(&NSMutex[NOTIFICATION_SCHEDULER]);
+
+        if (NSHeadMsg[NOTIFICATION_SCHEDULER] != NULL)
+        {
+            NSTask *node = NSHeadMsg[NOTIFICATION_SCHEDULER];
+            NSHeadMsg[NOTIFICATION_SCHEDULER] = node->nextTask;
+
+            switch (node->taskType)
+            {
+                case TASK_SEND_NOTIFICATION:
+                {
+                    NS_LOG(DEBUG, "CASE TASK_SEND_NOTIFICATION : ");
+                    NSSendNotification((NSMessage *)node->taskData);
+                    break;
+                }
+                case TASK_SEND_READ:
+                    NS_LOG(DEBUG, "CASE TASK_SEND_READ : ");
+                    NSSendSync((NSSyncInfo*) node->taskData);
+                    NSFreeSync((NSSyncInfo*) node->taskData);
+                    break;
+                case TASK_RECV_READ:
+                    NS_LOG(DEBUG, "CASE TASK_RECV_READ : ");
+                    NSSendSync((NSSyncInfo*) node->taskData);
+                    NSPushQueue(INTERFACE_SCHEDULER, TASK_CB_SYNC, node->taskData);
+                    break;
+
+                default:
+                    NS_LOG(ERROR, "Unknown type message");
+                    break;
+
+            }
+            OICFree(node);
+        }
+
+        pthread_mutex_unlock(&NSMutex[NOTIFICATION_SCHEDULER]);
+
+    }
+
+    NS_LOG(INFO, "Destroy NSNotificationSchedule");
+    return NULL;
+}
diff --git a/service/notification/src/provider/NSProviderNotification.h b/service/notification/src/provider/NSProviderNotification.h
new file mode 100644 (file)
index 0000000..7133e3e
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_PROVIDER_NOTIFICATION_H_\r
+#define _NS_PROVIDER_NOTIFICATION_H_\r
+\r
+#include <ocstack.h>\r
+#include "logger.h"\r
+#include "NSProviderScheduler.h"\r
+#include "NSProviderListener.h"\r
+#include "NSProviderResource.h"\r
+#include "NSProviderSubscription.h"\r
+#include "oic_string.h"\r
+#include "oic_malloc.h"\r
+#include "NSUtil.h"\r
+\r
+NSCacheList * messageList;\r
+\r
+NSResult NSRegisterResource();\r
+NSResult NSInitMessageList();\r
+\r
+#endif /* _NS_PROVIDER_NOTIFICATION_H_ */\r
diff --git a/service/notification/src/provider/NSProviderResource.c b/service/notification/src/provider/NSProviderResource.c
new file mode 100644 (file)
index 0000000..8da8796
--- /dev/null
@@ -0,0 +1,236 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "NSProviderResource.h"
+
+NSNotificationResource NotificationResource;
+NSMessageResource NotificationMessageResource;
+NSSyncResource NotificationSyncResource;
+
+OCStackApplicationResult NSHandlePublishCb(void *ctx, OCDoHandle handle,
+    OCClientResponse *clientResponse)
+{
+    if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
+    {
+        NS_LOG(DEBUG, "Invalid publish callback received");
+    }
+
+    NS_LOG_V(DEBUG, "Publish resource response received code: %d", clientResponse->result);
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+NSResult NSPublishResourceToCloud(char *serverAddress)
+{
+
+    NS_LOG(DEBUG, "NSPublishResourceToCloud - IN");
+    NS_LOG_V(DEBUG, "Cloud address: %s", serverAddress);
+
+    const char * publishQuery = "/oic/rd?rt=oic.wk.rdpub";
+
+    if (NSCloudPublish(serverAddress, publishQuery, &NSHandlePublishCb, 1,
+            NotificationResource.handle) != OC_STACK_OK)
+    {
+        NS_LOG(DEBUG, "Unable to publish resources to cloud");
+    }
+
+    NS_LOG(DEBUG, "NSPublishResourceToCloud - OUT");
+    return NS_OK;
+}
+
+NSResult NSCreateResource(char *uri)
+{
+    NS_LOG(DEBUG, "NSCreateResource - IN");
+    if (!uri)
+    {
+        NS_LOG(NS_ERROR, "Resource URI cannot be NULL");
+        return NS_ERROR;
+    }
+
+    if (strcmp(uri, NS_ROOT_URI) == 0)
+    {
+        NotificationResource.accepter = 0;
+        NotificationResource.message_uri = NS_COLLECTION_MESSAGE_URI;
+        NotificationResource.sync_uri = NS_COLLECTION_SYNC_URI;
+        NotificationResource.handle = NULL;
+
+        if (OCCreateResource(&NotificationResource.handle, NS_ROOT_TYPE, NS_DEFAULT_INTERFACE,
+                NS_ROOT_URI, NSEntityHandlerNotificationCb, NULL, OC_DISCOVERABLE) != OC_STACK_OK)
+        {
+            NS_LOG(NS_ERROR, "Fail to Create Notification Resource");
+            return NS_ERROR;
+        }
+    }
+    else if (strcmp(uri, NS_COLLECTION_MESSAGE_URI) == 0)
+    {
+
+        NotificationMessageResource.messageId = 0;
+
+        (NotificationMessageResource.providerId)[0] = '\0';
+        NotificationMessageResource.type = 0;
+        NotificationMessageResource.dateTime = NULL;
+        NotificationMessageResource.ttl = 0;
+        NotificationMessageResource.title = NULL;
+        NotificationMessageResource.contentText = NULL;
+        NotificationMessageResource.sourceName = NULL;
+        NotificationMessageResource.mediaContents = NULL;
+
+        if (OCCreateResource(&NotificationMessageResource.handle, NS_COLLECTION_MESSAGE_TYPE,
+                NS_DEFAULT_INTERFACE, NS_COLLECTION_MESSAGE_URI, NSEntityHandlerMessageCb, NULL,
+                OC_OBSERVABLE) != OC_STACK_OK)
+        {
+            NS_LOG(NS_ERROR, "Fail to Create Notification Message Resource");
+            return NS_ERROR;
+        }
+    }
+    else if (strcmp(uri, NS_COLLECTION_SYNC_URI) == 0)
+    {
+        NotificationSyncResource.id = NULL;
+        NotificationSyncResource.state = NULL;
+        NotificationSyncResource.handle = NULL;
+
+        if (OCCreateResource(&(NotificationSyncResource.handle), NS_COLLECTION_SYNC_TYPE,
+                NS_DEFAULT_INTERFACE, NS_COLLECTION_SYNC_URI, NSEntityHandlerSyncCb, NULL,
+                OC_OBSERVABLE) != OC_STACK_OK)
+        {
+            NS_LOG(NS_ERROR, "Fail to Create Notification Sync Resource");
+            return NS_ERROR;
+        }
+    }
+    else
+    {
+        NS_LOG(ERROR, "Fail to create resource with invalid URI");
+        return NS_ERROR;
+    }
+
+    NS_LOG(DEBUG, "NSCreateResource - OUT");
+    return NS_OK;
+}
+
+NSResult NSRegisterResource()
+{
+    NS_LOG(DEBUG, "NSRegisterResource - IN");
+
+    if (NSCreateResource(NS_COLLECTION_SYNC_URI) != NS_OK)
+    {
+        NS_LOG(ERROR, "Fail to register Sync Resource");
+        return NS_ERROR;
+    }
+
+    if (NSCreateResource(NS_COLLECTION_MESSAGE_URI) != NS_OK)
+    {
+        NS_LOG(ERROR, "Fail to register Message Resource");
+        return NS_ERROR;
+    }
+
+    if (NSCreateResource(NS_ROOT_URI) != NS_OK)
+    {
+        NS_LOG(ERROR, "Fail to register Notification Resource");
+        return NS_ERROR;
+    }
+
+    NS_LOG(DEBUG, "NSRegisterResource - OUT");
+    return NS_OK;
+}
+
+NSResult NSUnRegisterResource()
+{
+    NS_LOG(DEBUG, "NSUnRegisterResource - IN");
+
+    if (OCDeleteResource(NotificationResource.handle) != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "Fail to Delete Notification Resource");
+        return NS_ERROR;
+    }
+
+    if (OCDeleteResource(NotificationMessageResource.handle) != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "Fail to Delete Notification Message Resource");
+        return NS_ERROR;
+    }
+
+    if (OCDeleteResource(NotificationSyncResource.handle) != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "Fail to Delete Notification Sync Resource");
+        return NS_ERROR;
+    }
+
+    NotificationResource.handle = NULL;
+    NotificationMessageResource.handle = NULL;
+    NotificationSyncResource.handle = NULL;
+
+    NS_LOG(DEBUG, "NSUnRegisterResource - OUT");
+    return NS_OK;
+}
+
+NSResult NSPutNotificationResource(int accepter, OCResourceHandle * handle)
+{
+    NS_LOG(DEBUG, "NSPutNotificationResource - IN");
+
+    NotificationResource.accepter = accepter;
+    NotificationResource.message_uri = NS_COLLECTION_MESSAGE_URI;
+    NotificationResource.sync_uri = NS_COLLECTION_SYNC_URI;
+
+    *handle = NotificationResource.handle;
+
+    NS_LOG(DEBUG, "NSPutNotificationResource - OUT");
+    return NS_OK;
+}
+
+NSResult NSPutMessageResource(NSMessage *msg, OCResourceHandle * handle)
+{
+    NS_LOG(DEBUG, "NSPutMessageResource - IN");
+
+    if(msg != NULL)
+    {
+        NS_LOG(DEBUG, "NSMessage is valid");
+
+        NotificationMessageResource.messageId = msg->messageId;
+        OICStrcpy(NotificationMessageResource.providerId, UUID_STRING_SIZE, msg->providerId);
+        NotificationMessageResource.type = msg->type;
+        NotificationMessageResource.dateTime = msg->dateTime;
+        NotificationMessageResource.ttl = msg->ttl;
+        NotificationMessageResource.title = msg->title;
+        NotificationMessageResource.contentText = msg->contentText;
+        NotificationMessageResource.sourceName = msg->sourceName;
+        NotificationMessageResource.mediaContents = msg->mediaContents;
+    }
+    else
+    {
+        NS_LOG(ERROR, "NSMessage is NULL");
+    }
+
+    *handle = NotificationMessageResource.handle;
+    NS_LOG(DEBUG, "NSPutMessageResource - OUT");
+
+    return NS_OK;
+}
+
+NSResult NSPutSyncResource(NSSyncInfo *sync, OCResourceHandle * handle)
+{
+    NS_LOG(DEBUG, "NSPutSyncResource - IN");
+
+    (void) sync;
+
+    *handle = NotificationSyncResource.handle;
+
+    NS_LOG(DEBUG, "NSPutSyncResource - OUT");
+    return NS_OK;
+}
diff --git a/service/notification/src/provider/NSProviderResource.h b/service/notification/src/provider/NSProviderResource.h
new file mode 100644 (file)
index 0000000..4ee6621
--- /dev/null
@@ -0,0 +1,45 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_PROVIDER_RESOURCE_H_
+#define _NS_PROVIDER_RESOURCE_H_
+
+#include <ocstack.h>
+#include "logger.h"
+#include "NSCommon.h"
+#include "NSProviderListener.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+NSResult NSCreateResource(char *uri);
+
+NSResult NSPublishResourceToCloud(char *host);
+
+NSResult NSRegisterResource();
+
+NSResult NSUnRegisterResource();
+
+NSResult NSPutNotificationResource(int accepter, OCResourceHandle * handle);
+
+NSResult NSPutMessageResource(NSMessage *msg, OCResourceHandle * handle);
+
+NSResult NSPutSyncResource(NSSyncInfo *sync, OCResourceHandle * handle);
+
+#endif /* _NS_PROVIDER_RESOURCE_H_ */
diff --git a/service/notification/src/provider/NSProviderScheduler.c b/service/notification/src/provider/NSProviderScheduler.c
new file mode 100755 (executable)
index 0000000..072866c
--- /dev/null
@@ -0,0 +1,262 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "NSProviderScheduler.h"\r
+\r
+pthread_t NSThread[THREAD_COUNT];\r
+pthread_mutex_t NSMutex[THREAD_COUNT];\r
+sem_t NSSemaphore[THREAD_COUNT];\r
+bool NSIsRunning[THREAD_COUNT] =\r
+{ false, };\r
+\r
+NSTask* NSHeadMsg[THREAD_COUNT];\r
+NSTask* NSTailMsg[THREAD_COUNT];\r
+\r
+void * NSInterfaceSchedule(void *ptr);\r
+void * NSDiscoverySchedule(void *ptr);\r
+void * NSSubScriptionSchedule(void *ptr);\r
+void * NSNotificationSchedule(void *ptr);\r
+\r
+bool NSInitScheduler()\r
+{\r
+    NS_LOG(DEBUG, "NSInitScheduler - IN");\r
+\r
+    int i = 0;\r
+\r
+    for (i = 0; i < THREAD_COUNT; i++)\r
+    {\r
+        pthread_mutex_init(&NSMutex[i], NULL);\r
+        NSIsRunning[i] = true;\r
+        sem_init(&(NSSemaphore[i]), 0, 0);\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSInitScheduler - OUT");\r
+\r
+    return true;\r
+}\r
+\r
+bool NSStartScheduler()\r
+{\r
+    int i = 0;\r
+\r
+    for (i = 0; i < THREAD_COUNT; i++)\r
+    {\r
+        pthread_mutex_lock(&NSMutex[i]);\r
+\r
+        switch (i)\r
+        {\r
+            case INTERFACE_SCHEDULER:\r
+            {\r
+                NS_LOG(DEBUG, "CASE RESPONSE_SCHEDULER :");\r
+                pthread_create(&NSThread[i], NULL, NSInterfaceSchedule, NULL);\r
+            }\r
+                break;\r
+\r
+            case DISCOVERY_SCHEDULER:\r
+            {\r
+                NS_LOG(DEBUG, "CASE DISCOVERY_SCHEDULER :");\r
+                pthread_create(&NSThread[i], NULL, NSDiscoverySchedule, NULL);\r
+            }\r
+                break;\r
+\r
+            case SUBSCRIPTION_SCHEDULER:\r
+            {\r
+                NS_LOG(DEBUG, "CASE SUBSCRIPTION_SCHEDULER :");\r
+                pthread_create(&NSThread[i], NULL, NSSubScriptionSchedule, NULL);\r
+            }\r
+                break;\r
+\r
+            case NOTIFICATION_SCHEDULER:\r
+            {\r
+                NS_LOG(DEBUG, "CASE NOTIFICATION_SCHEDULER :");\r
+                pthread_create(&NSThread[i], NULL, NSNotificationSchedule, NULL);\r
+            }\r
+                break;\r
+\r
+            default:\r
+                break;\r
+\r
+        }\r
+\r
+        NSHeadMsg[i] = NSTailMsg[i] = NULL;\r
+\r
+        pthread_mutex_unlock(&NSMutex[i]);\r
+\r
+    }\r
+\r
+    return true;\r
+}\r
+\r
+bool NSStopScheduler()\r
+{\r
+    NS_LOG(DEBUG, "NSStopScheduler - IN");\r
+    int i = 0;\r
+\r
+    for (i = THREAD_COUNT - 1; i >= 0; --i)\r
+    {\r
+        int status = -1;\r
+\r
+        NSIsRunning[i] = false;\r
+\r
+        sem_post(&(NSSemaphore[i]));\r
+        pthread_join(NSThread[i], (void **) &status);\r
+\r
+        NSThread[i] = 0;\r
+\r
+        pthread_mutex_lock(&NSMutex[i]);\r
+\r
+        while (NSHeadMsg[i] != NULL)\r
+        {\r
+            NSTask* temp = NSHeadMsg[i];\r
+            NSHeadMsg[i] = NSHeadMsg[i]->nextTask;\r
+            NSFreeData(i, NSHeadMsg[i]);\r
+            OICFree(temp);\r
+        }\r
+\r
+        OICFree(NSHeadMsg[i]);\r
+        NSTailMsg[i] = NSHeadMsg[i] = NULL;\r
+\r
+        pthread_mutex_unlock(&NSMutex[i]);\r
+        pthread_mutex_destroy(&NSMutex[i]);\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSStopScheduler - OUT");\r
+\r
+    return true;\r
+}\r
+\r
+void NSPushQueue(NSSchedulerType schedulerType, NSTaskType taskType, void* data)\r
+{\r
+\r
+    if(NSIsRunning[schedulerType] == false)\r
+        return;\r
+\r
+    pthread_mutex_lock(&NSMutex[schedulerType]);\r
+\r
+    NS_LOG(DEBUG, "NSPushQueue - IN");\r
+    NS_LOG_V(DEBUG, "NSSchedulerType = %d", schedulerType);\r
+    NS_LOG_V(DEBUG, "NSTaskType = %d", taskType);\r
+\r
+    if (NSHeadMsg[schedulerType] == NULL)\r
+    {\r
+        NSHeadMsg[schedulerType] = (NSTask*) OICMalloc(sizeof(NSTask));\r
+        memset(NSHeadMsg[schedulerType], 0, sizeof(NSTask));\r
+        NSHeadMsg[schedulerType]->taskType = taskType;\r
+        NSHeadMsg[schedulerType]->taskData = data;\r
+        NSHeadMsg[schedulerType]->nextTask = NULL;\r
+        NSTailMsg[schedulerType] = NSHeadMsg[schedulerType];\r
+    }\r
+    else\r
+    {\r
+        NSTask* newNode = (NSTask*) OICMalloc(sizeof(NSTask));\r
+        memset(newNode, 0, sizeof(NSTask));\r
+        newNode->taskType = taskType;\r
+        newNode->taskData = data;\r
+        newNode->nextTask = NULL;\r
+\r
+        NSTailMsg[schedulerType]->nextTask = newNode;\r
+        NSTailMsg[schedulerType] = newNode;\r
+    }\r
+\r
+    sem_post(&(NSSemaphore[schedulerType]));\r
+    NS_LOG(DEBUG, "NSPushQueue - OUT");\r
+    pthread_mutex_unlock(&NSMutex[schedulerType]);\r
+}\r
+\r
+void NSFreeData(NSSchedulerType type, NSTask * task)\r
+{\r
+    NS_LOG(DEBUG, "NSFreeData - IN");\r
+\r
+    if (type == INTERFACE_SCHEDULER)\r
+    {\r
+        switch (task->taskType)\r
+        {\r
+            case TASK_CB_SUBSCRIPTION:\r
+                NS_LOG(DEBUG, "CASE TASK_CB_SUBSCRIPTION : Free");\r
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
+                break;\r
+            case TASK_CB_SYNC:\r
+                NS_LOG(DEBUG, "CASE TASK_CB_SYNC : Free");\r
+                NSFreeSync((NSSyncInfo*) task->taskData);\r
+                break;\r
+            default:\r
+                NS_LOG(DEBUG, "No Task Type");\r
+                break;\r
+        }\r
+    }\r
+    else if (type == DISCOVERY_SCHEDULER)\r
+    {\r
+        switch (task->taskType)\r
+        {\r
+            case TASK_START_PRESENCE:\r
+            case TASK_STOP_PRESENCE:\r
+            case TASK_REGISTER_RESOURCE:\r
+                NS_LOG(DEBUG, "Not required Free");\r
+                break;\r
+            default:\r
+                NS_LOG(DEBUG, "No Task Type");\r
+                break;\r
+        }\r
+    }\r
+    else if (type == SUBSCRIPTION_SCHEDULER)\r
+    {\r
+        switch (task->taskType)\r
+        {\r
+            case TASK_SEND_POLICY:\r
+            case TASK_RECV_SUBSCRIPTION:\r
+            case TASK_RECV_UNSUBSCRIPTION:\r
+            case TASK_SYNC_SUBSCRIPTION:\r
+                NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest : Free ");\r
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
+                break;\r
+            case TASK_SEND_ALLOW:\r
+            case TASK_SEND_DENY:\r
+                NS_LOG(DEBUG, "NSFreeConsumer : Free ");\r
+                NSFreeConsumer((NSConsumer *) task->taskData);\r
+                break;\r
+            default:\r
+                NS_LOG(DEBUG, "No Task Type");\r
+                break;\r
+        }\r
+    }\r
+    else if (type == NOTIFICATION_SCHEDULER)\r
+    {\r
+        switch (task->taskType)\r
+        {\r
+            case TASK_SEND_NOTIFICATION:\r
+            {\r
+                NS_LOG(DEBUG, "NSFreeMessage : Free ");\r
+                NSFreeMessage((NSMessage *)task->taskData);\r
+                break;\r
+            }\r
+            case TASK_SEND_READ:\r
+            case TASK_RECV_READ:\r
+                NS_LOG(DEBUG, "NSFreeSync : Free ");\r
+                NSFreeSync((NSSyncInfo*) task->taskData);\r
+                break;\r
+\r
+            default:\r
+                NS_LOG(DEBUG, "No Task Type");\r
+                break;\r
+        }\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSFreeData - OUT");\r
+}\r
diff --git a/service/notification/src/provider/NSProviderScheduler.h b/service/notification/src/provider/NSProviderScheduler.h
new file mode 100755 (executable)
index 0000000..961e193
--- /dev/null
@@ -0,0 +1,57 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _PROVIDER_SCHEDULER_H_\r
+#define _PROVIDER_SCHEDULER_H_\r
+\r
+#include <stdio.h>\r
+#include <pthread.h>\r
+#include <semaphore.h>\r
+#include <stdbool.h>\r
+#include "ocstack.h"\r
+#include "NSCommon.h"\r
+#include "NSConstants.h"\r
+#include "NSStructs.h"\r
+#include "logger.h"\r
+#include "oic_malloc.h"\r
+#include "oic_string.h"\r
+#include "NSUtil.h"\r
+\r
+extern NSTask* NSHeadMsg[THREAD_COUNT]; // Current MSG;\r
+extern NSTask* NSTailMsg[THREAD_COUNT]; // Recently MSG;\r
+\r
+extern pthread_t NSThread[THREAD_COUNT];\r
+extern pthread_mutex_t NSMutex[THREAD_COUNT];\r
+extern sem_t NSSemaphore[THREAD_COUNT];\r
+extern bool NSIsRunning[THREAD_COUNT];\r
+\r
+extern void * NSResponseSchedule(void *ptr);\r
+extern void * NSDiscoverySchedule(void *ptr);\r
+extern void * NSSubScriptionSchedule(void *ptr);\r
+extern void * NSNotificationSchedule(void *ptr);\r
+\r
+void NSSetList();\r
+bool NSInitScheduler();\r
+bool NSStartScheduler();\r
+bool NSStopScheduler();\r
+void NSPushQueue(NSSchedulerType, NSTaskType, void*);\r
+void NSFreeData(NSSchedulerType, NSTask * );\r
+\r
+#endif /* _PROVIDER_SCHEDULER_H_ */\r
diff --git a/service/notification/src/provider/NSProviderSubscription.c b/service/notification/src/provider/NSProviderSubscription.c
new file mode 100644 (file)
index 0000000..c770bca
--- /dev/null
@@ -0,0 +1,398 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "NSProviderSubscription.h"\r
+\r
+NSResult NSInitSubscriptionList()\r
+{\r
+    NS_LOG(DEBUG, "NSInitSubscriptionList - IN");\r
+\r
+    consumerSubList = NSStorageCreate();\r
+    consumerSubList->cacheType = NS_PROVIDER_CACHE_SUBSCRIBER;\r
+\r
+    NS_LOG(DEBUG, "NSInitSubscriptionList - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSSetSubscriptionAccessPolicy(NSAccessPolicy access)\r
+{\r
+    NS_LOG(DEBUG, "NSSetSubscriptionAcceptPolicy - IN");\r
+\r
+    if (access == NS_ACCESS_ALLOW)\r
+    {\r
+        NS_LOG(DEBUG, "Place Provider as a subscription accepter");\r
+    }\r
+    else if (access == NS_ACCESS_DENY)\r
+    {\r
+        NS_LOG(DEBUG, "Place Consumer as a subscription accepter");\r
+    }\r
+\r
+    NSSubscriptionAccess = access;\r
+\r
+    NS_LOG(DEBUG, "NSSetSubscriptionAcceptPolicy - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+int NSGetSubscriptionAccepter()\r
+{\r
+    return NSSubscriptionAccess;\r
+}\r
+\r
+NSResult NSSendAccessPolicyResponse(OCEntityHandlerRequest *entityHandlerRequest)\r
+{\r
+    NS_LOG(DEBUG, "NSSendAccessPolicyResponse - IN");\r
+\r
+    // put notification resource\r
+    OCResourceHandle notificationResourceHandle;\r
+    if (NSPutNotificationResource(NSGetSubscriptionAccepter(), &notificationResourceHandle)\r
+            != NS_OK)\r
+    {\r
+        NS_LOG(ERROR, "Fail to put notification resource");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    // make response for the Get Request\r
+    OCEntityHandlerResponse response;\r
+    response.numSendVendorSpecificHeaderOptions = 0;\r
+    memset(response.sendVendorSpecificHeaderOptions, 0,\r
+            sizeof response.sendVendorSpecificHeaderOptions);\r
+    memset(response.resourceUri, 0, sizeof response.resourceUri);\r
+\r
+    OCRepPayload* payload = OCRepPayloadCreate();\r
+    if (!payload)\r
+    {\r
+        NS_LOG(ERROR, "payload is NULL");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    OCRepPayloadSetUri(payload, NS_ROOT_URI);\r
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
+    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_POLICY, NSGetSubscriptionAccepter());\r
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_MESSAGE, NS_COLLECTION_MESSAGE_URI);\r
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_SYNC, NS_COLLECTION_SYNC_URI);\r
+\r
+    response.requestHandle = entityHandlerRequest->requestHandle;\r
+    response.resourceHandle = entityHandlerRequest->resource;\r
+    response.persistentBufferFlag = 0;\r
+    response.ehResult = OC_EH_OK;\r
+    response.payload = (OCPayload *) payload;\r
+\r
+    // Send Response\r
+    if (OCDoResponse(&response) != OC_STACK_OK)\r
+    {\r
+        NS_LOG(ERROR, "Fail to AccessPolicy send response");\r
+        return NS_ERROR;\r
+    }\r
+    OCRepPayloadDestroy(payload);\r
+    NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+\r
+    NS_LOG(DEBUG, "NSSendAccessPolicyResponse - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResourceType resourceType)\r
+{\r
+    NS_LOG(DEBUG, "NSHandleSubscription - IN");\r
+\r
+    char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID);\r
+\r
+    if(!id)\r
+    {\r
+        NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+        NS_LOG(ERROR, "Invalid ConsumerID");\r
+        return;\r
+    }\r
+\r
+    NS_LOG_V(DEBUG, "consumerId = %s", id);\r
+    if (resourceType == NS_RESOURCE_MESSAGE)\r
+    {\r
+        NS_LOG(DEBUG, "resourceType == NS_RESOURCE_MESSAGE");\r
+        NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
+        NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
+\r
+        OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
+\r
+        subData->isWhite = false;\r
+        subData->messageObId = entityHandlerRequest->obsInfo.obsId;\r
+        subData->syncObId = 0;\r
+\r
+        element->data = (void*) subData;\r
+        element->next = NULL;\r
+\r
+        NS_LOG_V(DEBUG, "SubList IP[ID] = [%s]", subData->id);\r
+        NS_LOG_V(DEBUG, "SubList message observation ID = [%d]", subData->messageObId);\r
+\r
+        if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
+        {\r
+            NS_LOG(DEBUG, "fail to write cache");\r
+        }\r
+\r
+        if (NSGetSubscriptionAccepter() == NS_ACCESS_ALLOW)\r
+        {\r
+            NS_LOG(DEBUG, "NSGetSubscriptionAccepter == NS_ACCEPTER_PROVIDER");\r
+            NSAskAcceptanceToUser(entityHandlerRequest);\r
+        }\r
+        else if (NSGetSubscriptionAccepter() == NS_ACCESS_DENY)\r
+        {\r
+            NS_LOG(DEBUG, "NSGetSubscriptionAccepter == NS_ACCEPTER_CONSUMER");\r
+            NSSendSubscriptionResponse(entityHandlerRequest, true);\r
+        }\r
+    }\r
+    else if (resourceType == NS_RESOURCE_SYNC)\r
+    {\r
+        NS_LOG(DEBUG, "resourceType == NS_RESOURCE_SYNC");\r
+        NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
+        NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
+        OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
+\r
+\r
+        subData->isWhite = false;\r
+        subData->syncObId = entityHandlerRequest->obsInfo.obsId;\r
+        subData->messageObId = 0;\r
+\r
+        element->data = (void*) subData;\r
+        element->next = NULL;\r
+\r
+        NS_LOG_V(DEBUG, "SubList IP[ID] = [%s]", subData->id);\r
+        NS_LOG_V(DEBUG, "SubList sync observation ID = [%d]", subData->syncObId);\r
+\r
+        if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
+        {\r
+            NS_LOG(ERROR, "Fail to write cache");\r
+        }\r
+\r
+        NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSHandleSubscription - OUT");\r
+}\r
+\r
+void NSHandleUnsubscription(OCEntityHandlerRequest *entityHandlerRequest)\r
+{\r
+    NS_LOG(DEBUG, "NSHandleUnsubscription - IN");\r
+\r
+    char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID);\r
+\r
+    if(!id)\r
+    {\r
+        NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+        NS_LOG(ERROR, "Invalid ConsumerID");\r
+        return;\r
+    }\r
+\r
+    NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
+    NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
+\r
+    OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
+    subData->isWhite = false;\r
+    subData->messageObId = entityHandlerRequest->obsInfo.obsId;\r
+\r
+    element->data = (void*) subData;\r
+    element->next = NULL;\r
+\r
+    NS_LOG_V(DEBUG, "SubList IP[ID] = [%s]", subData->id);\r
+    NS_LOG_V(DEBUG, "SubList observation ID = [%d]", subData->syncObId);\r
+\r
+    if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
+    {\r
+        NS_LOG(ERROR, "fail to write consumer white list");\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSHandleUnsubscription - IN");\r
+\r
+    NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+}\r
+\r
+void NSAskAcceptanceToUser(OCEntityHandlerRequest *entityHandlerRequest)\r
+{\r
+    NS_LOG(DEBUG, "NSAskAcceptanceToUser - IN");\r
+\r
+    NSPushQueue(INTERFACE_SCHEDULER, TASK_CB_SUBSCRIPTION, entityHandlerRequest);\r
+\r
+    NS_LOG(DEBUG, "NSAskAcceptanceToUser - OUT");\r
+}\r
+\r
+NSResult NSSendResponse(const char * id, bool accepted)\r
+{\r
+    NS_LOG(DEBUG, "NSSendResponse - IN");\r
+\r
+    OCRepPayload* payload = OCRepPayloadCreate();\r
+    if (!payload)\r
+    {\r
+        NS_LOG(ERROR, "fail to create playload");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    OCResourceHandle rHandle;\r
+    if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
+    {\r
+        NS_LOG(ERROR, "Fail to put notification resource");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
+    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, 1);\r
+    OCRepPayloadSetPropBool(payload, NS_ATTRIBUTE_ACCPETANCE, accepted);\r
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
+\r
+    NSCacheElement * element = NSStorageRead(consumerSubList, id);\r
+\r
+    if(element == NULL)\r
+    {\r
+        NS_LOG(ERROR, "element is NULL");\r
+        return NS_ERROR;\r
+    }\r
+    NSCacheSubData * subData = (NSCacheSubData*) element->data;\r
+\r
+    if (OCNotifyListOfObservers(rHandle, (OCObservationId*)&subData->messageObId, 1, payload, OC_HIGH_QOS)\r
+            != OC_STACK_OK)\r
+    {\r
+        NS_LOG(ERROR, "fail to send Acceptance");\r
+        OCRepPayloadDestroy(payload);\r
+        return NS_ERROR;\r
+\r
+    }\r
+    OCRepPayloadDestroy(payload);\r
+\r
+    NS_LOG(DEBUG, "NSSendResponse - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSSendSubscriptionResponse(OCEntityHandlerRequest *entityHandlerRequest, bool accepted)\r
+{\r
+    NS_LOG(DEBUG, "NSSendSubscriptionResponse - IN");\r
+\r
+    if (!entityHandlerRequest)\r
+    {\r
+        NS_LOG(ERROR, "Invalid request pointer");\r
+        return OC_EH_ERROR;\r
+    }\r
+\r
+    char * id = NSGetValueFromQuery(OICStrdup(entityHandlerRequest->query), NS_QUERY_CONSUMER_ID);\r
+\r
+    if(!id)\r
+    {\r
+        NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+        NS_LOG(ERROR, "Invalid ConsumerID");\r
+        return NS_ERROR;\r
+    }\r
+\r
+    if (accepted)\r
+    {\r
+        NS_LOG(DEBUG, "accepted is true");\r
+        NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
+        NSCacheSubData * subData = (NSCacheSubData *) OICMalloc(sizeof(NSCacheSubData));\r
+\r
+        OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
+\r
+        subData->isWhite = true;\r
+        subData->messageObId = entityHandlerRequest->obsInfo.obsId;\r
+\r
+        element->data = (void*) subData;\r
+        element->next = NULL;\r
+\r
+        if (NSStorageWrite(consumerSubList, element) != NS_OK)\r
+        {\r
+            NS_LOG(ERROR, "fail to write consumer white list");\r
+        }\r
+    }\r
+\r
+    NSSendResponse(id, accepted);\r
+\r
+    NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
+\r
+    NS_LOG(DEBUG, "NSSendSubscriptionResponse - OUT");\r
+    return NS_OK;\r
+}\r
+\r
+void * NSSubScriptionSchedule(void *ptr)\r
+{\r
+    if (ptr == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "Create NSSubScriptionSchedule");\r
+    }\r
+\r
+    while (NSIsRunning[SUBSCRIPTION_SCHEDULER])\r
+    {\r
+        sem_wait(&NSSemaphore[SUBSCRIPTION_SCHEDULER]);\r
+        pthread_mutex_lock(&NSMutex[SUBSCRIPTION_SCHEDULER]);\r
+\r
+        if (NSHeadMsg[SUBSCRIPTION_SCHEDULER] != NULL)\r
+        {\r
+            NSTask *node = NSHeadMsg[SUBSCRIPTION_SCHEDULER];\r
+            NSHeadMsg[SUBSCRIPTION_SCHEDULER] = node->nextTask;\r
+\r
+            switch (node->taskType)\r
+            {\r
+                case TASK_SEND_POLICY:\r
+                    NS_LOG(DEBUG, "CASE TASK_SEND_POLICY : ");\r
+                    NSSendAccessPolicyResponse((OCEntityHandlerRequest*) node->taskData);\r
+                    break;\r
+\r
+                case TASK_RECV_SUBSCRIPTION:\r
+                    NS_LOG(DEBUG, "CASE TASK_RECV_SUBSCRIPTION : ");\r
+                    NSHandleSubscription((OCEntityHandlerRequest*) node->taskData,\r
+                            NS_RESOURCE_MESSAGE);\r
+                    break;\r
+\r
+                case TASK_RECV_UNSUBSCRIPTION:\r
+                    NS_LOG(DEBUG, "CASE TASK_RECV_UNSUBSCRIPTION : ");\r
+                    NSHandleUnsubscription((OCEntityHandlerRequest*) node->taskData);\r
+                    break;\r
+\r
+                case TASK_SEND_ALLOW:\r
+                {\r
+                    NS_LOG(DEBUG, "CASE TASK_SEND_ALLOW : ");\r
+                    NSConsumer * consumer = (NSConsumer *) node->taskData;\r
+\r
+                    NSCacheUpdateSubScriptionState(consumerSubList, consumer->consumerId, true);\r
+                    NSSendResponse(consumer->consumerId, true);\r
+                    NSFreeConsumer(consumer);\r
+                    break;\r
+                }\r
+                case TASK_SEND_DENY:\r
+                {\r
+                    NS_LOG(DEBUG, "CASE TASK_SEND_DENY : ");\r
+                    NSConsumer * consumer = (NSConsumer *) node->taskData;\r
+\r
+                    NSCacheUpdateSubScriptionState(consumerSubList, consumer->consumerId, false);\r
+                    NSSendResponse(consumer->consumerId, false);\r
+                    NSFreeConsumer(consumer);\r
+\r
+                    break;\r
+                }\r
+                case TASK_SYNC_SUBSCRIPTION:\r
+                    NS_LOG(DEBUG, "CASE TASK_SYNC_SUBSCRIPTION : ");\r
+                    NSHandleSubscription((OCEntityHandlerRequest*) node->taskData,\r
+                            NS_RESOURCE_SYNC);\r
+                    break;\r
+                default:\r
+                    break;\r
+\r
+            }\r
+            OICFree(node);\r
+        }\r
+\r
+        pthread_mutex_unlock(&NSMutex[SUBSCRIPTION_SCHEDULER]);\r
+\r
+    }\r
+    NS_LOG(INFO, "Destroy NSSubScriptionSchedule");\r
+    return NULL;\r
+}\r
diff --git a/service/notification/src/provider/NSProviderSubscription.h b/service/notification/src/provider/NSProviderSubscription.h
new file mode 100644 (file)
index 0000000..e6d3a25
--- /dev/null
@@ -0,0 +1,49 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_PROVIDER_SUBSCRIPTION_H_\r
+#define _NS_PROVIDER_SUBSCRIPTION_H_\r
+\r
+#include "logger.h"\r
+#include "ocstack.h"\r
+#include "ocpayload.h"\r
+#include "NSCommon.h"\r
+#include "NSConstants.h"\r
+#include "NSProviderScheduler.h"\r
+#include "NSProviderResource.h"\r
+#include "NSProviderMemoryCache.h"\r
+#include "NSProviderSystem.h"\r
+#include "oic_string.h"\r
+#include "oic_malloc.h"\r
+\r
+NSAccessPolicy NSSubscriptionAccess;\r
+NSCacheList * consumerSubList;\r
+\r
+NSResult NSInitSubscriptionList();\r
+NSResult NSSetSubscriptionAccessPolicy(NSAccessPolicy policy);\r
+int NSGetSubscriptionAccepter();\r
+NSResult NSSendAccessPolicyResponse(OCEntityHandlerRequest *entityHandlerRequest);\r
+void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResourceType resourceType);\r
+void NSHandleUnsubscription(OCEntityHandlerRequest *entityHandlerRequest);\r
+void NSAskAcceptanceToUser(OCEntityHandlerRequest *entityHandlerRequest);\r
+NSResult NSSendSubscriptionResponse(OCEntityHandlerRequest *entityHandlerRequest, bool accepted);\r
+NSResult NSSendResponse(const char * id, bool accepted);\r
+\r
+#endif /* _NS_PROVIDER_SUBSCRIPTION_H_ */\r
diff --git a/service/notification/src/provider/NSProviderSystem.c b/service/notification/src/provider/NSProviderSystem.c
new file mode 100644 (file)
index 0000000..a9a69aa
--- /dev/null
@@ -0,0 +1,77 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+#include "NSProviderSystem.h"\r
+\r
+static NSConnectionState NSProviderConnectionState;\r
+NSProviderInfo * providerInfo;\r
+\r
+void NSSetProviderConnectionState(NSConnectionState state)\r
+{\r
+    NS_LOG(DEBUG, "NSSetProviderConnectionState");\r
+\r
+    NSProviderConnectionState = state;\r
+}\r
+\r
+NSConnectionState NSGetProviderConnectionState()\r
+{\r
+    NS_LOG(DEBUG, "Change Connection State");\r
+\r
+    return NSProviderConnectionState;\r
+}\r
+\r
+void NSInitProviderInfo()\r
+{\r
+    NS_LOG(DEBUG, "NSInitProviderInfo");\r
+\r
+    providerInfo = (NSProviderInfo *) OICMalloc(sizeof(NSProviderInfo));\r
+    const char * generatedUuid = (char *)OCGetServerInstanceIDString();\r
+    NS_LOG_V(DEBUG, "Generate Provider ID: %s", generatedUuid);\r
+    OICStrcpy(providerInfo->providerId, strlen(generatedUuid), generatedUuid);\r
+\r
+    providerInfo->providerName = NULL;\r
+}\r
+\r
+void NSDeinitProviderInfo()\r
+{\r
+    NS_LOG(DEBUG, "NSDeinitProviderInfo");\r
+\r
+    if(providerInfo == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "providerInfo is NULL");\r
+        return;\r
+    }\r
+\r
+    if(providerInfo->providerName != NULL)\r
+    {\r
+        OICFree(providerInfo->providerName);\r
+        providerInfo->providerName = NULL;\r
+    }\r
+\r
+    OICFree(providerInfo);\r
+    providerInfo = NULL;\r
+}\r
+\r
+NSProviderInfo * NSGetProviderInfo()\r
+{\r
+    NS_LOG_V(DEBUG, "ProviderInfo: %s", providerInfo->providerId);\r
+\r
+    return providerInfo;\r
+}\r
+\r
diff --git a/service/notification/src/provider/NSProviderSystem.h b/service/notification/src/provider/NSProviderSystem.h
new file mode 100644 (file)
index 0000000..ab00e8e
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_PROVIDER_SYSTEM__H_\r
+#define _NS_PROVIDER_SYSTEM__H_\r
+\r
+#include <string.h>\r
+#include "logger.h"\r
+#include "NSCommon.h"\r
+#include "NSConstants.h"\r
+#include "oic_malloc.h"\r
+#include "NSStructs.h"\r
+#include "NSUtil.h"\r
+\r
+void NSSetProviderConnectionState(NSConnectionState state);\r
+NSConnectionState NSGetProviderConnectionState();\r
+\r
+void NSInitProviderInfo();\r
+void NSDeinitProviderInfo();\r
+NSProviderInfo * NSGetProviderInfo();\r
+\r
+#endif /* _NS_PROVIDER_SYSTEM__H_ */\r
diff --git a/service/notification/src/provider/cache/linux/NSProviderMemoryCache.c b/service/notification/src/provider/cache/linux/NSProviderMemoryCache.c
new file mode 100755 (executable)
index 0000000..8ce8f97
--- /dev/null
@@ -0,0 +1,373 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "NSProviderMemoryCache.h"\r
+\r
+NSCacheList * NSStorageCreate()\r
+{\r
+    pthread_mutex_lock(&NSCacheMutex);\r
+    NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));\r
+    if (!newList)\r
+    {\r
+        pthread_mutex_unlock(&NSCacheMutex);\r
+        return NULL;\r
+    }\r
+\r
+    newList->head = newList->tail = NULL;\r
+\r
+    pthread_mutex_unlock(&NSCacheMutex);\r
+\r
+    NS_LOG(DEBUG, "NSCacheCreate");\r
+\r
+    return newList;\r
+}\r
+\r
+NSCacheElement * NSStorageRead(NSCacheList * list, const char * findId)\r
+{\r
+    pthread_mutex_lock(&NSCacheMutex);\r
+\r
+    NS_LOG(DEBUG, "NSCacheRead - IN");\r
+\r
+    NSCacheElement * iter = list->head;\r
+    NSCacheElement * next = NULL;\r
+    NSCacheType type = list->cacheType;\r
+\r
+    NS_LOG_V(DEBUG, "Find ID - %s", findId);\r
+\r
+    while (iter)\r
+    {\r
+        next = iter->next;\r
+\r
+        if (NSProviderCompareIdCacheData(type, iter->data, findId))\r
+        {\r
+            NS_LOG(DEBUG, "Found in Cache");\r
+            pthread_mutex_unlock(&NSCacheMutex);\r
+            return iter;\r
+        }\r
+\r
+        iter = next;\r
+    }\r
+\r
+    NS_LOG(DEBUG, "Not found in Cache");\r
+    NS_LOG(DEBUG, "NSCacheRead - OUT");\r
+    pthread_mutex_unlock(&NSCacheMutex);\r
+\r
+    return NULL;\r
+}\r
+\r
+NSResult NSCacheUpdateSubScriptionState(NSCacheList * list, char * id, bool state)\r
+{\r
+    pthread_mutex_lock(&NSCacheMutex);\r
+\r
+    NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - IN");\r
+\r
+    if (id == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "id is NULL");\r
+        pthread_mutex_unlock(&NSCacheMutex);\r
+        return NS_ERROR;\r
+    }\r
+\r
+    pthread_mutex_unlock(&NSCacheMutex);\r
+    NSCacheElement * it = NSStorageRead(list, id);\r
+    pthread_mutex_lock(&NSCacheMutex);\r
+\r
+    if (it)\r
+    {\r
+        NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
+        if (strcmp(itData->id, id) == 0)\r
+        {\r
+            NS_LOG(DEBUG, "Update Data - IN");\r
+\r
+            NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
+            NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
+            NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
+            NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
+\r
+            NS_LOG_V(DEBUG, "update state = %d", state);\r
+\r
+            itData->isWhite = state;\r
+\r
+            NS_LOG(DEBUG, "Update Data - OUT");\r
+            pthread_mutex_unlock(&NSCacheMutex);\r
+            return NS_OK;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        NS_LOG(DEBUG, "Not Found Data");\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - OUT");\r
+    pthread_mutex_unlock(&NSCacheMutex);\r
+    return NS_ERROR;\r
+}\r
+\r
+NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj)\r
+{\r
+    pthread_mutex_lock(&NSCacheMutex);\r
+\r
+    NSCacheType type = list->cacheType;\r
+\r
+    NS_LOG(DEBUG, "NSCacheWrite - IN");\r
+\r
+    if (newObj == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "newObj is NULL - IN");\r
+        pthread_mutex_unlock(&NSCacheMutex);\r
+        return NS_ERROR;\r
+    }\r
+\r
+    if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
+    {\r
+        NS_LOG(DEBUG, "Type is SUBSCRIBER");\r
+\r
+        NSCacheSubData * subData = (NSCacheSubData *) newObj->data;\r
+\r
+        pthread_mutex_unlock(&NSCacheMutex);\r
+        NSCacheElement * it = NSStorageRead(list, subData->id);\r
+        pthread_mutex_lock(&NSCacheMutex);\r
+\r
+        if (it)\r
+        {\r
+            NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
+\r
+            if (strcmp(itData->id, subData->id) == 0)\r
+            {\r
+                NS_LOG(DEBUG, "Update Data - IN");\r
+\r
+                NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
+                NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
+                NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
+                NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
+\r
+                NS_LOG_V(DEBUG, "subData_ID = %s", subData->id);\r
+                NS_LOG_V(DEBUG, "subData_MsgObID = %d", subData->messageObId);\r
+                NS_LOG_V(DEBUG, "subData_SyncObID = %d", subData->syncObId);\r
+                NS_LOG_V(DEBUG, "subData_IsWhite = %d", subData->isWhite);\r
+\r
+                if (itData->messageObId == 0)\r
+                {\r
+                    itData->messageObId = subData->messageObId;\r
+                }\r
+\r
+                if (itData->syncObId == 0)\r
+                {\r
+                    itData->syncObId = subData->syncObId;\r
+                }\r
+\r
+                NS_LOG(DEBUG, "Update Data - OUT");\r
+\r
+                pthread_mutex_unlock(&NSCacheMutex);\r
+                return NS_OK;\r
+            }\r
+        }\r
+\r
+    }\r
+    else if (type == NS_PROVIDER_CACHE_MESSAGE)\r
+    {\r
+        NS_LOG(DEBUG, "Type is MESSAGE");\r
+\r
+        NSCacheMsgData * msgData = (NSCacheMsgData *) newObj->data;\r
+\r
+        NSCacheElement * it = NSStorageRead(list, msgData->id);\r
+        if (it)\r
+        {\r
+            NSCacheMsgData * itData = (NSCacheMsgData *) it->data;\r
+\r
+            if (strcmp(itData->id, msgData->id) == 0)\r
+            {\r
+\r
+                itData->messageType = msgData->messageType;\r
+                NS_LOG(DEBUG, "Updated messageType");\r
+                pthread_mutex_unlock(&NSCacheMutex);\r
+                return NS_OK;\r
+\r
+            }\r
+        }\r
+    }\r
+\r
+    if (list->head == NULL)\r
+    {\r
+        NS_LOG(DEBUG, "list->head is NULL, Insert First Data");\r
+        list->head = list->tail = newObj;\r
+        pthread_mutex_unlock(&NSCacheMutex);\r
+        return NS_OK;\r
+    }\r
+\r
+    list->tail = list->tail->next = newObj;\r
+    NS_LOG(DEBUG, "list->head is not NULL");\r
+    pthread_mutex_unlock(&NSCacheMutex);\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSStorageDelete(NSCacheList * list, const char * delId)\r
+{\r
+    pthread_mutex_lock(&NSCacheMutex);\r
+    NSCacheElement * prev = list->head;\r
+    NSCacheElement * del = list->head;\r
+\r
+    NSCacheType type = list->cacheType;\r
+\r
+    if (NSProviderCompareIdCacheData(type, del->data, delId))\r
+    {\r
+        if (del == list->head) // first object\r
+        {\r
+            if (del == list->tail) // first object (one object)\r
+                list->tail = del->next;\r
+\r
+            list->head = del->next;\r
+\r
+            NSProviderDeleteCacheData(type, del->data);\r
+            OICFree(del);\r
+            pthread_mutex_unlock(&NSCacheMutex);\r
+            return NS_OK;\r
+        }\r
+    }\r
+\r
+    del = del->next;\r
+    while (del)\r
+    {\r
+        if (NSProviderCompareIdCacheData(type, del->data, delId))\r
+        {\r
+            if (del == list->tail) // delete object same to last object\r
+                list->tail = prev;\r
+\r
+            prev->next = del->next;\r
+            NSProviderDeleteCacheData(type, del->data);\r
+            OICFree(del);\r
+            pthread_mutex_unlock(&NSCacheMutex);\r
+            return NS_OK;\r
+        }\r
+\r
+        prev = del;\r
+        del = del->next;\r
+    }\r
+    pthread_mutex_unlock(&NSCacheMutex);\r
+    return NS_OK;\r
+}\r
+\r
+NSResult NSStorageDestroy(NSCacheList * list)\r
+{\r
+    NSCacheElement * iter = list->head;\r
+    NSCacheElement * next = NULL;\r
+\r
+    NSCacheType type = list->cacheType;\r
+\r
+    while (iter)\r
+    {\r
+        next = (NSCacheElement *) iter->next;\r
+\r
+        NSProviderDeleteCacheData(type, iter->data);\r
+        OICFree(iter);\r
+\r
+        iter = next;\r
+    }\r
+\r
+    OICFree(list);\r
+\r
+    return NS_OK;\r
+}\r
+\r
+bool NSProviderCompareIdCacheData(NSCacheType type, void * data, const char * id)\r
+{\r
+    NS_LOG(DEBUG, "NSProviderCompareIdCacheData - IN");\r
+\r
+    if (data == NULL)\r
+    {\r
+        return false;\r
+    }\r
+\r
+    if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
+    {\r
+        NSCacheSubData * subData = (NSCacheSubData *) data;\r
+\r
+\r
+        NS_LOG_V(DEBUG, "Data(subData) = [%s]", subData->id);\r
+        NS_LOG_V(DEBUG, "Data(compData) = [%s]", id);\r
+\r
+        if (strcmp(subData->id, id) == 0)\r
+        {\r
+            NS_LOG(DEBUG, "SubData is Same");\r
+            return true;\r
+        }\r
+\r
+        NS_LOG(DEBUG, "Message Data is Not Same");\r
+        return false;\r
+\r
+    }\r
+    else if (type == NS_PROVIDER_CACHE_MESSAGE)\r
+    {\r
+        NSCacheMsgData * msgData = (NSCacheMsgData *) data;\r
+\r
+        if (strcmp(msgData->id, id) == 0)\r
+        {\r
+            NS_LOG(DEBUG, "Message Data is Same");\r
+            return true;\r
+        }\r
+\r
+        NS_LOG(DEBUG, "Message Data is Not Same");\r
+        return false;\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSProviderCompareIdCacheData - OUT");\r
+\r
+    return false;\r
+}\r
+\r
+NSResult NSProviderDeleteCacheData(NSCacheType type, void * data)\r
+{\r
+    if (data == NULL)\r
+    {\r
+        return NS_OK;\r
+    }\r
+\r
+    if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
+    {\r
+        NSCacheSubData * subData = (NSCacheSubData *) data;\r
+\r
+        (subData->id)[0] = '\0';\r
+        OICFree(subData);\r
+\r
+        return NS_OK;\r
+    }\r
+    else if (type == NS_PROVIDER_CACHE_MESSAGE)\r
+    {\r
+        NSCacheMsgData * msgData = (NSCacheMsgData *) data;\r
+\r
+        if (msgData->id)\r
+        {\r
+            OICFree(msgData->id);\r
+            msgData->id = NULL;\r
+        }\r
+\r
+        if (msgData->nsMessage)\r
+        {\r
+            NSFreeMessage(msgData->nsMessage);\r
+        }\r
+\r
+        OICFree(msgData);\r
+\r
+        return NS_OK;\r
+    }\r
+\r
+    return NS_OK;\r
+}\r
+\r
diff --git a/service/notification/src/provider/cache/linux/NSProviderMemoryCache.h b/service/notification/src/provider/cache/linux/NSProviderMemoryCache.h
new file mode 100755 (executable)
index 0000000..096d18b
--- /dev/null
@@ -0,0 +1,46 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#ifndef _NS_PROVIDER_CACHEADAPTER__H_\r
+#define _NS_PROVIDER_CACHEADAPTER__H_\r
+\r
+#include <pthread.h>\r
+#include <stdbool.h>\r
+#include <string.h>\r
+\r
+#include "NSCommon.h"\r
+#include "NSConstants.h"\r
+#include "NSStructs.h"\r
+#include "oic_malloc.h"\r
+#include "oic_string.h"\r
+#include "NSStorageAdapter.h"\r
+#include "NSUtil.h"\r
+\r
+NSResult NSProviderDeleteCacheData(NSCacheType, void *);\r
+\r
+bool NSProviderCompareIdCacheData(NSCacheType, void *, const char *);\r
+\r
+bool NSProviderIsFoundCacheData(NSCacheType, void *, void*);\r
+\r
+NSResult NSCacheUpdateSubScriptionState(NSCacheList *, char *, bool);\r
+\r
+pthread_mutex_t NSCacheMutex;\r
+\r
+#endif /* _NS_PROVIDER_CACHEADAPTER__H_ */\r
diff --git a/service/notification/unittest/NSConsumerSimulator.h b/service/notification/unittest/NSConsumerSimulator.h
new file mode 100644 (file)
index 0000000..f1177ba
--- /dev/null
@@ -0,0 +1,147 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_SIMULATOR_H_
+#define _NS_CONSUMER_SIMULATOR_H_
+
+#include <iostream>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+class NSConsumerSimulator
+{
+private:
+    std::function<void(const std::string&, const std::string&, const std::string&)> m_messageFunc;
+    std::function<void(int, const std::string&)> m_syncFunc;
+
+    std::shared_ptr<OC::OCResource> m_syncResource;
+
+
+public:
+    NSConsumerSimulator()
+    : m_messageFunc(), m_syncFunc(),
+      m_syncResource() { };
+    ~NSConsumerSimulator() = default;
+
+    NSConsumerSimulator(const NSConsumerSimulator &) = delete;
+    NSConsumerSimulator & operator = (const NSConsumerSimulator &) = delete;
+
+    NSConsumerSimulator(NSConsumerSimulator &&) = delete;
+    NSConsumerSimulator & operator = (NSConsumerSimulator &&) = delete;
+
+    void findProvider()
+    {
+        OC::OCPlatform::findResource("", std::string("/oic/res?rt=oic.r.notification"),
+                OCConnectivityType::CT_DEFAULT,
+                std::bind(&NSConsumerSimulator::findResultCallback, this, std::placeholders::_1),
+                OC::QualityOfService::LowQos);
+    }
+
+    void syncToProvider(int & type, const std::string & id)
+    {
+        if (m_syncResource == nullptr)
+        {
+            std::cout << "m_syncResource is null" << std::endl;
+            return;
+        }
+
+        OC::OCRepresentation rep;
+        rep.setValue("ID", id);
+        rep.setValue("STATE", type);
+
+        m_syncResource->post(rep, OC::QueryParamsMap(), &onPost, OC::QualityOfService::LowQos);
+    }
+
+    void setCallback(const std::function<void(const std::string&, const std::string&, const std::string&)> & messageFunc,
+            const std::function<void(int, const std::string&)> & syncFunc)
+    {
+        m_messageFunc = messageFunc;
+        m_syncFunc = syncFunc;
+    }
+
+private:
+    static void onPost(const OC::HeaderOptions &/*headerOption*/,
+                const OC::OCRepresentation & /*rep*/ , const int eCode)
+    {
+        std::cout << __func__ << " result : " << eCode << std::endl;
+    }
+    void findResultCallback(std::shared_ptr<OC::OCResource> resource)
+    {
+        std::cout << __func__ << " " << resource->host() << std::endl;
+        resource->get(OC::QueryParamsMap(),
+                std::bind(&NSConsumerSimulator::onGet, this,
+                        std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, resource),
+                OC::QualityOfService::LowQos);
+    }
+    void onGet(const OC::HeaderOptions &/*headerOption*/,
+            const OC::OCRepresentation & rep , const int eCode,
+            std::shared_ptr<OC::OCResource> resource)
+    {
+        std::cout << __func__ << " " << rep.getHost() << " result : " << eCode << std::endl;
+
+        std::shared_ptr<OC::OCResource> msgResource
+            = OC::OCPlatform::constructResourceObject(resource->host(), resource->uri() + "/message",
+                    resource->connectivityType(), false, resource->getResourceTypes(),
+                    resource->getResourceInterfaces());
+        m_syncResource
+            = OC::OCPlatform::constructResourceObject(resource->host(), resource->uri() + "/sync",
+                    resource->connectivityType(), false, resource->getResourceTypes(),
+                    resource->getResourceInterfaces());
+
+        msgResource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
+                std::bind(&NSConsumerSimulator::onObserve, this,
+                        std::placeholders::_1, std::placeholders::_2,
+                        std::placeholders::_3, std::placeholders::_4, resource),
+                OC::QualityOfService::LowQos);
+        m_syncResource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
+                std::bind(&NSConsumerSimulator::onObserve, this,
+                        std::placeholders::_1, std::placeholders::_2,
+                        std::placeholders::_3, std::placeholders::_4, resource),
+                OC::QualityOfService::LowQos);
+
+    }
+    void onObserve(const OC::HeaderOptions &/*headerOption*/,
+            const OC::OCRepresentation &rep , const int &eCode, const int &,
+            std::shared_ptr<OC::OCResource> )
+    {
+        std::cout << __func__ << " " << rep.getHost() << " result : " << eCode;
+        std::cout << " uri : " << rep.getUri() << std::endl;
+
+        if (rep.getUri() == "/notification/message" && rep.hasAttribute("ID")
+                && rep.getValueToString("ID") != "0000-0000-0000-0000")
+        {
+            std::cout << "ID : " << rep.getValueToString("ID") << std::endl;
+            std::cout << "TITLE : " << rep.getValueToString("TITLE") << std::endl;
+            std::cout << "CONTENT : " << rep.getValueToString("CONTENT") << std::endl;
+            m_messageFunc(std::string(rep.getValueToString("ID")),
+                          std::string(rep.getValueToString("TITLE")),
+                          std::string(rep.getValueToString("CONTENT")));
+        }
+        else if (rep.getUri() == "/notification/sync")
+        {
+            m_syncFunc(int(rep.getValue<int>("STATE")),
+                       std::string(rep.getValueToString("ID")));
+        }
+    }
+};
+
+
+#endif //_NS_CONSUMER_SIMULATOR_H_
diff --git a/service/notification/unittest/NSConsumerTest.cpp b/service/notification/unittest/NSConsumerTest.cpp
new file mode 100644 (file)
index 0000000..8f38d43
--- /dev/null
@@ -0,0 +1,436 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+#include <atomic>
+#include <functional>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
+
+#include "ocstack.h"
+
+#include "NSCommon.h"
+#include "NSConsumerInterface.h"
+
+#include "NSProviderSimulator.h"
+
+namespace
+{
+    NSProviderSimulator g_providerSimul;
+    NSProvider * g_provider;
+
+    std::atomic_bool g_isStartedStack(false);
+
+    std::chrono::milliseconds g_waitForResponse(500);
+
+    std::condition_variable responseCon;
+    std::mutex mutexForCondition;
+
+}
+
+class TestWithMock: public testing::Test
+{
+public:
+    MockRepository mocks;
+
+protected:
+    virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test())) {}
+
+    virtual void TearDown() {
+        try
+        {
+            mocks.VerifyAll();
+        }
+        catch (...)
+        {
+            mocks.reset();
+            throw;
+        }
+    }
+};
+
+class NotificationConsumerTest : public TestWithMock
+{
+public:
+    NotificationConsumerTest() = default;
+    ~NotificationConsumerTest() = default;
+
+    static void NSProviderDiscoveredCallbackEmpty(NSProvider *)
+    {
+        std::cout << __func__ << std::endl;
+    }
+
+    static void NSNotificationReceivedCallbackEmpty(NSProvider *, NSMessage *) { }
+
+    static void NSSyncCallbackEmpty(NSProvider *, NSSync *) { }
+
+    static void foundResourceEmpty(std::shared_ptr< OC::OCResource >) { }
+
+protected:
+
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        if (g_isStartedStack == false)
+        {
+            OC::PlatformConfig cfg
+            {
+                OC::ServiceType::InProc,
+                OC::ModeType::Both,
+                "0.0.0.0",
+                0,
+                OC::QualityOfService::LowQos
+            };
+            OC::OCPlatform::Configure(cfg);
+
+            try
+            {
+                OC::OCPlatform::stopPresence();
+            }
+            catch (...)
+            {
+
+            }
+
+            g_isStartedStack = true;
+        }
+
+    }
+
+    void TearDown()
+    {
+        TestWithMock::TearDown();
+    }
+
+};
+
+TEST_F(NotificationConsumerTest, StartConsumerPositive)
+{
+    EXPECT_EQ(NS_OK,
+              NSStartConsumer(
+                    NSProviderDiscoveredCallbackEmpty,
+                    NSNotificationReceivedCallbackEmpty,
+                    NSSyncCallbackEmpty));
+}
+
+TEST_F(NotificationConsumerTest, StopConsumerPositive)
+{
+    EXPECT_EQ(NSStopConsumer(), NS_OK);
+}
+
+TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerFirst)
+{
+    mocks.ExpectCallFunc(NSProviderDiscoveredCallbackEmpty).Do(
+            [this, & responseCon](NSProvider *)
+            {
+                std::cout << "Call Discovered" << std::endl;
+                responseCon.notify_all();
+            });
+
+    NSStartConsumer(
+            NSProviderDiscoveredCallbackEmpty,
+            NSNotificationReceivedCallbackEmpty,
+            NSSyncCallbackEmpty);
+
+    g_providerSimul.setAccepter(1);
+    g_providerSimul.createNotificationResource();
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+    NSStopConsumer();
+    g_providerSimul.deleteNotificationResource();
+}
+
+TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerAfter)
+{
+    g_providerSimul.setAccepter(1);
+    g_providerSimul.createNotificationResource();
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    mocks.ExpectCallFunc(NSProviderDiscoveredCallbackEmpty).Do(
+            [this, & responseCon](NSProvider *)
+            {
+                std::cout << "Call Discovered" << std::endl;
+                responseCon.notify_all();
+            });
+
+    NSStartConsumer(
+            NSProviderDiscoveredCallbackEmpty,
+            NSNotificationReceivedCallbackEmpty,
+            NSSyncCallbackEmpty);
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+}
+
+TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenRescan)
+{
+    mocks.ExpectCallFunc(NSProviderDiscoveredCallbackEmpty)
+            .Do(
+            [this, & responseCon](NSProvider * provider)
+            {
+                std::cout << "Call Discovered" << std::endl;
+                g_provider = provider;
+                responseCon.notify_all();
+            });
+
+    NSRescanProvider();
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+//    NSStopConsumer();
+}
+
+TEST_F(NotificationConsumerTest, ExpectSubscribeSuccess)
+{
+    NSResult ret = NSSubscribe(g_provider);
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+    EXPECT_EQ(NS_OK, ret);
+}
+
+TEST_F(NotificationConsumerTest, ExpectReceiveNotification)
+{
+    std::string id = "id";
+    std::string title = "title";
+    std::string msg = "msg";
+
+    mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+            [](NSProvider *, NSMessage * message)
+            {
+                std::cout << "Income Notification : " << message->mId << std::endl;
+                NSDropNSObject(message);
+            });
+
+    g_providerSimul.notifyMessage(id, title, msg);
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+}
+
+TEST_F(NotificationConsumerTest, ExpectUnsubscribeSuccess)
+{
+    NSResult ret = NSUnsubscribe(g_provider);
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+    EXPECT_EQ(NS_OK, ret);
+}
+
+TEST_F(NotificationConsumerTest, ExpectReceiveNotificationWithAccepterisProvider)
+{
+    std::string id = "ExpectReceiveNotificationWithAccepterisProvider";
+    std::string title = "title";
+    std::string msg = "msg";
+
+    g_providerSimul.setAccepter(0);
+
+    NSRescanProvider();
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+            [](NSProvider *, NSMessage * message)
+            {
+                std::cout << "Income Notification : " << message->mId << std::endl;
+                NSDropNSObject(message);
+            });
+
+    g_providerSimul.notifyMessage(id, title, msg);
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+//    g_providerSimul.deleteNotificationResource();
+//    NSStopConsumer();
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenProviderNotifySync)
+{
+    std::string id = "ExpectCallbackReadCheckWhenProviderNotifySync";
+    std::string title = "title";
+    std::string msg = "msg";
+
+    NSSyncTypes type = Notification_Dismiss;
+
+    mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+            [](NSProvider *, NSMessage * message)
+            {
+                std::cout << "Income Notification : " << message->mId << std::endl;
+                NSDropNSObject(message);
+            });
+
+    mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+            [& type](NSProvider *, NSSync * sync)
+            {
+                std::cout << "Income Notification : " << sync->mMessageId
+                        << ", State : " << sync->mState << std::endl;
+                type = sync->mState;
+
+            });
+
+    g_providerSimul.notifyMessage(id, title, msg);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    g_providerSimul.sendRead(id);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+//    g_providerSimul.deleteNotificationResource();
+//    NSStopConsumer();
+
+    EXPECT_EQ(Notification_Read, type);
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenProviderNotifySync)
+{
+    std::string id = "ExpectCallbackDismissCheckWhenProviderNotifySync";
+    std::string title = "title";
+    std::string msg = "msg";
+
+    NSSyncTypes type = Notification_Read;
+
+    mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+            [](NSProvider *, NSMessage * message)
+            {
+                std::cout << "Income Notification : " << message->mId << std::endl;
+                NSDropNSObject(message);
+            });
+
+    mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+            [& type](NSProvider *, NSSync * sync)
+            {
+                std::cout << "Income Notification : " << sync->mMessageId
+                        << ", State : " << sync->mState << std::endl;
+                type = sync->mState;
+
+            });
+
+    g_providerSimul.notifyMessage(id, title, msg);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    g_providerSimul.sendDismiss(id);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+//    g_providerSimul.deleteNotificationResource();
+//    NSStopConsumer();
+
+    EXPECT_EQ(Notification_Dismiss, type);
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenConsumerPostSync)
+{
+    std::string id = "ExpectCallbackReadCheckWhenConsumerPostSync";
+    std::string title = "title";
+    std::string msg = "msg";
+
+    NSSyncTypes type = Notification_Dismiss;
+
+    mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+            [](NSProvider *, NSMessage * message)
+            {
+                std::cout << "Income Notification : " << message->mId << std::endl;
+                NSConsumerReadCheck(message);
+                std::unique_lock< std::mutex > lock{ mutexForCondition };
+                responseCon.wait_for(lock, g_waitForResponse);
+            });
+
+    mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+            [& type](NSProvider *, NSSync * sync)
+            {
+                std::cout << "Income Notification : " << sync->mMessageId
+                        << ", State : " << sync->mState << std::endl;
+                type = sync->mState;
+
+            });
+
+    g_providerSimul.notifyMessage(id, title, msg);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+//    g_providerSimul.deleteNotificationResource();
+//    NSStopConsumer();
+
+    EXPECT_EQ(Notification_Read, type);
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenConsumerPostSync)
+{
+    std::string id = "ExpectCallbackDismissCheckWhenConsumerPostSync";
+    std::string title = "title";
+    std::string msg = "msg";
+
+    NSSyncTypes type = Notification_Read;
+
+    mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+            [](NSProvider *, NSMessage * message)
+            {
+                std::cout << "Income Notification : " << message->mId << std::endl;
+                NSConsumerDismissCheck(message);
+                std::unique_lock< std::mutex > lock{ mutexForCondition };
+                responseCon.wait_for(lock, g_waitForResponse);
+            });
+
+    mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+            [& type](NSProvider *, NSSync * sync)
+            {
+                std::cout << "Income Notification : " << sync->mMessageId
+                        << ", State : " << sync->mState << std::endl;
+                type = sync->mState;
+
+            });
+
+    g_providerSimul.notifyMessage(id, title, msg);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    g_providerSimul.deleteNotificationResource();
+    NSStopConsumer();
+
+    EXPECT_EQ(Notification_Dismiss, type);
+}
diff --git a/service/notification/unittest/NSProviderSimulator.h b/service/notification/unittest/NSProviderSimulator.h
new file mode 100644 (file)
index 0000000..36a8f54
--- /dev/null
@@ -0,0 +1,300 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_PROVIDER_SIMULATOR_H_
+#define _NS_PROVIDER_SIMULATOR_H_
+
+#include <iostream>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "OCResourceResponse.h"
+
+namespace
+{
+    enum class requestType
+    {
+        NS_NOTIFICATION,
+        NS_MESSAGE,
+        NS_SYNC,
+    };
+}
+
+class NSProviderSimulator
+{
+private:
+    OCResourceHandle m_notificationHandle;
+    OCResourceHandle m_messageHandle;
+    OCResourceHandle m_syncHandle;
+    OC::OCRepresentation m_syncRep;
+    OC::OCRepresentation m_messageRep;
+    int m_accepter;
+
+    std::string m_notificationUri;
+    std::string m_messageUri;
+    std::string m_syncUri;
+
+    OC::ObservationIds m_syncObservers;
+
+public:
+    NSProviderSimulator()
+    : m_notificationHandle(), m_messageHandle(), m_syncHandle(),
+      m_syncRep(), m_messageRep(), m_accepter(0),
+      m_notificationUri(std::string("/notification")),
+      m_messageUri(std::string("/message")),
+      m_syncUri(std::string("/sync")),
+      m_syncObservers() { };
+
+    ~NSProviderSimulator() = default;
+
+    NSProviderSimulator(const NSProviderSimulator &) = delete;
+    NSProviderSimulator & operator = (const NSProviderSimulator &) = delete;
+
+    NSProviderSimulator(NSProviderSimulator &&) = delete;
+    NSProviderSimulator & operator = (NSProviderSimulator &&) = delete;
+
+private:
+    std::shared_ptr<OC::OCResourceResponse> getResponse(
+            std::shared_ptr< OC::OCResourceRequest > requests, requestType type)
+    {
+        auto response = std::make_shared<OC::OCResourceResponse>();
+        response->setRequestHandle(requests->getRequestHandle());
+        response->setResourceHandle(requests->getResourceHandle());
+
+        int requestFlag = requests->getRequestHandlerFlag();
+        if (requestFlag == OC::RequestHandlerFlag::RequestFlag)
+        {
+            std::string request = requests->getRequestType();
+
+            response->setErrorCode(200);
+            response->setResponseResult(OC_EH_OK);
+
+            if (request == "GET")
+            {
+                OC::OCRepresentation rep;
+
+                if (type == requestType::NS_NOTIFICATION)
+                {
+                    std::string msgUri = m_notificationUri + m_messageUri;
+                    std::string syncUri = m_notificationUri + m_syncUri;
+                    rep.setValue("ACCEPTER", m_accepter);
+                    rep.setValue("MESSAGE_URI", msgUri);
+                    rep.setValue("SYNC_URI", syncUri);
+                }
+                else if (type == requestType::NS_SYNC)
+                {
+                    rep = m_syncRep;
+                }
+                else if (type == requestType::NS_MESSAGE)
+                {
+                    rep = m_messageRep;
+                }
+                else
+                {
+                    return NULL;
+                }
+
+                response->setResourceRepresentation(rep);
+                return response;
+            }
+
+            else if (request == "POST" && type == requestType::NS_SYNC)
+            {
+                m_syncRep = requests->getResourceRepresentation();
+
+                std::cout << "Receive POST at Sync" << std::endl;
+                std::cout << "Sync Id : " << m_syncRep.getValueToString("ID") << std::endl;
+                std::cout << "Sync State : " << m_syncRep.getValueToString("STATE") << std::endl;
+
+                response->setResourceRepresentation(m_syncRep);
+
+                OC::OCPlatform::notifyListOfObservers(m_syncHandle, m_syncObservers, response);
+
+                return response;
+            }
+        }
+
+        return NULL;
+    }
+
+    void setObserver(std::shared_ptr< OC::OCResourceRequest > requests, requestType type)
+    {
+        if (type == requestType::NS_SYNC)
+        {
+            OC::ObservationInfo observationInfo = requests->getObservationInfo();
+            if (OC::ObserveAction::ObserveRegister == observationInfo.action)
+            {
+                m_syncObservers.push_back(observationInfo.obsId);
+            }
+            else if (OC::ObserveAction::ObserveUnregister == observationInfo.action)
+            {
+                m_syncObservers.erase(std::remove(
+                        m_syncObservers.begin(), m_syncObservers.end(),
+                        observationInfo.obsId), m_syncObservers.end());
+            }
+        }
+    }
+
+    OCEntityHandlerResult entityHandler(
+            std::shared_ptr< OC::OCResourceRequest > request, requestType type)
+    {
+        if (!request)
+        {
+            return OC_EH_ERROR;
+        }
+
+        std::cout << "Provider : Income request : " << request->getRequestHandlerFlag() << std::endl;
+        if ((request->getRequestHandlerFlag() & OC::RequestHandlerFlag::ObserverFlag))
+        {
+            std::cout << "Provider : Income Observe : " << std::endl;
+            setObserver(request, type);
+            return OC_EH_OK;
+        }
+
+        auto pResponse = getResponse(request, type);
+        if (pResponse == nullptr)
+        {
+            return OC_EH_ERROR;
+        }
+
+        try
+        {
+            OC::OCPlatform::sendResponse(pResponse);
+        }
+        catch (std::exception & e)
+        {
+            return OC_EH_ERROR;
+        }
+
+        return OC_EH_OK;
+    }
+
+public:
+
+    void setAccepter(int accepter)
+    {
+        m_accepter = accepter;
+    }
+
+    void notifyMessage()
+    {
+        std::cout << "Provider : notify~" << std::endl;
+        OC::OCPlatform::notifyAllObservers(m_messageHandle);
+    }
+
+    void notifyMessage(const std::string & id, const std::string & title, const std::string & content)
+    {
+        setMessage(id, title, content);
+        notifyMessage();
+    }
+
+    void sendRead(const std::string & id)
+    {
+        m_syncRep.setValue("ID", id);
+        m_syncRep.setValue("STATE", (int)0);
+        OC::OCPlatform::notifyAllObservers(m_syncHandle);
+    }
+    void sendDismiss(const std::string & id)
+    {
+        m_syncRep.setValue("ID", id);
+        m_syncRep.setValue("STATE", (int)1);
+        OC::OCPlatform::notifyAllObservers(m_syncHandle);
+    }
+
+    void setMessage(const std::string & id, const std::string & title, const std::string & content)
+    {
+        m_messageRep.setValue("ID", id);
+        m_messageRep.setValue("TITLE", title);
+        m_messageRep.setValue("CONTENTTEXT", content);
+    }
+
+    void deleteNotificationResource()
+    {
+        OC::OCPlatform::unregisterResource(m_notificationHandle);
+        OC::OCPlatform::unregisterResource(m_messageHandle);
+        OC::OCPlatform::unregisterResource(m_syncHandle);
+    }
+
+    void createNotificationResource()
+    {
+        createNotificationResource(m_notificationUri);
+    }
+
+    void createNotificationResource(const std::string & uri)
+    {
+        if (m_notificationUri != uri)
+        {
+            m_notificationUri = uri;
+        }
+
+        OC::OCPlatform::startPresence(30);
+
+        std::string notificationUri = m_notificationUri;
+        std::string resourceTypeName = "oic.r.message.notification";
+        std::string resourceInterface = OC::DEFAULT_INTERFACE;
+
+        uint8_t resourceProperty = OC_OBSERVABLE;
+        std::string childUri = uri + m_messageUri;
+        try
+        {
+            OC::OCPlatform::registerResource(
+                    m_messageHandle, childUri,
+                    resourceTypeName, resourceInterface,
+                    std::bind(& NSProviderSimulator::entityHandler, this,
+                            std::placeholders::_1, requestType::NS_MESSAGE),
+                            resourceProperty);
+        } catch (std::exception & e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        resourceTypeName = "oic.r.sync.notification";
+        childUri = uri + m_syncUri;
+        try
+        {
+            OC::OCPlatform::registerResource(
+                    m_syncHandle, childUri,
+                    resourceTypeName, resourceInterface,
+                    std::bind(& NSProviderSimulator::entityHandler, this,
+                            std::placeholders::_1, requestType::NS_SYNC),
+                            resourceProperty);
+        } catch (std::exception & e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+
+        resourceProperty = OC_DISCOVERABLE;
+        resourceTypeName = "oic.r.notification";
+        try
+        {
+            OC::OCPlatform::registerResource(
+                    m_notificationHandle, notificationUri,
+                    resourceTypeName, resourceInterface,
+                    std::bind(& NSProviderSimulator::entityHandler, this,
+                            std::placeholders::_1, requestType::NS_NOTIFICATION),
+                            resourceProperty);
+        } catch (std::exception & e)
+        {
+            std::cout << e.what() << std::endl;
+        }
+    }
+};
+
+#endif /* _NS_PROVIDER_SIMULATOR_H_ */
diff --git a/service/notification/unittest/NSProviderTest.cpp b/service/notification/unittest/NSProviderTest.cpp
new file mode 100644 (file)
index 0000000..41c7fab
--- /dev/null
@@ -0,0 +1,286 @@
+//******************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+#include <atomic>
+#include <functional>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
+
+#include "NSConsumerSimulator.h"
+
+#include "NSCommon.h"
+#include "NSProviderInterface.h"
+
+namespace
+{
+    std::atomic_bool g_isStartedStack(false);
+
+    std::chrono::milliseconds g_waitForResponse(500);
+
+    std::condition_variable responseCon;
+    std::mutex mutexForCondition;
+
+    NSConsumerSimulator g_consumerSimul;
+    NSConsumer * g_consumer;
+
+}
+
+class TestWithMock: public testing::Test
+{
+public:
+    MockRepository mocks;
+
+protected:
+    virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test())) {}
+
+    virtual void TearDown() {
+        try
+        {
+            mocks.VerifyAll();
+        }
+        catch (...)
+        {
+            mocks.reset();
+            throw;
+        }
+    }
+};
+
+class NotificationProviderTest : public TestWithMock
+{
+public:
+    NotificationProviderTest() = default;
+    ~NotificationProviderTest() = default;
+
+    static void NSRequestedSubscribeCallbackEmpty(NSConsumer *)
+    {
+        std::cout << __func__ << std::endl;
+    }
+
+    static void NSSyncCallbackEmpty(NSSync *)
+    {
+        std::cout << __func__ << std::endl;
+    }
+
+    static void NSMessageCallbackFromConsumerEmpty(
+            const std::string &, const std::string &, const std::string &)
+    {
+        std::cout << __func__ << std::endl;
+    }
+
+    static void NSSyncCallbackFromConsumerEmpty(int, const std::string &)
+    {
+        std::cout << __func__ << std::endl;
+    }
+
+protected:
+
+    void SetUp()
+    {
+        TestWithMock::SetUp();
+
+        if (g_isStartedStack == false)
+        {
+            OC::PlatformConfig cfg
+            {
+                OC::ServiceType::InProc,
+                OC::ModeType::Both,
+                "0.0.0.0",
+                0,
+                OC::QualityOfService::LowQos
+            };
+            OC::OCPlatform::Configure(cfg);
+
+            try
+            {
+                OC::OCPlatform::stopPresence();
+            }
+            catch (...)
+            {
+
+            }
+
+            g_isStartedStack = true;
+        }
+
+    }
+
+    void TearDown()
+    {
+        TestWithMock::TearDown();
+    }
+
+};
+
+TEST_F(NotificationProviderTest, StartProviderPositive)
+{
+    NSResult ret = NSStartProvider(NS_ACCEPTER_PROVIDER,
+            NSRequestedSubscribeCallbackEmpty,
+            NSSyncCallbackEmpty);
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+    EXPECT_EQ(ret, NS_OK);
+}
+
+TEST_F(NotificationProviderTest, StopProviderPositive)
+{
+    NSResult ret = NSStopProvider();
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+
+    EXPECT_EQ(ret, NS_OK);
+}
+
+TEST_F(NotificationProviderTest, ExpectCallbackWhenReceiveSubscribeRequestWithAccepterProvider)
+{
+    mocks.ExpectCallFunc(NSRequestedSubscribeCallbackEmpty).Do(
+            [](NSConsumer * consumer)
+            {
+                std::cout << "NSRequestedSubscribeCallback" << std::endl;
+                g_consumer = consumer;
+                responseCon.notify_all();
+            });
+
+    NSStartProvider(NS_ACCEPTER_PROVIDER,
+            NSRequestedSubscribeCallbackEmpty, NSSyncCallbackEmpty);
+
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    g_consumerSimul.setCallback(NSMessageCallbackFromConsumerEmpty,
+            NSSyncCallbackFromConsumerEmpty);
+    g_consumerSimul.findProvider();
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, std::chrono::milliseconds(1000));
+}
+
+TEST_F(NotificationProviderTest, NeverCallNotifyOnConsumerByAcceptIsFalse)
+{
+    bool expectTrue = true;
+
+    mocks.OnCallFunc(NSMessageCallbackFromConsumerEmpty).Do(
+            [& expectTrue](const std::string &id, const std::string&, const std::string&)
+            {
+                if (id == "NeverCallNotifyOnConsumerByAcceptIsFalse")
+                {
+                    std::cout << "This function never call" << std::endl;
+                    expectTrue = false;
+                }
+            });
+
+    NSAccept(g_consumer, false);
+
+    NSMessage * msg = new NSMessage();
+    msg->mId = strdup(std::string("NeverCallNotifyOnConsumerByAcceptIsFalse").c_str());
+    msg->mTitle = strdup(std::string("Title").c_str());
+    msg->mContentText = strdup(std::string("ContentText").c_str());
+    NSSendMessage(msg);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, std::chrono::milliseconds(1000));
+
+    EXPECT_EQ(expectTrue, true);
+}
+
+TEST_F(NotificationProviderTest, ExpectCallNotifyOnConsumerByAcceptIsTrue)
+{
+    mocks.ExpectCallFunc(NSMessageCallbackFromConsumerEmpty).Do(
+            [](const std::string &id, const std::string&, const std::string&)
+            {
+                if (id == "ExpectCallNotifyOnConsumerByAcceptIsTrue")
+                {
+                    std::cout << "ExpectCallNotifyOnConsumerByAcceptIsTrue" << std::endl;
+                    responseCon.notify_all();
+                }
+            });
+
+    NSAccept(g_consumer, true);
+
+    NSMessage * msg = new NSMessage();
+    msg->mId = strdup(std::string("ExpectCallNotifyOnConsumerByAcceptIsTrue").c_str());
+    msg->mTitle = strdup(std::string("Title").c_str());
+    msg->mContentText = strdup(std::string("ContentText").c_str());
+    NSSendMessage(msg);
+    {
+        std::unique_lock< std::mutex > lock{ mutexForCondition };
+        responseCon.wait_for(lock, g_waitForResponse);
+    }
+
+    std::unique_lock< std::mutex > lock{ mutexForCondition };
+    responseCon.wait_for(lock, g_waitForResponse);
+}
+
+//TEST_F(NotificationProviderTest, ExpectCallbackSyncOnReadToConsumer)
+//{
+//    int type = 0;
+//    std::string id = "ExpectCallNotifyOnConsumerByAcceptIsTrue";
+//    mocks.ExpectCallFunc(NSSyncCallbackFromConsumerEmpty).Do(
+//            [& id](int type, const std::string & syncId)
+//            {
+//        std::cout << "NSSyncCallbackEmpty" << std::endl;
+//                if (syncId == id &&
+//                        type == Notification_Read)
+//                {
+//                    std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
+//                    responseCon.notify_all();
+//                }
+//            });
+//
+//    NSMessage * msg = new NSMessage();
+//    msg->mId = strdup(std::string("ExpectCallNotifyOnConsumerByAcceptIsTrue").c_str());
+//    msg->mTitle = strdup(std::string("Title").c_str());
+//    msg->mContentText = strdup(std::string("ContentText").c_str());
+//    NSProviderReadCheck(msg);
+//    std::unique_lock< std::mutex > lock{ mutexForCondition };
+//    responseCon.wait_for(lock, std::chrono::milliseconds(5000));
+//}
+
+//TEST_F(NotificationProviderTest, ExpectCallbackSyncOnReadFromConsumer)
+//{
+//    int type = 0;
+//    std::string id("ExpectCallNotifyOnConsumerByAcceptIsTrue");
+//    mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+//            [& id](NSSync * sync)
+//            {
+//                std::cout << "NSSyncCallbackEmpty" << std::endl;
+//                if (sync->mMessageId == id && sync->mState == Notification_Read)
+//                {
+//                    std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
+//                    responseCon.notify_all();
+//                }
+//            });
+//
+//    g_consumerSimul.syncToProvider(type, std::string(id));
+//    std::unique_lock< std::mutex > lock{ mutexForCondition };
+//    responseCon.wait_for(lock, std::chrono::milliseconds(5000));
+//}
diff --git a/service/notification/unittest/SConscript b/service/notification/unittest/SConscript
new file mode 100644 (file)
index 0000000..3c77952
--- /dev/null
@@ -0,0 +1,92 @@
+#******************************************************************
+#
+# Copyright 2016 Samsung Electronics All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# Notification Unit Test build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+######################################################################
+#unit test setting
+######################################################################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+notification_test_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+GTest = File(gtest_dir + '/lib/.libs/libgtest.a')
+GTest_Main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+notification_test_env.AppendUnique(LIBPATH = [lib_env.get('BUILD_DIR')])
+notification_test_env.AppendUnique(LIBS = [
+    'connectivity_abstraction', 'oc', 'octbstack', 'oc_logger', 'coap',
+    GTest_Main, GTest])
+
+if target_os not in ['windows', 'winrt']:
+    notification_test_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+notification_test_env.AppendUnique(CXXFLAGS = ['-pthread'])
+notification_test_env.AppendUnique(LIBS = ['pthread'])
+
+notification_test_env.PrependUnique(CPPPATH = [ src_dir + '/extlibs/hippomocks-master', gtest_dir + '/include'])
+notification_test_env.AppendUnique(CPPPATH = ['../include'])
+
+######################################################################
+# Build Test
+######################################################################
+
+notification_consumer_test_env = notification_test_env.Clone()
+notification_consumer_test_env.AppendUnique(LIBS = ['notification_consumer'])
+
+notification_provider_test_env = notification_test_env.Clone()
+notification_provider_test_env.AppendUnique(LIBS = ['notification_provider'])
+
+notification_consumer_test_src = env.Glob('./NSConsumerTest.cpp')
+notification_consumer_test = notification_consumer_test_env.Program('notification_consumer_test', notification_consumer_test_src)
+Alias("notification_consumer_test", notification_consumer_test)
+env.AppendTarget('notification_consumer_test')
+
+notification_provider_test_src = env.Glob('./NSProviderTest.cpp')
+notification_provider_test = notification_provider_test_env.Program('notification_provider_test', notification_provider_test_src)
+Alias("notification_provider_test", notification_provider_test)
+env.AppendTarget('notification_provider_test')
+
+if env.get('TEST') == '1':
+    if target_os == 'linux':
+            from tools.scons.RunTest import *
+            run_test(notification_consumer_test_env, '', 'service/notification/unittest/notification_consumer_test')
+            run_test(notification_provider_test_env, '', 'service/notification/unittest/notification_provider_test')
\ No newline at end of file