]> rtime.felk.cvut.cz Git - tiny-bt.git/blobdiff - src/hcidriver.c
next new support functions were added and old ideas were deleted
[tiny-bt.git] / src / hcidriver.c
index 46833f0d23bc2baecd614c63ec940f9cd4eb9fb6..1dfa3c4e85bb04a58e1c5dbc1af8597d5557a058 100644 (file)
@@ -42,30 +42,44 @@ int call_hci_inquiry_cmd(int dd, bt_address *p_addressarray,int timeout){
        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){
@@ -125,6 +139,8 @@ int hci_close_dev(int dd){
 
 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);
@@ -147,49 +163,198 @@ int hci_send_command(int dd, hci_request *p_req){
        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*****************************/
@@ -198,10 +363,7 @@ void assemble_hci_data(void *p_con_handle,void *p_data_size,void *p_data){
 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);
@@ -236,6 +398,14 @@ void swap_addrbytes(bt_address *p_addr){
        }
        *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;