📄 ping.txt
字号:
///////////////////////////////////////////////////////////////////////////////////////
//
// PING.C version 1.10 July 29/99 (C)opyright by Microchip Technology Inc
//
///////////////////////////////////////////////////////////////////////////////////////
//
// 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
//
///////////////////////////////////////////////////////////////////////////////////////
// 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
#include <pic1663.h> // Defines specific to this processor
#define serial_init() RCSTA=0x90;TXSTA=0x24;SPBRG=103 // Set up serial port
#define serial_tx_ready() TXIF // Transmitter empty
#define serial_send(a) TXREG=a // Transmit char a
#define serial_rx_ready() RCIF // Receiver full
#define serial_get() RCREG // 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'
bank1 unsigned char tx_str[MaxRx+1]; // Transmitter buffer
bank1 unsigned char rx_str[MaxTx+1]; // Receiver buffer
// Process all the interupts in the PIC here
static void interrupt isr(void) {
if (T0IF) { // Timer overflow interrupt?
TMR0 = 100; // Set to overflow again in 10ms @ 4MHz
T0IF = 0; // Clear overflow interrupt flag
TIME++; // Increment 10 ms counter
}
}
// 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 code, 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(code); // 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
// addr1 is used to control the status LED, 0=off, 1=flash, 2=on
// returns 0 if timeout, returns 1 if wait string is matched
char sendwait(const char *send, const char *wait, unsigned int timeout) {
addr2=addr3=0;
for (TIME_SET(0); TIME<timeout; ) { // loop until time runs out
if (!addr1) PORTB&=0xFB; // if addr1=0 turn off status LED
else if (addr1==1) { // if addr1=1 flash status LED
if (TIME&4) PORTB&=0xFB; // flash period is 8 x 10ms
else PORTB|=4;
} else PORTB|=4; // if addr1>1 turn on status LED
if (serial_rx_ready()) { // is there an incoming character
PORTB|=1; // turn on the Rx LED
addr4 = serial_get(); // get character
if (serial_error()) serial_fix(); // clear serial errors
if (wait[addr2]==addr4) addr2++; // does char match wait string
else addr2=0; // otherwise reset match pointer
PORTB&=0xFE; // turn off the Rx LED
if (!wait[addr2]) return 1; // finished if string matches
} else if (send[addr3] && (serial_tx_ready())) { // if char to send and Tx ready
if (send[addr3]=='|') { // if pause character
if (TIME>100) { // has 1 second expired yet?
TIME_SET(0); // if yes clear timer
addr3++; // and point to next character
}
} else {
PORTB|=2; // turn on Tx LED
TIME_SET(0); // clear timer, timeout starts after last char
serial_send(send[addr3]); // send the character
addr3++; // point to next char in tx string
}
PORTB&=0xFD; // turn off Tx LED
if (!send[addr3] && !(*wait))
return 1; // done if end of string and no wait string
}
}
return 0; // return with 0 to indicate timeout
}
void flash(void) { // flash all LEDs if catastrophic failure
for (TIME_SET(0);;) {
if (TIME&8) PORTB|=0x07; // flash period is 16 x 10ms
else PORTB&=0xF8;
if (TIME>3000) PORTB&=0xF7; // after 30 seconds turn off the power
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -