package uk.co.mmscomputing.sms;
import java.io.*;
import uk.co.mmscomputing.dsp.phone.FSKOutputStream;
public class SMSLandLineOutputStream extends FilterOutputStream{
static private int T10 = 300; // BT SIN413 p.6; T10min = n * 100 ms [1] 5.3.1 p.14
private byte[] bytes=new byte[178]; // buffer data
private int count;
public SMSLandLineOutputStream(OutputStream out){
super(new FSKOutputStream(out));
count=0;
}
private void writeChecksum()throws IOException{
int checksum=0;
for(int i=0;i<count;i++){ // [1] 5.3.2.1 p.16
checksum+=bytes[i]&0x00FF;
}
checksum=(-checksum)&0x00FF; // checksum: Two's complement modulo 256 of sum of bytes (excluding checksum byte).
out.write(checksum);
}
// Data Link Layer message structure
// Mark Signal | Message Type | Message Length | Payload (Transfer Layer Message) | Checksum
protected void writeMessage(boolean segmented)throws IOException{
if(bytes[0]==SMSConstants.SMS_DLL_EST){
((FSKOutputStream)out).writeDelay(T10); // T10min = n * 100 ms [1] 5.3.1 p.14
}else{
((FSKOutputStream)out).writeDelay(100); // T11min = 100 ms [1] 5.3.1 p.14
}
((FSKOutputStream)out).writeMarkSignal(80); // 55 .. 80 .. 105; [1] 5.3.2.1 p.15
if(segmented){ bytes[0]&=(byte)0x007F; // if segmented clear bit 7
}else{ bytes[0]|=(byte)0x0080; // else set bit 7
}
bytes[1]=(byte)(count-2); // set length of message excluding checksum
out.write(bytes,0,count); // write type length payload
writeChecksum(); // write checksum
((FSKOutputStream)out).writeBits(-1,10);
}
public void write(int b)throws IOException{
if(count==bytes.length){ // send as segmented message
writeMessage(true);
count=2; // byte 0: type needs to be send again; byte 1: length
}
bytes[count++]=(byte)b; // buffer message data
if(count==1){ // expect first byte to be type of message !
count++; // skip length here, set in writeMessage
}
}
public void flush()throws IOException{ // flush to send transport protocol data unit
if(count>0){
writeMessage(false);
count=0;
}
out.flush();
}
}
// [1] Final draft ETSI ES 201 912 V1.2.1 (2004-06)