1 /*******************************************************************
4 bth_main.c - API bth library (recieve, send ...)
6 Copyright (C) 2006 by Petr Kovacik petr_kovacik@gmail.com
8 *******************************************************************/
13 #include <periph/sci_rs232.h>
14 #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"
35 #include <periph/sci_rs232.h>
37 /*--------BD address whitch are accept for connection-------------*/
38 bdaddr_t bth_accept_bd_addr[]={};
40 /*----------------local device info (master) -----------------------*/
41 bths_dev_info bth_local_info;//={0,{0,0,0,0,0,0,0,0},{0,0,0},0,{0,0,0},0};
43 /*----------------conect device info (slave) -----------------------*/
44 bths_connect_bluet* bth_connected[8];
46 /*-------------------------------- recieve data buffer -----------------------------*/
47 uint8_t bth_pole_char_in[SCI_BTH_BUF_LEN];
48 bth_que_t bth_rs232_que_in;
49 uint8_t bth_rs232_buf_in[SCI_BTH_BUF_LEN];
50 //-- --- ----- ----- ---- ------ ----- -- ---- --
51 //-- --- ----- ----- ---- ------ ----- -- ---- --
52 bth_que_t bth_inface_que_in;
53 bth_que_t bth_inface_que_out;
57 void *bth_pole_adrr_comm_packet[LENCOMMAND]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
58 bths_command_buf_info bth_com_buf_info={LENCOMMAND,0,0};
59 /***********************************************************************************/
60 void *bth_pole_adrr_check_packet[LENCOMMAND]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
61 bths_command_buf_info bth_check_buf_info={LENCOMMAND,0,0};
62 /***********************************************************************************/
64 /*kontroluje synchoronizaci prijimanych dat pomoci TPU jednotky*/
65 uint8_t bth_controll_flag=0;
68 /**-------------------------------------------------------------------------------*/
69 /*----- odeslani command prikazu, pokud je local bluetooth volny k odeslani------*/
70 /* 0 = data presunuta do SCI bufferu = budou odeslana, bluetooth zarizeni je volne
71 1 = prikaz se nepovedlo presunout do SCI bufferu, ale bluet device je volne
72 2 = bluetooth zarizeni je zamestnane, tj. data se nepresunula do bufferu
73 3 = v potvrzovacim zasobniku neni uz misto*/
76 * Po zavolani funkce, se odesle paket, ktery je zarazen ve fronte paketu k odeslani (bth zazizeni je
77 * volne), pokud neni novy paket nebo zazizeni neni volne, nic se nevykona
79 int bth_send_queue(void)
83 if(bth_local_info.busy!=0)
84 {return 1;}; //zarizeni neni volne
85 if(bth_com_buf_info.aktual==bth_com_buf_info.sent) //PRAVDEPODOBNE neni co odesilat
87 if(bth_com_buf_info.sent<(LENCOMMAND-2))
89 if(bth_pole_adrr_comm_packet[bth_com_buf_info.sent+1]==NULL)
90 {return 1;}; //URCITE neni co odesilat
94 if(bth_pole_adrr_comm_packet[0]==NULL)
95 {return 1;}; //URCITE neni co odesilat
99 /*bth_send_packet(AdrOdkud,kolikBytu;)*/
100 switch(*(uint8_t*)bth_pole_adrr_comm_packet[bth_com_buf_info.sent])
102 case HCI_ACLDATA_PKT:
103 __bthtomc16((uint8_t*)&(hp_size),((uint8_t*)bth_pole_adrr_comm_packet[bth_com_buf_info.sent])+HCI_PKT_SIZE+HCI_ACL_HDR____dlen);
104 hp_size=hp_size+HCI_ACL_HDR_SIZE+HCI_PKT_SIZE;
105 if(!(bth_send_packet(bth_pole_adrr_comm_packet[bth_com_buf_info.sent],hp_size)))
107 free(bth_pole_adrr_comm_packet[bth_com_buf_info.sent]);
108 bth_pole_adrr_comm_packet[bth_com_buf_info.sent]=NULL;
109 if(bth_com_buf_info.sent<(LENCOMMAND-2)){bth_com_buf_info.sent++;}
110 else{ bth_com_buf_info.sent=0;};
113 free(bth_pole_adrr_comm_packet[bth_com_buf_info.sent]);
114 bth_pole_adrr_comm_packet[bth_com_buf_info.sent]=NULL;
116 case HCI_COMMAND_PKT:
117 hp_size=((uint16_t)*(((uint8_t*)bth_pole_adrr_comm_packet[bth_com_buf_info.sent])+HCI_PKT_SIZE+2)+HCI_COMMAND_HDR_SIZE+HCI_PKT_SIZE);
118 if(!(bth_send_packet(bth_pole_adrr_comm_packet[bth_com_buf_info.sent],hp_size)))
119 {/*odeslano - zaradim prikaz k moznosti potvrzeni*/
120 for(i=0; i<LENCOMMAND; i++)
122 if(bth_pole_adrr_check_packet[i]==NULL)
124 bth_pole_adrr_check_packet[i]=bth_pole_adrr_comm_packet[bth_com_buf_info.sent];
125 bth_pole_adrr_comm_packet[bth_com_buf_info.sent]=NULL;
126 /*nastavim adresu pro pristi command prikaz - princip kruhove zasobniku*/
127 if(bth_com_buf_info.sent<(LENCOMMAND-2)){bth_com_buf_info.sent++;}
128 else{ bth_com_buf_info.sent=0;};
142 * Prevod hexa znaku do tisknutelne podoby. V tomto tvaru se odesle po seriov. rozhranni do PC
145 void bth_conv_char_text(uint8_t zn)
146 { uint8_t map_leters[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
150 sci_rs232_sendch(map_leters[val],sci_rs232_chan_default);
152 sci_rs232_sendch(map_leters[val],sci_rs232_chan_default);
160 *Funkce odesle data o velikosti hp_size od adresy hp do bth (UART)
162 int bth_send_packet(uint8_t *hp, uint16_t hp_size)
165 /*je bluetooth zarizeni volne, nebo zamestnano predchozim prikazem?*/
166 if(bth_local_info.busy==0)
169 VypisHexa(hp,hp_size);
172 for(i=0; i<hp_size;i++)
175 sci_rs232_sendch(zn,2); //bth
176 // VypisHexa((hp+i),1);
179 bth_local_info.busy=1;
180 return(0); //vsechno odeslano ==== OK =====
184 return 2; //zamestnane
189 *Funkce vlozi znak do fronty
192 inline int bth_que_put(bth_que_t *q, int c)
195 p=q->ip; //nastav se na aktual pozici v souboru
196 *(p++)=c; //na nasledujici pam. bunku uloz znak
197 if(p==q->buf_end) return -1;//buffer neni kruhovy p=q->buf_beg;
198 // if(p==q->op) return -1;
200 return 0; //pokud nejsou problemy, vrat znak, jinak -1
205 *prijaty HCI datovy paket je zaslan jako point to point
208 int bth_pkt_type_pointopoint(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
210 l2cap_hdr bth_l2cap_packet;
218 case 0x20:/*first data packet L2CAP*/
219 bth_dev_num=bth_find_conected_dev(handle);
220 __bthtomc16((uint8_t*)&(bth_l2cap_packet.len),(uint8_t*)bth_p+L2CAP_HDR____len);
221 __bthtomc16((uint8_t*)&(bth_l2cap_packet.cid),(uint8_t*)bth_p+L2CAP_HDR____cid);
226 switch((uint8_t)(bth_l2cap_packet.cid))
231 l2cap_signaling(((uint8_t*)bth_p+L2CAP_CMD_HDR_SIZE),(size+L2CAP_HDR____len),bth_dev_num);
236 /*skutecna nefalcovana data ...*/
237 /*musim najit kanal s cislem cid pro zarizeni bth_dev_num*/
238 if(bth_find_chanal(bth_dev_num, bth_l2cap_packet.cid)>-1)
240 /*TADY JSOU DOSLA DATA, KTERA UZ NEJSOU KONFIGURACNI*/
243 bth_data=(uint8_t*)bth_p+L2CAP_HDR_SIZE;
244 bth_size_data=size-L2CAP_HDR_SIZE;
246 // uint8_t odesli[]={'a','h','o','j'};
247 for(i=0; i<bth_size_data;i++)
249 flag=bth_inface_r_isr(0, *((uint8_t*)bth_data+i));
252 // sci_rs232_sendch(*((uint8_t*)bth_data+i),sci_rs232_chan_default); //do PC
253 // VypisHexa((void*)((uint8_t*)bth_data+i),1);
256 /*zasobnik plny, neni schopen prijmout dalsi znaky*/
257 // sci_rs232_sendch('.',sci_rs232_chan_default); //do PC
261 // VypisHexa(bth_data,bth_size_data);
267 case 0x40: return(-3); /*next data packet L2CAP*/ /*funkce neni rozepsana, prijmam jen 1pkt zpravy*/
268 case 0x30: return (-4); /*Reserved for future use*/
269 case 0x00: return (-4); /*Reserved for future use*/
276 *prijaty HCI datovy paket je zaslan jako broadcast (nedopsana funkce)
278 int bth_pkt_type_broadcast(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
282 case 0x20:/*first data packet L2CAP*/
283 return(-3); /*neni napsano pro prijem znaku broadcast cestou*/
284 case 0x40: return(-3); /*next data packet L2CAP*/ /*funkce neni rozepsana, prijmam jen 1pkt zpravy*/
285 case 0x30: return (-4); /*Reserved for future use*/
286 case 0x00: return (-4); /*Reserved for future use*/
294 *prijaty HCI datovy paket je zaslan vramci picosite (nedopsana funkce)
296 int bth_pkt_type_piconet(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
300 case 0x20:/*first data packet L2CAP*/
301 return(-3); /*neni napsano pro prijem znaku piconet cestou*/
302 case 0x40: return(-3); /*next data packet L2CAP*/ /*funkce neni rozepsana, prijmam jen 1pkt zpravy*/
303 case 0x30: return (-4); /*Reserved for future use*/
304 case 0x00: return (-4); /*Reserved for future use*/
312 *budouci vyuziti (nedopsana funkce)
314 int bth_pkt_type_reserved(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size)
320 /****************************************************************************/
321 /****************************************************************************/
324 *pointry na funkce. Funkce jsou volany podle prijateho datoveho HCI peketu
326 typedef int (*bth_kind_pkt)(uint16_t handle, uint8_t bound_flag, uint8_t *bth_p, uint16_t size);
327 bth_kind_pkt bth_char_pkt_fce[]={
328 bth_pkt_type_pointopoint, bth_pkt_type_broadcast, bth_pkt_type_piconet, bth_pkt_type_reserved};
329 #define COM_PROT_SUM_FC (sizeof(bth_char_pkt_fce)/sizeof(bth_char_pkt_fce[0]))
333 *pointry na funkce. Funkce jsou volany podle event codu, dekodovaneho z prijateho event HCI peketu
335 typedef int (*bth_p_ivent_fce)(uint8_t *bth_p, uint8_t size);
336 bth_p_ivent_fce bth_event_array_fce[]={bth_evt_none,bth_evt_inquiry_complete, bth_evt_inquiry_result,
337 bth_evt_conn_complete, bth_evt_conn_request, bth_evt_disconn_complete,
338 bth_evt_auth_complete, bth_remote_name_req_complete,
339 bth_evt_encrypt_cahnge, bth_evt_change_conn_link_key_complete,
340 bth_evt_master_link_key_complete, bth_evt_read_remote_features_complete,
341 bth_evt_read_remote_version_complete, bth_evt_qos_setup_complete,
342 bth_evt_cmd_complete, bth_evt_cmd_status, bth_evt_hardware_error,
343 bth_evt_flush_occurred, bth_evt_role_cahage, bth_evt_num_comp_pkts,
344 bth_evt_mode_change, bth_evt_return_link_keys, bth_evt_pin_code_req,
345 bth_evt_link_key_req, bth_evt_link_key_notify, bth_evt_loopback_command,
346 bth_evt_data_buffer_overflow, bth_evt_max_slots_change,
347 bth_evt_read_clock_offset_complete, bth_evt_conn_ptype_changed,
348 bth_evt_qos_violation, bth_evt_page_scan_mode_change,
349 bth_evt_pscan_rep_mode_change, bth_evt_flow_spec_complete,
350 bth_evt_inquiry_result_with_rssi};
352 #define EV_SUM_FC (sizeof(bth_event_array_fce)/sizeof(bth_event_array_fce[0]))
356 *Hlavni funkce, ktera ulozi prijaty znak "c" (od bth) ulozi ho do vstupni fronty, zkontroluje zda-li
357 * je paekt cely a pokud ano, tak zavola funkce pro jeho zpracovani (pro ACL HCI a pro Event HCI)
359 int bth_recieve_packet(int c)
361 hci_event_hdr bth_event_packet;
362 hci_acl_hdr bth_acl_packet;
365 uint8_t char_acl_pkt;
369 if(bth_controll_flag!=0)
371 bth_stop_TPU_counter();
372 bth_clear_TPU_counter();
373 bth_start_TPU_counter();
374 if(bth_get_timer()>0)
376 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg;
383 VypisHexa((uint8_t*)&c,1);
385 //VypisHexa((uint8_t*)&c,1);
386 bth_que_put(&bth_rs232_que_in, c); //ulozim prijaty znak do zasobniku
387 typ_paket=((uint8_t*)bth_rs232_que_in.buf_beg); //zjistim tzp paketu ACL, Even, SCO ...
391 /*naplnim strukturu "hci_event_hdr" ze zasobniku - po bytech*/
392 store16(bth_event_packet.evt, *(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE));
393 store16(bth_event_packet.plen, *(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+1));
395 if(bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg>3)
397 if((bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg) == (bth_event_packet.plen+HCI_EVENT_HDR_SIZE+HCI_PKT_SIZE))
400 if(bth_controll_flag!=0)
402 bth_stop_TPU_counter();
406 /*pointer na fci prislusenijici even codu*/
407 if(bth_event_packet.evt<EV_SUM_FC) //overeni existence fce
409 data_ad=(uint8_t*)(bth_rs232_que_in.buf_beg+HCI_EVENT_HDR_SIZE+HCI_PKT_SIZE);
410 error_code=(*bth_event_array_fce[bth_event_packet.evt])(data_ad,bth_event_packet.plen);
411 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg; //nastav se na zacatek, pro pristi event
413 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg; //nastav se na zacatek, pro pristi event
418 // bth_error_detect_status((uint8_t)error_code); //error vypisy
421 {//bth_error_detect_event((uint8_t)(-error_code)); //error vypisy
426 case HCI_ACLDATA_PKT:
427 if(bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg>5)
429 __bthtomc16((uint8_t*)&(bth_acl_packet.dlen),(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+HCI_ACL_HDR____dlen));
432 if((bth_rs232_que_in.ip-bth_rs232_que_in.buf_beg) == ((bth_acl_packet.dlen)+HCI_ACL_HDR_SIZE+HCI_PKT_SIZE))
435 /* **** kontrola sousednosti dvou znaku TPU3 **** */
436 if(bth_controll_flag!=0)
438 bth_stop_TPU_counter();
440 /*****************************************************/
442 __bthtomc16((uint8_t*)&(bth_acl_packet.handle),(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+HCI_ACL_HDR____handle));
443 bth_acl_packet.handle=bth_acl_packet.handle & 0x0fff;
445 /*prom 'char_acl_pkt' vyjadruje vlastnosti paketu, if point to point nebo broadcast, or char. L2CAP*/
446 store16(char_acl_pkt, (0xf0&*(((uint8_t*)bth_rs232_que_in.buf_beg)+HCI_PKT_SIZE+HCI_ACL_HDR____handle+1)));
448 /*rozhodnuti o jaky paket se jedna (PtP,Piconet,broat...) a o jaky typ komunikace se zarizenim (L2CAP, HCI)*/
449 data_ad=(uint8_t*)bth_rs232_que_in.buf_beg+HCI_PKT_SIZE+HCI_ACL_HDR_SIZE;
450 com_pr=char_acl_pkt&0xc0;
451 if(com_pr<COM_PROT_SUM_FC) //fce existuje
453 bth_char_pkt_fce[com_pr]
454 (bth_acl_packet.handle, char_acl_pkt&0x30, data_ad,bth_acl_packet.dlen);
458 /*HCI data - nikoliv L2CAP - obsluha ani nahravani do
459 datoveho zas. neni napsano - predpoklada se zasilani dat pres L2CAP
460 viz. if pred timto else */
462 bth_rs232_que_in.ip=bth_rs232_que_in.buf_beg;
463 // sci_rs232_sendch('\n',sci_rs232_chan_default); //do PC
473 * Funkce vola funkce, ktere jsou potrebne pro nastaveni zarizeni do slave rezimu
475 void bth_parametr_slave(void)
477 bth_local_info.busy=1;
478 bth_cmd_write_page_scan(0x0040, 0x0020);
479 bth_cmd_write_inquiry_scan_activity(0x0040, 0x0020);
480 bth_cmd_write_scan_enable(0x03);
481 // bth_cmd_read_bd_addr(); //funguje command event neni
486 * Funkce nastavi MC, aby mohl zasilat HCI pakety do bth zarizeni
487 * Pokud jsou inicializovany TPU kanal, tak ho vynuluje a zastavi
491 if(bth_controll_flag>0)
494 bth_controll_flag=10;
495 bth_stop_TPU_counter();
496 bth_clear_TPU_counter();
500 bth_local_info.busy=0;
505 * nastaveni zasobniku - inicializacni funkce
509 // bth_check_command_for_send=NULL;
511 bth_rs232_que_in.buf_end=(uint8_t*)bth_pole_char_in+SCI_RS232_BUF_LEN;
512 bth_rs232_que_in.buf_beg=bth_pole_char_in;
513 bth_rs232_que_in.ip=bth_pole_char_in;
516 /****************************************************************************/
517 /****************************************************************************/
520 * Pomocna funce, ktera slouzi k prevodum znaku an tisknutelne znaky
522 int VypisHexa(uint8_t *s, int delka)
525 uint8_t tisk[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
527 for(i=0; i<delka; i++)
531 printf("%c",tisk[((zn>>4)&0x000F)]);
532 printf("%c",tisk[zn & 0x000F]);
534 sci_rs232_sendch(tisk[(zn&0xf0)>>4],sci_rs232_chan_default); //do PC
535 sci_rs232_sendch(tisk[(zn&0x0f)],sci_rs232_chan_default); //do PC