📄 bt_ip_lap.c
字号:
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 + -