return 0;
}
// fill up the input parameter address pointer by one address
-int call_hci_read_bd_addr_cmd(int dd,bt_address *p_address, int timeout){
- read_bd_addr_rp cmdp,*p_cmdp; //command parameters return/comand
- hci_request req,*p_req;
- __u16 OCF_OGF,*p_OCF_OGF;
- p_OCF_OGF=&OCF_OGF;
- p_cmdp=&cmdp;
- p_req=&req;
-
+int call_hci_read_bd_addr_cmd(int dd,bt_address *p_address,__u16 *p_ocf_ogf){
+ read_bd_addr_rp cmdp,*p_cmdp=&cmdp; //command parameters return/comand
+ hci_request req,*p_req=&req;
memset(p_req,0,sizeof(req));
- assemble_ocf_ogf(0x09,0x04,p_OCF_OGF);
- p_req->p_OCF_OGF=p_OCF_OGF;
+ p_req->p_OCF_OGF=p_ocf_ogf;
p_req->p_retcmdp=p_cmdp;
p_req->retcmdp_len=READ_BD_ADDR_RP_SIZE;
p_req->cmdp_len=0;
p_req->event=EVT_CMD_COMPLETE;
- if(hci_send_request(dd,p_req,timeout)<0)
+ if(hci_send_request(dd,p_req,1000)<0)
return -1;
if(p_cmdp->status)
return -1;
-
bacpy(p_address, &cmdp.bdaddr);
+
+ return 0;
+}
+
+int call_hci_read_local_name_cmd(int dd, void *p_name,__u16 *p_ocf_ogf){
+ read_local_name_rp cmdp,*p_cmdp=&cmdp;
+ hci_request req,*p_req=&req;
+
+ memset(p_req,0,sizeof(req));
+ p_req->p_OCF_OGF=p_ocf_ogf;
+ p_req->p_retcmdp=p_cmdp;
+ p_req->retcmdp_len=READ_LOCAL_NAME_RP_SIZE;
+ p_req->cmdp_len=0;
+ p_req->event=EVT_CMD_COMPLETE;
+
+ if(hci_send_request(dd,p_req,1000)<0)
+ return -1;
+ if(p_cmdp->status)
+ return -1;
+ memcpy(p_name, &p_cmdp->name, 8); //copy name
return 0;
+
}
int call_hci_create_connection_cmd(int dd, bt_address *p_address, int timeout){
int hci_send_command(int dd, hci_request *p_req){
__u8 array[p_req->cmdp_len+4]; //type + OCF+OGF+plen
+ //__u16 correct_opcode,*p_cor_opcode=&correct_opcode;
+ //correct_opcode=swap_2_bytes(*(p_req->p_OCF_OGF));
int ii;
array[0]=0x01;
memcpy(&array[1],p_req->p_OCF_OGF,2);
return 0;
}
-int hci_send_request(int dd, hci_request *p_req,int timeout){
- return 0;
-}
-
-/*void print_device_list(int ctl){
- bt_device_req_list dlist,*p_dlist;
- bt_device_req *p_dreq;
- int i;
- bt_device devi;
- p_dlist=&dlist;
- p_dlist->dev_num=HCI_MAX_DEV;
- p_dreq=p_dlist->dev_req;
+int hci_send_request(int dd, hci_request *p_req,int timeout){
+ __u8 recbuf[HCI_MAX_EVENT_SIZE],*p_recbuf;
+ int j,count=0;
+ socklen_t len;
+ hci_event_hdr *p_hdr;
+ struct hci_filter nf, of;
+ int try_count, sign=0;;
+
+
- if(ioctl(ctl, HCIGETDEVLIST, (void *) p_dlist)<0){
- perror("Can't get device list");
- exit(1);
+
+ len = sizeof(of);
+ if(getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &len)<0){
+ printf("some problem with getsockopt: %d",dd);
+ return -1;
}
- for(i=0;i<p_dlist->dev_num;i++){
- devi.dev_id=(p_dreq+i)->dev_id;
- if(ioctl(ctl, HCIGETDEVINFO, (void *) &devi)<0)
- printf("No info");
- continue;
+ hci_filter_clear(&nf);
+ hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
+ hci_filter_set_event(EVT_CMD_STATUS, &nf);
+ hci_filter_set_event(p_req->event, &nf);
+ hci_filter_set_opcode(*(p_req->p_OCF_OGF), &nf);
- }
-
-}
-
-
+ if(setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf))<0){
+ printf("some problem with setsockopt: %d",dd);
+ return -1;
+ }
+
+ if(hci_send_command(dd, p_req)<0){
+ printf("some problems with sending command: %d",dd);
+ goto fail;
+ }
+
+ try_count= 10;
+
+ while(try_count--){
+ printf("try %d \n",try_count);
+ evt_cmd_complete *cc;
+ evt_cmd_status *cs;
+ evt_remote_name_req_complete *rnrc;
+ remote_name_req_cp *cpar;
+ inquiry_info_with_rssi *p_res_ev;
+
+ if(timeout){
+ struct pollfd p;
+ int n;
+
+ p.fd = dd; p.events = POLLIN;
+ while((n = poll(&p, 1, timeout)) < 0){ //pool return 1 when there are some incoming data
+ if(errno == EAGAIN || errno == EINTR)
+ continue;
+ perror("Problem with poll");
+ goto fail;
+ }
+
+ if (!n) { //time out pool return 0
+ errno = ETIMEDOUT;
+ perror("Poll return 0 timeout");
+ printf("exited pool timeout \n ");
+ goto fail;
+ }
+
+ timeout -= 10;
+ if(timeout < 0) timeout = 0;
+
+ }
+ printf("Timeout after round is: %d \n",timeout);
+
+ while((len=read(dd, recbuf, sizeof(recbuf)))<0){
+ if(errno == EAGAIN || errno == EINTR)
+ continue;
+ perror("Problem with cmd sending");
+ goto fail;
+ }
+ printf("Count of received bytes %d \n ",len);
+ for(j=0;j<len;j++){
+ printf("%2.2X ",recbuf[j]);
+ }
+ printf("\n");
+ p_hdr = (void *) (recbuf + 1);
+ p_recbuf = recbuf + (1 + HCI_EVENT_HDR_SIZE);
+ len -= (1 + HCI_EVENT_HDR_SIZE);
+
+ switch(p_hdr->evt){
+ case EVT_CMD_STATUS:
+ cs = (void *) p_recbuf;
+ if(cs->opcode != *(p_req->p_OCF_OGF))
+ continue;
+ if(p_req->event != EVT_CMD_STATUS){
+ if(cs->status){ // if there is something except 0 it is error
+ errno = EIO;
+ perror("Some error state has occured on receive");
+ goto fail;
+ }
+ break;
+ }
+ p_req->retcmdp_len = min(len, p_req->retcmdp_len);
+ memcpy(p_req->p_retcmdp, p_recbuf, p_req->retcmdp_len);
+ goto succes;
+
+ case EVT_CMD_COMPLETE:
+ cc = (void *) p_recbuf;
+ if(cc->opcode != *(p_req->p_OCF_OGF))
+ continue;
+ p_recbuf += EVT_CMD_COMPLETE_SIZE;
+ len -= EVT_CMD_COMPLETE_SIZE;
+
+ p_req->retcmdp_len = min(len, p_req->retcmdp_len);
+ memcpy(p_req->p_retcmdp, p_recbuf, p_req->retcmdp_len);
+ printf("retcmdp lenght: %d \n",p_req->retcmdp_len);
+ goto succes;
+ // __u8 first,*p_first;
+ // p_first=&first;
+ // for(j=0;j<p_req->retcmdp_len;j++){
+ // memcpy(p_first,p_req->p_retcmdp+j,1);
+ // printf("%d. byte is: %X \n",j,first);
+ // printf(" %X",*((unsigned int *)p_req->p_retcmdp+j));
+ //printf("address of p_req: %d \n",p_req);
+ //printf("address of p_req: %d \n",p_req->p_retcmdp);
+ // }
+ // printf("Ok\n");
+
+
+ case EVT_REMOTE_NAME_REQ_COMPLETE:
+ if(p_hdr->evt != p_req->event)
+ break;
+ rnrc = (void *) p_recbuf;
+ cpar = p_req->p_cmdp;
+
+ if(bacmp(&rnrc->bdaddr, &cpar->bdaddr))
+ continue;
+
+ p_req->retcmdp_len = min(len, p_req->retcmdp_len);
+ memcpy(p_req->p_retcmdp, p_recbuf, p_req->retcmdp_len);
+ goto succes;
+
+ case EVT_INQUIRY_RESULT:
+ printf("bingo inquiry result event \n");
+ break;
+ //goto succes;
+
+/* case EVT_INQUIRY_RESULT_WITH_RSSI:
+ printf("bingo inquiry result RSSI event \n");
+ p_res_ev = (void *) p_recbuf;
+ p_actual = &(p_res_ev->ba_array);
+ for(j=0;j<count;j++){
+ if(compare_bda(p_actual,(p_req->p_retcmdp+(j*sizeof(bt_address)))) == 1){
+ sign=1;
+ } //im looking for all array members an compare with actual address
+ }
+ if(!sign){ // if in array address doesnt exist i will add it to array
+ *(bt_address*)(p_req->p_retcmdp+(count*sizeof(bt_address)))= *p_actual;
+ count++;
+ }
+ if(count==0){
+ *(bt_address*)(p_req->p_retcmdp)= *p_actual;
+ count++;
+ }
+
+ //printf("type %2.2X \n",((hci_inquiry_result_RSSI_ev *)p_req->p_retcmdp)->RSSI_array);
+ break;
+ //goto succes;
+*/
+ case EVT_INQUIRY_COMPLETE:
+ printf("bingo inquiry complete event \n");
+ goto succes;
+
+
+ default: if(p_hdr->evt != p_req->event)
+ break;
+ p_req->retcmdp_len = min(len, p_req->retcmdp_len);
+ memcpy(p_req->p_retcmdp, p_recbuf, p_req->retcmdp_len);
+ goto succes;
+
+ }
+
-void assemble_hci_data(void *p_con_handle,void *p_data_size,void *p_data){
- __u16 data_size=0;
- data_size= *(__u16 *)p_data_size;
- __u8 array[data_size+5]; //type + handle + flags + size
- array[0]=0x02;
- memcpy(&array[1],p_con_handle,2);
- memcpy(&array[3],p_data_size,2);
- memcpy(&array[6],p_data,data_size);
- //call send to socket/uart
+ }
+ errno = ETIMEDOUT;
+ return -1;
-} */
+fail:
+ setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
+ hci_close_dev(dd);
+ return -1;
+succes:
+ setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of));
+ return 0;
+
+}
/*****************************HCI support functions*****************************/
void assemble_ocf_ogf(__u8 ocf,__u8 ogf,__u16 *p_ocf_ogf){
__u16 var1;
__u16 result;
- //result=ocf;
- //result=(result<<8);
- //var1=(ogf<<2);
- //*p_ocf_ogf=(result|var1);
+
var1=(ogf<<10);
result=ocf;
*p_ocf_ogf=(result|var1);
}
*p_addr=*p_help;
}
+__u16 swap_2_bytes(__u16 twobytes){
+ __u16 first,second,result=0;
+ first=twobytes&255;
+ second=twobytes&65280;
+ result=result|(first<<8);
+ result=result|(second>>8);
+ return result;
+}
__u8 swap8(__u8 byte1){
__u8 i,mask=0,hvar1=0,resvar=0;
cmd_state_request array_req[MAX_CMD_STATE_REQUEST];
int cmd_req_id;
+int global_index;
-int create_master_connection(hci_dev_info *master){//establish connection and send a coutn of bytes every x second
+int create_master_connection(struct hci_dev_info *master){//establish connection and send a coutn of bytes every x second
//array of open request which are in waiting state for appropriate event or answer
connection_hci connection,*p_connection=&connection;
p_connection->con_id=0;
}
-
+ return 0;
}
-int show_all_local_dev(hci_dev_info *master){ // and choose a master device which will initiate the connection
+int show_all_local_dev(struct hci_dev_info *master){ // and choose a master device which will initiate the connection
int sock,i;
- hci_dev_list_req dlist,*p_dlist=&dlist;
- hci_dev_req *p_dreq;
+ struct hci_dev_list_req dlist,*p_dlist=&dlist;
+ struct hci_dev_req *p_dreq;
+ p_dlist->dev_num=HCI_MAX_DEV;
p_dreq=p_dlist->dev_req;
if((sock=socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI))<0){
return -1;
}
if(p_dlist->dev_num > 0){
- hci_dev_info dev_array[p_dlist->dev_num];
+ struct hci_dev_info dev_array[p_dlist->dev_num];
for(i=0;i<p_dlist->dev_num;i++){
dev_array[i].dev_id=(p_dreq+i)->dev_id;
if(ioctl(sock, HCIGETDEVINFO, (void *) &dev_array[i])<0){
continue;
}
int dd=hci_open_device(dev_array[i].dev_id);
- if(l2cap_call_cmd(READ_BD_ADDR_CMD_OP,dd)< 0){
+ if(l2cap_call_cmd(READ_BD_ADDR_CMD_OP,dd,&dev_array[i].bdaddr)< 0){
printf("Error in call hci bd addr cmd \n");
return -1;
}
- if(l2cap_call_cmd(READ_LOCAL_NAME_CMD_OP,dd)< 0){
+ if(l2cap_call_cmd(READ_LOCAL_NAME_CMD_OP,dd,&dev_array[i].name)< 0){
printf("Error in call hci bd addr cmd \n");
return -1;
}
printf("There is no hci device \n");
return -1;
}
+ return 0;
}
-int l2cap_call_cmd(__u16 ocf_ogf,int dd){
+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;
+ sw_opcode=swap_2_bytes(ocf_ogf);
switch(ocf_ogf){
case READ_BD_ADDR_CMD_OP:{
p_new_req->actual_status=ESTABLISHED;
- p_new_req->id=cmd_rq_id++;
+ p_new_req->id=cmd_req_id++;
p_new_req->req_opcode = ocf_ogf;
p_new_req->evt_code = EVT_CMD_COMPLETE;
p_new_req->p_serv_rutine=rutine_catch_bd_addr;
printf("Mistake with req array adding \n ");
return -1;
}
- call_hci_read_bd_addr_cmd()
+
+ if(call_hci_read_bd_addr_cmd(dd,(bt_address *)p_param,&sw_opcode)){
+ printf("Mistake with bt addr cmd \n ");
+ return -1;
+ }
+ req_fcn_remove();
+ return 0;
}
case READ_LOCAL_NAME_CMD_OP:{
+ p_new_req->actual_status=ESTABLISHED;
+ p_new_req->id=cmd_req_id++;
+ p_new_req->req_opcode = ocf_ogf;
+ p_new_req->evt_code = EVT_CMD_COMPLETE;
+ p_new_req->p_serv_rutine=rutine_catch_bd_addr;
+ if(req_fcn_add(p_new_req)<0){
+ printf("Mistake with req array adding \n ");
+ return -1;
+ }
+ if(call_hci_read_local_name_cmd(dd,p_param,&sw_opcode)){
+ printf("Mistake with read local name cmd \n ");
+ return -1;
+ }
+ req_fcn_remove();
+ return 0;
}
-
-
}
-
+ return 0;
}
/* request array support functions */
int req_fcn_add(cmd_state_request *p_req){ //fcn add the request at the end of array or replace the oldest request
cmd_state_request the_oldest=array_req[0];
for(i=0;i<MAX_CMD_STATE_REQUEST;i++){
- if(array_req[i]->actual_status==0 || array_req[i]->actual_status==3 ){
+ if((array_req[i].actual_status)==0 || array_req[i].actual_status==3 ){
array_req[i]=*p_req;
sig=1;
+ global_index=i;
break;
}
- if(array_req[i]->id < the_oldest.id){ //the smallest id (oldest request) will stay here
+ if((array_req[i].id) < the_oldest.id){ //the smallest id (oldest request) will stay here
the_oldest = array_req[i];
index=i;
+
}
}
if(!sig){
- return -1;
- array_req[index]=*p_req;
+ //return -1;
+ array_req[index]=*p_req;
+ global_index=index;
}
- return 1;
+ return 0;
+}
+
+void req_fcn_remove(void){
+ array_req[global_index].actual_status=DONE;
}
/* rutines for each command */
int main(void){
struct hci_dev_info master,*p_master=&master;
cmd_req_id=0;
- memset(array_req,0,(sizeof(cmd_state_request)*));
+ global_index=0;
+ memset(array_req,0,(sizeof(cmd_state_request)*MAX_CMD_STATE_REQUEST));
+ if(show_all_local_dev(p_master)<0){
+ printf("error no dev \n");
+ return -1;
+ }