2 * C Implementation: testovaci
7 * Author: root <root@ubuntu>, (C) 2008
9 * Copyright: See COPYING file that comes with this distribution
14 #include <sys/ioctl.h>
17 #include "tiny_bt_hci_core.h"
18 #include "tiny_bt_hci_cmd.h"
21 static expect_evt evt_array[MAX_CMD_STATE_REQUEST];
23 static int global_index;
24 extern connection_hci connection;
25 /******************************HCI callback functions*********************/
27 static void callback_hci_all_commands(void *p_arg, void *p_recbuf)
30 p_rp = (void *) p_recbuf;
33 perror("command status error\n");
35 exit(-1); // !!!!!!!!!!!!!!!!
38 printf("command status with opcode: %d\n",p_rp->opcode);
42 static void callback_hci_read_bd_addr(void *p_arg, void *p_recbuf)
44 read_bd_addr_data *p_data = p_arg;
45 read_bd_addr_rp *p_rp;
47 p_rp = (void *) (p_recbuf + 3);
48 memcpy(p_data->p_address, &p_rp->bdaddr, 6);
49 p_data->callback_app_read_bd_addr(p_data->p_address);
53 static void callback_hci_read_local_name(void *p_arg, void *p_recbuf)
55 read_local_name_data *p_data = p_arg;
56 read_local_name_rp *p_rp;
58 p_rp = (void *) (p_recbuf + 3);
59 memcpy(p_data->p_name, &p_rp->name, 248);
60 p_data->callback_app_read_local_name(p_data->p_name);
64 static void callback_hci_inquiry_RSSI(void *p_arg, void *p_recbuf)
66 inquiry_RSSI_data *p_data = p_arg;
67 inquiry_info_with_rssi *p_rp;
69 p_rp = (void *) (p_recbuf + 1);
70 memcpy(p_data->p_address, &p_rp->bdaddr, 6);
71 p_data->callback_app_inquiry_RSSI(p_data->p_address);
75 static void callback_hci_inquiry_comple(void *p_arg, void *p_recbuf)
77 inquiry_complete_data *p_data = p_arg;
80 p_byte = (void *) p_recbuf;
82 perror("inquiry complete status error\n");
86 p_data->callback_app_inquiry_complete();
90 static void callback_hci_create_connection(void *p_arg, void *p_recbuf)
92 connection_complete_data *p_data = p_arg;
93 evt_conn_complete *p_rp;
95 p_rp = (void *) (p_recbuf + 3);
96 memcpy(p_data->p_handle, &p_rp->handle, 2);
97 //memcpy(p_data->p_address,&p_rp->bdaddr,6);
98 p_data->callback_app_connection_complete(p_data->p_handle);
102 static void callback_hci_connection_request(void *p_arg, void *p_recbuf)
104 connection_request_data *p_data = p_arg;
105 evt_conn_request *p_rp;
107 p_rp = (void *) (p_recbuf);
108 memcpy(p_data->p_address, &p_rp->bdaddr, 6);
109 p_data->callback_app_connection_request(p_data->p_address);
113 static void callback_hci_disconnect(void *p_arg, void *p_recbuf)
115 disconnect_data *p_data = p_arg;
116 evt_disconn_complete *p_rp;
118 p_rp = (void *) (p_recbuf);
119 p_data->callback_app_disconnect(&p_rp->handle, &p_rp->reason);
123 /******************************array functions*********************/
124 /*fcn add the request at the end of array or replace the oldest request*/
125 void add_evt_toarray(expect_evt *p_evt)
128 int sig = 0,index = 0;
129 expect_evt the_oldest = evt_array[0];
131 for (i = 0; i < MAX_EVT_COUNT; i++) {/*todo use constatns will be better*/
132 if (evt_array[i].actual_status == 0 || evt_array[i].actual_status == 3) {
133 evt_array[i] = *p_evt;
138 /*the smallest id (oldest request) will stay here*/
139 if (evt_array[i].id < the_oldest.id) {
140 the_oldest = evt_array[i];
146 evt_array[index] = *p_evt;
147 global_index = index;
151 int look_up_inarray(__u8 evt_type, __u16 opcode)
154 int index = -1, oldestid = 65535;
156 if (evt_array[global_index].evt_type == evt_type && evt_array[global_index].actual_status != DONE) {
158 if(evt_array[global_index].req_opcode == opcode)
165 for (i = 0; i < MAX_CMD_STATE_REQUEST; i++) {
166 if (evt_array[i].evt_type == evt_type && evt_array[i].actual_status != DONE ) {
168 if (evt_array[i].req_opcode == opcode) {
169 if (evt_array[i].id < oldestid) {
170 oldestid = evt_array[i].id;
175 if (evt_array[i].id < oldestid) {
176 oldestid = evt_array[i].id;
187 /******************************tiny_bt_functions functions*********************/
188 int tiny_bt_init(__u8 dev_id)
190 struct hci_filter nf;
192 expect_evt evt, *p_evt = &evt;
193 connection_hci *p_conn = &connection;
194 req_state status = PERMANENT;
195 connection_state con_state = DISCONNECT;
197 memset(evt_array, 0, MAX_CMD_STATE_REQUEST * sizeof(expect_evt));
201 p_conn->con_state = con_state;
203 memset(p_evt, 0, sizeof(evt));
204 p_evt->actual_status = status;
205 p_evt->id = evt_id++;
206 p_evt->evt_type = EVT_CMD_STATUS;
207 p_evt->p_callback = callback_hci_all_commands;
208 p_evt->p_data = NULL;
209 add_evt_toarray(p_evt);
211 if ((dd = hw_bt_open_device(dev_id)) < 0) {
212 perror("device impossible to open\n");
216 hci_filter_clear(&nf);
217 hci_filter_all_ptypes(&nf);
218 hci_filter_all_events(&nf);
219 // hci_filter_set_opcode(swap_2_bytes(READ_BD_ADDR_CMD_OP),&nf);
221 if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) {
222 perror("some problem with setsockopt\n");
225 printf("init was succesful dd:%d\n",dd);
229 int tiny_bt_process()
233 static int inqRSSI_index = -1;
234 hci_event_hdr *p_hdr;
235 __u8 recbuf[HCI_MAX_EVENT_SIZE], *p_recbuf;
237 len = hw_bt_read(recbuf);
240 printf("Count of received bytes %d\n ", len);
241 for (j = 0; j < len; j++) {
242 printf(" %2.2X ",recbuf[j]);
245 if (recbuf[0] == HCI_EVENT_PKT) {
246 p_hdr = (void *) (recbuf + 1);
247 p_recbuf = (void *) (recbuf + (1 + HCI_EVENT_HDR_SIZE));
248 if (p_hdr->evt == EVT_CMD_COMPLETE) {
249 evt_cmd_complete *p_ccevt;
250 p_ccevt = (void *) p_recbuf;
251 if ((index = look_up_inarray(p_hdr->evt, swap_2_bytes(p_ccevt->opcode))) < 0) {
255 evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
256 if (evt_array[index].actual_status != PERMANENT)
257 evt_array[index].actual_status = DONE;
260 } else if (p_hdr->evt == EVT_INQUIRY_RESULT_WITH_RSSI || p_hdr->evt == EVT_INQUIRY_RESULT) {
261 if ((index = look_up_inarray(EVT_INQUIRY_RESULT_WITH_RSSI, 0)) < 0) {
265 evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
266 if (evt_array[index].actual_status != PERMANENT)
267 evt_array[index].actual_status = DONE;
271 } else if (p_hdr->evt == EVT_MAX_SLOTS_CHANGE || p_hdr->evt == EVT_NUM_COMP_PKTS) {
274 } else if (p_hdr->evt == EVT_INQUIRY_COMPLETE) {
275 if ((index = look_up_inarray(p_hdr->evt, 0)) < 0) {
279 if ((inqRSSI_index = look_up_inarray(EVT_INQUIRY_RESULT_WITH_RSSI, 0)) < 0) {
283 evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
284 if (evt_array[index].actual_status != PERMANENT) {
285 evt_array[index].actual_status = DONE;
286 }// mark inq result evt like a DONE
287 if (evt_array[inqRSSI_index].actual_status != PERMANENT) {
288 free(evt_array[inqRSSI_index].p_data);
289 evt_array[inqRSSI_index].actual_status = DONE;
293 if ((index = look_up_inarray(p_hdr->evt, 0)) < 0) {
297 evt_array[index].p_callback(evt_array[index].p_data, p_recbuf);
298 if (evt_array[index].actual_status != PERMANENT)
299 evt_array[index].actual_status = DONE;
303 } else if (recbuf[0] == HCI_ACLDATA_PKT) {
304 printf("Incoming data:\n");
305 printf("Count of received bytes %d\n ", len);
306 for(j = 0; j < len; j++) {
307 printf("%2.2X ", recbuf[j]);
317 printf("There is no awaiting evt like this\n");
324 printf("Packet have bad format\n");
328 printf("There is no data on socket");
332 int tiny_bt_read_bd_addr(bt_address *p_dest, void(*callback_app_read_bd_addr)(bt_address *p_address))
334 expect_evt evt, *p_evt = &evt;
335 req_state status = ESTABLISHED;
336 read_bd_addr_data *p_data;
338 memset(p_evt, 0, sizeof(evt));
339 p_evt->actual_status = status;
340 p_evt->id = evt_id++;
341 p_evt->evt_type = EVT_CMD_COMPLETE;
342 p_evt->req_opcode = READ_BD_ADDR_CMD_OP;
343 p_evt->p_callback = &callback_hci_read_bd_addr;
345 p_data = malloc(sizeof(read_bd_addr_data));
346 p_data->p_address = p_dest;
347 p_data->callback_app_read_bd_addr = callback_app_read_bd_addr;
348 p_evt->p_data = (void *) p_data;
349 add_evt_toarray(p_evt);
351 if (send_hci_read_bd_addr_cmd() < 0) {
352 perror("send_hci_cmd error\n");
358 int tiny_bt_read_local_name(char *p_name, void(*callback_app_read_local_name)(char *p_name))
360 expect_evt evt, *p_evt = &evt;
361 req_state status = ESTABLISHED;
362 read_local_name_data *p_data;
364 memset (p_evt, 0, sizeof(evt));
365 p_evt->actual_status = status;
366 p_evt->id = evt_id++;
367 p_evt->evt_type = EVT_CMD_COMPLETE;
368 p_evt->req_opcode = READ_LOCAL_NAME_CMD_OP;
369 p_evt->p_callback = callback_hci_read_local_name;
371 p_data = malloc(sizeof(read_local_name_data));
372 p_data->p_name = p_name;
373 p_data->callback_app_read_local_name = callback_app_read_local_name;
374 p_evt->p_data = (void *) p_data;
376 add_evt_toarray(p_evt);
377 if(send_hci_read_local_name_cmd() < 0) {
378 perror("send_hci_cmd error\n");
384 int tiny_bt_inquiry(bt_address *p_dest_addr, void(*callback_app_inquiry_RSSI)(bt_address *p_address), void(*callback_app_inquiry_complete)(void))
386 expect_evt evt,*p_evt = &evt;
387 req_state status = ESTABLISHED;
388 req_state istatus = ESTABLISHED;
389 inquiry_RSSI_data *p_data;
390 inquiry_complete_data *p_idata;
392 memset(p_evt, 0, sizeof(evt));
393 p_evt->actual_status = status;
394 p_evt->id = evt_id++;
395 p_evt->evt_type = EVT_INQUIRY_RESULT_WITH_RSSI;
396 p_evt->req_opcode = INQUIRY_CMD_OP;
397 p_evt->p_callback = callback_hci_inquiry_RSSI;
399 p_data = malloc(sizeof(inquiry_RSSI_data));
400 p_data->p_address = p_dest_addr;
401 p_data->callback_app_inquiry_RSSI = callback_app_inquiry_RSSI;
402 p_evt->p_data = (void *) p_data;
404 add_evt_toarray(p_evt);
406 memset(p_evt, 0, sizeof(evt));
407 p_evt->actual_status = istatus;
408 p_evt->id = evt_id++;
409 p_evt->evt_type = EVT_INQUIRY_COMPLETE;
410 p_evt->req_opcode = INQUIRY_CMD_OP;
411 p_evt->p_callback = callback_hci_inquiry_comple;
413 p_idata = malloc(sizeof(inquiry_complete_data));
414 p_idata->callback_app_inquiry_complete = callback_app_inquiry_complete;
415 p_evt->p_data = (void *)p_idata;
417 add_evt_toarray(p_evt);
419 if(send_hci_inquiry_cmd()<0) {
420 perror("send_hci_cmd error");
426 void tiny_bt_inquiry_register_again(bt_address *p_dest_addr, void(*callback_app_inquiry_RSSI)(bt_address *p_address))
428 expect_evt evt, *p_evt = &evt;
429 req_state status = ESTABLISHED;
430 inquiry_RSSI_data *p_data;
432 memset(p_evt, 0, sizeof(evt));
433 p_evt->actual_status = status;
434 p_evt->id = evt_id++;
435 p_evt->evt_type = EVT_INQUIRY_RESULT_WITH_RSSI;
436 p_evt->req_opcode = INQUIRY_CMD_OP;
437 p_evt->p_callback = callback_hci_inquiry_RSSI;
439 p_data = malloc(sizeof(inquiry_RSSI_data));
440 p_data->p_address = p_dest_addr;
441 p_data->callback_app_inquiry_RSSI = callback_app_inquiry_RSSI;
442 p_evt->p_data = (void *) p_data;
444 add_evt_toarray(p_evt);
447 int tiny_bt_connect(bt_address *p_dest_addr, __u16 *p_handle, void( *callback_app_connection_complete)(__u16 *p_handle))
449 expect_evt evt, *p_evt = &evt;
450 req_state status = ESTABLISHED;
451 connection_complete_data *p_data;
453 memset(p_evt, 0, sizeof(evt));
454 p_evt->actual_status = status;
455 p_evt->id = evt_id++;
456 p_evt->evt_type = EVT_CONN_COMPLETE;
457 p_evt->req_opcode = CREATE_CONNECTION_CMD_OP;
458 p_evt->p_callback = callback_hci_create_connection;
460 p_data = malloc(sizeof(connection_complete_data));
461 p_data->p_handle = p_handle;
462 p_data->callback_app_connection_complete = callback_app_connection_complete;
463 p_evt->p_data = (void *) p_data;
465 add_evt_toarray (p_evt);
466 if (send_hci_create_connection_cmd(p_dest_addr) < 0) {
467 perror("send_hci_cmd error\n");
474 void tiny_bt_wait_for_connection(bt_address *p_dest_addr, void(*callback_app_conection_request)(bt_address *p_address))
476 expect_evt evt, *p_evt = &evt;
477 req_state status = ESTABLISHED;
478 connection_request_data *p_data;
480 memset(p_evt, 0, sizeof(evt));
481 p_evt->actual_status = status;
482 p_evt->id = evt_id++;
483 p_evt->evt_type = EVT_CONN_REQUEST;
484 p_evt->p_callback = callback_hci_connection_request;
486 p_data = malloc(sizeof(connection_request_data));
487 p_data->p_address = p_dest_addr;
488 p_data->callback_app_connection_request = callback_app_conection_request;
489 p_evt->p_data = (void*) p_data;
491 add_evt_toarray(p_evt);
494 int tiny_bt_accept_connection(bt_address *p_dest_addr, __u16 *p_handle, void(*callback_app_connection_complete)(__u16 *p_handle))
496 expect_evt evt, *p_evt = &evt;
497 req_state status = ESTABLISHED;
498 connection_complete_data *p_data;
500 memset(p_evt, 0, sizeof(evt));
501 p_evt->actual_status = status;
502 p_evt->id = evt_id++;
503 p_evt->evt_type = EVT_CONN_COMPLETE;
504 p_evt->req_opcode = ACCEPT_CONNECTION_REQ_OP;
505 p_evt->p_callback = callback_hci_create_connection;
507 p_data = malloc(sizeof(connection_complete_data));
508 p_data->p_handle = p_handle;
509 p_data->callback_app_connection_complete = callback_app_connection_complete;
510 p_evt->p_data = (void *) p_data;
512 add_evt_toarray(p_evt);
513 // and register disconnect event
514 if (send_hci_accept_conn_req_cmd(p_dest_addr) < 0) {
515 perror("send_hci_cmd error\n");
521 void tiny_bt_disconnect_register(void(*callback_app_disconnect)(__u16 *p_handle, __u8 *p_reason))
523 expect_evt evt, *p_evt = &evt;
524 req_state status = ESTABLISHED;
525 disconnect_data *p_data;
527 memset(p_evt, 0, sizeof(evt));
528 p_evt->actual_status = status;
529 p_evt->id = evt_id++;
530 p_evt->evt_type = EVT_DISCONN_COMPLETE;
531 p_evt->p_callback = callback_hci_disconnect;
533 p_data = malloc(sizeof(disconnect_data));
534 p_data->callback_app_disconnect = callback_app_disconnect;
535 p_evt->p_data = (void *) p_data;
537 add_evt_toarray(p_evt);
540 int tiny_bt_disconnect(__u16 *p_handle, void(*callback_app_disconnect)(__u16 *p_handle, __u8 *p_reason))
542 expect_evt evt, *p_evt = &evt;
543 req_state status = ESTABLISHED;
544 disconnect_data *p_data;
546 memset(p_evt, 0, sizeof(evt));
547 p_evt->actual_status = status;
548 p_evt->id = evt_id++;
549 p_evt->evt_type = EVT_DISCONN_COMPLETE;
550 p_evt->p_callback = callback_hci_disconnect;
552 p_data = malloc(sizeof(disconnect_data));
553 p_data->callback_app_disconnect = callback_app_disconnect;
554 p_evt->p_data = (void *) p_data;
556 add_evt_toarray(p_evt);
558 if (send_hci_disconnect_cmd(*p_handle) < 0) {
559 perror ("send_hci_cmd error\n");
566 int tiny_bt_send_data(char *p_data, __u16 lenght, __u16 *p_chandle)
568 if (send_hci_data(p_data, lenght, p_chandle) < 0) {
569 perror ("send_hci_cmd error\n");