📄 w5300.c
字号:
* \return 1 - success \n
* 2 - ID or password error \n
* 3 - Timeout occurs while processing PPPoE \n
* 4 - Not support authentication type.
*/
uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
{
uint8 loop_idx = 0;
uint8 isr = 0;
uint8 buf[PPP_OPTION_BUF_LEN];
uint32 len;
uint8 str[PPP_OPTION_BUF_LEN];
uint8 str_idx,dst_idx;
/////////////////////////////
// PHASE1. PPPoE Discovery //
/////////////////////////////
// start to connect pppoe connection
printf("-- PHASE 1. PPPoE Discovery process --");
printf(" ok\r\n");
printf("\r\n");
setSn_CR(0,Sn_CR_PCON);
wait_10ms(100);
// check if PPPoE discovery phase is success or not
loop_idx = 0;
while (!(getSn_IR(0) & Sn_IR_PNEXT))
{
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout before LCP\r\n");
return 3;
}
wait_10ms(100);
}
setSn_IR(0,Sn_IR_PNEXT);
/////////////////////////
// PHASE2. LCP process //
/////////////////////////
printf("-- PHASE 2. LCP process --");
{
// Magic number option
// option format (type value + length value + data)
// write magic number value
buf[0] = 0x05; // type value
buf[1] = 0x06; // length value
buf[2] = 0x01; buf[3] = 0x01; buf[4] = 0x01; buf[5]= 0x01; // data
// for MRU option, 1492 0x05d4
// buf[6] = 0x01; buf[7] = 0x04; buf[8] = 0x05; buf[9] = 0xD4;
}
wiz_write_buf(0,buf, 0x06);
setSn_TX_WRSR(0,0x06);
setSn_CR(0,Sn_CR_PCR); // send LCP request to PPPoE server
wait_10ms(100);
while (!((isr = getSn_IR(0)) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PRECV) // Not support option
{
len = getSn_RX_RSR(0);
if ( len > 2 )
{
wiz_read_buf(0,str, 2);
len = ((uint16)str[0] << 8) + str[1];
wiz_read_buf(0,(str+2), len);
setSn_CR(0,Sn_CR_RECV);
// get option length
len = (uint32)str[4]; len = ((len & 0xff) << 8) + (uint32)str[5];
len += 2;
str_idx = 6; dst_idx = 0; // PPP header is 6 byte, so starts at 6.
do
{
if ((str[str_idx] == 0x01) || (str[str_idx] == 0x02) || (str[str_idx] == 0x03) || (str[str_idx] == 0x05))
{
// skip as length of support option. str_idx+1 is option's length.
str_idx += str[str_idx+1];
}
else
{
// not support option , REJECT
memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
} while (str_idx != len);
// send LCP REJECT packet
wiz_write_buf(0,buf, dst_idx);
setSn_TX_WRSR(0,dst_idx);
setSn_CR(0,Sn_CR_PCJ);
setSn_IR(0,Sn_IR_PRECV);
}
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after LCP\r\n");
return 3;
}
wait_10ms(100);
}
setSn_IR(0,Sn_IR_PNEXT);
printf(" ok\r\n");
printf("\r\n");
///////////////////////////////////
// PHASE 3. PPPoE Authentication //
///////////////////////////////////
printf("-- PHASE 3. PPPoE Authentication mode --\r\n");
printf("Authentication protocol : %04x, ", getPATR());
loop_idx = 0;
if (getPATR() == 0xC023) // PAP type
{
printf("PAP\r\n"); // in case of adsl normally supports PAP.
// send authentication data
// copy (idlen + id + passwdlen + passwd)
buf[loop_idx] = idlen; loop_idx++;
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen;
buf[loop_idx] = passwdlen; loop_idx++;
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen;
wiz_write_buf(0,buf, loop_idx);
setSn_TX_WRSR(0,loop_idx);
setSn_CR(0,Sn_CR_PCR);
wait_10ms(100);
}
else if (getPATR() == 0xC223) // CHAP type
{
uint8 chal_len;
md5_ctx context;
uint8 digest[16];
len = getSn_RX_RSR(0);
if ( len > 2 )
{
wiz_read_buf(0,str,2);
len = ((uint32)str[0] << 8) + (uint32)str[1];
wiz_read_buf(0, str, len);
setSn_CR(0,Sn_CR_RECV);
#ifdef __DEF_IINCHIP_DBG__
{
int16 i;
printf("recv CHAP\r\n");
for (i = 0; i < 32; i++) printf ("%02X ", str[i]);
printf("\r\n");
}
#endif
// str is C2 23 xx CHAL_ID xx xx CHAP_LEN CHAP_DATA
// index 0 1 2 3 4 5 6 7 ...
memset(buf,0x00,64);
buf[loop_idx] = str[3]; loop_idx++; // chal_id
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen; //passwd
chal_len = str[6]; // chal_id
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(str+7), chal_len); loop_idx += chal_len; //challenge
buf[loop_idx] = 0x80;
#ifdef __DEF_IINCHIP_DBG__
{
int16 i;
printf("CHAP proc d1\r\n");
for (i = 0; i < 64; i++) printf ("%02X ", buf[i]);
printf("\r\n");
}
#endif
md5_init(&context);
md5_update(&context, buf, loop_idx);
md5_final(digest, &context);
#ifdef __DEF_IINCHIP_DBG__
{
uint i;
printf("CHAP proc d1\r\n");
for (i = 0; i < 16; i++) printf ("%02X", digest[i]);
printf("\r\n");
}
#endif
loop_idx = 0;
buf[loop_idx] = 16; loop_idx++; // hash_len
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(digest), 16); loop_idx += 16; // hashed value
memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen; // id
wiz_write_buf(0,buf, loop_idx);
setSn_TX_WRSR(0,loop_idx);
setSn_CR(0,Sn_CR_PCR);
wait_10ms(100);
}
}
else
{
printf("Not support\r\n");
#ifdef __DEF_IINCHIP_DBG__
printf("Not support PPP Auth type: %.4x\r\n",getPATR());
#endif
return 4;
}
printf("\r\n");
printf("-- Waiting for PPPoE server's admission --");
loop_idx = 0;
while (!((isr = getSn_IR(0)) & Sn_IR_PNEXT))
{
if (isr & Sn_IR_PFAIL)
{
printf("failed\r\nReinput id, password..\r\n");
return 2;
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after PAP\r\n");
return 3;
}
wait_10ms(100);
}
setSn_IR(0,Sn_IR_PNEXT);
printf("ok\r\n");
printf("\r\n");
///////////////////////////
// PHASE 4. IPCP process //
///////////////////////////
printf("-- PHASE 4. IPCP process --");
// IP Address
buf[0] = 0x03; buf[1] = 0x06; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00;
wiz_write_buf(0,buf, 6);
setSn_TX_WRSR(0,6);
setSn_CR(0,Sn_CR_PCR);
wait_10ms(100);
loop_idx = 0;
while (1)
{
if (getSn_IR(0) & Sn_IR_PRECV)
{
len = getSn_RX_RSR(0);
if ( len > 2 )
{
wiz_read_buf(0,str,2);
len = ((uint32)str[0] << 8) + (uint32)str[1];
wiz_read_buf(0, str, len);
setSn_CR(0,Sn_CR_RECV);
str_idx = 6; dst_idx = 0;
if (str[2] == 0x03) // in case of NAK
{
do
{
if (str[str_idx] == 0x03) // request only ip information
{
memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
}
else
{
// skip byte
str_idx += str[str_idx+1];
}
// for debug
//printf("s: %d, d: %d, l: %d", str_idx, dst_idx, len);
} while (str_idx != len);
wiz_write_buf(0,buf, dst_idx);
setSn_TX_WRSR(0,dst_idx);
setSn_CR(0,Sn_CR_PCR); // send ipcp request
wait_10ms(100);
break;
}
}
setSn_IR(0,Sn_IR_PRECV);
}
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP\r\n");
return 3;
}
wait_10ms(100);
wiz_write_buf(0, buf, 6);
setSn_TX_WRSR(0,6);
setSn_CR(0,Sn_CR_PCR); //ipcp re-request
}
loop_idx = 0;
while (!(getSn_IR(0) & Sn_IR_PNEXT))
{
printf(".");
if (loop_idx++ == 10) // timeout
{
printf("timeout after IPCP NAK\r\n");
return 3;
}
wait_10ms(100);
setSn_CR(0,Sn_CR_PCR); // send ipcp request
}
setSn_IR(0,Sn_IR_PNEXT);
printf("ok\r\n");
printf("\r\n");
return 1;
// after this function, the pppoe server's mac address and pppoe session id is saved in PHAR and PSIDR repectly.
}
uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen)
{
uint8 ret;
uint8 isr;
// PHASE0. PPPoE setup
printf("-- PHASE 0. PPPoE setup process --\r\n");
printf("\r\n");
setMR(getMR()|MR_PPPoE); // set PPPoE mode and FIFO swap
setMR(getMR()|MR_FS); // If little-endian, set MR_FS. Otherwise, comment.
isr = getSn_IR(0);
setSn_IR(0,(uint16)isr); // clear the previous value of Sn_IR(0)
setPTIMER(200); // set LPC request time to 5 seconds
setPMAGICR(0x01); // set the magic number
setSn_MR(0, Sn_MR_PPPoE); // set Sn_MR(0) to PPPoE mode
setSn_CR(0,Sn_CR_OPEN); //open SOCKET0 with PPPoE mode
ret = pppinit_in(id, idlen, passwd, passwdlen); // process the PPPoE message
setSn_CR(0, Sn_CR_CLOSE); // close PPPoE SOCKET0
return ret;
}
void pppterm(uint8 *mac, uint16 sessionid)
{
uint8 isr;
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm()\r\n");
#endif
// set PPPoE mode
setMR(getMR() | MR_PPPoE);
// set pppoe server's mac address and session id
// must be setted these value.
setSn_DHAR(0, mac);
setSn_DPORTR(0,sessionid);
// clear the previous value of Sn_IR(0)
isr = getSn_IR(0);
setSn_IR(0,(uint16)isr);
//open SOCKET0 with PPPoE mode
setSn_MR(0, Sn_MR_PPPoE);
setSn_CR(0,Sn_CR_OPEN);
while(getSn_SSR(0) != SOCK_PPPoE)
// close PPPoE connection
setSn_CR(0,Sn_CR_PDISCON);
wait_10ms(100);
// close socket
setSn_CR(0,Sn_CR_CLOSE);
#ifdef __DEF_IINCHIP_DBG__
printf("pppterm() end ..\r\n");
#endif
}
#endif
void wait_1us(uint16 us)
{
uint16 i,j;
for(i = 0; i < us ; i++)
{
for(j = 0; j < 100; j++);
}
}
void wait_1ms(uint16 ms)
{
uint16 i;
for(i = 0; i < ms ; i++)
{
wait_1us(1000);
}
}
void wait_10ms(uint16 ms)
{
uint16 i;
for(i = 0; i < ms ; i++)
{
wait_1ms(10);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -