/*******************************************************************************
* Copyright (c) 2011, 2016 Eurotech and/or its affiliates
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eurotech
*******************************************************************************/
package org.eclipse.kura.example.beacon;
import java.util.Map;
import org.eclipse.kura.bluetooth.BluetoothAdapter;
import org.eclipse.kura.bluetooth.BluetoothBeaconCommandListener;
import org.eclipse.kura.bluetooth.BluetoothService;
import org.eclipse.kura.configuration.ConfigurableComponent;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BeaconExample implements ConfigurableComponent, BluetoothBeaconCommandListener {
private static final Logger s_logger = LoggerFactory.getLogger(BeaconExample.class);
private final String PROPERTY_ENABLE = "enableAdvertising";
private final String PROPERTY_MIN_INTERVAL = "minBeaconInterval";
private final String PROPERTY_MAX_INTERVAL = "maxBeaconInterval";
private final String PROPERTY_UUID = "uuid";
private final String PROPERTY_MAJOR = "major";
private final String PROPERTY_MINOR = "minor";
private final String PROPERTY_COMPANY = "companyCode";
private final String PROPERTY_TX_POWER = "txPower";
private final String PROPERTY_LIMITED = "LELimited";
private final String PROPERTY_BR_SUPPORTED = "BR_EDRSupported";
private final String PROPERTY_BR_CONTROLLER = "LE_BRController";
private final String PROPERTY_BR_HOST = "LE_BRHost";
private final String PROPERTY_INAME = "iname";
private BluetoothService m_bluetoothService;
private BluetoothAdapter m_bluetoothAdapter;
private boolean m_enable;
private Integer m_minInterval;
private Integer m_maxInterval;
private String m_uuid;
private Integer m_major;
private Integer m_minor;
private String m_companyCode;
private Integer m_txPower;
private boolean m_LELimited;
private boolean m_BRSupported;
private boolean m_BRController;
private boolean m_BRHost;
private String m_iname = "hci0";
public void setBluetoothService(BluetoothService bluetoothService) {
this.m_bluetoothService = bluetoothService;
}
public void unsetBluetoothService(BluetoothService bluetoothService) {
this.m_bluetoothService = null;
}
// --------------------------------------------------------------------
//
// Activation APIs
//
// --------------------------------------------------------------------
protected void activate(ComponentContext context, Map<String, Object> properties) {
s_logger.info("Activating Bluetooth Beacon example...");
if (properties != null) {
if (properties.get(this.PROPERTY_ENABLE) != null) {
this.m_enable = (Boolean) properties.get(this.PROPERTY_ENABLE);
}
if (properties.get(this.PROPERTY_MIN_INTERVAL) != null) {
this.m_minInterval = (int) ((Integer) properties.get(this.PROPERTY_MIN_INTERVAL) / 0.625);
}
if (properties.get(this.PROPERTY_MAX_INTERVAL) != null) {
this.m_maxInterval = (int) ((Integer) properties.get(this.PROPERTY_MAX_INTERVAL) / 0.625);
}
if (properties.get(this.PROPERTY_UUID) != null) {
if (((String) properties.get(this.PROPERTY_UUID)).trim().replace("-", "").length() == 32) {
this.m_uuid = ((String) properties.get(this.PROPERTY_UUID)).replace("-", "");
} else {
s_logger.warn("UUID is too short!");
}
}
if (properties.get(this.PROPERTY_MAJOR) != null) {
this.m_major = (Integer) properties.get(this.PROPERTY_MAJOR);
}
if (properties.get(this.PROPERTY_MINOR) != null) {
this.m_minor = (Integer) properties.get(this.PROPERTY_MINOR);
}
if (properties.get(this.PROPERTY_COMPANY) != null) {
this.m_companyCode = (String) properties.get(this.PROPERTY_COMPANY);
}
if (properties.get(this.PROPERTY_TX_POWER) != null) {
this.m_txPower = (Integer) properties.get(this.PROPERTY_TX_POWER);
}
if (properties.get(this.PROPERTY_LIMITED) != null) {
this.m_LELimited = (Boolean) properties.get(this.PROPERTY_LIMITED);
}
if (properties.get(this.PROPERTY_BR_SUPPORTED) != null) {
this.m_BRSupported = (Boolean) properties.get(this.PROPERTY_BR_SUPPORTED);
}
if (properties.get(this.PROPERTY_BR_CONTROLLER) != null) {
this.m_BRController = (Boolean) properties.get(this.PROPERTY_BR_CONTROLLER);
}
if (properties.get(this.PROPERTY_BR_HOST) != null) {
this.m_BRHost = (Boolean) properties.get(this.PROPERTY_BR_HOST);
}
if (properties.get(this.PROPERTY_INAME) != null) {
this.m_iname = (String) properties.get(this.PROPERTY_INAME);
}
}
// Get Bluetooth adapter with Beacon capabilities and ensure it is enabled
this.m_bluetoothAdapter = this.m_bluetoothService.getBluetoothAdapter(this.m_iname, this);
if (this.m_bluetoothAdapter != null) {
s_logger.info("Bluetooth adapter interface => " + this.m_iname);
s_logger.info("Bluetooth adapter address => " + this.m_bluetoothAdapter.getAddress());
s_logger.info("Bluetooth adapter le enabled => " + this.m_bluetoothAdapter.isLeReady());
if (!this.m_bluetoothAdapter.isEnabled()) {
s_logger.info("Enabling bluetooth adapter...");
this.m_bluetoothAdapter.enable();
s_logger.info("Bluetooth adapter address => " + this.m_bluetoothAdapter.getAddress());
}
configureBeacon();
} else {
s_logger.warn("No Bluetooth adapter found ...");
}
}
protected void deactivate(ComponentContext context) {
s_logger.debug("Deactivating Beacon Example...");
// Stop the advertising
this.m_bluetoothAdapter.stopBeaconAdvertising();
// cancel bluetoothAdapter
this.m_bluetoothAdapter = null;
s_logger.debug("Deactivating Beacon Example... Done.");
}
protected void updated(Map<String, Object> properties) {
if (properties != null) {
if (properties.get(this.PROPERTY_ENABLE) != null) {
this.m_enable = (Boolean) properties.get(this.PROPERTY_ENABLE);
}
if (properties.get(this.PROPERTY_MIN_INTERVAL) != null) {
this.m_minInterval = (int) ((Integer) properties.get(this.PROPERTY_MIN_INTERVAL) / 0.625);
}
if (properties.get(this.PROPERTY_MAX_INTERVAL) != null) {
this.m_maxInterval = (int) ((Integer) properties.get(this.PROPERTY_MAX_INTERVAL) / 0.625);
}
if (properties.get(this.PROPERTY_UUID) != null) {
if (((String) properties.get(this.PROPERTY_UUID)).trim().replace("-", "").length() == 32) {
this.m_uuid = ((String) properties.get(this.PROPERTY_UUID)).replace("-", "");
} else {
s_logger.warn("UUID is too short!");
}
}
if (properties.get(this.PROPERTY_MAJOR) != null) {
this.m_major = (Integer) properties.get(this.PROPERTY_MAJOR);
}
if (properties.get(this.PROPERTY_MINOR) != null) {
this.m_minor = (Integer) properties.get(this.PROPERTY_MINOR);
}
if (properties.get(this.PROPERTY_COMPANY) != null) {
this.m_companyCode = (String) properties.get(this.PROPERTY_COMPANY);
}
if (properties.get(this.PROPERTY_TX_POWER) != null) {
this.m_txPower = (Integer) properties.get(this.PROPERTY_TX_POWER);
}
if (properties.get(this.PROPERTY_LIMITED) != null) {
this.m_LELimited = (Boolean) properties.get(this.PROPERTY_LIMITED);
}
if (properties.get(this.PROPERTY_BR_SUPPORTED) != null) {
this.m_BRSupported = (Boolean) properties.get(this.PROPERTY_BR_SUPPORTED);
}
if (properties.get(this.PROPERTY_BR_CONTROLLER) != null) {
this.m_BRController = (Boolean) properties.get(this.PROPERTY_BR_CONTROLLER);
}
if (properties.get(this.PROPERTY_BR_HOST) != null) {
this.m_BRHost = (Boolean) properties.get(this.PROPERTY_BR_HOST);
}
if (properties.get(this.PROPERTY_INAME) != null) {
this.m_iname = (String) properties.get(this.PROPERTY_INAME);
}
}
// Stop the advertising
this.m_bluetoothAdapter.stopBeaconAdvertising();
// cancel bluetoothAdapter
this.m_bluetoothAdapter = null;
// Get Bluetooth adapter and ensure it is enabled
this.m_bluetoothAdapter = this.m_bluetoothService.getBluetoothAdapter(this.m_iname, this);
if (this.m_bluetoothAdapter != null) {
s_logger.info("Bluetooth adapter interface => " + this.m_iname);
s_logger.info("Bluetooth adapter address => " + this.m_bluetoothAdapter.getAddress());
s_logger.info("Bluetooth adapter le enabled => " + this.m_bluetoothAdapter.isLeReady());
if (!this.m_bluetoothAdapter.isEnabled()) {
s_logger.info("Enabling bluetooth adapter...");
this.m_bluetoothAdapter.enable();
s_logger.info("Bluetooth adapter address => " + this.m_bluetoothAdapter.getAddress());
}
configureBeacon();
} else {
s_logger.warn("No Bluetooth adapter found ...");
}
s_logger.debug("Updating Beacon Example... Done.");
}
// --------------------------------------------------------------------
//
// Private methods
//
// --------------------------------------------------------------------
private void configureBeacon() {
if (this.m_enable) {
if (this.m_minInterval != null && this.m_maxInterval != null) {
this.m_bluetoothAdapter.setBeaconAdvertisingInterval(this.m_minInterval, this.m_maxInterval);
}
this.m_bluetoothAdapter.startBeaconAdvertising();
if (this.m_uuid != null && this.m_major != null && this.m_minor != null && this.m_companyCode != null
&& this.m_txPower != null) {
this.m_bluetoothAdapter.setBeaconAdvertisingData(this.m_uuid, this.m_major, this.m_minor,
this.m_companyCode, this.m_txPower, this.m_LELimited, this.m_LELimited ? false : true,
this.m_BRSupported, this.m_BRController, this.m_BRHost);
}
} else {
this.m_bluetoothAdapter.stopBeaconAdvertising();
}
}
// --------------------------------------------------------------------
//
// BluetoothBeaconCommandListener APIs
//
// --------------------------------------------------------------------
@Override
public void onCommandFailed(String errorCode) {
s_logger.warn("Error in executing command. Error Code: " + errorCode);
}
@Override
public void onCommandResults(String results) {
s_logger.info("Command results : " + results);
}
}