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

📄 bt_ip_lap.c

📁 蓝牙协议源代码 bluetooth stack for lwip
💻 C
📖 第 1 页 / 共 3 页
字号:
    LWIP_DEBUGF(BT_IP_DEBUG, ("modem_emu: !strncasecmp(data, \"CLIENT\", 6)\n"));
    q = pbuf_alloc(PBUF_RAW, sizeof("CLIENTSERVER\r\n"), PBUF_RAM);
    ((u8_t *)q->payload) = "CLIENTSERVER\r\n";
    pbuf_free(p);
  } else if(data[p->len - 1] != 0x0D) {
    LWIP_DEBUGF(BT_IP_DEBUG, ("modem_emu: data[p->len - 1] != 0x0D\n"));
    rfcomm_arg(pcb, p);
    return ERR_OK;
  } else {
    LWIP_DEBUGF(BT_IP_DEBUG, ("modem_emu: Unknown. Sending OK\n"));
    q = pbuf_alloc(PBUF_RAW, sizeof("OK\r\n"), PBUF_RAM);
    ((u8_t *)q->payload) = "OK\r\n";
    pbuf_free(p);
  }

  if(rfcomm_cl(pcb)) {
    rfcomm_uih_credits(pcb, PBUF_POOL_SIZE - rfcomm_remote_credits(pcb), q);
  } else {
    rfcomm_uih(pcb, rfcomm_cn(pcb), q);
  }
  pbuf_free(q);

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
err_t
rfcomm_accept(void *arg, struct rfcomm_pcb *pcb, err_t err) 
{
  struct ppp_pcb *ppppcb;
  struct netif *netif;

  LWIP_DEBUGF(BT_IP_DEBUG, ("rfcomm_accept: CN = %d\n", rfcomm_cn(pcb)));
  
  rfcomm_disc(pcb, rfcomm_disconnected);
  if(pcb->cn != 0) {
    if((ppppcb = ppp_new(pcb)) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("rfcomm_accept: Could not allocate a PPP PCB\n"));
      return ERR_MEM;
    }
    ppp_disconnected(ppppcb, ppp_is_disconnected);
    ppp_listen(ppppcb, ppp_accept);

    netif = nat_netif_add(NULL, bluetoothif_init);
    ppp_netif(ppppcb, netif); 

    rfcomm_recv(pcb, modem_emu);
  }
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
static err_t
bt_disconnect_ind(void *arg, struct l2cap_pcb *pcb, err_t err)
{
  err_t ret;

  LWIP_DEBUGF(BT_IP_DEBUG, ("bt_disconnect_ind\n"));

  if(pcb->psm == SDP_PSM) { 
    sdp_lp_disconnected(pcb);
  } else if(pcb->psm == RFCOMM_PSM) {
    ret = rfcomm_lp_disconnected(pcb);
  }

  l2cap_close(pcb);
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
err_t
bt_connect_ind(void *arg, struct l2cap_pcb *pcb, err_t err)
{
  LWIP_DEBUGF(BT_IP_DEBUG, ("bt_connect_ind\n"));

  /* Tell L2CAP that we wish to be informed of a disconnection request */
  l2cap_disconnect_ind(pcb, bt_disconnect_ind);

  /* Tell L2CAP that we wish to be informed of incoming data */
  if(pcb->psm == SDP_PSM) {
    l2cap_recv(pcb, sdp_recv);
  } else if (pcb->psm == RFCOMM_PSM) {
    l2cap_recv(pcb, rfcomm_input);
  }
  return ERR_OK;  
}
/*-----------------------------------------------------------------------------------*/
err_t
lap_init(void)
{
  struct l2cap_pcb *l2cappcb;
  struct rfcomm_pcb *rfcommpcb;
  struct sdp_record *record;

  if((l2cappcb = l2cap_new()) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("lap_init: Could not alloc L2CAP PCB for SDP_PSM\n"));
      return ERR_MEM;
  }
  l2cap_connect_ind(l2cappcb, SDP_PSM, bt_connect_ind);
  
  if((l2cappcb = l2cap_new()) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("lap_init: Could not alloc L2CAP PCB for RFCOMM_PSM\n"));
      return ERR_MEM;
  }
  l2cap_connect_ind(l2cappcb, RFCOMM_PSM, bt_connect_ind);

  LWIP_DEBUGF(RFCOMM_DEBUG, ("lap_init: Allocate RFCOMM PCB for CN 0******************************\n"));
  if((rfcommpcb = rfcomm_new(NULL)) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("lap_init: Could not alloc RFCOMM PCB for channel 0\n"));
      return ERR_MEM;
  }
  rfcomm_listen(rfcommpcb, 0, rfcomm_accept);

  LWIP_DEBUGF(RFCOMM_DEBUG, ("lap_init: Allocate RFCOMM PCB for CN 1******************************\n"));
  if((rfcommpcb = rfcomm_new(NULL)) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("lap_init: Could not alloc RFCOMM PCB for channel 1\n"));
      return ERR_MEM;
  }
  rfcomm_listen(rfcommpcb, 1, rfcomm_accept);

  if((record = sdp_record_new((u8_t *)lap_service_record, sizeof(lap_service_record))) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("lap_init: Could not alloc SDP record\n"));
      //return ERR_MEM;
  } else {
    sdp_register_service(record);
  }

  LWIP_DEBUGF(BT_IP_DEBUG, ("LAP initialized\n"));
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * ppp_connected():
 *
 * Called by PPP when a LCP and IPCP connection has been established.
 * Connects to a given TCP host.
 *
 */
/*-----------------------------------------------------------------------------------*/
err_t
ppp_connected(void *arg, struct ppp_pcb *pcb, err_t err)
{
  struct tcp_pcb *tcppcb;
  struct ip_addr ipaddr;
  err_t ret;
  u8_t flag = 0x03;

  LWIP_DEBUGF(BT_IP_DEBUG, ("ppp_connected: err = %d\n", err));
  
  /* return ppp_echo(pcb, NULL); */

  if(err != ERR_OK) {
    netif_remove(pcb->bluetoothif);
    pcb->bluetoothif = NULL;
    //TODO: RESTART??
    return ERR_OK;
  }

  //pcb->bluetoothif->netmask.addr = htonl(~(ntohl(pcb->bluetoothif->gw.addr) ^ ntohl(pcb->bluetoothif->ip_addr.addr)));

  nat_init(pcb->bluetoothif, ip_input); /* Set function to be called by NAT to pass a packet up to the TCP/IP 
					   stack */

  ret = lap_init(); /* Initialize the LAP role */
  
  //if(bt_ip_state.profile == DUN_PROFILE) {
    /* Make LAP discoverable */
    hci_cmd_complete(command_complete);
    hci_set_event_filter(0x02, 0x00, &flag); /* Auto accept all connections with role switch enabled */
  //} 

  //tcppcb = tcp_new();
  //IP4_ADDR(&ipaddr, 130,240,45,234);
 
  //tcp_connect(tcppcb, &ipaddr, 8989, tcp_connected);
  
  return ret;
}
/*-----------------------------------------------------------------------------------*/
/*
 * at_input():
 *
 * Called by RFCOMM during the DUN profile GPRS connection attempt.
 * When a GPRS connection is established, PPP is connected.
 *
 */
/*-----------------------------------------------------------------------------------*/
u8_t at_state;
err_t
at_input(void *arg, struct rfcomm_pcb *pcb, struct pbuf *p, err_t err) 
{
  struct ppp_pcb *ppppcb;
  struct ip_addr ipaddr, netmask, gw;
  struct netif *netif;;
  
  //  u16_t i;
  struct pbuf *q;
  
  //for(q = p; q != NULL; q = q->next) {
  //  for(i = 0; i < q->len; ++i) {
  //    LWIP_DEBUGF(BT_IP_DEBUG, ("at_input: 0x%x\n",((u8_t *)p->payload)[i]));
  //  }
  //  LWIP_DEBUGF(BT_IP_DEBUG, ("*\n"));
  //}
  
  LWIP_DEBUGF(BT_IP_DEBUG, ("at_input: %s\n", ((u8_t *)p->payload)));
  LWIP_DEBUGF(BT_IP_DEBUG, ("state == %d\n", at_state));
  if(at_state == 0 && ((u8_t *)p->payload)[2] == 'O') {
    //q = pbuf_alloc(PBUF_RAW, sizeof("AT&F\r")-1, PBUF_RAM);
    //((u8_t *)q->payload) = "AT&F\r";
    q = pbuf_alloc(PBUF_RAW, sizeof("ATE1\r"), PBUF_RAM);
    ((u8_t *)q->payload) = "ATE1\r";
    if(rfcomm_cl(pcb)) {
      rfcomm_uih_credits(pcb, 2, q);
    } else {
      rfcomm_uih(pcb, rfcomm_cn(pcb), q);
    }
    pbuf_free(q);
    
    at_state = 1;
  } else if(at_state == 1 && ((u8_t *)p->payload)[2] == 'O') {
    q = pbuf_alloc(PBUF_RAW, sizeof("AT+cgdcont=1,\"IP\",\"online.telia.se\"\r"), PBUF_RAM);
    ((u8_t *)q->payload) = "AT+cgdcont=1,\"IP\",\"online.telia.se\"\r";
    if(rfcomm_cl(pcb)) {
      rfcomm_uih_credits(pcb, 2, q);
    } else {
      rfcomm_uih(pcb, rfcomm_cn(pcb), q);
    }
    pbuf_free(q);
   
    at_state = 4;
  } else if(at_state == 4 && ((u8_t *)p->payload)[2] == 'O') {
    q = pbuf_alloc(PBUF_RAW, sizeof("ATD*99***1#\r"), PBUF_RAM);
    ((u8_t *)q->payload) = "ATD*99***1#\r";
    if(rfcomm_cl(pcb)) {
      rfcomm_uih_credits(pcb, 2, q);
    } else {
      rfcomm_uih(pcb, rfcomm_cn(pcb), q);
    }
    pbuf_free(q);
  
    at_state = 5;
  } else if(at_state == 5 && ((u8_t *)p->payload)[2] == 'C') {
    at_state = 6;
    /* Establish a PPP connection */
    if((ppppcb = ppp_new(pcb)) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("rfcomm_msc_rsp: Could not alloc PPP pcb\n"));
      return ERR_MEM;
    }
    /* Add PPP network interface to lwIP and initialize NAT */
    gw.addr = 0;
    ipaddr.addr = 0;
    IP4_ADDR(&netmask, 255,255,255,0);
    
    netif = netif_add(&ipaddr, &netmask, &gw, NULL, bluetoothif_init, nat_input);
    
    netif_set_default(netif);
    
    ppp_netif(ppppcb, netif);

    rfcomm_recv(pcb, ppp_input);
    ppp_disconnected(ppppcb, ppp_is_disconnected);
    return ppp_connect(ppppcb, ppp_connected);
  }
  pbuf_free(p);

  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * pin_req():
 *
 * Called by HCI when a request for a PIN code has been received. A PIN code is 
 * required to create a new link key.
 * Replys to the request with the given PIN code
 *
 */
/*-----------------------------------------------------------------------------------*/
err_t 
pin_req(void *arg, struct bd_addr *bdaddr)
{
  LWIP_DEBUGF(BT_IP_DEBUG, ("pin_req\n"));
  return hci_pin_code_request_reply(bdaddr, 4, "1234");
}
/*-----------------------------------------------------------------------------------*/
/*
* link_key_not():
 *
 * Called by HCI when a new link key has been created for the connection
 * Writes the key to the Bluetooth host controller, where it can be stored for future
 * connection attempts.
  *
*/
/*-----------------------------------------------------------------------------------*/
err_t 
link_key_not(void *arg, struct bd_addr *bdaddr, u8_t *key)
{
  LWIP_DEBUGF(BT_IP_DEBUG, ("link_key_not\n"));
  return hci_write_stored_link_key(bdaddr, key); /* Write link key to be stored in the
                                                    Bluetooth host controller */
}
/*-----------------------------------------------------------------------------------*/
/*
 * l2cap_disconnected_cfm():
 *
 * Called by L2CAP to confirm that the L2CAP disconnection request was successful
 *
 */
/*-----------------------------------------------------------------------------------*/
err_t
l2cap_disconnected_cfm(void *arg, struct l2cap_pcb *pcb) 
{
  LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_disconnected_cfm\n"));
  l2cap_close(pcb);
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * get_rfcomm_cn():
 *
 * Parse the RFCOMM channel number from an SDP attribute list
 *
*/
/*-----------------------------------------------------------------------------------*/
u8_t
get_rfcomm_cn(u16_t attribl_bc, struct pbuf *attribute_list)
{
  u8_t i;
  for(i = 0; i < attribl_bc; i++) {
    if(((u8_t *)attribute_list->payload)[i] == (SDP_DE_TYPE_UUID | SDP_DE_SIZE_16)) {
      if(ntohs(*((u16_t *)(((u8_t *)attribute_list->payload)+i+1))) == 0x0003) {
	return *(((u8_t *)attribute_list->payload)+i+4);
      }
    }
  }
  return 0;
}
/*-----------------------------------------------------------------------------------*/
/*
 * rfcomm_connected():
 *
 * Called by RFCOMM when a connection attempt response was received.
 * Creates a RFCOMM connection for the channel retreived from SDP.
 * Initializes a search for other devices if the connection attempt failed.
 */
/*-----------------------------------------------------------------------------------*/
err_t
rfcomm_connected(void *arg, struct rfcomm_pcb *pcb, err_t err) 
{
  struct pbuf *p;
  struct ip_addr ipaddr, netmask, gw;
  struct netif *netif;
  struct ppp_pcb *ppppcb;

  if(err == ERR_OK) {
    LWIP_DEBUGF(BT_IP_DEBUG, ("rfcomm_connected. CN = %d\n", rfcomm_cn(pcb)));
    rfcomm_disc(pcb, rfcomm_disconnected);

    if(bt_ip_state.profile == DUN_PROFILE) {
      /* Establish a GPRS connection */
      LWIP_DEBUGF(BT_IP_DEBUG, ("rfcomm_msc_rsp: Establish a GPRS connection\n"));
      rfcomm_recv(pcb, at_input);

⌨️ 快捷键说明

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