]> rtime.felk.cvut.cz Git - tiny-bt.git/blobdiff - src2/hil2cap.c
new version
[tiny-bt.git] / src2 / hil2cap.c
diff --git a/src2/hil2cap.c b/src2/hil2cap.c
new file mode 100644 (file)
index 0000000..3b59493
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+*  C Implementation: testovaci
+*
+* Description: 
+*
+*
+* Author: root <root@ubuntu>, (C) 2008
+*
+* Copyright: See COPYING file that comes with this distribution
+*
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdint.h>
+#include "hil2cap.h"
+#include "hcidriver.h"
+
+
+expect_evt evt_array[MAX_CMD_STATE_REQUEST];
+int evt_id;
+int global_index;
+connection_hci connection,*p_connection=&connection;
+
+
+void add_evt_toarray(expect_evt *p_evt){ //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];
+
+       for(i=0;i<MAX_EVT_COUNT;i++){
+               if((evt_array[i].actual_status)==0 || evt_array[i].actual_status==3 ){
+                       evt_array[i]=*p_evt;
+                       sig=1;
+                       global_index=i;
+                       break;
+               }
+               if((evt_array[i].id) < the_oldest.id){ //the smallest id (oldest request) will stay here
+                       the_oldest = evt_array[i];
+                       index=i;
+                       
+               }
+       }
+       if(!sig){
+       
+               evt_array[index]=*p_evt;
+               global_index=index;     
+       }
+}
+
+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 tiny_bt_init(bt_device *p_device){
+       expect_evt evt,*p_evt=&evt;
+       req_state status = PERMANENT;
+       evt_id=0;
+       global_index=0;
+       p_connection->con_id=0;
+       p_connection->con_state=DISCONNECTED;
+       
+       memset(p_evt,0,sizeof(evt));
+       p_evt->actual_status=status;
+       p_evt->id=evt_id++;
+       p_evt->evt_type=EVT_CMD_STATUS;
+
+       add_evt_toarray(p_evt);
+       
+}
+
+int tiny_bt_process(){
+       int len,j,index;
+       hci_event_hdr *p_hdr;
+       __u8 recbuf[HCI_MAX_EVENT_SIZE],*p_recbuf;
+       
+       len = hw_bt_read(recbuf);
+
+       if(len){
+                       printf("Count of received bytes %d \n ",len);
+                       for(j=0;j<len;j++){
+                               printf("%2.2X ",recbuf[j]);     
+                       }
+                       printf("\n");
+                       if(recbuf[0]==HCI_EVENT_PKT){ 
+                               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_callback(evt_array[index].p_data, p_recbuf)<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{
+                       printf("There is nothing on socket %d \n",dd);
+                       return 0;
+               }
+       
+       return 0;
+}
+       
+
+int tiny_bt_read_bd_addr(bd_address *p_dest, void (*callback_app_read_bd_addr)(bt_address *p_address)){
+       expect_evt evt,*p_evt=&evt;
+       req_state status = ESTABLISHED;
+       read_bd_addr_data *p_data;
+       
+       memset(p_evt,0,sizeof(evt));
+       p_evt->actual_status=status;
+       p_evt->id=evt_id++;
+       p_evt->evt_type=EVT_CMD_COMPLETE;
+       p_evt->req_opcode=READ_BD_ADDR_CMD_OP;
+       p_evt->p_callback=&callback_hci_read_bd_addr;
+       
+       p_data=malloc(sizeof(read_bd_addr_data));
+       p_data->p_address=p_dest;
+       p_data->callback_app_read_bd_addr=callback_app_read_bd_addr;
+       p_evt->p_data=(void *)p_data;
+       
+       add_evt_toarray(p_evt);
+       if(send_hci_read_bd_addr_cmd()<0){
+               perror("send_hci_cmd error");
+               return -1;
+       }
+       return 0;
+}
+
+int tiny_bt_read_local_name(char *p_name, void (*callback_app_read_local_name)(char *p_name)){
+       expect_evt evt,*p_evt=&evt;
+       req_state status = ESTABLISHED;
+       read_local_name_data *p_data;
+
+       memset(p_evt,0,sizeof(evt));
+       p_evt->actual_status=status;
+       p_evt->id=evt_id++;
+       p_evt->evt_type=EVT_CMD_COMPLETE;
+       p_evt->req_opcode=READ_LOCAL_NAME_CMD_OP;
+       p_evt->p_callback=callback_hci_read_local_name;
+       
+       p_data=malloc(sizeof(read_local_name_data));
+       p_data->p_name=p_name;
+       p_data->callback_hci_read_local_name=callback_app_read_local_name;
+       p_evt->p_data=(void *)p_data;
+       
+       add_evt_toarray(p_evt);
+       if(send_hci_read_local_name_cmd()<0){
+               perror("send_hci_cmd error");
+               return -1;
+       }
+       return 0;
+}
+
+int tiny_bt_connect(bt_address *p_dest_addr, __u16 *p_handle, void (*callback_app_connection_complete)(__u16 *p_handle, bt_address *p_address)){
+       expect_evt evt,*p_evt=&evt;
+       req_state status = ESTABLISHED;
+       connection_complete_data *p_data;
+
+       memset(p_evt,0,sizeof(evt));
+       p_evt->actual_status=status;
+       p_evt->id=evt_id++;
+       p_evt->evt_type=EVT_CONN_COMPLETE;
+       p_evt->req_opcode=CREATE_CONNECTION_CMD_OP;
+       p_evt->p_callback=callback_hci_connection_complete;
+       
+       p_data=malloc(sizeof(connection_complete_data));
+       p_data->p_handle=p_handle;
+       p_data->callback_app_connection_complete=callback_app_connection_complete;
+       p_evt->p_data=(void *)p_data;
+       
+       add_evt_toarray(p_evt);
+       if(send_hci_create_connection_cmd(p_dest_addr)<0){
+               perror("send_hci_cmd error");
+               return -1;
+       }
+       return 0;
+       
+}
+
+int tiny_bt_wait_for_connection(){
+
+}
+
+
+
+
+
+
+int create_master_connection(connection_hci *p_connection){//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
+       p_connection->con_id=0;
+       p_connection->con_state=DISCONNECTED;
+       
+       p_connection->socket_fd=hci_open_device_sraw(p_connection->master.dev_id);
+       if(l2cap_call_cmd(CREATE_CONNECTION_CMD_OP,p_connection->socket_fd,p_connection)<0){
+               printf("connection problem \n");
+               return -1;
+       }       
+       
+       
+       return 0;
+}
+
+int show_all_local_dev(struct hci_dev_info *master){ // and choose a master device which will initiate the connection
+       int sock,i;
+       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((ioctl(sock, HCIGETDEVLIST, (void *) p_dlist))<0){
+               return -1;
+       }
+       if(p_dlist->dev_num > 0){
+               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){
+                               printf("No info");
+                               continue;
+                       }
+                       int dd=hci_open_device(dev_array[i].dev_id);
+                       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,&dev_array[i].name)< 0){
+                               printf("Error in call hci bd addr cmd \n");
+                               return -1;
+                       }
+                       //hci_close_dev(dev_array[i].dev_id);
+               }
+               *master = dev_array[0]; //I will take a first dev like a master
+               
+       }
+       else{
+               printf("There is no hci device \n");
+               return -1;
+       }
+       return 0;
+               
+}
+
+int show_all_remote_dev(struct hci_dev_info *p_master, bt_address *p_remadrar, int *p_remd_count){
+       int dd=hci_open_device(p_master->dev_id);
+       
+       if((*p_remd_count=l2cap_call_cmd(INQUIRY_CMD_OP, dd, p_remadrar))< 0){
+                               printf("Error in call inquiry command \n");
+                               return -1;
+                       }
+       return 0;
+
+}
+
+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,ret_val;
+       sw_opcode=swap_2_bytes(ocf_ogf);
+       p_new_req->actual_status=ESTABLISHED;
+       p_new_req->id=cmd_req_id++;
+       p_new_req->req_opcode = ocf_ogf;        
+       
+       switch(ocf_ogf){
+       
+       case READ_BD_ADDR_CMD_OP:
+               p_new_req->evt_code = EVT_CMD_COMPLETE;
+               p_new_req->p_serv_rutine=NULL;
+
+               if(req_fcn_add(p_new_req)<0){
+                       printf("Mistake with req array adding \n ");
+                       return -1;
+               }
+               
+               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->evt_code = EVT_CMD_COMPLETE;
+               p_new_req->p_serv_rutine=NULL;
+
+               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;
+       
+       case INQUIRY_CMD_OP:
+               
+               p_new_req->evt_code = EVT_INQUIRY_COMPLETE;
+               p_new_req->p_serv_rutine=NULL;
+               
+               if(req_fcn_add(p_new_req)<0){
+                       printf("Mistake with req array adding \n ");
+                       return -1;
+               }
+               if((remd_count=call_hci_inquiry_cmd(dd,p_param,&sw_opcode)) < 0){
+                       printf("Mistake with inquiry cmd \n ");
+                       return -1;
+               }
+               req_fcn_remove();
+               return remd_count;
+       
+       case CREATE_CONNECTION_CMD_OP:
+               p_new_req->evt_code = EVT_CONN_COMPLETE;
+               p_new_req->p_serv_rutine=NULL;
+               
+               if(req_fcn_add(p_new_req)<0){
+                       printf("Mistake with req array adding \n ");
+                       return -1;
+               }
+               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;
+       }
+       
+       return 0;
+}
+
+
+int main(void){
+       struct hci_dev_info master,*p_master=&master;
+       bt_address remote_bd_addr_array[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;
+       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;
+       }
+       if(show_all_remote_dev(p_master, remote_bd_addr_array, &remd_count)<0){
+               printf("error no remote dev \n");
+               return -1;
+       }
+       printf("All remote devices:\n");
+       for(i=0;i<remd_count;i++){
+               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;
+       if(create_master_connection(p_connection)<0){
+               printf("connection error");
+               return -1;
+       }
+
+return 0;
+}
+