]> rtime.felk.cvut.cz Git - tiny-bt.git/blob - src2/tiny_bt_hci_core.c
new version of callback functions and new was added
[tiny-bt.git] / src2 / tiny_bt_hci_core.c
1 /*
2 *  C Implementation: testovaci
3 *
4 * Description:
5 *
6 *
7 * Author: root <root@ubuntu>, (C) 2008
8 *
9 * Copyright: See COPYING file that comes with this distribution
10 *
11 */
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/ioctl.h>
15 #include <errno.h>
16 #include <stdint.h>
17 #include "tiny_bt_hci_core.h"
18 #include "tiny_bt_hci_cmd.h"
19 #include "bt_hw.h"
20
21
22 static expect_evt evt_array[MAX_CMD_STATE_REQUEST];
23 static int evt_id;
24 static int global_index;
25 extern connection_hci connection;
26 /******************************HCI callback functions*********************/
27
28 static void callback_hci_all_commands(void *p_arg, void *p_recbuf){
29         evt_cmd_status *p_rp;
30         p_rp = (void *) p_recbuf;
31
32         if(p_rp->status){
33                 perror("command status error\n");
34                 //return -1;
35                 exit(-1); // !!!!!!!!!!!!!!!!
36         }
37                 
38         printf("command status with opcode: %d\n",p_rp->opcode);
39         //return 0;
40 }
41
42 static void callback_hci_read_bd_addr(void *p_arg, void *p_recbuf){
43         read_bd_addr_data *p_data=p_arg;
44         read_bd_addr_rp *p_rp;
45                 
46         p_rp = (void *) (p_recbuf+3);   
47         memcpy(p_data->p_address,&p_rp->bdaddr,6);
48         p_data->callback_app_read_bd_addr(p_data->p_address);
49         free(p_data);
50 }
51
52 static void callback_hci_read_local_name(void *p_arg, void *p_recbuf){
53         read_local_name_data *p_data=p_arg;
54         read_local_name_rp *p_rp;
55
56         p_rp = (void *) (p_recbuf+3);
57         memcpy(p_data->p_name,&p_rp->name,248);
58         p_data->callback_app_read_local_name(p_data->p_name);
59         free(p_data);
60 }
61
62 static void callback_hci_inquiry_RSSI(void *p_arg, void *p_recbuf){
63         inquiry_RSSI_data *p_data=p_arg;
64         inquiry_info_with_rssi *p_rp;
65
66         p_rp = (void *) (p_recbuf+1);
67         memcpy(p_data->p_address,&p_rp->bdaddr,6);
68         p_data->callback_app_inquiry_RSSI(p_data->p_address);
69         free(p_data);
70 }
71
72 static void callback_hci_inquiry_comple(void *p_arg, void *p_recbuf){
73         inquiry_complete_data *p_data=p_arg;
74         __u8 *p_byte;
75
76         p_byte = (void *) p_recbuf;
77         if(*p_byte){
78                 perror("inquiry complete status error\n");
79                 exit(-1); // !!!!!!!!
80         }
81                 
82         p_data->callback_app_inquiry_complete();
83         free(p_data);
84 }
85
86 static void callback_hci_create_connection(void *p_arg, void *p_recbuf){
87         connection_complete_data *p_data=p_arg;
88         evt_conn_complete *p_rp;
89
90         p_rp = (void *) (p_recbuf+3);
91         memcpy(p_data->p_handle,&p_rp->handle,2);
92         //memcpy(p_data->p_address,&p_rp->bdaddr,6);
93         p_data->callback_app_connection_complete(p_data->p_handle);
94         free(p_data);
95 }
96
97
98 void add_evt_toarray(expect_evt *p_evt)   //fcn add the request at the end of array or replace the oldest request
99 {
100         int i,sig=0,index=0;
101         expect_evt the_oldest=evt_array[0];
102
103         for ( i=0;i<MAX_EVT_COUNT;i++ )
104         {
105                 if ( ( evt_array[i].actual_status ) ==0 || evt_array[i].actual_status==3 )
106                 {
107                         evt_array[i]=*p_evt;
108                         sig=1;
109                         global_index=i;
110                         break;
111                 }
112                 if ( ( evt_array[i].id ) < the_oldest.id )   //the smallest id (oldest request) will stay here
113                 {
114                         the_oldest = evt_array[i];
115                         index=i;
116
117                 }
118         }
119         if ( !sig )
120         {
121
122                 evt_array[index]=*p_evt;
123                 global_index=index;
124         }
125 }
126
127 int look_up_inarray(__u8 evt_type, __u16 opcode){
128         
129         int i,index=-1,oldestid=65535;
130
131
132         if(evt_array[global_index].evt_type == evt_type && evt_array[global_index].actual_status != DONE){
133                 if(opcode!=0){
134                         if(evt_array[global_index].req_opcode == opcode)
135                                 return global_index;    
136                 }
137                 else{
138                         return global_index;
139                 }
140                 
141         }
142         else
143         {
144                 for ( i=0;i<MAX_CMD_STATE_REQUEST;i++ )
145                 {
146                         if ( evt_array[i].evt_type == evt_type && evt_array[i].actual_status != DONE )
147                         {       
148                                 if(opcode!=0){
149                                         if(evt_array[i].req_opcode == opcode){
150                                                 if(evt_array[i].id<oldestid){
151                                                         oldestid=evt_array[i].id;
152                                                         index=i;
153                                                 }
154                                         }
155                                 }
156                                 else{
157                                         if(evt_array[i].id<oldestid){
158                                                 oldestid=evt_array[i].id;
159                                                 index=i;
160                                         }
161                                 }
162                         }
163                 }
164                 return index;
165         }
166         return -1;
167 }
168
169
170
171
172 int tiny_bt_init(__u8 dev_id){
173         struct hci_filter nf;
174         int dd;
175         expect_evt evt,*p_evt=&evt;
176         connection_hci *p_conn=&connection;
177         req_state status = PERMANENT;
178         connection_state con_state = DISCONNECT;
179         evt_id=0;
180         global_index=0;
181         p_conn->con_id=0;
182         p_conn->con_state=con_state;
183
184         memset(p_evt,0,sizeof(evt));
185         p_evt->actual_status=status;
186         p_evt->id=evt_id++;
187         p_evt->evt_type=EVT_CMD_STATUS;
188         p_evt->p_callback=callback_hci_all_commands;
189         p_evt->p_data=NULL;
190
191         add_evt_toarray(p_evt);
192         
193         dd=hw_bt_open_device(dev_id);
194         
195         hci_filter_clear(&nf);
196         hci_filter_all_ptypes(&nf);
197         hci_filter_all_events(&nf);
198 //      hci_filter_set_opcode(swap_2_bytes(READ_BD_ADDR_CMD_OP),&nf);
199                 
200         if(setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf))<0){
201                 perror("some problem with setsockopt");
202                 return -1;
203         }
204         printf("init was succesful dd:%d\n",dd);
205
206         return 0;
207
208 }
209
210 int tiny_bt_process(){
211         
212         int len,j,index;
213         static int inqRSSI_index=-1;
214         hci_event_hdr *p_hdr;
215         __u8 recbuf[HCI_MAX_EVENT_SIZE],*p_recbuf;
216
217         len=hw_bt_read(recbuf);
218
219         if ( len )
220         {
221                 printf ( "Count of received bytes %d \n ",len );
222                 for ( j=0;j<len;j++ )
223                 {
224                         printf ( "%2.2X ",recbuf[j] );
225                 }
226                 printf ( "\n" );
227                 if ( recbuf[0]==HCI_EVENT_PKT )
228                 {
229                         p_hdr = ( void * ) ( recbuf + 1 );
230                         p_recbuf = ( void * ) ( recbuf + ( 1 + HCI_EVENT_HDR_SIZE ) );
231                         if(p_hdr->evt==EVT_CMD_COMPLETE ){
232                                 evt_cmd_complete *p_ccevt;
233                                 p_ccevt = (void *) p_recbuf;
234                                 if((index=look_up_inarray(p_hdr->evt,swap_2_bytes(p_ccevt->opcode)))<0){
235                                         printf ( "There is no awaiting evt like this\n" );
236                                         return -1;
237                                 }
238                                 else{
239                                         evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
240                                         if(evt_array[index].actual_status != PERMANENT){
241                                                 evt_array[index].actual_status = DONE;
242                                         }
243                                 }
244                         }
245                         /*else if(p_hdr->evt==EVT_INQUIRY_RESULT_WITH_RSSI){
246                                 if((index=look_up_inarray(p_hdr->evt,0))<0){
247                                         printf("There is no awaiting evt like this\n");
248                                         return -1;
249                                 }
250                                 else{
251                                         inqRSSI_index=index; //I will save a inq evt index
252                                         evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
253                                 }
254
255                         }  */
256                         else if(p_hdr->evt==EVT_INQUIRY_COMPLETE){
257                                 if((index=look_up_inarray(p_hdr->evt,0))<0){
258                                         printf("There is no awaiting evt like this\n");
259                                         return -1;
260                                 }
261                                 if((inqRSSI_index=look_up_inarray(EVT_INQUIRY_RESULT_WITH_RSSI,0))<0){
262                                         printf("There is no awaiting evt like this\n");
263                                         return -1;
264                                 }
265                                 
266                                 else{
267                                         evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
268                                         if(evt_array[index].actual_status != PERMANENT){
269                                                 evt_array[index].actual_status = DONE;
270                                         }// mark inq result evt like a DONE
271                                         if(evt_array[inqRSSI_index].actual_status != PERMANENT){
272                                                 free(evt_array[inqRSSI_index].p_data);
273                                                 evt_array[inqRSSI_index].actual_status = DONE;
274                                         }
275                                 }
276
277                         }
278                         else{
279                                 if((index=look_up_inarray(p_hdr->evt,0))<0){
280                                         printf("There is no awaiting evt like this\n");
281                                         return -1;
282                                 }
283                                 else{
284                                         evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
285                                         if(evt_array[index].actual_status != PERMANENT){
286                                                 evt_array[index].actual_status = DONE;
287                                         }
288                                 }
289                         }
290                         return 1;
291                 }
292                 else if ( recbuf[0]==2 )
293                 {
294
295                 }
296                 else return 0; // 0 or -1
297
298         }
299         else
300         {
301                 //printf ( "There is nothing on socket \n");
302                 return 0;
303         }
304
305         return 0;
306 }
307
308 int tiny_bt_read_bd_addr(bt_address *p_dest, void(*callback_app_read_bd_addr)(bt_address *p_address)){
309         expect_evt evt,*p_evt=&evt;
310         req_state status = ESTABLISHED;
311         read_bd_addr_data *p_data;
312
313         memset(p_evt,0,sizeof(evt));
314         p_evt->actual_status=status;
315         p_evt->id=evt_id++;
316         p_evt->evt_type=EVT_CMD_COMPLETE;
317         p_evt->req_opcode=READ_BD_ADDR_CMD_OP;
318         p_evt->p_callback=&callback_hci_read_bd_addr;
319
320         p_data=malloc(sizeof(read_bd_addr_data));
321         p_data->p_address=p_dest;
322         p_data->callback_app_read_bd_addr=callback_app_read_bd_addr;
323         p_evt->p_data=(void *) p_data;
324
325         add_evt_toarray(p_evt);
326         if(send_hci_read_bd_addr_cmd()<0)
327         {
328                 perror("send_hci_cmd error");
329                 return -1;
330         }
331         return 0;
332 }
333
334 int tiny_bt_read_local_name(char *p_name, void(*callback_app_read_local_name)(char *p_name)){
335         expect_evt evt,*p_evt=&evt;
336         req_state status = ESTABLISHED;
337         read_local_name_data *p_data;
338
339         memset (p_evt,0,sizeof(evt));
340         p_evt->actual_status=status;
341         p_evt->id=evt_id++;
342         p_evt->evt_type=EVT_CMD_COMPLETE;
343         p_evt->req_opcode=READ_LOCAL_NAME_CMD_OP;
344         p_evt->p_callback=callback_hci_read_local_name;
345
346         p_data=malloc (sizeof(read_local_name_data));
347         p_data->p_name=p_name;
348         p_data->callback_app_read_local_name=callback_app_read_local_name;
349         p_evt->p_data=(void *) p_data;
350
351         add_evt_toarray(p_evt);
352         if(send_hci_read_local_name_cmd()<0)
353         {
354                 perror("send_hci_cmd error");
355                 return -1;
356         }
357         return 0;
358 }
359
360 int tiny_bt_inquiry(bt_address *p_dest_addr, void(*callback_app_inquiry_RSSI)(bt_address *p_address), void(*callback_app_inquiry_complete)(void)){
361         
362         expect_evt evt,*p_evt=&evt;
363         req_state status = ESTABLISHED;
364         req_state istatus = ESTABLISHED;
365         inquiry_RSSI_data *p_data;
366         inquiry_complete_data *p_idata;
367         
368         memset (p_evt,0,sizeof(evt));
369         p_evt->actual_status=status;
370         p_evt->id=evt_id++;
371         p_evt->evt_type=EVT_INQUIRY_RESULT_WITH_RSSI;
372         p_evt->req_opcode=INQUIRY_CMD_OP;
373         p_evt->p_callback=callback_hci_inquiry_RSSI;
374
375         p_data=malloc(sizeof(inquiry_RSSI_data));
376         p_data->p_address=p_dest_addr;
377         p_data->callback_app_inquiry_RSSI=callback_app_inquiry_RSSI;
378         p_evt->p_data=(void *) p_data;
379         
380         add_evt_toarray(p_evt);
381
382         memset (p_evt,0,sizeof(evt));
383         p_evt->actual_status=istatus;
384         p_evt->id=evt_id++;
385         p_evt->evt_type=EVT_INQUIRY_COMPLETE;
386         p_evt->req_opcode=INQUIRY_CMD_OP;
387         p_evt->p_callback=callback_hci_inquiry_comple;
388
389         p_idata=malloc(sizeof(inquiry_complete_data));
390         p_idata->callback_app_inquiry_complete=callback_app_inquiry_complete;
391         p_evt->p_data = (void *)p_idata;
392         
393         add_evt_toarray(p_evt);
394         
395         if(send_hci_inquiry_cmd()<0)
396         {
397                 perror("send_hci_cmd error");
398                 return -1;
399         }
400         return 0;
401 }
402
403 void tiny_bt_inquiry_register_again(bt_address *p_dest_addr, void(*callback_app_inquiry_RSSI)(bt_address *p_address)){
404         expect_evt evt,*p_evt=&evt;
405         req_state status = ESTABLISHED;
406         inquiry_RSSI_data *p_data;
407         
408         memset (p_evt,0,sizeof(evt));
409         p_evt->actual_status=status;
410         p_evt->id=evt_id++;
411         p_evt->evt_type=EVT_INQUIRY_RESULT_WITH_RSSI;
412         p_evt->req_opcode=INQUIRY_CMD_OP;
413         p_evt->p_callback=callback_hci_inquiry_RSSI;
414
415         p_data=malloc(sizeof(inquiry_RSSI_data));
416         p_data->p_address=p_dest_addr;
417         p_data->callback_app_inquiry_RSSI=callback_app_inquiry_RSSI;
418         p_evt->p_data=(void *) p_data;
419         
420         add_evt_toarray(p_evt);
421 }
422
423 int tiny_bt_connect(bt_address *p_dest_addr, __u16 *p_handle, void( *callback_app_connection_complete)(__u16 *p_handle))
424 {
425         expect_evt evt,*p_evt=&evt;
426         req_state status = ESTABLISHED;
427         connection_complete_data *p_data;
428
429         memset ( p_evt,0,sizeof ( evt ) );
430         p_evt->actual_status=status;
431         p_evt->id=evt_id++;
432         p_evt->evt_type=EVT_CONN_COMPLETE;
433         p_evt->req_opcode=CREATE_CONNECTION_CMD_OP;
434         p_evt->p_callback=callback_hci_create_connection;
435
436         p_data=malloc ( sizeof ( connection_complete_data ) );
437         p_data->p_handle=p_handle;
438         p_data->callback_app_connection_complete=callback_app_connection_complete;
439         p_evt->p_data= ( void * ) p_data;
440
441         add_evt_toarray ( p_evt );
442         if ( send_hci_create_connection_cmd ( p_dest_addr ) <0 )
443         {
444                 perror ( "send_hci_cmd error" );
445                 return -1;
446         }
447         return 0;
448
449 }
450
451 int tiny_bt_wait_for_connection()
452 {
453         return 0;
454 }
455