diff --git a/.gitignore b/.gitignore
index cd8838ac6d..ac1222119b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,10 @@ target
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+# Android Studio
+.gradle
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle
new file mode 100644
index 0000000000..1fd0aa8186
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/build.gradle
@@ -0,0 +1,46 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion '22.0.1'
+ defaultConfig {
+ applicationId "agent.sense.android.iot.carbon.wso2.org.wso2_senseagent"
+ minSdkVersion 19
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ applicationVariants.all { variant ->
+ variant.outputs.each { output ->
+ def newName = output.outputFile.name
+ newName = newName.replace("app-", "androidsense")
+ newName = newName.replace("release", "")
+ //noinspection GroovyAssignabilityCheck
+ output.outputFile = new File(output.outputFile.parent, newName)
+ }
+ }
+ }
+ }
+ packagingOptions {
+ exclude 'META-INF/NOTICE'
+ exclude 'META-INF/LICENSE'
+ }
+ productFlavors {
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:22.2.1'
+ compile 'com.android.support:design:22.2.1'
+ compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'
+ compile 'com.github.rholder:snowball-stemmer:1.3.0.581.1'
+ compile 'commons-codec:commons-codec:1.4'
+ compile 'com.netflix.feign:feign-jaxrs:8.16.0'
+ compile 'com.netflix.feign:feign-jackson:8.16.0'
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..5a799fbdad
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/AndroidManifest.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/RegisterActivity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/RegisterActivity.java
new file mode 100644
index 0000000000..a7e069757c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/RegisterActivity.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherReceiver;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.AndroidSenseMQTTHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+import org.wso2.carbon.iot.android.sense.event.SenseScheduleReceiver;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.ActivitySelectSensor;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.AvailableSensorsInDevice;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+import org.wso2.carbon.iot.android.sense.util.SenseClient;
+import org.wso2.carbon.iot.android.sense.util.SenseUtils;
+import org.wso2.carbon.iot.android.sense.util.dto.RegisterInfo;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+
+/**
+ * A login screen that offers to register the device.
+ */
+public class RegisterActivity extends Activity {
+
+ private EditText mUsernameView;
+ private EditText mPasswordView;
+ private EditText mHostView;
+ private EditText mMqttPortView;
+ private View mProgressView;
+ private View mLoginFormView;
+ private Handler mUiHandler = new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getSharedPreferences(SupportedSensors.SELECTED_SENSORS, 0).edit().clear().apply();
+
+ if (LocalRegistry.isExist(getApplicationContext())) {
+ Intent intent = new Intent(getApplicationContext(), ActivitySelectSensor.class);
+ startActivity(intent);
+ }
+ setContentView(R.layout.activity_register);
+ mUsernameView = (EditText) findViewById(R.id.username);
+ mPasswordView = (EditText) findViewById(R.id.password);
+ mHostView = (EditText) findViewById(R.id.hostname);
+ mMqttPortView = (EditText) findViewById(R.id.mqttPort);
+ AvailableSensorsInDevice availableSensorsInDevice = new AvailableSensorsInDevice(getApplicationContext());
+ availableSensorsInDevice.setContent();
+
+ Button deviceRegisterButton = (Button) findViewById(R.id.device_register_button);
+
+
+ deviceRegisterButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ attemptLogin();
+ }
+ });
+
+ mLoginFormView = findViewById(R.id.login_form);
+ mProgressView = findViewById(R.id.login_progress);
+ }
+
+ public void attemptLogin() {
+ showProgress(true);
+ // Reset errors.
+ mUsernameView.setError(null);
+ mPasswordView.setError(null);
+
+ // Store values at the time of the login attempt.
+ final String username = mUsernameView.getText().toString();
+ final String password = mPasswordView.getText().toString();
+ final String hostname = mHostView.getText().toString();
+ String mqttPort = mMqttPortView.getText().toString();
+ boolean cancel = false;
+ View focusView = null;
+
+ // Check for a valid password, if the user entered one.
+ if (!TextUtils.isEmpty(password)) {
+ // mPasswordView.setError(getString(R.string.error_invalid_password));
+ focusView = mPasswordView;
+ //cancel = true;
+ }
+ // Check for a valid username .
+ if (TextUtils.isEmpty(username)) {
+ mUsernameView.setError(getString(R.string.error_field_required));
+ focusView = mUsernameView;
+ cancel = true;
+ }
+ if (TextUtils.isEmpty(username)) {
+ mHostView.setError(getString(R.string.error_field_required));
+ focusView = mHostView;
+ cancel = true;
+ }
+
+ if (cancel) {
+ focusView.requestFocus();
+ } else {
+ final int mqttPortNo= Integer.parseInt(mqttPort);
+ Thread myThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ SenseClient client = new SenseClient(getApplicationContext());
+ LocalRegistry.addServerURL(getBaseContext(), hostname);
+ String deviceId = SenseUtils.generateDeviceId(getBaseContext(), getContentResolver());
+ final RegisterInfo registerStatus = client.register(username, password, deviceId, mUiHandler);
+ mUiHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(getApplicationContext(), registerStatus.getMsg(), Toast.LENGTH_LONG).show();
+ }
+ });
+
+ if (registerStatus.isRegistered()) {
+ LocalRegistry.addUsername(getApplicationContext(), username);
+ LocalRegistry.addDeviceId(getApplicationContext(), deviceId);
+ LocalRegistry.addMqttPort(getApplicationContext(), mqttPortNo);
+ MQTTTransportHandler mqttTransportHandler = AndroidSenseMQTTHandler.getInstance(getApplicationContext());
+ if (!mqttTransportHandler.isConnected()) {
+ mqttTransportHandler.connect();
+ }
+ SenseScheduleReceiver senseScheduleReceiver = new SenseScheduleReceiver();
+ senseScheduleReceiver.clearAbortBroadcast();
+ senseScheduleReceiver.onReceive(getApplicationContext(), null);
+
+ DataPublisherReceiver dataUploaderReceiver = new DataPublisherReceiver();
+ dataUploaderReceiver.clearAbortBroadcast();
+ dataUploaderReceiver.onReceive(getApplicationContext(), null);
+
+ mUiHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Intent intent = new Intent(getApplicationContext(), ActivitySelectSensor.class);
+ startActivity(intent);
+ }
+ });
+
+ }
+ mUiHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ showProgress(false);
+ }
+ });
+
+ }
+ });
+ myThread.start();
+
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+ public void showProgress(final boolean show) {
+ // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
+ // for very easy animations. If available, use these APIs to fade-in
+ // the progress spinner.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
+ int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
+
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ mLoginFormView.animate().setDuration(shortAnimTime).alpha(
+ show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+ });
+
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mProgressView.animate().setDuration(shortAnimTime).alpha(
+ show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ });
+ } else {
+ // The ViewPropertyAnimator APIs are not available, so simply show
+ // and hide the relevant UI components.
+ mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
+ mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
+ }
+ }
+
+}
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/constants/SenseConstants.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/constants/SenseConstants.java
new file mode 100644
index 0000000000..0661144ada
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/constants/SenseConstants.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.constants;
+
+/**
+ * This hold constants related to android_sense.
+ */
+public class SenseConstants {
+ public final static String DEVICE_TYPE = "android_sense";
+ public final static String REGISTER_CONTEXT = "/android_sense";
+ public final static String DCR_CONTEXT = "/dynamic-client-web";
+ public final static String TOKEN_ISSUER_CONTEXT = "/oauth2";
+ public final static String API_APPLICATION_REGISTRATION_CONTEXT = "/api-application-registration";
+
+ public static final int MQTT_BROKER_PORT = 1883;
+ public static final String EVENT_LISTENER_STARTED = "xxStartedxx";
+ public static final String EVENT_LISTENER_FINISHED = "xxFinishedxx";
+ public static final String EVENT_LISTENER_ONGOING = "xxOngoingxx";
+
+ public final class Request {
+ public final static String REQUEST_SUCCESSFUL = "200";
+ public final static String REQUEST_CONFLICT = "409";
+ public final static int MAX_ATTEMPTS = 2;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherReceiver.java
new file mode 100644
index 0000000000..b09d15a889
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherReceiver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.data.publisher;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * This creates and AlarmManagerService that triggers the data uploader service with a 30 seconds interval.
+ */
+public class DataPublisherReceiver extends BroadcastReceiver {
+ private static int ALARM_INTERVAL = 30000;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent i = new Intent(context, DataPublisherService.class);
+ PendingIntent pending = PendingIntent.getService(context, 0, i, 0);
+ service.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ALARM_INTERVAL, pending);
+ }
+
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java
new file mode 100644
index 0000000000..51c7cb807b
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/DataPublisherService.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.data.publisher;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Sensor;
+import android.os.IBinder;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.AndroidSenseMQTTHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.TransportHandlerException;
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationData;
+import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorData;
+import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryData;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ProcessWords;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+//import org.wso2.carbon.iot.android.sense.util.SenseClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is an android service which publishes the data to the server.
+ */
+public class DataPublisherService extends Service {
+ private static final String TAG = DataPublisherService.class.getName();
+ private static String KEY_TAG = "key";
+ private static String TIME_TAG = "time";
+ private static String VALUE_TAG = "value";
+ public static Context context;
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ context = this;
+ Log.d(TAG, "service started");
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ List events = new ArrayList<>();
+ //retreive sensor data.
+ List sensorDataMap = SenseDataHolder.getSensorDataHolder();
+ for (SensorData sensorData : sensorDataMap) {
+ Event event = new Event();
+ event.setTimestamp(sensorData.getTimestamp());
+
+ switch (sensorData.getSensorType()) {
+ case Sensor.TYPE_ACCELEROMETER:
+ event.setAccelerometer(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ event.setMagnetic(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_GYROSCOPE:
+ event.setGyroscope(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_LIGHT:
+ event.setLight(sensorData.getSensorValues()[0]);
+ break;
+ case Sensor.TYPE_PRESSURE:
+ event.setPressure(sensorData.getSensorValues()[0]);
+ break;
+ case Sensor.TYPE_PROXIMITY:
+ event.setProximity(sensorData.getSensorValues()[0]);
+ break;
+ case Sensor.TYPE_GRAVITY:
+ event.setGravity(sensorData.getSensorValues());
+ break;
+ case Sensor.TYPE_ROTATION_VECTOR:
+ event.setGravity(sensorData.getSensorValues());
+ break;
+ }
+ events.add(event);
+ }
+ SenseDataHolder.resetSensorDataHolder();
+
+ //retreive batter data.
+ List batteryDataMap = SenseDataHolder.getBatteryDataHolder();
+ for (BatteryData batteryData : batteryDataMap) {
+ Event event = new Event();
+ event.setTimestamp(batteryData.getTimestamp());
+ event.setBattery(batteryData.getLevel());
+ events.add(event);
+ }
+ SenseDataHolder.resetBatteryDataHolder();
+ //retreive location data.
+ List locationDataMap = SenseDataHolder.getLocationDataHolder();
+ for (LocationData locationData : locationDataMap) {
+ Event event = new Event();
+ event.setTimestamp(locationData.getTimeStamp());
+ event.setGps(new double[]{locationData.getLatitude(), locationData.getLongitude()});
+ events.add(event);
+ }
+ SenseDataHolder.resetLocationDataHolder();
+
+ //retreive words
+ ProcessWords.cleanAndPushToWordMap();
+ List wordDatMap = SenseDataHolder.getWordDataHolder();
+ for (WordData wordData : wordDatMap) {
+ if (wordData.getOccurences() == 0) {
+ continue;
+ }
+ for (int i = 0; i < wordData.getOccurences(); i++) {
+ Event event = new Event();
+ event.setTimestamp(wordData.getTimestamp());
+ event.setWord(wordData.getWord());
+ String word = wordData.getWord();
+ String status = word;
+ if ((!word.equals(SenseConstants.EVENT_LISTENER_STARTED)) && (!word.equals(SenseConstants
+ .EVENT_LISTENER_FINISHED))) {
+ status = SenseConstants.EVENT_LISTENER_ONGOING;
+ }
+ event.setWordStatus(status);
+ events.add(event);
+ }
+ }
+ SenseDataHolder.resetWordDataHolder();
+ //publish the data
+ if (events.size() > 0) {
+ String user = LocalRegistry.getUsername(context);
+ String deviceId = LocalRegistry.getDeviceId(context);
+ JSONArray jsonArray = new JSONArray();
+ for (Event event : events) {
+ event.setOwner(user);
+ event.setDeviceId(deviceId);
+ jsonArray.put(event.getEvent());
+ }
+ MQTTTransportHandler mqttTransportHandler = AndroidSenseMQTTHandler.getInstance(context);
+ if (!mqttTransportHandler.isConnected()) {
+ mqttTransportHandler.connect();
+ }
+ mqttTransportHandler.publishDeviceData(user, deviceId, jsonArray.toString());
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, "Json Data Parsing Exception", e);
+ } catch (TransportHandlerException e) {
+ Log.e(TAG, "Data Publish Failed", e);
+ }
+ }
+ };
+ Thread dataUploaderThread = new Thread(runnable);
+ dataUploaderThread.start();
+ return Service.START_NOT_STICKY;
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java
new file mode 100644
index 0000000000..554c38b12f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/Event.java
@@ -0,0 +1,222 @@
+package org.wso2.carbon.iot.android.sense.data.publisher;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * This hold the definition of the stream that android sense is publishing to.
+ */
+public class Event {
+
+ private String owner;
+ private String deviceId;
+ private String type;
+ private float battery;
+ private double gps[]; //lat,long
+ private float accelerometer[]; //x,y,z
+ private float magnetic[]; //x,y,z
+ private float gyroscope[]; //x,y,z
+ private float light;
+ private float pressure;
+ private float proximity;
+ private float gravity[];
+ private float rotation[];
+ private String wordSessionId;
+ private String word;
+ private String wordStatus;
+ private long timestamp;
+
+ private float getBattery() {
+ return battery;
+ }
+
+ public void setBattery(float battery) {
+ this.type = "battery";
+ this.battery = battery;
+ }
+
+ private double[] getGps() {
+ return gps != null ? gps : new double[]{0, 0};
+ }
+
+ public void setGps(double[] gps) {
+ this.type = "gps";
+ this.gps = gps;
+ }
+
+ private float[] getAccelerometer() {
+ return accelerometer != null ? accelerometer : new float[]{0, 0, 0};
+ }
+
+ public void setAccelerometer(float[] accelerometer) {
+ this.type = "accelerometer";
+ this.accelerometer = accelerometer;
+ }
+
+ private float[] getMagnetic() {
+ return magnetic != null ? magnetic : new float[]{0, 0, 0};
+ }
+
+ public void setMagnetic(float[] magnetic) {
+ this.type = "magnetic";
+ this.magnetic = magnetic;
+ }
+
+ private float[] getGyroscope() {
+ return gyroscope != null ? gyroscope : new float[]{0, 0, 0};
+ }
+
+ public void setGyroscope(float[] gyroscope) {
+ this.type = "gyroscope";
+ this.gyroscope = gyroscope;
+ }
+
+ public float getLight() {
+ return light;
+ }
+
+ public void setLight(float light) {
+ this.type = "light";
+ this.light = light;
+ }
+
+ public float getPressure() {
+ return pressure;
+ }
+
+ public void setPressure(float pressure) {
+ this.type = "pressure";
+ this.pressure = pressure;
+ }
+
+ public float getProximity() {
+ return proximity;
+ }
+
+ public void setProximity(float proximity) {
+ this.type = "proximity";
+ this.proximity = proximity;
+ }
+
+ private float[] getGravity() {
+ return gravity != null ? gravity : new float[]{0, 0, 0};
+ }
+
+ public void setGravity(float gravity[]) {
+ this.type = "gravity";
+ this.gravity = gravity;
+ }
+
+ private float[] getRotation() {
+ return rotation != null ? rotation : new float[]{0, 0, 0};
+ }
+
+ public void setRotation(float rotation[]) {
+ this.type = "rotation";
+ this.rotation = rotation;
+ }
+
+ private String getWordSessionId() {
+ return wordSessionId != null ? wordSessionId : "";
+ }
+
+ public void setWordSessionId(String wordSessionId) {
+ this.wordSessionId = wordSessionId;
+ }
+
+ private String getWord() {
+ return word != null ? word : "";
+ }
+
+ public void setWord(String word) {
+ this.type = "word";
+ this.word = word;
+ }
+
+ private long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ private String getDeviceId() {
+ return deviceId;
+ }
+
+ public void setDeviceId(String deviceId) {
+ this.deviceId = deviceId;
+ }
+
+ private String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public String getWordStatus() {
+ return wordStatus != null ? wordStatus : "";
+ }
+
+ public void setWordStatus(String wordStatus) {
+ this.wordStatus = wordStatus;
+ }
+
+ public JSONObject getEvent() throws JSONException {
+ JSONObject jsonEvent = new JSONObject();
+ JSONObject jsonMetaData = new JSONObject();
+ jsonMetaData.put("owner", getOwner());
+ jsonMetaData.put("deviceId", getDeviceId());
+ jsonMetaData.put("type", type);
+ jsonMetaData.put("timestamp", getTimestamp());
+ jsonEvent.put("metaData", jsonMetaData);
+
+ JSONObject jsonPayloadData = new JSONObject();
+ jsonPayloadData.put("battery", getBattery());
+ //gps
+ double gpsEvents[] = getGps();
+ jsonPayloadData.put("gps_lat", gpsEvents[0]);
+ jsonPayloadData.put("gps_long", gpsEvents[1]);
+ //acceleromter
+ float events[] = getAccelerometer();
+ jsonPayloadData.put("accelerometer_x", events[0]);
+ jsonPayloadData.put("accelerometer_y", events[1]);
+ jsonPayloadData.put("accelerometer_z", events[2]);
+ //magnetic
+ events = getMagnetic();
+ jsonPayloadData.put("magnetic_x", events[0]);
+ jsonPayloadData.put("magnetic_y", events[1]);
+ jsonPayloadData.put("magnetic_z", events[2]);
+ //gyroscope
+ events = getGyroscope();
+ jsonPayloadData.put("gyroscope_x", events[0]);
+ jsonPayloadData.put("gyroscope_y", events[1]);
+ jsonPayloadData.put("gyroscope_z", events[2]);
+
+ jsonPayloadData.put("light", getLight());
+ jsonPayloadData.put("pressure", getPressure());
+ jsonPayloadData.put("proximity", getProximity());
+ //gravity
+ events = getGravity();
+ jsonPayloadData.put("gravity_x", events[0]);
+ jsonPayloadData.put("gravity_y", events[1]);
+ jsonPayloadData.put("gravity_z", events[2]);
+ //rotation
+ events = getRotation();
+ jsonPayloadData.put("rotation_x", events[0]);
+ jsonPayloadData.put("rotation_y", events[1]);
+ jsonPayloadData.put("rotation_z", events[2]);
+ //word
+ jsonPayloadData.put("word", getWord());
+ jsonPayloadData.put("word_sessionId", getWordSessionId());
+ jsonPayloadData.put("word_status", getWordStatus());
+
+ jsonEvent.put("payloadData", jsonPayloadData);
+
+ return jsonEvent;
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/AndroidSenseMQTTHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/AndroidSenseMQTTHandler.java
new file mode 100644
index 0000000000..5ae9b37391
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/AndroidSenseMQTTHandler.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+package org.wso2.carbon.iot.android.sense.data.publisher.mqtt;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.TransportHandlerException;
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ProcessWords;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+/**
+ * This is an example for the use of the MQTT capabilities provided by the IoT-Server. This example depicts the use
+ * of MQTT Transport for the Android Sense device-type. This class extends the abstract class
+ * "MQTTTransportHandler". "MQTTTransportHandler" consists of the MQTT client specific functionality and implements
+ * the "TransportHandler" interface. The actual functionality related to the "TransportHandler" interface is
+ * implemented here, in this concrete class. Whilst the abstract class "MQTTTransportHandler" is intended to provide
+ * the common MQTT functionality, this class (which is its extension) provides the implementation specific to the
+ * MQTT communication of the Device-Type (Android Sense) in concern.
+ *
+ * Hence, the methods of this class are implementation of the "TransportHandler" interface which handles the device
+ * specific logic to connect-to, publish-to, process-incoming-messages-from and disconnect-from the MQTT broker
+ * listed in the configurations.
+ */
+public class AndroidSenseMQTTHandler extends MQTTTransportHandler {
+ private static final String TAG = "AndroidSenseMQTTHandler";
+ private static volatile AndroidSenseMQTTHandler mInstance;
+
+
+ /**
+ * return a sigleton Instance
+ * @param context is the android context object.
+ * @return AndroidSenseMQTTHandler.
+ */
+ public static AndroidSenseMQTTHandler getInstance(Context context) {
+ if (mInstance == null) {
+ Class clazz = AndroidSenseMQTTHandler.class;
+ synchronized (clazz) {
+ if (mInstance == null) {
+ mInstance = new AndroidSenseMQTTHandler(context);
+ }
+ }
+ }
+ return mInstance;
+ }
+
+ /**
+ * Default constructor for the AndroidSenseMQTTHandler.
+ */
+ private AndroidSenseMQTTHandler(Context context) {
+ super(context);
+ }
+
+ /**
+ * {@inheritDoc}
+ * AndroidSense device-type specific implementation to connect to the MQTT broker and subscribe to a topic.
+ * This method is called to initiate a MQTT communication.
+ */
+ @Override
+ public void connect() {
+ Runnable connector = new Runnable() {
+ public void run() {
+ while (!isConnected()) {
+ try {
+ connectToQueue();
+ } catch (TransportHandlerException e) {
+ Log.e(TAG, "Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ try {
+ Thread.sleep(timeoutInterval);
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ Log.e(TAG, "MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
+ }
+ }
+
+ try {
+ subscribeToQueue();
+ } catch (TransportHandlerException e) {
+ Log.w(TAG, "Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ }
+ }
+ }
+ };
+
+ Thread connectorThread = new Thread(connector);
+ connectorThread.setDaemon(true);
+ connectorThread.start();
+ }
+
+ /**
+ * {@inheritDoc}
+ * AndroidSense device-type specific implementation to process incoming messages. This is the specific
+ * method signature of the overloaded "processIncomingMessage" method that gets called from the messageArrived()
+ * callback of the "MQTTTransportHandler".
+ */
+ @Override
+ public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) {
+ if (messageParams.length != 0) {
+ // owner and the deviceId are extracted from the MQTT topic to which the message was received.
+ // = [ServerName/Owner/DeviceType/DeviceId/#]
+ String topic = messageParams[0];
+ String[] topicParams = topic.split("/");
+ String owner = topicParams[1];
+ String deviceId = topicParams[3];
+
+ Log.d(TAG, "Received MQTT message for: [OWNER-" + owner + "] & [DEVICE.ID-" + deviceId + "]");
+
+ String msg;
+ msg = mqttMessage.toString();
+ Log.d(TAG, "MQTT: Received Message [" + msg + "] topic: [" + topic + "]");
+ if (topic.contains("threshold")) {
+ try {
+ ProcessWords.setThreshold(Integer.parseInt(msg));
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Invalid threshold value " + msg);
+ }
+ } else if (topic.contains("words")) {
+ String words[] = msg.split(" ");
+ ProcessWords.addWords(Arrays.asList(words));
+ } else if (topic.contains("remove")) {
+ String words[] = msg.split(" ");
+ for (String word: words) {
+ ProcessWords.removeWord(word);
+ }
+ }
+ } else {
+ String errorMsg =
+ "MQTT message [" + mqttMessage.toString() + "] was received without the topic information.";
+ Log.w(TAG, errorMsg);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * AndroidSense device-type specific implementation to publish data to the device. This method calls the
+ * {@link #publishToQueue(String, MqttMessage)} method of the "MQTTTransportHandler" class.
+ */
+ @Override
+ public void publishDeviceData(String... publishData) throws TransportHandlerException {
+ if (publishData.length != 3) {
+ String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " +
+ "Need to be [owner, deviceId, content]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg);
+ }
+
+ String deviceOwner = publishData[0];
+ String deviceId = publishData[1];
+ String resource = publishData[2];
+
+ MqttMessage pushMessage = new MqttMessage();
+ String publishTopic = "wso2/" + SenseConstants.DEVICE_TYPE + "/" + deviceId + "/data";
+ String actualMessage = resource;
+ pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8));
+ pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE);
+ pushMessage.setRetained(false);
+ publishToQueue(publishTopic, pushMessage);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * Android Sense device-type specific implementation to disconnect from the MQTT broker.
+ */
+ @Override
+ public void disconnect() {
+ Runnable stopConnection = new Runnable() {
+ public void run() {
+ while (isConnected()) {
+ try {
+ closeConnection();
+ } catch (MqttException e) {
+ Log.w(TAG, "Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint
+ + " for device-type - " + SenseConstants.DEVICE_TYPE, e);
+
+ try {
+ Thread.sleep(timeoutInterval);
+ } catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
+ Log.e(TAG, "MQTT-Terminator: Thread Sleep Interrupt Exception at device-type - " +
+ SenseConstants.DEVICE_TYPE, e1);
+ }
+ }
+ }
+ }
+ };
+
+ Thread terminatorThread = new Thread(stopConnection);
+ terminatorThread.setDaemon(true);
+ terminatorThread.start();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void publishDeviceData() {
+ // nothing to do
+ }
+
+ @Override
+ public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void processIncomingMessage() {
+ // nothing to do
+ }
+
+ @Override
+ public void processIncomingMessage(MqttMessage message) throws TransportHandlerException {
+
+ }
+
+}
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java
new file mode 100644
index 0000000000..689138d729
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/MQTTTransportHandler.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+package org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport;
+import android.content.Context;
+import android.util.Log;
+import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
+import org.eclipse.paho.client.mqttv3.MqttCallback;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * This is an abstract class that implements the "TransportHandler" interface. The interface is an abstraction for
+ * the core functionality with regards to device-server communication regardless of the Transport protocol. This
+ * specific class contains the MQTT-Transport specific implementations. The class implements utility methods for the
+ * case of a MQTT communication. However, this "abstract class", even-though it implements the "TransportHandler"
+ * interface, does not contain the logic relevant to the interface methods. The specific functionality of the
+ * interface methods are intended to be implemented by the concrete class that extends this abstract class and
+ * utilizes the MQTT specific functionality (ideally a device API writer who would like to communicate to the device
+ * via MQTT Protocol).
+ *
+ * This class contains the Device-Management specific implementation for all the MQTT functionality. This includes
+ * connecting to a MQTT Broker & subscribing to the appropriate MQTT-topic, action plan upon losing connection or
+ * successfully delivering a message to the broker and upon receiving a MQTT message. Makes use of the 'Paho-MQTT'
+ * library provided by Eclipse Org.
+ */
+public abstract class MQTTTransportHandler implements MqttCallback, TransportHandler {
+ private static final String TAG = "MQTTTransportHandler";
+
+ private MqttClient client;
+ private String clientId;
+ private MqttConnectOptions options; // options to be set to the client-connection.
+ // topic to which a will-message is automatically published by the broker upon the device losing its connection.
+ private String clientWillTopic;
+
+ protected String mqttBrokerEndPoint;
+ protected int timeoutInterval; // interval to use for reconnection attempts etc.
+ protected String subscribeTopic;
+
+ // Quality of Service Levels for MQTT Subscription and Publishing.
+ public static final int QoS_0 = 0; // At-Most Once
+ @SuppressWarnings("unused")
+ public static final int QoS_1 = 1; // At-Least Once
+ public static final int QoS_2 = 2; // Exactly Once
+
+ public static final int DEFAULT_MQTT_QUALITY_OF_SERVICE = QoS_0;
+ // Prefix to the Will-Topic to which a message is published if client loses its connection.
+ private static final String DISCONNECTION_WILL_TOPIC_PREFIX = "Disconnection/";
+ // Will-Message of the client to be published if connection is lost.
+ private static final String DISCONNECTION_WILL_MSG = "Lost-Connection";
+ /**
+ * Constructor for the MQTTTransportHandler which takes in the owner, type of the device and the MQTT Broker URL
+ * and the topic to subscribe.
+ * @param context activity context.
+ */
+ protected MQTTTransportHandler(Context context) {
+ String username = LocalRegistry.getUsername(context);
+ String deviceId = LocalRegistry.getDeviceId(context);
+ this.clientId = deviceId + ":" + SenseConstants.DEVICE_TYPE;
+ this.subscribeTopic = "wso2/" + SenseConstants.DEVICE_TYPE + "/" + deviceId + "/command/#";
+ this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + SenseConstants.DEVICE_TYPE;
+ this.mqttBrokerEndPoint = "tcp://" + LocalRegistry.getServerHost(context) + ":" + LocalRegistry.getMqttPort(context);
+ this.timeoutInterval = DEFAULT_TIMEOUT_INTERVAL;
+ setUsernameAndPassword(LocalRegistry.getAccessToken(context), "");
+ this.initMQTTClient();
+ }
+
+ /**
+ * Constructor for the MQTTTransportHandler which takes in the owner, type of the device and the MQTT Broker URL
+ * and the topic to subscribe. Additionally this constructor takes in the reconnection-time interval between
+ * successive attempts to connect to the broker.
+ *
+ * @param deviceOwner the owner of the device.
+ * @param deviceType the CDMF Device-Type of the device.
+ * @param mqttBrokerEndPoint the IP/URL of the MQTT broker endpoint.
+ * @param subscribeTopic the MQTT topic to which the client is to be subscribed
+ * @param intervalInMillis the time interval in MILLI-SECONDS between attempts to connect to the broker.
+ */
+ protected MQTTTransportHandler(String deviceOwner, String deviceType,
+ String mqttBrokerEndPoint, String subscribeTopic, int intervalInMillis) {
+ this.clientId = deviceOwner + ":" + deviceType;
+ this.subscribeTopic = subscribeTopic;
+ this.clientWillTopic = DISCONNECTION_WILL_TOPIC_PREFIX + deviceType;
+ this.mqttBrokerEndPoint = mqttBrokerEndPoint;
+ this.timeoutInterval = intervalInMillis;
+ this.initMQTTClient();
+ }
+
+
+ /**
+ * Initializes the MQTT-Client. Creates a client using the given MQTT-broker endpoint and the clientId (which is
+ * constructed by a concatenation of [deviceOwner]:[deviceType]). Also sets the client's options parameter with
+ * the clientWillTopic (in-case of connection failure) and other info. Also sets the callback to this current class.
+ */
+ private void initMQTTClient() {
+ try {
+ client = new MqttClient(this.mqttBrokerEndPoint, clientId, null);
+ Log.i(TAG, "MQTT client was created with ClientID : " + clientId);
+ } catch (MqttException ex) {
+ String errorMsg = "Initializing the MQTT Client failed.";
+ Log.e(TAG, errorMsg, ex);
+ }
+
+ options = new MqttConnectOptions();
+ options.setKeepAliveInterval(120); // set the keep alive interval to 120 seconds by default.
+ options.setCleanSession(true); // sets clean session to true by default.
+ setDisconnectionWillForClient(QoS_2, true); // sets default will-topic & msg with QoS 2 and retained true.
+ client.setCallback(this); // callback for MQTT events are set to `this` object.
+ }
+
+ /**
+ * @param qos the Quality of Service at which the last-will-message is to be published.
+ * @param isRetained indicate whether to retain the last-will-message.
+ * @see MQTTTransportHandler#setDisconnectionWillForClient(String, String, int, boolean). Uses the default values
+ * for Will-Topic and Will-Message.
+ */
+ protected void setDisconnectionWillForClient(int qos, boolean isRetained) {
+ this.setDisconnectionWillForClient(clientWillTopic, DISCONNECTION_WILL_MSG, qos, isRetained);
+ }
+
+ /**
+ * Sets the [Will] option in the default options-set of the MQTT Client. A will-topic, will-message is parsed
+ * along with the QoS and the retained flag. When the client loses its connection to the broker, the broker
+ * publishes the will-message to the will-topic, to itself.
+ *
+ * @param willTopic the topic to which the last will message is to be published when client exists ungracefully.
+ * @param willMsg the message to be published upon client's ungraceful exit from the broker.
+ * @param qos the Quality of Service at which the last-will-message is to be published.
+ * @param isRetained indicate whether to retain the last-will-message.
+ */
+ protected void setDisconnectionWillForClient(String willTopic, String willMsg, int qos, boolean isRetained) {
+ this.options.setWill(willTopic, willMsg.getBytes(StandardCharsets.UTF_8), qos, isRetained);
+ }
+
+ /**
+ * Sets the [Clean-Session] option in the default options-set of the MQTT Client. It is set to `true` by default.
+ *
+ * @param setCleanSession `true` indicates that the session details can be cleared/cleaned upon disconnection,
+ * `false` indicates that the session details are to be persisted if the client disconnects.
+ */
+ @SuppressWarnings("unused")
+ protected void setClientCleanSession(boolean setCleanSession) {
+ this.options.setCleanSession(setCleanSession);
+ }
+
+ /**
+ * Sets the [Username] & [Password] options in the default options-set of the MQTT Client. By default these
+ * values are not set.
+ *
+ * @param username the username to be used by the client to connect to the broker.
+ * @param password the password to be used by the client to connect to the broker.
+ */
+ @SuppressWarnings("unused")
+ protected void setUsernameAndPassword(String username, String password) {
+ this.options.setUserName(username);
+ this.options.setPassword(password.toCharArray());
+ }
+
+ /**
+ * Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using default the
+ * MQTT-options.
+ *
+ * @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
+ */
+ protected void connectToQueue() throws TransportHandlerException {
+ this.connectToQueue(options);
+ }
+
+ /**
+ * Connects to the MQTT-Broker at the endpoint specified in the constructor to this class using the MQTT-Options
+ * passed.
+ *
+ * @param options options to be used by the client for this connection. (username, password, clean-session, etc)
+ * @throws TransportHandlerException in the event of 'Connecting to' the MQTT broker fails.
+ */
+ protected void connectToQueue(MqttConnectOptions options) throws TransportHandlerException {
+ try {
+ client.connect(options);
+ Log.d(TAG, "MQTT Client connected to queue at: " + this.mqttBrokerEndPoint);
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Exception occured whilst connecting to queue at [" + this.mqttBrokerEndPoint + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails.
+ * @see MQTTTransportHandler#subscribeToQueue(int). Uses default QoS of 1.
+ */
+ protected void subscribeToQueue() throws TransportHandlerException {
+ this.subscribeToQueue(QoS_0);
+ }
+
+ /**
+ * Subscribes to the MQTT-Topic specified in the constructor to this class.
+ *
+ * @throws TransportHandlerException in the event of 'Subscribing to' the MQTT broker fails.
+ */
+ protected void subscribeToQueue(int qos) throws TransportHandlerException {
+ try {
+ client.subscribe(subscribeTopic, qos);
+ Log.d(TAG, "Client [" + clientId + "] subscribed to topic: " + subscribeTopic);
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Exception occurred whilst client [" + clientId + "] tried to subscribe to " +
+ "topic: [" + subscribeTopic + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * @param topic the topic to which the message is to be published.
+ * @param payLoad the message (payload) of the MQTT publish action.
+ * @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
+ */
+ @SuppressWarnings("unused")
+ protected void publishToQueue(String topic, String payLoad) throws TransportHandlerException {
+ publishToQueue(topic, payLoad, DEFAULT_MQTT_QUALITY_OF_SERVICE, false);
+ }
+
+ /**
+ * @param topic the topic to which the message is to be published.
+ * @param message the message (payload) of the MQTT publish action as a `MQTTMessage`.
+ * @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue.
+ * @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
+ */
+ protected void publishToQueue(String topic, MqttMessage message) throws TransportHandlerException {
+ try {
+ client.publish(topic, message);
+ Log.d(TAG, "Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
+ "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * This method is used to publish messages to the MQTT-Endpoint to which this client is connected to. It is via
+ * publishing to this broker that the messages are communicated to the device. This is an overloaded method with
+ * different parameter combinations. This method invokes the publish method provided by the MQTT-Client library.
+ *
+ * @param topic the topic to which the message is to be published.
+ * @param payLoad the message (payload) of the MQTT publish action.
+ * @param qos the Quality-of-Service of the current publish action.
+ * Could be 0(At-most once), 1(At-least once) or 2(Exactly once)
+ * @param retained indicate whether to retain the publish-message in the event of no subscribers.
+ * @throws TransportHandlerException if any error occurs whilst trying to publish to the MQTT Queue.
+ */
+ protected void publishToQueue(String topic, String payLoad, int qos, boolean retained)
+ throws TransportHandlerException {
+ try {
+ client.publish(topic, payLoad.getBytes(StandardCharsets.UTF_8), qos, retained);
+ Log.d(TAG, "Message: " + payLoad + " to MQTT topic [" + topic + "] published successfully");
+
+ } catch (MqttException ex) {
+ String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
+ "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
+ Log.e(TAG, errorMsg);
+ throw new TransportHandlerException(errorMsg, ex);
+ }
+ }
+
+ /**
+ * Checks whether the connection to the MQTT-Broker exists.
+ *
+ * @return `true` if the client is connected to the MQTT-Broker, else `false`.
+ */
+ @Override
+ public boolean isConnected() {
+ return client.isConnected();
+ }
+
+ /**
+ * Callback method which is triggered once the MQTT client losers its connection to the broker. Spawns a new
+ * thread that executes necessary actions to try and reconnect to the endpoint.
+ *
+ * @param throwable a Throwable Object containing the details as to why the failure occurred.
+ */
+ @Override
+ public void connectionLost(Throwable throwable) {
+ Log.w(TAG, "Connection for client: " + this.clientId + " to " + this.mqttBrokerEndPoint + " was lost." +
+ "\nThis was due to - " + throwable.getMessage());
+ Thread reconnectThread = new Thread() {
+ public void run() {
+ connect();
+ }
+ };
+ reconnectThread.setDaemon(true);
+ reconnectThread.start();
+ }
+
+ /**
+ * Callback method which is triggered upon receiving a MQTT Message from the broker. Spawns a new thread that
+ * executes any actions to be taken with the received message.
+ *
+ * @param topic the MQTT-Topic to which the received message was published to and the client subscribed to.
+ * @param mqttMessage the actual MQTT-Message that was received from the broker.
+ */
+ @Override
+ public void messageArrived(final String topic, final MqttMessage mqttMessage) {
+ Log.d(TAG, "Got an MQTT message '" + mqttMessage.toString() + "' for topic '" + topic + "'.");
+
+ Thread messageProcessorThread = new Thread() {
+ public void run() {
+ try {
+ processIncomingMessage(mqttMessage, topic);
+ } catch (TransportHandlerException e) {
+ Log.e(TAG, "An error occurred when trying to process received MQTT message [" + mqttMessage + "] " +
+ "for topic [" + topic + "].", e);
+ }
+ }
+ };
+ messageProcessorThread.setDaemon(true);
+ messageProcessorThread.start();
+ }
+
+ /**
+ * Callback method which gets triggered upon successful completion of a message delivery to the broker.
+ *
+ * @param iMqttDeliveryToken the MQTT-DeliveryToken which includes the details about the specific message delivery.
+ */
+ @Override
+ public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
+ String topic = iMqttDeliveryToken.getTopics()[0];
+ String client = iMqttDeliveryToken.getClient().getClientId();
+
+ try {
+ if (iMqttDeliveryToken.isComplete()) {
+ if (iMqttDeliveryToken.getMessage() != null) {
+ String message = iMqttDeliveryToken.getMessage().toString();
+ Log.d(TAG, "Message to client [" + client + "] under topic (" + topic +
+ ") was delivered successfully with the delivery message: '" + message + "'");
+ } else {
+ Log.d(TAG, "Message to client [" + client + "] under topic (" + topic +
+ ") was delivered successfully.");
+ }
+ } else {
+ Log.w(TAG, "FAILED: Delivery of MQTT message to [" + client + "] under topic [" + topic + "] failed.");
+ }
+ } catch (MqttException e) {
+ Log.w(TAG, "Error occurred whilst trying to read the message from the MQTT delivery token.");
+ }
+ }
+
+ /**
+ * Closes the connection to the MQTT Broker.
+ */
+ public void closeConnection() throws MqttException {
+ if (client != null && isConnected()) {
+ client.disconnect();
+ }
+ }
+
+ /**
+ * Fetches the default options set for the MQTT Client
+ *
+ * @return the options that are currently set for the client.
+ */
+ public MqttConnectOptions getOptions() {
+ return options;
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandler.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandler.java
new file mode 100644
index 0000000000..88efba9a48
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandler.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+
+package org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport;
+
+/**
+ * This interface consists of the core functionality related to the transport between any device and the server. The
+ * interface is an abstraction, regardless of the underlying protocol used for the transport. Implementation of this
+ * interface by any class that caters a specific protocol (ex: HTTP, XMPP, MQTT, CoAP) would ideally have methods
+ * specific to the protocol used for communication and other methods that implement the logic related to the devices
+ * using the protocol. The methods of the interface are identified as generic ones for implementing transport
+ * protocols for device communication. The implementation can utilize the appropriate method signatures applicable for
+ * intended protocol.
+ *
+ * @param an object of the message type specific to the protocol implemented. To be set to 'String' if there
+ * isn't anything specific.
+ */
+public interface TransportHandler {
+ // a default timeout interval to be used for the protocol specific connections
+ int DEFAULT_TIMEOUT_INTERVAL = 5000; // millis ~ 5 sec
+
+ /**
+ * Implements the underlying connect mechanism specific to the protocol enabled by the interface. An object of a
+ * class that implements this interface would call this method before any communication is started via the
+ * intended protocol.
+ */
+ void connect();
+
+ /**
+ * Used to check whether a connection (via the implemented protocol) to the external-endpoint exists. Ideally
+ * used to verify that the connection persists and to spawn a reconnection attempt if not.
+ *
+ * @return 'true' if connection is already made & exists, else 'false'.
+ */
+ boolean isConnected();
+
+ /**
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message.
+ * @see TransportHandler#processIncomingMessage(Object, String...)
+ */
+ void processIncomingMessage() throws TransportHandlerException;
+
+ /**
+ * @param message the message (of the type specific to the protocol) received from the device.
+ * @throws TransportHandlerException
+ * @see TransportHandler#processIncomingMessage(Object, String...)
+ */
+ void processIncomingMessage(T message) throws TransportHandlerException;
+
+ /**
+ * This is an overloaded method with three different method-signatures. This method is used to process any
+ * incoming messages via the implemented protocol. It would ideally be invoked at a point where a message
+ * received event is activated (Ex: `MessageArrived` callback in Eclipse-Paho-MQTT Client & `PacketListener`(s)
+ * in XMPP).
+ *
+ *
+ * @param message the message (of the type specific to the protocol) received from the device.
+ * @param messageParams one or more other parameters received as part-of & relevant-to the message (Ex: MQTT Topic).
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst processing the message.
+ */
+ void processIncomingMessage(T message, String... messageParams) throws TransportHandlerException;
+
+ /**
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
+ * @see TransportHandler#publishDeviceData(String...)
+ */
+ void publishDeviceData() throws TransportHandlerException;
+
+ /**
+ * @param publishData the message (of the type specific to the protocol) to be sent to the device.
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
+ * @see TransportHandler#publishDeviceData(String...)
+ */
+ void publishDeviceData(T publishData) throws TransportHandlerException;
+
+ /**
+ * This is an overloaded method with three different method-signatures. This method is used to publish messages
+ * to an external-endpoint/device via the implemented protocol. It could in itself call the (communicating)
+ * external-endpoint or invoke any method provided by the protocol specific library.
+ *
+ *
+ * @param publishData one or more parameters specific to the message and the data to be sent.
+ * @throws TransportHandlerException in the event of any exceptions that occur whilst sending the message.
+ */
+ void publishDeviceData(String... publishData) throws TransportHandlerException;
+
+ /**
+ * Implements the underlying disconnect mechanism specific to the protocol enabled by the interface. An object of a
+ * class that implements this interface would call this method upon completion of all communication. In the case of
+ * the IoT-Server invoking this would only be required if the server shuts-down.
+ */
+ void disconnect();
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandlerException.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandlerException.java
new file mode 100644
index 0000000000..fe297b8284
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/data/publisher/mqtt/transport/TransportHandlerException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+
+package org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport;
+
+/**
+ * This exception will be thrown when the mqtt transport fails.
+ */
+public class TransportHandlerException extends Exception {
+ private static final long serialVersionUID = 2736466230451105440L;
+
+ private String errorMessage;
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public TransportHandlerException(String msg, Exception nestedEx) {
+ super(msg, nestedEx);
+ setErrorMessage(msg);
+ }
+
+ public TransportHandlerException(String message, Throwable cause) {
+ super(message, cause);
+ setErrorMessage(message);
+ }
+
+ public TransportHandlerException(String msg) {
+ super(msg);
+ setErrorMessage(msg);
+ }
+
+ public TransportHandlerException() {
+ super();
+ }
+
+ public TransportHandlerException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseScheduleReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseScheduleReceiver.java
new file mode 100644
index 0000000000..41ff9feffa
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseScheduleReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.event;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Calendar;
+
+/**
+ * This is a service which triggers to collect
+ */
+public class SenseScheduleReceiver extends BroadcastReceiver {
+ private static final int ALARM_INTERVAL = 5000;
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ Intent i = new Intent(context, SenseService.class);
+ PendingIntent pending = PendingIntent.getService(context, 0, i, 0);
+
+ Calendar cal = Calendar.getInstance();
+
+ cal.add(Calendar.SECOND, 30);
+ service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), ALARM_INTERVAL, pending);
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java
new file mode 100644
index 0000000000..69285234f7
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/SenseService.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.event;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import org.wso2.carbon.iot.android.sense.event.streams.SenseDataCollector;
+import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryDataReceiver;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+import org.wso2.carbon.iot.android.sense.util.SenseWakeLock;
+
+/**
+ * This service caters to initiate the data collection.
+ */
+public class SenseService extends Service {
+
+ public static Context context;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ SenseWakeLock.acquireWakeLock(this);
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ context = this;
+ if (!LocalRegistry.isExist(context)) return Service.START_NOT_STICKY;
+ //Below triggers the data collection for sensors,location and battery.
+ SenseDataCollector Sensor = new SenseDataCollector(this, SenseDataCollector.DataType.SENSOR);
+ SenseDataCollector Location = new SenseDataCollector(this, SenseDataCollector.DataType.LOCATION);
+ registerReceiver(new BatteryDataReceiver(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+ //service will not be stopped until we manually stop the service
+ return Service.START_NOT_STICKY;
+
+ }
+
+ @Override
+ public void onDestroy() {
+ SenseWakeLock.releaseCPUWakeLock();
+ super.onDestroy();
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/DataReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/DataReader.java
new file mode 100644
index 0000000000..1d8e422044
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/DataReader.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.event.streams;
+
+/**
+ * this class extended by each data reader implementation, where the data store logic is implemented in thread.
+ */
+public abstract class DataReader implements Runnable {
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationData.java
new file mode 100644
index 0000000000..3f5de2888f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationData.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.event.streams.Location;
+
+import java.util.Date;
+
+/**
+ * This defines the data structure of the location data that is been collected.
+ */
+public class LocationData {
+ private double latitude; // latitude
+ private double longitude; // longitude
+ private long timestamp;
+
+ LocationData(double latitude, double longitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ timestamp = new Date().getTime();
+
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ public long getTimeStamp() {
+ return timestamp;
+ }
+
+ public void setTimeStamp(long timeStamp) {
+ timestamp = timeStamp;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationDataReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationDataReader.java
new file mode 100644
index 0000000000..3504a12452
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Location/LocationDataReader.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.event.streams.Location;
+
+import android.content.Context;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.util.Log;
+import org.wso2.carbon.iot.android.sense.event.streams.DataReader;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This is used to retrieve the location data using GPS and used Network connection to increase the accuracy.
+ */
+public class LocationDataReader extends DataReader implements LocationListener {
+ protected LocationManager locationManager;
+ private Context mContext;
+ private boolean canGetLocation = false;
+ private static final String TAG = LocationDataReader.class.getName();
+
+ Location location; // location
+ double latitude; // latitude
+ double longitude; // longitude
+
+ public LocationDataReader(Context context) {
+ mContext = context;
+ getLocation();
+ }
+
+ public Location getLocation() {
+ locationManager = (LocationManager) mContext.getSystemService(mContext.LOCATION_SERVICE);
+
+ // getting GPS status
+ boolean isGPSEnabled = locationManager
+ .isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ // getting network status
+ boolean isNetworkEnabled = locationManager
+ .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
+
+ if (!isGPSEnabled && !isNetworkEnabled) {
+ // no network provider is enabled
+ } else {
+ this.canGetLocation = true;
+ // First get location from Network Provider
+ if (isNetworkEnabled) {
+ locationManager.requestLocationUpdates(
+ LocationManager.NETWORK_PROVIDER, 0, 0, this);
+ // MIN_TIME_BW_UPDATES,
+ // MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+
+ if (locationManager != null) {
+ location = locationManager
+ .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+ if (location != null) {
+ latitude = location.getLatitude();
+ longitude = location.getLongitude();
+ }
+ }
+ }
+ // if GPS Enabled get lat/long using GPS Services
+ if (isGPSEnabled) {
+ if (location == null) {
+ locationManager.requestLocationUpdates(
+ LocationManager.GPS_PROVIDER, 0, 0, this);
+ //MIN_TIME_BW_UPDATES,
+ //MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+
+ Log.d(TAG, "GPS Enabled");
+ if (locationManager != null) {
+ location = locationManager
+ .getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (location != null) {
+ latitude = location.getLatitude();
+ longitude = location.getLongitude();
+ }
+ }
+ }
+ }
+ }
+ return location;
+ }
+
+ public boolean canGetLocation() {
+ return this.canGetLocation;
+ }
+
+ public void stopUsingGPS() {
+ if (locationManager != null) {
+ locationManager.removeUpdates(LocationDataReader.this);
+ }
+ }
+
+ public double getLatitude() {
+ if (location != null) {
+ latitude = location.getLatitude();
+ }
+ // return latitude
+ return latitude;
+ }
+
+ /**
+ * Function to get longitude
+ */
+ public double getLongitude() {
+ if (location != null) {
+ longitude = location.getLongitude();
+ }
+ // return longitude
+ return longitude;
+ }
+
+ @Override
+ public void onLocationChanged(Location arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderDisabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderEnabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void run() {
+ Log.d(TAG, "running -Location");
+ try {
+ TimeUnit.MILLISECONDS.sleep(10000);
+ double lat = getLatitude();
+ double longit = getLongitude();
+ if (lat != 0 && longit != 0) {
+ SenseDataHolder.getLocationDataHolder().add(new LocationData(getLatitude(), getLongitude()));
+ }
+ } catch (InterruptedException e) {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+ Log.e(TAG, " Location Data Retrieval Failed");
+ }
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java
new file mode 100644
index 0000000000..2febb8ba20
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/SenseDataCollector.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.event.streams;
+
+import android.content.Context;
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationDataReader;
+import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorDataReader;
+
+/**
+ * This class triggered by service to collect the sensor data.
+ */
+public class SenseDataCollector {
+ public enum DataType {
+ SENSOR, LOCATION
+ }
+
+ public SenseDataCollector(Context ctx, DataType dt) {
+ DataReader dr = null;
+ switch (dt) {
+ case SENSOR:
+ dr = new SensorDataReader(ctx);
+ break;
+ case LOCATION:
+ dr = new LocationDataReader(ctx);
+ break;
+ }
+ if (dr != null) {
+ Thread DataCollector = new Thread(dr);
+ DataCollector.start();
+ }
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorData.java
new file mode 100644
index 0000000000..abdfeb1555
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorData.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.event.streams.Sensor;
+
+import android.hardware.SensorEvent;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+
+import java.util.Date;
+
+/**
+ * This defines the data structure of the sensor data that is been collected.
+ * look at http://developer.android.com/guide/topics/sensors/sensors_overview.html for field description.
+ */
+public class SensorData {
+ private int sensorType;
+ private String sensorName;
+ private String sensorVendor;
+ private float sensorValues[];
+ private int accuracyStatus;
+ private long timestamp;
+ private String collectTimestamp;
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ SensorData(SensorEvent event) {
+ sensorValues = event.values;
+ accuracyStatus = event.accuracy;
+ collectTimestamp = String.valueOf(event.timestamp);
+ timestamp = new Date().getTime();
+ sensorName = supportedSensors.getType(event.sensor.getType()).toUpperCase();
+ sensorVendor = event.sensor.getVendor();
+ sensorType = event.sensor.getType();
+ }
+
+ public int getSensorType() {
+ return sensorType;
+ }
+
+ public void setSensorType(int sensorType) {
+ this.sensorType = sensorType;
+ }
+
+ public String getSensorName() {
+ return sensorName;
+ }
+
+ public void setSensorName(String sensorName) {
+ this.sensorName = sensorName;
+ }
+
+ public String getSensorVendor() {
+ return sensorVendor;
+ }
+
+ public void setSensorVendor(String sensorVendor) {
+ this.sensorVendor = sensorVendor;
+ }
+
+ public float[] getSensorValues() {
+ return sensorValues;
+ }
+
+ public void setSensorValues(float sensorValues[]) {
+ this.sensorValues = sensorValues;
+ }
+
+ public int getAccuracyStatus() {
+ return accuracyStatus;
+ }
+
+ public void setAccuracyStatus(int accuracyStatus) {
+ this.accuracyStatus = accuracyStatus;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getCollectTimestamp() {
+ return collectTimestamp;
+ }
+
+ public void setCollectTimestamp(String collectTimestamp) {
+ this.collectTimestamp = collectTimestamp;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorDataReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorDataReader.java
new file mode 100644
index 0000000000..0c872eaa61
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/Sensor/SensorDataReader.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.event.streams.Sensor;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.event.streams.DataReader;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This is used to retrieve the sensor data.
+ */
+public class SensorDataReader extends DataReader implements SensorEventListener {
+ private SensorManager mSensorManager;
+ private Map senseDataStruct = new HashMap<>();
+ private Vector sensorVector = new Vector<>();
+ Context ctx;
+ private List sensorList = new ArrayList<>();
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+ private static final String TAG = SensorDataReader.class.getName();
+
+ public SensorDataReader(Context context) {
+ ctx = context;
+ SharedPreferences sharedPreferences = ctx.getSharedPreferences(SupportedSensors.SELECTED_SENSORS, Context
+ .MODE_MULTI_PROCESS);
+ Set selectedSet = sharedPreferences.getStringSet(SupportedSensors.SELECTED_SENSORS_BY_USER, null);
+ mSensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
+ selectedSensorList(selectedSet);
+ for (Sensor sensor : sensorList) {
+ mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ }
+
+ private void collectSensorData() {
+ for (Sensor sensor : sensorList) {
+ try {
+ if (senseDataStruct.containsKey(sensor.getName())) {
+ SensorData sensorInfo = senseDataStruct.get(sensor.getName());
+ sensorVector.add(sensorInfo);
+ Log.d(TAG, "Sensor Name " + sensor.getName() + ", Type " + sensor.getType() + " " +
+ ", sensorValue :" + sensorInfo.getSensorValues());
+ }
+ } catch (Throwable e) {
+ Log.d(TAG, "error on sensors");
+ }
+
+ }
+ mSensorManager.unregisterListener(this);
+ }
+
+ public Vector getSensorData() {
+ try {
+ TimeUnit.MILLISECONDS.sleep(1000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ Log.e(TAG, e.getMessage());
+ }
+ collectSensorData();
+ return sensorVector;
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ senseDataStruct.put(event.sensor.getName(), new SensorData(event));
+ }
+
+ @Override
+ public void run() {
+ Log.d(TAG, "running -sensorDataMap");
+ Vector sensorDatas = getSensorData();
+ for (SensorData data : sensorDatas) {
+ SenseDataHolder.getSensorDataHolder().add(data);
+ }
+ }
+
+ public void selectedSensorList(Set set) {
+ if (set != null) {
+ String[] sensorsSet = set.toArray(new String[set.size()]);
+ for (String s : sensorsSet) {
+ sensorList.add(mSensorManager.getDefaultSensor(supportedSensors.getType(s.toLowerCase())));
+ }
+ }
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryData.java
new file mode 100644
index 0000000000..666e02a85f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryData.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.event.streams.battery;
+
+import android.content.Intent;
+import android.os.BatteryManager;
+
+import java.util.Date;
+
+/**
+ * This defines the data structure of the battery data that is been collected.
+ * look at http://developer.android.com/reference/android/os/BatteryManager.html for field description.
+ */
+public class BatteryData {
+
+ private int health;
+ private int level;
+ private int plugged;
+ private int present;
+ private int scale;
+ private int status;
+ private int temperature;
+ private int voltage;
+ private long timestamp;
+
+ BatteryData(Intent intent) {
+ timestamp = new Date().getTime();
+ health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);
+ level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ present = intent.getExtras().getBoolean(BatteryManager.EXTRA_PRESENT) ? 1 : 0;
+ scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
+ status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);
+ String technology = intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY);
+ temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
+ voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
+
+ }
+
+ public int getHealth() {
+ return health;
+ }
+
+ public void setHealth(int health) {
+ this.health = health;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ public int getPlugged() {
+ return plugged;
+ }
+
+ public void setPlugged(int plugged) {
+ this.plugged = plugged;
+ }
+
+ public int getPresent() {
+ return present;
+ }
+
+ public void setPresent(int present) {
+ this.present = present;
+ }
+
+ public int getScale() {
+ return scale;
+ }
+
+ public void setScale(int scale) {
+ this.scale = scale;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public int getTemperature() {
+ return temperature;
+ }
+
+ public void setTemperature(int temperature) {
+ this.temperature = temperature;
+ }
+
+ public int getVoltage() {
+ return voltage;
+ }
+
+ public void setVoltage(int voltage) {
+ this.voltage = voltage;
+ }
+
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryDataReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryDataReceiver.java
new file mode 100644
index 0000000000..9fffa1c157
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/event/streams/battery/BatteryDataReceiver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.event.streams.battery;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+
+/**
+ * Whenever the battery level changes This receiver will be triggered.
+ */
+public class BatteryDataReceiver extends BroadcastReceiver {
+
+ /**
+ * when the data is retreived then its added to a inmemory map.
+ *
+ * @param context of the reciever.
+ * @param intent of the reciver
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ SenseDataHolder.getBatteryDataHolder().add(new BatteryData(intent));
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/ActivitySelectSensor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/ActivitySelectSensor.java
new file mode 100644
index 0000000000..053b7e38ce
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/ActivitySelectSensor.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.NavigationView;
+import android.support.design.widget.Snackbar;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.RegisterActivity;
+import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherReceiver;
+import org.wso2.carbon.iot.android.sense.data.publisher.DataPublisherService;
+import org.wso2.carbon.iot.android.sense.event.SenseScheduleReceiver;
+import org.wso2.carbon.iot.android.sense.event.SenseService;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.datastore.TempStore;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.RealTimeSensorChangeReceiver;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor.RealTimeSensorReader;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor.SensorViewAdaptor;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.sensor.selector.SelectSensorDialog;
+import org.wso2.carbon.iot.android.sense.speech.detector.WordRecognitionActivity;
+import org.wso2.carbon.iot.android.sense.util.LocalRegistry;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * Activity for selecting sensors available in the device
+ */
+
+public class ActivitySelectSensor extends AppCompatActivity
+ implements NavigationView.OnNavigationItemSelectedListener, SelectSensorDialog.SensorListListener {
+
+ private SharedPreferences sharedPreferences;
+ private SelectSensorDialog sensorDialog = new SelectSensorDialog();
+ private Set selectedSensorSet = new HashSet<>();
+ private ListView listView;
+ private SensorManager sensorManager;
+ private ArrayList sensors = new ArrayList<>();
+
+ private RealTimeSensorReader sensorReader = null;
+ private RealTimeSensorChangeReceiver realTimeSensorChangeReceiver = new RealTimeSensorChangeReceiver();
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_activity_select_sensor);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+ sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+
+ listView = (ListView) findViewById(R.id.senseListContainer);
+
+ registerReceiver(realTimeSensorChangeReceiver, new IntentFilter("sensorDataMap"));
+
+ //Publish data
+ FloatingActionButton fbtnPublishData = (FloatingActionButton) findViewById(R.id.publish);
+
+ fbtnPublishData.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Snackbar.make(view, "Publishing data started", Snackbar.LENGTH_LONG)
+ .setAction("Action", null).show();
+
+ DataPublisherReceiver dataPublisherReceiver = new DataPublisherReceiver();
+ dataPublisherReceiver.clearAbortBroadcast();
+ dataPublisherReceiver.onReceive(getApplicationContext(), null);
+ }
+ });
+
+ FloatingActionButton fbtnAddSensors = (FloatingActionButton) findViewById(R.id.addSensors);
+ fbtnAddSensors.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ sensorDialog.show(getFragmentManager(), "Sensor List");
+ }
+ });
+
+ FloatingActionButton fbtnSpeechRecongnizer = (FloatingActionButton) findViewById(R.id.speech);
+ fbtnSpeechRecongnizer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ EditText sessionIdText = (EditText) findViewById(R.id.sessionId);
+ String sessionId = sessionIdText.getText().toString();
+ if (!sessionId.isEmpty()) {
+ Intent intent = new Intent(getApplicationContext(), WordRecognitionActivity.class);
+ intent.putExtra("sessionId", sessionId);
+ startActivity(intent);
+ } else {
+ Toast.makeText(ActivitySelectSensor.this, "Please type a session id value", Toast.LENGTH_SHORT)
+ .show();
+ }
+
+ }
+ });
+
+ sharedPreferences = getSharedPreferences(SupportedSensors.SELECTED_SENSORS, 0);
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+ drawer.setDrawerListener(toggle);
+ toggle.syncState();
+
+ NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+ }
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.activity_select_sensor, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_deEnroll) {
+
+ /**
+ * unregister the sensors and broadcast receivers.
+ * */
+ unregisterSensors();
+ unregisterReceivers();
+
+ if (!LocalRegistry.isExist(getApplicationContext())) {
+ Intent activity = new Intent(getApplicationContext(), RegisterActivity.class);
+ startActivity(activity);
+ }
+
+ LocalRegistry.removeUsername(getApplicationContext());
+ LocalRegistry.removeDeviceId(getApplicationContext());
+ LocalRegistry.removeServerURL(getApplicationContext());
+ LocalRegistry.setExist(false);
+ //Stop the current running background services.
+ stopService(new Intent(this, SenseService.class)); //Stop sensor reading service
+ stopService(new Intent(this, DataPublisherService.class)); //Stop data uploader service
+
+ Intent registerActivity = new Intent(getApplicationContext(), RegisterActivity.class);
+ registerActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(registerActivity);
+ finish();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+ // Handle navigation view item clicks here.
+ int id = item.getItemId();
+
+ if (id == R.id.select) {
+ sensorDialog.show(getFragmentManager(), "Sensor List");
+ }
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+ return true;
+ }
+
+ @Override
+ public void onDialogPositiveClick(SelectSensorDialog dialog) {
+
+ Log.d("Selected sensors", dialog.getSet().toString());
+ selectedSensorSet = dialog.getSet();
+ update();
+ unregisterSensors();
+
+ SenseScheduleReceiver senseScheduleReceiver = new SenseScheduleReceiver();
+ senseScheduleReceiver.clearAbortBroadcast();
+ senseScheduleReceiver.onReceive(this, null);
+
+ /**
+ * Get the selected sensors
+ * Register them
+ * */
+ SensorViewAdaptor adaptor1 = new SensorViewAdaptor(getApplicationContext(), TempStore.sensorArrayList);
+ adaptor1.notifyDataSetChanged();
+
+ sensorReader = new RealTimeSensorReader(this, adaptor1);
+ getSensors();
+
+ for (Sensor s : sensors) {
+ sensorManager.registerListener(sensorReader, s, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ realTimeSensorChangeReceiver.updateOnChange(adaptor1);
+ listView.setAdapter(adaptor1);
+
+ }
+
+ public void update() {
+ Log.d("Update", "Set the values to Shared Preferences");
+
+ TempStore.sensorArrayList.clear();
+ TempStore.sensorDataMap.clear();
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putStringSet(SupportedSensors.SELECTED_SENSORS_BY_USER, selectedSensorSet);
+ editor.apply();
+ }
+
+ public void getSensors() {
+ sensors.clear();
+ for (String sensor : selectedSensorSet.toArray(new String[selectedSensorSet.size()])) {
+ sensors.add(sensorManager.getDefaultSensor(supportedSensors.getType(sensor.toLowerCase())));
+ }
+ }
+
+ /**
+ * This method will unregister all the registered sensors.
+ */
+ public void unregisterSensors() {
+ if (sensors.size() > 0) {
+ for (Sensor s : sensors) {
+ System.out.println(s.getName() + " Unregistered!");
+ sensorManager.unregisterListener(sensorReader, s);
+ }
+ }
+ }
+
+ /**
+ * This method unregisters the real-time broadcast receiver.
+ */
+ public void unregisterReceivers() {
+ unregisterReceiver(realTimeSensorChangeReceiver);
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/datastore/TempStore.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/datastore/TempStore.java
new file mode 100644
index 0000000000..2e53438347
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/datastore/TempStore.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.datastore;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor.RealTimeSensor;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Class to store the real time sensor readings.
+ */
+public class TempStore {
+
+ /**
+ * Hash map which is used to store sensor values with the sensor names.
+ */
+ public static ConcurrentMap sensorDataMap = new ConcurrentHashMap<>();
+
+ /**
+ * Array List which is used to populate the List view.
+ */
+ public static ArrayList sensorArrayList = new ArrayList<>();
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/RealTimeSensorChangeReceiver.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/RealTimeSensorChangeReceiver.java
new file mode 100644
index 0000000000..c231ac87ee
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/RealTimeSensorChangeReceiver.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.event;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.datastore.TempStore;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor.SensorViewAdaptor;
+
+/**
+ * This class is to detect the sensor change event and update the sensor array list.
+ * And update the view adaptor which is used to show the sensors list in the Android List view.
+ */
+public class RealTimeSensorChangeReceiver extends BroadcastReceiver {
+
+ SensorViewAdaptor adaptor;
+
+ public void updateOnChange(SensorViewAdaptor adaptor) {
+ this.adaptor = adaptor;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ TempStore.sensorArrayList.clear();
+ TempStore.sensorArrayList.addAll(TempStore.sensorDataMap.values());
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensor.java
new file mode 100644
index 0000000000..6a71739dc7
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensor.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor;
+
+import android.support.annotation.NonNull;
+
+/**
+ * The class to store the sensor data captured by the RealTimeSensorReader.
+ */
+public class RealTimeSensor implements Comparable {
+
+
+ /**
+ * Name of the sensor.
+ */
+ private String name;
+
+ /**
+ * The X value reading of the sensor.
+ */
+ private String valueX;
+
+ /**
+ * The Y value reading of the sensor.
+ */
+ private String valueY;
+
+ /**
+ * The Y value reading of the sensor.
+ */
+ private String valueZ;
+
+ public RealTimeSensor() {
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getValueX() {
+ return valueX;
+ }
+
+ public void setValueX(String valueX) {
+ this.valueX = valueX;
+ }
+
+ public String getValueY() {
+ return valueY;
+ }
+
+ public void setValueY(String valueY) {
+ this.valueY = valueY;
+ }
+
+ public String getValueZ() {
+ return valueZ;
+ }
+
+ public void setValueZ(String valueZ) {
+ this.valueZ = valueZ;
+ }
+
+ @Override
+ public String toString() {
+ return this.valueX + ", " + valueY + ", " + valueZ;
+ }
+
+ @Override
+ public int compareTo(@NonNull Object another) {
+ return this.toString().contains(another.toString()) ? 1 : 0;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensorReader.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensorReader.java
new file mode 100644
index 0000000000..fc4b474e65
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/event/realtimesensor/RealTimeSensorReader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor;
+
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.datastore.TempStore;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor.SensorViewAdaptor;
+
+/**
+ * This class reads the sensor values in real time.
+ */
+public class RealTimeSensorReader implements SensorEventListener {
+
+ private Context context;
+ private SensorViewAdaptor adaptor;
+ private SupportedSensors supportedSensors = SupportedSensors.getInstance();
+
+ public RealTimeSensorReader(Context context, SensorViewAdaptor adaptor) {
+ this.context = context;
+ this.adaptor = adaptor;
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ RealTimeSensor realTimeSensor = new RealTimeSensor();
+ realTimeSensor.setName(supportedSensors.getType(event.sensor.getType()).toUpperCase());
+
+ realTimeSensor.setValueX(event.values[0] + "");
+ realTimeSensor.setValueY(event.values[1] + "");
+ realTimeSensor.setValueZ(event.values[2] + "");
+
+ TempStore.sensorDataMap.put(supportedSensors.getType(event.sensor.getType()), realTimeSensor);
+
+ Intent intent = new Intent();
+ intent.setAction("sensorDataMap");
+ context.sendBroadcast(intent);
+
+ adaptor.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/AvailableSensorsInDevice.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/AvailableSensorsInDevice.java
new file mode 100644
index 0000000000..726c8cded2
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/AvailableSensorsInDevice.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Class to save the list of sensors that are available in the device, which are supported by the iot server.
+ * This list will be saved in Shared preferences so that app can use this data when needed.
+ */
+public class AvailableSensorsInDevice {
+
+ private SharedPreferences sensorPreference;
+
+ /**
+ * The Android sensor manager which is used to get the sensors available in device.
+ */
+ private SensorManager mSensorManager;
+
+ public AvailableSensorsInDevice(Context context) {
+ this.sensorPreference = context.getSharedPreferences(SupportedSensors.AVAILABLE_SENSORS, 0);
+ this.mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ }
+
+ /**
+ * This method filters the pre defined sensor types from sensors available in device and sets them in Shared
+ * preferences.
+ */
+ public void setContent() {
+ SupportedSensors supportedSensors = SupportedSensors.getInstance();
+ List sensor_List = supportedSensors.getSensorList();
+ Set sensorSet = new HashSet<>();
+ List sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+
+ for (String sen : sensor_List) {
+ if (sensors.contains(mSensorManager.getDefaultSensor(supportedSensors.getType(sen.toLowerCase())))) {
+ sensorSet.add(sen);
+ }
+ }
+
+ SharedPreferences.Editor editor = this.sensorPreference.edit();
+ editor.putStringSet(SupportedSensors.GET_AVAILABLE_SENSORS, sensorSet);
+ editor.apply();
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java
new file mode 100644
index 0000000000..6d57e6d704
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/sensorlisting/SupportedSensors.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting;
+
+import android.hardware.Sensor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Class to store the supported sensorDataMap types.
+ */
+public class SupportedSensors {
+
+ //For set user selected sensors. Will be used by sensorDataMap reading and dialog
+ public static String SELECTED_SENSORS = "Selected";
+ public static String SELECTED_SENSORS_BY_USER = "userSelection";
+
+ //For setting the available sensors in the device in dialog and AvailableSensorsInDevice
+ public static String AVAILABLE_SENSORS = "Sensors";
+ public static String GET_AVAILABLE_SENSORS = "getAvailableSensors";
+
+ public static final int SUPPORTED_SENSOR_COUNT = 10;
+ private static List sensorList = new ArrayList<>();
+ private static HashMap sensorTypeMap = new HashMap<>();
+ private static HashMap typeSensorMap = new HashMap<>();
+ private static SupportedSensors supportedSensors = new SupportedSensors();
+
+ private SupportedSensors() {
+ this.setList();
+ this.setSensorTypeMap();
+ this.setTypeSensorMap();
+ }
+
+ public static SupportedSensors getInstance() {
+ return supportedSensors;
+ }
+
+ /**
+ * Set the supported sensor types by the IOT server.
+ */
+ private void setList() {
+ sensorList.add("Accelerometer");
+ sensorList.add("Magnetometer");
+ sensorList.add("Gravity");
+ sensorList.add("Rotation Vector");
+ sensorList.add("Pressure");
+ sensorList.add("Light");
+ sensorList.add("Gyroscope");
+ sensorList.add("Proximity");
+ }
+
+ /**
+ * Populate the hash map which has Sensor name as the key and the sensor type as the value.
+ */
+ private void setSensorTypeMap() {
+ sensorTypeMap.put("accelerometer", Sensor.TYPE_ACCELEROMETER);
+ sensorTypeMap.put("magnetometer", Sensor.TYPE_MAGNETIC_FIELD);
+ sensorTypeMap.put("gravity", Sensor.TYPE_GRAVITY);
+ sensorTypeMap.put("rotation vector", Sensor.TYPE_GAME_ROTATION_VECTOR);
+ sensorTypeMap.put("pressure", Sensor.TYPE_PRESSURE);
+ sensorTypeMap.put("gyroscope", Sensor.TYPE_GYROSCOPE);
+ sensorTypeMap.put("light", Sensor.TYPE_LIGHT);
+ sensorTypeMap.put("proximity", Sensor.TYPE_PROXIMITY);
+ }
+
+ /**
+ * Populates the hash map which has Sensor type as the key and sensor name as the value.
+ */
+ private void setTypeSensorMap() {
+ typeSensorMap.put(Sensor.TYPE_ACCELEROMETER, "accelerometer");
+ typeSensorMap.put(Sensor.TYPE_MAGNETIC_FIELD, "magnetometer");
+ typeSensorMap.put(Sensor.TYPE_GRAVITY, "gravity");
+ typeSensorMap.put(Sensor.TYPE_GAME_ROTATION_VECTOR, "rotation vector");
+ typeSensorMap.put(Sensor.TYPE_PRESSURE, "pressure");
+ typeSensorMap.put(Sensor.TYPE_GYROSCOPE, "gyroscope");
+ typeSensorMap.put(Sensor.TYPE_LIGHT, "light");
+ typeSensorMap.put(Sensor.TYPE_PROXIMITY, "proximity");
+ }
+
+ /**
+ * Method to get the supported sensor list.
+ *
+ * @return the list of sensors supported by the iot server.
+ */
+ public List getSensorList() {
+ return sensorList;
+ }
+
+
+ /**
+ * @param sensor The name of the sensor.
+ * @return The integer representing the type of the sensor,
+ */
+ public int getType(String sensor) {
+ return sensorTypeMap.get(sensor);
+ }
+
+
+ /**
+ * @param type The type of the sensor.
+ * @return The sensor name related to the given sensor type.
+ */
+ public String getType(int type) {
+ return typeSensorMap.get(type);
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/adaptor/SensorViewAdaptor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/adaptor/SensorViewAdaptor.java
new file mode 100644
index 0000000000..77f3f710c7
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/adaptor/SensorViewAdaptor.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.view.adaptor;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.event.realtimesensor.RealTimeSensor;
+
+import java.util.List;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * Adaptor for populate the ListView.
+ * Takes list of Sensor readings
+ */
+public class SensorViewAdaptor extends BaseAdapter {
+
+ private Context context;
+ private List data;
+
+ public SensorViewAdaptor(Context context, List data) {
+ this.context = context;
+ this.data = data;
+ }
+
+ @Override
+ public int getCount() {
+ return data.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return data.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View view;
+
+ if (convertView == null) {
+ view = inflater.inflate(R.layout.display_sensor_values, parent, false);
+ holder = new ViewHolder();
+ holder.name = (TextView) view.findViewById(R.id.name);
+ holder.valuesX = (TextView) view.findViewById(R.id.X);
+ holder.valuesY = (TextView) view.findViewById(R.id.Y);
+ holder.valuesZ = (TextView) view.findViewById(R.id.Z);
+ view.setTag(holder);
+ } else {
+ view = convertView;
+ holder = (ViewHolder) view.getTag();
+ }
+
+ RealTimeSensor data = this.data.get(position);
+
+ holder.name.setText(data.getName());
+ holder.valuesX.setText(data.getValueX());
+ holder.valuesY.setText(data.getValueY());
+ holder.valuesZ.setText(data.getValueZ());
+
+ return view;
+
+ }
+
+ private class ViewHolder {
+ public TextView name;
+ public TextView valuesX;
+ public TextView valuesY;
+ public TextView valuesZ;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/sensor/selector/SelectSensorDialog.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/sensor/selector/SelectSensorDialog.java
new file mode 100644
index 0000000000..5c163c8021
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/realtimeviewer/view/sensor/selector/SelectSensorDialog.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.realtimeviewer.view.sensor.selector;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.realtimeviewer.sensorlisting.SupportedSensors;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Functionality
+ *
+ * Show the list of available sensors in a list
+ * Get the user selections
+ * Put them in to shared preferences
+ */
+
+public class SelectSensorDialog extends DialogFragment {
+
+ protected boolean[] selections = new boolean[SupportedSensors.SUPPORTED_SENSOR_COUNT];
+ Activity activity;
+ SensorListListener sensorListListener;
+ private Set selectedSensorSet = new HashSet<>();
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle("Select Sensors");
+ activity = getActivity();
+
+ SharedPreferences preferences = getActivity().getSharedPreferences(SupportedSensors.AVAILABLE_SENSORS, Context.
+ MODE_MULTI_PROCESS);
+
+ Set set = preferences.getStringSet(SupportedSensors.GET_AVAILABLE_SENSORS, null);
+ final CharSequence[] sequence = getSequence(set);
+
+ final boolean[] pos = new boolean[selections.length];
+ final boolean[] neg = new boolean[selections.length];
+
+ builder.setMultiChoiceItems(sequence, selections, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ if (isChecked) {
+ selectedSensorSet.add(sequence[which].toString());
+
+ pos[which] = true;
+ } else {
+ selectedSensorSet.remove(sequence[which].toString());
+ neg[which] = true;
+ }
+ }
+ });
+
+ builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Log.d("Click", "Ok");
+ //call sensorDataMap reading class
+ sensorListListener.onDialogPositiveClick(SelectSensorDialog.this);
+
+ }
+ });
+
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Log.d("Click", "Cancel");
+ for (int i = 0; i < SupportedSensors.SUPPORTED_SENSOR_COUNT; i++) {
+
+ if (pos[i])
+ selections[i] = false;
+ if (neg[i])
+ selections[i] = true;
+ }
+ }
+ });
+
+ return builder.create();
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ try {
+ sensorListListener = (SensorListListener) getActivity();
+ } catch (ClassCastException ex) {
+ throw new ClassCastException(activity.toString() + " must implement the SensorListener");
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ /**
+ * Interface to be implemented by the parent
+ */
+ public CharSequence[] getSequence(Set sensorset) {
+ CharSequence[] seq;
+ String[] seq2 = sensorset.toArray(new String[sensorset.size()]);
+ seq = Arrays.copyOf(seq2, seq2.length);
+ return seq;
+ }
+
+ public Set getSet() {
+ return this.selectedSensorSet;
+ }
+
+ public interface SensorListListener {
+ void onDialogPositiveClick(SelectSensorDialog dialog);
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/IVoiceControl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/IVoiceControl.java
new file mode 100644
index 0000000000..83b702d456
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/IVoiceControl.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector;
+
+/**
+ * This interface is used to retrieve the voice commands and restart the listenting service
+ */
+public interface IVoiceControl {
+ /**
+ * This will be executed when a voice command was found
+ * @param voiceCommands
+ */
+ public abstract void processVoiceCommands(String... voiceCommands);
+
+ /**
+ * This will be executed after a voice command was processed to keep the recognition service activated
+ */
+ public void restartListeningService();
+
+ public void finish();
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/WordRecognitionActivity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/WordRecognitionActivity.java
new file mode 100644
index 0000000000..a3521f9caf
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/WordRecognitionActivity.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.realtimeviewer.ActivitySelectSensor;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ListeningActivity;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.ProcessWords;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.VoiceRecognitionListener;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * This is main activity for word recognition.
+ */
+public class WordRecognitionActivity extends ListeningActivity {
+ Button setThreasholdButton;
+ Button addWordButton;
+ Button removeWordButton;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_speech_sense_main);
+ context = getApplicationContext(); // Needs to be set
+
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ VoiceRecognitionListener.getInstance().setListener(this); // Here we set the current listener
+ addListenerOnSetThreasholdButton();
+ addListenerOnAddWordButton();
+ addListenerOnRemoveWordButton();
+ String sessionId = getIntent().getStringExtra("sessionId");
+ ProcessWords.setSessionId(sessionId);
+ FloatingActionButton fbtnSpeechRecongnizer = (FloatingActionButton) findViewById(R.id.sensorChange);
+ fbtnSpeechRecongnizer.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ WordData wordData = new WordData(ProcessWords.getSessionId(), SenseConstants.EVENT_LISTENER_FINISHED, 1);
+ SenseDataHolder.getWordDataHolder().add(wordData);
+ stopListening();
+ Intent intent = new Intent(getApplicationContext(), ActivitySelectSensor.class);
+ startActivity(intent);
+ }
+ });
+ Long tsLong = System.currentTimeMillis() / 1000;
+ WordData wordData = new WordData(sessionId, SenseConstants.EVENT_LISTENER_STARTED, 1);
+ SenseDataHolder.getWordDataHolder().add(wordData);
+ startListening(); // starts listening
+ }
+
+ @Override
+ public void onBackPressed() {
+ }
+
+ @Override
+ public void processVoiceCommands(String... voiceCommands) {
+ if(voiceCommands==null || voiceCommands.length==0){
+ return;
+ }
+ ProcessWords processWords = new ProcessWords(this);
+ processWords.execute(voiceCommands);
+ restartListeningService();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ // getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.action_deEnroll) {
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ public void addListenerOnSetThreasholdButton() {
+ setThreasholdButton = (Button) findViewById(R.id.setThreshold);
+ setThreasholdButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ String thresholdString = ((EditText) findViewById(R.id.editThreashold)).getText().toString();
+ try{
+ ProcessWords.setThreshold(Integer.parseInt(thresholdString));
+ } catch (NumberFormatException e) {
+ Toast.makeText(WordRecognitionActivity.this, "Invalid Threshold - " + thresholdString, Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ }
+
+ public void addListenerOnAddWordButton() {
+ addWordButton = (Button) findViewById(R.id.addWord);
+ addWordButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ String word = ((EditText) findViewById(R.id.wordText)).getText().toString();
+ ProcessWords.addWord(word);
+ Toast.makeText(WordRecognitionActivity.this, word + " is added to the list", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ public void addListenerOnRemoveWordButton() {
+ removeWordButton = (Button) findViewById(R.id.removeWord);
+ removeWordButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ String word = ((EditText) findViewById(R.id.wordText)).getText().toString();
+ Toast.makeText(WordRecognitionActivity.this, word + " is removed from the list", Toast.LENGTH_SHORT).show();
+ ProcessWords.removeWord(word);
+ }
+
+ });
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ListeningActivity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ListeningActivity.java
new file mode 100644
index 0000000000..db37583b58
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ListeningActivity.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.speech.RecognizerIntent;
+import android.speech.SpeechRecognizer;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.speech.detector.IVoiceControl;
+
+/**
+ * This Activity Contols the Speech Recognizer Activity.
+ */
+public abstract class ListeningActivity extends Activity implements IVoiceControl {
+
+ protected SpeechRecognizer sr;
+ protected Context context;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ /**
+ * Starts the listening service.
+ */
+ protected void startListening() {
+ initSpeech();
+ Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
+ sr.startListening(intent);
+ }
+
+ /**
+ * Stop the listening service.
+ */
+ protected void stopListening() {
+ if (sr != null) {
+ sr.stopListening();
+ sr.cancel();
+ sr.destroy();
+ }
+ sr = null;
+ }
+
+ /**
+ * Initialize the speech.
+ */
+ protected void initSpeech() {
+ if (sr == null) {
+ sr = SpeechRecognizer.createSpeechRecognizer(this);
+ if (!SpeechRecognizer.isRecognitionAvailable(context)) {
+ Toast.makeText(context, "Speech Recognition is not available",
+ Toast.LENGTH_LONG).show();
+ finish();
+ }
+ sr.setRecognitionListener(VoiceRecognitionListener.getInstance());
+ }
+ }
+
+ @Override
+ public void finish() {
+ stopListening();
+ super.finish();
+ }
+
+ @Override
+ protected void onStop() {
+ stopListening();
+ super.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (sr != null) {
+ sr.stopListening();
+ sr.cancel();
+ sr.destroy();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause() {
+ if(sr!=null){
+ sr.stopListening();
+ sr.cancel();
+ sr.destroy();
+
+ }
+ sr = null;
+
+ super.onPause();
+ }
+
+ /**
+ * Is abstract so the inheriting classes need to implement it. Here you put your code which should be executed once
+ * a command was found
+ */
+ @Override
+ public abstract void processVoiceCommands(String ... voiceCommands);
+
+ @Override
+ public void restartListeningService() {
+ stopListening();
+ startListening();
+ }
+}
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ProcessWords.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ProcessWords.java
new file mode 100644
index 0000000000..9933904a57
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/ProcessWords.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+import android.app.Activity;
+import android.os.AsyncTask;
+import android.widget.EditText;
+
+import org.apache.commons.codec.language.Soundex;
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationData;
+import org.wso2.carbon.iot.android.sense.util.SenseDataHolder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.tartarus.snowball.ext.englishStemmer;
+
+import agent.sense.android.iot.carbon.wso2.org.wso2_senseagent.R;
+
+/**
+ * This class process the words form required words with the recongnized words to check whether it matches with the
+ * certain threshold.
+ */
+public class ProcessWords extends AsyncTask {
+ private static volatile double threshold = 80;
+ private static volatile Map wordDataMap = new ConcurrentHashMap<>();
+ private static String sessionId = "default";
+ private static Soundex soundex = new Soundex();
+ Activity activity;
+
+ public ProcessWords(Activity activity) {
+ this.activity = activity;
+ }
+
+ /**
+ * Add the list of words which are used for reference.
+ * @param wordlist that needs to be looked upon in the speech
+ */
+ public static void addWords(List wordlist) {
+ for (String word : wordlist) {
+ if (!wordDataMap.keySet().contains(word) && !word.isEmpty()) {
+ wordDataMap.put(word, new WordData(sessionId, word, 0));
+ }
+ }
+ }
+
+ /**
+ * Process the recognized word list.
+ * @param voiceCommands word lists.
+ */
+ private void processTexts(String... voiceCommands) {
+ for (String requiredWord : wordDataMap.keySet()) {
+ int maxOccurunce = 0;
+ for (String command : voiceCommands) {
+ int occurence = 0;
+ for (String word : command.split(" ")) {
+ if (StringSimilarity.similarity(requiredWord, word) > threshold) {
+ occurence++;
+ continue;
+ }
+ if (soundex.encode(requiredWord).equals(soundex.encode(word))) {
+ occurence++;
+ continue;
+ }
+ if (StringSimilarity.similarity(requiredWord, stem(word)) > threshold) {
+ occurence++;
+ continue;
+ }
+ }
+ if (maxOccurunce < occurence) {
+ maxOccurunce = occurence;
+ }
+ }
+ if (maxOccurunce > 0) {
+ WordData wordData = wordDataMap.get(requiredWord);
+ wordData.addOccurences(maxOccurunce);
+ wordDataMap.put(requiredWord, wordData);
+ }
+ }
+ }
+
+ /**
+ * Check for distance between the referenced and recognized words.
+ * @param params
+ * @return
+ */
+ @Override
+ protected String doInBackground(String... params) {
+ processTexts(params);
+ publishProgress();
+ return "";
+ }
+
+ /**
+ * update it in the UI.
+ * @param values words list.
+ */
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ super.onProgressUpdate(values);
+ EditText content = (EditText) activity.findViewById(R.id.command);
+ String text = "";
+ for (String key : ProcessWords.wordDataMap.keySet()) {
+ text = text + key + " - " + ProcessWords.wordDataMap.get(key).getOccurences() + "\n";
+ }
+ content.setText(text);
+ EditText thresholdText = (EditText) activity.findViewById(R.id.editThreashold);
+ thresholdText.setText("" + threshold);
+ }
+
+ /**
+ * set the threshold to determine the distance.
+ * @param threshold to determine the distance.
+ */
+ public static synchronized void setThreshold(int threshold) {
+ ProcessWords.threshold = threshold;
+ }
+
+ /**
+ *
+ * @param sessionId for each listening session.
+ */
+ public static synchronized void setSessionId(String sessionId) {
+ ProcessWords.sessionId = sessionId;
+ }
+
+ /**
+ *
+ * retrieve sessionId for each listening session.
+ */
+ public static synchronized String getSessionId() {
+ return ProcessWords.sessionId;
+ }
+
+ /**
+ * @param word that is used for refrerence.
+ */
+ public static synchronized void addWord(String word) {
+ if (!wordDataMap.keySet().contains(word) && !word.isEmpty()) {
+ wordDataMap.put(word, new WordData(sessionId, word, 0));
+ }
+ }
+
+ /**
+ *
+ * @param word that needs to be removed from the reference list.
+ */
+ public static synchronized void removeWord(String word) {
+ cleanAndPushToWordMap();
+ wordDataMap.remove(word);
+ }
+
+ /**
+ * clean in memory content and pubish it to the server.
+ */
+ public static synchronized void cleanAndPushToWordMap() {
+ for (String word : wordDataMap.keySet()) {
+ WordData wordData = wordDataMap.get(word);
+ SenseDataHolder.getWordDataHolder().add(wordData);
+ wordDataMap.put(word, new WordData(sessionId, word, 0));
+ }
+ }
+
+ /**
+ * apply porter stem algorithm
+ * @param word to be stemmed.
+ * @return
+ */
+ private static String stem(String word)
+ {
+ englishStemmer stemmer = new englishStemmer();
+ stemmer.setCurrent(word);
+ boolean result = stemmer.stem();
+ if (!result)
+ {
+ return word;
+ }
+ return stemmer.getCurrent();
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/StringSimilarity.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/StringSimilarity.java
new file mode 100644
index 0000000000..a44e304f42
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/StringSimilarity.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+/**
+ * Calculates the similarity of strings.
+ */
+public class StringSimilarity {
+
+ /**
+ * Calculates the similarity (a number within 0 and 1) between two strings.
+ */
+ public static double similarity(String s1, String s2) {
+ String longer = s1, shorter = s2;
+ if (s1.length() < s2.length()) { // longer should always have greater length
+ longer = s2;
+ shorter = s1;
+ }
+ int longerLength = longer.length();
+ if (longerLength == 0) {
+ return 1.0; /* both strings are zero length */
+ }
+ return ((longerLength - editDistance(longer, shorter)) / (double) longerLength) * 100;
+ }
+
+ // Example implementation of the Levenshtein Edit Distance
+ // See http://rosettacode.org/wiki/Levenshtein_distance#Java
+ private static int editDistance(String s1, String s2) {
+ s1 = s1.toLowerCase();
+ s2 = s2.toLowerCase();
+
+ int[] costs = new int[s2.length() + 1];
+ for (int i = 0; i <= s1.length(); i++) {
+ int lastValue = i;
+ for (int j = 0; j <= s2.length(); j++) {
+ if (i == 0)
+ costs[j] = j;
+ else {
+ if (j > 0) {
+ int newValue = costs[j - 1];
+ if (s1.charAt(i - 1) != s2.charAt(j - 1))
+ newValue = Math.min(Math.min(newValue, lastValue),
+ costs[j]) + 1;
+ costs[j - 1] = lastValue;
+ lastValue = newValue;
+ }
+ }
+ }
+ if (i > 0)
+ costs[s2.length()] = lastValue;
+ }
+ return costs[s2.length()];
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/VoiceRecognitionListener.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/VoiceRecognitionListener.java
new file mode 100644
index 0000000000..52ce8d52ff
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/VoiceRecognitionListener.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+import android.os.Bundle;
+import android.speech.RecognitionListener;
+import android.speech.SpeechRecognizer;
+import org.wso2.carbon.iot.android.sense.speech.detector.IVoiceControl;
+import java.util.ArrayList;
+
+/**
+ * This triggers android voice recognition listener.
+ */
+public class VoiceRecognitionListener implements RecognitionListener {
+ private static VoiceRecognitionListener instance = null;
+
+ IVoiceControl listener; // This is your running activity (we will initialize it later)
+
+ public static VoiceRecognitionListener getInstance() {
+ if (instance == null) {
+ instance = new VoiceRecognitionListener();
+ }
+ return instance;
+ }
+
+ private VoiceRecognitionListener() { }
+
+ public void setListener(IVoiceControl listener) {
+ this.listener = listener;
+ }
+
+ public void processVoiceCommands(String... voiceCommands) {
+ listener.processVoiceCommands(voiceCommands);
+ }
+
+ // This method will be executed when voice commands were found
+ public void onResults(Bundle data) {
+ ArrayList matches = data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
+ String[] commands = new String[matches.size()];
+ commands = matches.toArray(commands);
+ processVoiceCommands(commands);
+ }
+
+ // User starts speaking
+ public void onBeginningOfSpeech() {
+ System.out.println("Starting to listen");
+ }
+
+ public void onBufferReceived(byte[] buffer) { }
+
+ // User finished speaking
+ public void onEndOfSpeech() {
+ System.out.println("Waiting for result...");
+ }
+
+ // If the user said nothing the service will be restarted
+ public void onError(int error) {
+ if (listener != null) {
+ listener.restartListeningService();
+ }
+ }
+ public void onEvent(int eventType, Bundle params) { }
+
+ public void onPartialResults(Bundle partialResults) { }
+
+ public void onReadyForSpeech(Bundle params) { }
+
+ public void onRmsChanged(float rmsdB) { }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/WordData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/WordData.java
new file mode 100644
index 0000000000..a112cbd817
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/speech/detector/util/WordData.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.speech.detector.util;
+
+/**
+ * This defines the data structure of the word data.
+ */
+public class WordData {
+ /**
+ * timestamp for all the occurences
+ */
+ private long timestamp;
+ private int occurences;
+ private String word;
+ private String sessionId;
+
+ public WordData(String sessionId, String word, int occurences) {
+ this.timestamp = System.currentTimeMillis() / 1000;
+ this.occurences = occurences;
+ this.word = word;
+ this.sessionId = sessionId;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public int getOccurences() {
+ return occurences;
+ }
+
+ public String getWord() {
+ return word;
+ }
+
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * @param occurences for the word and then add the timestamp for each occurences.
+ */
+ public void addOccurences(int occurences) {
+ this.occurences = this.occurences + occurences;
+ this.timestamp = System.currentTimeMillis() / 1000;
+ }
+
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/LocalRegistry.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/LocalRegistry.java
new file mode 100644
index 0000000000..e9d3d430f7
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/LocalRegistry.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.data.publisher.mqtt.transport.MQTTTransportHandler;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * This is used to store the values in either in memory or in shared preferences.
+ */
+public class LocalRegistry {
+
+ private static final String SENSE_SHARED_PREFERENCES = "senseSharedPreferences";
+ private static final String USERNAME_KEY = "usernameKey";
+ private static final String DEVICE_ID_KEY = "deviceIdKey";
+ private static final String SERVER_HOST_KEY = "serverHostKey";
+ private static final String ACCESS_TOKEN_KEY = "accessTokenKey";
+ private static final String REFRESH_TOKEN_KEY = "refreshTokenKey";
+ private static final String MQTT_PORT_KEY = "mqttPort";
+ private static boolean exists = false;
+ private static String username;
+ private static String deviceId;
+ private static String serverURL;
+ private static MQTTTransportHandler mqttTransportHandler;
+ private static String accessToken;
+ private static String refreshToken;
+ private static int mqttPort;
+
+ public static boolean isExist(Context context) {
+ if (!exists) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ String username = sharedpreferences.getString(USERNAME_KEY, "");
+ String deviceId = sharedpreferences.getString(DEVICE_ID_KEY, "");
+ exists = (username != null && !username.isEmpty() && deviceId != null && !deviceId.isEmpty());
+ }
+ return exists;
+ }
+
+ public static void setExist(boolean status) {
+ exists = status;
+ }
+
+
+ public static void addUsername(Context context, String username) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(USERNAME_KEY, username);
+ editor.commit();
+ LocalRegistry.username = username;
+ }
+
+ public static String getUsername(Context context) {
+ if (LocalRegistry.username == null || username.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.username = sharedpreferences.getString(USERNAME_KEY, "");
+ }
+ return LocalRegistry.username;
+ }
+
+ public static void removeUsername(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.clear();
+ editor.remove(USERNAME_KEY);
+ editor.commit();
+ LocalRegistry.username = null;
+ }
+
+ public static void addDeviceId(Context context, String deviceId) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(DEVICE_ID_KEY, deviceId);
+ editor.commit();
+ LocalRegistry.deviceId = deviceId;
+ }
+
+ public static void removeDeviceId(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(DEVICE_ID_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.deviceId = null;
+ }
+
+ public static String getDeviceId(Context context) {
+ if (LocalRegistry.deviceId == null || LocalRegistry.deviceId.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.deviceId = sharedpreferences.getString(DEVICE_ID_KEY, "");
+ }
+ return LocalRegistry.deviceId;
+ }
+
+ public static void addServerURL(Context context, String host) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(SERVER_HOST_KEY, host);
+ editor.commit();
+ LocalRegistry.serverURL = host;
+ }
+
+ public static void removeServerURL(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(SERVER_HOST_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.serverURL = null;
+ }
+
+ public static String getServerURL(Context context) {
+ if (LocalRegistry.serverURL == null || LocalRegistry.serverURL.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.serverURL = sharedpreferences.getString(SERVER_HOST_KEY, "");
+ }
+ return LocalRegistry.serverURL;
+ }
+
+ public static void addAccessToken(Context context, String accessToken) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(ACCESS_TOKEN_KEY, accessToken);
+ editor.commit();
+ LocalRegistry.accessToken = accessToken;
+ }
+
+ public static void removeAccessToken(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(ACCESS_TOKEN_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.accessToken = null;
+ }
+
+ public static String getAccessToken(Context context) {
+ if (LocalRegistry.accessToken == null || LocalRegistry.accessToken.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.accessToken = sharedpreferences.getString(ACCESS_TOKEN_KEY, "");
+ }
+ return LocalRegistry.accessToken;
+ }
+
+ public static void addRefreshToken(Context context, String refreshToken) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putString(REFRESH_TOKEN_KEY, refreshToken);
+ editor.commit();
+ LocalRegistry.refreshToken = refreshToken;
+ }
+
+ public static void removeRefreshToken(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(REFRESH_TOKEN_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.refreshToken = null;
+ }
+
+ public static String getRefreshToken(Context context) {
+ if (LocalRegistry.refreshToken == null || LocalRegistry.refreshToken.isEmpty()) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.refreshToken = sharedpreferences.getString(REFRESH_TOKEN_KEY, "");
+ }
+ return LocalRegistry.refreshToken;
+ }
+
+ public static void addMqttPort(Context context, int port) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.putInt(MQTT_PORT_KEY, port);
+ editor.commit();
+ LocalRegistry.mqttPort = port;
+ }
+
+ public static void removeMqttPort(Context context) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedpreferences.edit();
+ editor.remove(MQTT_PORT_KEY);
+ editor.clear();
+ editor.commit();
+ LocalRegistry.mqttPort = 0;
+ }
+
+ public static int getMqttPort(Context context) {
+ if (LocalRegistry.mqttPort == 0) {
+ SharedPreferences sharedpreferences = context.getSharedPreferences(SENSE_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ LocalRegistry.mqttPort = sharedpreferences.getInt(MQTT_PORT_KEY, SenseConstants.MQTT_BROKER_PORT);
+ }
+ return LocalRegistry.mqttPort;
+ }
+
+ public static String getServerHost(Context context) {
+
+ URL url = null;
+ String urlString = getServerURL(context);
+ try {
+ url = new URL(urlString);
+ return url.getHost();
+ } catch (MalformedURLException e) {
+ Log.e("Host ", "Invalid urlString :" + urlString);
+ return null;
+ }
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClient.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClient.java
new file mode 100644
index 0000000000..0572682852
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClient.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.util.dto.RegisterInfo;
+
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Handler;
+
+/**
+ * This Client is used for http communication with the server.
+ */
+public class SenseClient {
+ private final static String TAG = "SenseService Client";
+
+ private Context context;
+
+ public SenseClient(Context context) {
+ this.context = context;
+ }
+
+ /**
+ * Enroll the device.
+ *
+ * @param username
+ * @param password
+ * @param deviceId
+ * @return
+ */
+ public RegisterInfo register(String username, String password, String deviceId, android.os.Handler mUiHandler) {
+ Map response = registerWithTimeWait(username, password, deviceId);
+ String responseStatus = response.get("status");
+ RegisterInfo registerInfo = new RegisterInfo();
+ if (responseStatus.trim().contains(SenseConstants.Request.REQUEST_SUCCESSFUL)) {
+ registerInfo.setMsg("Device Registered");
+ registerInfo.setIsRegistered(true);
+ return registerInfo;
+ } else if (responseStatus.trim().contains(SenseConstants.Request.REQUEST_CONFLICT)) {
+ registerInfo.setMsg("Login Successful");
+ registerInfo.setIsRegistered(true);
+ return registerInfo;
+ } else {
+ registerInfo.setMsg("Authentication failed, please check your credentials and try again.");
+ registerInfo.setIsRegistered(false);
+ return registerInfo;
+ }
+ }
+
+ public Map registerWithTimeWait(String username, String password, String deviceId) {
+ try {
+ SenseClientAsyncExecutor senseClientAsyncExecutor = new SenseClientAsyncExecutor(context);
+ String endpoint = LocalRegistry.getServerURL(context);
+ senseClientAsyncExecutor.execute(username, password, deviceId, endpoint);
+ Map response = senseClientAsyncExecutor.get();
+ if (response != null) {
+ return response;
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ Log.e("Send Sensor Data", "Thread Interruption for endpoint " + LocalRegistry.getServerURL(context));
+ } catch (ExecutionException e) {
+ Log.e("Send Sensor Data", "Failed to push data to the endpoint " + LocalRegistry.getServerURL(context));
+ }
+ return null;
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java
new file mode 100644
index 0000000000..79b3d740b8
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseClientAsyncExecutor.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.util.Log;
+
+import org.wso2.carbon.iot.android.sense.constants.SenseConstants;
+import org.wso2.carbon.iot.android.sense.util.dto.AccessTokenInfo;
+import org.wso2.carbon.iot.android.sense.util.dto.AndroidSenseManagerService;
+import org.wso2.carbon.iot.android.sense.util.dto.ApiApplicationRegistrationService;
+import org.wso2.carbon.iot.android.sense.util.dto.ApiRegistrationProfile;
+import org.wso2.carbon.iot.android.sense.util.dto.DynamicClientRegistrationService;
+import org.wso2.carbon.iot.android.sense.util.dto.OAuthApplicationInfo;
+import org.wso2.carbon.iot.android.sense.util.dto.OAuthRequestInterceptor;
+import org.wso2.carbon.iot.android.sense.util.dto.RegistrationProfile;
+import org.wso2.carbon.iot.android.sense.util.dto.TokenIssuerService;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import feign.Client;
+import feign.Feign;
+import feign.FeignException;
+import feign.auth.BasicAuthRequestInterceptor;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import feign.jaxrs.JAXRSContract;
+
+public class SenseClientAsyncExecutor extends AsyncTask> {
+
+ private final static String TAG = "SenseService Client";
+ private static final String STATUS = "status";
+ private final static String DEVICE_NAME = Build.MANUFACTURER + " " + Build.MODEL;
+ private Context context;
+
+ public SenseClientAsyncExecutor(Context context) {
+ this.context = context;
+
+ }
+
+ TrustManager[] trustAllCerts = new TrustManager[]{
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }
+ };
+
+ Client disableHostnameVerification = new Client.Default(getTrustedSSLSocketFactory(), new HostnameVerifier() {
+ @Override
+ public boolean verify(String s, SSLSession sslSession) {
+ return true;
+ }
+ });
+
+ @Override
+ protected Map doInBackground(String... parameters) {
+ if (android.os.Debug.isDebuggerConnected())
+ android.os.Debug.waitForDebugger();
+ String response;
+ Map response_params = new HashMap<>();
+ String username = parameters[0];
+ String password = parameters[1];
+ String deviceId = parameters[2];
+ String endpoint = parameters[3];
+ Map responseMap = new HashMap<>();
+ responseMap.put(STATUS, "200");
+ try {
+ //DynamicClientRegistraiton.
+ DynamicClientRegistrationService dynamicClientRegistrationService = Feign.builder()
+ .client(disableHostnameVerification).contract(new
+ JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(DynamicClientRegistrationService.class, endpoint + SenseConstants.DCR_CONTEXT);
+ RegistrationProfile registrationProfile = new RegistrationProfile();
+ String applicationName = "android-sense:" + deviceId;
+ registrationProfile.setOwner(username);
+ registrationProfile.setClientName(applicationName);
+ registrationProfile.setCallbackUrl("");
+ registrationProfile.setGrantType("password refresh_token client_credentials");
+ registrationProfile.setApplicationType("device");
+ registrationProfile.setTokenScope("production");
+ OAuthApplicationInfo oAuthApplicationInfo = dynamicClientRegistrationService.register(registrationProfile);
+
+ //PasswordGrantType
+ TokenIssuerService tokenIssuerService = Feign.builder().client(disableHostnameVerification).requestInterceptor(
+ new BasicAuthRequestInterceptor(oAuthApplicationInfo.getClient_id(), oAuthApplicationInfo.getClient_secret()))
+ .contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(TokenIssuerService.class, endpoint + SenseConstants.TOKEN_ISSUER_CONTEXT);
+ AccessTokenInfo accessTokenInfo = tokenIssuerService.getToken("password", username, password);
+
+ //ApiApplicationRegistration
+ ApiApplicationRegistrationService apiApplicationRegistrationService = Feign.builder().client(disableHostnameVerification)
+ .requestInterceptor(new OAuthRequestInterceptor(accessTokenInfo.getAccess_token()))
+ .contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(ApiApplicationRegistrationService.class, endpoint + SenseConstants.API_APPLICATION_REGISTRATION_CONTEXT);
+ ApiRegistrationProfile apiRegistrationProfile = new ApiRegistrationProfile();
+ apiRegistrationProfile.setApplicationName(applicationName);
+ apiRegistrationProfile.setConsumerKey(oAuthApplicationInfo.getClient_id());
+ apiRegistrationProfile.setConsumerSecret(oAuthApplicationInfo.getClient_secret());
+ apiRegistrationProfile.setIsAllowedToAllDomains(false);
+ apiRegistrationProfile.setIsMappingAnExistingOAuthApp(true);
+ apiRegistrationProfile.setTags(new String[]{SenseConstants.DEVICE_TYPE});
+ String replyMsg = apiApplicationRegistrationService.register(apiRegistrationProfile);
+
+ //DeviceRegister
+ AndroidSenseManagerService androidSenseManagerService = Feign.builder().client(disableHostnameVerification)
+ .requestInterceptor(new OAuthRequestInterceptor(accessTokenInfo.getAccess_token()))
+ .contract(new JAXRSContract()).encoder(new JacksonEncoder()).decoder(new JacksonDecoder())
+ .target(AndroidSenseManagerService.class, endpoint + SenseConstants.REGISTER_CONTEXT);
+ boolean registered = androidSenseManagerService.register(deviceId, DEVICE_NAME);
+ if (registered) {
+ LocalRegistry.addAccessToken(context, accessTokenInfo.getAccess_token());
+ LocalRegistry.addRefreshToken(context, accessTokenInfo.getRefresh_token());
+ }
+ return responseMap;
+ } catch (FeignException e) {
+ responseMap.put(STATUS, "" + e.status());
+ return responseMap;
+ }
+ }
+
+ private SSLSocketFactory getTrustedSSLSocketFactory() {
+ try {
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ return sc.getSocketFactory();
+ } catch (KeyManagementException | NoSuchAlgorithmException e) {
+ Log.e(SenseClientAsyncExecutor.class.getName(), "Invalid Certificate");
+ return null;
+ }
+
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java
new file mode 100644
index 0000000000..463cf8ab9f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseDataHolder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.util;
+
+import org.wso2.carbon.iot.android.sense.event.streams.Location.LocationData;
+import org.wso2.carbon.iot.android.sense.event.streams.Sensor.SensorData;
+import org.wso2.carbon.iot.android.sense.event.streams.battery.BatteryData;
+import org.wso2.carbon.iot.android.sense.speech.detector.util.WordData;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * This holds the sensor,battery and location data inmemory.
+ */
+public class SenseDataHolder {
+
+ private static List sensorDataHolder;
+ private static List batteryDataHolder;
+ private static List locationDataHolder;
+ private static List wordDataHolder;
+
+ public static List getSensorDataHolder(){
+ if(sensorDataHolder == null){
+ sensorDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return sensorDataHolder;
+ }
+
+ public static List getBatteryDataHolder(){
+ if(batteryDataHolder == null){
+ batteryDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return batteryDataHolder;
+ }
+
+ public static List getLocationDataHolder(){
+ if(locationDataHolder == null){
+ locationDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return locationDataHolder;
+ }
+
+ public static List getWordDataHolder(){
+ if(wordDataHolder == null){
+ wordDataHolder = new CopyOnWriteArrayList<>();
+ }
+ return wordDataHolder;
+ }
+
+ public static void resetSensorDataHolder(){
+ sensorDataHolder = null;
+ }
+
+ public static void resetBatteryDataHolder(){
+ batteryDataHolder = null;
+ }
+
+ public static void resetLocationDataHolder(){
+ locationDataHolder = null;
+ }
+
+ public static void resetWordDataHolder() {
+ wordDataHolder = null;
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseUtils.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseUtils.java
new file mode 100644
index 0000000000..956e780def
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.telephony.TelephonyManager;
+
+import java.util.UUID;
+
+public class SenseUtils {
+
+ /**
+ * this generate the device Id
+ *
+ * @param baseContext
+ * @param contentResolver
+ * @return
+ */
+ //http://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id
+ public static String generateDeviceId(Context baseContext, ContentResolver contentResolver) {
+
+ final TelephonyManager tm = (TelephonyManager) baseContext.getSystemService(Context.TELEPHONY_SERVICE);
+
+ final String tmDevice, tmSerial, androidId;
+ tmDevice = String.valueOf(tm.getDeviceId());
+ tmSerial = String.valueOf(tm.getSimSerialNumber());
+ androidId = String.valueOf(android.provider.Settings.Secure.getString(contentResolver, android.provider.Settings.Secure.ANDROID_ID));
+
+ UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
+ return deviceUuid.toString();
+
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseWakeLock.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseWakeLock.java
new file mode 100644
index 0000000000..1a6a36bbbe
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/SenseWakeLock.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+package org.wso2.carbon.iot.android.sense.util;
+
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.Log;
+
+/**
+ * It doesnt let the phone goto sleep.
+ */
+public class SenseWakeLock {
+
+ private static PowerManager.WakeLock wakeLock;
+ private static String TAG = "Wake Lock";
+
+ public static void acquireWakeLock(Context context) {
+ Log.i(SenseWakeLock.class.getSimpleName(), "Acquire CPU wakeup lock start");
+ if (wakeLock == null) {
+ Log.i(TAG, "CPU wakeUp log is not null");
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SenseWakeLock");
+ }
+ wakeLock.acquire();
+ }
+
+ public static void releaseCPUWakeLock() {
+ if (wakeLock != null) {
+ wakeLock.release();
+ wakeLock = null;
+ }
+ Log.i(TAG, "Release wakeup");
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AccessTokenInfo.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AccessTokenInfo.java
new file mode 100644
index 0000000000..6b3400fb5a
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AccessTokenInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+/**
+ * This hold access token info that returned from the api call
+ */
+public class AccessTokenInfo {
+ public String token_type;
+ public String expires_in;
+ public String refresh_token;
+ public String access_token;
+
+ public String getToken_type() {
+ return token_type;
+ }
+
+ public void setToken_type(String token_type) {
+ this.token_type = token_type;
+ }
+
+ public String getExpires_in() {
+ return expires_in;
+ }
+
+ public void setExpires_in(String expires_in) {
+ this.expires_in = expires_in;
+ }
+
+ public String getRefresh_token() {
+ return refresh_token;
+ }
+
+ public void setRefresh_token(String refresh_token) {
+ this.refresh_token = refresh_token;
+ }
+
+ public String getAccess_token() {
+ return access_token;
+ }
+
+ public void setAccess_token(String access_token) {
+ this.access_token = access_token;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AndroidSenseManagerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AndroidSenseManagerService.java
new file mode 100644
index 0000000000..7c77b5e0de
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/AndroidSenseManagerService.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+
+/**
+ * This holds the android manager service definition that is used with netflix feign.
+ */
+public interface AndroidSenseManagerService {
+
+ @Path("/enrollment/devices/{device_id}")
+ @POST
+ boolean register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiApplicationRegistrationService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiApplicationRegistrationService.java
new file mode 100644
index 0000000000..e8cd26148b
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiApplicationRegistrationService.java
@@ -0,0 +1,25 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * This is the application registration service that exposed for apimApplicationRegistration
+ */
+
+@Path("/register")
+public interface ApiApplicationRegistrationService {
+
+ /**
+ * This method is used to register api application
+ *
+ * @param registrationProfile contains the necessary attributes that are needed in order to register an app.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ String register(ApiRegistrationProfile registrationProfile);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiRegistrationProfile.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiRegistrationProfile.java
new file mode 100644
index 0000000000..98db81fb86
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/ApiRegistrationProfile.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+
+/**
+ * This class represents the data that are required to register
+ * the oauth application.
+ */
+public class ApiRegistrationProfile {
+
+ public String applicationName;
+ public String tags[];
+ public boolean isAllowedToAllDomains;
+ public String consumerKey;
+ public String consumerSecret;
+ public boolean isMappingAnExistingOAuthApp;
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public void setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ public String[] getTags() {
+ return tags;
+ }
+
+ public void setTags(String[] tags) {
+ this.tags = tags;
+ }
+
+ public boolean isAllowedToAllDomains() {
+ return isAllowedToAllDomains;
+ }
+
+ public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
+ this.isAllowedToAllDomains = isAllowedToAllDomains;
+ }
+
+ public boolean isMappingAnExistingOAuthApp() {
+ return isMappingAnExistingOAuthApp;
+ }
+
+ public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) {
+ this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp;
+ }
+
+ public String getConsumerKey() {
+ return consumerKey;
+ }
+
+ public void setConsumerKey(String consumerKey) {
+ this.consumerKey = consumerKey;
+ }
+
+ public String getConsumerSecret() {
+ return consumerSecret;
+ }
+
+ public void setConsumerSecret(String consumerSecret) {
+ this.consumerSecret = consumerSecret;
+ }
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/DynamicClientRegistrationService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/DynamicClientRegistrationService.java
new file mode 100644
index 0000000000..aa409673a8
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/DynamicClientRegistrationService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/register")
+public interface DynamicClientRegistrationService {
+
+ /**
+ * This method is used to register an Oauth application.
+ *
+ * @param profile contains the necessary attributes that are
+ * needed in order to register an app.
+ * @return Status 200 if success including consumerKey and consumerSecret.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ OAuthApplicationInfo register(RegistrationProfile profile);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthApplicationInfo.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthApplicationInfo.java
new file mode 100644
index 0000000000..5ad8541be8
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthApplicationInfo.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+/**
+ * This class represents an OAuth application populated with necessary data.
+ */
+public class OAuthApplicationInfo {
+
+ public String client_id;
+ public String client_name;
+ public String callback_url;
+ public String client_secret;
+
+ public String getClient_id() {
+ return client_id;
+ }
+
+ public void setClient_id(String client_id) {
+ this.client_id = client_id;
+ }
+
+ public String getClient_name() {
+ return client_name;
+ }
+
+ public void setClient_name(String client_name) {
+ this.client_name = client_name;
+ }
+
+ public String getCallback_url() {
+ return callback_url;
+ }
+
+ public void setCallback_url(String callback_url) {
+ this.callback_url = callback_url;
+ }
+
+ public String getClient_secret() {
+ return client_secret;
+ }
+
+ public void setClient_secret(String client_secret) {
+ this.client_secret = client_secret;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthRequestInterceptor.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthRequestInterceptor.java
new file mode 100644
index 0000000000..b84a1add87
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/OAuthRequestInterceptor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+
+import static feign.Util.checkNotNull;
+
+/**
+ * This is a request interceptor to add oauth token header.
+ */
+public class OAuthRequestInterceptor implements RequestInterceptor {
+
+ private final String headerValue;
+
+ /**
+ * Creates an interceptor that authenticates all requests with the specified OAUTH token
+ *
+ * @param token the access token to use for authentication
+ */
+ public OAuthRequestInterceptor(String token) {
+ checkNotNull(token, "access_token");
+ headerValue = "Bearer " + token;
+ }
+ @Override
+ public void apply(RequestTemplate template) {
+ template.header("Authorization", headerValue);
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegisterInfo.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegisterInfo.java
new file mode 100644
index 0000000000..b3052e4e1c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegisterInfo.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+/**
+ * This holds the data related to registration.
+ */
+public class RegisterInfo {
+
+ private boolean isRegistered;
+ private String msg;
+
+ public boolean isRegistered() {
+ return isRegistered;
+ }
+
+ public void setIsRegistered(boolean isRegistered) {
+ this.isRegistered = isRegistered;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegistrationProfile.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegistrationProfile.java
new file mode 100644
index 0000000000..046c112a38
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/RegistrationProfile.java
@@ -0,0 +1,67 @@
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+
+/**
+ * This class represents the data that are required to register
+ * the oauth application.
+ */
+public class RegistrationProfile {
+
+ public String callbackUrl;
+ public String clientName;
+ public String tokenScope;
+ public String owner;
+ public String grantType;
+ public String applicationType;
+
+ private static final String TAG = RegistrationProfile.class.getSimpleName();
+
+ public String getCallbackUrl() {
+ return callbackUrl;
+ }
+
+ public void setCallbackUrl(String callBackUrl) {
+ this.callbackUrl = callBackUrl;
+ }
+
+ public String getClientName() {
+ return clientName;
+ }
+
+ public void setClientName(String clientName) {
+ this.clientName = clientName;
+ }
+
+ public String getTokenScope() {
+ return tokenScope;
+ }
+
+ public void setTokenScope(String tokenScope) {
+ this.tokenScope = tokenScope;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public String getGrantType() {
+ return grantType;
+ }
+
+ public void setGrantType(String grantType) {
+ this.grantType = grantType;
+ }
+
+ public String getApplicationType() {
+ return applicationType;
+ }
+
+ public void setApplicationType(String applicationType) {
+ this.applicationType = applicationType;
+ }
+
+}
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/TokenIssuerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/TokenIssuerService.java
new file mode 100644
index 0000000000..161f07f45c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/java/org/wso2/carbon/iot/android/sense/util/dto/TokenIssuerService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) 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.
+ *
+ */
+
+package org.wso2.carbon.iot.android.sense.util.dto;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * This hold the api defintion that is used as a contract with netflix feign.
+ */
+@Path("/token")
+public interface TokenIssuerService {
+
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ AccessTokenInfo getToken(@QueryParam("grant_type") String grant, @QueryParam("username") String username,
+ @QueryParam("password") String password);
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/mic.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/mic.png
new file mode 100644
index 0000000000..c799610295
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/mic.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/pushtoserver.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/pushtoserver.png
new file mode 100644
index 0000000000..3dc93ed290
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/pushtoserver.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/sensor.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/sensor.png
new file mode 100644
index 0000000000..a73fb4ee5b
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/sensor.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/side_nav_bar.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/side_nav_bar.xml
new file mode 100644
index 0000000000..5dcda64085
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/drawable/side_nav_bar.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_activity_select_sensor.xml
new file mode 100644
index 0000000000..0650eddb59
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_activity_select_sensor.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_register.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_register.xml
new file mode 100644
index 0000000000..a02e11ade1
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_register.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_sense_settings.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_sense_settings.xml
new file mode 100644
index 0000000000..82891d0c75
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_sense_settings.xml
@@ -0,0 +1,16 @@
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_speech_sense_main.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_speech_sense_main.xml
new file mode 100644
index 0000000000..f024bc2239
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/activity_speech_sense_main.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/app_bar_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/app_bar_activity_select_sensor.xml
new file mode 100644
index 0000000000..6dc91c927a
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/app_bar_activity_select_sensor.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/content_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/content_activity_select_sensor.xml
new file mode 100644
index 0000000000..e431b902a2
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/content_activity_select_sensor.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/display_sensor_values.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/display_sensor_values.xml
new file mode 100644
index 0000000000..e9e5504871
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/display_sensor_values.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/fragment_select_sensor_dialog.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/fragment_select_sensor_dialog.xml
new file mode 100644
index 0000000000..63208a6e08
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/fragment_select_sensor_dialog.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/nav_header_activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/nav_header_activity_select_sensor.xml
new file mode 100644
index 0000000000..d07c2cfe29
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/layout/nav_header_activity_select_sensor.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_activity_select_sensor_drawer.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_activity_select_sensor_drawer.xml
new file mode 100644
index 0000000000..861bf44cda
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_activity_select_sensor_drawer.xml
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_select_sensor.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_select_sensor.xml
new file mode 100644
index 0000000000..c0d1d71701
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/activity_select_sensor.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/menu_sense_settings.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/menu_sense_settings.xml
new file mode 100644
index 0000000000..f4a7a3d8c8
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/menu/menu_sense_settings.xml
@@ -0,0 +1,7 @@
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..cde69bccce
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/wso2logo.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/wso2logo.png
new file mode 100644
index 0000000000..b4114a6c19
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-hdpi/wso2logo.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-mdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..c133a0cbd3
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..bfa42f0e7b
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..324e72cdd7
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/client_truststore.bks b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/client_truststore.bks
new file mode 100644
index 0000000000..0b3bfedf2c
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/client_truststore.bks differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/wso2carbon.cer b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/wso2carbon.cer
new file mode 100644
index 0000000000..8c02f03efb
Binary files /dev/null and b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/raw/wso2carbon.cer differ
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-v21/styles.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000000..65d0c39df5
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,8 @@
+>
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-w820dp/dimens.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000000..63fc816444
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 64dp
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/device.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/device.xml
new file mode 100644
index 0000000000..e7f032534c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/device.xml
@@ -0,0 +1,4 @@
+
+
+ false
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/dimens.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..2626ab6a62
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/dimens.xml
@@ -0,0 +1,9 @@
+
+
+ 16dp
+ 16dp
+
+ 16dp
+ 160dp
+ 16dp
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..a335b9272f
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings.xml
@@ -0,0 +1,14 @@
+
+ WSO2-SenseAgent
+ Sense Settings
+ Server URL https://host:9443
+ Speakup to capture the words
+ DeEnroll
+ ActivitySelectSensor
+
+ Open navigation drawer
+ Close navigation drawer
+
+
+ Hello blank fragment
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings_activity_register.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings_activity_register.xml
new file mode 100644
index 0000000000..f45b28c7fb
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/strings_activity_register.xml
@@ -0,0 +1,13 @@
+
+
+
+ Username
+ Password
+ Register Device
+ Sign in
+ sessionId
+ This email address is invalid
+ This password is too short
+ This password is incorrect
+ This field is required
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/styles.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..35fee10cea
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/app/src/main/res/values/styles.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/build.gradle b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/build.gradle
new file mode 100644
index 0000000000..952246faf1
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/build.gradle
@@ -0,0 +1,21 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ maven { url 'https://repo.eclipse.org/content/repositories/paho-releases/' }
+ }
+ 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()
+ maven { url 'https://repo.eclipse.org/content/repositories/paho-releases/' }
+ }
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradle/wrapper/gradle-wrapper.properties b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..5a1377c93b
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Dec 11 10:25:01 IST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew
new file mode 100755
index 0000000000..91a7e269e1
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew
@@ -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/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew.bat b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew.bat
new file mode 100644
index 0000000000..8a0b282aa6
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/gradlew.bat
@@ -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/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/pom.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/pom.xml
new file mode 100644
index 0000000000..7476a92b0c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+ 4.0.0
+ org.wso2.iot.agents
+ org.wso2.carbon.device.mgt.iot.androidsense.agent
+ 1.0.0
+ Android Sense
+ Android Sense
+ pom
+
+
+
+ exec-maven-plugin
+ org.codehaus.mojo
+
+
+ Gradle Build
+ generate-sources
+
+ exec
+
+
+ ./gradlew
+
+ assembleRelease
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/settings.gradle b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/settings.gradle
new file mode 100644
index 0000000000..e7b4def49c
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.agent/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml
index d9cff3eee8..3a2404ddfb 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/pom.xml
@@ -46,24 +46,14 @@
cxf-rt-frontend-jaxrs
provided
-
- org.apache.cxf
- cxf-rt-transports-http
- provided
-
org.eclipse.paho
org.eclipse.paho.client.mqttv3
+ provided
-
- org.apache.httpcomponents
- httpasyncclient
- 4.1
- provided
-
org.wso2.carbon.devicemgt-plugins
org.wso2.carbon.device.mgt.iot
@@ -100,12 +90,6 @@
provided
-
- commons-httpclient.wso2
- commons-httpclient
- provided
-
-
org.wso2.carbon
org.wso2.carbon.utils
@@ -174,9 +158,19 @@
org.wso2.carbon.apimgt.annotations
provided
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ provided
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.identity.jwt.client.extension
+ provided
+
org.wso2.carbon.devicemgt
- org.wso2.carbon.apimgt.webapp.publisher
+ org.wso2.carbon.apimgt.application.extension
provided
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java
index 427f113bab..4d63e66b0f 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerService.java
@@ -38,167 +38,13 @@ import javax.ws.rs.core.Response;
@API(name = "android_sense", version = "1.0.0", context = "/android_sense", tags = {"android_sense"})
public interface AndroidSenseControllerService {
- /**
- * Service to push all the sensor data collected by the Android. Called by the Android device
- *
- * @param dataMsg The json string containing sensor readings
- */
- @Path("device/sensors")
- @POST
- @Consumes(MediaType.APPLICATION_JSON)
- Response addSensorData(DeviceData dataMsg);
-
- /**
- * End point which is called by Front-end js to get Light sensor readings from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/light")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "light", name = "Light", description = "Read Light data from the device", type = "monitor")
- Response getLightData(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Battery data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/battery")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "battery", name = "Battery", description = "Read Battery data from the device", type = "monitor")
- Response getBattery(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get GPS data from the server.
- *
- * @param deviceId The registered device id call to this API.
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/gps")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "gps", name = "gps", description = "Read GPS data from the device", type = "monitor")
- Response getGPS(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Magnetic data readings from the server.
- *
- * @param deviceId The registered device id
- * call to this API.
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/magnetic")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "magnetic", name = "Magnetic", description = "Read Magnetic data from the device", type = "monitor")
- Response readMagnetic(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Accelerometer data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/accelerometer")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "accelerometer", name = "Accelerometer", description = "Read Accelerometer data from the device",
- type = "monitor")
- Response readAccelerometer(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Rotation data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/rotation")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "rotation", name = "Rotation", description = "Read Rotational Vector data from the device",
- type = "monitor")
- Response readRotation(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Proximity data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/proximity")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "proximity", name = "Proximity", description = "Read Proximity data from the device",
- type = "monitor")
- Response readProximity(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Gyroscope data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/gyroscope")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "gyroscope", name = "Gyroscope", description = "Read Gyroscope data from the device",
- type = "monitor")
- Response readGyroscope(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Pressure data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/pressure")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "pressure", name = "Pressure", description = "Read Pressure data from the device", type = "monitor")
- Response readPressure(@PathParam("deviceId") String deviceId);
-
- /**
- * End point which is called by Front-end js to get Gravity data from the server.
- *
- * @param deviceId The registered device id
- * @return This method returns a SensorRecord object.
- */
- @Path("device/{deviceId}/sensors/gravity")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "gravity", name = "Gravity",
- description = "Read Gravity data from the device", type = "monitor")
- Response readGravity(@PathParam("deviceId") String deviceId);
-
- @Path("device/{deviceId}/sensors/words")
- @GET
- @Consumes("application/json")
- @Produces("application/json")
- @Feature(code = "words", name = "Words", description = "Get the key words and occurrences",
- type = "monitor")
- Response getWords(@PathParam("deviceId") String deviceId, @QueryParam("sessionId") String sessionId);
-
/**
* End point to send the key words to the device
*
* @param deviceId The registered device Id.
* @param keywords The key words to be sent. (Comma separated values)
*/
- @Path("device/{deviceId}/sensors/words")
+ @Path("device/{deviceId}/words")
@POST
@Feature(code = "keywords", name = "Add Keywords", description = "Send keywords to the device",
type = "operation")
@@ -210,13 +56,13 @@ public interface AndroidSenseControllerService {
* @param deviceId The registered device Id.
* @param threshold The key words to be sent. (Comma separated values)
*/
- @Path("device/{deviceId}/sensors/words/threshold")
+ @Path("device/{deviceId}/words/threshold")
@POST
@Feature(code = "threshold", name = "Add a Threshold", description = "Set a threshold for word in the device",
type = "operation")
Response sendThreshold(@PathParam("deviceId") String deviceId, @FormParam("threshold") String threshold);
- @Path("device/{deviceId}/sensors/words")
+ @Path("device/{deviceId}/words")
@DELETE
@Feature(code = "remove", name = "Remove Keywords", description = "Remove the keywords",
type = "operation")
@@ -225,7 +71,8 @@ public interface AndroidSenseControllerService {
/**
* Retrieve Sensor data for the device type
*/
- @Path("stats/device/{deviceId}/sensors/{sensorName}")
+
+ @Path("stats/{deviceId}/sensors/{sensorName}")
@GET
@Consumes("application/json")
@Produces("application/json")
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java
index 3d0dfa7f30..5e3d31c5a4 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseControllerServiceImpl.java
@@ -20,26 +20,36 @@ package org.wso2.carbon.device.mgt.iot.androidsense.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.dataservice.commons.SORT;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.AnalyticsDataRecord;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DeviceManagementAnalyticsException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
+import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
+import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.transport.AndroidSenseMQTTConnector;
+import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.DeviceData;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.SensorData;
+import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.SensorRecord;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
-import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
/**
@@ -50,267 +60,9 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
private static Log log = LogFactory.getLog(AndroidSenseControllerServiceImpl.class);
private static AndroidSenseMQTTConnector androidSenseMQTTConnector;
- /**
- * Fetches the `AndroidSenseMQTTConnector` specific to this Android Sense controller service.
- *
- * @return the 'AndroidSenseMQTTConnector' instance bound to the 'AndroidSenseMQTTConnector' variable of
- * this service.
- */
- @SuppressWarnings("Unused")
- public AndroidSenseMQTTConnector getAndroidSenseMQTTConnector() {
- return androidSenseMQTTConnector;
- }
-
- /**
- * Sets the `AndroidSenseMQTTConnector` variable of this Android Sense controller service.
- *
- * @param androidSenseMQTTConnector a 'AndroidSenseMQTTConnector' object that handles all MQTT related
- * communications of any connected Android Sense device-type
- */
- @SuppressWarnings("Unused")
- public void setAndroidSenseMQTTConnector(final AndroidSenseMQTTConnector androidSenseMQTTConnector) {
- Runnable connector = new Runnable() {
- public void run() {
- if (waitForServerStartup()) {
- return;
- }
- AndroidSenseControllerServiceImpl.androidSenseMQTTConnector = androidSenseMQTTConnector;
- if (MqttConfig.getInstance().isEnabled()) {
- androidSenseMQTTConnector.connect();
- } else {
- log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
- }
- }
- };
- Thread connectorThread = new Thread(connector);
- connectorThread.setDaemon(true);
- connectorThread.start();
- }
-
- private boolean waitForServerStartup() {
- while (!IoTServerStartupListener.isServerReady()) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- return true;
- }
- }
- return false;
- }
-
- public Response addSensorData(DeviceData dataMsg) {
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
- SensorData[] sensorData = dataMsg.values;
- String streamDef = null;
- Object payloadData[] = null;
- String sensorName = null;
- for (SensorData sensor : sensorData) {
- switch (sensor.key) {
- case "battery":
- streamDef = AndroidSenseConstants.BATTERY_STREAM_DEFINITION;
- payloadData = new Float[]{Float.parseFloat(sensor.value)};
- sensorName = AndroidSenseConstants.SENSOR_BATTERY;
- break;
- case "GPS":
- streamDef = AndroidSenseConstants.GPS_STREAM_DEFINITION;
- String gpsValue = sensor.value;
- String gpsValuesString[] = gpsValue.split(",");
- Float gpsValues[] = new Float[2];
- gpsValues[0] = Float.parseFloat(gpsValuesString[0]);
- gpsValues[1] = Float.parseFloat(gpsValuesString[0]);
- payloadData = gpsValues;
- sensorName = AndroidSenseConstants.SENSOR_GPS;
- break;
- default:
- try {
- int androidSensorId = Integer.parseInt(sensor.key);
- String value = sensor.value;
- String sensorValueString[] = value.split(",");
- Float sensorValues[] = new Float[1];
- switch (androidSensorId) {
- case 1:
- streamDef = AndroidSenseConstants.ACCELEROMETER_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ACCELEROMETER;
- break;
- case 2:
- streamDef = AndroidSenseConstants.MAGNETIC_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_MAGNETIC;
- break;
- case 4:
- streamDef = AndroidSenseConstants.GYROSCOPE_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GYROSCOPE;
- break;
- case 5:
- streamDef = AndroidSenseConstants.LIGHT_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_LIGHT;
- payloadData = new Float[]{Float.parseFloat(sensorValueString[0])};
- break;
- case 6:
- streamDef = AndroidSenseConstants.PRESSURE_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PRESSURE;
- payloadData = new Float[]{Float.parseFloat(sensorValueString[0])};
- break;
- case 8:
- streamDef = AndroidSenseConstants.PROXIMITY_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PROXIMITY;
- payloadData = new Float[]{Float.parseFloat(sensorValueString[0])};
- break;
- case 9:
- streamDef = AndroidSenseConstants.GRAVITY_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GRAVITY;
- break;
- case 11:
- streamDef = AndroidSenseConstants.ROTATION_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValueString[0]) *
- Float.parseFloat(sensorValueString[0]) * Float.parseFloat(sensorValueString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ROTATION;
- break;
- }
- } catch (NumberFormatException e) {
- log.error("Invalid sensor value is sent from the device");
- continue;
- }
- }
- Object metaData[] = {dataMsg.owner, AndroidSenseConstants.DEVICE_TYPE, dataMsg.deviceId, sensor.time};
- if (streamDef != null && payloadData != null && payloadData.length > 0) {
- try {
- SensorDataManager.getInstance()
- .setSensorRecord(dataMsg.deviceId, sensorName, sensor.value, sensor.time);
- deviceAnalyticsService.publishEvent(streamDef, "1.0.0", metaData, new Object[0], payloadData);
- } catch (DataPublisherConfigurationException e) {
- return Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode()).build();
- }
- }
- }
- return Response.ok().build();
- }
-
- public Response getLightData(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_LIGHT);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response getBattery(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_BATTERY);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response getGPS(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_GPS);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readMagnetic(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, AndroidSenseConstants
- .SENSOR_MAGNETIC);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readAccelerometer(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_ACCELEROMETER);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readRotation(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_ROTATION);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readProximity(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_PROXIMITY);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readGyroscope(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_GYROSCOPE);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readPressure(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_PRESSURE);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response readGravity(String deviceId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_GRAVITY);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response getWords(String deviceId, String sessionId) {
- try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- AndroidSenseConstants.SENSOR_WORDCOUNT);
- return Response.ok().entity(sensorRecord).build();
- } catch (DeviceControllerException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
- }
- }
-
- public Response sendKeyWords(String deviceId, String keywords) {
+ @Path("device/{deviceId}/words")
+ @POST
+ public Response sendKeyWords(@PathParam("deviceId") String deviceId, @FormParam("keywords") String keywords) {
try {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
androidSenseMQTTConnector.publishDeviceData(username, deviceId, "add", keywords);
@@ -320,7 +72,9 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
}
}
- public Response sendThreshold(String deviceId, String threshold) {
+ @Path("device/{deviceId}/words/threshold")
+ @POST
+ public Response sendThreshold(@PathParam("deviceId") String deviceId, @FormParam("threshold") String threshold) {
try {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
androidSenseMQTTConnector.publishDeviceData(username, deviceId, "threshold", threshold);
@@ -330,7 +84,9 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
}
}
- public Response removeKeyWords(String deviceId, String words) {
+ @Path("device/{deviceId}/words")
+ @DELETE
+ public Response removeKeyWords(@PathParam("deviceId") String deviceId, @QueryParam("words") String words) {
try {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
androidSenseMQTTConnector.publishDeviceData(username, deviceId, "remove", words);
@@ -340,59 +96,36 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
}
}
- public Response getAndroidSenseDeviceStats(String deviceId, String sensor, long from, long to) {
+ @Path("stats/{deviceId}/sensors/{sensorName}")
+ @GET
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Response getAndroidSenseDeviceStats(@PathParam("deviceId") String deviceId, @PathParam("sensorName") String sensor,
+ @QueryParam("from") long from, @QueryParam("to") long to) {
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String user = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
- List sensorDatas = new ArrayList<>();
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
String query = "owner:" + user + " AND deviceId:" + deviceId + " AND deviceType:" +
AndroidSenseConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
if (sensor.equals(AndroidSenseConstants.SENSOR_WORDCOUNT)) {
query = "owner:" + user + " AND deviceId:" + deviceId;
}
String sensorTableName = getSensorEventTableName(sensor);
+ List sensorDatas;
try {
- List records = deviceAnalyticsService.getAllEventsForDevice(sensorTableName, query);
if (sensor.equals(AndroidSenseConstants.SENSOR_WORDCOUNT)) {
- for (AnalyticsDataRecord record : records) {
- SensorData sensorData = new SensorData();
- sensorData.setKey((String) record.getValue("word"));
- sensorData.setTime((long) record.getValue("occurence"));
- sensorData.setValue((String) record.getValue("sessionId"));
- sensorDatas.add(sensorData);
- }
+ List sortByFields = new ArrayList<>();
+ SortByField sortByField = new SortByField("time", SORT.ASC, false);
+ sortByFields.add(sortByField);
+ sensorDatas = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
} else {
- Collections.sort(records, new Comparator() {
- @Override
- public int compare(AnalyticsDataRecord o1, AnalyticsDataRecord o2) {
- long t1 = (Long) o1.getValue("time");
- long t2 = (Long) o2.getValue("time");
- if (t1 < t2) {
- return -1;
- } else if (t1 > t2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- for (AnalyticsDataRecord record : records) {
- SensorData sensorData = new SensorData();
- sensorData.setTime((long) record.getValue("time"));
- sensorData.setValue("" + (float) record.getValue(sensor));
- sensorDatas.add(sensorData);
- }
+ sensorDatas = APIUtil.getAllEventsForDevice(sensorTableName, query, null);
}
- SensorData[] sensorDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.ok().entity(sensorDetails).build();
- } catch (DeviceManagementAnalyticsException e) {
+ return Response.ok().entity(sensorDatas).build();
+ } catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
- SensorData[] senserDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(senserDetails).build();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
}
}
@@ -440,4 +173,60 @@ public class AndroidSenseControllerServiceImpl implements AndroidSenseController
}
return sensorEventTableName;
}
+
+ /**
+ * Fetches the `AndroidSenseMQTTConnector` specific to this Android Sense controller service.
+ *
+ * @return the 'AndroidSenseMQTTConnector' instance bound to the 'AndroidSenseMQTTConnector' variable of
+ * this service.
+ */
+ @SuppressWarnings("Unused")
+ public AndroidSenseMQTTConnector getAndroidSenseMQTTConnector() {
+ return androidSenseMQTTConnector;
+ }
+
+ /**
+ * Sets the `AndroidSenseMQTTConnector` variable of this Android Sense controller service.
+ *
+ * @param androidSenseMQTTConnector a 'AndroidSenseMQTTConnector' object that handles all MQTT related
+ * communications of any connected Android Sense device-type
+ */
+ @SuppressWarnings("Unused")
+ public void setAndroidSenseMQTTConnector(final AndroidSenseMQTTConnector androidSenseMQTTConnector) {
+ Runnable connector = new Runnable() {
+ public void run() {
+ if (waitForServerStartup()) {
+ return;
+ }
+ //The delay is added till the server starts up.
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ AndroidSenseControllerServiceImpl.androidSenseMQTTConnector = androidSenseMQTTConnector;
+ if (MqttConfig.getInstance().isEnabled()) {
+ synchronized (androidSenseMQTTConnector) {
+ androidSenseMQTTConnector.connect();
+ }
+ } else {
+ log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
+ }
+ }
+ };
+ Thread connectorThread = new Thread(connector);
+ connectorThread.setDaemon(true);
+ connectorThread.start();
+ }
+
+ private boolean waitForServerStartup() {
+ while (!IoTServerStartupListener.isServerReady()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java
index 770930ec50..5cb401d13d 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerService.java
@@ -30,33 +30,33 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
-
+@Path("enrollment")
@DeviceType(value = "android_sense")
@API(name = "android_sense_mgt", version = "1.0.0", context = "/android_sense_mgt", tags = {"android_sense"})
public interface AndroidSenseManagerService {
- @Path("device/{device_id}")
+ @Path("/devices/{device_id}")
@POST
Response register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName);
- @Path("devices/{device_id}")
+ @Path("/devices/{device_id}")
@DELETE
Response removeDevice(@PathParam("device_id") String deviceId);
- @Path("devices/{device_id}")
+ @Path("/devices/{device_id}")
@PUT
Response updateDevice(@PathParam("device_id") String deviceId, @QueryParam("name") String name);
- @Path("devices/{device_id}")
+ @Path("/devices/{device_id}")
@GET
@Consumes("application/json")
@Produces("application/json")
Response getDevice(@PathParam("device_id") String deviceId);
- @Path("devices/{sketch_type}/download")
+ @Path("/devices/download")
@GET
@Produces("application/octet-stream")
- Response downloadSketch(@PathParam("sketch_type") String sketchType);
+ Response downloadSketch();
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java
index 531bc5deb8..45420f31cf 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/AndroidSenseManagerServiceImpl.java
@@ -27,15 +27,28 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.utils.CarbonUtils;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.io.File;
import java.util.Date;
+@Path("enrollment")
public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerService {
private static Log log = LogFactory.getLog(AndroidSenseManagerServiceImpl.class);
- public Response register(String deviceId, String deviceName) {
+ @Path("/devices/{device_id}")
+ @POST
+ public Response register(@PathParam("device_id") String deviceId, @QueryParam("deviceName") String deviceName) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(AndroidSenseConstants.DEVICE_TYPE);
@@ -53,19 +66,23 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
device.setName(deviceName);
device.setType(AndroidSenseConstants.DEVICE_TYPE);
enrolmentInfo.setOwner(APIUtil.getAuthenticatedUser());
+ enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD);
device.setEnrolmentInfo(enrolmentInfo);
boolean added = APIUtil.getDeviceManagementService().enrollDevice(device);
if (added) {
- return Response.ok().build();
+ APIUtil.registerApiAccessRoles(APIUtil.getAuthenticatedUser());
+ return Response.ok(true).build();
} else {
- return Response.status(Response.Status.NOT_ACCEPTABLE.getStatusCode()).build();
+ return Response.status(Response.Status.NOT_ACCEPTABLE.getStatusCode()).entity(false).build();
}
} catch (DeviceManagementException e) {
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(false).build();
}
}
- public Response removeDevice(String deviceId) {
+ @Path("/devices/{device_id}")
+ @DELETE
+ public Response removeDevice(@PathParam("device_id") String deviceId) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(AndroidSenseConstants.DEVICE_TYPE);
@@ -81,7 +98,9 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
}
}
- public Response updateDevice(String deviceId, String name) {
+ @Path("/devices/{device_id}")
+ @PUT
+ public Response updateDevice(@PathParam("device_id") String deviceId, @QueryParam("name") String name) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(AndroidSenseConstants.DEVICE_TYPE);
@@ -102,7 +121,11 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
}
}
- public Response getDevice(String deviceId) {
+ @Path("/devices/{device_id}")
+ @GET
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Response getDevice(@PathParam("device_id") String deviceId) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(AndroidSenseConstants.DEVICE_TYPE);
@@ -114,7 +137,10 @@ public class AndroidSenseManagerServiceImpl implements AndroidSenseManagerServic
}
}
- public Response downloadSketch(String sketchType) {
+ @Path("/devices/download")
+ @GET
+ @Produces("application/octet-stream")
+ public Response downloadSketch() {
try {
String sep = File.separator;
String sketchFolder = "repository" + sep + "resources" + sep + "sketches" + sep + "android_sense" + sep;
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java
index 0b8f30e224..bac5bea8de 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/transport/AndroidSenseMQTTConnector.java
@@ -18,27 +18,23 @@
package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.transport;
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
-import org.wso2.carbon.device.mgt.common.Device;
-import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
-import org.wso2.carbon.device.mgt.common.DeviceManagementException;
-import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
-import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.DeviceData;
-import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.SensorData;
+import org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.androidsense.plugin.constants.AndroidSenseConstants;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
-import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
-import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
+import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
+import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
+import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
+import org.wso2.carbon.user.api.UserStoreException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@@ -48,6 +44,8 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
private static Log log = LogFactory.getLog(AndroidSenseMQTTConnector.class);
private static String subscribeTopic = AndroidSenseConstants.MQTT_SUBSCRIBE_WORDS_TOPIC;
private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
+ private static final String KEY_TYPE = "PRODUCTION";
+ private static final String EMPTY_STRING = "";
private AndroidSenseMQTTConnector() {
super(iotServerSubscriber, AndroidSenseConstants.DEVICE_TYPE,
@@ -59,7 +57,25 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
+ AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
try {
+ String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
+ .getRealmConfiguration().getAdminUserName();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
+ APIManagementProviderService apiManagementProviderService = APIUtil
+ .getAPIManagementProviderService();
+ String[] tags = {AndroidSenseConstants.DEVICE_TYPE};
+ ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
+ AndroidSenseConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
+ String scopes = "device_type_" + AndroidSenseConstants.DEVICE_TYPE + " device_mqtt_connector";
+ AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
+ apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
+ //create token
+ String accessToken = accessTokenInfo.getAccessToken();
+ setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
subscribeToQueue();
} catch (TransportHandlerException e) {
@@ -69,6 +85,17 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
} catch (InterruptedException ex) {
log.error("MQTT-Subscriber: Thread Sleep Interrupt Exception.", ex);
}
+ }catch (JWTClientException e) {
+ log.error("Failed to retrieve token from JWT Client.", e);
+ return;
+ } catch (UserStoreException e) {
+ log.error("Failed to retrieve the user.", e);
+ return;
+ } catch (APIManagerException e) {
+ log.error("Failed to create an application and generate keys.", e);
+ return;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
}
}
}
@@ -125,189 +152,7 @@ public class AndroidSenseMQTTConnector extends MQTTTransportHandler {
@Override
public void processIncomingMessage(MqttMessage mqttMessage, String... strings) throws TransportHandlerException {
- String[] topic = strings[0].split("/");
- String deviceId = topic[3];
- if (log.isDebugEnabled()) {
- log.debug("Received MQTT message for: & [DEVICE.ID-" + deviceId + "]");
- }
- try {
- Gson gson = new Gson();
- String actualMessage = mqttMessage.toString();
- DeviceData deviceData = gson.fromJson(actualMessage, DeviceData.class);
-
- SensorData[] sensorData = deviceData.values;
- String streamDef = null;
- Object payloadData[] = null;
- String sensorName = null;
- PrivilegedCarbonContext.startTenantFlow();
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceManagementProviderService deviceManagementProviderService =
- (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null);
- if (deviceManagementProviderService != null) {
- DeviceIdentifier identifier = new DeviceIdentifier(deviceId, AndroidSenseConstants.DEVICE_TYPE);
- Device device = deviceManagementProviderService.getDevice(identifier);
- if (device != null) {
- String owner = device.getEnrolmentInfo().getOwner();
- ctx.setUsername(owner);
- ctx.setTenantDomain(MultitenantUtils.getTenantDomain(owner), true);
- } else {
- return;
- }
-
- } else {
- return;
- }
- ctx.setTenantDomain("carbon.super", true);
- for (SensorData sensor : sensorData) {
- if (sensor.key.equals("battery")) {
- streamDef = AndroidSenseConstants.BATTERY_STREAM_DEFINITION;
- payloadData = new Float[]{Float.parseFloat(sensor.value)};
- sensorName = AndroidSenseConstants.SENSOR_BATTERY;
- } else if (sensor.key.equals("GPS")) {
- streamDef = AndroidSenseConstants.GPS_STREAM_DEFINITION;
- String gpsValue = sensor.value;
- String gpsValuesString[] = gpsValue.split(",");
- Float gpsValues[] = new Float[2];
- gpsValues[0] = Float.parseFloat(gpsValuesString[0]);
- gpsValues[1] = Float.parseFloat(gpsValuesString[0]);
- payloadData = gpsValues;
- sensorName = AndroidSenseConstants.SENSOR_GPS;
- } else if (sensor.key.equals("word")) {
- try {
- streamDef = AndroidSenseConstants.WORD_COUNT_STREAM_DEFINITION;
- String[] values = sensor.value.split(",");
- String sessionId = values[0];
- String keyword = values[1];
- int occurrence = Integer.parseInt(values[2]);
- String status = values[3];
- sensorName = AndroidSenseConstants.SENSOR_WORDCOUNT;
- if (occurrence > 0) {
- payloadData = new Object[]{sessionId, keyword, status};
- for (int i = 0; i < occurrence; i++) {
- Long timestamp = Long.parseLong(values[3 + occurrence]);
- publishDataToDAS(deviceId, timestamp, sensorName, streamDef,
- sensor.value, payloadData);
-
- }
- continue;
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- log.error(
- "Timestamp does not match the occurence sensor values are sent from the device.");
- }
- continue;
- } else {
- try {
- int androidSensorId = Integer.parseInt(sensor.key);
- String sensorValue = sensor.value;
- String sensorValuesString[] = sensorValue.split(",");
- Float sensorValues[] = new Float[1];
-
- switch (androidSensorId) {
- case 1:
- streamDef = AndroidSenseConstants.ACCELEROMETER_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ACCELEROMETER;
- break;
- case 2:
- streamDef = AndroidSenseConstants.MAGNETIC_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_MAGNETIC;
- break;
- case 4:
- streamDef = AndroidSenseConstants.GYROSCOPE_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GYROSCOPE;
- break;
- case 5:
- streamDef = AndroidSenseConstants.LIGHT_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_LIGHT;
- payloadData = new Float[]{Float.parseFloat(sensorValuesString[0])};
- break;
- case 6:
- streamDef = AndroidSenseConstants.PRESSURE_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PRESSURE;
- payloadData = new Float[]{Float.parseFloat(sensorValuesString[0])};
- break;
- case 8:
- streamDef = AndroidSenseConstants.PROXIMITY_STREAM_DEFINITION;
- sensorName = AndroidSenseConstants.SENSOR_PROXIMITY;
- payloadData = new Float[]{Float.parseFloat(sensorValuesString[0])};
- break;
- case 9:
- streamDef = AndroidSenseConstants.GRAVITY_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_GRAVITY;
- break;
- case 11:
- streamDef = AndroidSenseConstants.ROTATION_STREAM_DEFINITION;
- sensorValues[0] = Float.parseFloat(sensorValuesString[0]) * Float.parseFloat(
- sensorValuesString[0]) * Float.
- parseFloat(sensorValuesString[0]);
- payloadData = sensorValues;
- sensorName = AndroidSenseConstants.SENSOR_ROTATION;
- break;
- }
- } catch (NumberFormatException e) {
- log.error("Invalid sensor values are sent from the device.");
- continue;
- }
- }
- publishDataToDAS(deviceId, sensor.time, sensorName, streamDef, sensor.value, payloadData);
- }
- } catch (JsonSyntaxException e) {
- throw new TransportHandlerException("Invalid message format " + mqttMessage.toString());
- } catch (DeviceManagementException e) {
- throw new TransportHandlerException("Invalid device id " + deviceId);
- } finally {
- PrivilegedCarbonContext.endTenantFlow();
- }
- }
-
- private void publishDataToDAS(String deviceId, Long time, String sensorName,
- String streamDefinition, String sensorValue, Object payloadData[]) {
- try {
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceManagementProviderService deviceManagementProviderService = (DeviceManagementProviderService) ctx
- .getOSGiService(DeviceManagementProviderService.class, null);
- if (deviceManagementProviderService != null) {
- DeviceIdentifier identifier = new DeviceIdentifier(deviceId, AndroidSenseConstants.DEVICE_TYPE);
- Device device = deviceManagementProviderService.getDevice(identifier);
- if (device != null) {
- String owner = device.getEnrolmentInfo().getOwner();
- ctx.setTenantDomain(MultitenantUtils.getTenantDomain(owner), true);
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
- if (deviceAnalyticsService != null) {
- Object metaData[] = {owner, AndroidSenseConstants.DEVICE_TYPE, deviceId, time};
- if (streamDefinition != null && payloadData != null && payloadData.length > 0) {
- try {
- SensorDataManager.getInstance().setSensorRecord(deviceId, sensorName, sensorValue, time);
- deviceAnalyticsService.publishEvent(streamDefinition, "1.0.0", metaData,
- new Object[0], payloadData);
- } catch (DataPublisherConfigurationException e) {
- log.error("Data publisher configuration failed - " + e);
- }
- }
- }
- }
- }
- } catch (DeviceManagementException e) {
- log.error("Failed to load device management service.", e);
- }
}
/**
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java
index 73287696e4..fd74ca1f3a 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/APIUtil.java
@@ -2,8 +2,27 @@ package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest;
+import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
+import org.wso2.carbon.analytics.datasource.commons.Record;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.api.UserStoreManager;
+import org.wso2.carbon.user.core.service.RealmService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* This class provides utility functions used by REST-API.
@@ -11,6 +30,7 @@ import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
public class APIUtil {
private static Log log = LogFactory.getLog(APIUtil.class);
+ private static Object lock = new Object();
public static String getAuthenticatedUser() {
PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
@@ -33,4 +53,142 @@ public class APIUtil {
}
return deviceManagementProviderService;
}
+
+ public static AnalyticsDataAPI getAnalyticsDataAPI() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ AnalyticsDataAPI analyticsDataAPI =
+ (AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null);
+ if (analyticsDataAPI == null) {
+ String msg = "Analytics api service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return analyticsDataAPI;
+ }
+
+ public static List getAllEventsForDevice(String tableName, String query, List sortByFields) throws AnalyticsException {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
+ int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
+ if (eventCount == 0) {
+ return null;
+ }
+ AnalyticsDrillDownRequest drillDownRequest = new AnalyticsDrillDownRequest();
+ drillDownRequest.setQuery(query);
+ drillDownRequest.setTableName(tableName);
+ drillDownRequest.setRecordCount(eventCount);
+ if (sortByFields != null) {
+ drillDownRequest.setSortByFields(sortByFields);
+ }
+ List resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest);
+ List recordIds = getRecordIds(resultEntries);
+ AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
+ Map sensorDatas = createSensorData(AnalyticsDataServiceUtils.listRecords(
+ analyticsDataAPI, response));
+ List sortedSensorData = getSortedSensorData(sensorDatas, resultEntries);
+ return sortedSensorData;
+ }
+
+ private static List getRecordIds(List searchResults) {
+ List ids = new ArrayList<>();
+ for (SearchResultEntry searchResult : searchResults) {
+ ids.add(searchResult.getId());
+ }
+ return ids;
+ }
+
+ public static List getSortedSensorData(Map sensorDatas,
+ List searchResults) {
+ List sortedRecords = new ArrayList<>();
+ for (SearchResultEntry searchResultEntry : searchResults) {
+ sortedRecords.add(sensorDatas.get(searchResultEntry.getId()));
+ }
+ return sortedRecords;
+ }
+
+ /**
+ * Creates the SensorDatas from records.
+ *
+ * @param records the records
+ * @return the Map of SensorRecord
+ */
+ public static Map createSensorData(List records) {
+ Map sensorDatas = new HashMap<>();
+ for (Record record : records) {
+ SensorRecord sensorData = createSensorData(record);
+ sensorDatas.put(sensorData.getId(), sensorData);
+ }
+ return sensorDatas;
+ }
+
+ /**
+ * Create a SensorRecord object out of a Record object
+ *
+ * @param record the record object
+ * @return SensorRecord object
+ */
+ public static SensorRecord createSensorData(Record record) {
+ SensorRecord recordBean = new SensorRecord();
+ recordBean.setId(record.getId());
+ recordBean.setValues(record.getValues());
+ return recordBean;
+ }
+
+ public static APIManagementProviderService getAPIManagementProviderService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ APIManagementProviderService apiManagementProviderService =
+ (APIManagementProviderService) ctx.getOSGiService(APIManagementProviderService.class, null);
+ if (apiManagementProviderService == null) {
+ String msg = "API management provider service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return apiManagementProviderService;
+ }
+
+ public static JWTClientManagerService getJWTClientManagerService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ JWTClientManagerService jwtClientManagerService =
+ (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
+ if (jwtClientManagerService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return jwtClientManagerService;
+ }
+
+ public static void registerApiAccessRoles(String user) {
+ UserStoreManager userStoreManager = null;
+ try {
+ userStoreManager = getUserStoreManager();
+ if (userStoreManager != null) {
+ synchronized (lock) {
+ String[] userList = new String[]{user};
+ if (!userStoreManager.isExistingRole(Constants.DEFAULT_ROLE_NAME)) {
+ userStoreManager.addRole(Constants.DEFAULT_ROLE_NAME, userList, Constants.DEFAULT_PERMISSION);
+ }
+ }
+ }
+ } catch (UserStoreException e) {
+ log.error("error on wso2 user component");
+ }
+ }
+
+ private static UserStoreManager getUserStoreManager() throws UserStoreException {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ return getRealmService().getTenantUserRealm(tenantId).getUserStoreManager();
+ }
+
+ public static RealmService getRealmService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ RealmService realmService =
+ (RealmService) ctx.getOSGiService(RealmService.class, null);
+ if (realmService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return realmService;
+ }
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/Constants.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/Constants.java
new file mode 100644
index 0000000000..c6b2c5b1a3
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/Constants.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util;
+
+import org.wso2.carbon.user.core.Permission;
+import org.wso2.carbon.user.core.authorization.TreeNode;
+
+/**
+ * This hold the constants related to android sense.
+ */
+public class Constants {
+
+ private static final String DEFAULT_PERMISSION_RESOURCE = "/_system/governance/permission/admin/device-mgt/android_sense/user";
+ public static final String DEFAULT_ROLE_NAME = "android_sense_user";
+ public static final Permission DEFAULT_PERMISSION[] = new Permission[]{new Permission(Constants.DEFAULT_PERMISSION_RESOURCE,
+ TreeNode.Permission.UI_EXECUTE.toString())};
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/DeviceData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/DeviceData.java
index 6b72507bb1..1e3fbea42b 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/DeviceData.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/DeviceData.java
@@ -1,3 +1,21 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+
package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorData.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorData.java
index becd170856..b235306c49 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorData.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorData.java
@@ -1,3 +1,21 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+
package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@@ -12,33 +30,32 @@ import javax.xml.bind.annotation.XmlRootElement;
@JsonIgnoreProperties(ignoreUnknown = true)
public class SensorData {
- @XmlElement public Long time;
- @XmlElement public String key;
-
- public String getValue() {
- return value;
- }
+ @XmlElement public Long time;
+ @XmlElement public String key;
+ @XmlElement public String value;
- public void setValue(String value) {
- this.value = value;
- }
+ public String getValue() {
+ return value;
+ }
- public String getKey() {
- return key;
- }
+ public void setValue(String value) {
+ this.value = value;
+ }
- public void setKey(String key) {
- this.key = key;
- }
+ public String getKey() {
+ return key;
+ }
- public Long getTime() {
- return time;
- }
+ public void setKey(String key) {
+ this.key = key;
+ }
- public void setTime(Long time) {
- this.time = time;
- }
+ public Long getTime() {
+ return time;
+ }
- @XmlElement public String value;
+ public void setTime(Long time) {
+ this.time = time;
+ }
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorRecord.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorRecord.java
new file mode 100644
index 0000000000..0948be5898
--- /dev/null
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/service/impl/util/SensorRecord.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.androidsense.service.impl.util;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@XmlRootElement
+/**
+ * This stores sensor event data for android sense.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SensorRecord {
+
+ @XmlElementWrapper(required = true, name = "values")
+ private Map values;
+
+ /** The id. */
+ @XmlElement(required = false, name = "id")
+ private String id;
+
+ /**
+ * Gets the values.
+ * @return the values
+ */
+ public Map getValues() {
+ return values;
+ }
+
+ /**
+ * Sets the values.
+ * @param values the values
+ */
+ public void setValues(Map values) {
+ this.values = values;
+ }
+
+ /**
+ * Sets the id.
+ * @param id the new id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Gets the id.
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String toString(){
+ List valueList = new ArrayList();
+ for (Map.Entry entry : values.entrySet()) {
+ valueList.add(entry.getKey() + ":" + entry.getValue());
+ }
+ return valueList.toString();
+
+ }
+
+}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml
index 780d13f662..e81d61e59a 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/META-INF/permissions.xml
@@ -28,152 +28,67 @@
-
-
- add sensor information
- /device-mgt/user/device/sensors
- /device/sensors
- POST
- android_sense_device
-
-
- Get light information
- /device-mgt/user/device/sensors/light
- /device/*/sensors/light
- GET
- android_sense_user
-
-
- Get battery information
- /device-mgt/user/device/sensors/battery
- /device/*/sensors/battery
- GET
- android_sense_user
-
-
- Get gps information
- /device-mgt/user/device/sensors/gps
- /device/*/sensors/gps
- GET
- android_sense_user
-
-
- Get magnetic information
- /device-mgt/user/device/sensors/magnetic
- /device/*/sensors/magnetic
- GET
- android_sense_user
-
-
- Get accelerometer information
- /device-mgt/user/device/accelerometer
- /device/*/sensors/accelerometer
- GET
- android_sense_user
-
- Get rotation information
- /device-mgt/user/device/sensors/rotation
- /device/*/sensors/rotation
- GET
- android_sense_user
-
-
- Get proximity information
- /device-mgt/user/device/sensors/proximity
- /device/*/sensors/proximity
- GET
- android_sense_user
-
-
- Get gyroscope information
- /device-mgt/user/device/gyroscope
- /device/*/sensors/gyroscope
- GET
- android_sense_user
-
-
- Get pressure information
- /device-mgt/user/device/sensors/pressure
- /device/*/sensors/pressure
- GET
- android_sense_user
-
-
- Get gravity information
- /device-mgt/user/device/sensors/gravity
- /device/*/sensors/gravity
- GET
- android_sense_user
-
-
- Get words information
- /device-mgt/user/device/sensors/words
- /device/*/sensors/words
- GET
- android_sense_user
-
-
- Get words information
- /device-mgt/user/device/sensors/word
- /device/*/sensors/words
+ Set words
+ /device-mgt/android_sense/user
+ /device/*/words
POST
android_sense_user
set word threshold information
- /device-mgt/user/device/sensors/words/threshold
- /device/*/sensors/words/threshold
+ /device-mgt/android_sense/user
+ /device/*/words/threshold
POST
android_sense_user
delete words
- /device-mgt/user/device/sensors/words
- /device/*/sensors/words
+ /device-mgt/android_sense/user
+ /device/*/words
DELETE
android_sense_user
get device stats
- /device-mgt/user/device/stats
- /stats/device/*/sensors/*
+ /device-mgt/android_sense/user
+ /stats/*/sensors/*
GET
android_sense_device
Get device
- /device-mgt/user/devices/list
- /devices/*
+ /device-mgt/android_sense/user
+ /enrollment/devices/*
GET
android_sense_user
Add device
- /device-mgt/user/devices/add
- /devices/register
+ /login
+ /enrollment/devices/*
POST
android_sense_user
Remove device
- /device-mgt/user/devices/remove
- /devices/*
+ /device-mgt/android_sense/user
+ /enrollment/devices/*
DELETE
android_sense_user
Download device
- /device-mgt/user/devices/add
- /devices/*/download
+ /device-mgt/android_sense/user
+ /enrollment/devices/download
GET
android_sense_user
Update device
- /device-mgt/user/devices/update
- /devices/*
- POST
+ /device-mgt/android_sense/user
+ /enrollment/devices/*
+ PUT
android_sense_user
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml
index 9ddba99b02..31dfb6aeef 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -36,6 +36,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml
index 138f002d0d..3908d86c60 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.api/src/main/webapp/WEB-INF/web.xml
@@ -22,7 +22,7 @@
doAuthentication
- false
+ true
isSharedWithAllTenants
@@ -42,16 +42,4 @@
managed-api-owner
admin
-
- managed-api-context-template
- /android_sense/{version}
-
-
- managed-api-application
- android_sense
-
-
- managed-api-isSecured
- true
-
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java
index 0ed7a9dd7b..e68e50a438 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/constants/AndroidSenseConstants.java
@@ -49,4 +49,5 @@ public class AndroidSenseConstants {
//MQTT Subscribe topic
public static final String MQTT_SUBSCRIBE_WORDS_TOPIC = "wso2/android_sense/+/data";
public static final String DATA_SOURCE_NAME = "jdbc/AndroidSenseDM_DB";
+ public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
}
diff --git a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java
index a57c4e5e10..a82a3ff96c 100644
--- a/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java
+++ b/components/iot-plugins/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/androidsense/plugin/impl/AndroidSenseManagerService.java
@@ -30,7 +30,6 @@ import java.util.List;
public class AndroidSenseManagerService implements DeviceManagementService {
private DeviceManager deviceManager;
- private static final String SUPER_TENANT_DOMAIN = "carbon.super";
@Override
public String getType() {
@@ -39,7 +38,7 @@ public class AndroidSenseManagerService implements DeviceManagementService {
@Override
public String getProviderTenantDomain() {
- return SUPER_TENANT_DOMAIN;
+ return AndroidSenseConstants.DEVICE_TYPE_PROVIDER_DOMAIN;
}
@Override
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml
index 7d698874aa..77142701b7 100644
--- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml
+++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/pom.xml
@@ -160,6 +160,11 @@
org.wso2.carbon.apimgt.webapp.publisher
provided
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ provided
+
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java
index 076a7bf035..6434c7b654 100644
--- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java
+++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoControllerServiceImpl.java
@@ -20,18 +20,17 @@ package org.wso2.carbon.device.mgt.iot.arduino.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.dataservice.commons.SORT;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.AnalyticsDataRecord;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DeviceManagementAnalyticsException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
import org.wso2.carbon.device.mgt.iot.arduino.service.impl.dto.DeviceData;
-import org.wso2.carbon.device.mgt.iot.arduino.service.impl.dto.SensorData;
+import org.wso2.carbon.device.mgt.iot.arduino.service.impl.dto.SensorRecord;
+import org.wso2.carbon.device.mgt.iot.arduino.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.arduino.service.impl.util.ArduinoServiceUtils;
import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
-import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord;
-
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
@@ -46,8 +45,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -107,8 +104,8 @@ public class ArduinoControllerServiceImpl implements ArduinoControllerService {
@QueryParam("protocol") String protocol) {
try {
- SensorRecord sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
- ArduinoConstants.SENSOR_TEMPERATURE);
+ org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord =
+ SensorDataManager.getInstance().getSensorRecord(deviceId, ArduinoConstants.SENSOR_TEMPERATURE);
return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecord).build();
} catch (DeviceControllerException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
@@ -192,43 +189,19 @@ public class ArduinoControllerServiceImpl implements ArduinoControllerService {
@QueryParam("to") long to) {
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
- List sensorDatas = new ArrayList<>();
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
String query = "deviceId:" + deviceId + " AND deviceType:" +
ArduinoConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
String sensorTableName = ArduinoConstants.TEMPERATURE_EVENT_TABLE;
- SensorData[] sensorDetails;
try {
- List records = deviceAnalyticsService.getAllEventsForDevice(sensorTableName, query);
- Collections.sort(records, new Comparator() {
- @Override
- public int compare(AnalyticsDataRecord o1, AnalyticsDataRecord o2) {
- long t1 = (Long) o1.getValue("time");
- long t2 = (Long) o2.getValue("time");
- if (t1 < t2) {
- return -1;
- } else if (t1 > t2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- for (AnalyticsDataRecord record : records) {
- SensorData sensorData = new SensorData();
- sensorData.setTime((long) record.getValue("time"));
- sensorData.setValue("" + (float) record.getValue(ArduinoConstants.SENSOR_TEMPERATURE));
- sensorDatas.add(sensorData);
- }
- sensorDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.status(Response.Status.OK.getStatusCode()).entity(sensorDetails).build();
- } catch (DeviceManagementAnalyticsException e) {
+ List sortByFields = new ArrayList<>();
+ SortByField sortByField = new SortByField("time", SORT.ASC, false);
+ sortByFields.add(sortByField);
+ List sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
+ return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
+ } catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
- sensorDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(sensorDetails).build();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
}
}
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java
index a5cd8b5e80..291508f3c8 100644
--- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java
+++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/ArduinoManagerServiceImpl.java
@@ -32,7 +32,6 @@ import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
-import org.wso2.carbon.identity.jwt.client.extension.JWTClientManager;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
@@ -208,14 +207,14 @@ public class ArduinoManagerServiceImpl implements ArduinoManagerService {
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
ArduinoConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
}
- JWTClient jwtClient = JWTClientManager.getInstance().getJWTClient();
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + ArduinoConstants.DEVICE_TYPE + " device_" + deviceId;
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner,
scopes);
//create token
- String accessToken = accessTokenInfo.getAccess_token();
- String refreshToken = accessTokenInfo.getRefresh_token();
+ String accessToken = accessTokenInfo.getAccessToken();
+ String refreshToken = accessTokenInfo.getRefreshToken();
//Register the device with CDMF
boolean status = register(deviceId, deviceName);
if (!status) {
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/dto/SensorData.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/dto/SensorData.java
deleted file mode 100644
index 9e46a7cad1..0000000000
--- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/dto/SensorData.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.wso2.carbon.device.mgt.iot.arduino.service.impl.dto;
-
-import org.codehaus.jackson.annotate.JsonIgnoreProperties;
-
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-@XmlRootElement
-/**
- * This stores sensor event data for the device type.
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class SensorData {
-
- @XmlElement public Long time;
- @XmlElement public String key;
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public void setKey(String key) {
- this.key = key;
- }
-
- public Long getTime() {
- return time;
- }
-
- public void setTime(Long time) {
- this.time = time;
- }
-
- @XmlElement public String value;
-
-}
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/dto/SensorRecord.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/dto/SensorRecord.java
new file mode 100644
index 0000000000..2593ed83b2
--- /dev/null
+++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/dto/SensorRecord.java
@@ -0,0 +1,68 @@
+package org.wso2.carbon.device.mgt.iot.arduino.service.impl.dto;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@XmlRootElement
+/**
+ * This stores sensor event data for android sense.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SensorRecord {
+
+ @XmlElementWrapper(required = true, name = "values")
+ private Map values;
+
+ /** The id. */
+ @XmlElement(required = false, name = "id")
+ private String id;
+
+ /**
+ * Gets the values.
+ * @return the values
+ */
+ public Map getValues() {
+ return values;
+ }
+
+ /**
+ * Sets the values.
+ * @param values the values
+ */
+ public void setValues(Map values) {
+ this.values = values;
+ }
+
+ /**
+ * Sets the id.
+ * @param id the new id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Gets the id.
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String toString(){
+ List valueList = new ArrayList();
+ for (Map.Entry entry : values.entrySet()) {
+ valueList.add(entry.getKey() + ":" + entry.getValue());
+ }
+ return valueList.toString();
+
+ }
+
+}
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/APIUtil.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/APIUtil.java
index fb759f25a3..44ce396e58 100644
--- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/APIUtil.java
+++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/APIUtil.java
@@ -2,9 +2,25 @@ package org.wso2.carbon.device.mgt.iot.arduino.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest;
+import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
+import org.wso2.carbon.analytics.datasource.commons.Record;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.device.mgt.iot.arduino.service.impl.dto.SensorRecord;
+import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* This class provides utility functions used by REST-API.
@@ -23,12 +39,6 @@ public class APIUtil {
return username;
}
- public static String getTenantDomainOftheUser() {
- PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- String tenantDomain = threadLocalCarbonContext.getTenantDomain();
- return tenantDomain;
- }
-
public static DeviceManagementProviderService getDeviceManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceManagementProviderService deviceManagementProviderService =
@@ -41,6 +51,86 @@ public class APIUtil {
return deviceManagementProviderService;
}
+ public static AnalyticsDataAPI getAnalyticsDataAPI() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ AnalyticsDataAPI analyticsDataAPI =
+ (AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null);
+ if (analyticsDataAPI == null) {
+ String msg = "Analytics api service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return analyticsDataAPI;
+ }
+
+ public static List getAllEventsForDevice(String tableName, String query, List sortByFields) throws AnalyticsException {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
+ int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
+ if (eventCount == 0) {
+ return null;
+ }
+ AnalyticsDrillDownRequest drillDownRequest = new AnalyticsDrillDownRequest();
+ drillDownRequest.setQuery(query);
+ drillDownRequest.setTableName(tableName);
+ drillDownRequest.setRecordCount(eventCount);
+ if (sortByFields != null) {
+ drillDownRequest.setSortByFields(sortByFields);
+ }
+ List resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest);
+ List recordIds = getRecordIds(resultEntries);
+ AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
+ Map sensorDatas = createSensorData(AnalyticsDataServiceUtils.listRecords(
+ analyticsDataAPI, response));
+ List sortedSensorData = getSortedSensorData(sensorDatas, resultEntries);
+ return sortedSensorData;
+ }
+
+ private static List getRecordIds(List searchResults) {
+ List ids = new ArrayList<>();
+ for (SearchResultEntry searchResult : searchResults) {
+ ids.add(searchResult.getId());
+ }
+ return ids;
+ }
+
+ public static List getSortedSensorData(Map sensorDatas,
+ List searchResults) {
+ List sortedRecords = new ArrayList<>();
+ for (SearchResultEntry searchResultEntry : searchResults) {
+ sortedRecords.add(sensorDatas.get(searchResultEntry.getId()));
+ }
+ return sortedRecords;
+ }
+
+ /**
+ * Creates the SensorDatas from records.
+ *
+ * @param records the records
+ * @return the Map of SensorRecord
+ */
+ public static Map createSensorData(List records) {
+ Map sensorDatas = new HashMap<>();
+ for (Record record : records) {
+ SensorRecord sensorData = createSensorData(record);
+ sensorDatas.put(sensorData.getId(), sensorData);
+ }
+ return sensorDatas;
+ }
+
+ /**
+ * Create a SensorRecord object out of a Record object
+ *
+ * @param record the record object
+ * @return SensorRecord object
+ */
+ public static SensorRecord createSensorData(Record record) {
+ SensorRecord recordBean = new SensorRecord();
+ recordBean.setId(record.getId());
+ recordBean.setValues(record.getValues());
+ return recordBean;
+ }
+
public static APIManagementProviderService getAPIManagementProviderService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
APIManagementProviderService apiManagementProviderService =
@@ -52,4 +142,21 @@ public class APIUtil {
}
return apiManagementProviderService;
}
+
+ public static JWTClientManagerService getJWTClientManagerService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ JWTClientManagerService jwtClientManagerService =
+ (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
+ if (jwtClientManagerService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return jwtClientManagerService;
+ }
+
+ public static String getTenantDomainOftheUser() {
+ PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ return threadLocalCarbonContext.getTenantDomain();
+ }
}
diff --git a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ArduinoServiceUtils.java b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ArduinoServiceUtils.java
index 421541c41c..fcf49a80eb 100644
--- a/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ArduinoServiceUtils.java
+++ b/components/iot-plugins/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.api/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/impl/util/ArduinoServiceUtils.java
@@ -27,7 +27,7 @@ import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
+import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.arduino.plugin.constants.ArduinoConstants;
import javax.ws.rs.HttpMethod;
@@ -193,8 +193,8 @@ public class ArduinoServiceUtils {
String owner = ctx.getUsername();
Object metdaData[] = {owner, ArduinoConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
Object payloadData[] = {temperature};
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
+ EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx
+ .getOSGiService(EventsPublisherService.class, null);
if (deviceAnalyticsService != null) {
try {
deviceAnalyticsService.publishEvent(TEMPERATURE_STREAM_DEFINITION, "1.0.0", metdaData,
diff --git a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/DigitalDisplayManagerServiceImpl.java b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/DigitalDisplayManagerServiceImpl.java
index c15a16fb6f..3f0e2dbec6 100644
--- a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/DigitalDisplayManagerServiceImpl.java
+++ b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/DigitalDisplayManagerServiceImpl.java
@@ -35,7 +35,6 @@ import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
-import org.wso2.carbon.identity.jwt.client.extension.JWTClientManager;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
@@ -188,16 +187,13 @@ public class DigitalDisplayManagerServiceImpl implements DigitalDisplayManagerSe
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
DigitalDisplayConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
}
- JWTClient jwtClient = JWTClientManager.getInstance().getJWTClient();
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + DigitalDisplayConstants.DEVICE_TYPE + " device_" + deviceId;
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
- //create token
- String accessToken = accessTokenInfo.getAccess_token();
- String refreshToken = accessTokenInfo.getRefresh_token();
- //adding registering data
+ String accessToken = accessTokenInfo.getAccessToken();
+ String refreshToken = accessTokenInfo.getRefreshToken();
boolean status;
- //Register the device with CDMF
status = register(deviceId, deviceName);
if (!status) {
String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
diff --git a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/APIUtil.java b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/APIUtil.java
index 51b41cd72e..1c8855a328 100644
--- a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/APIUtil.java
+++ b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/APIUtil.java
@@ -5,6 +5,7 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
/**
* This class provides utility functions used by REST-API.
@@ -52,4 +53,17 @@ public class APIUtil {
}
return apiManagementProviderService;
}
+
+ public static JWTClientManagerService getJWTClientManagerService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ JWTClientManagerService jwtClientManagerService =
+ (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
+ if (jwtClientManagerService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return jwtClientManagerService;
+ }
+
}
diff --git a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java
index 4c4c5b2576..49b9111f14 100644
--- a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java
+++ b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.api/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/service/impl/util/DigitalDisplayMQTTConnector.java
@@ -5,12 +5,21 @@ import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+import org.wso2.carbon.base.MultitenantConstants;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.digitaldisplay.service.impl.model.ScreenShotModel;
import org.wso2.carbon.device.mgt.iot.digitaldisplay.service.impl.websocket.DigitalDisplayWebSocketServerEndPoint;
import org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin.constants.DigitalDisplayConstants;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
+import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
+import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
+import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
+import org.wso2.carbon.user.api.UserStoreException;
import java.util.HashMap;
import java.util.Map;
@@ -24,6 +33,8 @@ public class DigitalDisplayMQTTConnector extends MQTTTransportHandler {
private static final String MQTT_TOPIC_APPENDER = "wso2/iot";
private static final String subscribeTopic =
MQTT_TOPIC_APPENDER + "/" + DigitalDisplayConstants.DEVICE_TYPE + "/+/digital_display_publisher";
+ private static final String KEY_TYPE = "PRODUCTION";
+ private static final String EMPTY_STRING = "";
private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
@@ -41,24 +52,44 @@ public class DigitalDisplayMQTTConnector extends MQTTTransportHandler {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
+ DigitalDisplayConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
try {
- String brokerUsername = MqttConfig.getInstance().getMqttQueueUsername();
- String brokerPassword = MqttConfig.getInstance().getMqttQueuePassword();
- setUsernameAndPassword(brokerUsername, brokerPassword);
+ String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
+ .getRealmConfiguration().getAdminUserName();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
+ APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
+ String[] tags = {DigitalDisplayConstants.DEVICE_TYPE};
+ ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
+ DigitalDisplayConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
+ String scopes = "device_type_" + DigitalDisplayConstants.DEVICE_TYPE + " device_mqtt_connector";
+ AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
+ apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
+ //create token
+ String accessToken = accessTokenInfo.getAccessToken();
+ setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
+ subscribeToQueue();
} catch (TransportHandlerException e) {
- log.error("Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException ex) {
log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
}
- }
-
- try {
- subscribeToQueue();
- } catch (TransportHandlerException e) {
- log.warn("Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ } catch (JWTClientException e) {
+ log.error("Failed to retrieve token from JWT Client.", e);
+ return;
+ } catch (UserStoreException e) {
+ log.error("Failed to retrieve the user.", e);
+ return;
+ } catch (APIManagerException e) {
+ log.error("Failed to create an application and generate keys.", e);
+ return;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
}
}
}
diff --git a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/constants/DigitalDisplayConstants.java b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/constants/DigitalDisplayConstants.java
index 00ef15972c..cbfb6a2568 100644
--- a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/constants/DigitalDisplayConstants.java
+++ b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/constants/DigitalDisplayConstants.java
@@ -34,4 +34,5 @@ public class DigitalDisplayConstants {
public final static String GET_DEVICE_STATUS_CONSTANT = "get_device_status";
public final static String PUBLISH_TOPIC = "wso2/iot/digital_display/%s/digital_display_subscriber";
public static final String DATA_SOURCE_NAME = "jdbc/DigitalDisplayDM_DB";
+ public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
}
diff --git a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/impl/DigitalDisplayManagerService.java b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/impl/DigitalDisplayManagerService.java
index 593b16e91a..01681c8a3d 100644
--- a/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/impl/DigitalDisplayManagerService.java
+++ b/components/iot-plugins/digital-display-plugin/org.wso2.carbon.device.mgt.iot.digitaldisplay.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/digitaldisplay/plugin/impl/DigitalDisplayManagerService.java
@@ -30,7 +30,6 @@ import java.util.List;
public class DigitalDisplayManagerService implements DeviceManagementService{
private DeviceManager deviceManager;
- private final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
@Override
public String getType() {
@@ -39,7 +38,7 @@ public class DigitalDisplayManagerService implements DeviceManagementService{
@Override
public String getProviderTenantDomain() {
- return DEVICE_TYPE_PROVIDER_DOMAIN;
+ return DigitalDisplayConstants.DEVICE_TYPE_PROVIDER_DOMAIN;
}
@Override
diff --git a/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/DroneManagerServiceImpl.java b/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/DroneManagerServiceImpl.java
index 6066f2de28..a20c3e719e 100644
--- a/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/DroneManagerServiceImpl.java
+++ b/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/DroneManagerServiceImpl.java
@@ -36,7 +36,6 @@ import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
-import org.wso2.carbon.identity.jwt.client.extension.JWTClientManager;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
@@ -238,14 +237,14 @@ public class DroneManagerServiceImpl implements DroneManagerService {
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
DroneConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
}
- JWTClient jwtClient = JWTClientManager.getInstance().getJWTClient();
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
String scopes = "device_type_" + DroneConstants.DEVICE_TYPE + " device_" + deviceId;
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
//create token
- String accessToken = accessTokenInfo.getAccess_token();
- String refreshToken = accessTokenInfo.getRefresh_token();
+ String accessToken = accessTokenInfo.getAccessToken();
+ String refreshToken = accessTokenInfo.getRefreshToken();
//adding registering data
XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(APIUtil.getAuthenticatedUser() + "_" + deviceId);
diff --git a/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/util/APIUtil.java b/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/util/APIUtil.java
index 4af82a9ba9..6d8bb627d6 100644
--- a/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/util/APIUtil.java
+++ b/components/iot-plugins/drone-analyzer-plugin/org.wso2.carbon.device.mgt.iot.droneanalyzer.api/src/main/java/org/wso2/carbon/device/mgt/iot/droneanalyzer/service/impl/util/APIUtil.java
@@ -5,6 +5,7 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
/**
* This class provides utility functions used by REST-API.
@@ -52,4 +53,16 @@ public class APIUtil {
}
return apiManagementProviderService;
}
+
+ public static JWTClientManagerService getJWTClientManagerService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ JWTClientManagerService jwtClientManagerService =
+ (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
+ if (jwtClientManagerService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return jwtClientManagerService;
+ }
}
diff --git a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java
index a413bbf9c7..901374a991 100644
--- a/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java
+++ b/components/iot-plugins/iot-base-plugin/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/transport/mqtt/MQTTTransportHandler.java
@@ -252,19 +252,24 @@ public abstract class MQTTTransportHandler implements MqttCallback, TransportHan
* @see MQTTTransportHandler#publishToQueue(String, String, int, boolean)
*/
protected void publishToQueue(String topic, MqttMessage message) throws TransportHandlerException {
+ if (!isConnected()) {
+ connectToQueue();
+ }
try {
client.publish(topic, message);
if (log.isDebugEnabled()) {
- log.debug("Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
+ log.debug(
+ "Message: " + message.toString() + " to MQTT topic [" + topic + "] published successfully");
}
} catch (MqttException ex) {
String errorMsg = "MQTT Client Error whilst client [" + clientId + "] tried to publish to queue at " +
- "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
+ "[" + mqttBrokerEndPoint + "] under topic [" + topic + "]";
log.info(errorMsg);
throw new TransportHandlerException(errorMsg, ex);
}
}
+
/**
* This method is used to publish messages to the MQTT-Endpoint to which this client is connected to. It is via
* publishing to this broker that the messages are communicated to the device. This is an overloaded method with
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml
index 3a00959390..3c79211237 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/pom.xml
@@ -141,6 +141,11 @@
org.wso2.carbon.apimgt.application.extension
provided
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ provided
+
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java
index b744455d2f..7568823452 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiControllerServiceImpl.java
@@ -20,21 +20,19 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.AnalyticsDataRecord;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DeviceManagementAnalyticsException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
+import org.wso2.carbon.analytics.dataservice.commons.SORT;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
-import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.DeviceData;
-import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorData;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.transport.RaspberryPiMQTTConnector;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.RaspberrypiServiceUtils;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
-import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import javax.servlet.http.HttpServletRequest;
@@ -51,8 +49,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -107,7 +103,7 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response requestTemperature(@PathParam("deviceId") String deviceId) {
- SensorRecord sensorRecord = null;
+ org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = null;
if (log.isDebugEnabled()) {
log.debug("Sending request to read raspberrypi-temperature of device [" + deviceId + "] via ");
}
@@ -172,42 +168,19 @@ public class RaspberryPiControllerServiceImpl implements RaspberryPiControllerSe
@QueryParam("from") long from, @QueryParam("to") long to) {
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
- List sensorDatas = new ArrayList<>();
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
String query = "owner:" + user + " AND deviceId:" + deviceId + " AND deviceType:" +
RaspberrypiConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
String sensorTableName = RaspberrypiConstants.TEMPERATURE_EVENT_TABLE;
try {
- List records = deviceAnalyticsService.getAllEventsForDevice(sensorTableName, query);
- Collections.sort(records, new Comparator() {
- @Override
- public int compare(AnalyticsDataRecord o1, AnalyticsDataRecord o2) {
- long t1 = (Long) o1.getValue("time");
- long t2 = (Long) o2.getValue("time");
- if (t1 < t2) {
- return -1;
- } else if (t1 > t2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- for (AnalyticsDataRecord record : records) {
- SensorData sensorData = new SensorData();
- sensorData.setTime((long) record.getValue("time"));
- sensorData.setValue("" + (float) record.getValue(RaspberrypiConstants.SENSOR_TEMPERATURE));
- sensorDatas.add(sensorData);
- }
- SensorData[] sensorDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.ok().entity(sensorDetails).build();
- } catch (DeviceManagementAnalyticsException e) {
+ List sortByFields = new ArrayList<>();
+ SortByField sortByField = new SortByField("time", SORT.ASC, false);
+ sortByFields.add(sortByField);
+ List sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
+ return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
+ } catch (AnalyticsException e) {
String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
- SensorData[] sensorDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(sensorDetails).build();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
}
}
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java
index 6d02816947..48f51bc7e0 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java
@@ -38,7 +38,6 @@ import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
-import org.wso2.carbon.identity.jwt.client.extension.JWTClientManager;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
@@ -240,13 +239,13 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
}
- JWTClient jwtClient = JWTClientManager.getInstance().getJWTClient();
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + RaspberrypiConstants.DEVICE_TYPE + " device_" + deviceId;
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
//create token
- String accessToken = accessTokenInfo.getAccess_token();
- String refreshToken = accessTokenInfo.getRefresh_token();
+ String accessToken = accessTokenInfo.getAccessToken();
+ String refreshToken = accessTokenInfo.getRefreshToken();
//adding registering data
XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(owner + "_" + deviceId);
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/dto/SensorRecord.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/dto/SensorRecord.java
new file mode 100644
index 0000000000..18b01f29d2
--- /dev/null
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/dto/SensorRecord.java
@@ -0,0 +1,68 @@
+package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@XmlRootElement
+/**
+ * This stores sensor event data for android sense.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SensorRecord {
+
+ @XmlElementWrapper(required = true, name = "values")
+ private Map values;
+
+ /** The id. */
+ @XmlElement(required = false, name = "id")
+ private String id;
+
+ /**
+ * Gets the values.
+ * @return the values
+ */
+ public Map getValues() {
+ return values;
+ }
+
+ /**
+ * Sets the values.
+ * @param values the values
+ */
+ public void setValues(Map values) {
+ this.values = values;
+ }
+
+ /**
+ * Sets the id.
+ * @param id the new id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Gets the id.
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String toString(){
+ List valueList = new ArrayList();
+ for (Map.Entry entry : values.entrySet()) {
+ valueList.add(entry.getKey() + ":" + entry.getValue());
+ }
+ return valueList.toString();
+
+ }
+
+}
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java
index 1d01f36dda..d5bf225bec 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java
@@ -22,17 +22,26 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.RaspberrypiServiceUtils;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
+import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
+import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
+import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
+import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.util.Calendar;
@@ -41,6 +50,8 @@ import java.util.UUID;
public class RaspberryPiMQTTConnector extends MQTTTransportHandler {
private static Log log = LogFactory.getLog(RaspberryPiMQTTConnector.class);
private static final String subscribeTopic = "wso2/" + RaspberrypiConstants.DEVICE_TYPE + "/+/publisher";
+ private static final String KEY_TYPE = "PRODUCTION";
+ private static final String EMPTY_STRING = "";
private static final String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
@@ -54,25 +65,45 @@ public class RaspberryPiMQTTConnector extends MQTTTransportHandler {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
- try {
- String brokerUsername = MqttConfig.getInstance().getMqttQueueUsername();
- String brokerPassword = MqttConfig.getInstance().getMqttQueuePassword();
- setUsernameAndPassword(brokerUsername, brokerPassword);
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
+ RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
+ try {
+ String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
+ .getRealmConfiguration().getAdminUserName();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
+ APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
+ String[] tags = {RaspberrypiConstants.DEVICE_TYPE};
+ ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
+ RaspberrypiConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
+ String scopes = "device_type_" + RaspberrypiConstants.DEVICE_TYPE + " device_mqtt_connector";
+ AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
+ apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
+ //create token
+ String accessToken = accessTokenInfo.getAccessToken();
+ setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
- } catch (TransportHandlerException e) {
- log.error("Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
- try {
- Thread.sleep(timeoutInterval);
- } catch (InterruptedException ex) {
- log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
- }
- }
-
- try {
subscribeToQueue();
- } catch (TransportHandlerException e) {
- log.warn("Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
- }
+ } catch (TransportHandlerException e) {
+ log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ try {
+ Thread.sleep(timeoutInterval);
+ } catch (InterruptedException ex) {
+ log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
+ }
+ } catch (JWTClientException e) {
+ log.error("Failed to retrieve token from JWT Client.", e);
+ return;
+ } catch (UserStoreException e) {
+ log.error("Failed to retrieve the user.", e);
+ return;
+ } catch (APIManagerException e) {
+ log.error("Failed to create an application and generate keys.", e);
+ return;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
}
}
};
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java
index b0e91eb495..9cdb687bb3 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/APIUtil.java
@@ -2,9 +2,25 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest;
+import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
+import org.wso2.carbon.analytics.datasource.commons.Record;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.dto.SensorRecord;
+import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* This class provides utility functions used by REST-API.
@@ -23,12 +39,6 @@ public class APIUtil {
return username;
}
- public static String getTenantDomainOftheUser() {
- PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- String tenantDomain = threadLocalCarbonContext.getTenantDomain();
- return tenantDomain;
- }
-
public static DeviceManagementProviderService getDeviceManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceManagementProviderService deviceManagementProviderService =
@@ -41,10 +51,90 @@ public class APIUtil {
return deviceManagementProviderService;
}
+ public static AnalyticsDataAPI getAnalyticsDataAPI() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ AnalyticsDataAPI analyticsDataAPI =
+ (AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null);
+ if (analyticsDataAPI == null) {
+ String msg = "Analytics api service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return analyticsDataAPI;
+ }
+
+ public static List getAllEventsForDevice(String tableName, String query, List sortByFields) throws AnalyticsException {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
+ int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
+ if (eventCount == 0) {
+ return null;
+ }
+ AnalyticsDrillDownRequest drillDownRequest = new AnalyticsDrillDownRequest();
+ drillDownRequest.setQuery(query);
+ drillDownRequest.setTableName(tableName);
+ drillDownRequest.setRecordCount(eventCount);
+ if (sortByFields != null) {
+ drillDownRequest.setSortByFields(sortByFields);
+ }
+ List resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest);
+ List recordIds = getRecordIds(resultEntries);
+ AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
+ Map sensorDatas = createSensorData(AnalyticsDataServiceUtils.listRecords(
+ analyticsDataAPI, response));
+ List sortedSensorData = getSortedSensorData(sensorDatas, resultEntries);
+ return sortedSensorData;
+ }
+
+ private static List getRecordIds(List searchResults) {
+ List ids = new ArrayList<>();
+ for (SearchResultEntry searchResult : searchResults) {
+ ids.add(searchResult.getId());
+ }
+ return ids;
+ }
+
+ public static List getSortedSensorData(Map sensorDatas,
+ List searchResults) {
+ List sortedRecords = new ArrayList<>();
+ for (SearchResultEntry searchResultEntry : searchResults) {
+ sortedRecords.add(sensorDatas.get(searchResultEntry.getId()));
+ }
+ return sortedRecords;
+ }
+
+ /**
+ * Creates the SensorDatas from records.
+ *
+ * @param records the records
+ * @return the Map of SensorRecord
+ */
+ public static Map createSensorData(List records) {
+ Map sensorDatas = new HashMap<>();
+ for (Record record : records) {
+ SensorRecord sensorData = createSensorData(record);
+ sensorDatas.put(sensorData.getId(), sensorData);
+ }
+ return sensorDatas;
+ }
+
+ /**
+ * Create a SensorRecord object out of a Record object
+ *
+ * @param record the record object
+ * @return SensorRecord object
+ */
+ public static SensorRecord createSensorData(Record record) {
+ SensorRecord recordBean = new SensorRecord();
+ recordBean.setId(record.getId());
+ recordBean.setValues(record.getValues());
+ return recordBean;
+ }
+
public static APIManagementProviderService getAPIManagementProviderService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
APIManagementProviderService apiManagementProviderService =
- (APIManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null);
+ (APIManagementProviderService) ctx.getOSGiService(APIManagementProviderService.class, null);
if (apiManagementProviderService == null) {
String msg = "API management provider service has not initialized.";
log.error(msg);
@@ -52,4 +142,21 @@ public class APIUtil {
}
return apiManagementProviderService;
}
+
+ public static JWTClientManagerService getJWTClientManagerService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ JWTClientManagerService jwtClientManagerService =
+ (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
+ if (jwtClientManagerService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return jwtClientManagerService;
+ }
+
+ public static String getTenantDomainOftheUser() {
+ PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ return threadLocalCarbonContext.getTenantDomain();
+ }
}
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/RaspberrypiServiceUtils.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/RaspberrypiServiceUtils.java
index cb4d52c487..1992a0e013 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/RaspberrypiServiceUtils.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/RaspberrypiServiceUtils.java
@@ -27,7 +27,7 @@ import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
+import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
@@ -211,8 +211,8 @@ public class RaspberrypiServiceUtils {
public static boolean publishToDAS(String deviceId, float temperature) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService(
- DeviceAnalyticsService.class, null);
+ EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx.getOSGiService(
+ EventsPublisherService.class, null);
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
Object metdaData[] = {owner, RaspberrypiConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
Object payloadData[] = {temperature};
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java
index c6534e46fb..a301ac6fb9 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java
@@ -35,5 +35,6 @@ public class RaspberrypiConstants {
//sensor events summerized table name
public static final String TEMPERATURE_EVENT_TABLE = "ORG_WSO2_IOT_DEVICES_TEMPERATURE";
public static final String DATA_SOURCE_NAME = "jdbc/RaspberryPiDM_DB";
+ public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
}
diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java
index 963475d4ca..bfbe62d148 100644
--- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java
+++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/impl/RaspberrypiManagerService.java
@@ -33,7 +33,6 @@ import java.util.List;
public class RaspberrypiManagerService implements DeviceManagementService {
private DeviceManager deviceManager;
- private final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
@Override
public String getType() {
@@ -42,7 +41,7 @@ public class RaspberrypiManagerService implements DeviceManagementService {
@Override
public String getProviderTenantDomain() {
- return DEVICE_TYPE_PROVIDER_DOMAIN;
+ return RaspberrypiConstants.DEVICE_TYPE_PROVIDER_DOMAIN;
}
@Override
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml
index e50829cf85..291381f857 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/pom.xml
@@ -245,6 +245,11 @@
org.wso2.carbon.apimgt.application.extension
provided
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ provided
+
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java
index b776a3e634..f49a2606eb 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmControllerServiceImpl.java
@@ -20,27 +20,26 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.dataservice.commons.SORT;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.certificate.mgt.core.dto.SCEPResponse;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
-import org.wso2.carbon.context.PrivilegedCarbonContext;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.AnalyticsDataRecord;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DeviceManagementAnalyticsException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.Feature;
import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
-import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord;
import org.wso2.carbon.device.mgt.iot.service.IoTServerStartupListener;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.DeviceData;
-import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorData;
+import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport.VirtualFireAlarmMQTTConnector;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.transport.VirtualFireAlarmXMPPConnector;
+import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.scep.ContentType;
@@ -62,8 +61,6 @@ import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -90,10 +87,142 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
// holds a mapping of the IP addresses to Device-IDs for HTTP communication
private ConcurrentHashMap deviceToIpMap = new ConcurrentHashMap<>();
+<<<<<<< HEAD
@POST
@Path("device/register/{deviceId}/{ip}/{port}")
public Response registerDeviceIP(@PathParam("deviceId") String deviceId, @PathParam("ip") String deviceIP,
@PathParam("port") String devicePort, @Context HttpServletRequest request) {
+=======
+ private boolean waitForServerStartup() {
+ while (!IoTServerStartupListener.isServerReady()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Fetches the `SecurityManager` specific to this VirtualFirealarm controller service.
+ *
+ * @return the 'SecurityManager' instance bound to the 'securityManager' variable of this service.
+ */
+ @SuppressWarnings("Unused")
+ public SecurityManager getSecurityManager() {
+ return securityManager;
+ }
+
+ /**
+ * Sets the `securityManager` variable of this VirtualFirealarm controller service.
+ *
+ * @param securityManager a 'SecurityManager' object that handles the encryption, decryption, signing and validation
+ * of incoming messages from VirtualFirealarm device-types.
+ */
+ @SuppressWarnings("Unused")
+ public void setSecurityManager(SecurityManager securityManager) {
+ this.securityManager = securityManager;
+ securityManager.initVerificationManager();
+ }
+
+ /**
+ * Fetches the `VirtualFireAlarmXMPPConnector` specific to this VirtualFirealarm controller service.
+ *
+ * @return the 'VirtualFireAlarmXMPPConnector' instance bound to the 'virtualFireAlarmXMPPConnector' variable of
+ * this service.
+ */
+ @SuppressWarnings("Unused")
+ public VirtualFireAlarmXMPPConnector getVirtualFireAlarmXMPPConnector() {
+ return virtualFireAlarmXMPPConnector;
+ }
+
+ /**
+ * Sets the `virtualFireAlarmXMPPConnector` variable of this VirtualFirealarm controller service.
+ *
+ * @param virtualFireAlarmXMPPConnector a 'VirtualFireAlarmXMPPConnector' object that handles all XMPP related
+ * communications of any connected VirtualFirealarm device-type
+ */
+ @SuppressWarnings("Unused")
+ public void setVirtualFireAlarmXMPPConnector(
+ final VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector) {
+ Runnable connector = new Runnable() {
+ public void run() {
+ if (waitForServerStartup()) {
+ return;
+ }
+ VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmXMPPConnector = virtualFireAlarmXMPPConnector;
+
+ if (XmppConfig.getInstance().isEnabled()) {
+ Runnable xmppStarter = new Runnable() {
+ @Override
+ public void run() {
+ virtualFireAlarmXMPPConnector.initConnector();
+ virtualFireAlarmXMPPConnector.connect();
+ }
+ };
+
+ Thread xmppStarterThread = new Thread(xmppStarter);
+ xmppStarterThread.setDaemon(true);
+ xmppStarterThread.start();
+ } else {
+ log.warn("XMPP disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmXMPPConnector not started.");
+ }
+ }
+ };
+ Thread connectorThread = new Thread(connector);
+ connectorThread.setDaemon(true);
+ connectorThread.start();
+ }
+
+ /**
+ * Fetches the `VirtualFireAlarmMQTTConnector` specific to this VirtualFirealarm controller service.
+ *
+ * @return the 'VirtualFireAlarmMQTTConnector' instance bound to the 'virtualFireAlarmMQTTConnector' variable of
+ * this service.
+ */
+ @SuppressWarnings("Unused")
+ public VirtualFireAlarmMQTTConnector getVirtualFireAlarmMQTTConnector() {
+ return virtualFireAlarmMQTTConnector;
+ }
+
+ /**
+ * Sets the `virtualFireAlarmMQTTConnector` variable of this VirtualFirealarm controller service.
+ *
+ * @param virtualFireAlarmMQTTConnector a 'VirtualFireAlarmMQTTConnector' object that handles all MQTT related
+ * communications of any connected VirtualFirealarm device-type
+ */
+ @SuppressWarnings("Unused")
+ public void setVirtualFireAlarmMQTTConnector(
+ final VirtualFireAlarmMQTTConnector virtualFireAlarmMQTTConnector) {
+ Runnable connector = new Runnable() {
+ public void run() {
+ if (waitForServerStartup()) {
+ return;
+ }
+ VirtualFireAlarmControllerServiceImpl.this.virtualFireAlarmMQTTConnector = virtualFireAlarmMQTTConnector;
+ //The delay is added for the server starts up.
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ if (MqttConfig.getInstance().isEnabled()) {
+ synchronized (virtualFireAlarmMQTTConnector) {
+ virtualFireAlarmMQTTConnector.connect();
+ }
+ } else {
+ log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, VirtualFireAlarmMQTTConnector not started.");
+ }
+ }
+ };
+ Thread connectorThread = new Thread(connector);
+ connectorThread.setDaemon(true);
+ connectorThread.start();
+ }
+
+ public Response registerDeviceIP(String deviceId, String deviceIP, String devicePort, HttpServletRequest request) {
+>>>>>>> 8a7d4bb6e0a9b94b8a5c9ca8d6d21c3924b2c677
String result;
if (log.isDebugEnabled()) {
log.debug("Got register call from IP: " + deviceIP + " for Device ID: " + deviceId);
@@ -148,6 +277,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
}
}
+<<<<<<< HEAD
@GET
@Path("device/{deviceId}/temperature")
@Consumes(MediaType.APPLICATION_JSON)
@@ -155,6 +285,10 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
public Response requestTemperature(@PathParam("deviceId") String deviceId,
@QueryParam("protocol") String protocol) {
SensorRecord sensorRecord = null;
+=======
+ public Response requestTemperature(String deviceId, String protocol) {
+ org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord sensorRecord = null;
+>>>>>>> 8a7d4bb6e0a9b94b8a5c9ca8d6d21c3924b2c677
String protocolString = protocol.toUpperCase();
if (log.isDebugEnabled()) {
log.debug("Sending request to read virtual-firealarm-temperature of device " +
@@ -308,6 +442,7 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
return Response.serverError().build();
}
+<<<<<<< HEAD
@Path("device/stats/{deviceId}/sensors/{sensorName}")
@GET
@Consumes("application/json")
@@ -316,45 +451,26 @@ public class VirtualFireAlarmControllerServiceImpl implements VirtualFireAlarmCo
@PathParam("sensorName") String sensor,
@QueryParam("username") String user, @QueryParam("from") long from,
@QueryParam("to") long to) {
+=======
+ public Response getVirtualFirealarmStats(String deviceId, String sensor, String user, long from, long to) {
+ String fromDate = String.valueOf(from);
+ String toDate = String.valueOf(to);
+ String query = "owner:" + user + " AND deviceId:" + deviceId + " AND deviceType:" +
+ VirtualFireAlarmConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
+ String sensorTableName = getSensorEventTableName(sensor);
+>>>>>>> 8a7d4bb6e0a9b94b8a5c9ca8d6d21c3924b2c677
try {
- String fromDate = String.valueOf(from);
- String toDate = String.valueOf(to);
- List sensorDatas = new ArrayList<>();
- PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx
- .getOSGiService(DeviceAnalyticsService.class, null);
- String query = "owner:" + user + " AND deviceId:" + deviceId + " AND deviceType:" +
- VirtualFireAlarmConstants.DEVICE_TYPE + " AND time : [" + fromDate + " TO " + toDate + "]";
- String sensorTableName = getSensorEventTableName(sensor);
if (sensorTableName != null) {
- List records = deviceAnalyticsService.getAllEventsForDevice(sensorTableName, query);
- Collections.sort(records, new Comparator() {
- @Override
- public int compare(AnalyticsDataRecord o1, AnalyticsDataRecord o2) {
- long t1 = (Long) o1.getValue("time");
- long t2 = (Long) o2.getValue("time");
- if (t1 < t2) {
- return -1;
- } else if (t1 > t2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- for (AnalyticsDataRecord record : records) {
- SensorData sensorData = new SensorData();
- sensorData.setTime((long) record.getValue("time"));
- sensorData.setValue("" + (float) record.getValue(sensor));
- sensorDatas.add(sensorData);
- }
- SensorData[] sensorDetails = sensorDatas.toArray(new SensorData[sensorDatas.size()]);
- return Response.ok().entity(sensorDetails).build();
+ List sortByFields = new ArrayList<>();
+ SortByField sortByField = new SortByField("time", SORT.ASC, false);
+ sortByFields.add(sortByField);
+ List sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields);
+ return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build();
}
- } catch (DeviceManagementAnalyticsException e) {
- String errorMsg = "Error on retrieving stats on table for sensor name" + sensor;
+ } catch (AnalyticsException e) {
+ String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query;
log.error(errorMsg);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build();
}
return Response.status(Response.Status.BAD_REQUEST).build();
}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java
index 5656a83bd0..284a2937ac 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/VirtualFireAlarmManagerServiceImpl.java
@@ -36,7 +36,6 @@ import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
-import org.wso2.carbon.identity.jwt.client.extension.JWTClientManager;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
@@ -235,12 +234,12 @@ public class VirtualFireAlarmManagerServiceImpl implements VirtualFireAlarmManag
apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
}
- JWTClient jwtClient = JWTClientManager.getInstance().getJWTClient();
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
String scopes = "device_type_" + VirtualFireAlarmConstants.DEVICE_TYPE + " device_" + deviceId;
AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
apiApplicationKey.getConsumerSecret(), owner, scopes);
- String accessToken = accessTokenInfo.getAccess_token();
- String refreshToken = accessTokenInfo.getRefresh_token();
+ String accessToken = accessTokenInfo.getAccessToken();
+ String refreshToken = accessTokenInfo.getRefreshToken();
//adding registering data
XmppAccount newXmppAccount = new XmppAccount();
newXmppAccount.setAccountName(owner + "_" + deviceId);
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/SensorData.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/SensorData.java
deleted file mode 100644
index e5e99609fe..0000000000
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/SensorData.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto;
-
-import org.codehaus.jackson.annotate.JsonIgnoreProperties;
-
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-
-@XmlRootElement
-/**
- * This stores sensor event data for the device type.
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class SensorData {
-
- @XmlElement public Long time;
- @XmlElement public String key;
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public void setKey(String key) {
- this.key = key;
- }
-
- public Long getTime() {
- return time;
- }
-
- public void setTime(Long time) {
- this.time = time;
- }
-
- @XmlElement public String value;
-
-}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/SensorRecord.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/SensorRecord.java
new file mode 100644
index 0000000000..e1f46d2d79
--- /dev/null
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/dto/SensorRecord.java
@@ -0,0 +1,68 @@
+package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@XmlRootElement
+/**
+ * This stores sensor event data for android sense.
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SensorRecord {
+
+ @XmlElementWrapper(required = true, name = "values")
+ private Map values;
+
+ /** The id. */
+ @XmlElement(required = false, name = "id")
+ private String id;
+
+ /**
+ * Gets the values.
+ * @return the values
+ */
+ public Map getValues() {
+ return values;
+ }
+
+ /**
+ * Sets the values.
+ * @param values the values
+ */
+ public void setValues(Map values) {
+ this.values = values;
+ }
+
+ /**
+ * Sets the id.
+ * @param id the new id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Gets the id.
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String toString(){
+ List valueList = new ArrayList();
+ for (Map.Entry entry : values.entrySet()) {
+ valueList.add(entry.getKey() + ":" + entry.getValue());
+ }
+ return valueList.toString();
+
+ }
+
+}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java
index e4e8e3cb8e..6cbd9af812 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/transport/VirtualFireAlarmMQTTConnector.java
@@ -22,6 +22,10 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
@@ -32,9 +36,14 @@ import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException;
import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
+import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.APIUtil;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.SecurityManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util.VirtualFireAlarmServiceUtils;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
+import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
+import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
+import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
+import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.nio.charset.StandardCharsets;
@@ -64,6 +73,8 @@ public class VirtualFireAlarmMQTTConnector extends MQTTTransportHandler {
// wildcard (+) is in place for device_owner & device_id
private static String subscribeTopic = "wso2/" + VirtualFireAlarmConstants.DEVICE_TYPE + "/+/publisher";
private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
+ private static final String KEY_TYPE = "PRODUCTION";
+ private static final String EMPTY_STRING = "";
/**
* Default constructor for the VirtualFirealarmMQTTConnector.
@@ -83,24 +94,44 @@ public class VirtualFireAlarmMQTTConnector extends MQTTTransportHandler {
Runnable connector = new Runnable() {
public void run() {
while (!isConnected()) {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
+ VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN, true);
try {
- String brokerUsername = MqttConfig.getInstance().getMqttQueueUsername();
- String brokerPassword = MqttConfig.getInstance().getMqttQueuePassword();
- setUsernameAndPassword(brokerUsername, brokerPassword);
+ String applicationUsername = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
+ .getRealmConfiguration().getAdminUserName();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(applicationUsername);
+ APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
+ String[] tags = {VirtualFireAlarmConstants.DEVICE_TYPE};
+ ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
+ VirtualFireAlarmConstants.DEVICE_TYPE, tags, KEY_TYPE, applicationUsername, true);
+ JWTClient jwtClient = APIUtil.getJWTClientManagerService().getJWTClient();
+ String scopes = "device_type_" + VirtualFireAlarmConstants.DEVICE_TYPE + " device_mqtt_connector";
+ AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(apiApplicationKey.getConsumerKey(),
+ apiApplicationKey.getConsumerSecret(), applicationUsername, scopes);
+ //create token
+ String accessToken = accessTokenInfo.getAccessToken();
+ setUsernameAndPassword(accessToken, EMPTY_STRING);
connectToQueue();
+ subscribeToQueue();
} catch (TransportHandlerException e) {
- log.error("Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ log.error("Connection/Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
try {
Thread.sleep(timeoutInterval);
} catch (InterruptedException ex) {
log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex);
}
- }
-
- try {
- subscribeToQueue();
- } catch (TransportHandlerException e) {
- log.warn("Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e);
+ } catch (JWTClientException e) {
+ log.error("Failed to retrieve token from JWT Client.", e);
+ return;
+ } catch (UserStoreException e) {
+ log.error("Failed to retrieve the user.", e);
+ return;
+ } catch (APIManagerException e) {
+ log.error("Failed to create an application and generate keys.", e);
+ return;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
}
}
}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java
index 8f92c500af..ed6f9892c8 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/APIUtil.java
@@ -2,9 +2,25 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
+import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest;
+import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
+import org.wso2.carbon.analytics.dataservice.commons.SortByField;
+import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils;
+import org.wso2.carbon.analytics.datasource.commons.Record;
+import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.dto.SensorRecord;
+import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* This class provides utility functions used by REST-API.
@@ -23,12 +39,6 @@ public class APIUtil {
return username;
}
- public static String getTenantDomainOftheUser() {
- PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- String tenantDomain = threadLocalCarbonContext.getTenantDomain();
- return tenantDomain;
- }
-
public static DeviceManagementProviderService getDeviceManagementService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
DeviceManagementProviderService deviceManagementProviderService =
@@ -41,6 +51,86 @@ public class APIUtil {
return deviceManagementProviderService;
}
+ public static AnalyticsDataAPI getAnalyticsDataAPI() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ AnalyticsDataAPI analyticsDataAPI =
+ (AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null);
+ if (analyticsDataAPI == null) {
+ String msg = "Analytics api service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return analyticsDataAPI;
+ }
+
+ public static List getAllEventsForDevice(String tableName, String query, List sortByFields) throws AnalyticsException {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI();
+ int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query);
+ if (eventCount == 0) {
+ return null;
+ }
+ AnalyticsDrillDownRequest drillDownRequest = new AnalyticsDrillDownRequest();
+ drillDownRequest.setQuery(query);
+ drillDownRequest.setTableName(tableName);
+ drillDownRequest.setRecordCount(eventCount);
+ if (sortByFields != null) {
+ drillDownRequest.setSortByFields(sortByFields);
+ }
+ List resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest);
+ List recordIds = getRecordIds(resultEntries);
+ AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
+ Map sensorDatas = createSensorData(AnalyticsDataServiceUtils.listRecords(
+ analyticsDataAPI, response));
+ List sortedSensorData = getSortedSensorData(sensorDatas, resultEntries);
+ return sortedSensorData;
+ }
+
+ private static List getRecordIds(List searchResults) {
+ List ids = new ArrayList<>();
+ for (SearchResultEntry searchResult : searchResults) {
+ ids.add(searchResult.getId());
+ }
+ return ids;
+ }
+
+ public static List getSortedSensorData(Map sensorDatas,
+ List searchResults) {
+ List sortedRecords = new ArrayList<>();
+ for (SearchResultEntry searchResultEntry : searchResults) {
+ sortedRecords.add(sensorDatas.get(searchResultEntry.getId()));
+ }
+ return sortedRecords;
+ }
+
+ /**
+ * Creates the SensorDatas from records.
+ *
+ * @param records the records
+ * @return the Map of SensorRecord
+ */
+ public static Map createSensorData(List records) {
+ Map sensorDatas = new HashMap<>();
+ for (Record record : records) {
+ SensorRecord sensorData = createSensorData(record);
+ sensorDatas.put(sensorData.getId(), sensorData);
+ }
+ return sensorDatas;
+ }
+
+ /**
+ * Create a SensorRecord object out of a Record object
+ *
+ * @param record the record object
+ * @return SensorRecord object
+ */
+ public static SensorRecord createSensorData(Record record) {
+ SensorRecord recordBean = new SensorRecord();
+ recordBean.setId(record.getId());
+ recordBean.setValues(record.getValues());
+ return recordBean;
+ }
+
public static APIManagementProviderService getAPIManagementProviderService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
APIManagementProviderService apiManagementProviderService =
@@ -52,4 +142,21 @@ public class APIUtil {
}
return apiManagementProviderService;
}
+
+ public static JWTClientManagerService getJWTClientManagerService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ JWTClientManagerService jwtClientManagerService =
+ (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
+ if (jwtClientManagerService == null) {
+ String msg = "JWT Client manager service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return jwtClientManagerService;
+ }
+
+ public static String getTenantDomainOftheUser() {
+ PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ return threadLocalCarbonContext.getTenantDomain();
+ }
}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java
index 4b8f1d2adb..21f27acf99 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.api/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/impl/util/VirtualFireAlarmServiceUtils.java
@@ -30,7 +30,7 @@ import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
-import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService;
+import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin.constants.VirtualFireAlarmConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl.exception.VirtualFireAlarmException;
@@ -242,8 +242,8 @@ public class VirtualFireAlarmServiceUtils {
public static boolean publishToDAS(String deviceId, float temperature) {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
- DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService(
- DeviceAnalyticsService.class, null);
+ EventsPublisherService deviceAnalyticsService = (EventsPublisherService) ctx.getOSGiService(
+ EventsPublisherService.class, null);
if (deviceAnalyticsService != null) {
String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
Object metdaData[] = {owner, VirtualFireAlarmConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java
index 3b8b5e2a82..5c4f03dd0f 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/constants/VirtualFireAlarmConstants.java
@@ -37,4 +37,5 @@ public class VirtualFireAlarmConstants {
//sensor events summerized table name for humidity
public static final String HUMIDITY_EVENT_TABLE = "DEVICE_HUMIDITY_SUMMARY";
public static final String DATA_SOURCE_NAME = "jdbc/VirtualFireAlarmDM_DB";
+ public final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
}
diff --git a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java
index 214afd8491..1667619a0c 100644
--- a/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java
+++ b/components/iot-plugins/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.plugin/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/plugin/impl/VirtualFireAlarmManagerService.java
@@ -32,7 +32,6 @@ import java.util.List;
public class VirtualFireAlarmManagerService implements DeviceManagementService{
private DeviceManager deviceManager;
- private final static String DEVICE_TYPE_PROVIDER_DOMAIN = "carbon.super";
@Override
public String getType() {
@@ -42,7 +41,7 @@ public class VirtualFireAlarmManagerService implements DeviceManagementService{
@Override
public String getProviderTenantDomain() {
- return DEVICE_TYPE_PROVIDER_DOMAIN;
+ return VirtualFireAlarmConstants.DEVICE_TYPE_PROVIDER_DOMAIN;
}
@Override
diff --git a/pom.xml b/pom.xml
index c0df257a15..7c0a7be07c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -256,7 +256,6 @@
org.wso2.carbon.devicemgt
org.wso2.carbon.device.mgt.analytics.data.publisher
${carbon.device.mgt.version}
- provided
org.wso2.carbon.devicemgt
@@ -310,6 +309,11 @@
org.wso2.carbon.databridge.commons
${carbon.analytics.common.version}
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ ${carbon.analytics.version}
+
@@ -440,7 +444,6 @@
${carbon.devicemgt.plugins.version}
-
org.wso2.carbon.analytics
@@ -1042,7 +1045,7 @@
7.0.34.wso2v2
- 2.7.16
+ 2.6.1
2.5.11
1.9.0
1.1.1
@@ -1061,6 +1064,7 @@
5.0.7
+ [5.0.7, 6.0.0)
4.5.0
@@ -1092,7 +1096,7 @@
5.0.11
[5.0.11,6.0.0)
- 1.0.5
+ 1.0.6-ALPHA
[1.0.5,2.0.0]
@@ -1127,7 +1131,6 @@
7.0.59.wso2v1
-
github-scm