CommsigniaLayer.java 7.39 KB
Newer Older
package org.etsi.its.adapter.layers;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.concurrent.TimeoutException;

import org.etsi.adapter.TERFactory;
import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.IManagementLayers;

import com.commsignia.v2x.client.ITSApplication;
import com.commsignia.v2x.client.ITSEventAdapter;
import com.commsignia.v2x.client.MessageSet;
import com.commsignia.v2x.client.exception.ClientException;
import com.commsignia.v2x.client.model.BTPType;
import com.commsignia.v2x.client.model.GNNotification;
import com.commsignia.v2x.client.model.GeonetSendData;
import com.commsignia.v2x.client.model.InjectData;
import com.commsignia.v2x.client.model.InjectData.Builder;
import com.commsignia.v2x.client.model.InjectData.Type;
import com.commsignia.v2x.client.model.WsmpNotification;
import com.commsignia.v2x.client.model.WsmpSendData;
import com.commsignia.v2x.client.model.dev.DeviceId;
import com.commsignia.v2x.client.model.dev.DeviceInfoResponse;
import com.commsignia.v2x.client.model.dev.FacilityModule;

import rx.Observable;
import rx.Scheduler;
import rx.Scheduler.Worker;

public class CommsigniaLayer extends Layer {
    
    /**
     * Well-known Ethernet broadcast address
     */
    public static byte[] MAC_BROADCAST = new byte[]{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
    
    /**
     * Parameter name for Link-Layer destination
     */
    public static final String LINK_LAYER_DESTINATION = "LinkLayerDestination";
    
    /**
     * Constructor
     * @param  management   Layer management instance
     * @param  lowerStack   Lower protocol stack   
     */
    public CommsigniaLayer(IManagementLayers management, Stack<String> lowerStack) {
        super(management, lowerStack);
        
        int its_aid = 5; 
        String targetHost = "172.17.15.38";
        int targetPort = 7942; 
        MessageSet defaultMessageSet = MessageSet.C;
        itsApplication = new ITSApplication(its_aid, targetHost, targetPort, defaultMessageSet);
        try {
            itsApplication.connect(1000);
            itsApplication.registerBlocking();
            DeviceInfoResponse deviceInfoResponse = itsApplication.requestDeviceInfoBlocking();
            System.out.println(deviceInfoResponse);
            itsApplication.setFacilityModuleStatus(FacilityModule.BSM, false);
            itsApplication.setFacilityModuleStatus(FacilityModule.CAM, false);
            itsApplication.addEventListener(new ITSEventAdapter() {
                @Override
                public void onGnNotification(GNNotification notification) {
                    ByteBuffer buffer = ByteBuffer.wrap(notification.getData());

                    System.out.printf("GN GBC receive. GN address: %s Sequence number: %d RSSI: %d dBm\n",
                            notification.getGNAddress(),
                            buffer.getInt(),
                            notification.getRssi()
                    );
                }
            });
            itsApplication. gnBindBlocking(BTPType.NONE, 65535);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
    
    /* (non-Javadoc)
     * @see org.etsi.its.adapter.layers.Layer#register(org.etsi.its.adapter.layers.Layer)
     */
    @Override
    public void register(Layer upperLayer) {
        
        if(registeredUpperLayer == null) {
            super.register(upperLayer);
            
            try {
                Method getEthernetType = registeredUpperLayer.getClass().getMethod("getEthernetType", (Class<?>[])null);
                if (getEthernetType != null) {
                    upperLayerFrameType = (Short) getEthernetType.invoke(registeredUpperLayer, (Object[]) null); 
                }
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            
            localMacAddress = management.getLinkLayerAddress();
        }
        
    }
    
    /* (non-Javadoc)
     * @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map)
     */
    @Override
    public boolean send(byte[] message, Map<String, Object> params) {
        TERFactory.getInstance().logDebug(">>> CommsigniaLayer.send: " + ByteHelper.byteArrayToString(message));
        
        byte[] dst = (byte[])params.get(LINK_LAYER_DESTINATION);
        if(dst == null) {
            dst = MAC_BROADCAST;
        }
            
        byte[] packet = ByteHelper.concat(
                dst,
                localMacAddress, 
                ByteHelper.intToByteArray(upperLayerFrameType, 2), 
                message
        );
        
        try {
            String dstAddress = String.format(
                "%02x:%02x:%02x:%02x:%02x:%02x", 
                dst[0], 
                dst[1], 
                dst[2], 
                dst[3], 
                dst[4], 
                dst[5]);
            String srcAddress = String.format(
                "%02x:%02x:%02x:%02x:%02x:%02x", 
                localMacAddress[0], 
                localMacAddress[1], 
                localMacAddress[2], 
                localMacAddress[3], 
                localMacAddress[4], 
                localMacAddress[5]);
            Builder build = new InjectData.Builder();
            build
                .withDstAddress(dstAddress)
                .withSrcAddress(srcAddress)
                .withType(Type.GNP)
                .withInterfaceID(2)
                .withData(message);
            InjectData injectData = build.build();
            TERFactory.getInstance().logDebug("CommsigniaLayer.send: " + ByteHelper.byteArrayToString(injectData.getData()));
            
            itsApplication.sendOnRadioBlocking(injectData);
            TERFactory.getInstance().logDebug("<<< GnLayer.send: " + ByteHelper.byteArrayToString(packet));
            return super.send(packet, params);
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        return false;
    }
    
    /* (non-Javadoc)
     * @see org.etsi.its.adapter.layers.Layer#unregister(org.etsi.its.adapter.layers.Layer)
     */
    @Override
    public void unregister(Layer upperLayer) {
        if (itsApplication != null) {
            try {
                itsApplication.gnCloseBlocking(BTPType.NONE, 65535);
                itsApplication.deregisterBlocking();
            } catch (ClientException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            itsApplication.shutdown();
            itsApplication = null;
        }
    }
    
    /**
     * Local Ethernet address 
     */
    private byte[] localMacAddress;
    
    /**
     * Upper layer's frame type
     */
    private short upperLayerFrameType;
    
    private ITSApplication itsApplication = null;
    
}