OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [tools/] [etermip.c] - Blame information for rev 352

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 242 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: etermip
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 6/13/07
5
 * FILENAME: etermip.c
6
 * PROJECT: Plasma CPU core
7
 * COPYRIGHT: Software placed into the public domain by the author.
8
 *    Software 'as is' without warranty.  Author liable for nothing.
9
 * DESCRIPTION:
10
 *    A terminal program supporting downloading new Plasma applications
11
 *    and Ethernet packet transfers.  Based on WinPcap example code.
12
 *    Requires WinPcap library at http://www.winpcap.org/.
13
 *--------------------------------------------------------------------*/
14
#include <windows.h>
15
#include <stdio.h>
16
#include <conio.h>
17
 
18
//#define SIMULATE_PLASMA
19
 
20
#if 0
21
   #include "pcap.h"
22
#else
23
   //From "pcap.h"
24
   #define PCAP_ERRBUF_SIZE 256
25
   typedef struct pcap_if {
26
      struct pcap_if *next;
27
      char *name;               /* name to hand to "pcap_open_live()" */
28
      char *description;        /* textual description of interface, or NULL */
29
      struct pcap_addr *addresses;
30
      unsigned long flags;      /* PCAP_IF_ interface flags */
31
   } pcap_if_t;
32
   struct pcap_pkthdr {
33
      struct timeval ts;        /* time stamp */
34
      unsigned long caplen;     /* length of portion present */
35
      unsigned long len;        /* length this packet (off wire) */
36
   };
37
   typedef struct pcap pcap_t;
38
 
39
   int pcap_findalldevs(pcap_if_t **, char *);
40
   void pcap_freealldevs(pcap_if_t *);
41
   pcap_t *pcap_open_live(const char *, int, int, int, char *);
42
   int pcap_setnonblock(pcap_t *, int, char *);
43
   int pcap_sendpacket(pcap_t *, const u_char *, int);
44
   const unsigned char *pcap_next(pcap_t *, struct pcap_pkthdr *);
45
#endif
46
 
47
//ETHER FIELD                 OFFSET   LENGTH   VALUE
48
#define ETHERNET_DEST         0        //6
49
#define ETHERNET_SOURCE       6        //6
50
#define ETHERNET_FRAME_TYPE   12       //2      IP=0x0800; ARP=0x0806
51
#define IP_PROTOCOL           23       //1      TCP=0x06;PING=0x01;UDP=0x11
52
#define IP_SOURCE             26       //4
53
 
54
static const unsigned char ethernetAddressNull[] =    {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
55
static const unsigned char ethernetAddressPhantom[] = {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4};
56
static const unsigned char ethernetAddressPhantom2[] = {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd5};
57
 
58
static pcap_t *adhandle;
59
static HANDLE serial_handle;
60
static int PacketBytes, PacketLength, PacketChecksum, Checksum;
61
static int ChecksumOk, ChecksumError;
62
static unsigned char PacketData[2000];
63
static int EthernetActive;
64
 
65
#ifdef SIMULATE_PLASMA
66
   extern void *IPFrameGet(int freeCount);
67
   extern int IPProcessEthernetPacket(void *frameIn, int length);
68
   extern void IPTick(void);
69 303 rhoads
   extern void IPInit(void (*frameSendFunction)(), unsigned char macAddress[6], char name[6]);
70 242 rhoads
   extern void HtmlInit(int UseFiles);
71
   extern void ConsoleInit(void);
72
   static void *ethFrame;
73
#endif
74
 
75
 
76
int WinPcapInit(void)
77
{
78
        pcap_if_t *alldevs;
79
        pcap_if_t *d;
80
        int inum;
81
        int i=0;
82
   int choice = -1;
83
        char errbuf[PCAP_ERRBUF_SIZE];
84
 
85
   /* Retrieve the device list */
86
        if(pcap_findalldevs(&alldevs, errbuf) == -1)
87
        {
88
                printf("Error in pcap_findalldevs: %s\n", errbuf);
89
                exit(1);
90
        }
91
 
92
        /* Print the list */
93
        for(d = alldevs; d; d=d->next)
94
        {
95
                printf("%d. %s", ++i, d->name);
96
                if (d->description)
97
                        printf(" (%s)\n", d->description);
98
                else
99
                        printf(" (No description available)\n");
100 303 rhoads
      if(strstr(d->description, "eneric") == 0 && strstr(d->description, "Linux") == 0)
101 242 rhoads
      {
102
         if(choice == -1)
103
            choice = i;
104
         else
105
            choice = -2;
106
      }
107
        }
108
 
109
        if(i==0)
110
        {
111
                printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
112
                return -1;
113
        }
114
 
115
   if(choice >= 0)
116
      inum = choice;
117
   else if(i == 1)
118
      inum = 1;
119
   else
120
   {
121
           printf("Enter the interface number (1-%d):",i);
122
           scanf("%d", &inum);
123
   }
124
   printf("inum = %d\n", inum);
125
 
126
        if(inum < 1 || inum > i)
127
        {
128
                printf("\nInterface number out of range.\n");
129
                /* Free the device list */
130
                pcap_freealldevs(alldevs);
131
                return -1;
132
        }
133
 
134
        /* Jump to the selected adapter */
135
        for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
136
 
137
        /* Open the adapter */
138
        if ((adhandle = pcap_open_live(d->name, // name of the device
139 269 rhoads
                                       65536,   // 65536 grants that the whole packet will be captured on all the MACs.
140
                                       1,       // promiscuous mode (nonzero means promiscuous)
141
                                       10,      // read timeout
142
                                       errbuf   // error buffer
143
                                       )) == NULL)
144 242 rhoads
        {
145
                printf("\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
146
                /* Free the device list */
147
                pcap_freealldevs(alldevs);
148
                return -1;
149
        }
150
 
151
        printf("\nlistening on %s...\n", d->description);
152
 
153
        /* At this point, we don't need any more the device list. Free it */
154
        pcap_freealldevs(alldevs);
155
 
156
   /* start the capture */
157
   pcap_setnonblock(adhandle, 1, errbuf);
158
 
159
   return 0;
160
}
161
 
162
 
163
void EthernetSendPacket(const unsigned char *packet, int length)
164
{
165 303 rhoads
   if(EthernetActive == 0)
166
      WinPcapInit();
167 242 rhoads
   EthernetActive = 1;
168
   pcap_sendpacket(adhandle, packet, length);
169
}
170
 
171
 
172
/* Callback function invoked by libpcap for every incoming packet */
173
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
174
{
175
#ifndef SIMULATE_PLASMA
176
   int i, checksum;
177
   unsigned char buf[80];
178
   DWORD count;
179
#else
180
   int rc;
181
#endif
182
   (void)param;
183
 
184 303 rhoads
   if(EthernetActive == 0)
185
      return;
186 242 rhoads
   if(pkt_data[ETHERNET_FRAME_TYPE] != 0x08)
187
      return;  //not IP or ARP
188
   if(pkt_data[ETHERNET_FRAME_TYPE+1] != 0x00 &&
189
      pkt_data[ETHERNET_FRAME_TYPE+1] != 0x06)
190
      return;  //not IP or ARP
191
   if(memcmp(pkt_data, ethernetAddressNull, 6) &&      //not broadcast address
192
      memcmp(pkt_data+ETHERNET_DEST, ethernetAddressPhantom, 6) &&
193
      memcmp(pkt_data+ETHERNET_DEST, ethernetAddressPhantom2, 6))
194
      return;
195
 
196
#ifndef SIMULATE_PLASMA
197
   //Send the ethernet packet over the serial port
198
   buf[0] = 0xff;
199
   buf[1] = (unsigned char)(header->len >> 8);
200
   buf[2] = (unsigned char)header->len;
201
   checksum = 0;
202
   for(i = 0; i < (int)header->len; ++i)
203
      checksum += pkt_data[i];
204
   buf[3] = (unsigned char)checksum;
205
   WriteFile(serial_handle, buf, 4, &count, NULL);
206
   WriteFile(serial_handle, pkt_data, header->len, &count, NULL);
207
#else
208
   if(ethFrame == NULL)
209
      ethFrame = IPFrameGet(0);
210
   if(ethFrame == NULL)
211
      return;
212
   memcpy(ethFrame, pkt_data, header->len);
213
   rc = IPProcessEthernetPacket(ethFrame, header->len);
214
   if(rc)
215
      ethFrame = NULL;
216
#endif
217
}
218
 
219
/**************************************************************/
220
 
221
long SerialOpen(char *name, long baud)
222
{
223
   DCB dcb;
224
   COMMTIMEOUTS comm_timeouts;
225
   BOOL rc;
226
   serial_handle = CreateFile(name, GENERIC_READ|GENERIC_WRITE,
227
      0, NULL, OPEN_EXISTING, 0, NULL);
228
   if(serial_handle == INVALID_HANDLE_VALUE)
229
      printf("Serial Port In Use!\n");
230
   rc = SetupComm(serial_handle, 16000, 16000);
231
   if(rc == FALSE)
232
      printf("Serial port already in use!!!\n");
233
   rc = GetCommState(serial_handle, &dcb);
234
   if(rc == FALSE)
235
      printf("ERROR2\n");
236
   dcb.BaudRate = baud;
237
   dcb.fBinary = 1;
238
   dcb.ByteSize = 8;
239
   dcb.fAbortOnError = 0;
240
   dcb.StopBits = 0; //ONESTOPBIT;
241
   dcb.fOutX = 0;
242
   dcb.fInX = 0;
243
   dcb.fNull = 0;
244
   dcb.Parity = 0;
245
   dcb.fOutxCtsFlow = 0;
246
   dcb.fOutxDsrFlow = 0;
247
   dcb.fOutX = 0;
248
   dcb.fInX = 0;
249
   dcb.fRtsControl = 0;
250
   rc = SetCommState(serial_handle, &dcb);
251
   if(rc == FALSE)
252
      printf("ERROR3\n");
253
   rc = GetCommTimeouts(serial_handle, &comm_timeouts);
254
   if(rc == FALSE)
255
      printf("ERROR4\n");
256
   comm_timeouts.ReadIntervalTimeout = MAXDWORD;  //non-blocking read
257
   comm_timeouts.ReadTotalTimeoutMultiplier = 0;
258
   comm_timeouts.ReadTotalTimeoutConstant = 0;
259
   comm_timeouts.WriteTotalTimeoutMultiplier = 0;  //blocking write
260
   comm_timeouts.WriteTotalTimeoutConstant = 0;
261
   rc = SetCommTimeouts(serial_handle, &comm_timeouts);
262
   if(rc == FALSE)
263
      printf("ERROR5\n");
264
   return(0);
265
}
266
 
267
 
268
static void UartPacketRead(int value)
269
{
270
   if(PacketBytes == 0 && value == 0xff)
271
   {
272
      ++PacketBytes;
273
   }
274
   else if(PacketBytes == 1)
275
   {
276
      ++PacketBytes;
277
      PacketLength = value << 8;
278
   }
279
   else if(PacketBytes == 2)
280
   {
281
      ++PacketBytes;
282
      PacketLength |= value;
283
      if(PacketLength > 1000)
284
      {
285
         PacketBytes = 0;
286
         printf("Eterm Length Bad! (%d)\n", PacketLength);
287
      }
288
   }
289
   else if(PacketBytes == 3)
290
   {
291
      ++PacketBytes;
292
      PacketChecksum = value;
293
      Checksum = 0;
294
   }
295
   else if(PacketBytes >= 4)
296
   {
297
      if(PacketBytes - 4 < sizeof(PacketData))
298
         PacketData[PacketBytes - 4] = (unsigned char)value;
299
      Checksum += value;
300
      ++PacketBytes;
301
      if(PacketBytes - 4 >= PacketLength)
302
      {
303
         if((unsigned char)Checksum == PacketChecksum)
304
         {
305
            ++ChecksumOk;
306
            EthernetSendPacket(PacketData, PacketLength);
307
         }
308
         else
309
         {
310
            ++ChecksumError;
311
            //printf("ChecksumError(%d %d)!\n", ChecksumOk, ChecksumError);
312
         }
313
         PacketBytes = 0;
314
      }
315
   }
316
}
317
 
318
 
319
long SerialRead(unsigned char *data, unsigned long length)
320
{
321
   DWORD count, bytes;
322
   unsigned char buf[8];
323
 
324
   count = 0;
325
   for(;;)
326
   {
327
      ReadFile(serial_handle, buf, 1, &bytes, NULL);
328
      if(bytes == 0)
329
         break;
330
      if(buf[0] == 0xff || PacketBytes)
331
         UartPacketRead(buf[0]);
332
      else
333
         data[count++] = buf[0];
334
      if(count >= length)
335
         break;
336
   }
337
   return count;
338
}
339
 
340
 
341
//****************************************************
342
 
343 277 rhoads
#define BUF_SIZE 1024*1024
344 242 rhoads
void SendFile(void)
345
{
346
   FILE *in;
347
   unsigned char *buf;
348
   long length;
349
   DWORD count;
350
 
351
   in=fopen("test.bin", "rb");
352
   if(in==NULL) {
353
      printf("Can't find test.bin\n");
354
      return;
355
   }
356
   buf = (unsigned char*)malloc(BUF_SIZE);
357
   memset(buf, 0, BUF_SIZE);
358
   length = (int)fread(buf, 1, BUF_SIZE, in);
359
   fclose(in);
360
   printf("Sending test.bin (length=%d bytes) to target...\n", length);
361
   WriteFile(serial_handle, buf, length, &count, NULL);
362
   printf("Done downloading\n");
363
   free(buf);
364
}
365
 
366
 
367
int main(int argc, char *argv[])
368
{
369
   unsigned int ticksLast = GetTickCount();
370
   int length;
371
   unsigned char buf[80];
372
   DWORD count;
373
   unsigned int ticks;
374 269 rhoads
   int downloadSkip = 0;
375 242 rhoads
   (void)argc;
376
   (void)argv;
377
 
378 303 rhoads
   //WinPcapInit();
379 242 rhoads
#ifndef SIMULATE_PLASMA
380
   SerialOpen("COM1", 57600);
381 269 rhoads
   if(argc != 2 || strcmp(argv[1], "none"))
382
      SendFile();
383
   else
384
      downloadSkip = 1;
385 242 rhoads
#else
386 295 rhoads
   IPInit(EthernetSendPacket, NULL, NULL);
387 242 rhoads
   HtmlInit(1);
388
   ConsoleInit();
389
#endif
390
 
391
   for(;;)
392
   {
393
      // Read keypresses
394
      while(kbhit())
395
      {
396
         buf[0] = (unsigned char)getch();
397 269 rhoads
         if(downloadSkip && buf[0] == '`')
398
            SendFile();
399 242 rhoads
         WriteFile(serial_handle, buf, 1, &count, NULL);
400
      }
401
 
402
      // Read UART
403
      for(;;)
404
      {
405
         length = SerialRead(buf, sizeof(buf));
406
         if(length == 0)
407
            break;
408
         buf[length] = 0;
409
         printf("%s", buf);
410
      }
411
 
412
      // Read Ethernet
413 303 rhoads
      while(EthernetActive)
414 242 rhoads
      {
415
         struct pcap_pkthdr header;
416
         const u_char *pkt_data;
417
         pkt_data = pcap_next(adhandle, &header);
418
         if(pkt_data == NULL)
419
            break;
420
         if(EthernetActive)
421
            packet_handler(NULL, &header, pkt_data);
422
      }
423
      Sleep(10);
424
      ticks = GetTickCount();
425
      if(ticks - ticksLast > 1000)
426
      {
427
#ifdef SIMULATE_PLASMA
428
         IPTick();
429
#endif
430
         ticksLast = ticks;
431
      }
432
   }
433
}
434 269 rhoads
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.