Mapping device input event codes to new event codes - linux

I am currently trying to restore an old arcade machine, and I'm running into issues with interpreting the events from the usb controller. In particular, the controller is sending the event code 1:300 (EV_KEY:300), but unfortunately 300 is not a valid event code. Because of this, I am unable to get it to work with the arcade software that I am using.
What I'm looking to do is run a process that intercepts the 1:300 events and turns them into some other type of event. For example, every time I press the joystick, I may want it to be interpreted as 1:194 (EV_KEY:KEY_F24).
Any idea how to do this?
Output from evtest:
Event: time 1669313468.400824, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9000d
Event: time 1669313468.400824, type 1 (EV_KEY), code 300 (?), value 0
I've tried various input mapping softwares such as evsieve, but to no avail.
Output from evsieve:
While parsing the arguments "--map key:300 key:up":
While parsing the key "key:300":
Invalid argument: unknown event code "300".

Well I think I at least found a temporary workaround:
CONTROLLER1_LOCATION=/dev/input/by-id/usb-GGG_GPWiz49-event-joystick
CONTROLLER1_EVENT_PORT=event6
BTN=BTN_TRIGGER_HAPPY4
sudo /bin/evtest $CONTROLLER1_LOCATION EV_KEY 300 \
| grep "300.*value" --line-buffered \
| grep --line-buffered -o "[01]$" \
| while read x ; do sudo evemu-event /dev/input/$CONTROLLER1_EVENT_PORT --type EV_KEY --code $BTN --value $x ; done
Basically this:
Monitors the device for matching erroneous events
Takes the output that corresponds to actual button presses
And sends a virtual event from the controller
This could definitely be cleaned up, but it'll do for now

Related

Strange status changed in alsamixer

My audio system is simple: two speakers in the rear panel--front left(FL) ,front right(FR) ,headphone in the front panel. The primitive status is as below--primitive status:
In this status , sound can be heared from FL,FR,and headphone.
I find a strange fact that master,front,surround in alsamixer changed into MM status when to click M on LFE,i move the cursor on LFE,and click M,LFE changed into MM,at the same time master,front,surround all changed into MM status !No sound can be heared !
And i click M for the second time on LFE,all status changed as below:
Let's go on from the primitive status,and unplug line from rear panel,no sound in headphone! The status in alsamixer gui is as below:
Now re-plug the line in the rear panel,the status in alsamixer gui turns into :
Please give an explanation in detail.
To see what's going on:
In one terminal window, run alsactl monitor.
In another terminal window, run alsamixer.
As you mute/unmute things in alsamixer, you can see the control commands in the monitor window. You should see multiple switch commands show up when you mute the LFE.
The reason this is happening is because of the pulseaudio profile in use by alsamixer.
Profiles are located in /usr/share/pulseaudio/alsa-mixer/profile-sets/*.conf
Paths are located in /usr/share/pulseaudio/alsa-mixer/paths/*.conf
So which ones are in use? You can check that with pacmd info | grep "active", which may produce something like:
active port: <analog-output-speaker>
active port: <analog-input-headphone-mic>
active profile: <output:analog-stereo+input:analog-stereo>
Ok, so the output mapping is analog-stereo. I can find this in /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf. It contains the following:
[Mapping analog-stereo]
device-strings = front:%f hw:%f
channel-map = left,right
paths-output = analog-output analog-output-lineout analog-output-speaker analog-output-headphones analog-output-headphones-2
paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
priority = 10
The real control is under /usr/share/pulseaudio/alsa-mixer/paths/analog-output-speaker.conf. You can read /usr/share/pulseaudio/alsa-mixer/paths/analog-output.conf.common for details, where we see two important sections:
; When a device shall be muted/unmuted *all* elements listed in a path
; file with "switch = mute" will be toggled.
(there's a bit of a caveat to this one. It seems that unmuting does NOT toggle other elements in the path)
and
; [Element ...] # For each element that we shall control
...
; switch = ignore | mute | off | on | select # What to do with this switch: ignore it, make it follow mute status,
; # always set it to off, always to on, or make it selectable as port.
; # If set to 'select' you need to define an Option section for on
; # and off
...
So now, if we want to adjust an element such that it's always on, always off, or simply ignores muting, we would set the corresponding switch= values in the Element of interest.
If you want to adjust the behavior of the headphones when activating that path (i.e. when plugging them in), change the Element values in paths/analog-output-headphones.conf

Linux Read - Timeout after x seconds *idle*

I have a (bash) script on a server that I have inherited the administration aspect of, and have recently discovered a flaw in the script that nobody has brought to my attention.
After discovering the issue, others have told me that it has been irritating them, but never told me (great...)
So, the script follows this concept
#!/bin/bash
function refreshscreen(){
# This function refreshes a "statistics screen"
...
echo "Enter command to override update"
read -t 10 variable
}
This script refreshes a statistics screen, and allows the user to stall the update in lieu of commands built into a case statement. However, the read times-out (read -t 10) after 10 seconds, regardless of if the user is typing.
Long story short, is there a way to prevent read from timing out if the user is actively typing a command? Best case scenario would be a "Time out of SEC idle/inactive seconds" opposed to just timeout after x seconds.
I have thought about running a background script at the end of the cycle before the read command pauses the screen to check for inactivity, but have not found a way to make that command work.
You can use read in a loop, reading one character at a time, and adding it to a final read string. This would then give the user some timeout amount of time per character rather than per command. Here's a sample function you might be able to incorporate into your script that shows what I'm talking about:
read_with_idle_timeout() {
local input=""
read -t 10 -N 1 variable
while [ ! -z $variable ]
do
input+=$variable
read -t 10 -N 1 variable
done
echo "Read: $input"
}
This will give the user 10 seconds to type each character. If they stop typing, you'll get as much of the command as they had started typing before the timeout occurred, and then your case statement can handle it. Perhaps you can store the final string in a global variable, or just put this code directly into your other function.
If you need more than one word, since read breaks on $IFS, you could call this function multiple times until you get all the input you're expecting.
I have searched for a simple solution that will do the following:
timeout after 10 seconds, if there is no user input at all
the user has infinite time to finish his answer if the first character was typed within the first 10 sec.
This can be implemented in two lines as follows:
read -N 1 -t 10 -p "What is your name? > " a
[ "$a" != "" ] && read b && echo "Your name is $a$b" || echo "(timeout)"
In case the user waits 10 sec before he enters the first character, the output will be:
What is your name? > (timeout)
If the user types the first character within 10 sec, he has unlimited time to finish this task. The output will look like follows:
What is your name? > Oliver
Your name is Oliver
Caveat: the first character is not editable, once it was typed, while all other characters can be edited (backspace and re-type). Any ideas for a simple solution?

alsa: How to programmatically find if a device is busy/in use using it name and without opening it

We have a Linux device which has a speaker and MIC devices. These devices are shared among different modules - example a VOIP call can use speaker, a hazard Warning system can use speaker, a Voice prompt can use a speaker etc:
There seems to be a function in ALSA which uses pcm to provide the status.
int snd_pcm_status (snd_pcm_t * pcm, snd_pcm_status_t * status)
However the *pcm is returned by snd_pcm_open. We do not want to open the device as we would like to know the status of the device using its "name"
Alsa API is here
How can we check if a resource/device is busy without opening it and using its name?
The same information for playback stream X of device Y on card Z is available in the file /proc/asound/cardZ/pcmYp/subX/status; when the device is not open, it just says "closed".
Please note that you cannot use this information to decide if you can open the device, because some other process could have openend it just after you've read this information. The only way to check if you can open it is to actually try.
Though it requires /dev/dsp, this seems to work:
#!/bin/dash
## If the speaker is not used by any, returns 0, and prints "free"
## Otherwise, returns 1 and prints "not free"
iExit (){
trap '' 0
exit $1
}
iCatch (){
# The speaker is already in use
echo not free
iExit 1
}
trap iCatch 0
{
exec 3>&1 1>/dev/dsp
# If the execution reaches here, the speaker is not used by any
# Otherwise, it's catched by iCatch
exec 1>&3
echo free
iExit 0
} 2>/dev/null
Without PulseAudio, it seems on some PC only one output is accepted at one time; on others simultaneous playbacks are allowed. But even in the latter case, the above code works.
NB: The above code does not work with bash; for bash, simply use if/else rather than trap.
NB 2: /dev/dsp may be lacking depending on the kernel configuration.

The coldStart trap's parameters - Whats going on and how do I find out what they should be

The coldStart trap's parameters - Whats going on and how do I find out what they should be
Hello, I'm new to SNMP, and have a simple question. I'm trying to send a coldStart trap to another system. The coldStart trap's OID is 1.3.6.1.6.3.1.1.5.1
Here is the coldStart's description in the mib:
coldStart NOTIFICATION-TYPE
STATUS current
DESCRIPTION
"A coldStart trap signifies that the SNMP entity,
supporting a notification originator application, is
reinitializing itself and that its configuration may
have been altered."
::= { snmpTraps 1 }
Clear thus far. Now, I'll try to send the trap:
# snmptrap -v 2c -c public otherLinuxSystem SNMPv2-MIB::coldStart
and this command returns:
Missing trap-oid parameter
What? Theres nothing in the mib about parameters. So, I googled, and I found adding a value, 0 in this case:
# snmptrap -v 2c -c public otherLinuxSystem SNMPv2-MIB::coldStart 0
Works. 1 or 2 works too. Heres my questions:
Do all traps have a parameter and its just implied? Is this defined somewhere I missed? How do I know what values represent what? what does 0, 1, and 2 mean in this case, and how can I find this myself in the future? Thanks.
The issue you observe is nothing specific to coldStart, but is just an issue of mistaken usage of net-snmp's snmptrap command. If you look at the bottom of the usage info if you call "snmptrap" with no parameters, you'll see:
-v 1 TRAP-PARAMETERS:
enterprise-oid agent trap-type specific-type uptime [OID TYPE VALUE]...
or
-v 2 TRAP-PARAMETERS:
uptime trapoid [OID TYPE VALUE] ...
You specified -v 2c in your argument, so snmptrap expects the second form. That is, two arguments required after the target address (otherLinuxSystem in your example): a value for sysUpTime.0 and a value for snmpTrapOID.0 that will be included in the trap (I suspect the arguments are swapped in your second example).
The first indicates when the trap occurred and the second identifies the trap itself. Both are required variables in all SNMPv2c/v3 traps; it just happens that net-snmp's snmptrap requires you to specify both of these (rather than, say, defaulting to the host's uptime for sysUpTime.0 if unspecified).

Calculating the difference between the first words(timestamp) using perl dynamically

I have a program that keeps on writing the icmp echo requests being received by a machine into a file.
I am using system ("tcpdump icmpecho[0] == 8 | tee abc.txt") to do that.
So this process keeps on going till I end the program manually.
Each line has the timestamp as its first word.
now i want to calculate the frequency of the echo requests I am receiving using a separate script so that if it reaches a certain threshold , I can print an alert.
I tried to use grep -Eo '^[^ ]+' file
to get the timestamps into an array, but I dont know what to do after getting them into an array. grep goes on in a while loop since the file it is reading from keeps on getting populated infinitely.(I'll not have an option of monitoring the differences and printing an alert if grep goes on like that right?)
All I am trying to do is to keep track of the frequency of icmp echo requests that are coming in on my machine and print an alert message whenever that frequency crosses a threshold. is there any alternative way?
All timestamps are saved in #arr
perl -ne '$f{$_}++ or push #arr, $_ for /(\d+:\d+)/ }{ print "$_ [$f{$_} times]\n" for #arr' file
constantly reading from log file,
perl -e 'open$T,pop;while(1){while(<$T>){ ++$f{$_}>10 and print "[$f{$_}]$_" for /(\d+:\d+)/ }sleep 1;seek $T,0,1}' file
I am using
tcpstat -i eth1 -f icmp[0] == 8
to get the request count. it gives me 3 more parameters but got to research a bit bout them!

Resources