package de.tudarmstadt.informatik.hostage.protocol; import java.util.ArrayList; import java.util.List; import de.tudarmstadt.informatik.hostage.wrapper.Packet; /** * SIP protocol. Implementation of RFC document 3261 It can handle the * following requests: INVITE, BYE. For all other requests * '400 Bad Request' will be replied. * @author Wulf Pfeiffer */ public class SIP implements Protocol { private static final String VERSION = "SIP/2.0"; private static final String INVITE = "INVITE"; private static final String ACK= "ACK"; private static final String BYE = "BYE"; private static final String STATUS_CODE_180 = "180 Ringing"; private static final String STATUS_CODE_200 = "200 OK"; private static final String STATUS_CODE_400 = "400 Bad Request"; private static final String STATUS_CODE_505 = "505 Version Not Supported"; private String header; private String sdpPayload; @Override public int getPort() { return 5060; } @Override public boolean isClosed() { // TODO Auto-generated method stub return false; } @Override public boolean isSecure() { return false; } @Override public List processMessage(Packet requestPacket) { // TODO Auto-generated method stub String request = null; if (requestPacket != null) { request = requestPacket.toString(); } List responsePackets = new ArrayList(); String[] lines = request.split("\r\n"); extractLines(lines); if(!lines[0].contains(VERSION)) { responsePackets.add(new Packet(STATUS_CODE_505)); return responsePackets; } else if(lines[0].contains(INVITE)) { responsePackets.add(getRingResponse()); responsePackets.add(getOkResponseWithSDP()); } else if(lines[0].contains(BYE)) { responsePackets.add(getOkResponse()); } else if(lines[0].contains(ACK)) { //nothing here } else { responsePackets.add(getBadRequestResponse()); } return responsePackets; } @Override public TALK_FIRST whoTalksFirst() { return TALK_FIRST.CLIENT; } @Override public String toString() { return "SIP"; } private void extractLines(String[] lines) { StringBuffer sbHeader = new StringBuffer(); StringBuffer sbSdp = new StringBuffer(); boolean recordHeader = false; boolean recordSdp = false; for (String line : lines) { if (line.startsWith("Via:")) { recordHeader = true; } else if (line.startsWith("Max-Forwards:")) { recordHeader = false; } else if(line.startsWith("v=")) { recordSdp = true; } else if(line.startsWith("a=")) { sbSdp.append(line + "\r\n"); header = sbHeader.toString(); sdpPayload = sbSdp.toString(); } if(recordHeader) { sbHeader.append(line + "\r\n"); } else if(recordSdp) { sbSdp.append(line + "\r\n"); } } } private Packet getRingResponse() { StringBuffer sb = new StringBuffer(); sb.append(VERSION + " " + STATUS_CODE_180 + "\r\n"); sb.append(header); sb.append("Content-Length: 0\r\n"); return new Packet(sb.toString()); } private Packet getOkResponseWithSDP() { StringBuffer sb = new StringBuffer(); sb.append(VERSION + " " + STATUS_CODE_200 + "\r\n"); sb.append(header); sb.append("Content-Type: application/sdp\r\n"); sb.append("Content-Length: " + sdpPayload.length() + "\r\n"); sb.append("\r\n"); sb.append(sdpPayload); return new Packet(sb.toString()); } private Packet getOkResponse() { StringBuffer sb = new StringBuffer(); sb.append(VERSION + " " + STATUS_CODE_200 + "\r\n"); sb.append(header); sb.append("Content-Length: 0\r\n"); return new Packet(sb.toString()); } private Packet getBadRequestResponse() { StringBuffer sb = new StringBuffer(); sb.append(VERSION + " " + STATUS_CODE_400 + "\r\n"); sb.append(header); sb.append("Content-Length: 0\r\n"); return new Packet(sb.toString()); } }