Rev 50 |
Blame |
Last modification |
View Log
| RSS feed
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "lib/x52/x52.h"
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <sys/time.h>
#include <bluetooth/rfcomm.h>
#include <linux/joystick.h>
#define JOY_DEV "/dev/input/js0"
#define MAX_BT_DEVICES 3
#define STATEID_SCANNING 0
#define STATEID_CONNECTING 1
#define BUTTON_SELECT 26
#define BUTTON_DOWN 28
#define BUTTON_UP 27
// #define AXIS_ROLL 0
// #define AXIS_NICK 1
// #define AXIS_GIER 5
// #define AXIS_GAS 2
// for x52
/*
#define AXIS_ROLL 4
#define AXIS_NICK 3
#define AXIS_GIER 5
#define AXIS_GAS 2
#define INVERT_ROLL -1
#define INVERT_NICK -1
#define INVERT_GIER 1
#define INVERT_GAS -1
*/
#define AXIS_ROLL 0
#define AXIS_NICK 1
#define AXIS_GIER 3
#define AXIS_GAS 2
#define INVERT_ROLL 1
#define INVERT_NICK -1
#define INVERT_GIER 1
#define INVERT_GAS -1
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>//for close() for socket
#define INPUT_NONE 0
#define INPUT_JOYDEV 1
#define INPUT_EVDEV 2
// time struct for measuring
struct timeval time_struct1
;
struct timeval time_struct2
;
int act_nick
=0;
int act_roll
=0;
int act_gier
=0;
int act_gas
=0;
int act_mode
=0;
int bt_device_count
=0;
char names
[MAX_BT_DEVICES
][248];
char addrs
[MAX_BT_DEVICES
][19];
int s
, status
;
unsigned char TxBuffer
[150];
unsigned char _TxBuffer
[150];
char RxBuffer
[150];
int x52_input_fd
, *axis
=NULL
, num_of_axis
=0, num_of_buttons
=0, x
;
char *button
=NULL
,*button_trigger
=NULL
, name_of_joystick
[80];
struct js_event x52_event_struct
;
int engines_on
=0;
int old_engines_on
=0;
char in_char
;
struct ExternControl_s
{
unsigned char Digital
[2]; // (noch unbenutzt)
unsigned char RemoteTasten
; //(gab es schon für das virtuelle Display)
signed char Nick
;
signed char Roll
;
signed char Gier
;
unsigned char Gas
; //(es wird das Stick-Gas auf diesen Wert begrenzt; --> StickGas ist das Maximum)
signed char Higt
; //(Höhenregler)
unsigned char free; // (unbenutzt)
unsigned char Frame
; // (Bestätigung)
unsigned char Config
;
};
struct ExternControl_s ExternControl
;
int state
=STATEID_SCANNING
;
struct x52
*x52_output
;
int selected_bt_device
=0;
void scan_bt
()
{
inquiry_info
*ii
= NULL
;
int dev_id
, sock
, len
, flags
;
int i
;
char addr
[19] = { 0 };
char name
[248] = { 0 };
dev_id
= hci_get_route
(NULL
);
sock
= hci_open_dev
( dev_id
);
if (dev_id
< 0 || sock
< 0) {
perror("opening socket");
exit(1);
}
len
= 8;
flags
= IREQ_CACHE_FLUSH
;
ii
= (inquiry_info
*)malloc(MAX_BT_DEVICES
* sizeof(inquiry_info
));
bt_device_count
= hci_inquiry
(dev_id
, len
, MAX_BT_DEVICES
, NULL
, &ii
, flags
);
if( bt_device_count
< 0 ) perror("hci_inquiry");
for (i
= 0; i
< bt_device_count
; i
++) {
ba2str
(&(ii
+i
)->bdaddr
, addr
);
sprintf(addrs
[i
],"%s",addr
);
memset(name
, 0, sizeof(name
));
if (hci_read_remote_name
(sock
, &(ii
+i
)->bdaddr
, sizeof(name
),
name
, 0) < 0)
sprintf(names
[i
],"[unknown]");
else
sprintf(names
[i
],"%s",name
);
}
free( ii
);
close
( sock
);
}
int yalv
; /* loop counter */
size_t read_bytes
; /* how many bytes were read */
struct input_event ev
[64]; /* the events (up to 64 at once) */
int evdev_fd
;
int connect_evdev
()
{
if ((evdev_fd
= open
("/dev/input/event10", O_RDONLY
)) < 0) {
printf(" cant open evdev ");
return 0;
}
return 1;
}
int connect_joy
()
{
axis
= (int *) calloc( 100, sizeof( int ) );
button
= (char *)calloc( 100, sizeof( char ) );
button_trigger
= (char *) calloc( 100, sizeof( char ) );
// axis = (int *) calloc( num_of_axis, sizeof( int ) );
// button = (char *)calloc( num_of_buttons, sizeof( char ) );
// button_trigger = (char *) calloc( num_of_buttons, sizeof( char ) );
if( ( x52_input_fd
= open
( JOY_DEV
, O_RDONLY
) ) < 0 )
{
printf( "Couldn't open joystick device %s\n", JOY_DEV
);
printf( "try modprobe joydev\n" );
return 0;
}
ioctl
( x52_input_fd
, JSIOCGAXES
, &num_of_axis
);
ioctl
( x52_input_fd
, JSIOCGBUTTONS
, &num_of_buttons
);
ioctl
( x52_input_fd
, JSIOCGNAME
(80), &name_of_joystick
);
printf("Joystick detected: %s\n\t%d axis\n\t%d buttons\n\n"
, name_of_joystick
, num_of_axis
, num_of_buttons
);
fcntl
( x52_input_fd
, F_SETFL
, O_NONBLOCK
); /* use non-blocking mode */
return 1;
}
void AddCRC
(unsigned int wieviele
)
{
unsigned int tmpCRC
= 0,i
;
for(i
= 0; i
< wieviele
;i
++)
{
tmpCRC
+= TxBuffer
[i
];
}
tmpCRC
%= 4096;
TxBuffer
[i
++] = '=' + tmpCRC
/ 64;
TxBuffer
[i
++] = '=' + tmpCRC
% 64;
TxBuffer
[i
++] = '\r';
}
void SendOutData
(unsigned char cmd
,unsigned char modul
, unsigned char *snd
, unsigned char len
)
{
unsigned int pt
= 0;
unsigned char a
,b
,c
;
unsigned char ptr
= 0;
TxBuffer
[pt
++] = '#'; // Startzeichen
TxBuffer
[pt
++] = modul
; // Adresse (a=0; b=1,...)
TxBuffer
[pt
++] = cmd
; // Commando
while(len
)
{
if(len
) { a
= snd
[ptr
++]; len
--;} else a
= 0;
if(len
) { b
= snd
[ptr
++]; len
--;} else b
= 0;
if(len
) { c
= snd
[ptr
++]; len
--;} else c
= 0;
TxBuffer
[pt
++] = '=' + (a
>> 2);
TxBuffer
[pt
++] = '=' + (((a
& 0x03) << 4) | ((b
& 0xf0) >> 4));
TxBuffer
[pt
++] = '=' + (((b
& 0x0f) << 2) | ((c
& 0xc0) >> 6));
TxBuffer
[pt
++] = '=' + ( c
& 0x3f);
}
AddCRC
(pt
);
printf("Sending to MK %d \n" , pt
);
status
= send
(s
,"\r" , 1, 0);
// for (c=0;c<pt+2;c++)
// {
status
= write
(s
,&TxBuffer
, pt
+3);
// printf("Send to MK %d \n" , TxBuffer[c] );
// }
/*while(TxBuffer[i] !='\r' && i<150)
{
// TxBuffer[i]='#';
status = send(s,&TxBuffer[i] , 1, 0);
printf(" +%d%c ",i,TxBuffer[i]);
i++;
}
status = send(s,"\r" , 1, 0);
*/
// status = send(s,"\r" , 1, 0);
printf("\n");
}
void write_display
(int line
,char* text
)
{
if (x52_output
) x52_settext
(x52_output
, line
, text
, strlen(text
));
}
void clear_display
()
{
write_display
(0,"");
write_display
(1,"");
write_display
(2,"");
}
void output_device_list
()
{
int i
;
char disp_txt
[20];
for(i
=0;i
<bt_device_count
;i
++)
{
if (i
<3)
{
if (selected_bt_device
==i
)
sprintf(disp_txt
,"#%s",names
[i
]);
else
sprintf(disp_txt
," %s",names
[i
]);
write_display
(i
,disp_txt
);
}
}
}
int connect_mk
(char dest
[18])
{
struct sockaddr_rc addr
;
struct sockaddr_in sa
;
sa.
sin_family = AF_INET
;
sa.
sin_addr.
s_addr = htonl
(0x0);
sa.
sin_port = htons
(54321);
// allocate a socket
// s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
s
= socket
(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
//);
// set the connection parameters (who to connect to)
addr.
rc_family = AF_BLUETOOTH
;
addr.
rc_channel = 1;
str2ba
( dest
, &addr.
rc_bdaddr );
// connect to server
// status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
status
= connect
(s
,(struct sockaddr
*) &sa
, sizeof(struct sockaddr_in
));
return status
;
/*
struct sockaddr_rc addr ;
// allocate a socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// set the connection parameters (who to connect to)
addr.rc_family = AF_BLUETOOTH;
addr.rc_channel = 1;
str2ba( dest, &addr.rc_bdaddr );
// connect to server
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
return status;
*/
}
int r
=0;
int count
=0;
int connected
=0;
int input
=INPUT_NONE
;
int main
(int argc
, char**argv
)
{
printf("Starting Riddim \n");
printf("\tRemote Interactive Digital Drone Interface Mashup\n");
// 1st argument -> Bluetooth adrees to bypass scanning ( takes to long for short testing roundtrips )
if (argv
[1])
{
if (connect_mk
(argv
[1])==-1)
{
printf("cant connect to QC at adress: %s\n",argv
[1]);
return 0;
}
printf("connected to QC at adress: %s\n",argv
[1]);
connected
=1;
}
int i
;
printf("\nInitializing X-52 input ..\n");
if (connect_joy
())
{
printf(".. done");//
input
=INPUT_JOYDEV
;
}
else
printf(".. ERROR ");//
/* printf("\nInitializing evdev input ..\n");
if (connect_evdev())
{
printf(".. done");//
input=INPUT_EVDEV;
}
else
printf(".. ERROR ");//
*/
printf("\nInitializing X-52 output ..");
x52_output
= x52_init
();
clear_display
();
write_display
(0, "RIDDIM active");
if (x52_output
) x52_setbri
(x52_output
, 1,128);
if (x52_output
)
printf(" done \n");
else
printf(" not found \n");
if (!connected
)
{
printf("Scanning for Bluetooth Devices ..\n");
write_display
(1,"Bluetooth Scan");
scan_bt
();
printf(" done \n");
printf(" %d Devices found \n",bt_device_count
);
}
int v_old
;
int polls
=0;
printf("starting loop ..\n");
while( 1 )
{
switch (input
)
{
case INPUT_NONE
:
printf("input none\n");
usleep
(10000);
break;
case INPUT_EVDEV
:
printf("input evdev\n");
usleep
(30000);
read_bytes
= read
(evdev_fd
, ev
, sizeof(struct input_event
) * 64);
printf("read done\n");
if (read_bytes
< (int) sizeof(struct input_event
)) {
perror("evtest: short read");
exit (1);
}
for (yalv
= 0; yalv
< (int) (read_bytes
/ sizeof(struct input_event
)); yalv
++)
{
// 1 -> nick
// 2 -> gas
// 4->roll
// 5-> gier
axis
[ ev
[yalv
].
code]= ev
[yalv
].
value;
printf("nick:%d roll:%d gier:%d gas:%d\n",axis
[3] , axis
[4] , axis
[5] , axis
[2]);
/*if ( ev[yalv].code==5)
printf("Event: time %ld.%06ld, type %d, code %d, value %d\n",
ev[yalv].time.tv_sec, ev[yalv].time.tv_usec, ev[yalv].type,
ev[yalv].code, ev[yalv].value);
*/
}
break;
case INPUT_JOYDEV
:
printf("input joydev\n");
// poll values from input device
for (polls
=0;polls
<100;polls
++) // FIXME - better Polling
{
read
(x52_input_fd
, &x52_event_struct
, sizeof(struct js_event
));
/* see what to do with the event */
switch (x52_event_struct.
type & ~JS_EVENT_INIT
)
{
case JS_EVENT_AXIS
:
axis
[ x52_event_struct.
number ] = x52_event_struct.
value;
break;
case JS_EVENT_BUTTON
:
button
[ x52_event_struct.
number ] = x52_event_struct.
value;
break;
}
}
for( x
=0 ; x
<num_of_buttons
; ++x
)
if( button
[x
]==0)
button_trigger
[x
]=0;
else
{
if (button_trigger
[x
]<100)button_trigger
[x
]++;
}
break;
}
printf("input done\n");
switch(state
)
{
case STATEID_SCANNING
:
state
=STATEID_CONNECTING
;
ExternControl.
Digital[0]=0;
ExternControl.
Digital[1]=0;
ExternControl.
RemoteTasten=0;
ExternControl.
Nick=(axis
[1]>>8)*(-1)+127;;
printf("nick%d\n",ExternControl.
Nick);
ExternControl.
Roll=(axis
[0]>>8)*(-1)+127;;
ExternControl.
Gier=(axis
[5]>>8)*(-1)+127;;
ExternControl.
Gas=(axis
[2]>>8)*(-1)+127;
ExternControl.
Higt=0;
ExternControl.
free=0;
ExternControl.
Frame='t';
ExternControl.
Config=1;
printf("sending data\n");
SendOutData
('b', 0, (unsigned char *)&ExternControl
, sizeof(ExternControl
));
gettimeofday
(&time_struct1
,NULL
);
if (button_trigger
[BUTTON_SELECT
]==1)
{
state
=STATEID_CONNECTING
;
clear_display
();
write_display
(0,"connecting to");
write_display
(1,names
[selected_bt_device
]);
connect_mk
(addrs
[selected_bt_device
]);
write_display
(0,"connected to");
}
if ((button_trigger
[BUTTON_UP
]+button_trigger
[BUTTON_DOWN
])==1)
{
printf("-> sel_dev %d - %d\n",selected_bt_device
,button_trigger
[19]);
if (button_trigger
[BUTTON_DOWN
]==1)
if (selected_bt_device
>0) selected_bt_device
--;
if (button_trigger
[BUTTON_UP
]==1)
if (selected_bt_device
<bt_device_count
-1) selected_bt_device
++;
output_device_list
() ;
}
break;
case STATEID_CONNECTING
:
RxBuffer
[1]=0;
// ftime(&time_struct);
printf("waiting for confirm frame\n");
RxBuffer
[2]=0;
int confirm_misses
=0;
while (RxBuffer
[2]!='t')
{
r
=0;
in_char
='#';
while(in_char
!='\n')
{
count
=read
(s
,&in_char
,1);
if (in_char
!=0)
{
RxBuffer
[r
++]=in_char
;
}
else
{
RxBuffer
[r
++]='0';
}
// printf("\ncount:%d r:%d %d %c \n",count , r, in_char, in_char);
}
RxBuffer
[r
++]='\0';
printf("--->%s\n",RxBuffer
);
// new
if (button_trigger
[12]>1)
{
SendOutData
('s', 0, (unsigned char *)&ExternControl
, sizeof(ExternControl
));
button_trigger
[12]=0;
}
if (++confirm_misses
>4)
SendOutData
('b', 0, (unsigned char *)&ExternControl
, sizeof(ExternControl
));
}
gettimeofday
(&time_struct2
,NULL
);
printf("last trip: %d",(int)(time_struct1.
tv_usec-time_struct2.
tv_usec));
act_mode
=button
[24] | (button
[25]<<1);
switch (act_mode
)
{
case 0:
act_nick
=(axis
[AXIS_NICK
]>>8)*(INVERT_NICK
);
act_roll
=(axis
[AXIS_ROLL
]>>8)*(INVERT_ROLL
);
act_gier
=(axis
[AXIS_GIER
]>>8)*(INVERT_GIER
);
act_gas
=((axis
[AXIS_GAS
]>>8)-128)*(-1);
// clip gas
if (act_gas
<0) act_gas
=0;
if (act_gas
>250) act_gas
=250;
//////// act_gas=0;
break;
case 1:
act_nick
=(axis
[AXIS_NICK
]>>8)*(INVERT_NICK
)/2;
act_roll
=(axis
[AXIS_ROLL
]>>8)*(INVERT_ROLL
)/2;
act_gier
=(axis
[AXIS_GIER
]>>8)*(INVERT_GIER
)/2;
act_gas
=(axis
[AXIS_GAS
]>>8)*(INVERT_GAS
);
break;
case 2:
act_nick
=(axis
[AXIS_NICK
]>>8)*(INVERT_NICK
)/3;
act_roll
=(axis
[AXIS_ROLL
]>>8)*(INVERT_ROLL
)/3;
act_gier
=(axis
[AXIS_GIER
]>>8)*(INVERT_GIER
)/3;
act_gas
=(axis
[AXIS_GAS
]>>8)*(INVERT_GAS
);
break;
}
ExternControl.
Digital[0]=0;
ExternControl.
Digital[1]=0;
ExternControl.
RemoteTasten=0;
ExternControl.
Nick=act_nick
; //(axis[1]>>8)*(-1)/2;
// printf("nick%d\n",ExternControl.Nick);
ExternControl.
Roll=act_roll
*(-1); //(axis[0]>>8)*(-1)/2;
ExternControl.
Gier=(axis
[5]>>8);
ExternControl.
Gier=act_gier
; // ************
ExternControl.
Gas=(axis
[2]>>8)*(-1)+127;
ExternControl.
Gas=act_gas
; // ************
// ExternControl.Gas=0; // ************
ExternControl.
Higt=0;
ExternControl.
free=0;
ExternControl.
Frame='t';
ExternControl.
Config=1;
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
);
printf("sending data\n");
SendOutData
('b', 0, (unsigned char *)&ExternControl
, sizeof(ExternControl
));
gettimeofday
(&time_struct1
,NULL
);
printf("sent data\n");
// printf("sleeping\n");
// for (polls=0;polls<100;polls++) // FIXME - better Polling
// printf("end_sleep\n");
int v
=axis
[6]/655+50;
if (v
!=v_old
)if (x52_output
) x52_setbri
(x52_output
, 0,v
);
v_old
=v
;
printf("v: %d \n",v
);
for (i
=0;i
<num_of_axis
;i
++)
printf("A%d: %d ", i
,axis
[i
]>>8 );
for( x
=0 ; x
<num_of_buttons
; ++x
)
printf("B%d: %d ", x
, button
[x
] );
break;
}
printf("\n");
fflush(stdout
);
printf("loop fin");
}
/******************** Cleanup **********************/
close
(x52_input_fd
);
close
(s
);
if (x52_output
) x52_close
(x52_output
);
return 0;
}