From: David Plotek Date: Mon, 11 Aug 2008 21:17:34 +0000 (+0200) Subject: hcidriver.c:new non block cmd call. X-Git-Url: http://rtime.felk.cvut.cz/gitweb/tiny-bt.git/commitdiff_plain/42bcee64136eb5ba8863125c06ec6da9968c6d47 hcidriver.c:new non block cmd call. slavetest.c: next new event rutines. --- diff --git a/src/hcidriver.c b/src/hcidriver.c index 109e852..823a545 100644 --- a/src/hcidriver.c +++ b/src/hcidriver.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include "hcidriver.h" @@ -11,6 +13,7 @@ + /************************** hci command functions**************************/ int call_hci_inquiry_cmd(int dd, void *p_addressarray,__u16 *p_ocf_ogf){ inquiry_cp cmdp,*p_cmdp=&cmdp; @@ -102,6 +105,24 @@ int call_hci_create_connection_cmd(int dd, bt_address *p_address, __u16 *p_ocf_o } +int call_hci_accept_conn_req_cmd(int dd, bt_address *p_address, __u16 *p_ocf_ogf){ + accept_conn_req_cp cmdp, *p_cmdp=&cmdp; + hci_request req,*p_req=&req; + + p_cmdp->bdaddr=*p_address; + p_cmdp->role=0x01; + memset(p_req,0,sizeof(req)); + p_req->p_OCF_OGF=p_ocf_ogf; + p_req->p_cmdp=p_cmdp; + p_req->cmdp_len=ACCEPT_CONN_REQ_CP_SIZE; + + if(hci_send_command(dd,p_req)<0){ + printf("problem with command sending\n"); + return -1; + } + return 0; +} + /*******************************HCI main functions ********************************/ @@ -127,6 +148,34 @@ int hci_open_device(int dev_id){ return dd; } +int hci_open_device_nonblock(int dev_id){ + struct sockaddr_hci address; + int dd; + int oldflag; + + if((dd=socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI))<0){ + perror("socket no created"); + return dd; //it return -1 when socket isn't created + } + + oldflag=fcntl(dd, F_GETFL, 0); + if(fcntl(dd, F_SETFL, oldflag | O_NONBLOCK) < 0){ + printf("problem with socket flag setting"); + return -1; + } + + memset(&address,0,sizeof(address)); + address.hci_family=AF_BLUETOOTH; + address.hci_dev=dev_id; + if(bind(dd,(struct sockaddr *) &address, sizeof(address))<0){ + perror("Socket not binded to hci device"); + close(dd); + return -1; + } + + return dd; +} + int hci_close_dev(int dd){ return close(dd); } diff --git a/src/hcidriver.h b/src/hcidriver.h index 8002b68..ab287e2 100644 --- a/src/hcidriver.h +++ b/src/hcidriver.h @@ -85,7 +85,9 @@ extern int call_hci_inquiry_cmd(int dd, void *p_addressarray,__u16 *p_ocf_ogf); extern int call_hci_read_bd_addr_cmd(int dd,bt_address *p_address,__u16 *p_ocf_ogf); extern int call_hci_read_local_name_cmd(int dd, void *p_name,__u16 *p_ocf_ogf); extern int call_hci_create_connection_cmd(int dd, bt_address *p_address, __u16 *p_ocf_ogf); +extern int call_hci_accept_conn_req_cmd(int dd, bt_address *p_address, __u16 *p_ocf_ogf); extern int hci_open_device(int dev_id); +extern int hci_open_device_nonblock(int dev_id); extern int hci_send_command(int dd, hci_request *p_req); extern int hci_send_request(int dd, hci_request *p_req,int timeout); //extern void print_device_list(int ctl); @@ -97,6 +99,7 @@ extern void assemble_ocf_ogf(__u8 ogf,__u8 ocf,__u16 *p_ocf_ogf); extern __u16 swap_2_bytes(__u16 twobytes); extern __u8 swap8(__u8 byte1); extern __u16 swap16(__u16 byte2); +extern __u16 swap_2_bytes(__u16 twobytes); //extern void bacpy(bt_address p_dest, bt_address p_source); extern void fill_add(bt_address *addr,__u8 first, __u8 sec, __u8 third, __u8 forth, __u8 fifth, __u8 sixth); extern void printba(bt_address *ba); diff --git a/src/hil2cap.c b/src/hil2cap.c index f06184c..0897bcc 100644 --- a/src/hil2cap.c +++ b/src/hil2cap.c @@ -99,7 +99,7 @@ int show_all_remote_dev(struct hci_dev_info *p_master, bt_address *p_remadrar, i int l2cap_call_cmd(__u16 ocf_ogf,int dd, void *p_param){ cmd_state_request new_req,*p_new_req=&new_req; __u16 sw_opcode; - int remd_count; + int remd_count,ret_val; sw_opcode=swap_2_bytes(ocf_ogf); p_new_req->actual_status=ESTABLISHED; p_new_req->id=cmd_req_id++; @@ -162,10 +162,11 @@ int l2cap_call_cmd(__u16 ocf_ogf,int dd, void *p_param){ printf("Mistake with req array adding \n "); return -1; } - if((((connection_hci *)p_param)->handle=call_hci_create_connection_cmd(dd, &(((connection_hci *)p_param)->slave.bdaddr), &sw_opcode)) < 0){ + if((ret_val=call_hci_create_connection_cmd(dd, &(((connection_hci *)p_param)->slave.bdaddr), &sw_opcode)) < 0){ printf("Mistake with inquiry cmd \n "); return -1; } + ((connection_hci *)p_param)->handle=ret_val; ((connection_hci *)p_param)->con_state=CONNECTED; req_fcn_remove(); return 0; @@ -214,8 +215,8 @@ return (void*)0; int main(void){ struct hci_dev_info master,*p_master=&master; bt_address remote_bd_addr_array[HCI_MAX_DEV]; - memset(remote_bd_addr_array,0,(sizeof(bt_address)*HCI_MAX_DEV)); connection_hci connection,*p_connection=&connection; + memset(remote_bd_addr_array,0,(sizeof(bt_address)*HCI_MAX_DEV)); bt_address prefered; int remd_count,i; cmd_req_id=0; @@ -234,9 +235,9 @@ int main(void){ printba(&remote_bd_addr_array[i]); } p_connection->master=master; - //p_connection->slave.bdaddr=remote_bd_addr_array[0]; - fill_add(&prefered,0x31,0x16,0xCA,0x72,0x02,0x00); - p_connection->slave.bdaddr=prefered; + p_connection->slave.bdaddr=remote_bd_addr_array[0]; + //fill_add(&prefered,0x31,0x16,0xCA,0x72,0x02,0x00); + //p_connection->slave.bdaddr=prefered; if(create_master_connection(p_connection)<0){ printf("connection error"); return -1; diff --git a/src/hil2cap.h b/src/hil2cap.h index 826ab3e..b3375fd 100644 --- a/src/hil2cap.h +++ b/src/hil2cap.h @@ -32,6 +32,7 @@ #define INQUIRY_CMD_OP 0x0104 #define INQUIRY_CANCEL_CMD_OP 0x0204 #define CREATE_CONNECTION_CMD_OP 0x0504 +#define ACCEPT_CONNECTION_REQ 0x0904 #define DISCONNECT_CMD_OP 0x0604 #define REMOTE_NAME_REQUEST_CMD_OP 0x1904 #define RESET_CMD_OP 0x030C @@ -46,7 +47,7 @@ typedef struct{ __u8 actual_status; __u8 id; __u16 req_opcode; - __u16 evt_code;//codes of expected ansver event,command status event will be accepted everytime + __u8 evt_code;//codes of expected ansver event,command status event will be accepted everytime void (*p_serv_rutine)(void); } __attribute__((packed)) cmd_state_request; @@ -54,8 +55,8 @@ typedef struct{ typedef struct{ __u8 actual_status; __u16 id; - __u16 evt_code; - void (*p_serv_rutine)(void); + __u8 evt_code; + int (*p_serv_rutine)(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged); } __attribute__((packed)) incoming_evt; typedef struct{ @@ -63,7 +64,7 @@ typedef struct{ __u8 con_state; struct hci_dev_info master; struct hci_dev_info slave; - int handle; + uint16_t handle; int socket_fd; }connection_hci; diff --git a/testf/t2/slavetest.c b/testf/t2/slavetest.c index 612d501..207fa5b 100644 --- a/testf/t2/slavetest.c +++ b/testf/t2/slavetest.c @@ -20,11 +20,13 @@ #include #include "hcidriver.h" #include "hil2cap.h" +#include "slavetest.h" incoming_evt evt_array[MAX_CMD_STATE_REQUEST]; int evt_id; int global_index; struct hci_filter nnf, oof; // the oldest and newest filters +connection_hci connection,*p_connection=&connection; int factorial(int num){ @@ -32,31 +34,6 @@ int factorial(int num){ return num*factorial(num-1); } -int hci_open_device(int dev_id){ - struct sockaddr_hci address; - int dd; - - if((dd=socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI))<0){ - perror("socket no created"); - return dd; //it return -1 when socket isn't created - } - - memset(&address,0,sizeof(address)); - address.hci_family=AF_BLUETOOTH; - address.hci_dev=dev_id; - if(bind(dd,(struct sockaddr *) &address, sizeof(address))<0){ - perror("Socket not binded to hci device"); - close(dd); - return -1; - } - - return dd; -} - -int hci_close_dev(int dd){ - return close(dd); -} - int add_evt_toarray(incoming_evt *p_evt,struct hci_filter *p_pf,int *p_fchanged){ //fcn add the request at the end of array or replace the oldest request int i,sig=0,index=0; incoming_evt the_oldest=evt_array[0]; @@ -81,32 +58,146 @@ int add_evt_toarray(incoming_evt *p_evt,struct hci_filter *p_pf,int *p_fchanged) } } if(!sig){ - //return -1; + evt_array[index]=*p_evt; global_index=index; } return 0; } +int look_up_inarray(__u8 evt_code){ + int i,index=-1,oldestid=65535; + + if(evt_array[global_index].evt_code == evt_code && evt_array[global_index].actual_status != DONE){ + return global_index; + } + else{ + for(i=0;imaster.bdaddr=p_evt->bdaddr; + + p_new_evt->id=evt_id++; + p_new_evt->actual_status=ESTABLISHED; + p_new_evt->evt_code = EVT_CONN_COMPLETE; + p_new_evt->p_serv_rutine=&rutine_connection_complete; + add_evt_toarray(p_new_evt,p_pf,p_fchanged); + + sw_opcode=swap_2_bytes(ACCEPT_CONNECTION_REQ); + hci_filter_set_opcode(sw_opcode, &nnf); + if(*p_fchanged){ + if(setsockopt(dd, SOL_HCI, HCI_FILTER, &nnf, sizeof(nnf))<0){ + printf("some problem with setsockopt: %d",dd); + return -1; + } + *p_fchanged=0; + } + + if(call_hci_accept_conn_req_cmd(dd, &p_evt->bdaddr, &sw_opcode)<0){ + printf("error with accepting connection\n"); + return -1; + } + printf("accept connection command was sended\n"); + return 0; +} -void rutine_con_req(void){ +int rutine_cmd_status(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged){ + evt_cmd_status *p_evt; + p_evt = (void *) p_recbuf; + if(p_evt->status){ + printf("command status error\n"); + return -1; + } + + printf("command status with opcode: %d",p_evt->opcode); + return 0; } -void rutine_cmd_status(void){ +int rutine_connection_complete(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged){ + __u16 sw_opcode; + incoming_evt new_evt,*p_new_evt=&new_evt; + evt_conn_complete *p_evt; + p_evt = (void *) p_recbuf; + + if(p_evt->status){ + printf("connection was not setted\n"); + return -1; + } + p_connection->con_state=CONNECTED; + p_connection->handle=p_evt->handle; + printf("connection was setted: %d\n",p_connection->handle); + + p_new_evt->id=evt_id++; + p_new_evt->actual_status=ESTABLISHED; + p_new_evt->evt_code = EVT_DISCONN_COMPLETE; + p_new_evt->p_serv_rutine=&rutine_disconnect; + add_evt_toarray(p_new_evt,p_pf,p_fchanged); + + sw_opcode=swap_2_bytes(ACCEPT_CONNECTION_REQ); + *p_pf=nnf; + *p_fchanged=1; + hci_filter_clear_event(EVT_CONN_REQUEST,&nnf); + hci_filter_clear_opcode(&nnf); + + + return 0; +} +int rutine_disconnect(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged){ + evt_disconn_complete *p_evt; + incoming_evt new_evt,*p_new_evt=&new_evt; + + p_evt = (void *) p_recbuf; + if(p_evt->status){ + printf("disconnection error: %d\n",p_evt->status); + return -1; + } + *p_pf=nnf; + *p_fchanged=1; + hci_filter_clear_event(EVT_CONN_COMPLETE,&nnf); + + p_connection->con_state=DISCONNECTED; + printf("connection was canceled: %d\n",p_connection->handle); + printf("disconnection reason: %d\n",p_evt->reason); + + p_new_evt->id=evt_id++; + p_new_evt->actual_status=ESTABLISHED; + p_new_evt->evt_code = EVT_CONN_REQUEST; + p_new_evt->p_serv_rutine=&rutine_con_req; + add_evt_toarray(p_new_evt,p_pf,p_fchanged); + + return 0; } -int check_socket(int dd){ - int len,j; +int check_socket(int dd,struct hci_filter *p_pf, int *p_fchanged){ + int len,j,index; + hci_event_hdr *p_hdr; __u8 recbuf[HCI_MAX_EVENT_SIZE],*p_recbuf; while((len=read(dd, recbuf, sizeof(recbuf)))<0){ - if(errno == EAGAIN || errno == EINTR) - printf("error in read EAGAIN or EINTR \n"); + if(errno == EINTR) continue; + if(errno == EAGAIN) + return 0; perror("Problem with cmd reading \n"); return -1; } @@ -117,6 +208,28 @@ int check_socket(int dd){ printf("%2.2X ",recbuf[j]); } printf("\n"); + if(recbuf[0]==4){ + p_hdr = (void *) (recbuf + 1); + p_recbuf = (void *) (recbuf + (1 + HCI_EVENT_HDR_SIZE)); + if((index=look_up_inarray(p_hdr->evt))<0){ + printf("There is no awaiting evt like this\n"); + return -1; + } + else{ + if(evt_array[index].p_serv_rutine(p_recbuf, dd, p_pf, p_fchanged)<0){ + printf("error with service rutine"); + return -1; + } + if(evt_array[index].actual_status != PERMANENT){ + evt_array[index].actual_status = DONE; + } + } + return 1; + } + else if(recbuf[0]==2){ + + } + else return 0; // 0 or -1 } else{ @@ -139,8 +252,10 @@ int main(void){ memset(evt_array,0,(sizeof(incoming_evt)*MAX_EVT_COUNT)); evt_id=0; global_index=0; + p_connection->con_id=0; + p_connection->con_state=DISCONNECTED; - int dd=hci_open_device(0); // only for testig 1 + int dd=hci_open_device_nonblock(0); // only for testig 1 len = sizeof(oof); //the oldest filter if(getsockopt(dd, SOL_HCI, HCI_FILTER, &oof, &len)<0){ @@ -172,18 +287,18 @@ int main(void){ } fchanged=0; } - if(check_socket(dd)<0){ + if(check_socket(dd, &pf, &fchanged)<0){ printf("problem with sock checking \n"); setsockopt(dd, SOL_HCI, HCI_FILTER, &pf, sizeof(pf)); - break; + continue; } - printf("I doing something %d \n",factorial(100)); - - + } setsockopt(dd, SOL_HCI, HCI_FILTER, &oof, sizeof(oof)); hci_close_dev(dd); return 0; } + + diff --git a/testf/t2/slavetest.h b/testf/t2/slavetest.h new file mode 100644 index 0000000..e3ce001 --- /dev/null +++ b/testf/t2/slavetest.h @@ -0,0 +1,28 @@ +// +// C++ Interface: slavetest +// +// Description: +// +// +// Author: root , (C) 2008 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef __SLAVETEST +#define __SLAVETEST + + + +extern int add_evt_toarray(incoming_evt *p_evt,struct hci_filter *p_pf,int *p_fchanged); +extern int look_up_inarray(__u8 evt_code); +extern int rutine_con_req(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged); +extern int rutine_cmd_status(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged); +extern int rutine_connection_complete(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged); +extern int rutine_disconnect(void *p_recbuf, int dd, struct hci_filter *p_pf, int *p_fchanged); +extern int check_socket(int dd,struct hci_filter *p_pf, int *p_fchanged); + + + +#endif +