#include "m.h"
#include "string.h"
#include "stdio.h"
/*
*********************************************************************************************************
* strToBuf
*
* Description: 将结构体转换成字节流
*
* Arguments : char* p_struct 指向结构体的字节指针
* char* p_byte 转换后得到的字节流存储在该处
* int s_size 结构体占内存空间大小
*
* Returns : void
*
* Notes : 例,结构体类型Test1 test,strToBuf((char*)&test,p_byte,sizeof(test));即可
*
*********************************************************************************************************
*/
void strToBuf(INT8U *p_struct,INT8U* p_byte,INT32U s_size){
INT32U i =0;
for(;i<s_size;i++){ /*将结构体中的数据一个字节一个字节的复制到字符数组中*/
*p_byte=(INT8U)*p_struct;
p_byte++;
p_struct++;
}
}
/*
*********************************************************************************************************
* Mbuf_InitList
*
* Description: 将请求分配的mbuf链成单向链表
*
* Arguments : void
*
* Returns : void
*
* Notes : 在主函数里面调用
*
*********************************************************************************************************
*/
void Mbuf_InitList(){
Mbuf* p_mbuf1;
Mbuf* p_mbuf2;
INT32U i;
p_mbuf1 = &MbufTbl[0];
p_mbuf2 = &MbufTbl[1];
for (i = 0; i < BUFSIZE-1; i++) { /*将MbufTbl链成链表,生成MbufFreeList*/
p_mbuf1->m_next=p_mbuf2;
p_mbuf1->m_nextpkt = (Mbuf*)0;
p_mbuf1->m_socket = (void*)0;
strcpy(p_mbuf1->M_databuf," ");
p_mbuf1++;
p_mbuf2++;
}
p_mbuf1->m_nextpkt = (Mbuf*)0;
p_mbuf1->m_hdr.mh_next=(Mbuf*)0; /*p_mbuf1指向MbufTbl[BUFSIZE-1],它的m_next指向一个空buf*/
p_mbuf1->m_socket = (void*)0;
strcpy(p_mbuf1->M_databuf," ");
MbufFreeList = &MbufTbl[0]; /*MbufFreeList指向MbufTbl[0],即链表的起始位置*/
}
/*
*********************************************************************************************************
* Mbuf_Get
*
* Description: 向MbufFreeList申请一个Mbuf
*
* Arguments : void
*
* Returns : Mbuf* 申请到的Mbuf指针
*
* Notes : 当MbufFreeList为空时,申请到一个空指针
*
*********************************************************************************************************
*/
Mbuf* Mbuf_Get(){
if(MbufFreeList==(Mbuf*)0) /*当MbufFreeList为空时,返回一个空指针*/
{
return (Mbuf*)0 ;
}else
{
Mbuf* p_mbuf = MbufFreeList; /*MbufFreeList不为空,则从链表上取下一个*/
MbufFreeList = MbufFreeList->m_next;
p_mbuf->m_next = (Mbuf*)0;
return p_mbuf;
}
}
/*
*********************************************************************************************************
* Mbuf_Create
*
* Description: 将指定长度的数据存入一个Mbuf数据链表中
*
* Arguments : char* p_buff 该指针指向需要存储的数据的起始位置
* int type 记录存储的数据原属于的结构体类型(ARP、TCP等)
* int len 需要存的数据长度
*
* Returns : Mbuf* 指向数据链表表头
*
* Notes : 当存储空间不够的时候,存储失败(还未处理)
*
*********************************************************************************************************
*/
Mbuf* Mbuf_Create(INT8U* p_buff,INT32U type,INT32U len){
struct mbuf* m_head;
struct mbuf* m_end;
INT32U seq = 0;
INT32U head = 1;
INT32S templen = len;
do{
struct mbuf* temp = Mbuf_Get(); /*申请一个Mbuf*/
if(templen > MAXSIZE) /*如果需要存储的数据长度大于MAXSIZE*/
{
temp->m_len = MAXSIZE; /*mbuf中的m_len成员值为MAXSIze,否则等于len*/
}
else
{
temp->m_len = (INT32U)templen;
}
if(head==1){ /*如果是链表的头部,则将m_flags设为1,标示其为头部*/
temp->m_flags = 1;
head = 0;
m_head = temp;
m_end = temp;
}
else{
temp->m_flags = 0; /*如果不是头部,则将申请到的Mbuf加到链表尾部*/
m_end->m_next = temp;
m_end = temp;
}
temp->m_type = type;
temp->m_data = temp->M_databuf; /*将m_data指针指向数据起始位置*/
CopyChar(temp->M_databuf,p_buff+(len-templen),temp->m_len);
m_end->m_seq = seq;
seq = seq+temp->m_len;
/*将数据复制到Mbuf中的M_databuf中*/
if(templen>MAXSIZE)
templen = templen-MAXSIZE; /*如果templen大于MAXSIZE,标示还有数据要存*/
else templen = 0;
/*如果小于或者等于,表示数据已经存完*/
}while(templen!=0);
return m_head;
}
/*
*********************************************************************************************************
* CopyChar
*
* Description: 从一个ch2复制指定长度的数据到ch1
*
* Arguments : char* ch1 该指针指向需要复制数据的数组
* char* ch2 该指针指向将被复制数据的数组
*
* Returns : void
*
* Notes : 当ch2存的有用数据长度小于len时,可能会复制到一些无用的数据
*
*********************************************************************************************************
*/
void CopyChar(INT8U* ch1,INT8U* ch2,INT32U len){
INT32U i;
for(i=0;i<len;i++){ /*复制len个字节*/
if(ch2!="\0")
*ch1=*ch2;
ch2++;
ch1++;
}
return;
}
/*
*********************************************************************************************************
* Mbuf_Free
*
* Description: 释放一个Mbuf
*
* Arguments : Mbuf* pm_buf 该指针指向需要释放的Mbuf
*
* Returns : void
*
*
*********************************************************************************************************
*/
void Mbuf_Free(Mbuf* pm_buf){
if(pm_buf->m_next!=(Mbuf*)0){
pm_buf->m_next->m_nextpkt = pm_buf->m_nextpkt;
pm_buf->m_next->m_socket = pm_buf->m_socket;
}else{
//如果里面的socket不为空,则将socket里的mbuf指针指向nextpkt
}
pm_buf->m_len = 0; /*将里面的数据都清空后添加到MbufFreeList的头部*/
pm_buf->m_nextpkt = (Mbuf*)0;
pm_buf->m_data = " ";
pm_buf->m_flags = 0;
pm_buf->m_type = 0;
strcpy(pm_buf->M_databuf," ");
pm_buf->m_socket = (void*)0;
pm_buf->m_next = MbufFreeList;
MbufFreeList = pm_buf;
}
/*
*********************************************************************************************************
* Mbuf_Getlen
*
* Description: 得到数据链表中存储的数据总长度
*
* Arguments : Mbuf* pm_buf 该指针指向需要计算数据长度的Mbuf数据链表首部
*
* Returns : int 返回数据总长度
*
*
*********************************************************************************************************
*/
INT32U Mbuf_GetLen(Mbuf* pm_buf){
Mbuf* temp_buf = pm_buf;
INT32U templen=0;
do{ /*若temp_buf不为空,则总长度加上temp_buf->m_len*/
templen+=temp_buf->m_len;
temp_buf = temp_buf->m_next;
}while(temp_buf!=(Mbuf*)0);
return templen;
}
/*
*********************************************************************************************************
* Mbuf_GetData
*
* Description: 从数据链表pm_buf中取出指定数据放入ch中
*
* Arguments : Mbuf** pm_buf 指向存储了数据的数据链表地址的指针,取出数据后,链表指针也会发生变化
* 所以用了2级指针
* char* ch 取出的数据放入ch中
* int len 需要取的数据长度
*
* Returns : void
*
*
* Note : 第一个参数为二级指针
*
*********************************************************************************************************
*/
void Mbuf_GetData(Mbuf** pm_buf,INT8U* ch,INT32U len){
INT32U templen=len;
INT8U* temp1 = ch;
Mbuf* temp_buf;
do{
INT8U* temp2 = (*pm_buf)->m_data;
if((*pm_buf)==(Mbuf*)0){
//printf("Data Not Enough!\n");
}
if(templen>(*pm_buf)->m_len) templen = (*pm_buf)->m_len;
CopyChar(temp1,temp2,templen);
temp1 = temp1+templen;
temp_buf = *pm_buf; /*temp_buf指向当前的Mbuf,当pm_buf指向下一个时,则释放temp_buf*/
if(templen == temp_buf->m_len){ /*当一个Mbuf中的数据全部取出时需要释放掉*/
*pm_buf = (*pm_buf)->m_next;
Mbuf_Free(temp_buf);
}
else{
temp_buf->m_data = (*pm_buf)->M_databuf+templen;
/*如果数据未全部取出,则修改m_data(数据起始位置)的值*/
temp_buf->m_len = (*pm_buf)->m_len-templen;
}
len = len-templen; /*每取出templen个数据之后,len的值都要减去templen*/
templen = len;
}while(len>0);
return ;
}
/*
*********************************************************************************************************
* Mbuf_Add
*
* Description: 将数据链表pm_buf2链接到pm_buf1的尾部
*
* Arguments : Mbuf* pm_buf1 数据链表1,添加之后在前面
* Mbuf* pm_buf2 数据链表2,添加之后在后面
*
* Returns : void
*
*
*********************************************************************************************************
*/
void Mbuf_Add(Mbuf* pm_buf1,Mbuf* pm_buf2){
INT32U templen;
Mbuf* temp_buf = pm_buf1;
templen = Mbuf_GetLen(pm_buf1);
while(temp_buf->m_next!=(Mbuf*)0) /*先找到pm_buf1链表的尾部,将尾部Mbuf的m_next指向pm_buf2即可*/
temp_buf = temp_buf->m_next;
temp_buf->m_next = pm_buf2;
while(pm_buf2!=(Mbuf*)0){
pm_buf2->m_seq+=templen;
pm_buf2 = pm_buf2->m_next;
}
}
/*
*********************************************************************************************************
* Mbuf_Insert
*
* Description: 将一个数据包按照序号插入到数据包链表中
*
* Arguments : Mbuf* p_list 起始数据包链表
* Mbuf* p_pkt 接收到的需要进行插入的数据包
*
* Returns : Mbuf* 插入后得到的数据包链表
*
*
*********************************************************************************************************
*/
Mbuf* Mbuf_Insert(Mbuf* p_list,Mbuf* p_pkt){
Mbuf* pm_buf = p_list; /*用来保存表首位置*/
if(p_list == (Mbuf*)0) return p_pkt; /*如果p_list为空,则返回p_pkt*/
if(p_list->m_seq > p_pkt->m_seq) /*如果p_pkt的序号比P_list大,则放在表首*/
{
p_pkt->m_nextpkt = p_list;
return p_pkt;
}
while(p_list->m_nextpkt!=(Mbuf*)0){ /*如果p_list的m_nextpkt指向的mbuf的序号大于p_pkt的序号,则将p_pkt插在p_list后面*/
if(p_list->m_nextpkt->m_seq > p_pkt->m_seq){
p_pkt->m_nextpkt = p_list->m_nextpkt;
p_list->m_nextpkt = p_pkt;
return pm_buf;
}
p_list = p_list->m_nextpkt;
}
p_list->m_nextpkt = p_pkt; /*将p_pkt放在链表尾部*/
return pm_buf;
}
/*
*********************************************************************************************************
* Mbuf_FindSeq
*
* Description: 根据序号找到对应的数据包
*
* Arguments : Mbuf* p_list 数据包链表
* INT32U seq 序号
*
* Returns : Mbuf* 根据序号找到的数据包
*
*
* Notes : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_FindSeq(Mbuf* p_list, INT32U seq){
while(p_list!=(Mbuf*)0){
if(seq==p_list->m_seq)
return p_list;
p_list = p_list->m_nextpkt;
}
return (Mbuf*)0;
}
/*
*********************************************************************************************************
* Mbuf_FindAck
*
* Description: 根据确认号找到对应的数据包ack==p_list->m_seq+Mbuf_GetLen(p_list)
*
* Arguments : Mbuf* p_list 数据包链表
* INT32U ack 确认号
*
* Returns : Mbuf* 根据序号找到的数据包
*
*
* Notes : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_FindAck(Mbuf* p_list, INT32U ack){
while(p_list!=(Mbuf*)0){
if(ack==p_list->m_seq+Mbuf_GetLen(p_list))
return p_list;
p_list = p_list->m_nextpkt;
}
return (Mbuf*)0;
}
/*
*********************************************************************************************************
* Mbuf_GetpktSeq
*
* Description: 根据序号取下已收到的连续数据包
*
* Arguments : Mbuf** p_list 接收队列地址
*
* Returns : Mbuf* 已经接收到的连续数据
*
*
* Notes : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_GetpktSeq(Mbuf** pp_list){
Mbuf* p_temp;
Mbuf* p_list = *pp_list;
p_temp = (Mbuf*)0;
while(p_list!=(Mbuf*)0){
Mbuf_Add(p_temp,p_list);
/*如果p_list的m_nextpkt指向的mbuf与其连续,则取下来*/
if(p_list->m_seq+Mbuf_GetLen(p_list)==p_list->m_nextpkt->m_seq)
p_list = p_list->m_nextpkt;
else
break;
}
return p_temp;
}
/*
*********************************************************************************************************
* Mbuf_GetpktACK
*
* Description: 根据确认号取下已被确认接收的连续数据包
*
* Arguments : Mbuf** p_list 发送缓存队列地址
*
* Returns : Mbuf* 已经被确认接收到的连续数据
*
*
* Notes : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_GetpktAck(Mbuf** pp_list){
Mbuf* p_temp;
Mbuf* p_list = *pp_list;
p_temp = (Mbuf*)0;
while(p_list!=(Mbuf*)0){
Mbuf_Add(p_temp,p_list);
if(p_list->m_ack>=1) /*如果p_list的接收次数m_ack大于等于1,则将其从发送缓存中删除*/
p_list = p_list->m_nextpkt;
else
break;
}
return p_temp;
}
/*
*********************************************************************************************************
* Mbuf_Freepkt
*
* Description:释放一个数据链表
*
* Arguments : Mbuf* p_list 链表首地址
*
* Returns : void
*
*
* Notes : 注意m_nextpkt指向
*********************************************************************************************************
*/
void Mbuf_Freepkt(Mbuf* p_list){
Mbuf* p_temp;
while(p_list!=(Mbuf*)0){
p_temp = p_list;
p_list = p_list->m_next;
Mbuf_Free(p_temp);
}
return;
}
/*
*********************************************************************************************************
* Mbuf_GetDataFree
*
* Description:取出数据,但并不将数据从mbuf中删除掉
*
* Arguments : Mbuf* pm_buf 数据链表首地址
* INT8U* ch 取出的数据存放的位置
* INT32U len 需要取的数据长度
*
* Returns : void
*
*
* Notes : void
*********************************************************************************************************
*/
void Mbuf_GetDataFree(Mbuf* pm_buf,INT8U* ch,INT32U len){
INT32U templen=len;
INT8U* temp1 = ch;
Mbuf* temp_buf;
do{
INT8U* temp2 = pm_buf->m_data;
if(pm_buf==(Mbuf*)0){
//printf("Data Not Enough!\n");
}
if(templen>pm_buf->m_len) templen = pm_buf->m_len;
CopyChar(temp1,temp2,templen);
temp1 = temp1+templen;
temp_buf = pm_buf; /*temp_buf指向当前的Mbuf,当pm_buf指向下一个时,不需释放temp_buf*/
if(templen == temp_buf->m_len){
pm_buf = pm_buf->m_next;
}
len = len-templen; /*每取出templen个数据之后,len的值都要减去templen*/
templen = len;
}while(len>0);
return ;
}