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

📄 bt_ip_lap.c

📁 蓝牙协议源代码 bluetooth stack for lwip
💻 C
📖 第 1 页 / 共 3 页
字号:
      //p = pbuf_alloc(PBUF_RAW, sizeof("ATZ\r")-1, PBUF_RAM);
      //((u8_t *)p->payload) = "ATZ\r";
      p = pbuf_alloc(PBUF_RAW, sizeof("AT\r"), PBUF_RAM);
      ((u8_t *)p->payload) = "AT\r";
      at_state = 0;
      if(rfcomm_cl(pcb)) {
	rfcomm_uih_credits(pcb, 6,  p);
      } else {
	rfcomm_uih(pcb, rfcomm_cn(pcb), p);
      }
      pbuf_free(p);
    } else {
      /* 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);
    }
  } else {
    LWIP_DEBUGF(BT_IP_DEBUG, ("rfcomm_connected. Connection attempt failed CN = %d\n", rfcomm_cn(pcb)));
    l2cap_close(pcb->l2cappcb);
    rfcomm_close(pcb);
    bt_ip_start();
  }
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * sdp_attributes_recv():
 *
 * Can be used as a callback by SDP when a response to a service attribute request or 
 * a service search attribute request was received.
 * Disconnects the L2CAP SDP channel and connects to the RFCOMM one.
 * If no RFCOMM channel was found it initializes a search for other devices.
 */
/*-----------------------------------------------------------------------------------*/
void
sdp_attributes_recv(void *arg, struct sdp_pcb *sdppcb, u16_t attribl_bc, struct pbuf *p)
{
  struct l2cap_pcb *l2cappcb;

  l2ca_disconnect_req(sdppcb->l2cappcb, l2cap_disconnected_cfm);
  /* Get the RFCOMM channel identifier from the protocol descriptor list */
  if((bt_ip_state.cn = get_rfcomm_cn(attribl_bc, p)) != 0) {
    if((l2cappcb = l2cap_new()) == NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("sdp_attributes_recv: Could not alloc L2CAP pcb\n"));
      return;
    }
    LWIP_DEBUGF(BT_IP_DEBUG, ("sdp_attributes_recv: RFCOMM channel: %d\n", bt_ip_state.cn));
    if(bt_ip_state.profile == DUN_PROFILE) {
      l2ca_connect_req(l2cappcb, &(sdppcb->l2cappcb->remote_bdaddr), RFCOMM_PSM, 0, l2cap_connected);
    } else {
      l2ca_connect_req(l2cappcb, &(sdppcb->l2cappcb->remote_bdaddr), RFCOMM_PSM, HCI_ALLOW_ROLE_SWITCH, l2cap_connected);
    }
    
  } else {
    bt_ip_start();
  }
  sdp_free(sdppcb);
}
/*-----------------------------------------------------------------------------------*/
/*
 * l2cap_connected():
 *
 * Called by L2CAP when a connection response was received.
 * Sends a L2CAP configuration request.
 * Initializes a search for other devices if the connection attempt failed.
 */
/*-----------------------------------------------------------------------------------*/
err_t
l2cap_connected(void *arg, struct l2cap_pcb *l2cappcb, u16_t result, u16_t status)
{
  struct sdp_pcb *sdppcb;
  struct rfcomm_pcb *rfcommpcb;

  u8_t ssp[] = {0x35, 0x03, 0x19, 0x11, 0x02}; /* Service search pattern with LAP UUID is default */ 
  err_t ret;

  u8_t attrids[] = {0x35, 0x03, 0x09, 0x00, 0x04}; /* Attribute IDs to search for in data element 
						      sequence form */

  if(result == L2CAP_CONN_SUCCESS) {
    LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: L2CAP connected pcb->state = %d\n", l2cappcb->state));
    /* Tell L2CAP that we wish to be informed of a disconnection request */
    l2cap_disconnect_ind(l2cappcb, l2cap_disconnected_ind);
    switch(l2cap_psm(l2cappcb)) {
    case SDP_PSM:
      LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: SDP L2CAP configured. Result = %d\n", result));
      if(bt_ip_state.profile == DUN_PROFILE) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: Using DUN profile\n"));
	ssp[4] = 0x03; /* Change service search pattern to contain DUN UUID */
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: Using LAP profile\n"));
      }
      
      if((sdppcb = sdp_new(l2cappcb)) == NULL) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: Failed to create a SDP PCB\n"));
	return ERR_MEM;
      }
      
      l2cap_recv(l2cappcb, sdp_recv);
      
      ret = sdp_service_search_attrib_req(sdppcb, 0xFFFF, ssp, sizeof(ssp), attrids, sizeof(attrids),
					  sdp_attributes_recv);
      return ret;
    case RFCOMM_PSM:
      LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: RFCOMM L2CAP configured. Result = %d CN = %d\n", result, bt_ip_state.cn));
      l2cap_recv(l2cappcb, rfcomm_input);

      if((rfcommpcb = rfcomm_new(l2cappcb)) == NULL) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: Failed to create a RFCOMM PCB\n"));
	return ERR_MEM;
      }

      hci_link_key_not(link_key_not); /* Set function to be called if a new link key is created */

      return rfcomm_connect(rfcommpcb, bt_ip_state.cn, rfcomm_connected); /* Connect with DLCI 0 */
    default:
      return ERR_VAL;
    }
  } else {
    LWIP_DEBUGF(BT_IP_DEBUG, ("l2cap_connected: L2CAP not connected. Redo inquiry\n"));
    l2cap_close(l2cappcb);
    bt_ip_start();
  }
  
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * inquiry_complete():
 *
 * Called by HCI when a inquiry complete event was received.
 * Connects to the first device in the list.
 * Initializes a search for other devices if the inquiry failed.
 */
/*-----------------------------------------------------------------------------------*/
err_t
inquiry_complete(void *arg, struct hci_pcb *pcb, struct hci_inq_res *ires, u16_t result)
{
  struct l2cap_pcb *l2cappcb;

  if(result == HCI_SUCCESS) {
    LWIP_DEBUGF(BT_IP_DEBUG, ("successful Inquiry\n"));
    if(ires != NULL) {
      LWIP_DEBUGF(BT_IP_DEBUG, ("Initiate L2CAP connection\n"));
      LWIP_DEBUGF(BT_IP_DEBUG, ("ires->psrm %d\n ires->psm %d\n ires->co %d\n", ires->psrm, ires->psm, ires->co));
      LWIP_DEBUGF(BT_IP_DEBUG, ("ires->bdaddr 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ires->bdaddr.addr[5], ires->bdaddr.addr[4], ires->bdaddr.addr[3], ires->bdaddr.addr[2], ires->bdaddr.addr[1], ires->bdaddr.addr[0]));

      if((ires->cod[1] & 0x1F) == 0x03) {
	bt_ip_state.profile = LAP_PROFILE;
      } else {
	bt_ip_state.profile = DUN_PROFILE;
      }
      
      if((l2cappcb = l2cap_new()) == NULL) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("inquiry_complete: Could not alloc L2CAP pcb\n"));
	return ERR_MEM;
      } 

      if(bt_ip_state.profile == DUN_PROFILE) {
        l2ca_connect_req(l2cappcb, &(ires->bdaddr), SDP_PSM, 0, l2cap_connected);
      } else {
	l2ca_connect_req(l2cappcb, &(ires->bdaddr), SDP_PSM, HCI_ALLOW_ROLE_SWITCH, l2cap_connected);
      }
    } else {
      hci_inquiry(0x009E8B33, 0x04, 0x01, inquiry_complete);
    }
  } else {
    LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful Inquiry.\n"));
    hci_inquiry(0x009E8B33, 0x04, 0x01, inquiry_complete);
  }
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * acl_wpl_complete():
 *
 * Called by HCI when a successful write link policy settings complete event was
 * received.
 */
/*-----------------------------------------------------------------------------------*/
err_t
acl_wpl_complete(void *arg, struct bd_addr *bdaddr)
{
  hci_sniff_mode(bdaddr, 200, 100, 10, 10);
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * acl_conn_complete():
 *
 * Called by HCI when a connection complete event was received.
 */
/*-----------------------------------------------------------------------------------*/
err_t
acl_conn_complete(void *arg, struct bd_addr *bdaddr)
{
  //hci_wlp_complete(acl_wpl_complete);
  //hci_write_link_policy_settings(bdaddr, 0x000F);
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * read_bdaddr_complete():
 *
 * Called by HCI when a read local bluetooth device address complete event was received.
 */
/*-----------------------------------------------------------------------------------*/
err_t
read_bdaddr_complete(void *arg, struct bd_addr *bdaddr)
{
  memcpy(&(bt_ip_state.bdaddr), bdaddr, 6);
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/*
 * command_complete():
 *
 * Called by HCI when an issued command has completed during the initialization of the
 * host controller.
 * Initializes a search for other devices when host controller initialization is
 * completed.
 */
/*-----------------------------------------------------------------------------------*/
err_t
command_complete(void *arg, struct hci_pcb *pcb, u8_t ogf, u8_t ocf, u8_t result)
{
  u8_t cod_lap_dun[] = {0x00,0x02,0x00,0x00,0x1E,0x00};
  u8_t cod_lap[] = {0x00,0x03,0x00};
  u8_t devname[] = {'E','I','S','L','A','B',' ','0','0','0',0};
  u8_t n1, n2, n3;
    
  switch(ogf) {
  case HCI_INFO_PARAM:
    switch(ocf) {
    case HCI_READ_BUFFER_SIZE:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("successful HCI_READ_BUFFER_SIZE.\n"));
	hci_read_bd_addr(read_bdaddr_complete);
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_READ_BUFFER_SIZE.\n"));
	return ERR_CONN;
      }
      break;
    case HCI_READ_BD_ADDR:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("successful HCI_READ_BD_ADDR.\n"));
	hci_set_event_filter(0x01, 0x01, cod_lap_dun); /* Report only devices with a specific type of CoD */
	
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_READ_BD_ADDR.\n"));
	return ERR_CONN;
      }
      break;
    default:
      LWIP_DEBUGF(BT_IP_DEBUG, ("Unknown HCI_INFO_PARAM command complete event\n"));
      break;
    }
    break;
  case HCI_HC_BB_OGF:
    switch(ocf) {
    case HCI_RESET:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("successful HCI_RESET.\n")); 
	hci_read_buffer_size();
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_RESET.\n"));
	return ERR_CONN;
      }
      break;
    case HCI_WRITE_SCAN_ENABLE:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("successful HCI_WRITE_SCAN_ENABLE.\n")); 
	hci_cmd_complete(NULL); /* Initialization done, don't come back */
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_WRITE_SCAN_ENABLE.\n"));
	return ERR_CONN;
      }
      break;
    case HCI_SET_EVENT_FILTER:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("successful HCI_SET_EVENT_FILTER.\n"));
	if(bt_ip_state.btctrl == 0) {
	  hci_write_cod(cod_lap); /*  */
	  bt_ip_state.btctrl = 1;
	} else {
	  hci_write_scan_enable(0x03); /* Inquiry and page scan enabled */
	}
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_SET_EVENT_FILTER.\n"));
	return ERR_CONN;
      }
      break;
    case HCI_CHANGE_LOCAL_NAME:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Successful HCI_CHANGE_LOCAL_NAME.\n"));
	hci_write_page_timeout(0x4000); /* 10.24s */
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_CHANGE_LOCAL_NAME.\n"));
	return ERR_CONN;
      }
      break;
    case HCI_WRITE_COD:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Successful HCI_WRITE_COD.\n"));
	n1 = (u8_t)(bt_ip_state.bdaddr.addr[0] / 100);
	n2 = (u8_t)(bt_ip_state.bdaddr.addr[0] / 10) - n1 * 10;
	n3 = bt_ip_state.bdaddr.addr[0] - n1 * 100 - n2 * 10;
	devname[7] = '0' + n1;
	devname[8] = '0' + n2;
	devname[9] = '0' + n3;
	hci_change_local_name(devname, sizeof(devname));
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_WRITE_COD.\n"));
	return ERR_CONN;
      }
      break;
    case HCI_WRITE_PAGE_TIMEOUT:
      if(result == HCI_SUCCESS) {
	LWIP_DEBUGF(BT_IP_DEBUG, ("successful HCI_WRITE_PAGE_TIMEOUT.\n"));
	hci_cmd_complete(NULL); /* Initialization done, don't come back */
	hci_connection_complete(acl_conn_complete);
	LWIP_DEBUGF(BT_IP_DEBUG, ("Initialization done.\n"));
	LWIP_DEBUGF(BT_IP_DEBUG, ("Discover other Bluetooth devices.\n"));
	hci_inquiry(0x009E8B33, 0x04, 0x01, inquiry_complete); //FAILED????
      } else {
	LWIP_DEBUGF(BT_IP_DEBUG, ("Unsuccessful HCI_WRITE_PAGE_TIMEOUT.\n"));
	return ERR_CONN;
      }
      break;
    default:
      LWIP_DEBUGF(BT_IP_DEBUG, ("Unknown HCI_HC_BB_OGF command complete event\n"));
      break;
    }
    break;
  default:
    LWIP_DEBUGF(BT_IP_DEBUG, ("Unknown command complete event. OGF = 0x%x OCF = 0x%x\n", ogf, ocf));
    break;
  }
  return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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