Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
127 | ligi | 1 | #include "bluetooth_handler.h" |
2 | |||
3 | int bt_device_count=0; |
||
4 | |||
5 | char names[MAX_BT_DEVICES][248]; |
||
6 | char addrs[MAX_BT_DEVICES][19]; |
||
7 | |||
130 | ligi | 8 | char BtHostRxBuffer[150]; |
522 | ligi | 9 | char BtHostRxBufferDecoded[150]; |
130 | ligi | 10 | |
522 | ligi | 11 | int BtRxCount; |
127 | ligi | 12 | int scan_bt() |
13 | { |
||
14 | inquiry_info *ii = NULL; |
||
15 | |||
16 | int dev_id, sock, len, flags; |
||
17 | int i; |
||
18 | char addr[19] = { 0 }; |
||
19 | char name[248] = { 0 }; |
||
20 | |||
21 | dev_id = hci_get_route(NULL); |
||
22 | sock = hci_open_dev( dev_id ); |
||
23 | if (dev_id < 0 || sock < 0) { |
||
24 | perror("opening socket"); |
||
25 | return 0; |
||
26 | } |
||
27 | |||
28 | len = 8; |
||
29 | |||
30 | flags = IREQ_CACHE_FLUSH; |
||
31 | ii = (inquiry_info*)malloc(MAX_BT_DEVICES * sizeof(inquiry_info)); |
||
32 | |||
33 | bt_device_count = hci_inquiry(dev_id, len, MAX_BT_DEVICES, NULL, &ii, flags); |
||
34 | if( bt_device_count < 0 ) perror("hci_inquiry"); |
||
35 | |||
36 | for (i = 0; i < bt_device_count; i++) { |
||
37 | ba2str(&(ii+i)->bdaddr, addr); |
||
38 | sprintf(addrs[i],"%s",addr); |
||
39 | |||
40 | memset(name, 0, sizeof(name)); |
||
41 | |||
42 | if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), |
||
43 | name, 0) < 0) |
||
44 | sprintf(names[i],"[unknown]"); |
||
45 | else |
||
46 | sprintf(names[i],"%s",name); |
||
47 | |||
48 | } |
||
49 | |||
50 | |||
51 | free( ii ); |
||
52 | close( sock ); |
||
53 | return 1; |
||
54 | } |
||
130 | ligi | 55 | |
483 | ligi | 56 | //struct timeval timeout; |
130 | ligi | 57 | fd_set readfds, writefds; |
58 | int s; |
||
59 | struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 }; |
||
60 | char buf[1024] = { 0 }; |
||
61 | int client, bytes_read, status; |
||
62 | unsigned int opt = sizeof(rem_addr); |
||
63 | |||
64 | int maxfd, sock_flags; |
||
65 | |||
66 | |||
522 | ligi | 67 | unsigned char BT_TxBuffer[MAX_BUFF_LEN]; |
130 | ligi | 68 | |
522 | ligi | 69 | extern struct str_DebugOut DebugOut; |
70 | struct str_VersionInfo VersionInfo; |
||
71 | |||
130 | ligi | 72 | int bt_host_init() |
73 | { |
||
74 | |||
75 | // allocate socket |
||
76 | s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); |
||
77 | |||
78 | // bind socket to port 1 of the first available bluetooth adapter |
||
79 | loc_addr.rc_family = AF_BLUETOOTH; |
||
80 | loc_addr.rc_bdaddr = *BDADDR_ANY; |
||
81 | loc_addr.rc_channel = 1; |
||
82 | bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr)); |
||
83 | |||
84 | // put server socket into listening mode |
||
85 | listen(s, 1); |
||
86 | |||
87 | // put server socket into nonblocking mode |
||
88 | sock_flags = fcntl( s, F_GETFL, 0 ); |
||
89 | fcntl( s, F_SETFL, sock_flags | O_NONBLOCK ); |
||
90 | |||
91 | return 1; |
||
92 | } |
||
93 | |||
94 | |||
95 | int bt_host_connected=0; |
||
96 | |||
97 | int bt_host_send(char RxBuffer[150],int len) |
||
98 | { |
||
99 | if (bt_host_connected) |
||
100 | { |
||
101 | send(client,"\r",1,0); |
||
102 | send(client,RxBuffer,len,0); |
||
103 | send(client,"\r",1,0); |
||
104 | } |
||
105 | return 1; |
||
106 | } |
||
107 | |||
522 | ligi | 108 | |
109 | struct { |
||
110 | unsigned char MenuePunkt; |
||
111 | unsigned char MaxMenue; |
||
112 | char DisplayBuff[80]; |
||
113 | } menu; |
||
114 | |||
115 | |||
116 | void copy_lcd_str(int x,int y,char str[]) |
||
117 | { |
||
118 | int pos=0; |
||
119 | while (str[pos]!=0) |
||
120 | { |
||
121 | |||
122 | menu.DisplayBuff[y*20+x+pos]=str[pos]; |
||
123 | pos++; |
||
124 | } |
||
125 | |||
126 | } |
||
127 | |||
128 | |||
129 | |||
130 | void Menu(void) |
||
131 | { |
||
132 | |||
133 | // menu.MenuePunkt=0; |
||
134 | menu.MaxMenue=3; |
||
135 | int x; |
||
136 | int y; |
||
137 | |||
138 | char tmp_str[20]; |
||
139 | |||
140 | for (x=0;x<20;x++) |
||
141 | for (y=0;y<4;y++) |
||
142 | menu.DisplayBuff[y*20+x]=' '; |
||
143 | |||
144 | switch(menu.MenuePunkt) |
||
145 | { |
||
146 | case 0: |
||
147 | // LCD_printfxy(0,0,"+ Riddim +"); |
||
148 | /* LCD_printfxy(0,1,"Version: %d %d",0,8); |
||
149 | LCD_printfxy(0,2,""); |
||
150 | LCD_printfxy(0,3,"(cc) 2009 ligi"); |
||
151 | */ |
||
152 | // clear_lcd |
||
153 | |||
154 | |||
155 | |||
156 | sprintf(tmp_str,"+ Riddim +"); |
||
157 | copy_lcd_str(0,0,tmp_str); |
||
158 | |||
159 | sprintf(tmp_str,"Version: V%d.%d/%d",RIDDIM_VERSION_MAJOR,RIDDIM_VERSION_MINOR,RIDDIM_VERSION_PATCH); |
||
160 | copy_lcd_str(0,1,tmp_str); |
||
161 | |||
162 | |||
163 | sprintf(tmp_str,"(cc) 2009 LiGi"); |
||
164 | copy_lcd_str(0,3,tmp_str); |
||
165 | |||
166 | // sprintf(&menu.DisplayBuff,"+ Riddim ++"); |
||
167 | |||
168 | // sprintf(&menu.DisplayBuff+20,"Version: %d %d",0,8); |
||
169 | |||
170 | break; |
||
171 | |||
172 | case 1: |
||
173 | sprintf(tmp_str,"Loop:"); |
||
174 | copy_lcd_str(0,0,tmp_str); |
||
175 | sprintf(tmp_str," Count %ld",trip_count); |
||
176 | copy_lcd_str(0,1,tmp_str); |
||
177 | sprintf(tmp_str," Time %ld",last_trip_time); |
||
178 | copy_lcd_str(0,2,tmp_str); |
||
179 | break; |
||
180 | |||
181 | |||
182 | case 2: |
||
183 | sprintf(tmp_str,"Inputs:"); |
||
184 | copy_lcd_str(0,0,tmp_str); |
||
185 | sprintf(tmp_str," Complete %d",evdevs_count); |
||
186 | copy_lcd_str(0,1,tmp_str); |
||
187 | sprintf(tmp_str," Connected %d",input_count); |
||
188 | copy_lcd_str(0,2,tmp_str); |
||
189 | sprintf(tmp_str," Configured %d",configured_input_count); |
||
190 | copy_lcd_str(0,3,tmp_str); |
||
191 | break; |
||
192 | |||
193 | case 3: |
||
194 | sprintf(tmp_str,"Nick: %d",act_nick); |
||
195 | copy_lcd_str(0,0,tmp_str); |
||
196 | sprintf(tmp_str,"Roll %d",act_roll); |
||
197 | copy_lcd_str(0,1,tmp_str); |
||
198 | sprintf(tmp_str,"Gier %d",act_gier); |
||
199 | copy_lcd_str(0,2,tmp_str); |
||
200 | sprintf(tmp_str,"Gas %d",act_gas); |
||
201 | copy_lcd_str(0,3,tmp_str); |
||
202 | break; |
||
203 | |||
204 | default: |
||
205 | sprintf(tmp_str,"illegal page %d",menu.MenuePunkt); |
||
206 | copy_lcd_str(0,0,tmp_str); |
||
207 | break; |
||
208 | } |
||
209 | } |
||
210 | |||
211 | |||
212 | |||
213 | void BT_Decode64(void) // die daten werden im rx buffer dekodiert, das geht nur, weil aus 4 byte immer 3 gemacht werden. |
||
214 | { |
||
215 | unsigned char a,b,c,d; |
||
216 | unsigned char x,y,z; |
||
217 | unsigned char ptrIn = 3; // start at begin of data block |
||
218 | unsigned char ptrOut = 0; |
||
219 | unsigned char len = BtRxCount - 5; // von der Gesamtbytezahl eines Frames gehen 3 Bytes des Headers ('#',Addr, Cmd) und 3 Bytes des Footers (CRC1, CRC2, '\r') ab. |
||
220 | |||
221 | while(len) |
||
222 | { |
||
223 | a = BtHostRxBuffer[ptrIn++] - '='; |
||
224 | b = BtHostRxBuffer[ptrIn++] - '='; |
||
225 | c = BtHostRxBuffer[ptrIn++] - '='; |
||
226 | d = BtHostRxBuffer[ptrIn++] - '='; |
||
227 | |||
228 | x = (a << 2) | (b >> 4); |
||
229 | y = ((b & 0x0f) << 4) | (c >> 2); |
||
230 | z = ((c & 0x03) << 6) | d; |
||
231 | printf("\naaaaa %d / %d\naaaaa s %s => x %d ; y %d ; z %d \n",ptrOut, BtRxCount ,BtHostRxBuffer,x,y,z); |
||
232 | |||
233 | |||
234 | if(len--) BtHostRxBufferDecoded[ptrOut++] = x; else break; |
||
235 | if(len--) BtHostRxBufferDecoded[ptrOut++] = y; else break; |
||
236 | if(len--) BtHostRxBufferDecoded[ptrOut++] = z; else break; |
||
237 | } |
||
238 | //RxDataLen = ptrOut ; // wie viele Bytes wurden dekodiert? |
||
239 | |||
240 | } |
||
241 | |||
242 | void BT_AddCRC(unsigned int wieviele) |
||
243 | { |
||
244 | unsigned int tmpCRC = 0,i; |
||
245 | for(i = 0; i < wieviele;i++) |
||
246 | { |
||
247 | tmpCRC += BT_TxBuffer[i]; |
||
248 | } |
||
249 | tmpCRC %= 4096; |
||
250 | BT_TxBuffer[i++] = '=' + tmpCRC / 64; |
||
251 | BT_TxBuffer[i++] = '=' + tmpCRC % 64; |
||
252 | BT_TxBuffer[i++] = '\r'; |
||
253 | } |
||
254 | |||
255 | void BT_SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len) |
||
256 | { |
||
257 | // return; |
||
258 | int status =0; |
||
259 | unsigned int pt = 0; |
||
260 | unsigned char a,b,c; |
||
261 | unsigned char ptr = 0; |
||
262 | |||
263 | printf("packing base len %d -cmd %c\n",len,cmd); |
||
264 | |||
265 | BT_TxBuffer[pt++] = '#'; // Startzeichen |
||
266 | BT_TxBuffer[pt++] = modul; // Adresse (a=0; b=1,...) |
||
267 | BT_TxBuffer[pt++] = cmd; // Commando |
||
268 | |||
269 | while(len) |
||
270 | { |
||
271 | if(len) { a = snd[ptr++]; len--;} else a = 0; |
||
272 | if(len) { b = snd[ptr++]; len--;} else b = 0; |
||
273 | if(len) { c = snd[ptr++]; len--;} else c = 0; |
||
274 | BT_TxBuffer[pt++] = '=' + (a >> 2); |
||
275 | BT_TxBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)); |
||
276 | BT_TxBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)); |
||
277 | BT_TxBuffer[pt++] = '=' + ( c & 0x3f); |
||
278 | } |
||
279 | |||
280 | |||
281 | |||
282 | BT_AddCRC(pt); |
||
283 | printf("Sending to BT_Client %d \n" , pt); |
||
284 | |||
285 | status = send(client,"\r" , 1, 0); |
||
286 | |||
287 | |||
288 | // for (c=0;c<pt+2;c++) |
||
289 | // { |
||
290 | status = write(client,&BT_TxBuffer , pt+3); |
||
291 | |||
292 | |||
293 | status = send(client,"\r" , 1, 0); |
||
294 | printf("\n"); |
||
295 | } |
||
296 | |||
297 | |||
298 | void bt_process_buffer() |
||
299 | { |
||
300 | printf("processing buffer\n"); |
||
301 | switch(BtHostRxBuffer[2]) |
||
302 | { |
||
303 | |||
304 | case 'v': |
||
305 | printf("got version request\n"); |
||
306 | VersionInfo.SWMinor=RIDDIM_VERSION_MINOR; |
||
307 | VersionInfo.SWMajor=RIDDIM_VERSION_MAJOR; |
||
308 | VersionInfo.SWPatch=RIDDIM_VERSION_PATCH; |
||
309 | |||
310 | BT_SendOutData('V', RIDDIM_ADDRESS, (unsigned char *) &VersionInfo, sizeof(VersionInfo)); |
||
311 | |||
312 | break; |
||
313 | |||
314 | case 'l': |
||
315 | printf("got display request\n"); |
||
316 | Menu(); |
||
317 | menu.MenuePunkt=BtHostRxBufferDecoded[0]; |
||
318 | printf("sending %s \n",menu.DisplayBuff); |
||
319 | BT_SendOutData('L', RIDDIM_ADDRESS, (unsigned char *) &menu, sizeof(menu)); |
||
320 | break; |
||
321 | |||
322 | } |
||
323 | |||
324 | } |
||
325 | |||
326 | |||
327 | |||
328 | |||
329 | |||
330 | |||
331 | |||
332 | |||
333 | int r=0; |
||
334 | |||
335 | struct timeval last_debug_time; |
||
336 | struct timeval act_time; |
||
337 | |||
130 | ligi | 338 | int bt_host_tick(int mk_fd) |
339 | { |
||
340 | |||
341 | // try to accept connection if none yet |
||
342 | if (!bt_host_connected) |
||
343 | { |
||
483 | ligi | 344 | // timeout.tv_sec = 0; |
345 | // timeout.tv_usec = 100; |
||
130 | ligi | 346 | FD_ZERO(&readfds); |
347 | FD_ZERO(&writefds); |
||
348 | FD_SET(s, &readfds); |
||
349 | maxfd = s; |
||
522 | ligi | 350 | |
351 | printf("waiting for bt connection\n"); |
||
483 | ligi | 352 | // status = select(maxfd + 1, &readfds, &writefds, 0, &timeout); |
353 | status = select(maxfd + 1, &readfds, &writefds, 0,& (struct timeval) { 0, 100 }); |
||
130 | ligi | 354 | if( status > 0 && FD_ISSET( s, &readfds ) ) { |
355 | // incoming connection |
||
356 | client = accept( s, (struct sockaddr*)&rem_addr, &opt ); |
||
357 | if( client >= 0 ) |
||
358 | { |
||
359 | bt_host_connected=1; |
||
360 | |||
361 | // close the server socket, leaving only the client socket open |
||
362 | // close(s); |
||
363 | |||
364 | |||
365 | ba2str( &rem_addr.rc_bdaddr, buf ); |
||
366 | fprintf(stderr, "accepted connection from %s!!!!!!!\n", buf); |
||
367 | memset(buf, 0, sizeof(buf)); |
||
368 | |||
369 | // put client socket into nonblocking mode |
||
370 | sock_flags = fcntl( client, F_GETFL, 0 ); |
||
371 | fcntl( client, F_SETFL, sock_flags | O_NONBLOCK ); |
||
372 | } |
||
373 | |||
374 | } |
||
375 | |||
376 | } |
||
377 | else |
||
378 | { |
||
522 | ligi | 379 | gettimeofday(&act_time,NULL); |
380 | if (act_time.tv_sec>last_debug_time.tv_sec) |
||
381 | { |
||
382 | |||
383 | DebugOut.Analog[9]=23; // voltage |
||
384 | DebugOut.Analog[5]=23; // alt |
||
385 | |||
386 | BT_SendOutData('D', RIDDIM_ADDRESS, (unsigned char *) &DebugOut, sizeof(DebugOut)); |
||
387 | |||
388 | |||
389 | gettimeofday(&last_debug_time,NULL); |
||
390 | } |
||
130 | ligi | 391 | printf("reading from bt_host"); |
392 | char in_char='#'; |
||
393 | int count=0; |
||
394 | |||
522 | ligi | 395 | struct timeval timeout; |
396 | timeout.tv_sec = 0; |
||
397 | timeout.tv_usec = 100; |
||
398 | |||
130 | ligi | 399 | FD_ZERO(&readfds); |
400 | FD_ZERO(&writefds); |
||
401 | FD_SET(client, &readfds); |
||
402 | maxfd = client; |
||
403 | |||
404 | printf("waiting for connection\n"); |
||
522 | ligi | 405 | status = select(maxfd + 1, &readfds, 0, 0, &timeout); |
130 | ligi | 406 | if( status >0 ) |
407 | { |
||
522 | ligi | 408 | count=read(client,&in_char,1); |
409 | //send(mk_fd,"\r",1,0); |
||
410 | if (count==-1) |
||
130 | ligi | 411 | { |
522 | ligi | 412 | bt_host_connected=0; |
413 | //return 0; |
||
414 | } |
||
415 | else |
||
416 | if(in_char!='\r') |
||
417 | { |
||
418 | |||
419 | printf("count: %d in %d chr %c r:%d\n",count,in_char,in_char,r); |
||
420 | //send(mk_fd,&in_char,1,0); |
||
421 | BtHostRxBuffer[r++]=in_char; |
||
422 | |||
130 | ligi | 423 | } |
522 | ligi | 424 | else |
425 | { |
||
426 | BtRxCount=r; |
||
427 | r=0; |
||
428 | |||
429 | BT_Decode64(); |
||
430 | bt_process_buffer(); |
||
431 | } |
||
432 | // send(mk_fd,"\r",1,0); |
||
130 | ligi | 433 | } |
434 | else |
||
435 | return 0; |
||
436 | } |
||
437 | |||
438 | return 1; |
||
439 | } |