Android Open Source - lifx-sdk-android L F X U D P Gateway Connection






From Project

Back to project page lifx-sdk-android.

License

The source code is released under:

MIT License

If you think the Android project lifx-sdk-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

//
//  LFXUDPGatewayConnection.java
//  LIFX//from w  w  w .  j a  v a 2 s  .  c o  m
//
//  Created by Jarrod Boyes on 24/03/14.
//  Copyright (c) 2014 LIFX Labs. All rights reserved.
//

package lifx.java.android.network_context.internal.transport_manager.gateway_connection;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;

import lifx.java.android.constant.LFXSDKConstants;
import lifx.java.android.entities.internal.LFXGatewayDescriptor;
import lifx.java.android.entities.internal.LFXMessage;
import lifx.java.android.entities.internal.structle.LxProtocol.Type;
import lifx.java.android.internal.LFXWiFiObserver;
import lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketGeneric.SocketMessage;
import lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketGeneric.SocketMessageListener;
import lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketGeneric.SocketState;
import lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketGeneric.SocketStateListener;
import lifx.java.android.util.LFXLog;
import lifx.java.android.util.LFXNetworkUtils;
import lifx.java.android.util.LFXTimerUtils;

public class LFXUDPGatewayConnection extends LFXGatewayConnection implements SocketMessageListener, SocketStateListener
{
  private Queue<LFXMessage> messageOutbox;
  private LFXSocketGeneric socket;
  private Timer outboxTimer;
  private Timer heartbeatTimer;
  private Timer idleTimeoutTimer;
  
  private Runnable getHeartbeatTimerTask()
  {
    Runnable heartbeatTimerTask = new TimerTask()
    {
      public void run()
      {
        heartbeatTimerDidFire();
      }
    };
    
    return heartbeatTimerTask;
  }
  
  private Runnable getIdleTimerTask()
  {
    Runnable idleTimerTask = new TimerTask()
    {
      public void run()
      {
        idleTimeoutTimerDidFire();
      }
    };
    
    return idleTimerTask;
  }
  
  private Runnable getOutBoxTimerTask()
  {
    Runnable outBoxTimerTask = new TimerTask() 
    {
      public void run() 
      {
        sendNextMessageFromOutbox();
      }  
    };
    
    return outBoxTimerTask;
  }
  
  public LFXUDPGatewayConnection( LFXGatewayDescriptor gatewayDescriptor, LFXGatewayConnectionListener listener)
  {
    super( gatewayDescriptor, listener);
    //LFXLog.Debug( "UDP Gateway Initializer");
    setConnectionState(LFXGatewayConnectionState.NOT_CONNECTED);
    messageOutbox = new LinkedList<LFXMessage>();
    //System.out.println( "Making Outbox Timer task.");
    outboxTimer = LFXTimerUtils.getTimerTaskWithPeriod( getOutBoxTimerTask(), LFXSDKConstants.LFX_UDP_MESSAGE_SEND_RATE_LIMIT_INTERVAL, false);
    socket = new LFXSocketUDP();
    //System.out.println( "Making Heartbeat Timer task.");
    heartbeatTimer = LFXTimerUtils.getTimerTaskWithPeriod( getHeartbeatTimerTask(), LFXSDKConstants.LFX_UDP_HEARTBEAT_INTERVAL, false);
    resetIdleTimeoutTimer();
  }

  public boolean isBroadcastConnection()
  {
    return getGatewayDescriptor().getHost().equals( LFXWiFiObserver.getWiFiBroadcastAddress());
  }

  public void heartbeatTimerDidFire()
  {
    if( isBroadcastConnection()) 
    {
      return;
    }
    
    if( getConnectionState() == LFXGatewayConnectionState.CONNECTED)
    {
      LFXMessage message = LFXMessage.messageWithTypeAndPath( Type.LX_PROTOCOL_DEVICE_GET_PAN_GATEWAY, getGatewayDescriptor().getPath());
      sendMessage( message);
    }
  }

  public void connect()
  {
    LFXLog.debug( "ConnectionState: " + getConnectionState());
    if( getConnectionState() != LFXGatewayConnectionState.NOT_CONNECTED)
    {
      return;
    }
    
    LFXLog.verbose( "Connecting UDP Socket " + getGatewayDescriptor().getHost() + ":" + getGatewayDescriptor().getPort());

    try
    {
      socket.addMessageListener( this);
      socket.addStateListener( this);
      socket.connect( InetAddress.getByName( getGatewayDescriptor().getHost()).getAddress(), getGatewayDescriptor().getPort());
      setConnectionState( LFXGatewayConnectionState.CONNECTED);
    } 
    catch( UnknownHostException e)
    {
      e.printStackTrace();
    }
  }

  private boolean shouldIgnoreDataFromHost( String host)
  {
      String localHost = LFXNetworkUtils.getLocalHostAddress();
    return localHost.equals( host);
  }

  public void sendData( byte[] data)
  {
    socket.sendMessage( new SocketMessage( data));
  }

  public void sendMessage( LFXMessage message)
  {
    LinkedList<LFXMessage> outboxAsLinkedList = (LinkedList<LFXMessage>) messageOutbox;
    
    for( int outboxIndex = 0; outboxIndex < outboxAsLinkedList.size(); outboxIndex++)
    {
      if( newMessageMakesQueuedMessageRedundant( message, outboxAsLinkedList.get( outboxIndex)))
      {
        outboxAsLinkedList.remove( outboxIndex);
        outboxAsLinkedList.add( outboxIndex, message);
        logMessageOutboxSize();
        return;
      }
    }
    
    messageOutbox.add( message);
    logMessageOutboxSize();
  }

  private void sendNextMessageFromOutbox()
  {
    LFXMessage nextMessage = messageOutbox.poll();
    
    if( nextMessage == null) 
    {
      return;
    }
    
    byte[] messageData = nextMessage.getMessageDataRepresentation();

    try
    {
      socket.sendMessage( new SocketMessage( messageData, InetAddress.getByName( getGatewayDescriptor().getHost()).getAddress(), getGatewayDescriptor().getPort()));
    } 
    catch( UnknownHostException e)
    {
      e.printStackTrace();
    }
  }

  private HashMap<String,Integer> types = new HashMap<String,Integer>();
  public void logMessageOutboxSize()
  {
    if( messageOutbox.size() > 10)
    {
      types.clear();

      LinkedList<LFXMessage> outboxAsLinkedList = (LinkedList<LFXMessage>) messageOutbox;
      
      for( int i = 0; i < messageOutbox.size(); i++)
      {
        String key = outboxAsLinkedList.get( i).getType().toString();
        Integer bla = types.get( key);
        
        if( bla == null)
        {
          bla = 0;
        }
        
        bla = bla + 1;
        
        types.put( key, bla);
      }
      
      LFXLog.warn( "UDP " + getGatewayDescriptor().getHost() + " Message Outbox backlog is " + messageOutbox.size());
      for( String aKey : types.keySet())
      {
        System.out.print( aKey + ": " + types.get( aKey) + ", ");
      }
      System.out.println();
      
    }
  }

  public void resetIdleTimeoutTimer()
  {
    if( isBroadcastConnection()) 
    {
      return;
    }
    
    if( idleTimeoutTimer != null)
    {
      idleTimeoutTimer.cancel();
      idleTimeoutTimer.purge();
    }
    
    idleTimeoutTimer = LFXTimerUtils.getTimerTaskWithPeriod( getIdleTimerTask(), LFXSDKConstants.LFX_UDP_IDLE_TIMEOUT_INTERVAL, false);
  }

  public void idleTimeoutTimerDidFire()
  {
    LFXLog.warn( "Idle timeout occured on UDP Connection " + toString() + ", disconnecting");
    setConnectionState( LFXGatewayConnectionState.NOT_CONNECTED);
    getListener().gatewayConnectionDidDisconnectWithError( this, null);
  }

  private void udpSocketDidReceiveDataFromAddressWithFilterContext( LFXSocketGeneric socket, byte[] data, byte[] address, Object filterContext)
  {
    InetAddress hostAddress = null;
    try
    {
      hostAddress = InetAddress.getByAddress( address);
    } 
    catch( UnknownHostException e)
    {
      e.printStackTrace();
    }
    
    if( hostAddress == null)
    {
      return;
    }
    
    String host = hostAddress.getHostAddress();
    
    host = LFXNetworkUtils.getIPv4StringByStrippingIPv6Prefix( host);

    if( !host.equals( getGatewayDescriptor().getHost()) && !isBroadcastConnection()) 
    {
      return;
    }
    
      if( shouldIgnoreDataFromHost( host))
    {
          return;
      }
      
    LFXMessage message = LFXMessage.messageWithMessageData( data);
    
    if( message == null)
    {
      LFXLog.error( "Couldn't create message from data: " + data);
      LFXLog.LFXMessage( data);
      return;
    }
    
      if( getListener() != null)
    {
      // NOTE: this is here to get rid of the duplicates that occur due to both the broadcast
      // UDP listener and gateway specific UDP listeners "receiving" the message.
      if( getGatewayDescriptor().getHost().equals( LFXWiFiObserver.getWiFiBroadcastAddress()))
      {
        getListener().gatewayConnectionDidReceiveMessageFromHost( this, message, host);
      }
      }
    
    resetIdleTimeoutTimer();
  }

  public void udpSocketDidCloseWithError( LFXSocketGeneric socket, String error)
  {
    setConnectionState( LFXGatewayConnectionState.NOT_CONNECTED);
    getListener().gatewayConnectionDidDisconnectWithError( this, error);
  }

  public void udpSocketDidNotConnect( LFXSocketGeneric socket, String error)
  {
    setConnectionState( LFXGatewayConnectionState.NOT_CONNECTED);
    getListener().gatewayConnectionDidDisconnectWithError( this, error);
  }

  @Override
  public void disconnect()
  {
    socket.close();
    heartbeatTimer.cancel();
    outboxTimer.cancel();
    
    if( idleTimeoutTimer != null)
    {
      idleTimeoutTimer.cancel();
    }
  }

  @Override
  public void notifyMessageReceived( SocketMessage message)
  {  
    udpSocketDidReceiveDataFromAddressWithFilterContext( null, message.getMessageData(), message.getIpAddress(), null);
  }

  @Override
  public void notifySocketStateChanged( LFXSocketGeneric socket, SocketState state)
  {
    switch( state)
    {
      case CONNECTED:
        getListener().gatewayConnectionDidConnect( this);
        break;
        
      case CONNECTING:
        break;
        
      case DISCONNECTED:
        getListener().gatewayConnectionDidDisconnectWithError( this, "");
        break;
    }
  }
}




Java Source Code List

com.example.lifx_sdk_samples.LFXSDKLightEditLabelActivity.java
com.example.lifx_sdk_samples.LFXSDKLightListAdapter.java
com.example.lifx_sdk_samples.LFXSDKLightPowerActivity.java
com.example.lifx_sdk_samples.LFXSDKLightRandomColorActivity.java
com.example.lifx_sdk_samples.LFXSDKSamplesActivity.java
com.example.lifx_sdk_samples.LFXSDKTaggedLightCollectionListAdapter.java
lifx.java.android.client.LFXClient.java
lifx.java.android.constant.LFXSDKConstants.java
lifx.java.android.entities.LFXHSBKColor.java
lifx.java.android.entities.LFXLightTarget.java
lifx.java.android.entities.LFXTypes.java
lifx.java.android.entities.internal.LFXBinaryPath.java
lifx.java.android.entities.internal.LFXBinaryTargetID.java
lifx.java.android.entities.internal.LFXBinaryTypes.java
lifx.java.android.entities.internal.LFXDeviceMapping.java
lifx.java.android.entities.internal.LFXGatewayDescriptor.java
lifx.java.android.entities.internal.LFXMessageObservationDescriptor.java
lifx.java.android.entities.internal.LFXMessage.java
lifx.java.android.entities.internal.LFXSiteID.java
lifx.java.android.entities.internal.LFXTagMapping.java
lifx.java.android.entities.internal.LFXTarget.java
lifx.java.android.entities.internal.structle.LxProtocolDevice.java
lifx.java.android.entities.internal.structle.LxProtocolLight.java
lifx.java.android.entities.internal.structle.LxProtocolSensor.java
lifx.java.android.entities.internal.structle.LxProtocolWan.java
lifx.java.android.entities.internal.structle.LxProtocolWifi.java
lifx.java.android.entities.internal.structle.LxProtocol.java
lifx.java.android.entities.internal.structle.Lx.java
lifx.java.android.entities.internal.structle.StructleTypes.java
lifx.java.android.internal.LFXWiFiObserver.java
lifx.java.android.light.LFXLightCollection.java
lifx.java.android.light.LFXLight.java
lifx.java.android.light.LFXTaggedLightCollection.java
lifx.java.android.light.internal.LFXAllLightsCollection.java
lifx.java.android.network_context.LFXNetworkContext.java
lifx.java.android.network_context.internal.routing_table.LFXRoutingTable.java
lifx.java.android.network_context.internal.transport_manager.LFXTransportManager.java
lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXGatewayConnection.java
lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketGeneric.java
lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketTCP.java
lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXSocketUDP.java
lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXTCPGatewayConnection.java
lifx.java.android.network_context.internal.transport_manager.gateway_connection.LFXUDPGatewayConnection.java
lifx.java.android.network_context.internal.transport_manager.lan.LFXLANTransportManager.java
lifx.java.android.network_context.internal.transport_manager.lan.gateway_discovery.LFXGatewayDiscoveryController.java
lifx.java.android.network_context.internal.transport_manager.lan.gateway_discovery.LFXGatewayDiscoveryTableEntry.java
lifx.java.android.util.LFXByteUtils.java
lifx.java.android.util.LFXLog.java
lifx.java.android.util.LFXNetworkUtils.java
lifx.java.android.util.LFXTimerUtils.java