:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / apps / utils / pice / loader / terminal.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7     termínal.c
8
9 Abstract:
10
11     serial terminal for pICE headless mode
12
13 Environment:
14
15     User mode only
16
17 Author:
18
19     Klaus P. Gerlicher
20
21 Revision History:
22
23     23-Jan-2001:        created
24
25 Copyright notice:
26
27   This file may be distributed under the terms of the GNU Public License.
28
29 --*/
30 #if 0 //ei not ready
31 #include "stdinc.h"
32 #include <curses.h>
33
34
35 #define CONSOLE_WIDTH (80)
36 #define CONSOLE_HEIGHT (25)
37
38 USHORT major_version=0xFFFF,minor_version=0xFFFF,build_number=0xFFFF;
39
40 USHORT g_attr = 0;
41
42 USHORT usCurX,usCurY,xSize,ySize;
43
44 USHORT foreground_color_map[]=
45 {
46 };
47
48 USHORT background_color_map[]=
49 {
50 };
51
52
53 int fd_comm;
54 struct termios oldtio;
55
56 //************************************************************************
57 // CheckSum()
58 //
59 //************************************************************************
60 UCHAR CheckSum(LPSTR p,ULONG Len)
61 {
62         UCHAR ucCheckSum = 0;
63         ULONG i;
64         for(i=0;i<Len;i++)
65         {
66                 ucCheckSum ^= *p++;
67         ucCheckSum += 1;
68         }
69
70         return ucCheckSum;
71 }
72
73 ///************************************************************************
74 // ReadByte()
75 //
76 ///************************************************************************
77 BOOLEAN ReadByte(PUCHAR pc)
78 {
79     return (read(fd_comm,pc,1) > 0);
80 }
81
82 ///************************************************************************
83 // SendByte()
84 //
85 ///************************************************************************
86 BOOLEAN SendByte(UCHAR c)
87 {
88     return (write(fd_comm,&c,1) > 0);
89 }
90
91
92 ///************************************************************************
93 // ReadPacket()
94 //
95 ///************************************************************************
96 PSERIAL_PACKET ReadPacket(void)
97 {
98     ULONG i;
99     PSERIAL_PACKET p;
100     SERIAL_PACKET_HEADER header;
101     PUCHAR pHeaderRaw,pData;
102     char temp[256];
103     ULONG ulCheckSum;
104
105     // read a packet header
106     pHeaderRaw = (PUCHAR)&header;
107     for(i=0;i<sizeof(SERIAL_PACKET_HEADER);i++)
108     {
109 //        //printf("reading()\n");
110         if(! ReadByte(pHeaderRaw))
111         {
112   //          //printf("no header byte read!\n");
113             return NULL;
114         }
115
116         pHeaderRaw++;
117     }
118
119     //printf("received header!\n");
120
121     ulCheckSum = header.packet_header_chksum;
122     header.packet_header_chksum = 0;
123
124     if(ulCheckSum != CheckSum((PUCHAR)&header,sizeof(SERIAL_PACKET_HEADER)) )
125     {
126         //printf("header checksum mismatch!\n");
127         tcflush(fd_comm, TCIFLUSH);
128         return NULL;
129     }
130
131     p = malloc(sizeof(SERIAL_PACKET_HEADER) + header.packet_size);
132     if(!p)
133     {
134         //printf("out of memory!\n");
135         return NULL;
136     }
137     PICE_memcpy(p,&header,sizeof(SERIAL_PACKET_HEADER));
138
139     sprintf(temp,"size %X chksum %x\n",header.packet_size,header.packet_chksum);
140     //printf(temp);
141
142     // read the attached data
143     pData = (PUCHAR)p + sizeof(header);
144     for(i=0;i<header.packet_size;i++)
145     {
146         if(! ReadByte(pData))
147         {
148             //printf("no data byte read!\n");
149             return NULL;
150         }
151
152         pData++;
153     }
154
155     //printf("received data!\n");
156
157     pData = (PUCHAR)p + sizeof(header);
158     if(header.packet_chksum != CheckSum(pData,header.packet_size))
159     {
160         free(p);
161         p = NULL;
162         //printf("data checksum mismatch!\n");
163         return NULL;
164     }
165
166     while(!SendByte(ACK));
167
168     return p;
169 }
170
171 ///************************************************************************
172 // SendPacket()
173 //
174 ///************************************************************************
175 BOOLEAN SendPacket(PSERIAL_PACKET p)
176 {
177     return TRUE;
178 }
179
180 void DeletePacket(PSERIAL_PACKET p)
181 {
182     free(p);
183 }
184
185 //************************************************************************
186 // SetupSerial()
187 //
188 //************************************************************************
189 BOOLEAN SetupSerial(ULONG port,ULONG baudrate)
190 {
191     struct termios newtio;
192     char* ports[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3"};
193
194     /*
195     Open modem device for reading and writing and not as controlling tty
196     because we don't want to get killed if linenoise sends CTRL-C.
197     */
198     //printf("opening comm %s\n",ports[port-1]);
199     fd_comm = open(ports[port-1], O_RDWR | O_NOCTTY);
200     if (fd_comm <0)
201     {
202         perror(ports[port-1]);
203         exit(-1);
204     }
205
206     //printf("tcgetattr()\n");
207     tcgetattr(fd_comm,&oldtio); /* save current modem settings */
208
209                            /*
210                            Set bps rate and hardware flow control and 8n1 (8bit,no parity,1 stopbit).
211                            Also don't hangup automatically and ignore modem status.
212                            Finally enable receiving characters.
213     */
214     newtio.c_cflag = baudrate | CS8 | CLOCAL | CREAD;
215
216     /*
217     Ignore bytes with parity errors and make terminal raw and dumb.
218     */
219     newtio.c_iflag = IGNPAR;
220
221     /*
222     Raw output.
223     */
224     newtio.c_oflag = 0;
225
226     /*
227     Don't echo characters because if you connect to a host it or your
228     modem will echo characters for you. Don't generate signals.
229     */
230     newtio.c_lflag = 0;
231
232     /* blocking read until 1 char arrives */
233     newtio.c_cc[VMIN]=0;
234     newtio.c_cc[VTIME]=0;
235
236     /* now clean the modem line and activate the settings for modem */
237     //printf("tcflush()\n");
238     tcflush(fd_comm, TCIFLUSH);
239     //printf("tcsetattr()\n");
240     tcsetattr(fd_comm,TCSANOW,&newtio);
241
242     // NCURSES
243     initscr();
244     refresh();
245
246     return TRUE;
247 }
248
249 //************************************************************************
250 // CloseSerial()
251 //
252 //************************************************************************
253 void CloseSerial(void)
254 {
255     // NCURSES
256     endwin();
257
258     tcsetattr(fd_comm,TCSANOW,&oldtio); /* save current modem settings */
259     close(fd_comm);
260 }
261
262 //************************************************************************
263 // ClrLine()
264 //
265 //************************************************************************
266 void ClrLine(UCHAR line)
267 {
268     move(line,0);
269 }
270
271 //************************************************************************
272 // InvertLine()
273 //
274 //************************************************************************
275 void InvertLine(UCHAR line)
276 {
277     move(line,0);
278 }
279
280 //************************************************************************
281 // SetCursorPosition()
282 //
283 //************************************************************************
284 void SetCursorPosition(USHORT x, USHORT y)
285 {
286     move(y,x);
287 }
288
289 //************************************************************************
290 // GetCursorPosition()
291 //
292 //************************************************************************
293 void GetCursorPosition(PUSHORT px,PUSHORT py)
294 {
295 }
296
297 //************************************************************************
298 // SetCursorState()
299 //
300 //************************************************************************
301 void SetCursorState(UCHAR c)
302 {
303 }
304
305
306 //************************************************************************
307 // Print()
308 //
309 //************************************************************************
310 void Print(LPSTR p,USHORT x,USHORT y)
311 {
312     // save the cursor pos
313     GetCursorPosition(&usCurX,&usCurY);
314
315     if(y<25)
316     {
317         SetCursorPosition(x,y);
318         refresh();
319
320         addstr(p);
321         refresh();
322         SetCursorPosition(usCurX,usCurY);
323     }
324 }
325
326 //************************************************************************
327 // ProcessPacket()
328 //
329 //************************************************************************
330 void ProcessPacket(PSERIAL_PACKET p)
331 {
332     ULONG ulSize;
333     PSERIAL_DATA_PACKET pData;
334
335     pData = (PSERIAL_DATA_PACKET)((PUCHAR)p + sizeof(SERIAL_PACKET_HEADER));
336     ulSize = p->header.packet_size;
337
338     switch(pData->type)
339     {
340         case PACKET_TYPE_CONNECT:
341             {
342                 PSERIAL_DATA_PACKET_CONNECT pDataConnect = (PSERIAL_DATA_PACKET_CONNECT)pData;
343                 UCHAR i;
344
345                 for(i=0;i<ySize;i++)
346                     ClrLine(i);
347
348                 SetCursorState(0);
349                 SetCursorPosition(0,0);
350 //                ResizeConsole(hConsole,pDataConnect->xsize,pDataConnect->ysize);
351                 xSize = pDataConnect->xsize;
352                 ySize = pDataConnect->ysize;
353             }
354             break;
355         case PACKET_TYPE_CLRLINE:
356             {
357                 PSERIAL_DATA_PACKET_CLRLINE pDataClrLine = (PSERIAL_DATA_PACKET_CLRLINE)pData;
358
359                 ClrLine(pDataClrLine->line);
360             }
361             break;
362         case PACKET_TYPE_INVERTLINE:
363             {
364                 PSERIAL_DATA_PACKET_INVERTLINE pDataInvertLine = (PSERIAL_DATA_PACKET_INVERTLINE)pData;
365
366                 InvertLine(pDataInvertLine->line);
367             }
368             break;
369         case PACKET_TYPE_PRINT:
370             {
371                 PSERIAL_DATA_PACKET_PRINT pDataPrint = (PSERIAL_DATA_PACKET_PRINT)pData;
372
373                 Print(pDataPrint->string,pDataPrint->x,pDataPrint->y);
374             }
375             break;
376         case PACKET_TYPE_CURSOR:
377             {
378                 PSERIAL_DATA_PACKET_CURSOR pDataCursor = (PSERIAL_DATA_PACKET_CURSOR)pData;
379
380                 SetCursorPosition(pDataCursor->x,pDataCursor->y);
381                 SetCursorState(pDataCursor->state);
382             }
383             break;
384         case PACKET_TYPE_POLL:
385             {
386                 PSERIAL_DATA_PACKET_POLL pDataPoll= (PSERIAL_DATA_PACKET_POLL)pData;
387
388                 if( (major_version != pDataPoll->major_version) ||
389                     (minor_version != pDataPoll->minor_version) ||
390                     (build_number != pDataPoll->build_number) )
391                 {
392                     major_version = pDataPoll->major_version;
393                     minor_version = pDataPoll->minor_version;
394                     build_number  = pDataPoll->build_number;
395
396 //                    SetAppTitle();
397                 }
398
399             }
400             break;
401         default:
402             //printf("UNHANDLED\n");
403             break;
404     }
405 }
406
407 //************************************************************************
408 // DebuggerShell()
409 //
410 //************************************************************************
411 void DebuggerShell(void)
412 {
413     PSERIAL_PACKET p;
414
415     //printf("DebuggerShell()\n");
416     for(;;)
417     {
418          p = ReadPacket();
419          if(p)
420          {
421              ProcessPacket(p);
422              DeletePacket(p);
423          }
424          else
425          {
426              usleep(100*1000);
427          }
428     }
429 }
430 #endif