1 /*******************************************************************
4 bth_main.c - API bth library (recieve, send ...)
6 Copyright (C) 2006 by Petr Kovacik petr_kovacik@gmail.com
8 *******************************************************************/
9 #include <bth_config.h>
14 #include <periph/sci_rs232.h>
15 #include <system_def.h>
25 #include "hci_event.h"
26 #include "hci_command.h"
27 #include "hci_error.h"
29 //#include "hci_lib.h"
30 #include "bth_receive.h"
31 #include "inline_fce.h"
32 #include "bth_inface.h"
33 #include "bth_fce_out.h"
34 #include "bth_h8s2638.h"
37 #define BTH_BUF_LEN 300
39 /*--------BD address whitch are accept for connection-------------*/
40 bdaddr_t bth_accept_bd_addr[]={};
42 /*----------------local device info (master) -----------------------*/
43 bths_dev_info bth_local_info;//={0,{0,0,0,0,0,0,0,0},{0,0,0},0,{0,0,0},0};
45 /*----------------conect device info (slave) -----------------------*/
46 bths_connect_bluet* bth_connected[8];
48 /*-------------------------------- recieve data buffer -----------------------------*/
49 bth_que_t bth_rs232_que_in;
50 //bth_que_t bth_inface_que_in;
51 //bth_que_t bth_inface_que_out;
55 void *bth_array_adrr_comm_packet[LENCOMMAND]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
56 bths_command_buf_info bth_com_buf_info={LENCOMMAND,0,0};
57 /***********************************************************************************/
58 void *bth_array_adrr_check_packet[LENCOMMAND]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
59 bths_command_buf_info bth_check_buf_info={LENCOMMAND,0,0};
60 /***********************************************************************************/
62 /*FIXME this check synchronisation of received data using TPU unit of CPU*/
63 uint8_t bth_controll_flag=0;
66 /**-------------------------------------------------------------------------------*/
67 /*FIXME ----- sending of command, if the local bluetooth is free (ready to send)------*/
68 /* 0 = data moved to SCI buffer = they will be sent, bluetooth device is free
69 1 = it wasn't possible to move tha command to SCI bufferu, but bluet device is free
70 2 = bluetooth device is busy, ie. data were not moved to the bufferu
71 3 = there is no space left in confirmation queue*/
74 * After this function is called, the packet, which is in the command queue, is sent. If there is no new
75 * packet or the device is busy, nothing is done.
77 * Po zavolani funkce, se odesle paket, ktery je zarazen ve fronte paketu k odeslani (bth zazizeni je
78 * volne), pokud neni novy paket nebo zazizeni neni volne, nic se nevykona
80 int bth_send_queue(void)
84 if(bth_local_info.busy!=0)
85 {return 1;}; //device is busy
86 if(bth_com_buf_info.aktual==bth_com_buf_info.sent) //PRAVDEPODOBNE neni co odesilat
88 if(bth_com_buf_info.sent<(LENCOMMAND-2))
90 if(bth_array_adrr_comm_packet[bth_com_buf_info.sent+1]==NULL)
91 {return 1;}; //There is certainly nothing to send
95 if(bth_array_adrr_comm_packet[0]==NULL)
96 {return 1;}; //There is certainly nothing to send
100 /*bth_send_packet(AdrFrom,howmanyBytes;)*/
101 switch(*(uint8_t*)bth_array_adrr_comm_packet[bth_com_buf_info.sent])
103 case HCI_ACLDATA_PKT:
104 __bthtomc16((uint8_t*)&(hp_size),((uint8_t*)bth_array_adrr_comm_packet[bth_com_buf_info.sent])+HCI_PKT_SIZE+HCI_ACL_HDR____dlen);
105 hp_size=hp_size+HCI_ACL_HDR_SIZE+HCI_PKT_SIZE;
106 if(!(bth_send_packet(bth_array_adrr_comm_packet[bth_com_buf_info.sent],hp_size)))
108 free(bth_array_adrr_comm_packet[bth_com_buf_info.sent]);
109 bth_array_adrr_comm_packet[bth_com_buf_info.sent]=NULL;
110 if(bth_com_buf_info.sent<(LENCOMMAND-2)){bth_com_buf_info.sent++;}
111 else{ bth_com_buf_info.sent=0;};
114 free(bth_array_adrr_comm_packet[bth_com_buf_info.sent]);
115 bth_array_adrr_comm_packet[bth_com_buf_info.sent]=NULL;
117 case HCI_COMMAND_PKT:
118 hp_size=((uint16_t)*(((uint8_t*)bth_array_adrr_comm_packet[bth_com_buf_info.sent])+HCI_PKT_SIZE+2)+HCI_COMMAND_HDR_SIZE+HCI_PKT_SIZE);
119 if(!(bth_send_packet(bth_array_adrr_comm_packet[bth_com_buf_info.sent],hp_size)))
120 {/*sent - add the command to allow confirmation*/
121 for(i=0; i<LENCOMMAND; i++)
123 if(bth_array_adrr_check_packet[i]==NULL)
125 bth_array_adrr_check_packet[i]=bth_array_adrr_comm_packet[bth_com_buf_info.sent];
126 bth_array_adrr_comm_packet[bth_com_buf_info.sent]=NULL;
127 /*set the address for the next command - principle of ring buffer*/
128 if(bth_com_buf_info.sent<(LENCOMMAND-2)){bth_com_buf_info.sent++;}
129 else{ bth_com_buf_info.sent=0;};
143 * Convert hexadecimal character to ASCII. It is then sent to serial line
145 //*************************** bth_conv_char_text *****************************
146 // used to convers int into ascii letter and print it on serial
147 // INPUT zn: interger to convert and print
149 //***************************************************************************
150 void bth_conv_char_text(uint8_t zn)
155 uint8_t map_leters[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
156 sci_rs232_sendch(map_leters[val],sci_rs232_chan_default);
158 sci_rs232_sendch(map_leters[val],sci_rs232_chan_default);
166 *Inserts a character to the queue
169 static inline int bth_que_put(bth_que_t *q, int c)
172 p=q->ip; //FIXME set us to the actual position in the file
173 *(p++)=c; //store the character to the next byte
174 if(p==q->buf_end) return -1;//this is not the ring buffer p=q->buf_beg;
175 // if(p==q->op) return -1;
177 return 0; //in case of success return the character, otherwise -1
183 *received HCI data packet is sent as point to point
186 int bth_pkt_type_pointopoint(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
188 l2cap_hdr bth_l2cap_packet;
196 case 0x20:/*first data packet L2CAP*/
197 bth_dev_num=bth_find_conected_dev(handle);
198 __bthtomc16((uint8_t*)&(bth_l2cap_packet.len),(uint8_t*)bth_p+L2CAP_HDR____len);
199 __bthtomc16((uint8_t*)&(bth_l2cap_packet.cid),(uint8_t*)bth_p+L2CAP_HDR____cid);
204 switch((uint8_t)(bth_l2cap_packet.cid))
209 l2cap_signaling(((uint8_t*)bth_p+L2CAP_CMD_HDR_SIZE),(size+L2CAP_HDR____len),bth_dev_num);
214 /*FIXME real data ...*/
215 /*We have to find the channel with the CID number for device bth_dev_num*/
216 if(bth_find_chanal(bth_dev_num, bth_l2cap_packet.cid)>-1)
218 /*here are the received data, which are not used for confguration */
221 bth_data=(uint8_t*)bth_p+L2CAP_HDR_SIZE;
222 bth_size_data=size-L2CAP_HDR_SIZE;
224 // uint8_t odesli[]={'a','h','o','j'};
225 for(i=0; i<bth_size_data;i++)
227 flag=bth_inface_r_isr(0, *((uint8_t*)bth_data+i));
230 // sci_rs232_sendch(*((uint8_t*)bth_data+i),sci_rs232_chan_default); //do PC
231 // VypisHexa((void*)((uint8_t*)bth_data+i),1);
234 /*queue is full, neni schopen prijmout dalsi znaky*/
235 // sci_rs232_sendch('.',sci_rs232_chan_default); //do PC
239 // VypisHexa(bth_data,bth_size_data);
245 case 0x40: return(-3); /*next data packet L2CAP*/ /*function is not written, I receive only one pakcet of the message*/
246 case 0x30: return (-4); /*Reserved for future use*/
247 case 0x00: return (-4); /*Reserved for future use*/
254 *Received HCI data packet is sent as broadcast (not finished function)
256 int bth_pkt_type_broadcast(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
260 case 0x20:/*first data packet L2CAP*/
261 return(-3); /*neni napsano pro prijem znaku broadcast cestou*/
262 case 0x40: return(-3); /*next data packet L2CAP*/ /*funkce neni rozepsana, prijmam jen 1pkt zpravy*/
263 case 0x30: return (-4); /*Reserved for future use*/
264 case 0x00: return (-4); /*Reserved for future use*/
272 *Received HCI data packet is send to piconet (not finished function)
274 int bth_pkt_type_piconet(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
278 case 0x20:/*first data packet L2CAP*/
279 return(-3); /*neni napsano pro prijem znaku piconet cestou*/
280 case 0x40: return(-3); /*next data packet L2CAP*/ /*funkce neni rozepsana, prijmam jen 1pkt zpravy*/
281 case 0x30: return (-4); /*Reserved for future use*/
282 case 0x00: return (-4); /*Reserved for future use*/
290 *Reserved for future (not finished)
292 int bth_pkt_type_reserved(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
298 /****************************************************************************/
299 /****************************************************************************/
302 *pointers to functions. Functions are called according to the received HCI pakcet
304 typedef int (*bth_kind_pkt)(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size);
305 bth_kind_pkt bth_char_pkt_fce[]={
306 bth_pkt_type_pointopoint, bth_pkt_type_broadcast, bth_pkt_type_piconet, bth_pkt_type_reserved};
307 #define COM_PROT_SUM_FC (sizeof(bth_char_pkt_fce)/sizeof(bth_char_pkt_fce[0]))
311 *pointrs to functions. Functions are called according to the event code, decoded from the received HCI packet
313 typedef int (*bth_p_ivent_fce)(uint8_t *bth_p, uint8_t size);
314 bth_p_ivent_fce bth_event_array_fce[]={bth_evt_none,bth_evt_inquiry_complete, bth_evt_inquiry_result,
315 bth_evt_conn_complete, bth_evt_conn_request, bth_evt_disconn_complete,
316 bth_evt_auth_complete, bth_remote_name_req_complete,
317 bth_evt_encrypt_cahnge, bth_evt_change_conn_link_key_complete,
318 bth_evt_master_link_key_complete, bth_evt_read_remote_features_complete,
319 bth_evt_read_remote_version_complete, bth_evt_qos_setup_complete,
320 bth_evt_cmd_complete, bth_evt_cmd_status, bth_evt_hardware_error,
321 bth_evt_flush_occurred, bth_evt_role_cahage, bth_evt_num_comp_pkts,
322 bth_evt_mode_change, bth_evt_return_link_keys, bth_evt_pin_code_req,
323 bth_evt_link_key_req, bth_evt_link_key_notify, bth_evt_loopback_command,
324 bth_evt_data_buffer_overflow, bth_evt_max_slots_change,
325 bth_evt_read_clock_offset_complete, bth_evt_conn_ptype_changed,
326 bth_evt_qos_violation, bth_evt_page_scan_mode_change,
327 bth_evt_pscan_rep_mode_change, bth_evt_flow_spec_complete,
328 bth_evt_inquiry_result_with_rssi};
330 #define EV_SUM_FC (sizeof(bth_event_array_fce)/sizeof(bth_event_array_fce[0]))
334 *The main function, which stores the received character "c" (from bth) to the input queue, checks if there is the whole pakcet in the queue and if so, it calls functions for processing the packet. (for ACL HCI and for Event HCI)
336 int bth_recieve_packet(int c)
338 hci_event_hdr bth_event_packet;
339 hci_acl_hdr bth_acl_packet;
342 uint8_t char_acl_pkt;
346 if(bth_controll_flag!=0)
348 bth_stop_TPU_counter();
349 bth_clear_TPU_counter();
350 bth_start_TPU_counter();
351 if(bth_get_timer()>0)
353 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg;
360 VypisHexa((uint8_t*)&c,1);
362 //VypisHexa((uint8_t*)&c,1);
363 bth_que_put(&bth_rs232_que_in, c); //store the received character to the queue
364 typ_paket=((uint8_t*)bth_rs232_que_in.buf_beg); //determine the type of the pakcet ACL, Even, SCO ...
368 /*fill in structure "hci_event_hdr" from the queue (bye by byte)*/
369 store8(bth_event_packet.evt, *(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE));
370 store8(bth_event_packet.plen, *(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+1));
372 if(bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg>3)
374 if((bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg) == (bth_event_packet.plen+HCI_EVENT_HDR_SIZE+HCI_PKT_SIZE))
377 if(bth_controll_flag!=0)
379 bth_stop_TPU_counter();
383 /*pointer to the function matching the event code*/
384 if(bth_event_packet.evt<EV_SUM_FC) //check whether the function exists
386 data_ad=(uint8_t*)(bth_rs232_que_in.buf_beg+HCI_EVENT_HDR_SIZE+HCI_PKT_SIZE);
387 error_code=(*bth_event_array_fce[bth_event_packet.evt])(data_ad,bth_event_packet.plen);
388 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg; //set to the beginning for the next event
390 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg; //nastav se na zacatek, pro pristi event
395 // bth_error_detect_status((uint8_t)error_code); //error msg
398 {//bth_error_detect_event((uint8_t)(-error_code)); //error msg
403 case HCI_ACLDATA_PKT:
404 if(bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg>5)
406 __bthtomc16((uint8_t*)&(bth_acl_packet.dlen),(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+HCI_ACL_HDR____dlen));
409 if((bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg) == ((bth_acl_packet.dlen)+HCI_ACL_HDR_SIZE+HCI_PKT_SIZE))
412 /* **** check the adjacency of two characters TPU3 **** */
413 if(bth_controll_flag!=0)
415 bth_stop_TPU_counter();
417 /*****************************************************/
419 __bthtomc16((uint8_t*)&(bth_acl_packet.handle),(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+HCI_ACL_HDR____handle));
420 bth_acl_packet.handle=bth_acl_packet.handle & 0x0fff;
422 /*variable 'char_acl_pkt' stores the properties of the packet, if it is point to point or broadcast, or char. L2CAP*/
423 store8(char_acl_pkt, (0xf0&*(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+HCI_ACL_HDR____handle+1)));
425 /*decide which packet is this (PtP,Piconet,broat...) and the type of communication (L2CAP, HCI)*/
426 data_ad=(uint8_t*)bth_rs232_que_in.buf_beg+HCI_PKT_SIZE+HCI_ACL_HDR_SIZE;
427 com_pr=char_acl_pkt&0xc0;
428 if(com_pr<COM_PROT_SUM_FC) //func exists
430 bth_char_pkt_fce[com_pr]
431 (bth_acl_packet.handle, char_acl_pkt&0x30, data_ad,bth_acl_packet.dlen);
435 /*HCI data - not L2CAP - neither handling nor loading to data queue is not implemented. It is assumed
436 sending of data using L2CAP. See if before this else. */
438 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg;
439 // sci_rs232_sendch('\n',sci_rs232_chan_default); //to PC
449 * Calls functions, which are necessary for setting the device to the slave mode.
451 void bth_parametr_slave(void)
453 bth_local_info.busy=1;
454 bth_cmd_write_page_scan(0x0040, 0x0020);
455 bth_cmd_write_inquiry_scan_activity(0x0040, 0x0020);
456 bth_cmd_write_scan_enable(0x03);
457 // bth_cmd_read_bd_addr(); //funguje command event neni
462 * Sets the MCU up, so it can send HCI packets to bth device
463 * If TPU channels are initialized, it resets and stop it
467 if(bth_controll_flag>0)
470 bth_controll_flag=10;
471 bth_stop_TPU_counter();
472 bth_clear_TPU_counter();
476 bth_local_info.busy=0;
481 * Setting of the queue - initialization function
485 static uint8_t bth_array_char_in[70];
486 // bth_check_command_for_send=NULL;
488 bth_rs232_que_in.buf_end=(uint8_t*)bth_array_char_in+BTH_BUF_LEN;
489 bth_rs232_que_in.buf_beg=bth_array_char_in;
490 bth_rs232_que_in.ip=bth_array_char_in;
493 /****************************************************************************/
494 /****************************************************************************/
497 * Auxiliary function, which converts characetrs to the printable form
499 int VypisHexa(uint8_t *s, int delka)
502 uint8_t tisk[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
504 for(i=0; i<delka; i++)
508 printf("%c",tisk[((zn>>4)&0x000F)]);
509 printf("%c",tisk[zn & 0x000F]);
511 sci_rs232_sendch(tisk[(zn&0xf0)>>4],sci_rs232_chan_default); //to PC
512 sci_rs232_sendch(tisk[(zn&0x0f)],sci_rs232_chan_default); //to PC