/* * This file is part of the Remote Sensor Actuator Interface (ReSAI). * * Copyright(c) Andreas Kipp, Frederic Siepmann * http://opensource.cit-ec.de/projects/resai * * This file may be licensed under the terms of of the * GNU Lesser General Public License Version 3 (the ``LGPL''), * or (at your option) any later version. * * Software distributed under the License is distributed * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either * express or implied. See the LGPL for the specific language * governing rights and limitations. * * You should have received a copy of the LGPL along with this * program. If not, go to http://www.gnu.org/licenses/lgpl.html * or write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The development of this software was supported by the * Excellence Cluster EXC 277 Cognitive Interaction Technology. * The Excellence Cluster EXC 277 is a grant of the Deutsche * Forschungsgemeinschaft (DFG) in the context of the German * Excellence Initiative. * */ /** * Beacon controls connection to ReSAI server by continually * exchanging connection state. * * @author akipp */ package de.unibi.airobots.resaidroid.helper; import java.util.HashMap; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; import android.content.Context; import android.util.Log; import de.unibi.airobots.resaidroid.communication.Communicator; import de.unibi.airobots.resaidroid.communication.XmppConnection; import de.unibi.airobots.resaidroid.constants.Constants.Commands; import de.unibi.airobots.resaidroid.constants.Constants.Properties; import de.unibi.airobots.resaidroid.constants.ReturnCodes; import de.unibi.airobots.resaidroid.constants.ServerConfig; import de.unibi.airobots.resaidroid.constants.Constants; import de.unibi.airobots.resaidroid.tabactivities.template.TabTemplate; public class Beacon extends Thread { private static final String TAG = "Beacon"; private int beaconTimer = 5000; private int serverBeaconCount = 0; private Message mIn; private boolean stopped = false; private PacketListener packetListener; private Context context; private TabTemplate activity; protected HashMap propertiesToSend = new HashMap(); protected Communicator com; public Beacon(int _beaconTimer, Context _context, Communicator _com) { Log.i(TAG, "Beacon created."); beaconTimer = _beaconTimer; context = _context; com = _com; packetListener = new MyPacketListener(); } @Override public void run() { while (true) { if (serverBeaconCount > Constants.MAX_MISSING_BEACONS) { activity.returnWithError(ReturnCodes.SERVER_NOT_RESPONDING); try { synchronized (this) { Log.i(TAG, "Beacon is sleeping."); wait(); } } catch (InterruptedException e) { EasyDialog.makeToast(context, "ERROR: " + e.getMessage()); } } Log.i(TAG, "START BEACON ROUND..."); if (stopped) { com.removeListener(packetListener); try { synchronized (this) { Log.i(TAG, "Beacon is sleeping."); wait(); } } catch (InterruptedException e) { EasyDialog.makeToast(context, "ERROR: " + e.getMessage()); } } else { PacketFilter filter = new PacketTypeFilter(Message.class); XmppConnection.addListener(packetListener, filter); } if (com.isConnected()) { propertiesToSend.clear(); propertiesToSend.put(Properties.CMD.name(), Commands.beacon.name()); propertiesToSend.put(Properties.CLIENT_TIME.name(), String.valueOf(System.currentTimeMillis())); propertiesToSend.put("TAG", "ReSAIServerThread"); com.sendMessage(ServerConfig.RECIPIENT_FULL, propertiesToSend); } else { stopped = true; } try { serverBeaconCount++; sleep(beaconTimer); } catch (InterruptedException e) { EasyDialog.makeToast(context, "Error on sleep."); } Log.i(TAG, "END BEACON ROUND."); } } public boolean isStopped() { return stopped; } public void setActivity(TabTemplate activity) { this.activity = activity; } public TabTemplate getActivity() { return activity; } public void setStopped(boolean _stopped) { stopped = _stopped; } /** * Private class to listen to incoming beacons. * @author akipp * */ private class MyPacketListener implements PacketListener { public void processPacket(Packet packet) { // Log.i(TAG, "new message"); if (packet instanceof Message) { mIn = (Message) packet; if (mIn.getPropertyNames().contains(Properties.CMD.name())) { if (mIn.getProperty(Properties.CMD.name()).equals( Commands.beacon.name())) { long clientTime = Long.parseLong(mIn.getProperty( Properties.CLIENT_TIME.name()).toString()); long serverTime = Long.parseLong(mIn.getProperty( Properties.SERVER_TIME.name()).toString()); long timeDiff = clientTime - serverTime; XmppConnection.setServerTime(serverTime); XmppConnection.setClientTime(clientTime); XmppConnection.setTimeDiff(timeDiff); XmppConnection .setLastBeacon(System.currentTimeMillis()); XmppConnection.setBeaconDuration(System .currentTimeMillis() - clientTime); serverBeaconCount = 0; } } } } } }