⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp_ping.c

📁 基于C51单片机的PPOE协议栈源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////////////
//
//    PING.C    version 1.10    July 29/99     (C)opyright by Microchip Technology Inc
//
//    Modified by ZeRoN, 2003.01.23
//    for KEIL C51 Compiler, uVision1, C51 v5.1
//
//    - used P2 for PORTB, Status LEDs
//
///////////////////////////////////////////////////////////////////////////////////////
//
// For more documentation read the Microchip Application Note 724
// This code is ready to compile with the HiTech C compiler demo for the PIC16C63A.
//
// You will need these additional things to make this code work:
//
//    - the simple hardware described in application note
//
//    - an Internet account with PPP dialup access (not compatible with all ISPs)
//
//    - replace 5551234 with your ISP's phone number in the line like this
//         if (sendwait("5551234\r","NNECT",3000)) {
//
//    - replace userid with your account userid in the line like this:
//         if (sendwait("userid\r","word:",200))
//
//    - replace password with your account password in the line like this:
//         if (sendwait("password\r","tion:",1000))
//
//    - replace the entire string in the line like this:
//         MakePacket(PAP,REQ,number,"\x14\x06userid\x08password");
//
//         C converts the \x## in the string to a character with that ASCII value
//         ## is a hexadecimal value, so the following character cannot be
//         if the next character is 0-9 or A-F or a-f then it will confuse the compiler
//         the solution is to convert the next characters to \x## until a non hex char
//         if in doubt look at the assembly output from the compiler
//         or try MakePacket(PAP,REQ,number,"\x14\x06" "userid\x08" "password");
//         replace the userid with yours and the \x06 with your userid length
//         replace the password with yours and the \x08 with your password length
//         replace the first value in the string, it must be the string length plus 4
//
// Once login is working you should also change the IP address of the Internet host to ping
// if you can not ping 207.161.117.67 with your PC this code will not work either
//    It is CF.A1.75.43, the characters 2 to 5, in the string in the line like this:
//       MakePacket(IP,0,1,"\x10\xCF\xA1\x75\x43\x8\x0\xF7\xFE\x0\x1\x0\x0");
//    Convert the address you want to hexadecimal and replace the four values.
//
// Make sure the power-on reset and brownout detect config bits are enabled
//
///////////////////////////////////////////////////////////////////////////////////////

//-------------------------------------------------------------------------------------
// My additions portion for P89C51RD2
//-------------------------------------------------------------------------------------
#define __KEIL__
#define CHIP_89C51RD2

typedef unsigned char UCHAR;
typedef unsigned int  UINT;
typedef unsigned long ULONG;

#include <stdio.h>
#include <intrins.h>
#include "reg51rd2.h"

// Defines
#define XTALFREQ       11059200
#define TIMERINTERVAL  0.010          /* Timer Interval 10mS. */
#ifdef CHIP_89C51RD2
  #define FCYCLE       (XTALFREQ/6)
#else
  #define FCYCLE       (XTALFREQ/12)
#endif
#define TCONST         (65536-((UINT)(TIMERINTERVAL*FCYCLE)))
#define HiTCONST       (UCHAR)(TCONST/256)
#define LoTCONST       (UCHAR)(TCONST%256)

#define TIMER0STOP     (TR0=0)
#define TIMER0RUN      (TR0=1)

#define GOIDLE         (PCON|=1)

#define TIMER_0S       0
#define TIMER_10MS     1
#define TIMER_50MS     5
#define TIMER_100MS    10
#define TIMER_500MS    50
#define TIMER_1S       100
#define TIMER_2S       200

#define SCIBPS57K6     57600
#define SCIBPS19K2     19200
#define SCIBPS4K8      4800
#ifdef CHIP_89C51RD2
  #define BRG          (XTALFREQ/16)
#else
  #define BRG          (XTALFREQ/32)
#endif
#define T2BRG57K6      (65536-((UINT)(BRG/SCIBPS57K6)))
#define HiT2BRG57K6    (UCHAR)(T2BRG57K6/256)
#define LoT2BRG57K6    (UCHAR)(T2BRG57K6%256)
#define T2BRG19K2      (65536-((UINT)(BRG/SCIBPS19K2)))
#define HiT2BRG19K2    (UCHAR)(T2BRG19K2/256)
#define LoT2BRG19K2    (UCHAR)(T2BRG19K2%256)
#define T2BRG4K8       (65536-((UINT)(BRG/SCIBPS4K8)))
#define HiT2BRG4K8     (UCHAR)(T2BRG4K8/256)
#define LoT2BRG4K8     (UCHAR)(T2BRG4K8%256)

#define ENABLE_INT     (EA=1)        /* enable interrupts */
#define DISABLE_INT    (EA=0)        /* disable interrupts */
//-------------------------------------------------------------------------------------

// Defines for Internet constants
#define   REQ  1    // Request options list for PPP negotiations
#define   ACK  2    // Acknowledge options list for PPP negotiations
#define   NAK  3    // Not acknowledged options list for PPP negotiations
#define   REJ  4    // Reject options list for PPP negotiations
#define   TERM 5    // Termination packet for LCP to close connection
#define   IP   0x0021    // Internet Protocol packet
#define   IPCP 0x8021    // Internet Protocol Configure Protocol packet
#define   CCP  0x80FD    // Compression Configure Protocol packet
#define   LCP  0xC021    // Link Configure Protocol packet
#define   PAP  0xC023    // Password Authenication Protocol packet

#define   MaxRx     46   // Maximum size of receive buffer
#define   MaxTx     46   // Maximum size of transmit buffer

unsigned char addr1, addr2, addr3, addr4;    // Assigned IP address
unsigned int rx_ptr, tx_ptr, tx_end;         // pointers into buffers
unsigned int checksum1, checksum2;           // Rx and Tx checksums
unsigned char number;                        // Unique packet id

#define serial_tx_ready()     TI                  // Transmitter empty
#define serial_send(a)        putchar(a)          // Transmit char a
#define serial_rx_ready()     RI                  // Receiver full
#define serial_get()          getchar()           // Receive char
#define serial_error()        OERR                // USART error
#define serial_fix()          {CREN=0;CREN=1;}    // Clear error

unsigned int TIME;                      // 10 millseconds counter
#define TIME_SET(a) TIME=a              // Set 10 millisecond counter to value 'a'
idata unsigned char tx_str[MaxRx+1];    // Transmitter buffer
idata unsigned char rx_str[MaxTx+1];    // Receiver buffer

//-------------------------------------------------------------------------------------
// My additions portion for P89C51RD2
//-------------------------------------------------------------------------------------
// Timer0 ISR
void timer0int_isr(void) interrupt 1 using 0 /* USED REGISTERS BANK 0 (NO R0-R7 USED) */
{
   TIMER0STOP;
   TH0=HiTCONST;
   TL0=LoTCONST;
   TIMER0RUN;
   TIME++;                    // Increment 10 ms counter
}

void timer0_init(void)
{
    TH0=HiTCONST;
    TL0=LoTCONST;
    TMOD=(TMOD&0xF0)|0x01;           /* 16 bits Timer */
    ET0=1;                           /* Timer 0 Interrupt enabled */
    TIMER0RUN;                       /* Timer 0 Started */
}

void serial_init(void)
{
    RCAP2H=HiT2BRG57K6;
    RCAP2L=LoT2BRG57K6;
    PCON=0x00;                       /* SMOD: SMOD=0 for 1x BuadRate by T1 */
    SCON=0x50;                       /* SCON: mode 1, 8-bit UART, enable rcvr    */
    T2CON=0x30;                      /* T2 as Baudrate Generator */
    TR2=1;                           /* TR2:  timer 2 run                        */
    TI=1;                            /* TI:   set TI to send first char of UART  */
}
//-------------------------------------------------------------------------------------

// Add next character to the CRC checksum for PPP packets
unsigned int calc(unsigned int c) {
   char i;                    // Just a loop index
   c &= 0xFF;                 // Only calculate CRC on low byte
   for (i=0;i<8;i++) {        // Loop eight times, once for each bit
      if (c&1) {              // Is bit high?
         c /= 2;              // Position for next bit      
         c ^= 0x8408;         // Toggle the feedback bits
      } else c /= 2;          // Just position for next bit
   }                          // This routine would be best optimized in assembly
   return c;                  // Return the 16 bit checksum
}

// Add character to the new packet
void add(unsigned char c) {
   checksum2 = calc(c^checksum2) ^ (checksum2/256); // Add CRC from this char to running total
   tx_str[tx_ptr] = c;        // Store character in the transmit buffer
   tx_ptr++;                  // Point to next empty spot in buffer
}

// Create packet of type, code, length, and data string specified
//   packet is the type, like LCP or IP
//   code is the LCP type of packet like REQ, not used for IP packets
//   num is the packet ID for LCP, or the IP data type for IP packets
//   *str is the packet data to be added after the header
//   returns the packet as a string in tx_str
void MakePacket(unsigned int packet, unsigned char pcode, unsigned char num, const unsigned char *str) {
   unsigned int length;       // Just a dual use temp variable
   tx_ptr = 1;                // Point to second character in transmit buffer
   tx_str[0] = ' ';           // Set first character to a space for now
   checksum2 = 0xFFFF;        // Initialize checksum
   add(0xFF);                 // Insert PPP header OxFF
   add(3);                    // Insert PPP header 0x03
   add(packet/256);           // Insert high byte of protocol field
   add(packet&255);           // Insert low byte of protocol field
   if (packet==IP) {          // If Internet Protocol
      add(0x45);              // Insert header version and length
      add(0);                 // Insert type of service
      add(0);                 // Insert total packet length high byte
      add((*str)+12);         // Insert total packet length low byte
      add(0x88);              // Insert identification high byte
      add(0x10);              // Insert identification low byte
      add(0x40);              // Insert flags and fragement offset
      add(0);                 // Insert rest of fragment offset
      add(127);               // Insert time to live countdown
      add(num);               // insert the protocol field
      length = 0x45+0x88+0x40+127+addr1+addr3+str[1]+str[3];  // high byte checksum
      packet = *str + 12 + 0x10 + num + addr2 + addr4 + str[2] + str[4];  
                              // low byte checksum
      packet += length/256;   // make 1's complement
      length = (length&255) + packet/256;    // by adding low carry to high byte
      packet = (packet&255) + length/256;    // and adding high carry to low byte
      length += packet/256;                  // fix new adding carries
      add(~length);           // Insert 1's complement checksum high byte
      add(~packet);           // Insert 1's complement checksum low byte
      add(addr1);             // Insert the 4 bytes of this login's IP address
      add(addr2);
      add(addr3);
      add(addr4);
      length = *str - 4;      // save the number of following data bytes
      str++;                  // point to the first data byte
   } else {
      add(pcode);             // Insert packet type, like REQ or NAK
      add(num);               // Insert packet ID number
      add(0);                 // Insert most significant byte of length
      length = *str - 3;      // point to the first data byte
   }
   while (length) {           // copy the whole string into packet
      length--;               // decrement packet length
      add(*str);              // add current character to packet
      str++;                  // point to next character
   }
   length = ~checksum2;       // invert the checksum
   add(length&255);           // Insert checksum msb
   add(length/256);           // Insert checksum lsb
   tx_end=tx_ptr;             // Set end of buffer marker to end of packet
   tx_ptr = 0;                // Point to the beginning of the packet
}

// Test the option list in packet for valid passwords
//   option is the 16 bit field, where a high accepts the option one greater than the
//   bit #
//   returns 2 for LCP NAK, 1 is only correct fields found, and zero means bad options
//   return also modifies RX_STR to list unacceptable options if NAK or REJ required
unsigned char TestOptions(unsigned int option){
   unsigned int size;         // size is length of option string
   unsigned ptr1 = 8,         // ptr1 points data insert location
            ptr2 = 8;         // ptr2 points to data origin
   char pass = 3;             // pass is the return value
   size = rx_str[7]+4;        // size if length of packet
   if (size>MaxRx) size=MaxRx;     // truncate packet if larger than buffer
   while (ptr1<size) {        // scan options in receiver buffer
      if (rx_str[ptr1]==3 && rx_str[ptr1+2]!=0x80  && rx_str[2]==0xc2)
         pass&=0xfd;          // found a CHAP request, mark for NAK
      if (!((1<<(rx_str[ptr1]-1))&option))
         pass=0;              // found illegal options, mark for REJ
      ptr1 += rx_str[ptr1+1]; // point to start of next option
   }
   if (!(pass&2)) {           // If marked for NAK or REJ
      if (pass&1) {           // save state for NAK
         option=0xfffb;
      }
      for (ptr1=8; ptr1<size;) {
         if (!((1<<(rx_str[ptr1]-1))&option)) {   // if illegal option
            for (pass=rx_str[ptr1+1]; ptr1<size && pass; ptr1++) {  // move option
               rx_str[ptr2]=rx_str[ptr1];         // move current byte to new storage
               ptr2++;                            // increment storage pointer
               pass--;                            // decrement number of characters
            }
         } else {
            ptr1+=rx_str[ptr1+1];                 // point to next option
         }
      }
      rx_str[7] = ptr2-4;                         // save new option string length
      pass=0;                                     // restore state for REJ
      if (option==0xfffb) pass=1;                 // restore state for NAK
   }
   return pass;
}

// Send a string and loop until wait string arrives or it times out
//  send is the string to transmit
//  wait is the string to wait for
//  timeout is in multiples of 10 milliseconds

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -