]> rtime.felk.cvut.cz Git - tiny-bt.git/commitdiff
hcidriver.c:new non block cmd call.
authorDavid Plotek <ploted1@fel.cvut.cz>
Mon, 11 Aug 2008 21:17:34 +0000 (23:17 +0200)
committerDavid Plotek <ploted1@fel.cvut.cz>
Mon, 11 Aug 2008 21:17:34 +0000 (23:17 +0200)
slavetest.c: next new event rutines.

src/hcidriver.c
src/hcidriver.h
src/hil2cap.c
src/hil2cap.h
testf/t2/slavetest.c
testf/t2/slavetest.h [new file with mode: 0644]

index 109e8522884f234091179dd644871174d9ffe110..823a545f4677985fafce5c1c1c563eab57b33298 100644 (file)
@@ -4,6 +4,8 @@
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <stdint.h>
+#include <fcntl.h>
 #include <sys/poll.h>
 #include <sys/ioctl.h>
 #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);
 }
index 8002b68eece26466b3341e3a901c954dd9257354..ab287e26f445ac23e6e9a114d6fbb1763fd8932f 100644 (file)
@@ -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);
index f06184ccfed90c41ad69bf1700e7dc52cb7a6850..0897bcc99b1042e70701ddf06fb29ff1aae57415 100644 (file)
@@ -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;
index 826ab3e282dbac81647b15ab00234f95c1924d38..b3375fd55cdbc88bc86d066618cf557385b92c0a 100644 (file)
@@ -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;
 
index 612d50120c65acb75286d0073cf3140d612e4a90..207fa5bf5e115f99c514238d769b11209c26546d 100644 (file)
 #include <sys/ioctl.h>
 #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;i<MAX_CMD_STATE_REQUEST;i++){
+                       if(evt_array[i].evt_code == evt_code && evt_array[i].actual_status != DONE){
+                               if(evt_array[i].id<oldestid){
+                                       oldestid=evt_array[i].id;
+                                       index=i;
+                               }
+                       }
+               }
+               return index;
+       }
+}
+
+int rutine_con_req(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_request *p_evt;
+
+       p_evt = (void *) p_recbuf;      
+       
+       p_connection->master.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 (file)
index 0000000..e3ce001
--- /dev/null
@@ -0,0 +1,28 @@
+//
+// C++ Interface: slavetest
+//
+// Description: 
+//
+//
+// Author: root <root@ubuntu>, (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
+