Subversion Repositories Projects

Rev

Rev 1566 | Rev 1611 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1563 - 1
package dongfang.mkt.comm;
2
 
3
import java.io.IOException;
4
import java.io.OutputStream;
5
 
1566 - 6
import dongfang.mkt.RequestFrameVisitor;
1563 - 7
import dongfang.mkt.frames.AllDisplaysRequestFrame;
8
import dongfang.mkt.frames.AnalogDebugLabelRequestFrame;
9
import dongfang.mkt.frames.AttitudeDataRequestFrame;
10
import dongfang.mkt.frames.ChangeParameterSetRequestFrame;
11
import dongfang.mkt.frames.CompassHeadingRequestFrame;
12
import dongfang.mkt.frames.DebugRequestFrame;
13
import dongfang.mkt.frames.ExternalControlRequestFrame;
14
import dongfang.mkt.frames.LoopbackTestRequestFrame;
15
import dongfang.mkt.frames.MotorTestRequestFrame;
16
import dongfang.mkt.frames.OSDDataRequestFrame;
17
import dongfang.mkt.frames.ReadExternalControlRequestFrame;
18
import dongfang.mkt.frames.RequestFrame;
19
import dongfang.mkt.frames.ResetRequestFrame;
20
import dongfang.mkt.frames.SetCompassHeadingRequestFrame;
21
import dongfang.mkt.frames.SingleDisplayRequestFrame;
22
import dongfang.mkt.frames.UniversalReadParamSetRequestFrame;
23
import dongfang.mkt.frames.UniversalWriteParamSetRequestFrame;
24
import dongfang.mkt.frames.VariablesRequestFrame;
25
import dongfang.mkt.frames.VersionRequestFrame;
26
 
27
public class MKOutputStream extends OutputStream implements RequestFrameVisitor {
28
        public class MKDataOutputStream {
29
                int[] inbuf = new int[3];
30
                int[] outbuf = new int[4];
31
                int inbufptr = 0;
32
 
33
                void writeByte(int b) throws IOException {
34
                        if(inbufptr == inbuf.length) flush();
35
                        inbuf[inbufptr++] = b;
36
                }
37
 
38
                public void writeBytes(int[] bs) throws IOException {
39
                        for (int i=0; i<bs.length; i++)
40
                                writeByte(bs[i]);
41
                }
42
 
43
                void writeWord(int w) throws IOException {
44
                        writeByte(w & 0xff);
45
                        writeByte(w >>> 8);
46
                }
47
 
48
                void writeChars(char[] s) throws IOException {
49
                        for (int i=0; i<s.length; i++) {
50
                                // Here, a 1:1 mapping between byte values and char codes is assumed.
51
                                // That means we're assuming ISO-8859-1 (= the first 256 code points
52
                                // of Unicode, which Java uses for chars)
53
                                writeByte(s[i]);
54
                        }
55
                }
56
 
57
                void flush() throws IOException {
58
                        if (inbufptr == 0)
59
                                return;
60
 
61
                        while(inbufptr < inbuf.length) {
62
                                // add padding .. well just clear it, for tidyness.
63
                                inbuf[inbufptr++] = 0;
64
                        }
65
 
66
                        MKOutputStream.this.writeByte((inbuf[0] >>> 2) + '=');
67
                        MKOutputStream.this.writeByte(( ((inbuf[0] & 0x03) << 4) | (inbuf[1] >>> 4) ) + '=');
68
                        MKOutputStream.this.writeByte(( ((inbuf[1] & 0x0f) << 2) | (inbuf[2] >>> 6)) + '=');
69
                        MKOutputStream.this.writeByte(((inbuf[2] & 0x3f) + '='));
70
 
71
                        inbufptr = 0;
72
                }
73
        }
74
 
75
        final OutputStream os;
76
        MKDataOutputStream base64OutputStream = new MKDataOutputStream();
77
        int crc;
78
 
79
        public MKOutputStream(OutputStream os) {
80
                this.os = os;
81
        }
82
 
83
        @Override
84
        public void write(int b) throws IOException {
85
                os.write(b);
86
                // System.out.println("Writing: " + b);
87
        }
88
 
89
        public void writeByte(int b) throws IOException {
90
                crc += b;
91
                write(b);
92
        }
93
 
94
        public void write(RequestFrame f) throws IOException {
95
                write(crc = '#');
96
 
97
                int address = f.getAddress() + 'a';
98
                writeByte(address);
99
 
100
                // Will cause one of the "visit" methods below 
101
                // to be called, depending on the type of f.
102
                f.accept(this);
103
                base64OutputStream.flush();
104
 
105
                crc %= 4096;
106
                write((crc >>> 6) + '=');
107
                write((crc & 0x3f) + '=');
108
 
109
                write('\r');
110
        }
111
 
112
        /*
113
        public void visit(RequestFrame f) {
114
                throw new RuntimeException("Unbound RequestFrame type: "
115
                                + f.getClass().getSimpleName()
116
                                + ". Don't know how to output.");
117
        }
118
        */
119
 
120
        public void visit(AnalogDebugLabelRequestFrame f) throws IOException {
121
                writeByte('a');
122
                base64OutputStream.writeByte(f.getChannel());
123
        }
124
 
125
        public void visit(AttitudeDataRequestFrame f) throws IOException {
126
                writeByte('c');
127
                base64OutputStream.writeByte(f.getAutoSendInterval());
128
        }
129
 
130
        public void visit(DebugRequestFrame f) throws IOException {
131
                writeByte('d');
132
                base64OutputStream.writeByte(f.getAutoSendInterval());
133
        }
134
 
135
        public void visit(ChangeParameterSetRequestFrame f) throws IOException {
136
                writeByte('f');
137
                base64OutputStream.writeByte(f.getParameterSetNumber());
138
        }
139
 
140
        public void visit(VersionRequestFrame f) throws IOException {
141
                writeByte('v');
142
        }
143
 
144
        public void visit(ResetRequestFrame f) throws IOException {
145
                writeByte('R');
146
        }
147
 
148
        public void visit(MotorTestRequestFrame f) throws IOException {
149
                writeByte('t');
150
                base64OutputStream.writeBytes(f.getMotorValues());
151
        }
152
 
153
        public void visit(SingleDisplayRequestFrame f) throws IOException {
154
                writeByte('l');
155
                base64OutputStream.writeByte(f.getMenuItemCode()); // In 0.74 there is not the all in one mode.
156
        }
157
 
158
        public void visit(AllDisplaysRequestFrame f) throws IOException {
159
                writeByte('h');
160
                base64OutputStream.writeByte(f.getPageOrder().getRemoteKeys());
161
                // mdo.writeByte(f.getAutoSendInterval());
162
        }
163
 
164
        public void visit(VariablesRequestFrame f) throws IOException {
165
                writeByte('x');
166
        }
167
 
168
        public void visit(ExternalControlRequestFrame f) throws IOException {
169
                writeByte('b');
170
                base64OutputStream.writeByte(f.getDigital()[0]);
171
                base64OutputStream.writeByte(f.getDigital()[1]);
172
                base64OutputStream.writeByte(f.getRemoteButtons());
173
                base64OutputStream.writeByte(f.getPitch());
174
                base64OutputStream.writeByte(f.getRoll());
175
                base64OutputStream.writeByte(f.getYaw());
176
                base64OutputStream.writeByte(f.getThrottle());
177
                base64OutputStream.writeByte(f.getHeight());
178
                base64OutputStream.writeByte(f.getCommand());
179
                base64OutputStream.writeByte(f.getFrameNum());
180
                base64OutputStream.writeByte(f.getArgument());
181
        }
182
 
183
        public void visit(ReadExternalControlRequestFrame f) throws IOException {
184
                writeByte('g');
185
        }
186
 
187
        public void visit(LoopbackTestRequestFrame f) throws IOException {
188
                writeByte('0');
189
                base64OutputStream.writeByte(f.getByte());
190
                base64OutputStream.writeWord(f.getWord());
191
                base64OutputStream.writeChars(f.getChararray());
192
        }
193
 
194
        public void visit(UniversalReadParamSetRequestFrame f) throws IOException {
195
                writeByte('q');
196
                base64OutputStream.writeByte(f.getConfigurationSetNumber());
197
        }
198
 
199
        public void visit(UniversalWriteParamSetRequestFrame f) throws IOException {
200
                writeByte('s');
201
                base64OutputStream.writeByte(f.getConfigurationSetNumber());
202
                base64OutputStream.writeByte(f.getConfigurationVersionNumber());
1573 - 203
                base64OutputStream.writeByte(f.getDataLength() + 12);
1563 - 204
                base64OutputStream.writeBytes(f.getData());
1573 - 205
                base64OutputStream.writeChars(f.getName());
1563 - 206
        }
207
 
208
        public void visit(SetCompassHeadingRequestFrame f) throws IOException {
209
                writeByte('K');
210
        }
211
 
212
        public void visit(CompassHeadingRequestFrame f) throws IOException {
213
                writeByte('w');
214
        }
215
 
216
        public void visit(OSDDataRequestFrame f) throws IOException {
217
                writeByte('o');
218
                base64OutputStream.writeByte(f.getAutoSendInterval());
219
        }
220
}