Is there a way to get the evdev keycode from a string? - c

I'd like to read button mappings from a text file that contains data like this:
DPAD_LEFT = 105
DPAD_RIGHT = 106
DPAD_UP = 103
DPAD_DOWN = 108
The right part is actually the evdev keycode (as defined in <linux/input.h>).
This is quite hard to read, so I'd like to be able have files like this:
DPAD_LEFT = KEY_LEFT
DPAD_RIGHT = KEY_RIGHT
DPAD_UP = KEY_UP
DPAD_DOWN = KEY_DOWN
But I'm currently not able to convert them back:
char[256] keyname;
some_method_to_read(&keyname, "DPAD_LEFT");
//keyname now contains "KEY_LEFT"
How do I get the corresponding keycode (e.g. 105)? Is there a standard way to do this?
EDIT: The only way I can think of right now is by duplicating all the keycodes in my source and putting them in an array or map, like the evtest utility does. But there are a lot of keycodes and this seems quite a bit of overkill to me. Also, this might get out-of-sync with the keycodes defined in <input/linux.h> at some point.
std::map<string, int> keynames;
#define MAP_KEYCODE(keycode) keynames[#keycode] = keycode
MAP_KEYCODE(KEY_LEFT);
MAP_KEYCODE(KEY_RIGHT);
MAP_KEYCODE(KEY_UP);
MAP_KEYCODE(KEY_DOWN);
// [...]

Have your program read the name-to-code mapping from a configuration file(s), say /usr/share/yourprogram/keycodes and/or $HOME/.yourprogram/keycodes.
Document that anyone can regenerate that file from their /usr/include/linux/input.h -- and regenerate the initial file yourself -- using for example
awk '$2 ~ /^KEY_/ { code[$2] = $3 }
END {
for (name in code)
if (code[name] ~ /^KEY_/)
code[name] = code[code[name]];
for (name in code)
if (code[name] !~ /KEY_/)
printf "%-24s %s\n", name, code[name]
}' /usr/include/linux/input.h | sort
You might have to add KEY_CNT youself (it's value is one more than KEY_MAX), as the above script does not do math, only direct aliases.
To describing the name-to-code mappings, I'd use
struct keycode {
struct keycode *next;
unsigned int code;
unsigned int hash;
unsigned char namelen;
char name[];
};
where the hash is a simple hash, say djb2,
unsigned int djb2(const char *const str, const size_t len)
{
unsigned int result = 5831U;
size_t i;
for (i = 0; i < len; i++)
result = result * 33U ^ (unsigned int)str[i];
return result;
}
Of currently defined key codes, only KEY_CUT and KEY_F15 map to the same djb2 hash, 1857856141. (If you used 31U instead of 33U, the current set would have no collisions, but that's no proof against future collisions. Better have one collision already, so you can test it is handled correctly.)
The function that reads the configuration file could just return the codes by prepending new ones to a singly-linked list, perhaps
int read_keycodes(const char *const filename,
struct keycode **list);
If you prepend to the list, you should later on ignore redefinitions of the same name. This way, if you read the system-wide configuration first, then the user-specific one, the user-specific one can override the system-wide ones.
After all keycode mappings are read, you construct a hash table, something like
struct keytab {
unsigned int size; /* index = hash % size */
struct keycode **slot;
};
(When building the hash table, discard keycodes whose exact names are already in the keytab. This way later definitions override earlier ones.)
This way you only need to calculate the hash of the name you want to look up, then probe the linked list in your keytab structure. Compare hashes first, then lengths; if both match, finally do a strcmp(). This way the lookup will be very fast, and relatively simple to implement, too. With current key codes, you'll only do the slow strcmp() twice for KEY_F15 and KEY_CUT; for all others, a single strcmp() will suffice.
Questions?

I found a way to do this properly: By using libevdev's libevdev_event_code_from_name function.
unsigned int event_type = EV_KEY;
const char* name = "BTN_A";
int code = libevdev_event_code_from_name(event_type, name);
if(code < 0)
{
puts("There was an error!");
}

Related

How to calculate SHA512/224 and SHA512/256 hashes using OpenSSL?

Here's how I calculate a SHA512 hash in C.
#include <openssl/sha.h>
#include <stdio.h>
char *calc_sha512(char *data) {
SHA512_CTX ctx;
char *md = malloc(sizeof(char)*(SHA512_DIGEST_LENGTH+1));
SHA512_Init(&ctx);
SHA512_Update(&ctx, data, strlen(data));
SHA512_Final(md, &ctx);
md[SHA512_DIGEST_LENGTH] = '\0';
return md;
}
int main() {
printf("%s\n", calc_sha512("foo"));
return 1;
}
Now when I try to transform it to 512/t (either 512/224 or 512/256), it doesn't work. I initially thought that for calculating a 512/t hash, you'd simply have to truncate the output to t bits, but upon further reading, it doesn't only truncate the output, it also have different initial constant values. So I'm trying to figure out any function in OpenSSL that supports that? So far I have looked into docs and header files, I can't find such method under either SHA or EVP. Does OpenSSL even support SHA512/t hashing algorithms? Does it provide the functionality out of the box? Any pointers to that would be helpful.
As you noticed, those truncated sha512 hashes use different initalisation vectors, probably to avoid giving away part of the actual sha512 hash if they would just literally truncate those bytes.
Support for sha512_256 has been implemented in the OpenSSL master tree a few months ago and will likely be in OpenSSL 1.1.1.
Check the changelog:
https://www.openssl.org/news/changelog.txt
Or the commit on Github:
https://github.com/openssl/openssl/commit/4bed94f0c11ef63587c6b2edb03c3c438e221604
... so depending on the platform you're on, you could use those new functions in the near future just like you are doing with the sha512 example you provided.
this function should return the SHA512/256 hash (binary form, not printable)
char *calc_sha512_256(char *data, unsigned int data_len) {
char *hash = malloc(SHA256_DIGEST_LENGTH);
if (!EVP_Digest(data, data_len, hash, NULL, EVP_sha512_256(), NULL)) {
free(hash);
hash = NULL;
}
return hash;
}

Unique String generator

I want to make a program (network server-client).
One of the specification for this program is next:
The server will receive the sent packages and save it into a file, with a unique name (generated by the server at the moment the transfer starts.
Ex __tf_"unique_random_string".txt
I made a function that returns a pointer to a "unique" string created.
The problem is: If i stop the server and then start it again it will generate the same names.
Ex:this file names were generated and then i stopped the server.
__ft_apqfwk.txt
__ft_arzowk.txt
__ft_cdyggx.txt
I start it again and i try to generate 3 file names. Them will be the same.
Sorry for my english. I'm still learning it.
My function to generate this "unique string" is:
char *create_random_name(void)
{
const char charset[] = "abcdefghijklmnopqrstuvwxyz";
char *file_name;
int i=0;
int key;
if((file_name = malloc(16 * sizeof ( char )) ) == NULL)
{
printf("Failed to alloc memory space\n");
return NULL;
}
strcpy(file_name,"__ft_");
for(i=5 ; i<11 ; i++)
{
key = rand() % (int)(sizeof(charset)-1);
file_name[i]=charset[key];
}
strcat(file_name,".txt");
file_name[15] = '\0';
return file_name;
}
One option is saving to a file the names that have been used, and using them as a checklist. You also want to seed rand with something like srand(time(NULL)).
another is ignoring the randomisation, and just going in order, e.g. aaa, aab aac...aba ,abb etc. Again, save where your cycle is up to on a file.
Your question seems a little bit unclear but if you want to generate a unique string there are a couple of things you can consider:
Get System timestamp ( yyyy-MM-dd-HH-mm-ss-fff-tt)
Use Random function to generate a random number
Combine this with your function and I am sure you will get a unique string.
Hope it helps !
If it's available, you could avoid manually generating random names that might collide and let the system do it for you (and handle collision resolution by creating a new name) by using mkstemps. This is also safer because it opens the file for you, removing the risk of a random name being generated, verified to be unique, then trying to open it and discovering another thread/process raced in and created it.
char name[] = "/path/to/put/files/in/__ft_XXXXXX.txt";
int fd = mkstemps(name, strlen(".txt"));
if (fd == -1) { ... handle error ... }
After mkstemps succeeds, name will hold the path to the file (it's mutated in place, replacing the XXXXXX string), and fd will be an open file descriptor to that newly created file; if you need a FILE*, use fdopen to convert to a stdio type.
Before calling rand(),--- once and only once---, call srand(time()) to initialize the random number generator.
Before settling on any specific file name, call stat() to assure that file name does not already exist.

major(stat.st_rdev) and minor(stat.st_rdev) on non-device files

Simple questions: in Linux, I stat() a file that is not a device. what is the expected value of the st_rdev field? Is it ok for me to run major(stat.st_rdev) and minor(stat.st_rdev)? If so, what are the expected return values?
Code example:
struct stat sstat = stat("myfileordevice");
ProcessFileOrDevice("myfileordevice",
sstat.st_mode,
major(stat.st_rdev),
minor(stat.st_rdev));
What value stat.st_rdev should have if I stat() a non-device filesystem entry?
It depends on the filesystem that the entry is on. The internal structures and functions in Linux (such asfs/stat.c) allow each filesystem to define the values.
In general, the value should be zero. Quick testing (stat -c '%t:%T' some-files-and-directories) indicates it tends to be. I just cannot find any guarantees or claims it should be zero.
Is it safe to use major(stat.st_rdev) and minor(stat.st_rdev)
Of course; they only apply some arithmetic to the specified value, and return the result.
Personally, I'd be inclined to use something like
unsigned int maj, min;
struct stat info;
/* stat(), fstat(), fstatat() or something
to fill the info buffer */
if (S_ISCHR(info.st_mode) || S_ISBLK(info.st_mode)) {
maj = major(info.st_rdev);
min = minor(info.sr_rdev);
} else {
maj = 0U;
min = 0U;
}
ProcessFileOrDevice("myfileordevice", info.st_mode, maj, min);
just to make sure. Note that the ProcessFileOrDevice() function could just as well do the check itself, and ignore maj and min values unless S_ISCHR(info.st_mode) or S_ISBLK(info.st_mode) values are true.
The man 2 stat man page contains further useful details.

Function overriding in C

I have a requirement in C similar to function overriding. I have 2 devices with different device IDs. I have a process which just calls device_create(device_id). The process doesn't know which device_create to call. It is upto driver of the device to execute device_create if the device_id matches to driver's device Id. Is there any way to do it in C?
If you use different shared objects (or dlls) to implement the function you could handle this programatically on your own. You could create a plugin like structure and use something like the Command pattern.
Not exactly simple, but can help with your problem.
Cheers.
OK. Understand I'm still of the mark, but leave this post for now.
You do not know the ID when process starts. When HW is attached you read the ID and want to call correct function based on the ID but without using the ID directly?
The closest I can think of as a simple solution is by using an array of function pointers:
void (*funs[3])(void) = {
&device_create100,
&device_create200,
NULL
};
But then only if you can normalize the ID to match index of the array. Say all ID's are in the range 1000-1032 that would be an 32 long function pointer array where you can use ID - 1000.
As this is rather unlikely you could resort to a sorted list, binary tree, hash table or the like on which you do a lookup.
struct node {
int (*fun)(void);
int id;
struct *node left;
struct *node right;
}
This is of course then assuming you have a rather big list of possible ID's and a switch is out of the question.
Old post.
What about function pointers:
int (*device_create)(int);
int device_create_init(int id)
{
switch (id) {
case 0x0a:
device_create = &device_create_100;
break;
case 0x0b:
device_create = &device_create_200;
break;
}
/* After first call, the now set device_create_xxx function will be
invoked on device_create() */
return device_create(id);
}
int main(void)
{
device_create = &device_create_init;
/* Loop */
return 0;
}

How do I write a dispatcher, if my compiler's support for pointers-to-functions is broken?

I am working on an embedded application where the device is controlled through a command interface. I mocked the command dispatcher in VC and had it working to my satisfaction; but when I then moved the code over to the embedded environment, I found out that the compiler has a broken implementation of pointer-to-func's.
Here's how I originally implemented the code (in VC):
/* Relevant parts of header file */
typedef struct command {
const char *code;
void *set_dispatcher;
void *get_dispatcher;
const char *_description;
} command_t;
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label, &set_##dispatcher, &get_##dispatcher, (const char*)description}
/* Dispatcher data structure in the C file */
const command_t commands[] = {
COMMAND_ENTRY("DH", Dhcp, "DHCP (0=off, 1=on)"),
COMMAND_ENTRY("IP", Ip, "IP Address (192.168.1.205)"),
COMMAND_ENTRY("SM", Subnet, "Subunet Mask (255.255.255.0)"),
COMMAND_ENTRY("DR", DefaultRoute, "Default router (192.168.1.1)"),
COMMAND_ENTRY("UN", Username, "Web username"),
COMMAND_ENTRY("PW", Password, "Web password"),
...
}
/* After matching the received command string to the command "label", the command is dispatched */
if (pc->isGetter)
return ((get_fn_t)(commands[i].get_dispatcher))(pc);
else
return ((set_fn_t)(commands[i].set_dispatcher))(pc);
}
Without the use of function pointers, it seems like my only hope is to use switch()/case statements to call functions. But I'd like to avoid having to manually maintain a large switch() statement.
What I was thinking of doing is moving all the COMMAND_ENTRY lines into a separate include file. Then wraps that include file with varying #define and #undefines. Something like:
/* Create enum's labels */
#define COMMAND_ENTRY(label,dispatcher,description) SET_##dispatcher, GET_##dispatcher
typedef enum command_labels = {
#include "entries.cinc"
DUMMY_ENUM_ENTRY} command_labels_t;
#undefine COMMAND_ENTRY
/* Create command mapping table */
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label, SET_##dispatcher, GET_##dispatcher, (const char*)description}
const command_t commands[] = {
#include "entries.cinc"
NULL /* dummy */ };
#undefine COMMAND_ENTRY
/*...*/
int command_dispatcher(command_labels_t dispatcher_id) {
/* Create dispatcher switch statement */
#define COMMAND_ENTRY(label,dispatcher,description) case SET_##dispatcher: return set_##dispatcher(pc); case GET_##dispatcher: return get_##dispatcher(pc);
switch(dispatcher_id) {
#include "entries.cinc"
default:
return NOT_FOUND;
}
#undefine COMMAND_ENTRY
}
Does anyone see a better way to handle this situation? Sadly, 'get another compiler' is not a viable option. :(
--- Edit to add:
Just to clarify, the particular embedded environment is broken in that the compiler is supposed to create a "function-pointer table" which is then used by the compiler to resolve calls to functions through a pointer. Unfortunately, the compiler is broken and doesn't generate a correct function-table.
So I don't have an easy way to extract the func address to invoke it.
--- Edit #2:
Ah, yes, the use of void *(set|get)_dispatcher was my attempt to see if the problem was with the typedefine of the func pointers. Originally, I had
typedef int (*set_fn_t)(cmdContext_t *pCmdCtx);
typedef int (*get_fn_t)(cmdContext_t *pCmdCtx);
typedef struct command {
const char *code;
set_fn_t set_dispatcher;
get_fn_t get_dispatcher;
const char *_description;
} command_t;
You should try changing your struct command so the function pointers have the actual type:
typedef struct command {
const char *code;
set_fn_t set_dispatcher;
get_fn_t get_dispatcher;
const char *_description;
} command_t;
Unfortunately, function pointers are not guaranteed to be able to convert to/from void pointers (that applies only to pointers to objects).
What's the embedded environment?
Given the information posted in the updates to the question, I see that it's really a bugged compiler.
I think that your proposed solution seems pretty reasonable - it's probably similar to what I would have come up with.
A function pointer isn't actually required to fit in a void*. You could check to make sure that the value you're calling is actually the address of the function. If not, use a function pointer type in the struct: either get_fn_t, or IIRC void(*)(void) is guaranteed to be compatible with any function pointer type.
Edit: OK, assuming that calling by value can't be made to work, I can't think of a neater way to do what you need than auto-generating the switch statement. You could maybe use an off-the-shelf ASP-style preprocessor mode for ruby/python/perl/php/whatever prior to the C preprocessor. Something like this:
switch(dispatcher_id) {
<% for c in commands %>
case SET_<% c.dispatcher %>: return set_<% c.dispatcher %>(pc);
case GET_<% c.dispatcher %>: return get_<% c.dispatcher %>(pc);
<% end %>
default:
return NOT_FOUND;
}
might be a bit more readable than the macro/include trick, but introducing a new tool and setting up the makefiles is probably not worth it for such a small amount of code. And the line numbers in the debug info won't relate to the file you think of as the source file unless you do extra work in your preprocessor to specify them.
Can you get the vendor to fix the compiler?
To what extent is the pointer-to-function broken?
If the compiler allows you to get the address of a function (I'm from C++, but &getenv is what I mean), you could wrap the calling convention stuff into assembler.
As said, I'm a C++ssie, but something in the way of
; function call
push [arg1]
push [arg2]
call [command+8] ; at the 4th location, the setter is stored
ret
If even that is broken, you could define an array of extern void* pointers which you define, again, in assembly.
try this syntax:
return (*((get_fn_t)commands[i].get_dispatcher))(pc);
It's been awhile since I've done C & function pointers, but I believe the original C syntax required the * when dereferencing function pointers but most compilers would let you get away without it.
Do you have access to the link map?
If so, maybe you can hack your way around the wonky function-pointer table:
unsigned long addr_get_dhcp = 0x1111111;
unsigned long addr_set_dhcp = 0x2222222; //make these unique numbers.
/* Relevant parts of header file */
typedef struct command {
const char *code;
unsigned long set_dispatcher;
unsigned long get_dispatcher;
const char *_description;
} command_t;
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label,
addr_set_##dispatcher, addr_get_##dispatcher, (const char*)description}
Now compile, grab the relevant addresses from the link map, replace the constants, and recompile. Nothing should move, so the map ought to stay the same. (Making the original constants unique should prevent the compiler from collapsing identical values into one storage location. You may need a long long, depending on the architecture)
If the concept works, you could probably add a post-link step running a script to do the replacement automagically. Of course, this is just a theory, it may fail miserably.
Maybe, you need to look into the structure again:
typedef struct command {
const char *code;
void *set_dispatcher; //IMO, it does not look like a function pointer...
void *get_dispatcher; //more like a pointer to void
const char *_description;
} command_t;
Let say your dispatchers have the following similar function definition:
//a function pointer type definition
typedef int (*genericDispatcher)(int data);
Assume that the dispatchers are like below:
int set_DhcpDispatcher(int data) { return data; }
int get_DhcpDispatcher(int data) { return 2*data; }
So, the revised structure will be:
typedef struct command {
const char *code;
genericDispatcher set_dispatcher;
genericDispatcher get_dispatcher;
const char *_description;
} command_t;
Your macro will be:
#define COMMAND_ENTRY(label,dispatcher,description) \
{ (const char*)label, \
set_##dispatcher##Dispatcher, \
get_##dispatcher##Dispatcher, \
(const char*)description }
Then, you can set your array as usual:
int main(int argc, char **argv)
{
int value1 = 0, value2 = 0;
const command_t commands[] = {
COMMAND_ENTRY("DH", Dhcp, "DHCP (0=off, 1=on)")
};
value1 = commands[0].set_dispatcher(1);
value2 = commands[0].get_dispatcher(2);
printf("value1 = %d, value2 = %d", value1, value2);
return 0;
}
Correct me, if I am wrong somewhere... ;)

Resources