统一以太网接口,2860和5500均升级,未测试

统一DHCP,简单测试,成功发出Request,收到Offer,但是程序未处理
This commit is contained in:
nnhy 2015-09-16 10:09:57 +00:00
parent 97c560deae
commit e772547197
23 changed files with 170 additions and 819 deletions

View File

@ -1020,7 +1020,8 @@ void HardSocket::OnClose()
Remote.Show(true); Remote.Show(true);
} }
int HardSocket::ReadByteArray(ByteArray& bs) // 接收数据
uint HardSocket::Receive(ByteArray& bs)
{ {
// 读取收到数据容量 // 读取收到数据容量
ushort size = __REV16(SocRegRead2(RX_RSR)); ushort size = __REV16(SocRegRead2(RX_RSR));
@ -1049,7 +1050,8 @@ int HardSocket::ReadByteArray(ByteArray& bs)
return size; return size;
} }
bool HardSocket::WriteByteArray(const ByteArray& bs) // 发送数据
bool HardSocket::Send(const ByteArray& bs)
{ {
// 读取状态 // 读取状态
byte st = ReadStatus(); byte st = ReadStatus();
@ -1075,7 +1077,7 @@ bool HardSocket::WriteByteArray(const ByteArray& bs)
bool HardSocket::OnWrite(const byte* buf, uint len) bool HardSocket::OnWrite(const byte* buf, uint len)
{ {
ByteArray bs(buf,len); ByteArray bs(buf,len);
return WriteByteArray(bs); return Send(bs);
} }
uint HardSocket::OnRead(byte* buf, uint len) uint HardSocket::OnRead(byte* buf, uint len)
@ -1083,7 +1085,7 @@ uint HardSocket::OnRead(byte* buf, uint len)
ByteArray bs(buf, len); ByteArray bs(buf, len);
// 不容 ByteArray 偷梁换柱把buf换掉 // 不容 ByteArray 偷梁换柱把buf换掉
return ReadByteArray(bs); return Receive(bs);
} }
void HardSocket::ClearRX() void HardSocket::ClearRX()
@ -1120,7 +1122,7 @@ void HardSocket::ReceiveTask(void* param)
assert_ptr(param); assert_ptr(param);
HardSocket* socket = (HardSocket*)param; HardSocket* socket = (HardSocket*)param;
socket->Receive(); socket->RaiseReceive();
} }
void HardSocket::Register(TransportHandler handler, void* param) void HardSocket::Register(TransportHandler handler, void* param)
@ -1239,7 +1241,7 @@ void TcpClient::OnProcess(byte reg)
else else
{ {
ByteArray bs; ByteArray bs;
int size = ReadByteArray(bs); int size = Receive(bs);
debug_printf("收到数据:"); debug_printf("收到数据:");
bs.Show(); bs.Show();
debug_printf("\r\n"); debug_printf("\r\n");
@ -1274,10 +1276,10 @@ void TcpClient::OnProcess(byte reg)
} }
// 异步中断 // 异步中断
void TcpClient::Receive() void TcpClient::RaiseReceive()
{ {
ByteArray bs; ByteArray bs;
int size = ReadByteArray(bs); int size = Receive(bs);
if(size > 1500)return; if(size > 1500)return;
// 回调中断 // 回调中断
@ -1308,7 +1310,7 @@ void UdpClient::OnProcess(byte reg)
else else
{ {
ByteArray bs; ByteArray bs;
int size = ReadByteArray(bs); int size = Receive(bs);
debug_printf("收到数据:"); debug_printf("收到数据:");
bs.Show(); bs.Show();
debug_printf("\r\n"); debug_printf("\r\n");
@ -1320,13 +1322,13 @@ void UdpClient::OnProcess(byte reg)
// UDP 异步只有一种情况 收到数据 可能有多个数据包 // UDP 异步只有一种情况 收到数据 可能有多个数据包
// UDP接收到的数据结构 RemoteIP(4 byte) + RemotePort(2 byte) + Length(2 byte) + Data(Length byte) // UDP接收到的数据结构 RemoteIP(4 byte) + RemotePort(2 byte) + Length(2 byte) + Data(Length byte)
void UdpClient::Receive() void UdpClient::RaiseReceive()
{ {
// UDP 异步只有一种情况 收到数据 可能有多个数据包 // UDP 异步只有一种情况 收到数据 可能有多个数据包
// UDP接收到的数据结构 RemoteIP(4 byte) + RemotePort(2 byte) + Length(2 byte) + Data(Length byte) // UDP接收到的数据结构 RemoteIP(4 byte) + RemotePort(2 byte) + Length(2 byte) + Data(Length byte)
byte buf[1024]; byte buf[1024];
ByteArray bs(buf, ArrayLength(buf)); ByteArray bs(buf, ArrayLength(buf));
ushort size = ReadByteArray(bs); ushort size = Receive(bs);
Stream ms(bs.GetBuffer(), size); Stream ms(bs.GetBuffer(), size);
// 拆包 // 拆包
@ -1358,7 +1360,7 @@ void UdpClient::Receive()
// { // {
// // 读取包头 // // 读取包头
// ByteArray bsHead(packetHead, ArrayLength(packetHead)); // ByteArray bsHead(packetHead, ArrayLength(packetHead));
// ushort size = ReadByteArray(bsHead, true); // ushort size = Receive(bsHead, true);
// if(size == ArrayLength(packetHead)) // if(size == ArrayLength(packetHead))
// { // {
// // 解析头 // // 解析头
@ -1405,7 +1407,7 @@ void UdpClient::Receive()
// if(RemainLength < DataLength) return; // if(RemainLength < DataLength) return;
// // 读取数据 // // 读取数据
// ByteArray bsData(dataBuf, DataLength); // ByteArray bsData(dataBuf, DataLength);
// ushort datasize = ReadByteArray(bsData, true); // ushort datasize = Receive(bsData, true);
// //
// // debug_printf("Data: "); // // debug_printf("Data: ");
// // bsData.Show(); // // bsData.Show();

View File

@ -11,7 +11,7 @@
class HardSocket; class HardSocket;
// W5500以太网驱动 // W5500以太网驱动
class W5500 class W5500 : public ISocketHost
{ {
private: private:
friend class HardSocket; friend class HardSocket;
@ -48,14 +48,6 @@ public:
bool Opened; // 是否已经打开 bool Opened; // 是否已经打开
IPAddress IP; // 本地IP地址
IPAddress Mask; // 子网掩码
MacAddress Mac; // 本地Mac地址
IPAddress DHCPServer;
IPAddress DNSServer;
IPAddress Gateway;
// 构造 // 构造
W5500(); W5500();
W5500(Spi* spi, Pin irq = P0 ,Pin rst = P0); // 必须具备复位引脚 否则寄存器不能读 W5500(Spi* spi, Pin irq = P0 ,Pin rst = P0); // 必须具备复位引脚 否则寄存器不能读
@ -114,9 +106,6 @@ public:
W5500* Host; // W5500公共部分控制器 W5500* Host; // W5500公共部分控制器
uint _tidRecv; // 收数据线程 uint _tidRecv; // 收数据线程
//IPEndPoint Remote; // 远程地址。默认发送数据的目标地址
//IPEndPoint Local; // 本地地址
HardSocket(W5500* host, byte protocol); HardSocket(W5500* host, byte protocol);
virtual ~HardSocket(); virtual ~HardSocket();
@ -127,12 +116,14 @@ public:
virtual bool OnOpen(); virtual bool OnOpen();
virtual void OnClose(); virtual void OnClose();
bool WriteByteArray(const ByteArray& bs);
int ReadByteArray(ByteArray& bs);
virtual bool OnWrite(const byte* buf, uint len); virtual bool OnWrite(const byte* buf, uint len);
virtual uint OnRead(byte* buf, uint len); virtual uint OnRead(byte* buf, uint len);
// 发送数据
virtual bool Send(const ByteArray& bs);
// 接收数据
virtual uint Receive(ByteArray& bs);
static void ReceiveTask(void* param); static void ReceiveTask(void* param);
virtual void Register(TransportHandler handler, void* param); virtual void Register(TransportHandler handler, void* param);
@ -142,7 +133,7 @@ public:
void Process(); void Process();
virtual void OnProcess(byte reg) = 0; virtual void OnProcess(byte reg) = 0;
// 用户注册的中断事件处理 异步调用 // 用户注册的中断事件处理 异步调用
virtual void Receive() = 0; virtual void RaiseReceive() = 0;
// 清空所有接收缓冲区 // 清空所有接收缓冲区
void ClearRX(); void ClearRX();
}; };
@ -163,7 +154,7 @@ public:
// 中断分发 维护状态 // 中断分发 维护状态
virtual void OnProcess(byte reg); virtual void OnProcess(byte reg);
// 用户注册的中断事件处理 异步调用 // 用户注册的中断事件处理 异步调用
virtual void Receive(); virtual void RaiseReceive();
private: private:
bool Linked; bool Linked;
@ -180,7 +171,7 @@ public:
// 中断分发 维护状态 // 中断分发 维护状态
virtual void OnProcess(byte reg); virtual void OnProcess(byte reg);
// 用户注册的中断事件处理 异步调用 // 用户注册的中断事件处理 异步调用
virtual void Receive(); virtual void RaiseReceive();
private: private:
// 数据包头和数据分开读取 // 数据包头和数据分开读取

View File

@ -1,20 +1,25 @@
#include "Time.h" #include "Time.h"
#include "Stream.h"
#include "ITransport.h"
#include "Dhcp.h" #include "Dhcp.h"
#define NET_DEBUG DEBUG #define NET_DEBUG DEBUG
Dhcp::Dhcp(TinyIP* tip) : UdpSocket(tip) Dhcp::Dhcp(ISocket* socket)
{ {
Type = IP_UDP; Socket = socket;
Local.Port = 68; Host = socket->Host;
Remote.Port = 67;
Remote.Address = IPAddress::Broadcast();
Running = false; socket->Local.Port = 68;
Result = false; socket->Remote.Port = 67;
ExpiredTime = 10; socket->Remote.Address = IPAddress::Broadcast();
OnStop = NULL; Running = false;
Result = false;
ExpiredTime = 10;
OnStop = NULL;
} }
void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len) void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
@ -24,9 +29,9 @@ void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
{ {
// 此时指向的是负载数据后的第一个字节所以第一个opt不许Next // 此时指向的是负载数据后的第一个字节所以第一个opt不许Next
DHCP_OPT* opt = (DHCP_OPT*)(p + len); DHCP_OPT* opt = (DHCP_OPT*)(p + len);
opt = opt->SetClientId(Tip->Mac); opt = opt->SetClientId(Host->Mac);
if(!Tip->IP.IsAny()) if(!Host->IP.IsAny())
opt = opt->Next()->SetData(DHCP_OPT_RequestedIP, Tip->IP.Value); opt = opt->Next()->SetData(DHCP_OPT_RequestedIP, Host->IP.Value);
// 构造产品名称把ID第一个字节附到最后 // 构造产品名称把ID第一个字节附到最后
String name; String name;
@ -44,13 +49,12 @@ void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
len = (byte*)opt + 1 - p; len = (byte*)opt + 1 - p;
} }
//memcpy(dhcp->ClientMac, (byte*)&Tip->Mac.Value, 6);
for(int i=0; i<6; i++) for(int i=0; i<6; i++)
dhcp.ClientMac[i] = Tip->Mac[i]; dhcp.ClientMac[i] = Host->Mac[i];
//RemoteIP = IPAddress::Broadcast; //Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, Remote.Address, Remote.Port, false);
ByteArray bs((byte*)&dhcp, sizeof(DHCP_HEADER) + len);
Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, Remote.Address, Remote.Port, false); Socket->Send(bs);
} }
// 获取选项,返回数据部分指针 // 获取选项,返回数据部分指针
@ -86,7 +90,7 @@ void Dhcp::Request(DHCP_HEADER& dhcp)
DHCP_OPT* opt = (DHCP_OPT*)p; DHCP_OPT* opt = (DHCP_OPT*)p;
opt->SetType(DHCP_TYPE_Request); opt->SetType(DHCP_TYPE_Request);
opt = opt->Next()->SetData(DHCP_OPT_DHCPServer, Tip->DHCPServer.Value); opt = opt->Next()->SetData(DHCP_OPT_DHCPServer, Host->DHCPServer.Value);
// 发往DHCP服务器 // 发往DHCP服务器
SendDhcp(dhcp, (byte*)opt->Next() - p); SendDhcp(dhcp, (byte*)opt->Next() - p);
@ -102,10 +106,10 @@ void Dhcp::PareOption(Stream& ms)
// 有些家用路由器会发送错误的len大于4字节导致覆盖前后数据 // 有些家用路由器会发送错误的len大于4字节导致覆盖前后数据
switch(opt) switch(opt)
{ {
case DHCP_OPT_Mask: Tip->Mask = ms.Read<int>(); len -= 4; break; case DHCP_OPT_Mask: Host->Mask = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DNSServer: Tip->DNSServer = ms.Read<int>(); len -= 4; break; case DHCP_OPT_DNSServer: Host->DNSServer = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_Router: Tip->Gateway = ms.Read<int>(); len -= 4; break; case DHCP_OPT_Router: Host->Gateway = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DHCPServer: Tip->DHCPServer = ms.Read<int>(); len -= 4; break; case DHCP_OPT_DHCPServer: Host->DHCPServer = ms.Read<int>(); len -= 4; break;
//default: //default:
// debug_printf("Unkown DHCP Option=%d Length=%d\r\n", opt, len); // debug_printf("Unkown DHCP Option=%d Length=%d\r\n", opt, len);
} }
@ -116,13 +120,11 @@ void Dhcp::PareOption(Stream& ms)
void RenewDHCP(void* param) void RenewDHCP(void* param)
{ {
TinyIP* tip = (TinyIP*)param; ISocket* socket = (ISocket*)param;
if(tip) if(socket)
{ {
/*Dhcp dhcp(tip);
dhcp.Start();*/
// 不能使用栈分配,因为是异步操作 // 不能使用栈分配,因为是异步操作
Dhcp* dhcp = new Dhcp(tip); Dhcp* dhcp = new Dhcp(socket);
dhcp->Start(); dhcp->Start();
} }
} }
@ -135,38 +137,25 @@ void Dhcp::Start()
debug_printf("Dhcp::Start ExpiredTime=%ds DhcpID=0x%08x\r\n", ExpiredTime, dhcpid); debug_printf("Dhcp::Start ExpiredTime=%ds DhcpID=0x%08x\r\n", ExpiredTime, dhcpid);
// 创建任务每秒发送一次Discover // 创建任务每秒发送一次Discover
//debug_printf("Dhcp发送Discover ");
taskID = Sys.AddTask(SendDiscover, this, 0, 1000000, "DHCP"); taskID = Sys.AddTask(SendDiscover, this, 0, 1000000, "DHCP");
// 通过DHCP获取IP期间关闭Arp响应
//Tip->EnableArp = false;
if(Tip->Arp) Tip->Arp->Enable = false;
Running = true; Running = true;
Open(); ITransport* port = dynamic_cast<ITransport*>(Socket);
if(port) port->Open();
} }
void Dhcp::Stop() void Dhcp::Stop()
{ {
Close(); ITransport* port = dynamic_cast<ITransport*>(Socket);
if(port) port->Close();
Running = false; Running = false;
if(taskID) Sys.RemoveTask(taskID);
{ taskID = 0;
debug_printf("Dhcp发送Discover ");
Sys.RemoveTask(taskID);
}
taskID = 0;
// 通过DHCP获取IP期间关闭Arp响应
//Tip->EnableArp = true;
if(Tip->Arp) Tip->Arp->Enable = true;
debug_printf("Dhcp::Stop Result=%d DhcpID=0x%08x\r\n", Result, dhcpid); debug_printf("Dhcp::Stop Result=%d DhcpID=0x%08x\r\n", Result, dhcpid);
if(Result) Tip->ShowInfo();
if(OnStop) OnStop(this, NULL); if(OnStop) OnStop(this, NULL);
// 销毁自己 // 销毁自己
@ -213,10 +202,10 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
if(__REV(dhcp->TransID) != dhcpid) return; if(__REV(dhcp->TransID) != dhcpid) return;
IPAddress remote = ip.SrcIP; IPAddress remote = ip.SrcIP;
if(opt->Data == DHCP_TYPE_Offer) if(opt->Data == DHCP_TYPE_Offer)
{ {
Tip->IP = dhcp->YourIP; Host->IP = dhcp->YourIP;
Stream optData(dhcp->Next(), len); Stream optData(dhcp->Next(), len);
PareOption(optData); PareOption(optData);
@ -224,7 +213,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
// 这里其实还应该发送ARP包确认IP是否被占用如果被占用还需要拒绝服务器提供的IP比较复杂可能性很低暂时不考虑 // 这里其实还应该发送ARP包确认IP是否被占用如果被占用还需要拒绝服务器提供的IP比较复杂可能性很低暂时不考虑
#if NET_DEBUG #if NET_DEBUG
debug_printf("DHCP::Offer IP:"); debug_printf("DHCP::Offer IP:");
Tip->IP.Show(); Host->IP.Show();
debug_printf(" From "); debug_printf(" From ");
remote.Show(); remote.Show();
debug_printf("\r\n"); debug_printf("\r\n");
@ -242,7 +231,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
} }
else if(opt->Data == DHCP_TYPE_Ack) else if(opt->Data == DHCP_TYPE_Ack)
{ {
Tip->IP = dhcp->YourIP; Host->IP = dhcp->YourIP;
#if NET_DEBUG #if NET_DEBUG
debug_printf("DHCP::Ack IP:"); debug_printf("DHCP::Ack IP:");
IPAddress(dhcp->YourIP).Show(); IPAddress(dhcp->YourIP).Show();
@ -251,7 +240,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
debug_printf("\r\n"); debug_printf("\r\n");
#endif #endif
//if(dhcp->YourIP == Tip->IP) //if(dhcp->YourIP == Host->IP)
{ {
// 查找租约时间,提前续约 // 查找租约时间,提前续约
opt = GetOption(data, len, DHCP_OPT_IPLeaseTime); opt = GetOption(data, len, DHCP_OPT_IPLeaseTime);
@ -266,7 +255,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
if(time > 0) if(time > 0)
{ {
//debug_printf("Dhcp过期获取 "); //debug_printf("Dhcp过期获取 ");
Sys.AddTask(RenewDHCP, Tip, (ulong)time / 2 * 1000000, -1, "DHCP超时"); Sys.AddTask(RenewDHCP, Socket, (ulong)time / 2 * 1000000, -1, "DHCP超时");
} }
} }
@ -282,7 +271,7 @@ void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
// 导致Nak的原因 // 导致Nak的原因
opt = GetOption(data, len, DHCP_OPT_Message); opt = GetOption(data, len, DHCP_OPT_Message);
debug_printf("DHCP::Nak IP:"); debug_printf("DHCP::Nak IP:");
Tip->IP.Show(); Host->IP.Show();
debug_printf(" From "); debug_printf(" From ");
remote.Show(); remote.Show();
if(opt) if(opt)

View File

@ -1,10 +1,11 @@
#ifndef _TinyIP_DHCP_H_ #ifndef _TinyIP_DHCP_H_
#define _TinyIP_DHCP_H_ #define _TinyIP_DHCP_H_
#include "Udp.h" #include "Net.h"
#include "Ethernet.h"
// DHCP协议 // DHCP协议
class Dhcp : public UdpSocket class Dhcp
{ {
private: private:
uint dhcpid; uint dhcpid;
@ -20,11 +21,14 @@ private:
static void SendDiscover(void* param); static void SendDiscover(void* param);
public: public:
ISocket* Socket;
ISocketHost* Host; // 主机
bool Running; // 正在运行 bool Running; // 正在运行
bool Result; // 是否获取IP成功 bool Result; // 是否获取IP成功
uint ExpiredTime; // 过期时间 uint ExpiredTime; // 过期时间
Dhcp(TinyIP* tip); Dhcp(ISocket* socket);
void Start(); // 开始 void Start(); // 开始
void Stop(); // 停止 void Stop(); // 停止

View File

@ -98,13 +98,33 @@ public:
static const MacAddress& Full(); static const MacAddress& Full();
}; };
// Socket主机
class ISocketHost
{
public:
IPAddress IP; // 本地IP地址
IPAddress Mask; // 子网掩码
MacAddress Mac; // 本地Mac地址
IPAddress DHCPServer;
IPAddress DNSServer;
IPAddress Gateway;
};
// Socket接口 // Socket接口
class ISocket class ISocket
{ {
public: public:
ISocketHost* Host; // 主机
//ushort Port; // 本地端口。用于过滤数据默认0表示接收所有端口的数据 //ushort Port; // 本地端口。用于过滤数据默认0表示接收所有端口的数据
IPEndPoint Local; // 本地地址。包含本地局域网IP地址实际监听的端口从1024开始累加 IPEndPoint Local; // 本地地址。包含本地局域网IP地址实际监听的端口从1024开始累加
IPEndPoint Remote; // 远程地址 IPEndPoint Remote; // 远程地址
// 发送数据
virtual bool Send(const ByteArray& bs) = 0;
// 接收数据
virtual uint Receive(ByteArray& bs) = 0;
}; };
#endif #endif

View File

@ -19,7 +19,7 @@ public:
ArpSession* _ArpSession; ArpSession* _ArpSession;
ArpSocket::ArpSocket(TinyIP* tip) : Socket(tip, IP_NONE) ArpSocket::ArpSocket(TinyIP* tip) : TinySocket(tip, IP_NONE)
{ {
//Type = IP_NONE; //Type = IP_NONE;

View File

@ -4,7 +4,7 @@
#include "TinyIP.h" #include "TinyIP.h"
// ARP协议 // ARP协议
class ArpSocket : public Socket class ArpSocket : public TinySocket
{ {
private: private:
// ARP表 // ARP表

View File

@ -33,7 +33,7 @@ public:
// 用于等待Ping响应的会话 // 用于等待Ping响应的会话
PingSession* _IcmpSession = NULL; PingSession* _IcmpSession = NULL;
IcmpSocket::IcmpSocket(TinyIP* tip) : Socket(tip, IP_ICMP) IcmpSocket::IcmpSocket(TinyIP* tip) : TinySocket(tip, IP_ICMP)
{ {
//Type = IP_ICMP; //Type = IP_ICMP;

View File

@ -7,7 +7,7 @@
#include "TinyIP.h" #include "TinyIP.h"
// ICMP协议 // ICMP协议
class IcmpSocket : public Socket class IcmpSocket : public TinySocket
{ {
public: public:
IcmpSocket(TinyIP* tip); IcmpSocket(TinyIP* tip);

View File

@ -8,7 +8,7 @@ bool* WaitAck;
bool Callback(TinyIP* tip, void* param, Stream& ms); bool Callback(TinyIP* tip, void* param, Stream& ms);
TcpSocket::TcpSocket(TinyIP* tip) : Socket(tip, IP_TCP) TcpSocket::TcpSocket(TinyIP* tip) : TinySocket(tip, IP_TCP)
{ {
//Port = 0; //Port = 0;
@ -150,9 +150,9 @@ void TcpSocket::OnAccept(TCP_HEADER& tcp, uint len)
SetMss(tcp); SetMss(tcp);
// 需要用到MSS所以采用4个字节的可选段 // 需要用到MSS所以采用4个字节的可选段
//Send(tcp, 4, TCP_FLAGS_SYN | TCP_FLAGS_ACK); //SendPacket(tcp, 4, TCP_FLAGS_SYN | TCP_FLAGS_ACK);
// 注意tcp->Size()包括头部的扩展数据这里不用单独填4 // 注意tcp->Size()包括头部的扩展数据这里不用单独填4
Send(tcp, 0, TCP_FLAGS_SYN | TCP_FLAGS_ACK); SendPacket(tcp, 0, TCP_FLAGS_SYN | TCP_FLAGS_ACK);
} }
// 客户端收到握手三也是首次收到来自服务端的数据或者0数据的ACK // 客户端收到握手三也是首次收到来自服务端的数据或者0数据的ACK
@ -176,7 +176,7 @@ void TcpSocket::OnAccept3(TCP_HEADER& tcp, uint len)
// 不需要Mss // 不需要Mss
tcp.Length = sizeof(TCP_HEADER) / 4; tcp.Length = sizeof(TCP_HEADER) / 4;
Send(tcp, 0, TCP_FLAGS_ACK); SendPacket(tcp, 0, TCP_FLAGS_ACK);
} }
void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len) void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
@ -187,7 +187,7 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
if (tcp.Flags & (TCP_FLAGS_FIN | TCP_FLAGS_RST)) //FIN结束连接请求标志位。为1表示是结束连接的请求数据包 if (tcp.Flags & (TCP_FLAGS_FIN | TCP_FLAGS_RST)) //FIN结束连接请求标志位。为1表示是结束连接的请求数据包
{ {
SetSeqAck(tcp, 1, true); SetSeqAck(tcp, 1, true);
Send(tcp, 0, TCP_FLAGS_ACK); SendPacket(tcp, 0, TCP_FLAGS_ACK);
} }
else else
{ {
@ -211,7 +211,7 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
SetSeqAck(tcp, len, true); SetSeqAck(tcp, len, true);
// 响应Ack和发送数据一步到位 // 响应Ack和发送数据一步到位
Send(tcp, len2, TCP_FLAGS_ACK | TCP_FLAGS_PUSH); SendPacket(tcp, len2, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
} }
if(OnReceived) if(OnReceived)
@ -223,7 +223,7 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
{ {
// 发送ACK通知已收到 // 发送ACK通知已收到
SetSeqAck(tcp, len, true); SetSeqAck(tcp, len, true);
Send(tcp, 0, TCP_FLAGS_ACK); SendPacket(tcp, 0, TCP_FLAGS_ACK);
return; return;
} }
} }
@ -239,10 +239,10 @@ void TcpSocket::OnDataReceive(TCP_HEADER& tcp, uint len)
} }
// 发送ACK通知已收到 // 发送ACK通知已收到
SetSeqAck(tcp, len, true); SetSeqAck(tcp, len, true);
Send(tcp, 0, TCP_FLAGS_ACK); SendPacket(tcp, 0, TCP_FLAGS_ACK);
// 响应Ack和发送数据一步到位 // 响应Ack和发送数据一步到位
//Send(tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH); //SendPacket(tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
} }
void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len) void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len)
@ -256,7 +256,7 @@ void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len)
{ {
SetSeqAck(tcp, 1, true); SetSeqAck(tcp, 1, true);
//Close(tcp, 0); //Close(tcp, 0);
Send(tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN); SendPacket(tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN);
} }
else if(!OnDisconnected) else if(!OnDisconnected)
{ {
@ -271,7 +271,7 @@ void TcpSocket::OnDisconnect(TCP_HEADER& tcp, uint len)
Status = Closed; Status = Closed;
} }
bool TcpSocket::Send(TCP_HEADER& tcp, uint len, byte flags) bool TcpSocket::SendPacket(TCP_HEADER& tcp, uint len, byte flags)
{ {
tcp.SrcPort = __REV16(Local.Port); tcp.SrcPort = __REV16(Local.Port);
tcp.DestPort = __REV16(Remote.Port); tcp.DestPort = __REV16(Remote.Port);
@ -344,7 +344,7 @@ void TcpSocket::SendAck(uint len)
TCP_HEADER* tcp = ms.Retrieve<TCP_HEADER>(); TCP_HEADER* tcp = ms.Retrieve<TCP_HEADER>();
tcp->Init(true); tcp->Init(true);
Send(*tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH); SendPacket(*tcp, len, TCP_FLAGS_ACK | TCP_FLAGS_PUSH);
} }
bool TcpSocket::Disconnect() bool TcpSocket::Disconnect()
@ -358,10 +358,10 @@ bool TcpSocket::Disconnect()
TCP_HEADER* tcp = ms.Retrieve<TCP_HEADER>(); TCP_HEADER* tcp = ms.Retrieve<TCP_HEADER>();
tcp->Init(true); tcp->Init(true);
return Send(*tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN); return SendPacket(*tcp, 0, TCP_FLAGS_ACK | TCP_FLAGS_PUSH | TCP_FLAGS_FIN);
} }
bool TcpSocket::Send(ByteArray& bs) bool TcpSocket::Send(const ByteArray& bs)
{ {
if(!Enable) if(!Enable)
{ {
@ -396,7 +396,7 @@ bool TcpSocket::Send(ByteArray& bs)
tcp->Ack = __REV(Ack); tcp->Ack = __REV(Ack);
// 发送数据的时候需要同时带PUSH和ACK // 发送数据的时候需要同时带PUSH和ACK
//debug_printf("Seq=0x%04x Ack=0x%04x \r\n", Seq, Ack); //debug_printf("Seq=0x%04x Ack=0x%04x \r\n", Seq, Ack);
if(!Send(*tcp, bs.Length(), TCP_FLAGS_PUSH | TCP_FLAGS_ACK)) return false; if(!SendPacket(*tcp, bs.Length(), TCP_FLAGS_PUSH | TCP_FLAGS_ACK)) return false;
bool wait = false; bool wait = false;
WaitAck = &wait; WaitAck = &wait;
@ -420,6 +420,11 @@ bool TcpSocket::Send(ByteArray& bs)
return wait; return wait;
} }
uint TcpSocket::Receive(ByteArray& bs)
{
return 0;
}
// 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要 // 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool TcpSocket::Connect(IPAddress& ip, ushort port) bool TcpSocket::Connect(IPAddress& ip, ushort port)
{ {
@ -451,7 +456,7 @@ bool TcpSocket::Connect(IPAddress& ip, ushort port)
SetMss(*tcp); SetMss(*tcp);
Status = SynSent; Status = SynSent;
if(!Send(*tcp, 0, TCP_FLAGS_SYN)) if(!SendPacket(*tcp, 0, TCP_FLAGS_SYN))
{ {
Status = Closed; Status = Closed;
return false; return false;

View File

@ -4,12 +4,12 @@
#include "TinyIP.h" #include "TinyIP.h"
// Tcp会话 // Tcp会话
class TcpSocket : public Socket, public ITransport, public ISocket class TcpSocket : public TinySocket, public ITransport, public ISocket
{ {
private: private:
uint Seq; // 序列号,本地发出数据包 uint Seq; // 序列号,本地发出数据包
uint Ack; // 确认号,对方发送数据包的序列号+1 uint Ack; // 确认号,对方发送数据包的序列号+1
public: public:
// Tcp状态 // Tcp状态
typedef enum typedef enum
@ -34,10 +34,15 @@ public:
// 处理数据包 // 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms); virtual bool Process(IP_HEADER& ip, Stream& ms);
bool Connect(IPAddress& ip, ushort port); // 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要 // 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool Send(ByteArray& bs); // 向Socket发送数据可能是外部数据包 bool Connect(IPAddress& ip, ushort port);
bool Disconnect(); // 关闭Socket bool Disconnect(); // 关闭Socket
// 发送数据
virtual bool Send(const ByteArray& bs);
// 接收数据
virtual uint Receive(ByteArray& bs);
// 收到Tcp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包 // 收到Tcp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*TcpHandler)(TcpSocket& socket, TCP_HEADER& tcp, byte* buf, uint len); typedef bool (*TcpHandler)(TcpSocket& socket, TCP_HEADER& tcp, byte* buf, uint len);
TcpHandler OnAccepted; TcpHandler OnAccepted;
@ -51,7 +56,7 @@ protected:
void SetSeqAck(TCP_HEADER& tcp, uint ackNum, bool cp_seq); void SetSeqAck(TCP_HEADER& tcp, uint ackNum, bool cp_seq);
void SetMss(TCP_HEADER& tcp); void SetMss(TCP_HEADER& tcp);
bool Send(TCP_HEADER& tcp, uint len, byte flags); bool SendPacket(TCP_HEADER& tcp, uint len, byte flags);
virtual void OnProcess(TCP_HEADER& tcp, Stream& ms); virtual void OnProcess(TCP_HEADER& tcp, Stream& ms);
virtual void OnAccept(TCP_HEADER& tcp, uint len); virtual void OnAccept(TCP_HEADER& tcp, uint len);

View File

@ -165,7 +165,7 @@ void TinyIP::Process(Stream& ms)
uint count = Sockets.Count(); uint count = Sockets.Count();
for(int i=count-1; i>=0; i--) for(int i=count-1; i>=0; i--)
{ {
Socket* socket = Sockets[i]; TinySocket* socket = Sockets[i];
if(socket && socket->Enable) if(socket && socket->Enable)
{ {
// 必须类型匹配 // 必须类型匹配
@ -407,7 +407,7 @@ bool TinyIP::IsBroadcast(const IPAddress& ip)
} }
#endif #endif
Socket::Socket(TinyIP* tip, IP_TYPE type) TinySocket::TinySocket(TinyIP* tip, IP_TYPE type)
{ {
assert_param2(tip, "空的Tip"); assert_param2(tip, "空的Tip");
@ -419,7 +419,7 @@ Socket::Socket(TinyIP* tip, IP_TYPE type)
if(type != IP_NONE) tip->Sockets.Add(this); if(type != IP_NONE) tip->Sockets.Add(this);
} }
Socket::~Socket() TinySocket::~TinySocket()
{ {
assert_param2(Tip, "空的Tip"); assert_param2(Tip, "空的Tip");
@ -428,12 +428,12 @@ Socket::~Socket()
Tip->Sockets.Remove(this); Tip->Sockets.Remove(this);
} }
Socket* SocketList::FindByType(ushort type) TinySocket* SocketList::FindByType(ushort type)
{ {
uint count = Count(); uint count = Count();
for(int i=count-1; i>=0; i--) for(int i=count-1; i>=0; i--)
{ {
Socket* socket = (*this)[i]; TinySocket* socket = (*this)[i];
if(socket) if(socket)
{ {
// 必须类型匹配 // 必须类型匹配

View File

@ -13,25 +13,25 @@
class TinyIP; class TinyIP;
// 网络数据处理Socket基类 // 网络数据处理Socket基类
class Socket class TinySocket
{ {
public: public:
TinyIP* Tip; // TinyIP控制器 TinyIP* Tip; // TinyIP控制器
IP_TYPE Type; // 类型 IP_TYPE Type; // 类型
bool Enable; // 启用 bool Enable; // 启用
Socket(TinyIP* tip, IP_TYPE type); TinySocket(TinyIP* tip, IP_TYPE type);
virtual ~Socket(); virtual ~TinySocket();
// 处理数据包 // 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms) = 0; virtual bool Process(IP_HEADER& ip, Stream& ms) = 0;
}; };
// Socket列表 // Socket列表
class SocketList : public List<Socket*> class SocketList : public List<TinySocket*>
{ {
public: public:
Socket* FindByType(ushort type); TinySocket* FindByType(ushort type);
}; };
//class TinyIP; //class TinyIP;
@ -71,7 +71,7 @@ public:
IPAddress Gateway; IPAddress Gateway;
// Arp套接字 // Arp套接字
Socket* Arp; TinySocket* Arp;
// 套接字列表。套接字根据类型来识别 // 套接字列表。套接字根据类型来识别
SocketList Sockets; SocketList Sockets;

View File

@ -3,7 +3,7 @@
//#define NET_DEBUG DEBUG //#define NET_DEBUG DEBUG
#define NET_DEBUG 0 #define NET_DEBUG 0
UdpSocket::UdpSocket(TinyIP* tip) : Socket(tip, IP_UDP) UdpSocket::UdpSocket(TinyIP* tip) : TinySocket(tip, IP_UDP)
{ {
//Port = 0; //Port = 0;
@ -77,16 +77,17 @@ void UdpSocket::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
//if(len2) Write(data, len2); //if(len2) Write(data, len2);
if(len2) if(len2)
{ {
Remote = CurRemote;
ByteArray bs(data, len2); ByteArray bs(data, len2);
Send(bs, CurRemote.Address, CurRemote.Port); Send(bs);
} }
if(OnReceived) if(OnReceived)
{ {
// 返回值指示是否向对方发送数据包 // 返回值指示是否向对方发送数据包
bool rs = OnReceived(*this, udp, CurRemote, ms); bool rs = OnReceived(*this, udp, CurRemote, ms);
if(rs && ms.Remain() > 0) Send(udp, len, CurRemote.Address, CurRemote.Port, false); if(rs && ms.Remain() > 0) SendPacket(udp, len, CurRemote.Address, CurRemote.Port, false);
} }
else else
{ {
@ -103,7 +104,7 @@ void UdpSocket::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
} }
} }
void UdpSocket::Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum) void UdpSocket::SendPacket(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum)
{ {
uint tlen = sizeof(UDP_HEADER) + len; uint tlen = sizeof(UDP_HEADER) + len;
udp.SrcPort = __REV16(Local.Port); udp.SrcPort = __REV16(Local.Port);
@ -128,22 +129,24 @@ void UdpSocket::Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool
} }
// 发送UDP数据到目标地址 // 发送UDP数据到目标地址
void UdpSocket::Send(ByteArray& bs, IPAddress ip, ushort port) bool UdpSocket::Send(const ByteArray& bs)
{ {
if(ip.IsAny()) ip = Remote.Address; //if(ip.IsAny()) ip = Remote.Address;
if(!port) port = Remote.Port; //if(!port) port = Remote.Port;
byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + 256]; byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + 256];
Stream ms(buf, ArrayLength(buf)); Stream ms(buf, ArrayLength(buf));
ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER)); ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER));
UDP_HEADER* udp = ms.Retrieve<UDP_HEADER>(); UDP_HEADER* udp = ms.Retrieve<UDP_HEADER>();
udp->Init(true); udp->Init(true);
// 复制数据,确保数据不会溢出 // 复制数据,确保数据不会溢出
ms.Write(bs); ms.Write(bs);
Send(*udp, bs.Length(), ip, port, true); SendPacket(*udp, bs.Length(), Remote.Address, Remote.Port, true);
return true;
} }
bool UdpSocket::OnWrite(const byte* buf, uint len) bool UdpSocket::OnWrite(const byte* buf, uint len)
@ -153,6 +156,11 @@ bool UdpSocket::OnWrite(const byte* buf, uint len)
return len; return len;
} }
uint UdpSocket::Receive(ByteArray& bs)
{
return 0;
}
uint UdpSocket::OnRead(byte* buf, uint len) uint UdpSocket::OnRead(byte* buf, uint len)
{ {
// 暂时不支持 // 暂时不支持

View File

@ -4,7 +4,7 @@
#include "TinyIP.h" #include "TinyIP.h"
// Udp会话 // Udp会话
class UdpSocket : public Socket, public ITransport, public ISocket class UdpSocket : public TinySocket, public ITransport, public ISocket
{ {
private: private:
@ -24,13 +24,15 @@ public:
typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, IPEndPoint& remote, Stream& ms); typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, IPEndPoint& remote, Stream& ms);
UdpHandler OnReceived; UdpHandler OnReceived;
// 发送UDP数据到目标地址 // 发送数据
void Send(ByteArray& bs, IPAddress ip = IPAddress::Any(), ushort port = 0); virtual bool Send(const ByteArray& bs);
// 接收数据
virtual uint Receive(ByteArray& bs);
virtual string ToString(); virtual string ToString();
protected: protected:
void Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum = true); void SendPacket(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum = true);
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms); virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
virtual bool OnOpen(); virtual bool OnOpen();

View File

@ -1,475 +0,0 @@
#include "Time.h"
#include "Dhcp.h"
#define NET_DEBUG DEBUG
// 字节序
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1
#endif
#pragma pack(push) // 保存对齐状态
// 强制结构体紧凑分配空间
#pragma pack(1)
// DHCP头部总长度240=0xF0字节偏移42=0x2A后面可选数据偏移282=0x11A
typedef struct _DHCP_HEADER
{
byte MsgType; // 若是client送给server的封包设为1反向为2
byte HardType; // 以太网1
byte HardLength; // 以太网6
byte Hops; // 若数据包需经过router传送每站加1若在同一网内为0
uint TransID; // 事务ID是个随机数用于客户和服务器之间匹配请求和相应消息
ushort Seconds; // 由用户指定的时间,指开始地址获取和更新进行后的时间
ushort Flags; // 从0-15bits最左一bit为1时表示server将以广播方式传送封包给 client其余尚未使用
IPAddr ClientIP; // 客户机IP
IPAddr YourIP; // 你的IP
IPAddr ServerIP; // 服务器IP
IPAddr RelayIP; // 中继代理IP
byte ClientMac[16]; // 客户端硬件地址
byte ServerName[64]; // 服务器名
byte BootFile[128]; // 启动文件名
uint Magic; // 幻数0x63825363小端0x63538263
void Init(uint dhcpid, bool recursion = false)
{
// 为了安全,清空一次
memset(this, 0, sizeof(this[0]));
MsgType = 1;
HardType = 1;
HardLength = 6;
Hops = 0;
TransID = __REV(dhcpid);
Flags = 0x80; // 从0-15bits最左一bit为1时表示server将以广播方式传送封包给 client其余尚未使用
SetMagic();
// if(recursion) Prev()->Init(recursion);
}
uint Size() { return sizeof(this[0]); }
// uint Offset() { return Prev()->Offset() + Size(); }
// UDP_HEADER* Prev() { return (UDP_HEADER*)((byte*)this - sizeof(UDP_HEADER)); }
byte* Next() { return (byte*)this + Size(); }
void SetMagic() { Magic = 0x63538263; }
bool Valid() { return Magic == 0x63538263; }
}DHCP_HEADER;
// DHCP后面可选数据格式为“代码+长度+数据”
typedef enum
{
DHCP_OPT_Mask = 1,
DHCP_OPT_Router = 3,
DHCP_OPT_TimeServer = 4,
DHCP_OPT_NameServer = 5,
DHCP_OPT_DNSServer = 6,
DHCP_OPT_LOGServer = 7,
DHCP_OPT_HostName = 12,
DHCP_OPT_MTU = 26, // 0x1A
DHCP_OPT_StaticRout = 33, // 0x21
DHCP_OPT_ARPCacheTimeout = 35, // 0x23
DHCP_OPT_NTPServer = 42, // 0x2A
DHCP_OPT_RequestedIP = 50, // 0x32
DHCP_OPT_IPLeaseTime = 51, // 0x33
DHCP_OPT_MessageType = 53, // 0x35
DHCP_OPT_DHCPServer = 54, // 0x36
DHCP_OPT_ParameterList = 55, // 0x37
DHCP_OPT_Message = 56, // 0x38
DHCP_OPT_MaxMessageSize = 57, // 0x39
DHCP_OPT_Vendor = 60, // 0x3C
DHCP_OPT_ClientIdentifier = 61, // 0x3D
DHCP_OPT_End = 255,
}DHCP_OPTION;
typedef enum
{
DHCP_TYPE_Discover = 1,
DHCP_TYPE_Offer = 2,
DHCP_TYPE_Request = 3,
DHCP_TYPE_Decline = 4,
DHCP_TYPE_Ack = 5,
DHCP_TYPE_Nak = 6,
DHCP_TYPE_Release = 7,
DHCP_TYPE_Inform = 8,
}DHCP_MSGTYPE;
typedef struct _DHCP_OPT
{
DHCP_OPTION Option; // 代码
byte Length; // 长度
byte Data; // 数据
struct _DHCP_OPT* Next() { return (struct _DHCP_OPT*)((byte*)this + 2 + Length); }
struct _DHCP_OPT* SetType(DHCP_MSGTYPE type)
{
Option = DHCP_OPT_MessageType;
Length = 1;
Data = type;
return this;
}
struct _DHCP_OPT* SetData(DHCP_OPTION option, ByteArray& bs)
{
Option = option;
Length = bs.Length();
bs.CopyTo(&Data);
return this;
}
struct _DHCP_OPT* SetData(DHCP_OPTION option, String& str)
{
ByteArray bs(str);
return SetData(option, bs);
}
struct _DHCP_OPT* SetData(DHCP_OPTION option, uint value)
{
Option = option;
Length = 4;
memcpy(&Data, (byte*)&value, Length);
// 需要考虑地址对齐问题只有4字节对齐才可以直接使用整数赋值
//*(uint*)&Data = value;
return this;
}
struct _DHCP_OPT* SetClientId(MacAddress& mac)
{
Option = DHCP_OPT_ClientIdentifier;
Length = 1 + 6;
Data = 1; // 类型ETHERNET=1
memcpy(&Data + 1, &mac.Value, 6);
return this;
}
struct _DHCP_OPT* End()
{
Option = DHCP_OPT_End;
return this;
}
}DHCP_OPT;
#pragma pack(pop) // 恢复对齐状态
Dhcp::Dhcp(W5500 * host)
{
assert_ptr(host);
_w5500 = host;
_w5500 -> = IPAddress(0, 0, 0, 0);
_UdpPort = new UdpClient(host);
_UdpPort->Local.Port = 68;
_UdpPort->Remote.Port = 67;
_UdpPort->Remote.Address = IPAddress::Broadcast();
Running = false;
Result = false;
ExpiredTime = 10;
OnStop = NULL;
}
//Dhcp::Dhcp(TinyIP* tip) : UdpSocket(tip)
//{
// Type = IP_UDP;
// Local.Port = 68;
// Remote.Port = 67;
// Remote.Address = IPAddress::Broadcast();
//
// Running = false;
// Result = false;
// ExpiredTime = 10;
//
// OnStop = NULL;
//}
void Dhcp::SendDhcp(DHCP_HEADER& dhcp, uint len)
{
byte* p = dhcp.Next();
if(p[len - 1] != DHCP_OPT_End)
{
// 此时指向的是负载数据后的第一个字节所以第一个opt不许Next
DHCP_OPT* opt = (DHCP_OPT*)(p + len);
opt = opt->SetClientId(_w5500->Mac);
if(!_w5500->IP.IsAny())
opt = opt->Next()->SetData(DHCP_OPT_RequestedIP, _w5500->IP.Value);
// 构造产品名称把ID第一个字节附到最后
String name;
name += "WSWL_SmartOS_"; // 产生拷贝效果
name.Append(Sys.ID[0]);
opt = opt->Next()->SetData(DHCP_OPT_HostName, name);
String vendor = "http://www.NewLifeX.com";
opt = opt->Next()->SetData(DHCP_OPT_Vendor, vendor);
byte ps[] = { 0x01, 0x06, 0x03, 0x2b}; // 需要参数 Mask/DNS/Router/Vendor
ByteArray bs(ps, ArrayLength(ps));
opt = opt->Next()->SetData(DHCP_OPT_ParameterList, bs);
opt = opt->Next()->End();
len = (byte*)opt + 1 - p;
}
//memcpy(dhcp->ClientMac, (byte*)&_w5500->Mac.Value, 6);
for(int i=0; i<6; i++)
dhcp.ClientMac[i] = _w5500->Mac[i];
//RemoteIP = IPAddress::Broadcast;
Send(*dhcp.Prev(), sizeof(DHCP_HEADER) + len, Remote.Address, Remote.Port, false);
}
// 获取选项,返回数据部分指针
DHCP_OPT* GetOption(byte* p, int len, DHCP_OPTION option)
{
byte* end = p + len;
while(p < end)
{
byte opt = *p++;
byte len = *p++;
if(opt == DHCP_OPT_End) return 0;
if(opt == option) return (DHCP_OPT*)(p - 2);
p += len;
}
return 0;
}
// 找服务器
void Dhcp::Discover(DHCP_HEADER& dhcp)
{
byte* p = dhcp.Next();
DHCP_OPT* opt = (DHCP_OPT*)p;
opt->SetType(DHCP_TYPE_Discover);
SendDhcp(dhcp, (byte*)opt->Next() - p);
}
void Dhcp::Request(DHCP_HEADER& dhcp)
{
byte* p = dhcp.Next();
DHCP_OPT* opt = (DHCP_OPT*)p;
opt->SetType(DHCP_TYPE_Request);
opt = opt->Next()->SetData(DHCP_OPT_DHCPServer, _w5500->DHCPServer.Value);
// 发往DHCP服务器
SendDhcp(dhcp, (byte*)opt->Next() - p);
}
void Dhcp::PareOption(Stream& ms)
{
while(ms.Remain())
{
byte opt = ms.Read<byte>();
if(opt == DHCP_OPT_End) break;
byte len = ms.Read<byte>();
// 有些家用路由器会发送错误的len大于4字节导致覆盖前后数据
switch(opt)
{
case DHCP_OPT_Mask: _w5500->Mask = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DNSServer: _w5500->DNSServer = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_Router: _w5500->Gateway = ms.Read<int>(); len -= 4; break;
case DHCP_OPT_DHCPServer: _w5500->DHCPServer = ms.Read<int>(); len -= 4; break;
//default:
// debug_printf("Unkown DHCP Option=%d Length=%d\r\n", opt, len);
}
// DNS可能有多个IP就不止4长度了
if(len > 0) ms.Seek(len);
}
}
void RenewDHCP(void* param)
{
TinyIP* tip = (TinyIP*)param;
if(tip)
{
/*Dhcp dhcp(tip);
dhcp.Start();*/
// 不能使用栈分配,因为是异步操作
Dhcp* dhcp = new Dhcp(tip);
dhcp->Start();
}
}
void Dhcp::Start()
{
_expiredTime = Time.Current() + ExpiredTime * 1000000;
dhcpid = (uint)Time.Current();
debug_printf("Dhcp::Start ExpiredTime=%ds DhcpID=0x%08x\r\n", ExpiredTime, dhcpid);
// 创建任务每秒发送一次Discover
//debug_printf("Dhcp发送Discover ");
taskID = Sys.AddTask(SendDiscover, this, 0, 1000000, "DHCP");
// 通过DHCP获取IP期间关闭Arp响应
//_w5500->EnableArp = false;
if(_w5500->Arp) _w5500->Arp->Enable = false;
Running = true;
Open();
}
void Dhcp::Stop()
{
Close();
Running = false;
if(taskID)
{
debug_printf("Dhcp发送Discover ");
Sys.RemoveTask(taskID);
}
taskID = 0;
// 通过DHCP获取IP期间关闭Arp响应
//_w5500->EnableArp = true;
if(_w5500->Arp) _w5500->Arp->Enable = true;
debug_printf("Dhcp::Stop Result=%d DhcpID=0x%08x\r\n", Result, dhcpid);
if(Result) _w5500->ShowInfo();
if(OnStop) OnStop(this, NULL);
// 销毁自己
delete this;
}
void Dhcp::SendDiscover(void* param)
{
Dhcp* _dhcp = (Dhcp*)param;
if(!_dhcp->Running) return;
// 检查总等待时间
if(_dhcp->_expiredTime < Time.Current())
{
_dhcp->Stop();
return;
}
byte buf[/*sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + */sizeof(DHCP_HEADER) + 100];
Stream ms(buf, ArrayLength(buf));
//ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER));
DHCP_HEADER* dhcp = ms.Retrieve<DHCP_HEADER>();
// 向DHCP服务器广播
debug_printf("DHCP::Discover...\r\n");
// dhcp->Init(_dhcp->dhcpid, true);
_dhcp->Discover(*dhcp);
}
void Dhcp::OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms)
{
DHCP_HEADER* dhcp = (DHCP_HEADER*)udp.Next();
if(!dhcp->Valid()) return;
byte* data = dhcp->Next();
uint len = ms.Remain();
// 获取DHCP消息类型
DHCP_OPT* opt = GetOption(data, len, DHCP_OPT_MessageType);
if(!opt) return;
// 所有响应都需要检查事务ID
if(__REV(dhcp->TransID) != dhcpid) return;
IPAddress remote = ip.SrcIP;
if(opt->Data == DHCP_TYPE_Offer)
{
_w5500->IP = dhcp->YourIP;
Stream optData(dhcp->Next(), len);
PareOption(optData);
// 向网络宣告已经确认使用哪一个DHCP服务器提供的IP地址
// 这里其实还应该发送ARP包确认IP是否被占用如果被占用还需要拒绝服务器提供的IP比较复杂可能性很低暂时不考虑
#if NET_DEBUG
debug_printf("DHCP::Offer IP:");
_w5500->IP.Show();
debug_printf(" From ");
remote.Show();
debug_printf("\r\n");
#endif
// 独立分配缓冲区进行操作,避免数据被其它线程篡改
byte buf[sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) + sizeof(DHCP_HEADER) + 100];
Stream ms(buf, ArrayLength(buf));
ms.Seek(sizeof(ETH_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER));
DHCP_HEADER* dhcp2 = ms.Retrieve<DHCP_HEADER>();
dhcp2->Init(dhcpid, true);
Request(*dhcp2);
}
else if(opt->Data == DHCP_TYPE_Ack)
{
_w5500->IP = dhcp->YourIP;
#if NET_DEBUG
debug_printf("DHCP::Ack IP:");
IPAddress(dhcp->YourIP).Show();
debug_printf(" From ");
remote.Show();
debug_printf("\r\n");
#endif
//if(dhcp->YourIP == _w5500->IP)
{
// 查找租约时间,提前续约
opt = GetOption(data, len, DHCP_OPT_IPLeaseTime);
if(opt)
{
// 续约时间,大字节序,时间单位秒
uint time = __REV(*(uint*)&opt->Data);
debug_printf("DHCP IPLeaseTime:%ds\r\n", time);
// DHCP租约过了一半以后重新获取IP地址
if(time > 0)
{
//debug_printf("Dhcp过期获取 ");
Sys.AddTask(RenewDHCP, _w5500, (ulong)time / 2 * 1000000, -1, "DHCP超时");
}
}
//return true;
Result = true;
// 完成任务
Stop();
}
}
#if NET_DEBUG
else if(opt->Data == DHCP_TYPE_Nak)
{
// 导致Nak的原因
opt = GetOption(data, len, DHCP_OPT_Message);
debug_printf("DHCP::Nak IP:");
_w5500->IP.Show();
debug_printf(" From ");
remote.Show();
if(opt)
{
debug_printf(" ");
Sys.ShowString(&opt->Data, opt->Length);
}
debug_printf("\r\n");
}
else
debug_printf("DHCP::Unkown Type=%d\r\n", opt->Data);
#endif
}

View File

@ -1,81 +0,0 @@
#ifndef _TinyIP_DHCP_H_
#define _TinyIP_DHCP_H_
#include "Udp.h"
/*
// DHCP协议
class Dhcp : public UdpSocket
{
private:
uint dhcpid;
uint taskID;
ulong _expiredTime;
ulong _nextTime;
void Discover(DHCP_HEADER& dhcp);
void Request(DHCP_HEADER& dhcp);
void PareOption(Stream& bs);
void SendDhcp(DHCP_HEADER& dhcp, uint len);
static void SendDiscover(void* param);
public:
bool Running; // 正在运行
bool Result; // 是否获取IP成功
uint ExpiredTime; // 过期时间
Dhcp(TinyIP* tip);
void Start(); // 开始
void Stop(); // 停止
EventHandler OnStop;
protected:
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
};
*/
class Dhcp
{
Dhcp(W5500 * host);
public:
DHCP_HEADER * dhcpdata;
private:
W5500 * _w5500;
UDPClient * _UdpPort;
uint dhcpid;
uint taskID;
ulong _expiredTime;
ulong _nextTime;
void Discover(DHCP_HEADER& dhcp);
void Request(DHCP_HEADER& dhcp);
void PareOption(Stream& bs);
void SendDhcp(DHCP_HEADER& dhcp, uint len);
static void SendDiscover(void* param);
public:
bool Running; // 正在运行
bool Result; // 是否获取IP成功
uint ExpiredTime; // 过期时间
Dhcp(TinyIP* tip);
void Start(); // 开始
void Stop(); // 停止
EventHandler OnStop;
protected:
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
};
#endif

View File

@ -1,12 +0,0 @@
#include "Tcp.h"
#define NET_DEBUG 0
//#define NET_DEBUG DEBUG
/*
A=>B SYN
B=>A SYN+ACK
A=>B ACK
*/

View File

@ -1,65 +0,0 @@
#ifndef _TinyIP_TCP_H_
#define _TinyIP_TCP_H_
#include "W5500.h"
// Tcp会话
class TcpSocket : public HardwareSocket, public ITransport
{
public:
// Tcp状态
typedef enum
{
Closed = 0,
SynSent = 1,
SynAck = 2,
Established = 3,
}TCP_STATUS;
ushort Port; // 本地端口接收该端口数据包。0表示接收所有端口的数据包
ushort BindPort; // 绑定端口用于发出数据包的源端口。默认为Port若Port为0则从1024算起累加
IPEndPoint Remote; // 远程地址。默认发送数据的目标地址
IPEndPoint Local; // 本地地址
TCP_STATUS Status; // 状态
TCP_HEADER* Header;
TcpSocket(W5500* pw5500):HardwareSocket(pw5500);
// 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms);
bool Connect(IPAddress& ip, ushort port); // 连接远程服务器记录远程服务器IP和端口后续发送数据和关闭连接需要
bool Send(ByteArray& bs); // 向Socket发送数据可能是外部数据包
bool Disconnect(); // 关闭Socket
// 收到Tcp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*TcpHandler)(TcpSocket& socket, TCP_HEADER& tcp, byte* buf, uint len);
TcpHandler OnAccepted;
TcpHandler OnReceived;
TcpHandler OnDisconnected;
virtual string ToString();
protected:
void SendAck(uint len);
void SetSeqAck(TCP_HEADER& tcp, uint ackNum, bool cp_seq);
void SetMss(TCP_HEADER& tcp);
bool Send(TCP_HEADER& tcp, uint len, byte flags);
virtual void OnProcess(TCP_HEADER& tcp, Stream& ms);
virtual void OnAccept(TCP_HEADER& tcp, uint len);
virtual void OnAccept3(TCP_HEADER& tcp, uint len);
virtual void OnDataReceive(TCP_HEADER& tcp, uint len);
virtual void OnDisconnect(TCP_HEADER& tcp, uint len);
virtual bool OnOpen();
virtual void OnClose();
virtual bool OnWrite(const byte* buf, uint len);
virtual uint OnRead(byte* buf, uint len);
};
#endif

View File

@ -1,4 +0,0 @@
#include "Udp.h"
//#define NET_DEBUG DEBUG
#define NET_DEBUG 0

View File

@ -1,43 +0,0 @@
#ifndef _TinyIP_UDP_H_
#define _TinyIP_UDP_H_
#include "W5500.h"
// Udp会话
class UdpSocket : public Socket, public ITransport
{
private:
public:
ushort Port; // 本地端口接收该端口数据包。0表示接收所有端口的数据包
ushort BindPort; // 绑定端口用于发出数据包的源端口。默认为Port若Port为0则从1024算起累加
IPEndPoint Remote; // 远程地址。默认发送数据的目标地址
IPEndPoint CurRemote; // 远程地址。本次收到数据的远程地址
IPEndPoint CurLocal; // 本地地址
UdpSocket(W5500* pw5500):HardwareSocket(pw5500);
// 处理数据包
virtual bool Process(IP_HEADER& ip, Stream& ms);
// 收到Udp数据时触发传递结构体和负载数据长度。返回值指示是否向对方发送数据包
typedef bool (*UdpHandler)(UdpSocket& socket, UDP_HEADER& udp, IPEndPoint& remote, Stream& ms);
UdpHandler OnReceived;
// 发送UDP数据到目标地址
void Send(ByteArray& bs, IPAddress ip = IPAddress::Any, ushort port = 0);
virtual string ToString();
protected:
void Send(UDP_HEADER& udp, uint len, IPAddress& ip, ushort port, bool checksum = true);
virtual void OnProcess(IP_HEADER& ip, UDP_HEADER& udp, Stream& ms);
virtual bool OnOpen();
virtual void OnClose();
virtual bool OnWrite(const byte* buf, uint len);
virtual uint OnRead(byte* buf, uint len);
};
#endif

View File

@ -462,7 +462,12 @@ void TokenController::ShowStat()
{ {
ByteArray bs(str); ByteArray bs(str);
//debug_printf("握手广播 "); //debug_printf("握手广播 ");
udp->Send(bs, IPAddress::Broadcast(), 514); //udp->Send(bs, IPAddress::Broadcast(), 514);
IPEndPoint ep = udp->Remote;
udp->Remote.Port = 514;
udp->Remote.Address = IPAddress::Broadcast();
udp->Send(bs);
udp->Remote = ep;
} }
} }