Unverified Commit 4763d797 authored by Javier Guerra's avatar Javier Guerra Committed by GitHub

Merge pull request #17 from openconnectivity/develop

Merge develop into master
parents a54fbb1f 2db78a88
......@@ -11,7 +11,7 @@
# Constants
PROJECT_NAME="otgc"
VERSION="2.7.0"
VERSION="2.8.0"
program=$0
......
......@@ -6,7 +6,7 @@
<groupId>otgc</groupId>
<artifactId>otgc</artifactId>
<version>2.7.0</version>
<version>2.8.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......
......@@ -62,8 +62,9 @@ public class DoxsRepository {
} else if (oxm == OcfOxmType.OC_OXMTYPE_RDP) {
ret = OCObt.requestRandomPin(uuid, (OCUuid ocUuid, int status) -> {
if (status >= 0) {
LOG.debug("Successfully request Random PIN " + OCUuidUtil.uuidToString(ocUuid));
String pin = randomPinHandler.handler();
String id = OCUuidUtil.uuidToString(ocUuid);
LOG.debug("Successfully request Random PIN " + id);
String pin = randomPinHandler.handler(id);
if (OCObt.performRandomPinOtm(uuid, pin, handler) != -1){
emitter.onComplete();
} else {
......
......@@ -162,7 +162,10 @@ public class IotivityRepository {
deviceDao.insert(new DeviceEntity(deviceId, device.getName(), endpoints, DeviceType.UNOWNED, Device.NOTHING_PERMITS));
}
unownedDevices.add(new Device(DeviceType.UNOWNED, deviceId, new OcDeviceInfo(), endpoints, Device.NOTHING_PERMITS));
Device device1 = new Device(DeviceType.UNOWNED, deviceId, new OcDeviceInfo(), endpoints, Device.NOTHING_PERMITS);
if (!unownedDevices.contains(device1)) {
unownedDevices.add(device1);
}
};
int ret;
......@@ -202,7 +205,10 @@ public class IotivityRepository {
deviceDao.insert(new DeviceEntity(deviceId, device.getName(), endpoints, DeviceType.OWNED_BY_SELF, Device.FULL_PERMITS));
}
ownedDevices.add(new Device(DeviceType.OWNED_BY_SELF, deviceId, new OcDeviceInfo(), endpoints, Device.FULL_PERMITS));
Device device1 = new Device(DeviceType.OWNED_BY_SELF, deviceId, new OcDeviceInfo(), endpoints, Device.FULL_PERMITS);
if (!ownedDevices.contains(device1)) {
ownedDevices.add(device1);
}
};
int ret;
......@@ -568,6 +574,38 @@ public class IotivityRepository {
});
}
public Completable post(String host, String uri, String deviceId, Map<String, Object> values) {
return Completable.create(emitter -> {
OCEndpoint ep = OCEndpointUtil.stringToEndpoint(host, new String[1]);
OCUuid uuid = OCUuidUtil.stringToUuid(deviceId);
OCEndpointUtil.setDi(ep, uuid);
OCResponseHandler handler = (OCClientResponse response) -> {
OCStatus code = response.getCode();
if (code == OCStatus.OC_STATUS_OK
|| code == OCStatus.OC_STATUS_CHANGED) {
emitter.onComplete();
} else {
emitter.onError(new Exception("POST " + uri + " error - code: " + code));
}
};
if (OCMain.initPost(uri, ep, null, handler, OCQos.HIGH_QOS)) {
CborEncoder root = OCRep.beginRootObject();
parseOCRepresentionToCbor(root, values);
OCRep.endRootObject();
if (!OCMain.doPost()) {
emitter.onError(new Exception("Do POST " + uri + " error"));
}
} else {
emitter.onError(new Exception("Init POST " + uri + " error"));
}
OCEndpointUtil.freeEndpoint(ep);
});
}
private void parseOCRepresentionToCbor(CborEncoder parent, OCRepresentation rep, Object valueArray) {
while (rep != null) {
switch (rep.getType()) {
......@@ -592,6 +630,9 @@ public class IotivityRepository {
case OC_REP_STRING_ARRAY:
OCRep.setStringArray(parent, rep.getName(), (String[])valueArray);
break;
case OC_REP_BOOL_ARRAY:
OCRep.setBooleanArray(parent, rep.getName(), (boolean[])valueArray);
break;
default:
break;
}
......@@ -600,6 +641,46 @@ public class IotivityRepository {
}
}
private void parseOCRepresentionToCbor(CborEncoder parent, Map<String, Object> values) {
for (String key : values.keySet()) {
if (values.get(key) instanceof Boolean) {
OCRep.setBoolean(parent, key, (boolean)values.get(key));
} else if (values.get(key) instanceof Integer) {
OCRep.setLong(parent, key, (Integer)values.get(key));
} else if (values.get(key) instanceof Double) {
OCRep.setDouble(parent, key, (Double)values.get(key));
} else if (values.get(key) instanceof String) {
OCRep.setTextString(parent, key, (String)values.get(key));
} else if (values.get(key) instanceof List) {
if (((List) values.get(key)).get(0) instanceof String) {
String[] ret = new String[((List<String>)values.get(key)).size()];
for (int i=0; i< ((List<String>)values.get(key)).size(); i++) {
ret[i] = ((List<String>)values.get(key)).get(i);
}
OCRep.setStringArray(parent, key, ret);
} else if (((List) values.get(key)).get(0) instanceof Integer) {
long[] ret = new long[((List<Integer>)values.get(key)).size()];
for (int i=0; i< ((List<Integer>)values.get(key)).size(); i++) {
ret[i] = ((List<Integer>)values.get(key)).get(i);
}
OCRep.setLongArray(parent, key, ret);
} else if (((List) values.get(key)).get(0) instanceof Double) {
double[] ret = new double[((List<Double>)values.get(key)).size()];
for (int i=0; i< ((List<Double>)values.get(key)).size(); i++) {
ret[i] = ((List<Double>)values.get(key)).get(i);
}
OCRep.setDoubleArray(parent, key, ret);
} else if (((List) values.get(key)).get(0) instanceof Boolean) {
boolean[] ret = new boolean[((List<Boolean>)values.get(key)).size()];
for (int i=0; i< ((List<Boolean>)values.get(key)).size(); i++) {
ret[i] = ((List<Boolean>)values.get(key)).get(i);
}
OCRep.setBooleanArray(parent, key, ret);
}
}
}
}
public void close() {
LOG.debug("Calling OCMain.mainShutdown()");
OCMain.mainShutdown();
......
......@@ -35,6 +35,7 @@ public class SerializableResource implements Serializable {
private List<String> types;
private List<String> interfaces;
Map<String, Object> properties = new HashMap<>();
Map<String, Boolean> propertiesAccess = new HashMap<>();
private boolean observing = false;
private boolean observable = true;
......@@ -95,6 +96,9 @@ public class SerializableResource implements Serializable {
case OC_REP_BOOL:
properties.put(ocRepresentation.getName(), ocRepresentation.getValue().getBool());
break;
case OC_REP_BOOL_ARRAY:
properties.put(ocRepresentation.getName(), OCRep.ocArrayToBooleanArray(ocRepresentation.getValue().getArray()));
break;
case OC_REP_STRING:
properties.put(ocRepresentation.getName(), ocRepresentation.getValue().getString());
break;
......@@ -121,6 +125,16 @@ public class SerializableResource implements Serializable {
}
}
public Map<String, Boolean> getPropertiesAccess() {
return this.propertiesAccess;
}
public void setPropertiesAccess(List<DynamicUiProperty> properties) {
for (DynamicUiProperty property : properties) {
propertiesAccess.put(property.getName(), property.isReadOnly());
}
}
public boolean isObserving() {
return this.observing;
}
......
......@@ -233,4 +233,14 @@ public class Device implements Comparable<Device> {
return res;
}
@Override
public boolean equals(Object device) {
boolean same = false;
if (device != null && device instanceof Device) {
same = this.deviceId.equals(((Device)device).getDeviceId());
}
return same;
}
}
package org.openconnectivity.otgc.domain.usecase;
import io.reactivex.Single;
import org.openconnectivity.otgc.data.repository.DoxsRepository;
import org.openconnectivity.otgc.data.repository.IotivityRepository;
import org.openconnectivity.otgc.data.repository.SettingRepository;
import org.openconnectivity.otgc.domain.model.devicelist.Device;
import org.openconnectivity.otgc.utils.constant.OcfOxmType;
import org.openconnectivity.otgc.utils.rx.SchedulersFacade;
import javax.inject.Inject;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class OnboardDevicesUseCase {
/* Repositories */
private final IotivityRepository iotivityRepository;
private final DoxsRepository doxsRepository;
private final SettingRepository settingRepository;
/* Scheduler */
private final SchedulersFacade schedulersFacade;
@Inject
public OnboardDevicesUseCase(IotivityRepository iotivityRepository,
DoxsRepository doxsRepository,
SettingRepository settingRepository,
SchedulersFacade schedulersFacade) {
this.iotivityRepository = iotivityRepository;
this.doxsRepository = doxsRepository;
this.settingRepository = settingRepository;
this.schedulersFacade = schedulersFacade;
}
public Single<Device> execute(Device device, List<OcfOxmType> oxms) {
int it1 = oxms.size() - 1;
if (it1 < 0) {
return null;
}
return executeOnboard(device, oxms.get(it1))
.onErrorResumeNext(error1 -> {
int it2 = it1 - 1;
if (it2 < 0) {
return null;
}
return iotivityRepository.scanUnownedDevices()
.filter(device1 -> device.getDeviceId().equals(device1.getDeviceId()))
.firstOrError()
.flatMap(device1 ->
executeOnboard(device1, oxms.get(it2))
.onErrorResumeNext(error -> {
int it3 = it1 - 2;
if (it3 < 0) {
return null;
}
return iotivityRepository.scanUnownedDevices()
.filter(device2 -> device.getDeviceId().equals(device2.getDeviceId()))
.firstOrError()
.flatMap(device2 -> executeOnboard(device2, oxms.get(it3)));
})
);
});
}
private Single<Device> executeOnboard(Device deviceToOnboard, OcfOxmType oxm) {
int delay = Integer.parseInt(settingRepository.get(SettingRepository.REQUESTS_DELAY_KEY, SettingRepository.REQUESTS_DELAY_DEFAULT_VALUE));
final Single<Device> getUpdatedOcSecureResource = iotivityRepository.scanOwnedDevices()
.filter(device -> deviceToOnboard.getDeviceId().equals(device.getDeviceId())
|| deviceToOnboard.equalsHosts(device))
.singleOrError();
return doxsRepository.doOwnershipTransfer(deviceToOnboard.getDeviceId(), oxm)
.delay(2 * delay, TimeUnit.SECONDS, schedulersFacade.ui())
.andThen(getUpdatedOcSecureResource
.onErrorResumeNext(error -> getUpdatedOcSecureResource
.retry(2)
.onErrorResumeNext(Single.error(error)))
);
}
}
......@@ -26,6 +26,7 @@ import org.openconnectivity.otgc.domain.model.client.SerializableResource;
import org.openconnectivity.otgc.domain.model.devicelist.Device;
import javax.inject.Inject;
import java.util.Map;
public class PostRequestUseCase {
private final IotivityRepository iotivityRepository;
......@@ -39,4 +40,9 @@ public class PostRequestUseCase {
return iotivityRepository.getSecureEndpoint(device)
.flatMapCompletable(endpoint -> iotivityRepository.post(endpoint, resource.getUri(), device.getDeviceId(), rep, valueArray));
}
public Completable execute(Device device, SerializableResource resource, Map<String, Object> values) {
return iotivityRepository.getSecureEndpoint(device)
.flatMapCompletable(endpoint -> iotivityRepository.post(endpoint, resource.getUri(), device.getDeviceId(), values));
}
}
......@@ -71,7 +71,7 @@ public class UiFromSwaggerUseCase {
uiElement.setPath(pathEntry.getKey());
String definitionName = getSchemaTitle(pathEntry.getValue());
if (definitionName != null && !definitionName.isEmpty()) {
uiElement.setResourceTypes(getResourceTypes(jsonSwagger, definitionName));
uiElement.setResourceTypes(getResourceTypes(swagger, definitionName));
uiElement.setInterfaces(getInterfaces(swagger, definitionName));
uiElement.setProperties(getProperties(swagger, definitionName));
uiElement.setSupportedOperations(getSupportedOperations(pathEntry.getValue()));
......@@ -94,20 +94,11 @@ public class UiFromSwaggerUseCase {
return schemaTitle;
}
private List<String> getResourceTypes(JSONObject jsonSwagger, String definitionName) throws JSONException {
List<String> resourceTypes = new ArrayList<>();
private List<String> getResourceTypes(Swagger swagger, String definitionName) throws JSONException {
ArrayProperty interfaces = (ArrayProperty) swagger.getDefinitions().get(definitionName).getProperties().get("rt");
StringProperty rtItems = (StringProperty) interfaces.getItems();
JSONArray jsonRt = jsonSwagger.getJSONObject("definitions")
.getJSONObject(definitionName)
.getJSONObject("properties")
.getJSONObject("rt")
.getJSONArray("default");
for (int i = 0; i < jsonRt.length(); i++) {
resourceTypes.add(jsonRt.getString(i));
}
return resourceTypes;
return rtItems.getEnum();
}
private List<String> getInterfaces(Swagger swagger, String definitionName) {
......
package org.openconnectivity.otgc.utils.handler;
public interface OCSetRandomPinHandler {
public String handler();
public String handler(String deviceId);
}
......@@ -23,10 +23,12 @@ import de.saxsys.mvvmfx.Scope;
import javafx.beans.property.*;
import org.openconnectivity.otgc.domain.model.devicelist.Device;
import java.util.List;
public class DeviceListToolbarDetailScope implements Scope {
private final ObjectProperty<Device> selectedDevice = new SimpleObjectProperty<>(this, "selectedDevice");
public ObjectProperty<Device> selectedDeviceProperty() {
private final ObjectProperty<List<Device>> selectedDevice = new SimpleObjectProperty<>(this, "selectedDevice");
public ObjectProperty<List<Device>> selectedDeviceProperty() {
return this.selectedDevice;
}
......@@ -43,7 +45,7 @@ public class DeviceListToolbarDetailScope implements Scope {
return this.selectedTab;
}
public final Device getSelectedDevice() {
/*public final Device getSelectedDevice() {
return this.selectedDeviceProperty().get();
}
public final void setSelectedDevice(final Device selectedDevice) {
......@@ -55,5 +57,5 @@ public class DeviceListToolbarDetailScope implements Scope {
}
public final void setPositionSelectedDevice(final int position) {
this.positionSelectedDeviceProperty().set(position);
}
}*/
}
......@@ -23,9 +23,11 @@ import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.InjectViewModel;
import de.saxsys.mvvmfx.utils.notifications.NotificationCenter;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.stage.Stage;
import org.apache.log4j.Logger;
import org.openconnectivity.otgc.utils.constant.NotificationKey;
......@@ -36,7 +38,8 @@ import org.openconnectivity.otgc.utils.viewmodel.Response;
import javax.inject.Inject;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.*;
import java.util.stream.Collectors;
public class DeviceListView implements FxmlView<DeviceListViewModel>, Initializable {
......@@ -64,10 +67,14 @@ public class DeviceListView implements FxmlView<DeviceListViewModel>, Initializa
listView.itemsProperty().bind(viewModel.devicesListProperty());
listView.setCellFactory(deviceListView -> new DeviceListViewCell());
listView.getSelectionModel().selectedItemProperty().addListener(((observable, oldValue, newValue) -> {
viewModel.selectedDeviceProperty().setValue(newValue);
viewModel.positionSelectedDeviceProperty().setValue(viewModel.devicesListProperty().indexOf(newValue));
}));
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
ObservableList<Device> devices = listView.getSelectionModel().getSelectedItems();
viewModel.selectedDeviceProperty().setValue(devices.stream().collect(Collectors.toList()));
if (devices.size() == 1) {
viewModel.positionSelectedDeviceProperty().setValue(viewModel.devicesListProperty().indexOf(devices.get(0)));
}
});
viewModel.scanResponseProperty().addListener(this::processScanResponse);
viewModel.updateDeviceResponseProperty().addListener(this::processUpdateDeviceResponse);
......
......@@ -77,15 +77,15 @@ public class MainView implements FxmlView<MainViewModel>, Initializable {
}
private String verifyPin = "";
OCSetRandomPinHandler randomPinCallbackListener = () -> {
OCSetRandomPinHandler randomPinCallbackListener = (String uuid) -> {
LOG.debug("Inside randomPinListener");
final Object lock = new Object();
Platform.runLater(() -> {
ButtonType yesButton = new ButtonType("Yes", ButtonBar.ButtonData.OK_DONE);
Alert alertDialog = new Alert(Alert.AlertType.CONFIRMATION);
alertDialog.setTitle("Insert random PIN");
alertDialog.setHeaderText("PIN: ");
alertDialog.setTitle(uuid);
alertDialog.setHeaderText("Insert random PIN: ");
final JFXTextField input = new JFXTextField();
alertDialog.getDialogPane().setGraphic(input);
alertDialog.getButtonTypes().clear();
......
......@@ -20,9 +20,7 @@
package org.openconnectivity.otgc.view.menu;
import com.google.inject.Inject;
import de.saxsys.mvvmfx.FluentViewLoader;
import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.InjectViewModel;
import de.saxsys.mvvmfx.*;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
......@@ -57,7 +55,7 @@ public class MenuView implements FxmlView<MenuViewModel>, Initializable {
@FXML
public void discover() {
// TODO
viewModel.discover();
}
@FXML
......
......@@ -29,9 +29,14 @@ import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.apache.log4j.Logger;
import org.openconnectivity.otgc.domain.model.devicelist.DeviceType;
import org.openconnectivity.otgc.utils.constant.NotificationKey;
......@@ -89,6 +94,11 @@ public class ToolbarView implements FxmlView<ToolbarViewModel>, Initializable {
viewModel.deviceInfoProperty().addListener(this::processDeviceInfoResponse);
viewModel.deviceRoleProperty().addListener(this::processDeviceRoleResponse);
viewModel.provisionAceOtmProperty().addListener(this::processProvisionAceOtmResponse);
viewModel.onboardWaitingProperty().addListener(this::processOnboardWaitingResponse);
viewModel.otmMultiResponseProperty().addListener(this::processOtmMultiResponse);
viewModel.deviceInfoMultiProperty().addListener(this::processDeviceInfoMultiResponse);
viewModel.deviceRoleMultiProperty().addListener(this::processDeviceRoleMultiResponse);
viewModel.provisionAceOtmMultiProperty().addListener(this::processProvisionAceOtmMultiResponse);
viewModel.offboardResponseProperty().addListener(this::processOffboardResponse);
viewModel.clientModeResponseProperty().addListener(this::processClientModeResponse);
viewModel.obtModeResponseProperty().addListener(this::processObtModeResponse);
......@@ -154,23 +164,20 @@ public class ToolbarView implements FxmlView<ToolbarViewModel>, Initializable {
@FXML
public void handleOnboardButton() {
switch(viewModel.deviceProperty.get().getDeviceType()) {
case UNOWNED:
positionBeingUpdated = viewModel.positionDeviceProperty().get();
viewModel.doOwnershipTransfer(viewModel.deviceProperty.get());
break;
case OWNED_BY_SELF:
case OWNED_BY_OTHER:
default:
break;
if (viewModel.deviceProperty.get().size() > 1) {
viewModel.onboardAllDevices(viewModel.deviceProperty.get());
} else {
positionBeingUpdated = viewModel.positionDeviceProperty().get();
viewModel.doOwnershipTransfer(viewModel.deviceProperty.get().get(0));
}
}
@FXML
public void handleOffboardButton() {
positionBeingUpdated = viewModel.positionDeviceProperty().get();
viewModel.offboard(viewModel.deviceProperty.get());
if (viewModel.deviceProperty.get().size() == 1) {
positionBeingUpdated = viewModel.positionDeviceProperty().get();
viewModel.offboard(viewModel.deviceProperty.get().get(0));
}
}
@FXML
......@@ -273,6 +280,109 @@ public class ToolbarView implements FxmlView<ToolbarViewModel>, Initializable {
}
}
private Stage waitingModal;
private void processOnboardWaitingResponse(ObservableValue<? extends Response<Boolean>> observableValue, Response<Boolean> oldValue, Response<Boolean> newValue) {
switch (newValue.status) {
case SUCCESS:
if (newValue.data) {
if (waitingModal == null) {
waitingModal = new Stage();
waitingModal.initModality(Modality.APPLICATION_MODAL);
waitingModal.initStyle(StageStyle.UTILITY);
//waitingModal.setAlwaysOnTop(true);
waitingModal.setTitle("Waiting");
waitingModal.setOnCloseRequest(event -> {
event.consume();
});
VBox vBox = new VBox(new Label("Please, wait while selected devices are onboarded."));
vBox.setAlignment(Pos.CENTER);
Scene scene = new Scene(vBox, 400, 100);
waitingModal.setScene(scene);
waitingModal.initOwner(primaryStage);
waitingModal.show();
notificationCenter.publish(NotificationKey.SET_PROGRESS_STATUS, true);
Toast.show(primaryStage, resourceBundle.getString("toolbar.otm.load"));
}
} else {
if (waitingModal != null && waitingModal.isShowing()) {
waitingModal.close();
waitingModal = null;
notificationCenter.publish(NotificationKey.SET_PROGRESS_STATUS, false);
viewModel.onScanPressed();
}
}
break;
default:
break;
}
}
private void processOtmMultiResponse(ObservableValue<? extends Response<Device>> observableValue, Response<Device> oldValue, Response<Device> newValue) {
switch (newValue.status) {
case SUCCESS:
break;
case ERROR:
LOG.debug(newValue.message);
Toast.show(primaryStage, resourceBundle.getString("toolbar.otm.error"));
break;
}
}
private void processDeviceInfoMultiResponse(ObservableValue<? extends Response<Device>> observableValue, Response<Device> oldValue, Response<Device> newValue) {
switch (newValue.status) {
case LOADING:
break;
case SUCCESS:
break;
case ERROR:
LOG.debug(newValue.message);
Toast.show(primaryStage, resourceBundle.getString("toolbar.get_device_info.error"));
break;
default: