3 /*******************************************************************
\r
6 hci_event_acc.c - Event fce (bth specification) - build event
\r
9 Copyright (C) 2006 by Petr Kovacik petr_kovacik@gmail.com
\r
11 *******************************************************************/
\r
19 #include "hci_event.h"
\r
20 #include "hci_command.h"
\r
23 #include <periph/sci_rs232.h>
\r
25 #include "inline_fce.h"
\r
29 typedef int (*bth_info_fce_def)(uint8_t *bth_p, uint8_t size);
\r
31 bth_info_fce_def bth_info_fce_ogf_01[]={
\r
32 cmd_ev_none, cmd_ev_none,cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none,
\r
33 cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_01x000b, cmd_ev_none, cmd_ev_01x000d, cmd_ev_01x000e,
\r
34 cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none,
\r
35 cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none,
\r
37 #define BTH_OGF_01_FC (sizeof(bth_info_fce_ogf_01)/sizeof(bth_info_fce_ogf_01[0]))
\r
40 bth_info_fce_def bth_info_fce_ogf_02[]={
\r
41 cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none,
\r
42 cmd_ev_none, cmd_ev_02x0009, cmd_ev_none, cmd_ev_none, cmd_ev_02x000C, cmd_ev_02x000D};
\r
43 #define BTH_OGF_02_FC (sizeof(bth_info_fce_ogf_02)/sizeof(bth_info_fce_ogf_02[0]))
\r
46 bth_info_fce_def bth_info_fce_ogf_03[]={
\r
47 cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none,
\r
48 cmd_ev_03x0008, cmd_ev_03x0009, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_03x000d, cmd_ev_none, cmd_ev_none,
\r
49 cmd_ev_none, cmd_ev_03x0011, cmd_ev_03x0012, cmd_ev_none, cmd_ev_03x0014, cmd_ev_03x0015,
\r
50 cmd_ev_none, cmd_ev_03x0017, cmd_ev_none, cmd_ev_03x0019, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_03x001d,
\r
51 cmd_ev_none, cmd_ev_03x001f, cmd_ev_none, cmd_ev_03x0021, cmd_ev_none, cmd_ev_03x0023, cmd_ev_none, cmd_ev_03x0025,
\r
52 cmd_ev_none, cmd_ev_03x0027, cmd_ev_03x0028, cmd_ev_03x0029, cmd_ev_none, cmd_ev_03x002b, cmd_ev_none, cmd_ev_03x002d,
\r
53 cmd_ev_03x002e, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_none, cmd_ev_03x0036,
\r
54 cmd_ev_none, cmd_ev_03x0038, cmd_ev_03x0039, cmd_ev_none, cmd_ev_03x003b,
\r
55 cmd_ev_none, cmd_ev_03x003d};
\r
56 #define BTH_OGF_03_FC (sizeof(bth_info_fce_ogf_03)/sizeof(bth_info_fce_ogf_03[0]))
\r
59 bth_info_fce_def bth_info_fce_ogf_04[]={
\r
60 cmd_ev_none, cmd_ev_04x0001, cmd_ev_none, cmd_ev_04x0003, cmd_ev_none, cmd_ev_04x0005, cmd_ev_none, cmd_ev_04x0007,
\r
61 cmd_ev_none, cmd_ev_04x0009};
\r
62 #define BTH_OGF_04_FC (sizeof(bth_info_fce_ogf_04)/sizeof(bth_info_fce_ogf_04[0]))
\r
66 /*********************************************************************************/
\r
69 0 = OK - command removed from the queue
\r
70 -1 = the queue was searched but the OPCODE was not found
\r
71 +num = an index of verified item in array "bth_pole_adrr_check_packet" with the searched opcode
\r
73 int bth_del_event(uint16_t opcode)
\r
76 uint16_t opcode_pkt;
\r
77 for(i=0;i<LENCOMMAND;i++)
\r
79 if(bth_array_adrr_check_packet[i]!=NULL)
\r
81 __bthtomc16(&opcode_pkt,((uint8_t*)bth_array_adrr_check_packet[i]+HCI_PKT_SIZE));
\r
82 if(opcode_pkt==opcode)
\r
89 /****************************************************************************/
\r
90 /*------------------------ INDIVIDUAL EVENT FUNCTIONS ----------------------*/
\r
91 /****************************************************************************/
\r
92 /****************************************************************************/
\r
96 2 = there was no commands in the confirmation queue to confirm
\r
97 3 = status embody an error of the command
\r
99 int bth_evt_none(uint8_t *bth_p, uint8_t size) //func with nonexisting index of event code
\r
105 int bth_evt_inquiry_complete(uint8_t *bth_p, uint8_t size) //0x01 - EVT_INQUIRY_COMPLETE
\r
108 return (*((uint8_t*)bth_p));
\r
110 int bth_evt_inquiry_result(uint8_t *bth_p, uint8_t size) //0x02
\r
116 int bth_evt_conn_complete(uint8_t *bth_p, uint8_t size) //0x03
\r
118 bths_connect_bluet *bth_q;
\r
121 for(j=0; j<=8;j++) //8 possible devices, witch which we can comunicate
\r
123 if(bth_connected[j]==NULL)
\r
126 if(j==9){return (-1);}; //it is possible to communicate with 8 devices at maximum. This one is the 9th one.
\r
127 /* Add the device to the list od connected devices.*/
\r
128 bth_connected[j]=(bths_connect_bluet*)calloc(1,sizeof(bths_connect_bluet));
\r
129 bth_q=(bths_connect_bluet*)bth_connected[j];
\r
130 /*Fill the structure of the connected device with information on remote device*/
\r
131 memcpy(&(bth_q->bdaddr),(uint8_t*)bth_p+EVT_CONN_COMPLETE____bdaddr,sizeof(bdaddr_t));
\r
132 // store_le16(&(bth_q->handle),(uint16_t)*(uint16_t*)((uint8_t*)bth_p+EVT_CONN_COMPLETE____handle));
\r
133 __bthtomc16((uint8_t*)&(bth_q->handle),((uint8_t*)bth_p+EVT_CONN_COMPLETE____handle));
\r
134 /* sci_rs232_sendch('c',sci_rs232_chan_default); //do PC
\r
135 VypisHexa((void*)&(((bths_connect_bluet*)bth_connected[j])->handle),2);
\r
136 sci_rs232_sendch('c',sci_rs232_chan_default); //do PC*/
\r
138 store8(bth_q->link_type,*((uint8_t*)bth_p+EVT_CONN_COMPLETE____link_type));
\r
139 store8(bth_q->encr_mode,*((uint8_t*)bth_p+EVT_CONN_COMPLETE____encr_mode));
\r
141 bth_cmd_write_link_policy_settings(bth_q->handle,htobs(0x000f)); //reply
\r
142 return (*((uint8_t*)bth_p+EVT_CONN_COMPLETE____status));
\r
145 int bth_evt_conn_request(uint8_t *bth_p, uint8_t size) //0x04
\r
148 // evt_conn_request bth_q;
\r
149 /*BD address of requesting device*/
\r
150 memcpy(&bdaddr,(uint8_t*)bth_p+EVT_CONN_REQUEST____bdaddr,sizeof(bdaddr_t));
\r
151 // if(bth_seach_bdaddr(&bdaddr,&(bth_accept_bd_addr[0]),1));
\r
152 bth_accept_conn_req_cp(&bdaddr);
\r
158 int bth_evt_disconn_complete(uint8_t *bth_p, uint8_t size) //0x05
\r
161 evt_disconn_complete bth_q;
\r
162 // store_le16(&bth_q.handle,*((uint16_t*)((uint8_t*)bth_p+EVT_DISCONN_COMPLETE____status)));
\r
163 __bthtomc16((uint8_t*)&(bth_q.handle),((uint8_t*)bth_p+EVT_DISCONN_COMPLETE____status));
\r
164 i=bth_find_conected_dev(bth_q.handle);
\r
165 free(bth_connected[i]); bth_connected[i]=NULL;
\r
166 // bth_local_info.busy=0;
\r
167 if(*((uint8_t*)bth_p+EVT_DISCONN_COMPLETE____reason)==0)
\r
168 return (*((uint8_t*)bth_p+EVT_DISCONN_COMPLETE____status));
\r
170 return (*((uint8_t*)bth_p+EVT_DISCONN_COMPLETE____reason));
\r
173 int bth_evt_auth_complete(uint8_t *bth_p, uint8_t size) //0x06
\r
178 int bth_remote_name_req_complete(uint8_t *bth_p, uint8_t size) //0x07
\r
183 int bth_evt_encrypt_cahnge(uint8_t *bth_p, uint8_t size) //0x08
\r
188 int bth_evt_change_conn_link_key_complete(uint8_t *bth_p, uint8_t size) //0x09
\r
193 int bth_evt_master_link_key_complete(uint8_t *bth_p, uint8_t size) //0x0A
\r
198 int bth_evt_read_remote_features_complete(uint8_t *bth_p, uint8_t size) //0x0B
\r
203 int bth_evt_read_remote_version_complete(uint8_t *bth_p, uint8_t size) //0x0C
\r
208 int bth_evt_qos_setup_complete(uint8_t *bth_p, uint8_t size) //0x0D
\r
213 int bth_evt_cmd_complete(uint8_t *bth_p, uint8_t size) //0x0E
\r
215 evt_cmd_complete bth_q;
\r
216 uint16_t opcode,ogf,ocf;
\r
219 store8(bth_q.ncmd,*((uint8_t*)bth_p+EVT_CMD_COMPLETE____ncmd));
\r
220 // store_le16(&bth_q.opcode,*((uint16_t*)((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode)));
\r
221 __bthtomc16(&bth_q.opcode,(((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode)));
\r
222 index=bth_del_event(bth_q.opcode);
\r
229 if(size-EVT_CMD_COMPLETE_SIZE==1) /* this is just a confirmation - status*/
\r
231 if(*((uint8_t*)bth_p+3)==0)
\r
233 free(bth_array_adrr_check_packet[index]);
\r
234 bth_array_adrr_check_packet[index]=NULL;
\r
235 bth_local_info.busy=0;
\r
236 return 0; //no complications was encountered during command execution
\r
240 /*status is not OK - an error occured - the sent command is still in the confirmation queue */
\r
241 free(bth_array_adrr_check_packet[index]);
\r
242 bth_array_adrr_check_packet[index]=NULL;
\r
243 bth_local_info.busy=0;
\r
244 return((int)*((uint8_t*)bth_p+EVT_CMD_COMPLETE_SIZE));
\r
249 /*I split to obcode to OGF and OCF and convert it to an one-byte variable*/
\r
250 // store_le16(&opcode,*(uint16_t*)((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode));
\r
251 __bthtomc16((uint8_t*)&(opcode),((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode));
\r
253 ogf=(uint8_t)cmd_opcode_ogf(opcode);
\r
254 ocf=(uint8_t)cmd_opcode_ocf(opcode);
\r
259 bth_local_info.busy=0;
\r
260 if(ocf<BTH_OGF_01_FC)
\r
261 return (bth_info_fce_ogf_01[ocf](((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode+2),EVT_CMD_COMPLETE_SIZE));
\r
264 bth_local_info.busy=0;
\r
265 if(ocf<BTH_OGF_02_FC)
\r
266 return (bth_info_fce_ogf_02[ocf](((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode+2),size-EVT_CMD_COMPLETE_SIZE)); //the number 0x00 is a random guess
\r
269 bth_local_info.busy=0;
\r
270 if(ocf<BTH_OGF_03_FC)
\r
271 return (bth_info_fce_ogf_03[ocf](((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode+2),size-EVT_CMD_COMPLETE_SIZE)); //the number 0x00 is a random guess
\r
275 bth_local_info.busy=0;
\r
276 if(ocf<BTH_OGF_04_FC)
\r
277 return (bth_info_fce_ogf_04[ocf](((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode+2),size-EVT_CMD_COMPLETE_SIZE)); //the number 0x00 is a random guess
\r
287 int bth_evt_cmd_status(uint8_t *bth_p, uint8_t size) //0x0F
\r
289 evt_cmd_status bth_q;
\r
290 store8(bth_q.status,*((uint8_t*)bth_p+EVT_CMD_STATUS____status));
\r
291 store8(bth_q.ncmd,*((uint8_t*)bth_p+EVT_CMD_STATUS____ncmd));
\r
292 // store_le16(&bth_q.opcode,*((uint16_t*)((uint8_t*)bth_p+EVT_CMD_STATUS____opcode)));
\r
293 __bthtomc8(&bth_q.opcode,(((uint8_t*)bth_p+EVT_CMD_STATUS____opcode)));
\r
294 // memcpy(&bth_q.opcode,(((uint8_t*)bth_p+EVT_CMD_STATUS____opcode)),2);
\r
298 index=bth_del_event(bth_q.opcode);
\r
301 bth_local_info.busy=0;
\r
306 if(size-EVT_CMD_STATUS_SIZE==0) /*this is just a confirmation - status*/
\r
308 if(bth_q.status==0)
\r
310 free(bth_array_adrr_check_packet[index]);
\r
311 bth_array_adrr_check_packet[index]=NULL;
\r
315 /*status is not OK - an error occured - the sent command is still in the confirmation queue */
\r
316 free(bth_array_adrr_check_packet[index]);
\r
317 bth_array_adrr_check_packet[index]=NULL;
\r
322 /*rozdelim obcode na OGF a OCF a prevedu na jednobytovou promenou*/ //same comment as in previous function
\r
323 ogf=(uint8_t)cmd_opcode_ogf((uint16_t)*(uint16_t*)((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode));
\r
324 ocf=(uint8_t)cmd_opcode_ocf((uint16_t)*(uint16_t*)((uint8_t*)bth_p+EVT_CMD_COMPLETE____opcode));
\r
325 /*This is a little more complicated cmd_status, which stores data inside and not the end. Other functions are split according to the obcode. Currently, functions are not implemented, only the "guidepost" is done.*/
\r
326 /*jedna se o slozitejsi cmd_status, ktery sebou nese i data, nikoliv zaver, dalsi fce jsou deleny podle
\r
327 obcodu. Fce nejsou napsany, je udelany pouze rozcestnik*/
\r
336 bth_local_info.busy=0; //NOTE do it differently, not always true
\r
339 return(bth_q.status);
\r
342 int bth_evt_hardware_error(uint8_t *bth_p, uint8_t size) //0x10
\r
347 int bth_evt_flush_occurred(uint8_t *bth_p, uint8_t size) //0x11
\r
352 int bth_evt_role_cahage(uint8_t *bth_p, uint8_t size) //0x12
\r
357 int bth_evt_num_comp_pkts(uint8_t *bth_p, uint8_t size) //0x13
\r
359 evt_num_comp_pkts bth_q;
\r
360 uint16_t handle,num_pkt;
\r
362 store16(bth_q.num_hndl,*((uint8_t*)bth_p+EVT_NUM_COMP_PKTS____num_hndl));
\r
363 /*Search through all devices with which the communications was started???*/
\r
364 /*prohledam vsechna zarizeni, se kterymi mam uzavrenou komunikaci*/
\r
365 for(j=0; j<(bth_q.num_hndl);j++)
\r
367 __bthtomc16((uint8_t*)&(handle),((uint8_t*)bth_p+1+(j*4)));
\r
369 __bthtomc16((uint8_t*)&(num_pkt),((uint8_t*)bth_p+3+(j*4)));
\r
373 if(bth_connected[i]!=NULL)
\r
375 if(bth_connected[i]->handle==handle)
\r
377 // sci_rs232_sendch(';',sci_rs232_chan_default); //do PC
\r
378 // VypisHexa((void*)&(handle),2);
\r
379 // sci_rs232_sendch(';',sci_rs232_chan_default); //do PC
\r
385 bth_local_info.busy=0;
\r
389 int bth_evt_mode_change(uint8_t *bth_p, uint8_t size) //0x14
\r
394 int bth_evt_return_link_keys(uint8_t *bth_p, uint8_t size) //0x15
\r
399 int bth_evt_pin_code_req(uint8_t *bth_p, uint8_t size) //0x16
\r
404 int bth_evt_link_key_req(uint8_t *bth_p, uint8_t size) //0x17
\r
409 int bth_evt_link_key_notify(uint8_t *bth_p, uint8_t size) //0x18
\r
414 int bth_evt_loopback_command(uint8_t *bth_p, uint8_t size) //0x19
\r
419 int bth_evt_data_buffer_overflow(uint8_t *bth_p, uint8_t size) //0x1A
\r
424 int bth_evt_max_slots_change(uint8_t *bth_p, uint8_t size) //0x1B
\r
426 evt_max_slots_change bth_q;
\r
428 // store_le16(&bth_q.handle,*((uint16_t*)((uint8_t*)bth_p+EVT_MAX_SLOTS_CHANGE____handle)));
\r
429 __bthtomc16((uint8_t*)&(bth_q.handle),(uint8_t*)bth_p+EVT_MAX_SLOTS_CHANGE____handle);
\r
431 // store_le16(&bth_q.max_slots,*((uint16_t*)((uint8_t*)bth_p+EVT_MAX_SLOTS_CHANGE____max_slots)));
\r
432 __bthtomc16((uint8_t*)&(bth_q.max_slots),(uint8_t*)bth_p+EVT_MAX_SLOTS_CHANGE____max_slots);
\r
434 /*Search through all devices with which the communications was started???*/
\r
435 /*prohledam vsechna zarizeni, se kterymi mam uzavrenou komunikaci*/
\r
438 /* sci_rs232_sendch('j',sci_rs232_chan_default); //do PC
\r
439 VypisHexa((void*)&(((bths_connect_bluet*)bth_connected[i])->handle),2);
\r
440 sci_rs232_sendch('j',sci_rs232_chan_default); //do PC*/
\r
441 if(bth_connected[i]!=NULL)
\r
444 /* sci_rs232_sendch('k',sci_rs232_chan_default); //do PC
\r
445 VypisHexa((void*)&(bth_q.handle),2);
\r
446 sci_rs232_sendch('k',sci_rs232_chan_default); //do PC*/
\r
448 if(bth_connected[i]->handle==bth_q.handle)
\r
451 bth_connected[i]->max_slots=bth_q.max_slots;
\r
459 int bth_evt_read_clock_offset_complete(uint8_t *bth_p, uint8_t size) //0x1C
\r
464 int bth_evt_conn_ptype_changed(uint8_t *bth_p, uint8_t size) //0x1D
\r
466 evt_conn_ptype_changed bth_q;
\r
467 // uint16_t local_ptype;
\r
469 store16(bth_q.status,*((uint8_t*)bth_p+EVT_CONN_PTYPE_CHANGED____status));
\r
470 // store_le16(&bth_q.handle,*((uint16_t*)((uint8_t*)bth_p+EVT_CONN_PTYPE_CHANGED____handle)));
\r
471 __bthtomc16((uint8_t*)&(bth_q.handle),(uint8_t*)bth_p+EVT_CONN_PTYPE_CHANGED____handle);
\r
473 // store_le16(&bth_q.ptype,*((uint16_t*)((uint8_t*)bth_p+EVT_CONN_PTYPE_CHANGED____ptype)));
\r
474 __bthtomc16((uint8_t*)&(bth_q.ptype),(uint8_t*)bth_p+EVT_CONN_PTYPE_CHANGED____ptype);
\r
476 dev_num=bth_find_conected_dev(bth_q.handle);
\r
477 //bth_local_info.pkt_type; - local info on packets
\r
478 // Change_Connection_Packet_Type - command, which can in case of need setup its packets
\r
479 //skterym se pripadne daji nastavit svoje packety
\r
482 bth_connected[dev_num]->ptype=bth_q.ptype;
\r
483 return(bth_q.status);
\r
489 int bth_evt_qos_violation(uint8_t *bth_p, uint8_t size) //0x1E
\r
495 int bth_evt_page_scan_mode_change(uint8_t *bth_p, uint8_t size) //0x1F
\r
502 int bth_evt_pscan_rep_mode_change(uint8_t *bth_p, uint8_t size) //0x20
\r
504 evt_pscan_rep_mode_change bth_q;
\r
505 memcpy(&(bth_q.bdaddr),(uint8_t*)bth_p+EVT_PSCAN_REP_MODE_CHANGE____bdaddr,sizeof(bdaddr_t));
\r
506 store16(bth_q.pscan_rep_mode,*((uint8_t*)bth_p+EVT_PSCAN_REP_MODE_CHANGE____pscan_rep_mode));
\r
508 /*Search through all devices with which the communications was started, needs to be written up */
\r
509 /*prohledam vsechna zarizeni dle BDADDR, se kterymi mam uzavrenou komunikaci -NUTNO DOPSAT NOTE*/
\r
515 int bth_evt_flow_spec_complete(uint8_t *bth_p, uint8_t size) //0x21
\r
520 int bth_evt_inquiry_result_with_rssi(uint8_t *bth_p, uint8_t size) //0x22
\r