When I call tcp_close(),the program will send FIN,and then the
receiver will reply FIN
But the tcp_pcb haven't been free after this operation.

What should I do now?

It is my source code below in the attach file.


> I use the lwip raw api.
>
>
> When I call tcp_close() the tcp state is ESTABLISH.
> and tcp_close() return err=ERR_OK.
>
> when will the tcp_pcb be free?

I don't really know the lwip raw api regarding TCP. But what I know is
that on socket-based systems, a TCP connection is only closed from one
side if you call close(). It remains in a closing state until the other
side has closed the connection, too.

Without looking in the code, I would say this is the same for lwip raw
api, too. I don't know if there is a function which aborts the
connection without waiting for the other side to close it, too.

Simon
/*------------------------------------------------------------*/
/*  Sample task of http                                                         
                  */
/*------------------------------------------------------------*/
#include    <stdio.h>
#include    <string.h>
#include    <ctype.h>
#include    <stdlib.h>
#include    "lwip/sys.h"
#include    "lwip/api.h"
#include    "app_server.h"
#include "TypeDef.h"
#include "net.h"

#include "http.h"
#include "app.h"
#include "includes.h"
#include "web.h"
#include "Matrix.h"
#include "flash.h"
#include "protocol.h"

//by ming 2005-01 add counter & runtimer

//static u32_t counter=0;
void app_server_init(void);
static INT32U tcpCtrlService(UCHAR *inbuf,UINT len,struct tcp_pcb* pcb,struct 
app_server_state *hs);
static void send_bc_cmd(INT8 WebPageBuf[],INT32U nLen,INT32U nCladdr,INT32U 
nPort);
static void EchoData(INT32U BodyLen,INT8 WebPageBuf[],struct tcp_pcb* 
pcb,struct app_server_state *hs);

//*****************************************************************//
extern INT8   html_message[30];             //ÍøÒ³ÇëÇó×Ö³¤×î¶à30¸ö×Ö½Ú
extern INT32U G_PostPageLen;                //POSTÒ³µÄ³¤¶È
extern INT8  *G_PostPageWr;                 //POSTÒ³µÄдÈëÖ¸Õë
extern INT16U G_session_time;               //»á»°Ê±¼ä
extern INT16U G_udpDeviceSaveSign;          //UDPÉ豸ÉèÖñ£´æ±ê¼Ç
extern SESSION G_Session[MAX_SESSION];      //WEB»á»°½á¹¹
extern INT16U G_MacId;                      
//´«µÝÎïÀíµØÖ·£¬WEBµÄsetÒ³×Ô¶¯°´ÐÐÊý·­Ò³
extern INT8U G_SetPage;                     
//ÉϴηÃÎʵÄSETÒ³£¬ÓÃÓÚË¢ÐÂ×Ô¶¯×ªÌøÕýÈ·ÐÐ
extern INT8U G_SetPageNow;                  //Ŀǰ·ÃÎʵÄSETÒ³
extern INT8U G_HttpSendDelay;               
//HTTP´«ËÍÐèÒªÑÓʱ£¬µ¼³öÅäÖúͺêµÄʱºò£¬Ç°Ê®ÃëÂýËÙ£¬Öð½¥ÌáËÙ
extern INT32U G_UpdateSys;                  
//=0½ûֹдµ×¶ËµØÖ·µÄFLASH£¬=1ϵͳ¸üв»ÏÞÖÆ
//******************************************************************//
extern CONNECTION  conxn[];
extern INT16U G_TcpDataLen;       //TCPÊý¾Ý°ü²é³¤¶È
extern UCHAR  debug;
extern MY my;                     //WEBÉèÖÃÍøÂçÊý¾Ý
//extern UCHAR outbuf_static[];     //¾²Ì¬·ÖÅäÄÚ´æ
extern UCHAR app_outbuf_static[];     //¾²Ì¬·ÖÅäÄÚ´æ
extern void chk_udp_link(void);
extern void BrodcastMy(void);
extern OS_EVENT *Flash_SEM;       //±£´æÊý¾Ýµ½FLASHµÄÈÎÎñ
extern UINT G_TcpWindow;          //TCP¶Ô¶ËµÄ½ÓÊÕ´°¿Ú¡£
extern INT8U  G_IE_Refresh;       //=1ÌύˢÐÂÖ÷Ò³
//--ÒÔÏ·®º£´º¶¨ÒåµÄº¯Êý--//
extern void SyncOsdDisp(void);    //Ë¢ÐÂËùÓмàµÄ×Ö·ûÑ¡Ïî
extern void KeyBoardReLog(void);  //·¢ÃüÁîÖØÆô¼üÅÌ£¬Í¬²½Êý¾Ý¡£ÐèҪͬ²½µÄÉèÖãº
                                  //1¡¢ÉèÖÃÉãÏñ»ú2¡¢ÉèÖüàÊÓÆ÷3¡¢ÉèÖñ¨¾¯µã
                                  //4¡¢ÉèÖÃOSD 5¡¢¸ü¸ÄÓû§Ãû³Æ6¡¢¸ü¸ÄÉ豸·ÖÇø£»
extern INT32U chip_id;
extern INT8U SendInf[];
extern INT8U nSendLen;
/*-----------------------------------------------------------------------------------*/
static void
conn_err(void *arg, err_t err)
{
  struct app_server_state *hs;

  hs = arg;
        if(hs){
          if(hs->pfile){
                        mem_free(hs->pfile);
                        hs->pfile=NULL;
                }
                if(hs->rcvData){
                        mem_free(hs->rcvData);
                        hs->rcvData=NULL;
                }
          mem_free(hs);
        }
}
/*-----------------------------------------------------------------------------------*/

static void
close_conn(struct tcp_pcb *pcb, struct app_server_state *hs)
{
  err_t err;
  tcp_arg(pcb, NULL);
  tcp_sent(pcb, NULL);
  tcp_recv(pcb, NULL);
        if(hs->pfile){
                mem_free(hs->pfile);
                hs->pfile=NULL;
        }
        if(hs->rcvData){
                mem_free(hs->rcvData);
                hs->rcvData=NULL;
        }
Uart_Printf("app_server¹Ø±ÕtcpÁ¬½Ó\n");

  mem_free(hs);
  err=tcp_close(pcb);
}
/*-----------------------------------------------------------------------------------*/
static void
app_send_data(struct tcp_pcb *pcb, struct app_server_state *hs)
{
  err_t err;
  u16_t len;
  INT8U *outbuf;
  u16_t maxLen;
  /* We cannot send more data than space available in the send
     buffer. */

  maxLen=tcp_sndbuf(pcb);

  if(maxLen < hs->left) {
    len = maxLen;//tcp_sndbuf(pcb);
  } else {
    len = hs->left;
  }
  if(!hs->file){
   if(!hs->sentlen&&hs->HeadLen){
        outbuf=app_outbuf_static;
        memcpy(outbuf,hs->Heade,hs->HeadLen);
        memcpy(outbuf+hs->HeadLen,hs->WebPageBuf+hs->sentlen,len-hs->HeadLen);
   }else
        {
                outbuf=hs->WebPageBuf+hs->sentlen-hs->HeadLen;
        //      memcpy(outbuf,hs->WebPageBuf+hs->sentlen-hs->HeadLen,len);
        }
//   outbuf[len]=0;      // Append NULL
   hs->file = outbuf;
   }
  do {
    err = tcp_write(pcb, hs->file, len, 1);
    if(err == ERR_MEM) {
      len /= 2;
          Uart_Printf("app_send_data err!\n");
    }
  } while(err == ERR_MEM && len > 1);  
  
  if(err == ERR_OK) {
    hs->file = NULL;
    hs->left -= len;
    hs->sentlen += len;
  }
}
/*-----------------------------------------------------------------------------------*/
static err_t
app_serv_poll(void *arg, struct tcp_pcb *pcb)
{
  struct app_server_state *hs;

  hs = arg;
  
  /*  printf("Polll\n");*/
  if(hs == NULL) {
    /*    printf("Null, close\n");*/
    tcp_abort(pcb);
    return ERR_ABRT;
  } else {
    ++hs->retries;
    if(hs->retries == 4) {
      tcp_abort(pcb);
      return ERR_ABRT;
    }
    app_send_data(pcb, hs);
  }

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
app_serv_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
  struct app_server_state *hs;

  hs = arg;

  hs->retries = 0;
  
  if(hs->left > 0||udpDevice[hs->dev_num].SeriesSend==1) {    
    app_send_data(pcb, hs);
  } else {
    close_conn(pcb, hs);
  }

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
app_serv_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  int i,nSaveDev=0;
  char *data,*pRcvData=NULL;
  struct app_server_state *hs;
  //by ming 2005.01
  u8_t hour,min,sec;
  u16_t day;
  struct pbuf *q=NULL;
  int len=0;
  char szRcvBuf[1514];
  hs = arg;
  if(err == ERR_OK && p != NULL) {

    /* Inform TCP that we have taken the data. */
    tcp_recved(pcb, p->tot_len);
    if(hs->file == NULL) {
      data = p->payload;
        len = p->tot_len;
        //ÕûºÏpbufÖеÄÊý¾Ý
        q=p;
        if(q->tot_len>PBUF_POOL_BUFSIZE||!hs->rcvFinish)
        {
                data = pRcvData=szRcvBuf;//hs->rcvData;

                while(q)
                {
                      if(q->payload) {
                                memcpy(pRcvData,q->payload,q->len);
                                pRcvData += q->len;
                        }
                        q=q->next;
                }
                pRcvData[0]=0;
        }
        ////////////////////////
      if(1) {//*data =='G'||*data =='P'||!hs->rcvFinish
                //TODO ÔÚÕâÀïÌí¼Óecho´¦Àí·þÎñ
                if(*data==ECHO_HEAD1 && *(data+1)==LINK_HEAD2 && 
*(data+5)==LINK_END1 && *(data+6)==LINK_END2)  //Ìṩ»ØÀ¡·þÎñ
                   {
                       for(i=1;i<MAX_DEV;i++)
                       {
                           if(pcb->remote_ip.addr==udpDevice[i].ipaddr.addr32) {
                                hs->dev_num=i;
                                udpDevice[i].hs = hs;
                                hs->pcb=pcb;
                             goto NEXT; //´æÔÚµÄÉ豸²»Ìí¼Ó
                          }else if(udpDevice[i].ipaddr.addr32==0&&nSaveDev==0) {
                                nSaveDev=i;//»ñÈ¡¿ÕÓàÉ豸´æ·ÅλÖÃ
                          }
                       }

                       if(*data==ECHO_HEAD1 && *(data+1)==LINK_HEAD2 && 
*(data+5)==LINK_END1 && *(data+6)==LINK_END2) {
                          if(*(data+2)>T_NO_DEV && *(data+2)<T_ECHO) {
                                for(i=nSaveDev;i<MAX_DEV;i++) {
                                      if(udpDevice[i].ipaddr.addr32==0) {
                                         
udpDevice[i].ipaddr.addr32=pcb->remote_ip.addr;  
//ÊÕµ½Á¬½ÓÊý¾Ý£¬ÔÚÉ豸ÁбíÖÐÌí¼ÓÉ豸
                                         udpDevice[i].type=*(data+2);           
       //É豸ÀàÐÍ´ÓÁ¬½Ó°üÈ¡³ö
                                         udpDevice[i].model=*(data+3);
                                         udpDevice[i].timer=0;
                                         
if(pcb->remote_port!=my.DevPort[udpDevice[i].type]) {//¶Ë¿Ú²»·ûÉèÖÃ
                                            sprintf((char 
*)udpDevice[i].discription,"%u¿Ú´íÓ¦%u",pcb->remote_port,my.DevPort[udpDevice[i].type]);
                                         }
                                         break;
                                      }
                                    }
                          }
                       }
                       NEXT:
                       EchoData(len,data,pcb,hs);
                   }
                else
                for(i=1;i<MAX_DEV;i++)
                {
                if(pcb->remote_ip.addr==udpDevice[i].ipaddr.addr32)
                        {
                                hs->dev_num=i;
                                udpDevice[i].hs = hs;
                                hs->pcb=pcb;
                                tcpCtrlService(data,p->tot_len,pcb,hs);
                                break;
                        }
                }
                pbuf_free(p);
                tcp_sent(pcb, app_serv_sent);
                if(hs->rcvFinish)
                {
                        if(hs->rcvData){
                                mem_free(hs->rcvData);
                                hs->rcvData=NULL;
                        }
                }
                else{//±£´æÎ´´¦ÀíµÄÊý¾Ý
                //      hs->rcvData=pRcvData;
                //      hs->rcvLeft=G_TcpDataLen;
                }

      } //if(*data =='G')
      
      else {
                        pbuf_free(p);
                        close_conn(pcb, hs);
      } //else if(*data =='G')

        } //if(hs->file == NULL) 
        
        else {
                pbuf_free(p);
    }
  }

  if(err == ERR_OK && p == NULL) {
    close_conn(pcb, hs);
  }
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
app_serv_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct app_server_state *hs;

  tcp_setprio(pcb, TCP_PRIO_MIN);
  
  /* Allocate memory for the structure that holds the state of the
     connection. */
  hs = mem_malloc(sizeof(struct app_server_state));

  if(hs == NULL) {
    return ERR_MEM;
  }
  
  /* Initialize the structure. */
  #if 0
  hs->file = NULL;
  hs->left = 0;
  hs->retries = 0;
  #else
  memset(hs,0,sizeof(struct app_server_state));
  #endif
  /* Tell TCP that this is the structure we wish to be passed for our
     callbacks. */
  tcp_arg(pcb, hs);

  /* Tell TCP that we wish to be informed of incoming data by a call
     to the app_serv_recv() function. */
  tcp_recv(pcb, app_serv_recv);

  tcp_err(pcb, conn_err);
  
  tcp_poll(pcb, app_serv_poll, 4);
  return ERR_OK;
}

/*-----------------------------------------------------------------------------------*/
void
app_server_init(void)
{
  struct tcp_pcb *pcb;

  //by ming 2005.1
  OSTimeSet((u32_t) 0x00000000);
//  counter = (u32_t) 0x00000000;
    
  pcb = tcp_new();
  tcp_bind(pcb, IP_ADDR_ANY, my.DevPort[T_MATRIX]);
  pcb = tcp_listen(pcb);
  tcp_accept(pcb, app_serv_accept);
  Uart_Printf("=================APP SERV initialized =================\r\n");
}

/*-----------------------------------------------------------------------------------*/
static err_t
app_client_connected( void *arg, struct tcp_pcb *pcb, err_t err)
{
        u16_t len;
        err_t error;
  struct app_server_state *rcvs;
        rcvs = arg;
/*  rcvs = mem_malloc(sizeof(struct app_server_state));
  if( rcvs == NULL)
  {
    printf("\nMalloc error");
    return ERR_MEM;
  }
  
        memset(rcvs,0,sizeof(struct app_server_state));  
*/      
        if( err == ERR_OK)
        {
        //      tcp_arg( pcb, rcvs);

                app_send_data(pcb, rcvs);

                tcp_sent( pcb, app_serv_sent);

                tcp_recv( pcb, app_serv_recv);

                tcp_err( pcb, conn_err);

                tcp_poll( pcb, app_serv_poll, 4);
    
                return ERR_OK;
        }
        else
        {
    return err;
        }
}
/*-----------------------------------------------------------------------------------*/
void app_client_init(INT8U *sp,INT8U Len,INT8U DeviceNum)
{

  err_t err;
  struct tcp_pcb *pcb;
  struct ip_addr remote_addr;
  struct app_server_state *rcvs;
  INT8U* pBuff;
  pcb = tcp_new();
  if( pcb == NULL)
  {
    printf("\nNot enough memory to create new connection");
    return;
  }
  printf("\nCreat pcb successfully");
  rcvs = mem_malloc(sizeof(struct app_server_state));
  memset(rcvs,0,sizeof(struct app_server_state));
  rcvs->dev_num = DeviceNum;
  pBuff = mem_malloc(Len);
  memcpy(pBuff,sp,Len);
  rcvs->WebPageBuf = pBuff;
  rcvs->pfile= pBuff;
  rcvs->BodyLen=Len;
  rcvs->left = Len;
  tcp_arg(pcb, rcvs);
  printf("\nReceiver init");

        err = tcp_connect( pcb, &udpDevice[DeviceNum].ipaddr, 18806, 
app_client_connected);
  
  if( err == ERR_OK)
  {
    printf("\ntcp_connect has been called successfully");
    return;
  }
  else if ( err == ERR_MEM)
  {
    printf("\nNot enough memory ro enqueue the SYN");
    return;
  }
  else
  {
    printf("\ntcp_connect has been failed");
    return;
  }
  
  return;
}

static void EchoData(INT32U BodyLen,INT8 WebPageBuf[],struct tcp_pcb* 
pcb,struct app_server_state *hs) //nr-TCP connection number
{
        hs->left=BodyLen;
        hs->WebPageBuf=WebPageBuf;
        hs->BodyLen = BodyLen;
        app_send_data(pcb, hs);
}
//¹¦ÄÜ£º½«ÏàÓ¦µÄWebʵÌå·¢ËͳöÈ¥
//²ÎÊý£ºWebµÄÍ·³¤¶È£¬WebµÄʵÌ峤¶È£¬WebµÄÍ·Êý¾Ý£¬WebµÄʵÌåÊý¾Ý£¬
static void SendData(INT32U BodyLen,INT8 WebPageBuf[],struct tcp_pcb* 
pcb,struct app_server_state *hs,INT32U nBCflag) //nr-TCP connection number
{
        UINT i,len=0;
        i=nBCflag?nBCflag:hs->dev_num;
        if(udpDevice[i].type!=T_NO_DEV)  
                {
                   if(udpDevice[i].SendReady==1 && udpDevice[i].len==0)  
//len==0±íÊ¾ÖØ·¢Êý¾ÝÍê±Ï
                   {       
                          len = FifoLen(udpSendBuf[i].rdp,udpSendBuf[i].wrp);
                          if(len > 0)
                          {
                                if(nBCflag)
                                        {
                                        
send_bc_cmd(&udpSendBuf[i].buf[udpSendBuf[i].rdp],len,udpDevice[i].ipaddr.addr32,my.DevPort[T_TERMINAL]);
                                        }
                                else
                                        {
                                        hs->left=len;
                                        
hs->WebPageBuf=&udpSendBuf[i].buf[udpSendBuf[i].rdp];
                                        hs->BodyLen = len;
                                        app_send_data(pcb, hs);
                                        
//udp_send1(&udpSendBuf[i].buf[udpSendBuf[i].rdp],i,len,0);
                                        }
                                udpSendBuf[i].rdp = 0;
                                udpSendBuf[i].wrp = 0;
                          }
                          udpDevice[i].SendReady = 0;
                   }
                }
                else 
                {
                   udpSendBuf[i].rdp = 0;
                   udpSendBuf[i].wrp = 0;   // Çå¿ÕUDP»º³åÇø
                }

}

//TCP ·½Ê½·¢Ë͹㲥°ü
//
static void send_bc_cmd(INT8 WebPageBuf[],INT32U nLen,INT32U nCladdr,INT32U 
nPort)
{
        struct netconn *conn,*newconn;
        struct netbuf *buf;
        struct ip_addr addr;
        char *data;
        err_t err=0;
        int i;
        /* ´´½¨Ò»¸öеÄÁ¬½Ó*/
        conn = netconn_new(NETCONN_TCP);
        /* ÉèÖÃÔ¶³ÌÖ÷»úµÄIPµØÖ·*/
        addr.addr = htonl(nCladdr);
        /* Á¬½ÓÔ¶³ÌÖ÷»ú*/
        err=netconn_connect(conn, &addr, nPort);
        if(err == ERR_OK)
        {
        /* ·¢ËÍ*/
        err = netconn_write(conn, WebPageBuf, nLen, NETCONN_NOCOPY);
        }
        netconn_close(conn);
        netconn_delete(conn);
}
#if 0
static void parse_client_data(UCHAR *inbuf,UINT len,struct tcp_pcb *pcb,struct 
app_server_state *hs)
{
        UCHAR i,j;

   // Capture sender's port number and ip_addr
   // to send return message to
   UINT nSaveDev=1;
   if(pcb->local_port==ECHO_PORT)  //Ìṩ»ØÀ¡·þÎñ
   {
       for(i=1;i<MAX_DEV;i++)
       {
          if(pcb->remote_ip.addr==udpDevice[i].ipaddr.addr32 && 
pcb->remote_port==my.DevPort[udpDevice[i].type])
          {
             udpDevice[i].timer=0;                    //Á¬½Ó³¬Ê±¼ÆÊ±Æ÷ÇåÁã
   //          udp_echo_service(inbuf,udp->length-8,i); 
             SendData(0,len,NULL,inbuf,pcb,hs);//¾ßÌåÉ豸¶Ë¿Ú
             return;
          }
          else if(pcb->remote_ip.addr==udpDevice[i].ipaddr.addr32) {
             goto NEXT; //´æÔÚµÄÉ豸²»Ìí¼Ó
          }else if(udpDevice[i].ipaddr.addr32==0&&nSaveDev==1) {
                nSaveDev=i;//»ñÈ¡¿ÕÓàÉ豸´æ·ÅλÖÃ
          }
       }
    //   inbuf+=42;  //È¥µô°üÍ·
       if(*inbuf==LINK_HEAD1 && *(inbuf+1)==LINK_HEAD2 && *(inbuf+5)==LINK_END1 
&& *(inbuf+6)==LINK_END2) {
          if(*(inbuf+2)>T_NO_DEV && *(inbuf+2)<T_ECHO) {
                for(i=nSaveDev;i<MAX_DEV;i++) {
                      if(udpDevice[i].ipaddr.addr32==0) {
                         udpDevice[i].ipaddr.addr32=pcb->remote_ip.addr;  
//ÊÕµ½Á¬½ÓÊý¾Ý£¬ÔÚÉ豸ÁбíÖÐÌí¼ÓÉ豸
                         udpDevice[i].type=*(inbuf+2);                  
//É豸ÀàÐÍ´ÓÁ¬½Ó°üÈ¡³ö
                         udpDevice[i].model=*(inbuf+3);
                         udpDevice[i].timer=0;
                         if(pcb->remote_port!=my.DevPort[udpDevice[i].type]) 
{//¶Ë¿Ú²»·ûÉèÖÃ
                            sprintf((char 
*)udpDevice[i].discription,"%u¿Ú´íÓ¦%u",pcb->remote_port,my.DevPort[udpDevice[i].type]);
                         }
                         break;
                      }
                    }
          }
       }
   //    inbuf-=42;
NEXT:
       udpDevice[MAX_DEV+1].ipaddr.addr32=pcb->remote_ip.addr; 
//±¸·ÝIP£¬ÓÃÓÚ·´À¡
       my.DevPort[T_ECHO]=pcb->remote_port;                  
//±£´æ¶Ë¿Ú£¬ÓÃÓÚ·´À¡
//       udp_echo_service(inbuf,udp->length-8,MAX_DEV+1);      //ECHOÐéÉ豸¶Ë¿Ú
       SendData(0,len,NULL,inbuf,pcb,hs);
   }
   else if(pcb->local_port==my.DevPort[T_MATRIX])             //Ìṩ¾ØÕó·þÎñ
   {
      for(i=1;i<MAX_DEV;i++)
      {
         if((pcb->remote_ip.addr==udpDevice[i].ipaddr.addr32) && 
(udpDevice[i].set_st==UDP_LINK))  // fanhaichun20060522
         {
            udpDevice[i].st_now=UDP_LINK;                        //˵Ã÷ÍøÂçͨ
            if(pcb->remote_port==my.DevPort[udpDevice[i].type])            
            {
                    udpDevice[i].timer=0;                             
//Á¬½Ó³¬Ê±¼ÆÊ±Æ÷ÇåÁã
                    if(*(inbuf+42-42)==SEQ_HEAD && *(inbuf+44-42)==SEQ_END && 
*(inbuf+45-42)==SEQ_END) { //Ðè·´À¡µÄÊý¾Ý°ü
                        
if((FifoLen(udpRecBuf[i].rdp,udpRecBuf[i].wrp)+4)<UDPMAXREC) {
                                        j=(UINT)*(inbuf+43-42);                 
                     
                                        inbuf+=3;                  
//¶ªÆúÁ÷Ë®ºÅ°üÍ·
                                        if(tcpCtrlService(inbuf,len,i)) {
                                        //    udp_send1(&i,i,j,3);     
//·´À¡Á÷Ë®ºÅ,&iûÓÐʵ¼ÊÓô¦ mode=3
                                        //      SendData(0,j,NULL,&i,pcb,hs);
                                        }
                                }
                        }
                        else if(*(inbuf+42-42)==FBK_HEAD && 
*(inbuf+44-42)==FBK_END && *(inbuf+45-42)==FBK_END) { //·´À¡°ü 
                                if(udpDevice[i].sequence==*(inbuf+43-42)) {
                                        udpDevice[i].sendmode=NOR_SEND;
                                        udpDevice[i].len=0;
                                udpDevice[i].retry=0;
                                udpSendBuf[i].rdp=udpSendBuf[i].wrp; 
//Çå¿Õ»º³åÇø
                                }  
                        }
                        else {  //ÆÕͨ¿ØÖÆÊý¾Ý°ü
                              udpDevice[i].timer=0;              
//Á¬½Ó³¬Ê±¼ÆÊ±Æ÷ÇåÁã
                              tcpCtrlService(inbuf,len,i);
                        }
                      return;
            }
            else if(pcb->remote_port==ECHO_PORT)     //ECHO·´À¡±¨
            {
               udpDevice[i].timer=0;                 //Á¬½Ó³¬Ê±¼ÆÊ±Æ÷ÇåÁã
            }
         }
      } 
   }
}
#endif
static INT32U tcpCtrlService(UCHAR *inbuf,UINT len,struct tcp_pcb* pcb,struct 
app_server_state *hs)
{
//    inbuf+=42;  //È¥µô°üÍ·
    //³¤¶È±ØÐëСÓÚ»º³åÇøµÄ³¤¶È
    UCHAR dev_num=hs->dev_num;
    
if((FifoLen(udpRecBuf[dev_num].rdp,udpRecBuf[dev_num].wrp)+len)<(UDPMAXREC-1)) 
    {
       while(len--)
       {
          udpRecBuf[dev_num].buf[udpRecBuf[dev_num].wrp++]=*inbuf++;          
//ÕâÀォЭÒé½ÓÊÕµ½»·Ðлº³å¶ÓÁÐÖÐ
          if(udpRecBuf[dev_num].wrp>=UDPMAXREC) udpRecBuf[dev_num].wrp=0;
       }
//       OSSemPost(Key_Code_Protocol_SEM); //·¢ËÍÐźÅÁ¿Í¨Öª½øÐÐÍøÂçЭÒé½âÎöÈÎÎñ
        Udp_Code_ProtocolExtend(dev_num);
       return 1;
    }
    else 
    {
//      OSSemPost(Key_Code_Protocol_SEM); //·¢ËÍÐźÅÁ¿Í¨Öª½øÐÐÍøÂçЭÒé½âÎöÈÎÎñ
        return 0;
    }
}

#define __UDPINTERFACE_C__
/*-----------------------------------------------------------------------------
   º¯ÊýÔ­ÐÍ: INT8U WriteNetFIFO(INT8U *sp,INT8U Len,INT8U DeviceNum)
   ¹¦ÄÜÃèÊö: 
-----------------------------------------------------------------------------*/
INT8U WriteNetFIFO(INT8U *sp,INT8U Len,INT8U DeviceNum)
{
#if 1
        INT16U LeaveLen;
        INT32U counter;
        INT32U nBCflag=0;
        #if OS_CRITICAL_METHOD == 3    
    OS_CPU_SR  cpu_sr;    
    cpu_sr = 0; 
        #endif          
        if(DeviceNum >= MAX_DEV){
                DeviceNum %= MAX_DEV;
                nBCflag=DeviceNum;
                }
        if (Len > UDPMAXREC) return(FAILURE);
        
        // ÆôÓÿɿ¿Á¬½ÓÐèÒªÅжÏÊÇ·ñ¿ÉÒÔ·¢ËÍ
        if (G_matrix.UDP_FeedBack == 1)
        {
                counter = 0;
                while(udpDevice[DeviceNum].sendmode == FEED_BACK)
                {
                        counter++;
                        OSTimeDly(10);
                        if (counter>500) udpDevice[DeviceNum].sendmode = 
NOR_SEND;
                }       
        }
        
        LeaveLen = FifoLen(udpSendBuf[DeviceNum].wrp,udpSendBuf[DeviceNum].rdp);
        
        if (LeaveLen == 0) 
        {       
                LeaveLen = UDPMAXREC;
        }
        else if (LeaveLen <= 24) 
        {
                LeaveLen = 1;
        }
        
        if (LeaveLen <= Len)
        {
                // ÊÇ·ñÆôÓÃÁ÷Á¿¿ØÖÆ             
                if (G_matrix.UDP_FeedBack == 1)
                {
                        if((udpDevice[DeviceNum].type == 
T_KEYBOARD)&&(DeviceNum != MAX_DEV)) 
                        {
                                udpDevice[DeviceNum].sendmode = FEED_BACK;      
                
                        }
                }                               
                // ÊÇ·ñÆôÓÃÍøÂçµ÷ÊÔ             
                #if NET_DEBUG ==1
                if (DeviceNum==DeviceId_DEBUG)
                {
                        udpDevice[DeviceNum].sendmode = NOR_SEND;
                }
                #endif
                udpDevice[DeviceNum].SendReady = 1;                     
                ////OSSemPost(TCPIP_SEM);// Æô¶¯·¢ËÍ
                if(nBCflag)
                        {
                        SendData(0,NULL,NULL,NULL,nBCflag);
                        }else
                
SendData(0,NULL,udpDevice[DeviceNum].hs->pcb,udpDevice[DeviceNum].hs,nBCflag);
        }
                
        // ½øÈëÁÙ½ç¶Î´úÂë
        OS_ENTER_CRITICAL();
        if(udpSendBuf[DeviceNum].wrp >= UDPMAXREC)
        {
                udpSendBuf[DeviceNum].wrp = 0;
        }
        for(;Len!=0;Len--)
        {
                udpSendBuf[DeviceNum].buf[udpSendBuf[DeviceNum].wrp++] = *sp++;
                if(udpSendBuf[DeviceNum].wrp >= UDPMAXREC)
                {
                        udpSendBuf[DeviceNum].wrp = 0;
                }
        }       
        OS_EXIT_CRITICAL();     
        
        // ÊÇ·ñÊÇÁ¬Ðø·¢ËÍ
        if (udpDevice[DeviceNum].SeriesSend == 
0&&!nBCflag)//nBCflag´ú±í¹ã²¥ÐèÒªÁ¬Ðø·¢£¬
        {
                // ÊÇ·ñÆôÓÃÁ÷Á¿¿ØÖÆ             
                if (G_matrix.UDP_FeedBack == 1)
                {
                        if((udpDevice[DeviceNum].type == 
T_KEYBOARD)&&(DeviceNum != MAX_DEV)) 
                        {
                                udpDevice[DeviceNum].sendmode = FEED_BACK;
                        }
                }                               
                // ÊÇ·ñÆôÓÃÍøÂçµ÷ÊÔ
                #if NET_DEBUG ==1
                if (DeviceNum==DeviceId_DEBUG)
                {
                        udpDevice[DeviceNum].sendmode = NOR_SEND;
                }
                #endif
                udpDevice[DeviceNum].SendReady = 1;             
                ////OSSemPost(TCPIP_SEM);
                if(nBCflag)
                        {
                        SendData(0,NULL,NULL,NULL,nBCflag);
                        }
                else
                
SendData(0,NULL,udpDevice[DeviceNum].hs->pcb,udpDevice[DeviceNum].hs,nBCflag);
        }
        #endif
        return(SUCCESS);                
}

void SendBCData(INT8U *frame,INT8U len)
{
        memcpy(SendInf,frame,len);
        nSendLen = len;
        OSSemPost(Key_Code_Protocol_SEM);
}
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to