Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
41 | ligi | 1 | #include <stdio.h> |
2 | #include <stdlib.h> |
||
3 | #include <string.h> |
||
4 | #include <fcntl.h> |
||
5 | #include "lib/x52/x52.h" |
||
6 | #include <unistd.h> |
||
7 | #include <sys/socket.h> |
||
8 | #include <bluetooth/bluetooth.h> |
||
9 | #include <bluetooth/hci.h> |
||
10 | #include <bluetooth/hci_lib.h> |
||
11 | |||
50 | ligi | 12 | #include <sys/time.h> |
41 | ligi | 13 | |
50 | ligi | 14 | |
43 | ligi | 15 | #include <bluetooth/rfcomm.h> |
41 | ligi | 16 | |
43 | ligi | 17 | |
41 | ligi | 18 | #include <linux/joystick.h> |
19 | #define JOY_DEV "/dev/input/js0" |
||
20 | |||
21 | #define MAX_BT_DEVICES 3 |
||
22 | |||
47 | ligi | 23 | |
24 | #define STATEID_SCANNING 0 |
||
25 | #define STATEID_CONNECTING 1 |
||
26 | |||
27 | #define BUTTON_SELECT 26 |
||
28 | #define BUTTON_DOWN 28 |
||
29 | #define BUTTON_UP 27 |
||
30 | |||
50 | ligi | 31 | |
32 | #define AXIS_ROLL 0 |
||
33 | #define AXIS_NICK 1 |
||
34 | #define AXIS_GIER 5 |
||
35 | #define AXIS_GAS 2 |
||
36 | |||
37 | #define INVERT_ROLL -1 |
||
38 | #define INVERT_NICK -1 |
||
39 | #define INVERT_GIER 1 |
||
40 | #define INVERT_GAS -1 |
||
41 | |||
42 | |||
43 | // time struct for measuring |
||
44 | struct timeval time_struct1; |
||
45 | struct timeval time_struct2; |
||
46 | |||
47 | |||
48 | int act_nick=0; |
||
49 | int act_roll=0; |
||
50 | int act_gier=0; |
||
51 | int act_gas=0; |
||
52 | int act_mode=0; |
||
53 | |||
41 | ligi | 54 | int bt_device_count=0; |
55 | |||
56 | char names[MAX_BT_DEVICES][248]; |
||
57 | char addrs[MAX_BT_DEVICES][19]; |
||
58 | |||
43 | ligi | 59 | int s, status; |
60 | unsigned char TxBuffer[150]; |
||
61 | unsigned char _TxBuffer[150]; |
||
62 | |||
48 | ligi | 63 | char RxBuffer[150]; |
64 | |||
65 | |||
47 | ligi | 66 | int x52_input_fd, *axis=NULL, num_of_axis=0, num_of_buttons=0, x; |
67 | char *button=NULL,*button_trigger=NULL, name_of_joystick[80]; |
||
68 | |||
69 | struct js_event x52_event_struct; |
||
70 | |||
48 | ligi | 71 | int engines_on=0; |
72 | int old_engines_on=0; |
||
73 | |||
74 | char in_char; |
||
75 | |||
50 | ligi | 76 | struct ExternControl_s |
47 | ligi | 77 | { |
78 | unsigned char Digital[2]; // (noch unbenutzt) |
||
79 | unsigned char RemoteTasten; //(gab es schon für das virtuelle Display) |
||
80 | signed char Nick; |
||
81 | signed char Roll; |
||
82 | signed char Gier; |
||
83 | unsigned char Gas; //(es wird das Stick-Gas auf diesen Wert begrenzt; --> StickGas ist das Maximum) |
||
48 | ligi | 84 | signed char Higt; //(Höhenregler) |
47 | ligi | 85 | unsigned char free; // (unbenutzt) |
86 | unsigned char Frame; // (Bestätigung) |
||
87 | unsigned char Config; |
||
50 | ligi | 88 | }; |
47 | ligi | 89 | |
90 | |||
50 | ligi | 91 | struct ExternControl_s ExternControl ; |
47 | ligi | 92 | |
43 | ligi | 93 | int state=STATEID_SCANNING; |
94 | |||
95 | |||
96 | struct x52 *x52_output; |
||
97 | |||
98 | int selected_bt_device=0; |
||
41 | ligi | 99 | void scan_bt() |
100 | { |
||
101 | inquiry_info *ii = NULL; |
||
102 | |||
103 | int dev_id, sock, len, flags; |
||
104 | int i; |
||
105 | char addr[19] = { 0 }; |
||
106 | char name[248] = { 0 }; |
||
107 | |||
108 | dev_id = hci_get_route(NULL); |
||
109 | sock = hci_open_dev( dev_id ); |
||
110 | if (dev_id < 0 || sock < 0) { |
||
111 | perror("opening socket"); |
||
112 | exit(1); |
||
113 | } |
||
114 | |||
115 | len = 8; |
||
116 | |||
117 | flags = IREQ_CACHE_FLUSH; |
||
118 | ii = (inquiry_info*)malloc(MAX_BT_DEVICES * sizeof(inquiry_info)); |
||
119 | |||
120 | bt_device_count = hci_inquiry(dev_id, len, MAX_BT_DEVICES, NULL, &ii, flags); |
||
121 | if( bt_device_count < 0 ) perror("hci_inquiry"); |
||
122 | |||
123 | for (i = 0; i < bt_device_count; i++) { |
||
124 | ba2str(&(ii+i)->bdaddr, addr); |
||
125 | sprintf(addrs[i],"%s",addr); |
||
126 | |||
127 | memset(name, 0, sizeof(name)); |
||
128 | |||
129 | if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), |
||
130 | name, 0) < 0) |
||
131 | sprintf(names[i],"[unknown]"); |
||
132 | else |
||
133 | sprintf(names[i],"%s",name); |
||
134 | |||
135 | } |
||
136 | |||
137 | |||
138 | free( ii ); |
||
139 | close( sock ); |
||
140 | } |
||
141 | |||
142 | |||
50 | ligi | 143 | int connect_joy() |
43 | ligi | 144 | { |
41 | ligi | 145 | |
43 | ligi | 146 | |
147 | if( ( x52_input_fd = open( JOY_DEV, O_RDONLY ) ) < 0 ) |
||
148 | { |
||
149 | printf( "Couldn't open joystick device %s\n", JOY_DEV ); |
||
50 | ligi | 150 | printf( "try modprobe joydev\n" ); |
151 | return 0; |
||
43 | ligi | 152 | } |
153 | |||
154 | ioctl( x52_input_fd, JSIOCGAXES, &num_of_axis ); |
||
155 | ioctl( x52_input_fd, JSIOCGBUTTONS, &num_of_buttons ); |
||
156 | ioctl( x52_input_fd, JSIOCGNAME(80), &name_of_joystick ); |
||
157 | |||
158 | axis = (int *) calloc( num_of_axis, sizeof( int ) ); |
||
159 | button = (char *)calloc( num_of_buttons, sizeof( char ) ); |
||
160 | button_trigger = (char *) calloc( num_of_buttons, sizeof( char ) ); |
||
161 | |||
162 | printf("Joystick detected: %s\n\t%d axis\n\t%d buttons\n\n" |
||
163 | , name_of_joystick |
||
164 | , num_of_axis |
||
165 | , num_of_buttons ); |
||
166 | |||
167 | fcntl( x52_input_fd, F_SETFL, O_NONBLOCK ); /* use non-blocking mode */ |
||
168 | |||
50 | ligi | 169 | return 1; |
43 | ligi | 170 | } |
171 | |||
172 | |||
41 | ligi | 173 | |
174 | |||
43 | ligi | 175 | void AddCRC(unsigned int wieviele) |
176 | { |
||
177 | unsigned int tmpCRC = 0,i; |
||
178 | for(i = 0; i < wieviele;i++) |
||
179 | { |
||
180 | tmpCRC += TxBuffer[i]; |
||
181 | } |
||
182 | tmpCRC %= 4096; |
||
183 | TxBuffer[i++] = '=' + tmpCRC / 64; |
||
184 | TxBuffer[i++] = '=' + tmpCRC % 64; |
||
185 | TxBuffer[i++] = '\r'; |
||
186 | } |
||
41 | ligi | 187 | |
48 | ligi | 188 | |
189 | void SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len) |
||
43 | ligi | 190 | { |
50 | ligi | 191 | unsigned int pt = 0; |
192 | unsigned char a,b,c; |
||
193 | unsigned char ptr = 0; |
||
43 | ligi | 194 | |
50 | ligi | 195 | TxBuffer[pt++] = '#'; // Startzeichen |
196 | TxBuffer[pt++] = modul; // Adresse (a=0; b=1,...) |
||
197 | TxBuffer[pt++] = cmd; // Commando |
||
48 | ligi | 198 | |
50 | ligi | 199 | while(len) |
200 | { |
||
201 | if(len) { a = snd[ptr++]; len--;} else a = 0; |
||
202 | if(len) { b = snd[ptr++]; len--;} else b = 0; |
||
203 | if(len) { c = snd[ptr++]; len--;} else c = 0; |
||
204 | TxBuffer[pt++] = '=' + (a >> 2); |
||
205 | TxBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)); |
||
206 | TxBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)); |
||
207 | TxBuffer[pt++] = '=' + ( c & 0x3f); |
||
208 | } |
||
43 | ligi | 209 | |
48 | ligi | 210 | |
211 | |||
212 | AddCRC(pt); |
||
213 | printf("Sending to MK %d \n" , pt); |
||
214 | |||
43 | ligi | 215 | status = send(s,"\r" , 1, 0); |
48 | ligi | 216 | |
217 | |||
218 | // for (c=0;c<pt+2;c++) |
||
219 | // { |
||
50 | ligi | 220 | status = write(s,&TxBuffer , pt+3); |
221 | // printf("Send to MK %d \n" , TxBuffer[c] ); |
||
222 | // } |
||
48 | ligi | 223 | /*while(TxBuffer[i] !='\r' && i<150) |
43 | ligi | 224 | { |
50 | ligi | 225 | // TxBuffer[i]='#'; |
226 | status = send(s,&TxBuffer[i] , 1, 0); |
||
227 | printf(" +%d%c ",i,TxBuffer[i]); |
||
228 | i++; |
||
43 | ligi | 229 | } |
48 | ligi | 230 | |
50 | ligi | 231 | status = send(s,"\r" , 1, 0); |
48 | ligi | 232 | */ |
233 | // status = send(s,"\r" , 1, 0); |
||
43 | ligi | 234 | printf("\n"); |
235 | } |
||
41 | ligi | 236 | |
237 | |||
43 | ligi | 238 | void write_display(int line,char* text) |
239 | { |
||
240 | if (x52_output) x52_settext(x52_output, line , text, strlen(text)); |
||
241 | } |
||
242 | |||
243 | void clear_display() |
||
244 | { |
||
245 | write_display(0,""); |
||
246 | write_display(1,""); |
||
247 | write_display(2,""); |
||
248 | } |
||
249 | |||
250 | |||
251 | void output_device_list() |
||
252 | { |
||
253 | int i; |
||
254 | char disp_txt[20]; |
||
255 | for(i=0;i<bt_device_count;i++) |
||
256 | { |
||
257 | if (i<3) |
||
258 | { |
||
259 | |||
260 | if (selected_bt_device==i) |
||
261 | sprintf(disp_txt,"#%s",names[i]); |
||
262 | else |
||
263 | sprintf(disp_txt," %s",names[i]); |
||
264 | write_display(i,disp_txt); |
||
265 | } |
||
266 | } |
||
267 | } |
||
268 | |||
50 | ligi | 269 | int connect_mk(char dest[18]) |
43 | ligi | 270 | { |
271 | struct sockaddr_rc addr ; |
||
272 | |||
273 | // allocate a socket |
||
274 | s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); |
||
275 | |||
276 | // set the connection parameters (who to connect to) |
||
277 | addr.rc_family = AF_BLUETOOTH; |
||
278 | addr.rc_channel = 1; |
||
279 | str2ba( dest, &addr.rc_bdaddr ); |
||
280 | |||
281 | // connect to server |
||
282 | status = connect(s, (struct sockaddr *)&addr, sizeof(addr)); |
||
283 | |||
50 | ligi | 284 | return status; |
285 | |||
43 | ligi | 286 | } |
287 | |||
288 | |||
289 | |||
290 | |||
50 | ligi | 291 | int r=0; |
292 | int count=0; |
||
293 | int connected=0; |
||
43 | ligi | 294 | |
295 | int main(int argc, char**argv) |
||
296 | { |
||
297 | printf("Starting Riddim \n"); |
||
298 | printf("\tRemote Interactive Digital Drone Interface Mashup\n"); |
||
50 | ligi | 299 | |
300 | // 1st argument -> Bluetooth adrees to bypass scanning ( takes to long for short testing roundtrips ) |
||
301 | if (argv[1]) |
||
302 | { |
||
303 | if (connect_mk(argv[1])==-1) |
||
304 | { |
||
305 | printf("cant connect to QC at adress: %s\n",argv[1]); |
||
306 | return 0; |
||
307 | } |
||
308 | printf("connected to QC at adress: %s\n",argv[1]); |
||
309 | connected=1; |
||
310 | } |
||
47 | ligi | 311 | int i; |
312 | |||
43 | ligi | 313 | printf("\nInitializing X-52 input ..\n"); |
50 | ligi | 314 | if (!connect_joy()) return 0; |
315 | printf(".. done");// |
||
43 | ligi | 316 | |
50 | ligi | 317 | |
43 | ligi | 318 | printf("\nInitializing X-52 output .."); |
319 | |||
47 | ligi | 320 | x52_output = x52_init(); |
321 | |||
322 | clear_display(); |
||
43 | ligi | 323 | |
47 | ligi | 324 | write_display(0, "RIDDIM active"); |
43 | ligi | 325 | |
47 | ligi | 326 | if (x52_output) x52_setbri(x52_output, 1,128); |
327 | if (x52_output) |
||
328 | printf(" done \n"); |
||
329 | else |
||
330 | printf(" not found \n"); |
||
43 | ligi | 331 | |
50 | ligi | 332 | if (!connected) |
43 | ligi | 333 | { |
50 | ligi | 334 | printf("Scanning for Bluetooth Devices ..\n"); |
335 | write_display(1,"Bluetooth Scan"); |
||
336 | scan_bt(); |
||
337 | printf(" done \n"); |
||
338 | printf(" %d Devices found \n",bt_device_count); |
||
43 | ligi | 339 | } |
41 | ligi | 340 | |
50 | ligi | 341 | |
43 | ligi | 342 | int v_old; |
41 | ligi | 343 | while( 1 ) |
344 | { |
||
50 | ligi | 345 | // poll values from input device |
43 | ligi | 346 | int polls=0; |
50 | ligi | 347 | for (polls=0;polls<100;polls++) // FIXME - better Polling |
43 | ligi | 348 | { |
50 | ligi | 349 | read(x52_input_fd, &x52_event_struct, sizeof(struct js_event)); |
43 | ligi | 350 | |
351 | |||
50 | ligi | 352 | /* see what to do with the event */ |
353 | switch (x52_event_struct.type & ~JS_EVENT_INIT) |
||
354 | { |
||
355 | case JS_EVENT_AXIS: |
||
356 | axis [ x52_event_struct.number ] = x52_event_struct.value; |
||
357 | break; |
||
358 | case JS_EVENT_BUTTON: |
||
359 | button [ x52_event_struct.number ] = x52_event_struct.value; |
||
360 | break; |
||
361 | } |
||
43 | ligi | 362 | } |
47 | ligi | 363 | |
364 | for( x=0 ; x<num_of_buttons ; ++x ) |
||
365 | if( button[x]==0) |
||
366 | button_trigger[x]=0; |
||
367 | else |
||
368 | { |
||
369 | if (button_trigger[x]<100)button_trigger[x]++; |
||
370 | } |
||
43 | ligi | 371 | |
372 | |||
373 | |||
47 | ligi | 374 | switch(state) |
375 | { |
||
48 | ligi | 376 | |
377 | |||
47 | ligi | 378 | case STATEID_SCANNING: |
48 | ligi | 379 | |
50 | ligi | 380 | state=STATEID_CONNECTING; |
48 | ligi | 381 | |
382 | ExternControl.Digital[0]=0; |
||
383 | ExternControl.Digital[1]=0; |
||
384 | ExternControl.RemoteTasten=0; |
||
385 | ExternControl.Nick=(axis[1]>>8)*(-1)+127;; |
||
386 | |||
387 | printf("nick%d\n",ExternControl.Nick); |
||
388 | ExternControl.Roll=(axis[0]>>8)*(-1)+127;; |
||
389 | ExternControl.Gier=(axis[5]>>8)*(-1)+127;; |
||
390 | ExternControl.Gas=(axis[2]>>8)*(-1)+127; |
||
391 | ExternControl.Higt=0; |
||
392 | ExternControl.free=0; |
||
393 | ExternControl.Frame='t'; |
||
394 | ExternControl.Config=1; |
||
395 | |||
396 | printf("sending data\n"); |
||
397 | |||
50 | ligi | 398 | |
399 | SendOutData('b', 0, (unsigned char *)&ExternControl, sizeof(ExternControl)); |
||
400 | gettimeofday(&time_struct1,NULL); |
||
48 | ligi | 401 | |
47 | ligi | 402 | if (button_trigger[BUTTON_SELECT]==1) |
403 | { |
||
404 | state=STATEID_CONNECTING; |
||
405 | clear_display(); |
||
406 | write_display(0,"connecting to"); |
||
407 | write_display(1,names[selected_bt_device]); |
||
408 | connect_mk(addrs[selected_bt_device]); |
||
409 | write_display(0,"connected to"); |
||
410 | } |
||
43 | ligi | 411 | |
47 | ligi | 412 | if ((button_trigger[BUTTON_UP]+button_trigger[BUTTON_DOWN])==1) |
413 | { |
||
414 | printf("-> sel_dev %d - %d\n",selected_bt_device,button_trigger[19]); |
||
415 | if (button_trigger[BUTTON_DOWN]==1) |
||
416 | if (selected_bt_device>0) selected_bt_device--; |
||
417 | if (button_trigger[BUTTON_UP]==1) |
||
418 | if (selected_bt_device<bt_device_count-1) selected_bt_device++; |
||
419 | |||
420 | output_device_list() ; |
||
421 | } |
||
422 | break; |
||
48 | ligi | 423 | |
47 | ligi | 424 | case STATEID_CONNECTING: |
50 | ligi | 425 | |
48 | ligi | 426 | RxBuffer[1]=0; |
50 | ligi | 427 | |
428 | |||
429 | // ftime(&time_struct); |
||
430 | //printf("t:%d",time_struct.millitm); |
||
48 | ligi | 431 | while (RxBuffer[1]!='t') |
50 | ligi | 432 | { |
43 | ligi | 433 | |
50 | ligi | 434 | r=0; |
435 | in_char='#'; |
||
43 | ligi | 436 | |
50 | ligi | 437 | while(in_char!='\r') |
48 | ligi | 438 | { |
50 | ligi | 439 | count=read(s,&in_char,1); |
440 | if (in_char!=0) |
||
441 | { |
||
442 | RxBuffer[r++]=in_char; |
||
443 | } |
||
444 | else |
||
445 | { |
||
446 | RxBuffer[r++]='0'; |
||
447 | } |
||
448 | // printf("count:%d r:%d %d %c \n",count , r, in_char, in_char); |
||
48 | ligi | 449 | } |
50 | ligi | 450 | RxBuffer[r++]='\0'; |
451 | printf("--->%s\n",RxBuffer); |
||
452 | |||
48 | ligi | 453 | } |
50 | ligi | 454 | gettimeofday(&time_struct2,NULL); |
43 | ligi | 455 | |
50 | ligi | 456 | printf("last trip: %d",(int)(time_struct1.tv_usec-time_struct2.tv_usec)); |
457 | act_mode=button[24] | (button[25]<<1); |
||
43 | ligi | 458 | |
50 | ligi | 459 | switch (act_mode) |
460 | { |
||
461 | case 0: |
||
462 | act_nick=(axis[AXIS_NICK]>>8)*(INVERT_NICK); |
||
463 | act_roll=(axis[AXIS_ROLL]>>8)*(INVERT_ROLL); |
||
464 | act_gier=(axis[AXIS_GIER]>>8)*(INVERT_GIER); |
||
465 | act_gas=(axis[AXIS_GAS]>>8)*(INVERT_GAS); |
||
466 | |||
467 | break; |
||
468 | |||
469 | case 1: |
||
470 | act_nick=(axis[AXIS_NICK]>>8)*(INVERT_NICK)/2; |
||
471 | act_roll=(axis[AXIS_ROLL]>>8)*(INVERT_ROLL)/2; |
||
472 | act_gier=(axis[AXIS_GIER]>>8)*(INVERT_GIER)/2; |
||
473 | act_gas=(axis[AXIS_GAS]>>8)*(INVERT_GAS); |
||
474 | |||
475 | break; |
||
476 | |||
477 | case 2: |
||
478 | act_nick=(axis[AXIS_NICK]>>8)*(INVERT_NICK)/3; |
||
479 | act_roll=(axis[AXIS_ROLL]>>8)*(INVERT_ROLL)/3; |
||
480 | act_gier=(axis[AXIS_GIER]>>8)*(INVERT_GIER)/3; |
||
481 | act_gas=(axis[AXIS_GAS]>>8)*(INVERT_GAS); |
||
482 | |||
483 | |||
484 | break; |
||
485 | |||
486 | } |
||
487 | |||
48 | ligi | 488 | ExternControl.Digital[0]=0; |
489 | ExternControl.Digital[1]=0; |
||
490 | ExternControl.RemoteTasten=0; |
||
50 | ligi | 491 | ExternControl.Nick=act_nick; //(axis[1]>>8)*(-1)/2; |
492 | // printf("nick%d\n",ExternControl.Nick); |
||
493 | ExternControl.Roll=act_roll; //(axis[0]>>8)*(-1)/2; |
||
48 | ligi | 494 | ExternControl.Gier=(axis[5]>>8); |
495 | ExternControl.Gas=(axis[2]>>8)*(-1)+127; |
||
496 | ExternControl.Higt=0; |
||
497 | ExternControl.free=0; |
||
498 | ExternControl.Frame='t'; |
||
50 | ligi | 499 | |
48 | ligi | 500 | ExternControl.Config=1; |
50 | ligi | 501 | printf("act_mode %d , act_nick %d , act_roll %d , act_gier %d , act_gas %d",act_mode , act_nick , act_roll , act_gier , act_gas); |
48 | ligi | 502 | |
503 | |||
504 | |||
505 | printf("sending data\n"); |
||
506 | |||
50 | ligi | 507 | SendOutData('b', 0, (unsigned char *)&ExternControl, sizeof(ExternControl)); |
508 | gettimeofday(&time_struct1,NULL); |
||
48 | ligi | 509 | printf("sent data\n"); |
510 | |||
511 | |||
50 | ligi | 512 | // printf("sleeping\n"); |
513 | // usleep(10000); |
||
514 | // printf("end_sleep\n"); |
||
48 | ligi | 515 | |
47 | ligi | 516 | int v=axis[6]/655+50; |
517 | if (v!=v_old)if (x52_output) x52_setbri(x52_output, 0,v ); |
||
518 | v_old=v; |
||
519 | |||
48 | ligi | 520 | printf("v: %d \n",v); |
43 | ligi | 521 | |
522 | |||
47 | ligi | 523 | for (i=0;i<num_of_axis;i++) |
524 | printf("A%d: %d ", i,axis[i]>>8 ); |
||
525 | |||
526 | for( x=0 ; x<num_of_buttons ; ++x ) |
||
527 | |||
528 | printf("B%d: %d ", x, button[x] ); |
||
43 | ligi | 529 | |
47 | ligi | 530 | break; |
531 | } |
||
532 | |||
48 | ligi | 533 | printf("\n"); |
47 | ligi | 534 | fflush(stdout); |
48 | ligi | 535 | printf("loop fin"); |
43 | ligi | 536 | |
50 | ligi | 537 | } |
41 | ligi | 538 | |
43 | ligi | 539 | |
47 | ligi | 540 | /******************** Cleanup **********************/ |
541 | close(x52_input_fd); |
||
542 | close(s); |
||
41 | ligi | 543 | |
544 | if (x52_output) x52_close(x52_output); |
||
545 | return 0; |
||
546 | } |