use of org.openremote.agent.protocol.bluetooth.mesh.transport.ProvisionedMeshNode in project openremote by openremote.
the class BluetoothMeshNetwork method getNode.
public synchronized ProvisionedMeshNode getNode(int sourceAddress) {
ProvisionedMeshNode node = null;
MeshNetwork network = getMeshNetwork();
if (network != null) {
node = network.getNode(sourceAddress);
}
return node;
}
use of org.openremote.agent.protocol.bluetooth.mesh.transport.ProvisionedMeshNode in project openremote by openremote.
the class BluetoothMeshNetwork method addMeshModel.
public synchronized void addMeshModel(int address, int modelId, int appKeyIndex) {
MeshNetwork network = getMeshNetwork();
MeshModel model = SigModelParser.getSigModel(modelId);
if (model == null) {
LOG.severe("Bluetooth Mesh model with ID='" + String.format("0x%04X", modelId) + "' is not supported.");
return;
}
// TODO: proper handling of unicast and group addresses
if (address < 0xC000) {
ProvisionedMeshNode node = getNode(address);
if (node == null) {
List<NetworkKey> networkKeys = new ArrayList<>(1);
networkKeys.add(networkKey);
List<ApplicationKey> applicationKeys = new ArrayList<>(applicationKeyMap.size());
applicationKeys.addAll(applicationKeyMap.values());
node = new ProvisionedMeshNode(network.getSelectedProvisioner(), networkKeys, applicationKeys);
node.setUnicastAddress(address);
}
Map<Integer, Element> oldElementMap = node.getElements();
Map<Integer, Element> newElementMap = new HashMap<>();
Map<Integer, MeshModel> newModelMap = new HashMap<>();
Element oldElement = oldElementMap.get(address);
if (oldElement != null) {
newModelMap.putAll(oldElement.getMeshModels());
}
int locationDescriptor = 0;
model.setBoundAppKeyIndex(appKeyIndex);
newModelMap.put(modelId, model);
Element newElement = new Element(address, locationDescriptor, newModelMap);
newElementMap.putAll(oldElementMap);
newElementMap.put(address, newElement);
node.setElements(newElementMap);
if (getNode(address) == null) {
network.nodes.add(node);
network.sequenceNumbers.put(node.getUnicastAddress(), node.getSequenceNumber());
network.unicastAddress = network.nextAvailableUnicastAddress(node.getNumberOfElements(), network.getSelectedProvisioner());
node.setMeshUuid(network.getMeshUUID());
network.loadSequenceNumbers();
}
}
addShadowModel(address, modelId, appKeyIndex);
}
use of org.openremote.agent.protocol.bluetooth.mesh.transport.ProvisionedMeshNode in project openremote by openremote.
the class BaseMeshNetwork method addProvisioner.
/**
* Adds a provisioner to the network
*
* @param provisioner {@link Provisioner}
* @throws IllegalArgumentException if unicast address is invalid, in use by a node
*/
public synchronized boolean addProvisioner(final Provisioner provisioner) throws IllegalArgumentException {
if (provisioner.allocatedUnicastRanges.isEmpty()) {
if (provisioner.getProvisionerAddress() != null) {
throw new IllegalArgumentException("Provisioner has no allocated unicast range assigned.");
}
}
for (Provisioner other : provisioners) {
if (provisioner.hasOverlappingUnicastRanges(other.getAllocatedUnicastRanges()) || provisioner.hasOverlappingGroupRanges(other.getAllocatedGroupRanges()) || provisioner.hasOverlappingSceneRanges(other.getAllocatedSceneRanges())) {
throw new IllegalArgumentException("Provisioner ranges overlap.");
}
}
if (!provisioner.isAddressWithinAllocatedRange(provisioner.getProvisionerAddress())) {
throw new IllegalArgumentException("Unicast address assigned to a provisioner must be within an allocated unicast address range.");
}
if (isAddressInUse(provisioner.getProvisionerAddress())) {
throw new IllegalArgumentException("Unicast address is in use by another node.");
}
if (provisioner.isNodeAddressInUse(nodes)) {
throw new IllegalArgumentException("Unicast address is already in use.");
}
if (isProvisionerUuidInUse(provisioner.getProvisionerUuid())) {
throw new IllegalArgumentException("Provisioner uuid already in use.");
}
provisioner.assignProvisionerAddress(provisioner.getProvisionerAddress());
provisioners.add(provisioner);
notifyProvisionerAdded(provisioner);
if (provisioner.isLastSelected()) {
selectProvisioner(provisioner);
}
if (provisioner.getProvisionerAddress() != null) {
final ProvisionedMeshNode node = new ProvisionedMeshNode(provisioner, netKeys, appKeys);
nodes.add(node);
notifyNodeAdded(node);
}
return true;
}
use of org.openremote.agent.protocol.bluetooth.mesh.transport.ProvisionedMeshNode in project openremote by openremote.
the class BluetoothMeshNetwork method onMeshPduCreated.
@Override
public synchronized void onMeshPduCreated(byte[] pdu) {
LOG.info("Sending PDU to mesh proxy: [data:" + dataAsHexString(pdu) + "]");
if (bluetoothMeshProxy != null) {
bluetoothMeshProxy.sendData(getMtu(), pdu, (proxy, data, isSuccess) -> {
if (isSuccess) {
LOG.info("Succeeded to send PDU to mesh proxy: [data:" + dataAsHexString(pdu) + "]");
meshManagerApi.handleWriteCallbacks(getMtu(), data);
} else {
LOG.warning("Failed to send PDU to mesh proxy: [data:" + dataAsHexString(pdu) + "]");
}
});
Integer sourceAddress = getMeshNetwork().getSelectedProvisioner().getProvisionerAddress();
if (sourceAddress != null) {
ProvisionedMeshNode sourceNode = getMeshNetwork().getNode(sourceAddress);
if (sourceNode != null) {
final int newSequenceNumber = sourceNode.getSequenceNumber();
executorService.execute(() -> sequenceNumberManager.save(networkKey, sourceUnicastAddress, newSequenceNumber));
}
}
}
}
Aggregations