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

📄 ppp.c

📁 蓝牙协议源代码 bluetooth stack for lwip
💻 C
📖 第 1 页 / 共 5 页
字号:
    p = lcp_cfg_req(pcb, NULL);    if((ret = ppp_cp_output(pcb, PPP_LCP, LCP_CFG_REQ, ppp_next_id(), p)) == ERR_OK) {      pcb->state = PPP_LCP_CFG;    }  }  return ret;}/*-----------------------------------------------------------------------------------*//*  * ppp_disconnect(): * * Closes the connection held by the PCB but does not dealloc it. Call the  * disconnected callback when disconnection is complete. *//*-----------------------------------------------------------------------------------*/err_tppp_disconnect(struct ppp_pcb *pcb){  err_t ret;  if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN ||      pcb->state == PPP_LCP_CLOSING) {    PPP_EVENT_DISCONNECTED(pcb, ERR_OK, PPP_LCP, ret);    return ERR_OK;  }  pcb->state = PPP_LCP_CLOSING;  return ppp_cp_output(pcb, PPP_LCP, LCP_TERM_REQ, ppp_next_id(), NULL);}/*-----------------------------------------------------------------------------------*//*  * ppp_echo(): * * Sends an empty PPP echo request message. Also specify the function that should * be called when a PPP echo reply has been received. *//*-----------------------------------------------------------------------------------*/err_tppp_echo(struct ppp_pcb *pcb, err_t (* echo_rsp)(void *arg,						 struct ppp_pcb *tpcb,						 err_t err)){  if(pcb->state == PPP_LCP_CLOSED || pcb->state == PPP_LCP_LISTEN ||      pcb->state == PPP_LCP_CFG || pcb->state == PPP_LCP_CLOSING) {    return ERR_CLSD;  }  pcb->echo_rsp = echo_rsp;  return ppp_cp_output(pcb, PPP_LCP, LCP_ECHO_REQ, ppp_next_id(), NULL);}/*-----------------------------------------------------------------------------------*//*  * ppp_cp_output(): * * Sends a PPP control protocol packet (IPCP or LCP). *//*-----------------------------------------------------------------------------------*/err_tppp_cp_output(struct ppp_pcb *pcb, u16_t proto, u8_t code, u8_t id, struct pbuf *q){  struct pbuf *p, *r;  struct ppp_req *req;  err_t ret;  u16_t fcs;  u8_t j = 0;  LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_cp_output: Code == 0x%x\n", code));  if(pcb->lcpcfg & LCP_CFG_OUT_ACCOMP && pcb->state != PPP_LCP_CFG) {    p = pbuf_alloc(PBUF_RAW, PPP_HDR_LEN - 2 + PPP_CPHDR_LEN, PBUF_RAM);  } else {    p = pbuf_alloc(PBUF_RAW, PPP_HDR_LEN + PPP_CPHDR_LEN, PBUF_RAM);  }    if(!(pcb->lcpcfg & LCP_CFG_OUT_ACCOMP && pcb->state != PPP_LCP_CFG)) {    ((u16_t *)p->payload)[j/2] = htons(PPP_ADDRCTRL); /* Set adddress control field */    j+= 2;  }  ((u16_t *)p->payload)[j/2] = htons(proto); /* Set protocol field */  j+= 2;  ((u8_t *)p->payload)[j++] = code; /* Set type of control packet */  ((u8_t *)p->payload)[j++] = id; /* Set packet identifier */  if(q == NULL) {    ((u16_t *)p->payload)[j/2] = htons(PPP_CPHDR_LEN); /* Set length of control packet */    j+= 2;  } else {    ((u16_t *)p->payload)[j/2] = htons(q->tot_len + PPP_CPHDR_LEN); /* Set length of control packet */    j+= 2;    pbuf_chain(p, q);    pbuf_free(q);  }  r = pbuf_alloc(PBUF_RAW, 2, PBUF_RAM); /* Alloc a pbuf for fcs */  /* Add FCS to packet */  fcs =  fcs16_crc_calc(p, p->tot_len);  ((u8_t *)r->payload)[0]  = (fcs & 0xFF); /* Least significant byte first */  ((u8_t *)r->payload)[1] = ((fcs >> 8) & 0xFF);  pbuf_chain(p, r);  pbuf_free(r);  ret = ppp_output(pcb, p);  /* Check if a timer should be associated with the request */  if(ret == ERR_OK && (code == LCP_CFG_REQ || code == IPCP_CFG_REQ ||      code == LCP_TERM_REQ || code == IPCP_TERM_REQ)) {    /* Check if the request already is in the outstanding requests list */    for(req = pcb->reqs; req != NULL; req = req->next) {      if(req->id == id) {	break;      }    }    if(req == NULL) {      /* Add request to outstanding requests list */      LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_cp_output: Allocate memory for request with ID 0x%x Code 0x%x***********\n", id, code));      if((req = lwbt_memp_malloc(MEMP_PPP_REQ)) == NULL) {	LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_cp_output: could not allocate memory for request\n"));	pbuf_free(p); /* Dealloc control packet */	return ERR_MEM;      }      req->p = p;      req->id = id;      req->proto = proto;      if((req->rto = (PPP_RTO/(PPP_NRTX + 1))) == 0) {	req->rto = 1;      }      req->nrtx = PPP_NRTX;      PPP_REQ_REG(&(pcb->reqs), req);    }  } else {    pbuf_free(p); /* Free control packet */  }  return ret;}/*-----------------------------------------------------------------------------------*//*  * ppp_netif_output(): * * Output IP data from a lwIP network interface over PPP. *//*-----------------------------------------------------------------------------------*/err_tppp_netif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr){  struct ppp_pcb *pcb;  /*  struct pbuf *q;  u16_t i;    for(q = p; q != NULL; q = q->next) {     for(i = 0; i < q->len; ++i) {      LWIP_DEBUGF(TCP_DEBUG, ("Out: 0x%x\n", ((u8_t *)q->payload)[i]));    }    LWIP_DEBUGF(TCP_DEBUG, ("\n"));  }  */  for(pcb = ppp_active_pcbs; pcb != NULL; pcb = pcb->next) {    if(pcb->bluetoothif == netif) {      break;    }  }  if(pcb != NULL) {    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_netif_output: Local IP address: %d.%d.%d.%d\n", (u8_t)(ntohl(pcb->bluetoothif->ip_addr.addr) >> 24) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->ip_addr.addr) >> 16) & 0xff, (u8_t)(ntohl(pcb->bluetoothif->ip_addr.addr) >> 8) & 0xff, (u8_t)ntohl(pcb->bluetoothif->ip_addr.addr) & 0xff));    return ppp_data_output(pcb, p);  }  return ERR_CONN; /* No matching PPP connection exists */}/*-----------------------------------------------------------------------------------*//*  * ppp_data_output(): * * Output IP data over PPP. *//*-----------------------------------------------------------------------------------*/err_tppp_data_output(struct ppp_pcb *pcb, struct pbuf *q){  struct pbuf *r, *p;  u8_t hdrlen = PPP_HDR_LEN;  u8_t i = 0;  err_t ret;  u16_t fcs;    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_data_output: q->tot_len = %d\n", q->tot_len));  if(pcb == NULL) {    return ERR_CONN; /* Not connected */  }  if(pcb->state != PPP_IPCP_OPEN) {    return ERR_CONN; /* Not connected */  }  if(pcb->lcpcfg & LCP_CFG_OUT_ACCOMP) {    hdrlen -= 2;  }  if(pcb->lcpcfg & LCP_CFG_OUT_PCOMP) {    --hdrlen;  }    p = pbuf_alloc(PBUF_RAW, hdrlen, PBUF_RAM);    if(!(pcb->lcpcfg & LCP_CFG_OUT_ACCOMP)) {    *((u16_t *)p->payload) = htons(PPP_ADDRCTRL);    i += 2;  }  if(pcb->lcpcfg & LCP_CFG_OUT_PCOMP) {    ((u8_t *)p->payload)[i] = PPP_IP_DATA;  } else {    ((u16_t *)p->payload)[i/2] = htons(PPP_IP_DATA); //TODO: WE MAY DIVIDE BY ZERO HERE...  }  /* Chain any information data to header */  if(q != NULL) {    pbuf_chain(p, q);    //pbuf_free(q);  }  r = pbuf_alloc(PBUF_RAW, 2, PBUF_RAM); /* Alloc a pbuf for fcs */  /* Add FCS to packet */  fcs =  fcs16_crc_calc(p, p->tot_len);  ((u8_t *)r->payload)[0]  = (fcs & 0x00ff); /* Least significant byte first */  ((u8_t *)r->payload)[1] = ((fcs >> 8) & 0x00ff);  pbuf_chain(p, r);  pbuf_free(r);  ret = ppp_output(pcb, p);  /* Free PPP header. Higher layers will handle rest of packet */  if(q != NULL) {    pbuf_dechain(p);    pbuf_realloc(q, q->tot_len-2); /* Remove FCS from packet */  }  pbuf_free(p);  return ret;}/*-----------------------------------------------------------------------------------*//*  * ppp_output_alloc(): * * Called by ppp_output() to allocate a pbuf with the same size as the remaining * characters in the packet to be byte stuffed. *//*-----------------------------------------------------------------------------------*/struct pbuf *ppp_output_alloc(struct pbuf *p, u16_t i){  struct pbuf *q;  u16_t k = 0;    /* Get length of remaining characters in packet */  for(q = p; q != NULL; q = q->next) {    k += q->len;   }  k -= i;  q = pbuf_alloc(PBUF_RAW, k, PBUF_RAM); /* Alloc a pbuf for that size */  return q;}/*-----------------------------------------------------------------------------------*//*  * ppp_output(): * * Output PPP data. Byte stuffs the packet and forward it to RFCOMM. *//*-----------------------------------------------------------------------------------*/err_tppp_output(struct ppp_pcb *pcb, struct pbuf *p) {  struct pbuf *q, *r, *s;  u16_t i;  u16_t j = 0;  u8_t c;  err_t ret;  /* To minimize the number of pbufs we need to chain together we always allocate the same size as the     number of characters remaining to be checked */  r = pbuf_alloc(PBUF_RAW, p->tot_len + 1, PBUF_RAM);  s = r;  ((u8_t *)s->payload)[j++] = PPP_END;    for(q = p; q != NULL; q = q->next) {    for(i = 0; i < q->len; ++i) {      c = ((u8_t *)q->payload)[i];      if(j == s->len) {	s = ppp_output_alloc(q, i);	pbuf_chain(r, s);	pbuf_free(s);	j = 0;      }      switch(c) {      case PPP_END:	((u8_t *)s->payload)[j++] = PPP_ESC;	if(j == s->len) {	  s = ppp_output_alloc(q, i);	  pbuf_chain(r, s);	  pbuf_free(s);	  j = 0;	}	((u8_t *)s->payload)[j++] = PPP_ESC_END;	break;      case PPP_ESC:	((u8_t *)s->payload)[j++] = PPP_ESC;	if(j == s->len) {	  s = ppp_output_alloc(q, i);	  pbuf_chain(r, s);	  pbuf_free(s);	  j = 0;	}	((u8_t *)s->payload)[j++] = PPP_ESC_ESC;	break;      default:	/* Check if the character should be escaped according to the ACCM */	if(c < 0x20) {	  if(pcb->outaccm & (1 << c) || pcb->state == PPP_LCP_CFG) {	    ((u8_t *)s->payload)[j++] = PPP_ESC;	    if(j == s->len) {	      s = ppp_output_alloc(q, i);	      pbuf_chain(r, s);	      pbuf_free(s);	      j = 0;	    }	    ((u8_t *)s->payload)[j++] = c ^ 0x20; /* Character following escape character is 						     exclusive-ord with 0x20 */	  } else {	    ((u8_t *)s->payload)[j++] = c;	  }	} else {	  ((u8_t *)s->payload)[j++] = c;	}	break;      }    }  }  s = pbuf_alloc(PBUF_RAW, 1, PBUF_RAM); /* Alloc a pbuf for PPP_END */  *((u8_t *)s->payload) = PPP_END;  pbuf_chain(r, s);  pbuf_free(s);    LWIP_DEBUGF(LWBT_PPP_DEBUG, ("ppp_output: r->tot_len = %d\n", r->tot_len));  /*  for(s = r; s != NULL; s = s->next) {    //u8_t i;    for(i = 0; i < s->len; ++i) {      LWIP_DEBUGF(SDP_DEBUG, ("ppp_output: REQ 0x%x\n", ((u8_t *)s->payload)[i]));    }    LWIP_DEBUGF(SDP_DEBUG, ("ppp_output: STOP\n"));  }  */  /* Check which convergence layer is in use */  if(rfcomm_cl(pcb->rfcommpcb)) {    ret = rfcomm_uih_credits(pcb->rfcommpcb, PBUF_POOL_SIZE - rfcomm_remote_credits(pcb->rfcommpcb), r);  } else {    ret = rfcomm_uih(pcb->rfcommpcb, rfcomm_cn(pcb->rfcommpcb), r);  }  pbuf_free(r); /* Free byte stuffed copy of outgoing packet */  return ret;}/*-----------------------------------------------------------------------------------*//*  * ppp_next_id(): * * Return a new control protocol identifier. Aids in matching requests and replies. *//*-----------------------------------------------------------------------------------*/u8_tppp_next_id(void){  return ++id_nxt;}/*-----------------------------------------------------------------------------------*//*  * ppp_disconnected(): * * Used to specify the function that should be called when a PPP connection is  * disconnected *//*-----------------------------------------------------------------------------------*/voidppp_disconnected(struct ppp_pcb *pcb, err_t (* disconnected)(void *arg, 							     struct ppp_pcb *pcb,							     u16_t proto,							     err_t err)){  pcb->disconnected = disconnected;}/*-----------------------------------------------------------------------------------*//*  * ppp_listen(): * * Set the state of the connection to be PPP_LCP_LISTEN, which means that it is able  * to accept incoming connections. *//*---------------------------

⌨️ 快捷键说明

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