⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppp.c

📁 蓝牙协议源代码 bluetooth stack for lwip
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 2003 EISLAB, Lulea University of Technology. * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without modification,  * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  * OF SUCH DAMAGE. * * This file is part of the lwBT Bluetooth stack. *  * Author: Conny Ohult <conny@sm.luth.se> * *//*-----------------------------------------------------------------------------------*//* ppp.c * * Implementation of the PPP protocol. * Used to carry packets from the higher IP layer across the RFCOMM serial port  * emulation layer. *//*-----------------------------------------------------------------------------------*/#include "netif/lwbt/rfcomm.h"#include "netif/lwbt/ppp.h"#include "netif/lwbt/lwbt_memp.h"#include "netif/lwbt/fcs.h"#include "lwbtopts.h"#include "lwip/debug.h"struct ppp_pcb *ppp_listen_pcbs;  /* List of all PPP PCBs listening for a connection */struct ppp_pcb *ppp_active_pcbs;  /* List of all active PPP PCBs */struct ppp_pcb *ppp_tmp_pcb;struct ppp_req *ppp_tmp_req;u8_t id_nxt; /* Next Identifier to be sent *//* Forward declarations */err_t ppp_output(struct ppp_pcb *pcb, struct pbuf *p);err_t ppp_cp_output(struct ppp_pcb *pcb, u16_t proto, u8_t code, u8_t id, struct pbuf *q);u8_t ppp_next_id(void);struct pbuf *lcp_cfg_req(struct ppp_pcb *pcb, struct pbuf *options);err_t ipcp_cfg_req(struct ppp_pcb *pcb);void ppp_pbuf_ref_chain(struct pbuf *p);/*-----------------------------------------------------------------------------------*//*  * ppp_init(): * * Initializes the PPP layer. *//*-----------------------------------------------------------------------------------*/voidppp_init(void){  /* Clear globals */  ppp_active_pcbs = NULL;  ppp_tmp_pcb = NULL;  /* Initialize the lcp and ipcp identifier */  id_nxt = 0;}/*-----------------------------------------------------------------------------------*//* * ppp_tmr(): * * Called every 1s and implements the command timer that * removes a DLC if it has been waiting for a response enough * time. *//*-----------------------------------------------------------------------------------*/voidppp_tmr(void){  struct ppp_pcb *pcb;  struct ppp_req *req;  err_t ret;  /* Step through all of the active pcbs */  for(pcb = ppp_active_pcbs; pcb != NULL; pcb = pcb->next) {    /* Step through any unresponded requests */    for(req = pcb->reqs; req != NULL; req = req->next) {      --req->rto; /* Adjust rto timer */      LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_tmr: req->rto = %d\n", req->rto));      /* Check if restart timer has expired */      if(req->rto == 0) {	/* Check if max number of retransmissions have been reached */	if(req->nrtx == 0) {	  LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_tmr: Max number of retransmissions have been reached\n"));	  PPP_REQ_RMV(&(pcb->reqs), req);	  pbuf_free(req->p);	  LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_tmr: Free memory for request with ID 0x%x***********\n", req->id));	  lwbt_memp_free(MEMP_PPP_REQ, req);	  pcb->state = PPP_LCP_CLOSED;	  PPP_EVENT_DISCONNECTED(pcb,ERR_CLSD,req->proto,ret);	} else {	  --req->nrtx;	  /* Retransmitt request with timeout doubled. It may not exceed the configured 	     timeout value */	  req->rto = PPP_RTO/(req->nrtx + 1);	  LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_tmr: Retransmitt\n"));	  ppp_output(pcb, req->p);	}      }    }  }}/*-----------------------------------------------------------------------------------*//*  * ppp_lp_disconnected(): * * Called by the application to indicate that the lower protocol disconnected. *//*-----------------------------------------------------------------------------------*/err_tppp_lp_disconnected(struct rfcomm_pcb *rfcommpcb){  struct ppp_pcb *pcb;  err_t ret = ERR_OK;  LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_lp_disconnected\n"));  for(pcb = ppp_active_pcbs; pcb != NULL; pcb = pcb->next) {    if(pcb->rfcommpcb == rfcommpcb) {      pcb->state = PPP_LCP_CLOSED;      PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_LCP, ret);      return ret; /* Since there should be only one PPP connection */    }  }  for(pcb = ppp_listen_pcbs; pcb != NULL; pcb = pcb->next) {    if(pcb->rfcommpcb == rfcommpcb) {      pcb->state = PPP_LCP_CLOSED;      PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_LCP, ret);      return ret; /* Since there should be only one PPP connection */    }  }  return ret;}/*-----------------------------------------------------------------------------------*//*  * ppp_process_lcp(): * * Parses the received LCP packet and handles it. *//*-----------------------------------------------------------------------------------*/voidppp_process_lcp(struct ppp_pcb *pcb, struct pbuf *p){  struct ppp_cp_hdr *cphdr;  struct ppp_cfg_hdr *cfghdr;  struct ppp_req *req;  struct pbuf *r, *s;  u8_t rspstate = LCP_CFG_ACK;  u16_t len;  err_t ret;  cphdr = p->payload;  pbuf_header(p, -PPP_CPHDR_LEN);  cphdr->len = ntohs(cphdr->len);  len = cphdr->len - PPP_CPHDR_LEN;    if(cphdr->code == LCP_CFG_ACK || cphdr->code == LCP_CFG_NAK ||      cphdr->code == LCP_CFG_REJ || cphdr->code == LCP_CODE_REJ ||      cphdr->code == LCP_TERM_ACK) {    for(req = pcb->reqs; req != NULL; req = req->next) {      /* Remove any matching request */      if(cphdr->id == req->id) {	PPP_REQ_RMV(&(pcb->reqs), req);	pbuf_free(req->p);	LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: Free memory for request with id 0x%x***********\n", req->id));	lwbt_memp_free(MEMP_PPP_REQ, req);      }    }  } LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: cphdr->code = 0x%x\n", cphdr->code)); /*   {   struct pbuf *q;   for(q = p; q != NULL; q = q->next) {   u16_t i;    for(i = 0; i < q->len; ++i) {      LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: 0x%x\n", ((u8_t *)q->payload)[i]));    }    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: q->len == %d q->tot_len == %d\n", q->len, q->tot_len));  }} */  r = NULL;    switch(cphdr->code) {  case LCP_CFG_REQ:    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_CFG_REQ\n"));    if(pcb->state == PPP_LCP_CLOSED) {      /* A terminate-ack is sent to indicate that we are in a closed state */      ppp_cp_output(pcb, PPP_LCP, LCP_TERM_ACK, ppp_next_id(), NULL);      break;    } else if(pcb->state == PPP_LCP_LISTEN) {      /* If pcb in LISTEN state we move it to the active list */      PPP_RMV(&(ppp_listen_pcbs), pcb);      PPP_REG(&ppp_active_pcbs, pcb);    }    pcb->state = PPP_LCP_CFG;    while(len > 0) {       cfghdr = p->payload;      switch(cfghdr->type) {      case LCP_CFG_MRU:	/* ACK - Parameter accepted */	pcb->mru = ntohs(((u16_t *)p->payload)[1]);	if(rspstate == LCP_CFG_ACK) {	  s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM);	  memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len);	  if(r == NULL) {	    r = s;	  } else {	    pbuf_chain(r, s);	    pbuf_free(s);	  }	} /* if rspstate == LCP_CFG_NAK or LCP_CFG_REJ do not add packet to outgoing pbuf */      case LCP_CFG_ACCM:	/* ACK - Parameter accepted */	/* Since we will handle all characters that are escaped we do not need to save the 	   ACCM for incoming data */	if(rspstate == LCP_CFG_ACK) {	  s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM);	  memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len);	  if(r == NULL) {	    r = s;	  } else {	    pbuf_chain(r, s);	    pbuf_free(s);	  }	} /* if rspstate == LCP_CFG_NAK or LCP_CFG_REJ do not add packet to outgoing pbuf */	break;#if PPP_AUTH      case LCP_CFG_AUTH:	//TODO: NOT IMPLEMENTDED	break;#endif#if PPP_PHDR_COMP      case LCP_CFG_P_COMP:	pcb->lcpcfg |= LCP_CFG_IN_PCOMP;	if(rspstate == LCP_CFG_ACK) {	  s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM);	  memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len);	  if(r == NULL) {	    r = s;	  } else {	    pbuf_chain(r, s);	    pbuf_free(s);	  }	}	break;#endif /* PPP_PHDR_COMP */#if PPP_ACHDR_COMP      case LCP_CFG_AC_COMP:	pcb->lcpcfg |= LCP_CFG_IN_ACCOMP;	if(rspstate == LCP_CFG_ACK) {	  s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM);	  memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len);	  if(r == NULL) {	    r = s;	  } else {	    pbuf_chain(r, s);	    pbuf_free(s);	  }	}	break;#endif /* PPP_ACHDR_COMP */      default:	/* Reject parameter */	if(rspstate != LCP_CFG_REJ) {	  rspstate = LCP_CFG_REJ;	  if(r != NULL) {	    pbuf_free(r);	    r = NULL;	  }	}	s = pbuf_alloc(PBUF_RAW, cfghdr->len, PBUF_RAM);	memcpy((u8_t *)s->payload, (u8_t *)p->payload, cfghdr->len);	if(r == NULL) {	  r = s;	} else {	  pbuf_chain(r, s);	  pbuf_free(s);	}	break;      } /* switch */      //pbuf_header(p, -(cfghdr->len - PPP_CFGHDR_LEN));      //len -= cfghdr->len - PPP_CFGHDR_LEN;      pbuf_header(p, -(cfghdr->len));      len -= cfghdr->len;    } /* while */    if(!(pcb->pppcfg & PPP_IR) && !(pcb->lcpcfg2 & LCP_CFG_OUT_REQ)) {      /* Send a LCP configure request for outgoing link if it hasnt been configured */      p = lcp_cfg_req(pcb, NULL);      ppp_cp_output(pcb, PPP_LCP, LCP_CFG_REQ, ppp_next_id(), p);      pcb->lcpcfg2 |= LCP_CFG_OUT_REQ;    }    /* Send response to configuration request */    ppp_cp_output(pcb, PPP_LCP, rspstate, cphdr->id, r);    if(rspstate == LCP_CFG_ACK) {      pcb->lcpcfg |= LCP_CFG_OUT_ACK;      /* LCP connection established if a configuration a ack has been received */      if(pcb->lcpcfg & LCP_CFG_IN_ACK) {	if(pcb->lcpcfg & LCP_CFG_PAP && pcb->pppcfg & PPP_IR) {	  //TODO: CALL AUTHENTICATE FUNCTION IN UPPER LAYER 	  /* Authenticate if we are the initiator */	} else {	  pcb->state = PPP_IPCP_CFG;	  if(pcb->pppcfg & PPP_IR) { /* Configure IPCP connection if we are the initiator */	    if(ipcp_cfg_req(pcb) != ERR_OK) {	      LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: ipcp config request failed\n"));	      ppp_disconnect(pcb);	    }  	  }	}      }    }    break;  case LCP_CFG_ACK:    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_CFG_ACK\n"));    if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN) {      /* A terminate-ack is sent to indicate that we are in a closed state */      ppp_cp_output(pcb, PPP_LCP, LCP_TERM_ACK, ppp_next_id(), NULL);      break;    }    pcb->lcpcfg |= LCP_CFG_IN_ACK;    pcb->naks = 0;    while(len > 0) {      cfghdr = p->payload;      //pbuf_header(p, -PPP_CFGHDR_LEN);      //len -= PPP_CFGHDR_LEN;      switch(cfghdr->type) {      case LCP_CFG_MRU:	/* Maximum receive unit that the implementation can receive. Doesnt need to be stored */	break;      case LCP_CFG_ACCM:	pcb->outaccm = ntohl(*((u32_t *)(((u16_t *)p->payload) + 1)));	break;#if PPP_PHDR_COMP      case LCP_CFG_P_COMP: 	pcb->lcpcfg |= LCP_CFG_OUT_PCOMP;	break;#endif /* PPP_PHDR_COMP */#if PPP_ACHDR_COMP      case LCP_CFG_AC_COMP:	pcb->lcpcfg |= LCP_CFG_OUT_ACCOMP;	break;#endif /* PPP_ACHDR_COMP */      default:	/* Silently discard configuration option */	break;      } /* switch */      pbuf_header(p, -cfghdr->len);      len -= cfghdr->len;    } /* while */    /* LCP connection established if a configuration a ack has been sent */    if(pcb->lcpcfg & LCP_CFG_OUT_ACK) {      /* LCP connection established */      pcb->state = PPP_IPCP_CFG;      if(pcb->pppcfg & PPP_IR) { /* Configure IPCP connection if we are the initiator */	if(ipcp_cfg_req(pcb) != ERR_OK) {	  LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: ipcp config request failed\n"));	  ppp_disconnect(pcb);	}       }     }    break;  case LCP_CFG_NAK:    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_process_lcp: LCP_CFG_NAK\n"));    if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN) {      /* A terminate-ack is sent to indicate that we are in a closed state */      ppp_cp_output(pcb, PPP_LCP, LCP_TERM_ACK, ppp_next_id(), NULL);      break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -