Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
xdrm-brackets | 2d176987ea | |
SeekDaSky | d11649e9b9 | |
SeekDaSky | 710a5def49 | |
xdrm-brackets | 87509e8efe | |
xdrm-brackets | 4636c79334 | |
SeekDaSky | c8da1b3ba6 | |
SeekDaSky | 821808a420 | |
xdrm-brackets | f5232693d3 | |
xdrm-brackets | 1246fbbdc5 |
4
Makefile
4
Makefile
|
@ -28,7 +28,7 @@ link-viewTerm:
|
||||||
|
|
||||||
link-ctrlTerm:
|
link-ctrlTerm:
|
||||||
@echo "(5) Linking CTRL TERMINAL executable";
|
@echo "(5) Linking CTRL TERMINAL executable";
|
||||||
@echo -e "#!/bin/bash\n\njava -jar ./ctrlTerm/ctrlTerm.jar;\n" > ./x-ctrlTerm;
|
@echo -e "#!/bin/bash\n\njava -jar ./ctrlTerm/commandTerm.jar;\n" > ./x-ctrlTerm;
|
||||||
@chmod ug+x ./x-ctrlTerm;
|
@chmod ug+x ./x-ctrlTerm;
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,4 +44,4 @@ clean:
|
||||||
@find ./x-viewTerm > /dev/null 2>&1 && rm ./x-viewTerm || return 0;
|
@find ./x-viewTerm > /dev/null 2>&1 && rm ./x-viewTerm || return 0;
|
||||||
@find ./x-ctrlTerm > /dev/null 2>&1 && rm ./x-ctrlTerm || return 0;
|
@find ./x-ctrlTerm > /dev/null 2>&1 && rm ./x-ctrlTerm || return 0;
|
||||||
@make clean --directory=./sgca > /dev/null;
|
@make clean --directory=./sgca > /dev/null;
|
||||||
@make clean --directory=./plane > /dev/null;
|
@make clean --directory=./plane > /dev/null;
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class ControlTerminal {
|
||||||
|
|
||||||
|
private final static int SGCA_MULTICAST_PORT = 4446;
|
||||||
|
private final static String SCGA_MULTICAST_ADDRESS = "224.0.0.3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args){
|
||||||
|
System.out.println("\033[2J");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handshake
|
||||||
|
*/
|
||||||
|
int port = 0;
|
||||||
|
String addressString = "0.0.0.0";
|
||||||
|
|
||||||
|
try {
|
||||||
|
DatagramSocket socket = new DatagramSocket();
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(21);
|
||||||
|
buf.clear();
|
||||||
|
buf.put((byte)(0x05));
|
||||||
|
|
||||||
|
DatagramPacket payload = new DatagramPacket(buf.array(),buf.array().length,InetAddress.getByName(SCGA_MULTICAST_ADDRESS),SGCA_MULTICAST_PORT);
|
||||||
|
socket.send(payload);
|
||||||
|
|
||||||
|
socket.receive(payload);
|
||||||
|
|
||||||
|
buf = ByteBuffer.wrap(payload.getData());
|
||||||
|
if(buf.get() == 5){
|
||||||
|
System.out.println("--Connection request successful");
|
||||||
|
byte address[] = new byte[4];
|
||||||
|
buf = buf.get(address,0,4);
|
||||||
|
InetAddress addressObj = InetAddress.getByAddress(address);
|
||||||
|
addressString = addressObj.getHostAddress();
|
||||||
|
//emulate an unsigned short
|
||||||
|
char cast = buf.getChar();
|
||||||
|
port = (int) cast;
|
||||||
|
System.out.println("----Address : "+addressString);
|
||||||
|
System.out.println("----Port : "+port);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch ( IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opening final socket
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
//create all objects
|
||||||
|
AsynchronousDatagramSocket socket = new AsynchronousDatagramSocket();
|
||||||
|
PlaneContainer container = new PlaneContainer();
|
||||||
|
Printer printer = new Printer();
|
||||||
|
Pinger pinger = new Pinger(socket,InetAddress.getByName(addressString),port);
|
||||||
|
|
||||||
|
//bind them
|
||||||
|
socket.bindContainer(container);
|
||||||
|
container.bindPrinter(printer);
|
||||||
|
container.bindSocket(socket);
|
||||||
|
printer.bindContainer(container);
|
||||||
|
|
||||||
|
|
||||||
|
//send first packet
|
||||||
|
InetAddress SGCAaddress = InetAddress.getByName(addressString);
|
||||||
|
DatagramPacket p = new DatagramPacket(new byte[13],13,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("First packet sent");
|
||||||
|
|
||||||
|
//send first feedback packet
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(27);
|
||||||
|
buf.put((byte) 0x01);
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("Feedback request sent");
|
||||||
|
|
||||||
|
System.out.println("length: "+"aze".getBytes().length);
|
||||||
|
|
||||||
|
//run Pinger
|
||||||
|
new Thread(pinger).start();
|
||||||
|
|
||||||
|
//now we let the objects do the job
|
||||||
|
Scanner s = new Scanner(System.in);
|
||||||
|
int planeNumber;
|
||||||
|
int data;
|
||||||
|
Plane plane;
|
||||||
|
ArrayList<String> keys;
|
||||||
|
byte flags;
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
String input = s.nextLine();
|
||||||
|
if(input.length() == 0){
|
||||||
|
//if empty line, we send a feedback request
|
||||||
|
buf = ByteBuffer.allocate(27);
|
||||||
|
buf.put((byte) 0x01);
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("Request sent, waiting for response");
|
||||||
|
|
||||||
|
}else if(input.equals("u")){
|
||||||
|
System.out.println("Please enter plane number");
|
||||||
|
try{
|
||||||
|
planeNumber = s.nextInt();
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Wrong input please retry");
|
||||||
|
s.nextLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
keys = new ArrayList(container.getMap().keySet());
|
||||||
|
plane = container.getMap().get(keys.get(planeNumber-1));
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Unknown plane please retry");
|
||||||
|
s.nextLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
flags = 0x01;
|
||||||
|
while(true){
|
||||||
|
System.out.println("Enter the information you want to update (1: alt,2:cap,3:speed)");
|
||||||
|
try{
|
||||||
|
data = s.nextInt();
|
||||||
|
switch(data){
|
||||||
|
case 1:
|
||||||
|
System.out.println("Enter the new altitude");
|
||||||
|
data = s.nextInt();
|
||||||
|
plane.setZ(data);
|
||||||
|
flags = (byte) (flags|0x08);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
System.out.println("Enter the new cap");
|
||||||
|
data = s.nextInt();
|
||||||
|
plane.setCap(data);
|
||||||
|
flags = (byte) (flags|0x02);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
System.out.println("Enter the new speed");
|
||||||
|
data = s.nextInt();
|
||||||
|
plane.setSpeed(data);
|
||||||
|
flags = (byte) (flags|0x04);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("Wrong input please retry");
|
||||||
|
s.nextLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}catch(Exception e){
|
||||||
|
System.out.println("Wrong input please retry");
|
||||||
|
s.nextLine();
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("Do you want to update more data on this plane (y/n)");
|
||||||
|
|
||||||
|
if(s.next().equals("n")){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.setExpectedFlags(flags);
|
||||||
|
buf = ByteBuffer.allocate(27);
|
||||||
|
buf.put(flags);
|
||||||
|
buf.put(plane.toBytes());
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,SGCAaddress,port);
|
||||||
|
socket.send(p);
|
||||||
|
System.out.println("Request sent, waiting for response");
|
||||||
|
s.nextLine();
|
||||||
|
}else{
|
||||||
|
System.out.println("Unknown command, please retry");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
public class InvalidFlagException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidFlagException(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFlagException(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
public class Pinger implements Runnable{
|
||||||
|
|
||||||
|
private AsynchronousDatagramSocket socket;
|
||||||
|
private InetAddress addr;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
public Pinger(AsynchronousDatagramSocket socket,InetAddress addr,int port){
|
||||||
|
this.socket = socket;
|
||||||
|
this.addr = addr;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DatagramPacket p;
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(27);
|
||||||
|
while(true){
|
||||||
|
try {
|
||||||
|
Thread.sleep(8000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
p = new DatagramPacket(buf.array(),buf.array().length,this.addr,this.port);
|
||||||
|
try {
|
||||||
|
this.socket.send(p);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class Plane{
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
private int z;
|
||||||
|
private int cap;
|
||||||
|
private int speed;
|
||||||
|
|
||||||
|
private boolean isDead;
|
||||||
|
|
||||||
|
public Plane(String code,int x, int y, int z, int cap, int speed){
|
||||||
|
this.code = code;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.cap = cap;
|
||||||
|
this.speed = speed;
|
||||||
|
this.isDead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(int z) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCap() {
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead(){
|
||||||
|
return this.isDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCap(int cap) {
|
||||||
|
this.cap = cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpeed(int speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Die Motherfucker
|
||||||
|
public void die(){
|
||||||
|
this.isDead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLine(int i){
|
||||||
|
switch(i){
|
||||||
|
case 0:
|
||||||
|
return "--------------------------------";
|
||||||
|
case 1:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m Code: "+this.code+"\t\t\t|";
|
||||||
|
}else{
|
||||||
|
return "\033[4;37;42m Code: "+this.code+"\t\t\t|";
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
return "\033[0m --Coords: {"+this.x+";"+this.y+";"+this.z+"} \t|";
|
||||||
|
case 3:
|
||||||
|
return "\033[0m --Cap: "+this.cap+"\t\t\t|";
|
||||||
|
case 4:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m ATTENTION: avion hors ligne\t|\033[0m";
|
||||||
|
}else if(this.speed<300){
|
||||||
|
return "\033[5;37;41m --Speed: "+this.speed+"\t\t\t|\033[0m";
|
||||||
|
}else{
|
||||||
|
return "\033[0m --Speed: "+this.speed+"\t\t\t|";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toBytes(){
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(26);
|
||||||
|
buf.put(this.code.getBytes());
|
||||||
|
//EOL char
|
||||||
|
buf.put((byte)0);
|
||||||
|
buf.putInt(this.x);
|
||||||
|
buf.putInt(this.y);
|
||||||
|
buf.putInt(this.z);
|
||||||
|
buf.putInt(this.cap);
|
||||||
|
buf.putInt(this.speed);
|
||||||
|
|
||||||
|
return buf.array();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
public class PlaneContainer {
|
||||||
|
|
||||||
|
private HashMap<String,Plane> map;
|
||||||
|
private AsynchronousDatagramSocket socket;
|
||||||
|
private Printer printer;
|
||||||
|
private byte expectedFlags = 0x01;
|
||||||
|
|
||||||
|
public PlaneContainer(){
|
||||||
|
this.map = new HashMap<String,Plane>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindSocket(AsynchronousDatagramSocket s){
|
||||||
|
this.socket = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindPrinter(Printer p){
|
||||||
|
this.printer = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpectedFlags(byte flags){
|
||||||
|
this.expectedFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyReceive() throws InvalidFlagException{
|
||||||
|
DatagramPacket packet = this.socket.synchronousReceive();
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.wrap(packet.getData());
|
||||||
|
|
||||||
|
byte flag;
|
||||||
|
byte nbrPlane;
|
||||||
|
ArrayList<String> codes;
|
||||||
|
|
||||||
|
flag = buf.get();
|
||||||
|
nbrPlane = buf.get();
|
||||||
|
|
||||||
|
codes = new ArrayList<String>(nbrPlane);
|
||||||
|
|
||||||
|
//System.out.println("Processing "+nbrPlane+" planes");
|
||||||
|
|
||||||
|
if(this.expectedFlags != flag){
|
||||||
|
if((this.expectedFlags&(byte)0x02) == 2 && (flag&(byte)0x02) != 2){
|
||||||
|
System.out.println("\033[5;37;41m Could not apply cap \033[0m");
|
||||||
|
}
|
||||||
|
if((this.expectedFlags&(byte)0x04) == 4 && (flag&(byte)0x04) != 4){
|
||||||
|
System.out.println("\033[5;37;41m Could not apply speed \033[0m");
|
||||||
|
}
|
||||||
|
if((this.expectedFlags&(byte)0x08) == 8 && (flag&(byte)0x08) != 8){
|
||||||
|
System.out.println("\033[5;37;41m Could not apply alt \033[0m");
|
||||||
|
}
|
||||||
|
System.out.println("\033[5;37;41m One or more fields could not be updated \033[0m");
|
||||||
|
if((flag&(byte)0x10) == 1){
|
||||||
|
System.out.println("\033[5;37;41m Plane crashed gracefully \033[0m");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.expectedFlags = 0x01;
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flag == 0){
|
||||||
|
//this is a ping response
|
||||||
|
return;
|
||||||
|
}else if((flag&(byte)0x01) != 1){
|
||||||
|
throw new InvalidFlagException("Flag is not a feedback flag :"+flag);
|
||||||
|
}else{
|
||||||
|
String code;
|
||||||
|
byte rawCode[] = new byte[5];
|
||||||
|
Plane plane;
|
||||||
|
for(int i = 0;i<nbrPlane;i++){
|
||||||
|
//get plane code
|
||||||
|
buf = buf.get(rawCode,0,5);
|
||||||
|
code = new String(rawCode);
|
||||||
|
plane = this.map.get(code);
|
||||||
|
codes.add(code);
|
||||||
|
|
||||||
|
//remove EOL char
|
||||||
|
buf.get();
|
||||||
|
|
||||||
|
if(plane != null){
|
||||||
|
//fill the plane
|
||||||
|
plane.setX(buf.getInt());
|
||||||
|
plane.setY(buf.getInt());
|
||||||
|
plane.setZ(buf.getInt());
|
||||||
|
plane.setCap(buf.getInt());
|
||||||
|
plane.setSpeed(buf.getInt());
|
||||||
|
}else{
|
||||||
|
plane = new Plane(code,buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt());
|
||||||
|
this.map.put(code, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check for dead planes
|
||||||
|
for(String code : this.map.keySet()){
|
||||||
|
if(!codes.contains(code)){
|
||||||
|
this.map.get(code).die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.printer.notifyReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String,Plane> getMap(){
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package ControlTerminal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Printer {
|
||||||
|
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public Printer(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void notifyReceive(){
|
||||||
|
System.out.println("\033[2J \033[H");
|
||||||
|
HashMap<String,Plane> map = this.container.getMap();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
String lines[] = new String[5];
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map.keySet().size() == 0){
|
||||||
|
System.out.println("\033[37;43m No plane connected \033[0m");
|
||||||
|
}else{
|
||||||
|
for(String code : map.keySet()){
|
||||||
|
if(i <= 1){
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}else{
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Please enter your command (ENTER to update data, u to update a plane)");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package DatagramSocket;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import ControlTerminal.InvalidFlagException;
|
||||||
|
import ControlTerminal.PlaneContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
|
|
||||||
|
public final static int MAX_MESSAGE_SIZE = 300;
|
||||||
|
|
||||||
|
private SynchronizedBuffer<DatagramPacket> buf;
|
||||||
|
private DatagramSocket socket;
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public AsynchronousDatagramSocket() throws SocketException{
|
||||||
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
this.socket = new DatagramSocket();
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsynchronousDatagramSocket(int port) throws SocketException{
|
||||||
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
this.socket = new DatagramSocket(port);
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(DatagramPacket dp) throws IOException{
|
||||||
|
this.socket.send(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean asynchronousReceive(DatagramPacket dp){
|
||||||
|
if(this.buf.available() == 0){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
dp = this.buf.removeElement(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatagramPacket synchronousReceive(){
|
||||||
|
return this.buf.removeElement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean available(){
|
||||||
|
return this.buf.available()>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(){
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DatagramPacket packet;
|
||||||
|
while(true){
|
||||||
|
packet = new DatagramPacket(new byte[MAX_MESSAGE_SIZE],MAX_MESSAGE_SIZE);
|
||||||
|
try {
|
||||||
|
this.socket.receive(packet);
|
||||||
|
this.buf.addElement(packet);
|
||||||
|
this.container.notifyReceive();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(AsynchronousDatagramSocket.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (InvalidFlagException e) {
|
||||||
|
System.out.println("\033[01;31m Unexpected flag received \033[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package DatagramSocket;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class SynchronizedBuffer<T>{
|
||||||
|
|
||||||
|
private LinkedList<T> elements = new LinkedList<T>();
|
||||||
|
|
||||||
|
public synchronized T removeElement(boolean sync){
|
||||||
|
if(!sync && this.elements.isEmpty()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(this.elements.isEmpty()){
|
||||||
|
try {
|
||||||
|
this.wait();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Logger.getLogger(SynchronizedBuffer.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.elements.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addElement(T elem){
|
||||||
|
this.elements.add(elem);
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int available(){
|
||||||
|
return this.elements.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,9 +19,9 @@ boot: lib/network/tcp/client.o lib/network/udp/server.o plane.h plane.c
|
||||||
|
|
||||||
|
|
||||||
# Run full compilation
|
# Run full compilation
|
||||||
all: clean boot
|
all: boot
|
||||||
|
|
||||||
# cleans the compiled files
|
# cleans the compiled files
|
||||||
clean:
|
clean:
|
||||||
@find ./lib/network/**/*.o >/dev/null 2>&1 && rm ./lib/network/**/*.o || return 0;
|
@rm ./lib/network/**/*.o;
|
||||||
@find ./boot >/dev/null 2>&1 && rm ./boot || return 0;
|
@rm ./boot;
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo){
|
||||||
|
|
||||||
|
/* [0] Initialisation des variables
|
||||||
|
=========================================================*/
|
||||||
|
*pSocket = -1;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
|
||||||
|
/* [1] Création de la socket
|
||||||
|
=======================================================*/
|
||||||
|
/* 1. Création de la socket */
|
||||||
|
*pSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
/* 2. Gestion erreur */
|
||||||
|
if( *pSocket < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* 3. Timeout */
|
||||||
|
timeout.tv_sec = SOCK_TIMEOUT;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
if( setsockopt(*pSocket, SOL_SOCKET, SO_RCVTIMEO|SO_SNDTIMEO, (char*) &timeout, sizeof(struct timeval) ) < 0 ){
|
||||||
|
close(*pSocket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [2] On définit les infos de la socket
|
||||||
|
=========================================================*/
|
||||||
|
/* (1) Reset des valeurs */
|
||||||
|
bzero(pInfo, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
|
/* (2) On définit les infos */
|
||||||
|
pInfo->sin_family = AF_INET;
|
||||||
|
pInfo->sin_port = htons(pPort);
|
||||||
|
pInfo->sin_addr.s_addr = inet_addr(pAddr);
|
||||||
|
|
||||||
|
|
||||||
|
/* [n] Code succès
|
||||||
|
=========================================================*/
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**************************
|
||||||
|
* UDP Client Dependency *
|
||||||
|
***************************
|
||||||
|
* Designed & Developed by *
|
||||||
|
* Adrien Marquès *
|
||||||
|
* <xdrm-brackets> *
|
||||||
|
***************************
|
||||||
|
* doowap31@gmail.com *
|
||||||
|
**************************/
|
||||||
|
#ifndef _LIB_NETWORK_UDP_CLIENT_H_
|
||||||
|
#define _LIB_NETWORK_UDP_CLIENT_H_
|
||||||
|
|
||||||
|
|
||||||
|
/* Remarque:
|
||||||
|
*
|
||||||
|
* Il s'agit en réalité d'un serveur UDP, mais en multicast les membres du groupe pour qui sont copiées les requêtes
|
||||||
|
* sont par habitude appelés clients
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "../../header.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Créée une socket UDP + crée le sockaddr_in pour la suite
|
||||||
|
*
|
||||||
|
* ==IN==
|
||||||
|
* @pAddr<const char*> Adresse du groupe multicast UDP
|
||||||
|
* @pPort<const int> Port d'écoute UDP
|
||||||
|
*
|
||||||
|
* ==OUT==
|
||||||
|
* @pSocket<int*> Pointeur sur le <int> à rempliR => contiendra un pointeur sur la socket créée
|
||||||
|
* @pInfo<sockaddr_in*> Pointeur sur le <sockaddr_In> à remplir => contiendra un pointeur sur les infos server
|
||||||
|
*
|
||||||
|
* ==RETURN==
|
||||||
|
* @status<int> -1 si erreur, sinon 0
|
||||||
|
*
|
||||||
|
* @history
|
||||||
|
* [1] Création de la socket
|
||||||
|
* [2] On définit les infos de la socket
|
||||||
|
* [3] On crée la socket
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int UDP_SOCKET(int* pSocket, const char* pAddr, const int pPort, struct sockaddr_in* pInfo);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -378,4 +378,5 @@ int main(){
|
||||||
// on se déplace une fois toutes les initialisations faites
|
// on se déplace une fois toutes les initialisations faites
|
||||||
printf("\n=== COMMUNICATION PROTOCOL ===\n");
|
printf("\n=== COMMUNICATION PROTOCOL ===\n");
|
||||||
update();
|
update();
|
||||||
}
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -31,11 +31,11 @@ boot: lib/network/common.o lib/network/tcp/server.o lib/network/udp/server.o lib
|
||||||
|
|
||||||
|
|
||||||
# Run full compilation
|
# Run full compilation
|
||||||
all: clean boot
|
all: boot
|
||||||
|
|
||||||
# cleans the compiled files
|
# cleans the compiled files
|
||||||
clean:
|
clean:
|
||||||
@find lib/network/*.o >/dev/null 2>&1 && rm lib/network/*.o || return 0;
|
@rm lib/network/*.o;
|
||||||
@find lib/network/**/*.o >/dev/null 2>&1 && rm lib/network/**/*.o || return 0;
|
@rm lib/network/**/*.o;
|
||||||
@find lib/local/*.o >/dev/null 2>&1 && rm lib/local/*.o || return 0;
|
@rm lib/local/*.o;
|
||||||
@find boot >/dev/null 2>&1 && rm boot || return 0;
|
@rm boot;
|
||||||
|
|
|
@ -76,7 +76,8 @@ int main(int argc, char* argv[]){
|
||||||
|
|
||||||
/* [2] On attends la fin de tous les THREADS
|
/* [2] On attends la fin de tous les THREADS
|
||||||
==========================================================*/
|
==========================================================*/
|
||||||
for( char i = 0 ; i < 4 ; i++ )
|
char i;
|
||||||
|
for( i = 0 ; i < 4 ; i++ )
|
||||||
pthread_join(listenManagers[(int)i], NULL);
|
pthread_join(listenManagers[(int)i], NULL);
|
||||||
|
|
||||||
|
|
||||||
|
@ -452,4 +453,4 @@ void* MCAST_PUBLISH(void* THREADABLE_ARGS){
|
||||||
close(SOCKET);
|
close(SOCKET);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# [1] Create script file
|
||||||
|
cd `pwd`/..;
|
||||||
|
make all;
|
||||||
|
cp boot install/sgca;
|
||||||
|
make clean;
|
||||||
|
cd install;
|
||||||
|
|
||||||
|
|
||||||
|
# [2] Create service target (boot)
|
||||||
|
sudo ln -s $(pwd)/sgca /usr/sbin/sgca;
|
||||||
|
|
||||||
|
# [3] Create service unit
|
||||||
|
sudo ln -s $(pwd)/sgca.service /lib/systemd/system/sgca.service;
|
||||||
|
|
||||||
|
# [4] Enable service (optional if no [Install])
|
||||||
|
sudo systemctl enable sgca.service;
|
||||||
|
|
||||||
|
# [5] Create log file
|
||||||
|
sudo touch /var/log/sgca;
|
|
@ -0,0 +1,10 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Systeme de Gestion du Controle Aerien
|
||||||
|
Requires=network.target
|
||||||
|
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
ExecStart=/usr/sbin/sgca
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# [1] Remove service target (boot)
|
||||||
|
sudo rm /usr/sbin/sgca;
|
||||||
|
|
||||||
|
# [2] Disable service
|
||||||
|
sudo systemctl stop sgca.service;
|
||||||
|
sudo systemctl disable sgca.service;
|
||||||
|
|
||||||
|
# [3] Remove service unit
|
||||||
|
sudo rm /lib/systemd/system/sgca.service;
|
||||||
|
|
||||||
|
# [4] Remove log file
|
||||||
|
sudo rm /var/log/sgca;
|
||||||
|
|
|
@ -215,9 +215,11 @@ void* manageViewTerm(void* THREADABLE_ARGS){
|
||||||
int sent; // compteurs d'envoi
|
int sent; // compteurs d'envoi
|
||||||
int i, index = -1; // Compteurs globaux
|
int i, index = -1; // Compteurs globaux
|
||||||
char* buffer = malloc(1); // Buffer d'envoi
|
char* buffer = malloc(1); // Buffer d'envoi
|
||||||
|
int SOCKET;
|
||||||
|
|
||||||
/* 2. On récupère les arguments */
|
/* 2. On récupère les arguments */
|
||||||
struct handler_arg* arg = THREADABLE_ARGS;
|
struct handler_arg* arg = THREADABLE_ARGS;
|
||||||
|
memcpy(&SOCKET, &arg->socket, sizeof(int));
|
||||||
|
|
||||||
/* 3. On récupère le rang dans les "managers" */
|
/* 3. On récupère le rang dans les "managers" */
|
||||||
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
||||||
|
@ -228,7 +230,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
/* 4. Attente d'un client */
|
/* 4. Attente d'un client */
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
if( recvfrom(arg->socket, buffer, MAX_BUF_LEN*sizeof(char), 0, (struct sockaddr*) &clientInfo, &len) < 0 ){
|
if( recvfrom(SOCKET, buffer, MAX_BUF_LEN*sizeof(char), 0, (struct sockaddr*) &clientInfo, &len) < 0 ){
|
||||||
printf("{udp_vterm}{com}(%d) No terminal detected, exiting\n", index);
|
printf("{udp_vterm}{com}(%d) No terminal detected, exiting\n", index);
|
||||||
loop = 0;
|
loop = 0;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +250,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
/* 2. Envoi */
|
/* 2. Envoi */
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
sent = sendto(arg->socket, buffer, buflen + 1, 0, (struct sockaddr*) &clientInfo, len);
|
sent = sendto(SOCKET, buffer, buflen + 1, 0, (struct sockaddr*) &clientInfo, len);
|
||||||
|
|
||||||
/* 3. Gestion erreur */
|
/* 3. Gestion erreur */
|
||||||
if( sent <= 0 ){
|
if( sent <= 0 ){
|
||||||
|
@ -261,7 +263,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
/* 1. Réception feedback (0x10) */
|
/* 1. Réception feedback (0x10) */
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
sent = recvfrom(arg->socket, buffer, 1, 0, (struct sockaddr*) &clientInfo, &len);
|
sent = recvfrom(SOCKET, buffer, 1, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
/* 2. Gestion erreur (erreur ou mauvais feedback != 0x10) */
|
/* 2. Gestion erreur (erreur ou mauvais feedback != 0x10) */
|
||||||
if( sent <= 0 || buffer[0] != TERMREQ_OFF ){
|
if( sent <= 0 || buffer[0] != TERMREQ_OFF ){
|
||||||
|
@ -284,7 +286,7 @@ void* manageViewTerm(void* THREADABLE_ARGS){
|
||||||
arg->activeUDPManagers[index] = 0;
|
arg->activeUDPManagers[index] = 0;
|
||||||
|
|
||||||
/* 2. On ferme la socket + libère la mémoire */
|
/* 2. On ferme la socket + libère la mémoire */
|
||||||
close(arg->socket);
|
close(SOCKET);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
|
|
||||||
|
@ -331,10 +333,13 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
char* dataBuffer = malloc(1);
|
char* dataBuffer = malloc(1);
|
||||||
struct term_req request; // Requête
|
struct term_req request; // Requête
|
||||||
char flags;
|
char flags;
|
||||||
|
int SOCKET;
|
||||||
|
struct in_addr* ip = malloc(sizeof(struct in_addr));
|
||||||
|
|
||||||
|
|
||||||
/* 2. On récupère les arguments */
|
/* 2. On récupère les arguments */
|
||||||
struct handler_arg* arg = THREADABLE_ARGS;
|
struct handler_arg* arg = THREADABLE_ARGS;
|
||||||
|
memcpy(&SOCKET, &arg->socket, sizeof(int));
|
||||||
|
|
||||||
/* 3. On récupère le rang dans les "managers" */
|
/* 3. On récupère le rang dans les "managers" */
|
||||||
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
for( i = 0 ; i < MAX_UDP_THR ; i++ )
|
||||||
|
@ -344,11 +349,16 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
|
|
||||||
/* 4. Attente d'un client */
|
/* 4. Attente d'un client */
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
if( recvfrom(arg->socket, buffer, MAX_BUF_LEN*sizeof(char), 0, (struct sockaddr*) &clientInfo, &len) < 0 ){
|
if( recvfrom(SOCKET, buffer, MAX_BUF_LEN*sizeof(char), 0, (struct sockaddr*) &clientInfo, &len) < 0 ){
|
||||||
printf("{udp_cterm}{com}(%d) No terminal detected, exiting\n", index);
|
printf("{udp_cterm}{com}(%d) No terminal detected, exiting\n", index);
|
||||||
loop = 0;
|
loop = 0;
|
||||||
}else
|
}else{
|
||||||
printf("{udp_cterm}{com}(%d) Terminal connected\n", index);
|
ip->s_addr = clientInfo.sin_addr.s_addr;
|
||||||
|
printf("{udp_cterm}{com}(%d) Terminal connected from %s:%d\n", index, inet_ntoa(*ip), ntohs(clientInfo.sin_port));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ip);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while( loop ){
|
while( loop ){
|
||||||
|
@ -360,14 +370,14 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
/* 1. On lit sur la socket */
|
/* 1. On lit sur la socket */
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
|
bzero(buffer, sizeof(char)*MAX_BUF_LEN);
|
||||||
count = recvfrom(arg->socket, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
count = recvfrom(SOCKET, buffer, MAX_BUF_LEN, 0, (struct sockaddr*) &clientInfo, &len);
|
||||||
|
|
||||||
/* 2. Si erreur reception */
|
/* 2. Si erreur reception */
|
||||||
if( count <= 0 ) // because of timeout or error
|
if( count <= 0 ) // because of timeout or error
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( count < TERMREQ_LEN ){
|
if( count < TERMREQ_LEN ){
|
||||||
send(arg->socket, "\0\0", sizeof(char)*2, 0);
|
send(SOCKET, "\0\0", sizeof(char)*2, 0);
|
||||||
if( DEBUGMOD&BUF ) printf("{udp_cterm}{com}(%d) Error receiving request\n", index);
|
if( DEBUGMOD&BUF ) printf("{udp_cterm}{com}(%d) Error receiving request\n", index);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +400,7 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
update = ( request.flags&TERMREQ_ALT || request.flags&TERMREQ_CAP || request.flags&TERMREQ_SPD );
|
update = ( request.flags&TERMREQ_ALT || request.flags&TERMREQ_CAP || request.flags&TERMREQ_SPD );
|
||||||
fbk = request.flags&TERMREQ_FBK;
|
fbk = request.flags&TERMREQ_FBK;
|
||||||
if( !( update || fbk ) ){
|
if( !( update || fbk ) ){
|
||||||
send(arg->socket, "\x00\0", sizeof(char)*2, 0);
|
send(SOCKET, "\x00\0", sizeof(char)*2, 0);
|
||||||
if( request.flags != 0 )
|
if( request.flags != 0 )
|
||||||
printf("{udp_cterm}{com}(%d) Invalid flags\n", index);
|
printf("{udp_cterm}{com}(%d) Invalid flags\n", index);
|
||||||
continue;
|
continue;
|
||||||
|
@ -500,7 +510,7 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
=========================================================*/
|
=========================================================*/
|
||||||
printf("{udp_cterm}{com}(%d) Sending response { flags: %d; n: %d }\n", index, dataBuffer[0], dataBuffer[1]);
|
printf("{udp_cterm}{com}(%d) Sending response { flags: %d; n: %d }\n", index, dataBuffer[0], dataBuffer[1]);
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
if( sendto(arg->socket, dataBuffer, dataLen, 0, (struct sockaddr*) &clientInfo, len) < 0 )
|
if( sendto(SOCKET, dataBuffer, dataLen, 0, (struct sockaddr*) &clientInfo, len) < 0 )
|
||||||
printf("{udp_cterm}{com}(%d) Cannot answer to terminal\n", index);
|
printf("{udp_cterm}{com}(%d) Cannot answer to terminal\n", index);
|
||||||
|
|
||||||
|
|
||||||
|
@ -514,7 +524,7 @@ void* manageCtrlTerm(void* THREADABLE_ARGS){
|
||||||
arg->activeUDPManagers[index] = 0;
|
arg->activeUDPManagers[index] = 0;
|
||||||
|
|
||||||
/* 2. On ferme la socket */
|
/* 2. On ferme la socket */
|
||||||
close(arg->socket);
|
close(SOCKET);
|
||||||
free(dataBuffer);
|
free(dataBuffer);
|
||||||
|
|
||||||
/* 3. On arrête le THREAD */
|
/* 3. On arrête le THREAD */
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package DatagramSocket;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import ViewTerminal.InvalidFlagException;
|
||||||
|
import ViewTerminal.PlaneContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class AsynchronousDatagramSocket implements Runnable, AutoCloseable{
|
||||||
|
|
||||||
|
public final static int MAX_MESSAGE_SIZE = 300;
|
||||||
|
|
||||||
|
private SynchronizedBuffer<DatagramPacket> buf;
|
||||||
|
private DatagramSocket socket;
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public AsynchronousDatagramSocket() throws SocketException{
|
||||||
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
this.socket = new DatagramSocket();
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsynchronousDatagramSocket(int port) throws SocketException{
|
||||||
|
this.buf = new SynchronizedBuffer<>();
|
||||||
|
this.socket = new DatagramSocket(port);
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(DatagramPacket dp) throws IOException{
|
||||||
|
this.socket.send(dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean asynchronousReceive(DatagramPacket dp){
|
||||||
|
if(this.buf.available() == 0){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
dp = this.buf.removeElement(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatagramPacket synchronousReceive(){
|
||||||
|
return this.buf.removeElement(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean available(){
|
||||||
|
return this.buf.available()>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(){
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DatagramPacket packet;
|
||||||
|
while(true){
|
||||||
|
packet = new DatagramPacket(new byte[MAX_MESSAGE_SIZE],MAX_MESSAGE_SIZE);
|
||||||
|
try {
|
||||||
|
this.socket.receive(packet);
|
||||||
|
this.buf.addElement(packet);
|
||||||
|
this.container.notifyReceive();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Logger.getLogger(AsynchronousDatagramSocket.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
} catch (InvalidFlagException e) {
|
||||||
|
System.out.println("\033[01;31m Unexpected flag received \033[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package DatagramSocket;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class SynchronizedBuffer<T>{
|
||||||
|
|
||||||
|
private LinkedList<T> elements = new LinkedList<T>();
|
||||||
|
|
||||||
|
public synchronized T removeElement(boolean sync){
|
||||||
|
if(!sync && this.elements.isEmpty()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(this.elements.isEmpty()){
|
||||||
|
try {
|
||||||
|
this.wait();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Logger.getLogger(SynchronizedBuffer.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.elements.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void addElement(T elem){
|
||||||
|
this.elements.add(elem);
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int available(){
|
||||||
|
return this.elements.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
public class InvalidFlagException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public InvalidFlagException(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFlagException(String message){
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
public class Plane {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
private int z;
|
||||||
|
private int cap;
|
||||||
|
private int speed;
|
||||||
|
|
||||||
|
private boolean isDead;
|
||||||
|
|
||||||
|
public Plane(String code,int x, int y, int z, int cap, int speed){
|
||||||
|
this.code = code;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.cap = cap;
|
||||||
|
this.speed = speed;
|
||||||
|
this.isDead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZ(int z) {
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCap() {
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead(){
|
||||||
|
return this.isDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCap(int cap) {
|
||||||
|
this.cap = cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpeed(int speed) {
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Die Motherfucker
|
||||||
|
public void die(){
|
||||||
|
this.isDead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLine(int i){
|
||||||
|
switch(i){
|
||||||
|
case 0:
|
||||||
|
return "--------------------------------";
|
||||||
|
case 1:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m Code: "+this.code+"\t\t\t|";
|
||||||
|
}else{
|
||||||
|
return "\033[4;37;42m Code: "+this.code+"\t\t\t|";
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
return "\033[0m --Coords: {"+this.x+";"+this.y+";"+this.z+"} \t|";
|
||||||
|
case 3:
|
||||||
|
return "\033[0m --Cap: "+this.cap+"\t\t\t|";
|
||||||
|
case 4:
|
||||||
|
if(this.isDead){
|
||||||
|
return "\033[4;37;41m ATTENTION: avion hors ligne\t|\033[0m";
|
||||||
|
}else if(this.speed<300){
|
||||||
|
return "\033[5;37;41m --Speed: "+this.speed+"\t\t\t|\033[0m";
|
||||||
|
}else{
|
||||||
|
return "\033[0m --Speed: "+this.speed+"\t\t\t|";
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
public class PlaneContainer {
|
||||||
|
|
||||||
|
private HashMap<String,Plane> map;
|
||||||
|
private AsynchronousDatagramSocket socket;
|
||||||
|
private Printer printer;
|
||||||
|
|
||||||
|
public PlaneContainer(){
|
||||||
|
this.map = new HashMap<String,Plane>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindSocket(AsynchronousDatagramSocket s){
|
||||||
|
this.socket = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindPrinter(Printer p){
|
||||||
|
this.printer = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyReceive() throws InvalidFlagException{
|
||||||
|
DatagramPacket packet = this.socket.synchronousReceive();
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(1);
|
||||||
|
buf.put((byte)16);
|
||||||
|
DatagramPacket ping = new DatagramPacket(buf.array(),buf.array().length,packet.getAddress(),packet.getPort());
|
||||||
|
try {
|
||||||
|
this.socket.send(ping);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = ByteBuffer.wrap(packet.getData());
|
||||||
|
|
||||||
|
byte flag;
|
||||||
|
byte nbrPlane;
|
||||||
|
ArrayList<String> codes;
|
||||||
|
|
||||||
|
flag = buf.get();
|
||||||
|
nbrPlane = buf.get();
|
||||||
|
|
||||||
|
codes = new ArrayList<String>(nbrPlane);
|
||||||
|
|
||||||
|
//System.out.println("Processing "+nbrPlane+" planes");
|
||||||
|
|
||||||
|
if(flag != 1){
|
||||||
|
throw new InvalidFlagException("Flag is not a feedback flag :"+flag);
|
||||||
|
}else{
|
||||||
|
String code;
|
||||||
|
byte rawCode[] = new byte[5];
|
||||||
|
Plane plane;
|
||||||
|
for(int i = 0;i<nbrPlane;i++){
|
||||||
|
//get plane code
|
||||||
|
buf = buf.get(rawCode,0,5);
|
||||||
|
code = new String(rawCode);
|
||||||
|
plane = this.map.get(code);
|
||||||
|
codes.add(code);
|
||||||
|
|
||||||
|
//remove EOL char
|
||||||
|
buf.get();
|
||||||
|
|
||||||
|
if(plane != null){
|
||||||
|
//fill the plane
|
||||||
|
plane.setX(buf.getInt());
|
||||||
|
plane.setY(buf.getInt());
|
||||||
|
plane.setZ(buf.getInt());
|
||||||
|
plane.setCap(buf.getInt());
|
||||||
|
plane.setSpeed(buf.getInt());
|
||||||
|
}else{
|
||||||
|
plane = new Plane(code,buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt(),buf.getInt());
|
||||||
|
this.map.put(code, plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check for dead planes
|
||||||
|
for(String code : this.map.keySet()){
|
||||||
|
if(!codes.contains(code)){
|
||||||
|
this.map.get(code).die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.printer.notifyReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String,Plane> getMap(){
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Printer {
|
||||||
|
|
||||||
|
private PlaneContainer container;
|
||||||
|
|
||||||
|
public Printer(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindContainer(PlaneContainer c){
|
||||||
|
this.container = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyReceive(){
|
||||||
|
System.out.println("\033[2J \033[H");
|
||||||
|
HashMap<String,Plane> map = this.container.getMap();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
String lines[] = new String[5];
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map.keySet().size() == 0){
|
||||||
|
System.out.println("\033[37;43m Aucun avion connecté au système \033[0m");
|
||||||
|
}else{
|
||||||
|
for(String code : map.keySet()){
|
||||||
|
if(i <= 1){
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}else{
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
lines[k] = "";
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
lines[k] += map.get(code).getLine(k);
|
||||||
|
}
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int k = 0;k<5;k++){
|
||||||
|
System.out.println(lines[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ViewTerminal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import DatagramSocket.AsynchronousDatagramSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author lmascaro
|
||||||
|
*/
|
||||||
|
public class ViewTerminal {
|
||||||
|
|
||||||
|
private final static int SGCA_MULTICAST_PORT = 4445;
|
||||||
|
private final static String SCGA_MULTICAST_ADDRESS = "224.0.0.2";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args){
|
||||||
|
System.out.println("\033[2J");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handshake
|
||||||
|
*/
|
||||||
|
int port = 0;
|
||||||
|
String addressString = "0.0.0.0";
|
||||||
|
|
||||||
|
try {
|
||||||
|
DatagramSocket socket = new DatagramSocket();
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(21);
|
||||||
|
buf.clear();
|
||||||
|
buf.put((byte)(0x01));
|
||||||
|
|
||||||
|
DatagramPacket payload = new DatagramPacket(buf.array(),buf.array().length,InetAddress.getByName(SCGA_MULTICAST_ADDRESS),SGCA_MULTICAST_PORT);
|
||||||
|
socket.send(payload);
|
||||||
|
|
||||||
|
socket.receive(payload);
|
||||||
|
|
||||||
|
buf = ByteBuffer.wrap(payload.getData());
|
||||||
|
if(buf.get() == 1){
|
||||||
|
System.out.println("--Connection request successful");
|
||||||
|
byte address[] = new byte[4];
|
||||||
|
buf = buf.get(address,0,4);
|
||||||
|
InetAddress addressObj = InetAddress.getByAddress(address);
|
||||||
|
addressString = addressObj.getHostAddress();
|
||||||
|
//emulate an unsigned short
|
||||||
|
char cast = buf.getChar();
|
||||||
|
port = (int) cast;
|
||||||
|
System.out.println("----Address : "+addressString);
|
||||||
|
System.out.println("----Port : "+port);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch ( IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opening final socket
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
//create all objects
|
||||||
|
AsynchronousDatagramSocket socket = new AsynchronousDatagramSocket();
|
||||||
|
PlaneContainer container = new PlaneContainer();
|
||||||
|
Printer printer = new Printer();
|
||||||
|
|
||||||
|
//bind them
|
||||||
|
socket.bindContainer(container);
|
||||||
|
container.bindPrinter(printer);
|
||||||
|
container.bindSocket(socket);
|
||||||
|
printer.bindContainer(container);
|
||||||
|
|
||||||
|
//send first packet
|
||||||
|
DatagramPacket p = new DatagramPacket(new byte[13],13,InetAddress.getByName(addressString),port);
|
||||||
|
socket.send(p);
|
||||||
|
|
||||||
|
//now we let the objects do the job
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue