SIGINT getting generated in a program using libev - macos

Hi I am dealing with a problem on Mac OS 13.1, while using libev, opening a DLL (libcrypto.3.dylib) and then doing popen to run a shell command and read the ouptut to a string.
The scenario in the program is illustrated in the sample as follows.
The main thread in the process creates a child thread and waits for SIGINT to terminate the program.
The child thread starts an event loop using libev, one of the event handlers is a timer, which does dlopen of libcrypto.3.dylib and then calls popen to run the command "uname -o 2>/dev/null".
At this stage signal SIGINT, gets generated, this terminates the wait on the main thread and the whole program gets terminated after that.
If the dlopen and popen are done without libev in a child thread. It works fine. In fact, even if the loop is initialized and not actually run, the signal gets generated and delivered.
Not able to understand the cause of SIGINT. If I try with another library (a very trivial one), it seems to work properly.
The code for the simualation is given below.
ev.cpp The main program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <dlfcn.h>
extern "C" {
#include "ev.h"
}
pthread_cond_t cond;
pthread_mutex_t mutex;
int run_func()
{
//void * dll = dlopen("/Volumes/NEW_DISK/user/sudheerp/usr/local/lib/libevlcrypto.so", RTLD_GLOBAL | RTLD_NOW);
//printf("[%s:%d]: dll = [%p]\n", __FILE__, __LINE__, dll);
//void * sym = dlsym(dll, "open_libevlcrypto");
//printf("[%s:%d]: sym = [%p]\n", __FILE__, __LINE__, sym);
//void * dll = dlopen("/Volumes/NEW_DISK/user/sudheerp/temp/io.open/clib.so", RTLD_GLOBAL | RTLD_NOW);
//printf("[%s:%d]: dll = [%p]\n", __FILE__, __LINE__, dll);
//void * sym = dlsym(dll, "open_libevlcrypto");
//printf("[%s:%d]: sym = [%p]\n", __FILE__, __LINE__, sym);
//void * dll = dlopen("/Volumes/NEW_DISK/user/sudheerp/temp/io.open/lib.so", RTLD_GLOBAL | RTLD_NOW);
//printf("[%s:%d]: dll = [%p]\n", __FILE__, __LINE__, dll);
//void * sym = dlsym(dll, "open_libevlcrypto");
//printf("[%s:%d]: sym = [%p]\n", __FILE__, __LINE__, sym);
void * dll = dlopen("/opt/local/libexec/openssl3/lib/libcrypto.3.dylib", RTLD_GLOBAL | RTLD_NOW);
printf("[%s:%d]: dll = [%p]\n", __FILE__, __LINE__, dll);
{
FILE * fp = popen("uname -o 2>/dev/null","r");
char out_s[256];
fgets(out_s, 255, fp);
for(int i = 0; i<strlen(out_s); i++) {
if (out_s[i] == '\n' || out_s[i] == '\r') {
out_s[i] = 0;
break;
}
}
printf("%s\n", out_s);
pclose(fp);
}
printf("[%s:%d] first uname complete\n", __FILE__, __LINE__);
{
FILE * fp = popen("uname -o 2>/dev/null","r");
char out_s[256];
fgets(out_s, 255, fp);
for(int i = 0; i<strlen(out_s); i++) {
if (out_s[i] == '\n' || out_s[i] == '\r') {
out_s[i] = 0;
break;
}
}
printf("%s\n", out_s);
pclose(fp);
}
printf("[%s:%d] second uname complete\n", __FILE__, __LINE__);
return 0;
}
ev_io stdin_watcher;
ev_timer timeout_watcher;
static void stdin_cb (EV_P_ ev_io *w, int revents)
{
puts ("stdin ready");
ev_io_stop (EV_A_ w);
ev_break (EV_A_ EVBREAK_ALL);
}
static void timeout_cb (EV_P_ ev_timer *w, int revents)
{
puts ("timeout");
run_func();
}
struct ev_loop *loop = EV_DEFAULT;
void* thread_main (void*p)
{
ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
ev_io_start (loop, &stdin_watcher);
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 2);
ev_timer_start (loop, &timeout_watcher);
ev_run (loop, 0);
return (void*)0;
}
void stop_the_loop()
{
ev_io_stop(loop, &stdin_watcher);
ev_timer_stop(loop, &timeout_watcher);
}
int main()
{
pthread_t t;
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_create(&t, NULL, thread_main, (void*)0);
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGINT);
sigaddset(&sset, SIGQUIT);
sigaddset(&sset, SIGTERM);
sigprocmask(SIG_BLOCK, &sset, NULL);
int sig;
sigwait(&sset, &sig);
printf("[%s:%d]:Got signal [%d]\n", __FILE__, __LINE__, sig);
stop_the_loop();
pthread_join(t,NULL);
return 0;
}
Makefile
all: signals ev sev lib.o lib.so clib.so
signals: signals.cpp
clang++ -Wno-c++17-compat-mangling -I/Volumes/NEW_DISK/user/sudheerp/usr/local/include/evpoco signals.cpp -L. -lev -o signals
ev: ev.o
clang -o ev ev.o -L. -lev -L/Volumes/NEW_DISK/user/sudheerp/usr/local/lib -llua
sev: sev.o
clang -o sev sev.o -L. -lev -L/Volumes/NEW_DISK/user/sudheerp/usr/local/lib -llua
clib.o: clib.c
clang -c -arch x86_64 -arch arm64 -Wno-c++17-compat-mangling -I/opt/local/libexec/openssl3/include clib.c -o clib.o
clib.so: clib.o
clang -O2 -g -arch x86_64 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk -bundle -bind_at_load -o clib.so clib.o /opt/local/libexec/openssl3/lib/libcrypto.dylib
lib.o: lib.c
clang -c -Wno-c++17-compat-mangling -arch x86_64 -arch arm64 lib.c -o lib.o
lib.so: lib.o
clang -O2 -g -arch x86_64 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk -bundle -bind_at_load -o lib.so lib.o
run.o: run.c
clang -c -Wno-c++17-compat-mangling -I../libev-4.33 run.c -o run.o
ev.o: ev.cpp
clang++ -c -Wno-c++17-compat-mangling -I../libev-4.33 -I/Volumes/NEW_DISK/user/sudheerp/usr/local/include/evpoco ev.cpp -o ev.o
sev.o: sev.cpp
clang++ -c -Wno-c++17-compat-mangling -I../libev-4.33 -I${HOME}/platform/lua-5.3.5/src -I/Volumes/NEW_DISK/user/sudheerp/usr/local/include/evpoco sev.cpp -o sev.o
clean:
rm -rf ev.o signals.o ev signals run.o sev.o sev lib.o lib.so clib.o clib.so
lib.c the source code for dummy lib.so
#include <string.h>
#include <stddef.h>
#include <assert.h>
#include <arpa/inet.h>
static int hmac_fdigest(void *L)
{
return 0;
}
static int generate_hash(void *L, const char * algo)
{
return 0;
}
static int generate_hash_from_string_sha1(void *L)
{
return generate_hash(L, "SHA1");
}
static int generate_hash_from_string_sha256(void *L)
{
return generate_hash(L, "SHA256");
}
static int generate_hash_from_string_sha384(void *L)
{
return generate_hash(L, "SHA384");
}
static int generate_hash_from_string_sha512(void *L)
{
return generate_hash(L, "SHA512");
}
typedef struct {
char * name;
void * ptr;
} Reg;
static const Reg _lib[] = {
{ NULL, NULL }
};
struct cipher_text_s {
unsigned char * buffer;
size_t len;
};
const static char *_cipher_text_name = "cipher_text";
static int cipher_text__gc(void *L)
{
return 0;
}
static int cipher_text__tostring(void *L)
{
return 1;
}
const static char *_cipher_key_name = "cipher_key";
static int cipher_key__gc(void *L)
{
return 0;
}
static int cipher_key__tostring(void *L)
{
return 1;
}
static int generate_symmetric_key(void *L)
{
return 1;
}
static int generate_aes_key(void *L)
{
return 1;
}
const static char *_rsa_key_name = "rsa_key";
static int rsa_key__gc(void *L)
{
return 0;
}
static int rsa_key__tostring(void *L)
{
return 1;
}
static int get_rsa_public_key(void *L)
{
return 1;
}
static int load_rsa_public_key(void *L)
{
return 1;
}
static int get_rsa_private_key(void *L)
{
return 1;
}
static int load_rsa_private_key(void *L)
{
return 1;
}
static int generate_rsa_key_pair(void *L)
{
return 1;
}
static void * deserialize_symmetric_key(void *L, unsigned char * data)
{
return NULL;;
}
struct serialized_cipher_key_s {
unsigned char * buffer;
size_t buffer_size;
};
static void serialize_symmetric_key(void *L, void * key, struct serialized_cipher_key_s * s_cipher_key_p)
{
return ;
}
static int rsa_encrypt_symm_key(void *L)
{
return 3;
}
static int rsa_decrypt_udata_enc_symm_key(void *L)
{
return 1;
}
static int rsa_decrypt_enc_symm_key(void *L)
{
return 1;
}
static int rsa_decrypt_b64_enc_symm_key(void *L)
{
return 1;
}
static int encrypt_text(void *L)
{
return 3;
}
static int decrypt_cipher_text(void *L)
{
return 1;
}
static int decrypt_b64_cipher_text(void *L)
{
return 1;
}
static int decrypt_udata_cipher_text(void *L)
{
return 1;
}
int open_libevlcrypto(void *L)
{
static const Reg crypto_methods[] = {
{"s_sha1_hash", generate_hash_from_string_sha1}
,{"s_sha256_hash", generate_hash_from_string_sha256}
,{"s_sha384_hash", generate_hash_from_string_sha384}
,{"s_sha512_hash", generate_hash_from_string_sha512}
,{"hmac_digest", hmac_fdigest}
,{"generate_symmetric_key", generate_symmetric_key}
,{"generate_aes_key", generate_aes_key}
,{"generate_rsa_key_pair", generate_rsa_key_pair}
,{"get_rsa_public_key", get_rsa_public_key}
,{"get_rsa_private_key", get_rsa_private_key}
,{"load_rsa_public_key", load_rsa_public_key}
,{"load_rsa_private_key", load_rsa_private_key}
,{"rsa_encrypt_symm_key", rsa_encrypt_symm_key}
,{"rsa_decrypt_enc_symm_key", rsa_decrypt_enc_symm_key}
,{"rsa_decrypt_udata_enc_symm_key", rsa_decrypt_udata_enc_symm_key}
,{"rsa_decrypt_b64_enc_symm_key", rsa_decrypt_b64_enc_symm_key}
,{"encrypt_text", encrypt_text}
,{"decrypt_cipher_text", decrypt_cipher_text}
,{"decrypt_udata_cipher_text", decrypt_udata_cipher_text}
,{"decrypt_b64_cipher_text", decrypt_b64_cipher_text}
,{NULL, NULL}
};
return 1;
}
#include <string.h>
#include <stddef.h>
#include <assert.h>
#include <arpa/inet.h>
static int hmac_fdigest(void *L)
{
return 0;
}
static int generate_hash(void *L, const char * algo)
{
return 0;
}
static int generate_hash_from_string_sha1(void *L)
{
return generate_hash(L, "SHA1");
}
static int generate_hash_from_string_sha256(void *L)
{
return generate_hash(L, "SHA256");
}
static int generate_hash_from_string_sha384(void *L)
{
return generate_hash(L, "SHA384");
}
static int generate_hash_from_string_sha512(void *L)
{
return generate_hash(L, "SHA512");
}
typedef struct {
char * name;
void * ptr;
} Reg;
static const Reg _lib[] = {
{ NULL, NULL }
};
struct cipher_text_s {
unsigned char * buffer;
size_t len;
};
const static char *_cipher_text_name = "cipher_text";
static int cipher_text__gc(void *L)
{
return 0;
}
static int cipher_text__tostring(void *L)
{
return 1;
}
const static char *_cipher_key_name = "cipher_key";
static int cipher_key__gc(void *L)
{
return 0;
}
static int cipher_key__tostring(void *L)
{
return 1;
}
static int generate_symmetric_key(void *L)
{
return 1;
}
static int generate_aes_key(void *L)
{
return 1;
}
const static char *_rsa_key_name = "rsa_key";
static int rsa_key__gc(void *L)
{
return 0;
}
static int rsa_key__tostring(void *L)
{
return 1;
}
static int get_rsa_public_key(void *L)
{
return 1;
}
static int load_rsa_public_key(void *L)
{
return 1;
}
static int get_rsa_private_key(void *L)
{
return 1;
}
static int load_rsa_private_key(void *L)
{
return 1;
}
static int generate_rsa_key_pair(void *L)
{
return 1;
}
static void * deserialize_symmetric_key(void *L, unsigned char * data)
{
return NULL;;
}
struct serialized_cipher_key_s {
unsigned char * buffer;
size_t buffer_size;
};
static void serialize_symmetric_key(void *L, void * key, struct serialized_cipher_key_s * s_cipher_key_p)
{
return ;
}
static int rsa_encrypt_symm_key(void *L)
{
return 3;
}
static int rsa_decrypt_udata_enc_symm_key(void *L)
{
return 1;
}
static int rsa_decrypt_enc_symm_key(void *L)
{
return 1;
}
static int rsa_decrypt_b64_enc_symm_key(void *L)
{
return 1;
}
static int encrypt_text(void *L)
{
return 3;
}
static int decrypt_cipher_text(void *L)
{
return 1;
}
static int decrypt_b64_cipher_text(void *L)
{
return 1;
}
static int decrypt_udata_cipher_text(void *L)
{
return 1;
}
int open_libevlcrypto(void *L)
{
static const Reg crypto_methods[] = {
{"s_sha1_hash", generate_hash_from_string_sha1}
,{"s_sha256_hash", generate_hash_from_string_sha256}
,{"s_sha384_hash", generate_hash_from_string_sha384}
,{"s_sha512_hash", generate_hash_from_string_sha512}
,{"hmac_digest", hmac_fdigest}
,{"generate_symmetric_key", generate_symmetric_key}
,{"generate_aes_key", generate_aes_key}
,{"generate_rsa_key_pair", generate_rsa_key_pair}
,{"get_rsa_public_key", get_rsa_public_key}
,{"get_rsa_private_key", get_rsa_private_key}
,{"load_rsa_public_key", load_rsa_public_key}
,{"load_rsa_private_key", load_rsa_private_key}
,{"rsa_encrypt_symm_key", rsa_encrypt_symm_key}
,{"rsa_decrypt_enc_symm_key", rsa_decrypt_enc_symm_key}
,{"rsa_decrypt_udata_enc_symm_key", rsa_decrypt_udata_enc_symm_key}
,{"rsa_decrypt_b64_enc_symm_key", rsa_decrypt_b64_enc_symm_key}
,{"encrypt_text", encrypt_text}
,{"decrypt_cipher_text", decrypt_cipher_text}
,{"decrypt_udata_cipher_text", decrypt_udata_cipher_text}
,{"decrypt_b64_cipher_text", decrypt_b64_cipher_text}
,{NULL, NULL}
};
return 1;
}

This is happening because the default loop of libev installs a handle for SIGCHLD.
struct ev_loop *loop = EV_DEFAULT;
With this whenever a child process terminates the handler gets triggered. (This happens each time io.popen completes)
Further, the signal can get delivered in any of the threads of the multi-threaded program "ev"
Sometimes the signal gets delivered in the main thread, which is waiting for SIGINT to arrive in order to terminate the whole program. When this happens the waiting process is interrupted (or SIGINT is delivered) and thus the program is terminated, even though there is no other source of interruption.

Related

rmmod for my platform driver causes kernel panic?

I have written a simple GPIO sysfs driver. However, my driver is crashing when I call rmmod. I don't know what I am missing. I am suspecting that my probe() function is causing this issue. I am using kernel 4.19 version. Here is my long code:
struct of_device_id gpio_sysfs_dt_match[] = {
{ .compatible = "org,bone-gpio-sysfs" },
{ } // NULL terminated
};
ssize_t direction_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return 0;
}
ssize_t direction_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
return 0;
}
ssize_t value_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return 0;
}
ssize_t value_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
return 0;
}
ssize_t label_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return 0;
}
static DEVICE_ATTR_RW(direction);
static DEVICE_ATTR_RW(value);
static DEVICE_ATTR_RO(label);
static struct attribute *gpio_attrs[] = {
&dev_attr_direction.attr,
&dev_attr_value.attr,
&dev_attr_label.attr,
NULL
};
static struct attribute_group gpio_group = {
.attrs = gpio_attrs,
};
const struct attribute_group *gpio_attr_groups[] =
{
&gpio_group,
NULL
};
int gpio_sysfs_platform_driver_probe (struct platform_device *pDev)
{
struct device_node *parent = pDev->dev.of_node;
struct device_node *child;
struct gpiodev_private_data *dev_data;
struct device dev = pDev->dev;
const char *name;
int i = 0;
int ret;
gpiodrv_data.total_devices = of_get_child_count(parent);
if (!gpiodrv_data.total_devices) {
dev_err(&dev, "Error - No devices found\r\n");
return -EINVAL;
}
dev_info(&dev, "child count = %d\r\n", gpiodrv_data.total_devices);
gpiodrv_data.dev_sysfs = devm_kzalloc(&pDev->dev, sizeof(struct device *) * gpiodrv_data.total_devices, GFP_KERNEL);
for_each_available_child_of_node(parent, child) {
dev_data = devm_kzalloc(&dev, sizeof(struct gpiodev_private_data),GFP_KERNEL);
if (!dev_data) {
pr_err("No memory \r\n");
return -ENOMEM;
}
if (of_property_read_string(child, "label", &name)) {
pr_err("Missing label \r\n");
snprintf(dev_data->label,sizeof(dev_data->label), "unknown-gpio-%d",i);
} else {
strcpy(dev_data->label, name);
dev_info(&dev,"GPIO label = %s\n",dev_data->label);
}
dev_data->desc = devm_fwnode_get_gpiod_from_child(&dev,"bone",&child->fwnode, GPIOD_ASIS, dev_data->label);
if (IS_ERR(dev_data->desc)) {
ret = PTR_ERR(dev_data->desc);
if(ret == -ENONET) {
dev_err(&dev, "get gpiod failed - no entry found\r\n");
}
return ret;
}
/** gpio/gpio.txt **/
ret = gpiod_direction_output(dev_data->desc, 0);
if(ret) {
dev_err(&dev,"Err setting gpio direction failed = %d\r\n",i);
return ret;
}
gpiodrv_data.dev_sysfs[i] = device_create_with_groups(gpiodrv_data.class_gpio, &dev, 0, dev_data, gpio_attr_groups, dev_data->label);
if(IS_ERR(gpiodrv_data.dev_sysfs[i])) {
ret = PTR_ERR(gpiodrv_data.dev_sysfs[i]);
dev_err(&dev, "Error creating device with groups \r\n");
return ret;
}
i++;
}
return 0;
}
int gpio_sysfs_driver_remove(struct platform_device *pDev)
{
int i = 0;
dev_info(&pDev->dev, "Removing gpio syfs driver\r\n");
for (i = 0; i < gpiodrv_data.total_devices; i++) {
device_unregister(gpiodrv_data.dev_sysfs[i]);
}
return 0;
}
struct platform_driver gpiosysfs_platform_driver = {
.probe = gpio_sysfs_platform_driver_probe,
.remove = gpio_sysfs_driver_remove,
.driver = {
.name = "bone-gpio-sysfs",
. of_match_table = of_match_ptr(gpio_sysfs_dt_match),
},
};
/**Entry Point of the Kernel Module **/
/** Called when the module is inserted -insmod **/
static int __init gpio_sysfs_init(void)
{
int ret;
gpiodrv_data.class_gpio = class_create(THIS_MODULE, "bone_gpios");
ret = platform_driver_register(&gpiosysfs_platform_driver);
return ret;
}
/** Called when the module is removed - rmmod**/
static void __exit gpio_sysfs_exit(void)
{
platform_driver_unregister(&gpiosysfs_platform_driver);
class_destroy(gpiodrv_data.class_gpio);
pr_info("module unloaded\n");
}
The problem is seen when I call rmmod of my driver. When I do this, I see a kernel crash - pointing to the platform driver unregister. What am I doing wrong here? If I comment out probe then I don't see this problem. Perhaps, some problem is introduced inside probe. As you can see I am using managed resource API so I guess, I don't have to call kfree() since I am using dev_kzalloc().

BUG: Unable to handle kernel paging request at error for the sample kernel module

I am writing a sample kernel module which reads data sent through ioctl call from application and prints them.
I am passing structure "ioctl_struct" through ioctl from the application and in the kernel module, I will be printing its member variables.
this works absolutely fine in a few machines. In a few machines
"BUG: unable to handle kernel paging request at"
the error is thrown while accessing "name and testStruct's id1 and id2".
I don't think this module is hardware/kernel dependent.
I am not sure where it's going wrong. any help would be appreciated.
thanks.
Driver.c kernel module
static const char DEVICE_NAME[]="testipc";
static struct proc_dir_entry * proc_ipc = NULL;
struct test
{
int id1;
int id2;
};
struct ioctl_struct
{
__user struct test *testStruct;
__user int * id;
__user char * name;
int cmd;
};
static int __init etx_driver_init(void);
static void __exit etx_driver_exit(void);
static long etx_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static struct file_operations fops =
{
.owner = THIS_MODULE,
.read = etx_read,
.write = etx_write,
.open = etx_open,
.unlocked_ioctl = etx_ioctl,
.release = etx_release,
.unlocked_ioctl = etx_ioctl,
};
static long etx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
printk("reached ioctl....\n");
struct ioctl_struct buf;
if (copy_from_user(&buf, (void *)arg, sizeof(buf)))
return -EFAULT;
printk("succes..2\n");
printk("id %d\n",buf.id);
printk("cmd %d\n",buf.cmd);
printk("filename %s\n",buf.name);
printk("token %d\n",buf.testStruct->id1);
printk("token %d\n",buf.testStruct->id2);
return 0;
}
static int __init etx_driver_init(void)
{
printk("new test driver loaded..");
proc_ipc = proc_create(DEVICE_NAME, 0, NULL, &fops);
if (!proc_ipc)
{
printk(KERN_ALERT "Unable to create /proc/%s\n", DEVICE_NAME);
return 1;
}
return 0;
}
void __exit etx_driver_exit(void)
{
if (proc_ipc)
proc_remove(proc_ipc);
proc_ipc = NULL;
}
module_init(etx_driver_init);
module_exit(etx_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lin");
MODULE_DESCRIPTION("A simple driver");
MODULE_VERSION("1.0");
and following is my application file
#include <stdio.h>
#include<sys/ioctl.h>
# define __user
static int fd=NULL;
#define TEST_IOCTL _IOWR('z', 80, struct ioctl_struct)
struct test
{
int id1;
int id2;
};
struct ioctl_struct
{
__user struct test *testStruct;
__user int * id;
__user char * name;
int cmd;
};
void init()
{
printf("\nOpening Driver\n");
fd = open("/proc/testipc", O_RDWR);
if(fd < 0) {
printf("Cannot open device file...\n");
return 0;
}
}
void send()
{
int id=5;
int *pid=id;
char name[10]={'H','e','l','l','o'};
struct test testStruct;
testStruct.id1=44;
testStruct.id2=33;
struct ioctl_struct request;
request.name = name ;
request.id = pid;
request.cmd = 33;
request.testStruct = &testStruct;
ioctl(fd, TEST_IOCTL, &request);
}
void finish()
{
printf("Closing Driver\n");
close(fd);
}
int main()
{
init();
send();
finish();
return 0;
}
In dmesg,
id 5,
cmd 33,
Hello,
44,
33,
should be printed

I'm trying to implement GPS data into the waveshortmessage, but i'm having problems implementing omnet2traci function

I'm using omnet5, veins 4.4, and sumo 0.25. I've looked at Converting Veins Coordinates to GPS which didn't help much since i have the updated version.
This one https://stackoverflow.com/questions/40650825/connection-to-traci-server-lost-check-your-servers-log-error-message-88-soc seems like it might work with a little error checking, but I'm not sure what the user did to make it work.
I've seen that you can use omnet2traci to convert the regular coordinates to the sumo ones, but I'm having trouble implementing it properly. When I tried calling it in message with:
class Veins::TraCIConnection::omnet2traci;
then using:
Veins::TraCICoord gpspos = omnet2traci(senderPos);
but I'm getting undeclared identifier error. I tried changing to .cc and .h code to compensate for it by creating a small copy of the omnet2traci coding from TraCIConnection. After all that it gives me errors:
omnetpp-5.0/include/omnetpp/cdynamicexpression.h:50:9: error: expected identifier
ADD, SUB, MUL, DIV, MOD, POW, NEG,
^
.\veins/modules/mobility/traci/TraCIConstants.h:707:13: note: expanded from macro 'ADD'
#define ADD 0x80
^
omnetpp-5.0/include/omnetpp/coutvector.h:66:27: error: expected identifier
enum Type { TYPE_INT, TYPE_DOUBLE, TYPE_ENUM };
^
.\veins/modules/mobility/traci/TraCIConstants.h:304:21: note: expanded from macro 'TYPE_DOUBLE'
#define TYPE_DOUBLE 0x0B
^
At this point it seems like it working around the problem and hoping it works instead of actually solving the problem. Full code below, added in parts are starred. *note I had to snip the end parts of the .cc code because it went over the text limit, but nothing was changed.
Waveshortmessage.msg
//Waveshortmessage.msg
cplusplus {{
**#include <stdint.h>
#include "veins/modules/mobility/traci/TraCIBuffer.h"
#include "veins/modules/mobility/traci/TraCICommandInterface.h"
#include "veins/modules/mobility/traci/TraCIConnection.h"
#include "veins/modules/mobility/traci/TraCIConstants.h"
#include "veins/modules/mobility/traci/TraCICoord.h"**
#include "veins/base/utils/Coord.h"
}}
class noncobject Coord;
**class noncobject Veins::TraCICoord;
class Veins::TraCIConnection::omnet2traci;**
packet WaveShortMessage {
//Version of the Wave Short Message
int wsmVersion = 0;
//Determine which security mechanism was used
int securityType = 0;
//Channel Number on which this packet was sent
int channelNumber;
//Data rate with which this packet was sent
int dataRate = 1;
//Power Level with which this packet was sent
int priority = 3;
//Unique number to identify the service
int psid = 0;
//Provider Service Context
string psc = "Service with some Data";
//Length of Wave Short Message
int wsmLength;
//Data of Wave Short Message
string wsmData = "Some Data";
int senderAddress = 0;
int recipientAddress = -1;
int serial = 0;
Coord senderPos;
**Veins::TraCICoord gpspos = omnet2traci(senderPos);**
simtime_t timestamp = 0;
}
Waveshortmessage.cc
//waveshortmessage.cc
// Generated file, do not edit! Created by nedtool 5.0 from veins/modules/messages/WaveShortMessage.msg.
//
**#define WANT_WINSOCK2
#include <platdep/sockets.h>
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) || defined(_WIN64)
#include <ws2tcpip.h>
#else
#include <netinet/tcp.h>
#include <netdb.h>
#include <arpa/inet.h>
#endif
#include <algorithm>
#include <functional>
//#include "veins/modules/mobility/traci/TraCIConnection.h"
#include "veins/modules/mobility/traci/TraCIConstants.h"
#define MYDEBUG EV**
// Disable warnings about unused variables, empty switch stmts, etc:
#ifdef _MSC_VER
# pragma warning(disable:4101)
# pragma warning(disable:4065)
#endif
#include <iostream>
#include <sstream>
#include "WaveShortMessage_m.h"
namespace omnetpp {
// Template pack/unpack rules. They are declared *after* a1l type-specific pack functions for multiple reasons.
// They are in the omnetpp namespace, to allow them to be found by argument-dependent lookup via the cCommBuffer argument
// Packing/unpacking an std::vector
template<typename T, typename A>
void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::vector<T,A>& v)
{
int n = v.size();
doParsimPacking(buffer, n);
for (int i = 0; i < n; i++)
doParsimPacking(buffer, v[i]);
}
template<typename T, typename A>
void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::vector<T,A>& v)
{
int n;
doParsimUnpacking(buffer, n);
v.resize(n);
for (int i = 0; i < n; i++)
doParsimUnpacking(buffer, v[i]);
}
// Packing/unpacking an std::list
template<typename T, typename A>
void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::list<T,A>& l)
{
doParsimPacking(buffer, (int)l.size());
for (typename std::list<T,A>::const_iterator it = l.begin(); it != l.end(); ++it)
doParsimPacking(buffer, (T&)*it);
}
template<typename T, typename A>
void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::list<T,A>& l)
{
int n;
doParsimUnpacking(buffer, n);
for (int i=0; i<n; i++) {
l.push_back(T());
doParsimUnpacking(buffer, l.back());
}
}
// Packing/unpacking an std::set
template<typename T, typename Tr, typename A>
void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::set<T,Tr,A>& s)
{
doParsimPacking(buffer, (int)s.size());
for (typename std::set<T,Tr,A>::const_iterator it = s.begin(); it != s.end(); ++it)
doParsimPacking(buffer, *it);
}
template<typename T, typename Tr, typename A>
void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::set<T,Tr,A>& s)
{
int n;
doParsimUnpacking(buffer, n);
for (int i=0; i<n; i++) {
T x;
doParsimUnpacking(buffer, x);
s.insert(x);
}
}
// Packing/unpacking an std::map
template<typename K, typename V, typename Tr, typename A>
void doParsimPacking(omnetpp::cCommBuffer *buffer, const std::map<K,V,Tr,A>& m)
{
doParsimPacking(buffer, (int)m.size());
for (typename std::map<K,V,Tr,A>::const_iterator it = m.begin(); it != m.end(); ++it) {
doParsimPacking(buffer, it->first);
doParsimPacking(buffer, it->second);
}
}
template<typename K, typename V, typename Tr, typename A>
void doParsimUnpacking(omnetpp::cCommBuffer *buffer, std::map<K,V,Tr,A>& m)
{
int n;
doParsimUnpacking(buffer, n);
for (int i=0; i<n; i++) {
K k; V v;
doParsimUnpacking(buffer, k);
doParsimUnpacking(buffer, v);
m[k] = v;
}
}
// Default pack/unpack function for arrays
template<typename T>
void doParsimArrayPacking(omnetpp::cCommBuffer *b, const T *t, int n)
{
for (int i = 0; i < n; i++)
doParsimPacking(b, t[i]);
}
template<typename T>
void doParsimArrayUnpacking(omnetpp::cCommBuffer *b, T *t, int n)
{
for (int i = 0; i < n; i++)
doParsimUnpacking(b, t[i]);
}
// Default rule to prevent compiler from choosing base class' doParsimPacking() function
template<typename T>
void doParsimPacking(omnetpp::cCommBuffer *, const T& t)
{
throw omnetpp::cRuntimeError("Parsim error: no doParsimPacking() function for type %s", omnetpp::opp_typename(typeid(t)));
}
template<typename T>
void doParsimUnpacking(omnetpp::cCommBuffer *, T& t)
{
throw omnetpp::cRuntimeError("Parsim error: no doParsimUnpacking() function for type %s", omnetpp::opp_typename(typeid(t)));
}
} // namespace omnetpp
// forward
template<typename T, typename A>
std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec);
// Template rule which fires if a struct or class doesn't have operator<<
template<typename T>
inline std::ostream& operator<<(std::ostream& out,const T&) {return out;}
// operator<< for std::vector<T>
template<typename T, typename A>
inline std::ostream& operator<<(std::ostream& out, const std::vector<T,A>& vec)
{
out.put('{');
for(typename std::vector<T,A>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
if (it != vec.begin()) {
out.put(','); out.put(' ');
}
out << *it;
}
out.put('}');
char buf[32];
sprintf(buf, " (size=%u)", (unsigned int)vec.size());
out.write(buf, strlen(buf));
return out;
}
**Veins::TraCICoord Veins::TraCIConnection::omnet2traci(Coord coord) const {
return TraCICoord(coord.x + netbounds1.x - margin, (netbounds2.y - netbounds1.y) - (coord.y - netbounds1.y) + margin);
}
std::list<Veins::TraCICoord> Veins::TraCIConnection::omnet2traci(const std::list<Coord>& list) const {
std::list<TraCICoord> result;
std::transform(list.begin(), list.end(), std::back_inserter(result), std::bind1st(std::mem_fun<TraCICoord, TraCIConnection, Coord>(&TraCIConnection::omnet2traci), this));
return result;
}**
Register_Class(WaveShortMessage);
WaveShortMessage::WaveShortMessage(const char *name, int kind) : ::omnetpp::cPacket(name,kind)
{
this->wsmVersion = 0;
this->securityType = 0;
this->channelNumber = 0;
this->dataRate = 1;
this->priority = 3;
this->psid = 0;
this->psc = "Service with some Data";
this->wsmLength = 0;
this->wsmData = "Some Data";
this->senderAddress = 0;
this->recipientAddress = -1;
this->serial = 0;
this->gpspos = omnet2traci(senderPos);
this->timestamp = 0;
}
WaveShortMessage::WaveShortMessage(const WaveShortMessage& other) : ::omnetpp::cPacket(other)
{
copy(other);
}
WaveShortMessage::~WaveShortMessage()
{
}
WaveShortMessage& WaveShortMessage::operator=(const WaveShortMessage& other)
{
if (this==&other) return *this;
::omnetpp::cPacket::operator=(other);
copy(other);
return *this;
}
void WaveShortMessage::copy(const WaveShortMessage& other)
{
this->wsmVersion = other.wsmVersion;
this->securityType = other.securityType;
this->channelNumber = other.channelNumber;
this->dataRate = other.dataRate;
this->priority = other.priority;
this->psid = other.psid;
this->psc = other.psc;
this->wsmLength = other.wsmLength;
this->wsmData = other.wsmData;
this->senderAddress = other.senderAddress;
this->recipientAddress = other.recipientAddress;
this->serial = other.serial;
this->senderPos = other.senderPos;
this->gpspos = other.gpspos;
this->timestamp = other.timestamp;
}
void WaveShortMessage::parsimPack(omnetpp::cCommBuffer *b) const
{
::omnetpp::cPacket::parsimPack(b);
doParsimPacking(b,this->wsmVersion);
doParsimPacking(b,this->securityType);
doParsimPacking(b,this->channelNumber);
doParsimPacking(b,this->dataRate);
doParsimPacking(b,this->priority);
doParsimPacking(b,this->psid);
doParsimPacking(b,this->psc);
doParsimPacking(b,this->wsmLength);
doParsimPacking(b,this->wsmData);
doParsimPacking(b,this->senderAddress);
doParsimPacking(b,this->recipientAddress);
doParsimPacking(b,this->serial);
doParsimPacking(b,this->senderPos);
doParsimPacking(b,this->gpspos);
doParsimPacking(b,this->timestamp);
}
void WaveShortMessage::parsimUnpack(omnetpp::cCommBuffer *b)
{
::omnetpp::cPacket::parsimUnpack(b);
doParsimUnpacking(b,this->wsmVersion);
doParsimUnpacking(b,this->securityType);
doParsimUnpacking(b,this->channelNumber);
doParsimUnpacking(b,this->dataRate);
doParsimUnpacking(b,this->priority);
doParsimUnpacking(b,this->psid);
doParsimUnpacking(b,this->psc);
doParsimUnpacking(b,this->wsmLength);
doParsimUnpacking(b,this->wsmData);
doParsimUnpacking(b,this->senderAddress);
doParsimUnpacking(b,this->recipientAddress);
doParsimUnpacking(b,this->serial);
doParsimUnpacking(b,this->senderPos);
doParsimUnpacking(b,this->gpspos);
doParsimUnpacking(b,this->timestamp);
}
int WaveShortMessage::getWsmVersion() const
{
return this->wsmVersion;
}
void WaveShortMessage::setWsmVersion(int wsmVersion)
{
this->wsmVersion = wsmVersion;
}
int WaveShortMessage::getSecurityType() const
{
return this->securityType;
}
void WaveShortMessage::setSecurityType(int securityType)
{
this->securityType = securityType;
}
int WaveShortMessage::getChannelNumber() const
{
return this->channelNumber;
}
void WaveShortMessage::setChannelNumber(int channelNumber)
{
this->channelNumber = channelNumber;
}
int WaveShortMessage::getDataRate() const
{
return this->dataRate;
}
void WaveShortMessage::setDataRate(int dataRate)
{
this->dataRate = dataRate;
}
int WaveShortMessage::getPriority() const
{
return this->priority;
}
void WaveShortMessage::setPriority(int priority)
{
this->priority = priority;
}
int WaveShortMessage::getPsid() const
{
return this->psid;
}
void WaveShortMessage::setPsid(int psid)
{
this->psid = psid;
}
const char * WaveShortMessage::getPsc() const
{
return this->psc.c_str();
}
void WaveShortMessage::setPsc(const char * psc)
{
this->psc = psc;
}
int WaveShortMessage::getWsmLength() const
{
return this->wsmLength;
}
void WaveShortMessage::setWsmLength(int wsmLength)
{
this->wsmLength = wsmLength;
}
const char * WaveShortMessage::getWsmData() const
{
return this->wsmData.c_str();
}
void WaveShortMessage::setWsmData(const char * wsmData)
{
this->wsmData = wsmData;
}
int WaveShortMessage::getSenderAddress() const
{
return this->senderAddress;
}
void WaveShortMessage::setSenderAddress(int senderAddress)
{
this->senderAddress = senderAddress;
}
int WaveShortMessage::getRecipientAddress() const
{
return this->recipientAddress;
}
void WaveShortMessage::setRecipientAddress(int recipientAddress)
{
this->recipientAddress = recipientAddress;
}
int WaveShortMessage::getSerial() const
{
return this->serial;
}
void WaveShortMessage::setSerial(int serial)
{
this->serial = serial;
}
Coord& WaveShortMessage::getSenderPos()
{
return this->senderPos;
}
void WaveShortMessage::setSenderPos(const Coord& senderPos)
{
this->senderPos = senderPos;
}
Veins::TraCICoord& WaveShortMessage::getGpspos()
{
return this->gpspos;
}
void WaveShortMessage::setGpspos(const Veins::TraCICoord& gpspos)
{
this->gpspos = gpspos;
}
::omnetpp::simtime_t WaveShortMessage::getTimestamp() const
{
return this->timestamp;
}
void WaveShortMessage::setTimestamp(::omnetpp::simtime_t timestamp)
{
this->timestamp = timestamp;
}
class WaveShortMessageDescriptor : public omnetpp::cClassDescriptor
{
private:
mutable const char **propertynames;
public:
WaveShortMessageDescriptor();
virtual ~WaveShortMessageDescriptor();
virtual bool doesSupport(omnetpp::cObject *obj) const override;
virtual const char **getPropertyNames() const override;
virtual const char *getProperty(const char *propertyname) const override;
virtual int getFieldCount() const override;
virtual const char *getFieldName(int field) const override;
virtual int findField(const char *fieldName) const override;
virtual unsigned int getFieldTypeFlags(int field) const override;
virtual const char *getFieldTypeString(int field) const override;
virtual const char **getFieldPropertyNames(int field) const override;
virtual const char *getFieldProperty(int field, const char *propertyname) const override;
virtual int getFieldArraySize(void *object, int field) const override;
virtual std::string getFieldValueAsString(void *object, int field, int i) const override;
virtual bool setFieldValueAsString(void *object, int field, int i, const char *value) const override;
virtual const char *getFieldStructName(int field) const override;
virtual void *getFieldStructValuePointer(void *object, int field, int i) const override;
};
Register_ClassDescriptor(WaveShortMessageDescriptor);
WaveShortMessageDescriptor::WaveShortMessageDescriptor() : omnetpp::cClassDescriptor("WaveShortMessage", "omnetpp::cPacket")
{
propertynames = nullptr;
}
WaveShortMessageDescriptor::~WaveShortMessageDescriptor()
{
delete[] propertynames;
}
bool WaveShortMessageDescriptor::doesSupport(omnetpp::cObject *obj) const
{
return dynamic_cast<WaveShortMessage *>(obj)!=nullptr;
}
const char **WaveShortMessageDescriptor::getPropertyNames() const
{
if (!propertynames) {
static const char *names[] = { nullptr };
omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
const char **basenames = basedesc ? basedesc->getPropertyNames() : nullptr;
propertynames = mergeLists(basenames, names);
}
return propertynames;
}
const char *WaveShortMessageDescriptor::getProperty(const char *propertyname) const
{
omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
return basedesc ? basedesc->getProperty(propertyname) : nullptr;
}
int WaveShortMessageDescriptor::getFieldCount() const
{
omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
return basedesc ? 15+basedesc->getFieldCount() : 15;
}
unsigned int WaveShortMessageDescriptor::getFieldTypeFlags(int field) const
{
omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
if (basedesc) {
if (field < basedesc->getFieldCount())
return basedesc->getFieldTypeFlags(field);
field -= basedesc->getFieldCount();
}
static unsigned int fieldTypeFlags[] = {
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISEDITABLE,
FD_ISCOMPOUND,
FD_ISCOMPOUND,
FD_ISEDITABLE,
};
return (field>=0 && field<15) ? fieldTypeFlags[field] : 0;
}
const char *WaveShortMessageDescriptor::getFieldName(int field) const
{
omnetpp::cClassDescriptor *basedesc = getBaseClassDescriptor();
if (basedesc) {
if (field < basedesc->getFieldCount())
return basedesc->getFieldName(field);
field -= basedesc->getFieldCount();
}
static const char *fieldNames[] = {
"wsmVersion",
"securityType",
"channelNumber",
"dataRate",
"priority",
"psid",
"psc",
"wsmLength",
"wsmData",
"senderAddress",
"recipientAddress",
"serial",
"senderPos",
"gpspos",
"timestamp",
};
return (field>=0 && field<15) ? fieldNames[field] : nullptr;
}
Waveshortmessage.h
//Waveshortmessage.h
// Generated file, do not edit! Created by nedtool 5.0 from veins/modules/messages/WaveShortMessage.msg.
//
#ifndef __WAVESHORTMESSAGE_M_H
#define __WAVESHORTMESSAGE_M_H
#include <omnetpp.h>
// nedtool version check
#define MSGC_VERSION 0x0500
#if (MSGC_VERSION!=OMNETPP_VERSION)
# error Version mismatch! Probably this file was generated by an earlier version of nedtool: 'make clean' should help.
#endif
// cplusplus {{
** #include <stdint.h>
#include "veins/modules/mobility/traci/TraCIBuffer.h"
#include "veins/modules/mobility/traci/TraCICommandInterface.h"
#include "veins/modules/mobility/traci/TraCIConnection.h"
#include "veins/modules/mobility/traci/TraCIConstants.h"
#include "veins/modules/mobility/traci/TraCICoord.h" **
#include "veins/base/utils/Coord.h"
// }}
/**
* Class generated from <tt>veins/modules/messages/WaveShortMessage.msg:40</tt> by nedtool.
* <pre>
* packet WaveShortMessage
* {
* //Version of the Wave Short Message
* int wsmVersion = 0;
* //Determine which security mechanism was used
* int securityType = 0;
* //Channel Number on which this packet was sent
* int channelNumber;
* //Data rate with which this packet was sent
* int dataRate = 1;
* //Power Level with which this packet was sent
* int priority = 3;
* //Unique number to identify the service
* int psid = 0;
* //Provider Service Context
* string psc = "Service with some Data";
* //Length of Wave Short Message
* int wsmLength;
* //Data of Wave Short Message
* string wsmData = "Some Data";
*
* int senderAddress = 0;
* int recipientAddress = -1;
* int serial = 0;
* Coord senderPos;
*
* Veins::TraCICoord gpspos = omnet2traci(senderPos);
*
* simtime_t timestamp = 0;
*
* }
* </pre>
*/
class WaveShortMessage : public ::omnetpp::cPacket
{
protected:
int wsmVersion;
int securityType;
int channelNumber;
int dataRate;
int priority;
int psid;
::omnetpp::opp_string psc;
int wsmLength;
::omnetpp::opp_string wsmData;
int senderAddress;
int recipientAddress;
int serial;
Coord senderPos;
Veins::TraCICoord gpspos;
::omnetpp::simtime_t timestamp;
private:
void copy(const WaveShortMessage& other);
protected:
// protected and unimplemented operator==(), to prevent accidental usage
bool operator==(const WaveShortMessage&);
public:
WaveShortMessage(const char *name=nullptr, int kind=0);
WaveShortMessage(const WaveShortMessage& other);
virtual ~WaveShortMessage();
WaveShortMessage& operator=(const WaveShortMessage& other);
virtual WaveShortMessage *dup() const {return new WaveShortMessage(*this);}
virtual void parsimPack(omnetpp::cCommBuffer *b) const;
virtual void parsimUnpack(omnetpp::cCommBuffer *b);
// field getter/setter methods
virtual int getWsmVersion() const;
virtual void setWsmVersion(int wsmVersion);
virtual int getSecurityType() const;
virtual void setSecurityType(int securityType);
virtual int getChannelNumber() const;
virtual void setChannelNumber(int channelNumber);
virtual int getDataRate() const;
virtual void setDataRate(int dataRate);
virtual int getPriority() const;
virtual void setPriority(int priority);
virtual int getPsid() const;
virtual void setPsid(int psid);
virtual const char * getPsc() const;
virtual void setPsc(const char * psc);
virtual int getWsmLength() const;
virtual void setWsmLength(int wsmLength);
virtual const char * getWsmData() const;
virtual void setWsmData(const char * wsmData);
virtual int getSenderAddress() const;
virtual void setSenderAddress(int senderAddress);
virtual int getRecipientAddress() const;
virtual void setRecipientAddress(int recipientAddress);
virtual int getSerial() const;
virtual void setSerial(int serial);
virtual Coord& getSenderPos();
virtual const Coord& getSenderPos() const {return const_cast<WaveShortMessage*>(this)->getSenderPos();}
virtual void setSenderPos(const Coord& senderPos);
virtual Veins::TraCICoord& getGpspos();
virtual const Veins::TraCICoord& getGpspos() const {return const_cast<WaveShortMessage*>(this)->getGpspos();}
virtual void setGpspos(const Veins::TraCICoord& gpspos);
virtual ::omnetpp::simtime_t getTimestamp() const;
virtual void setTimestamp(::omnetpp::simtime_t timestamp);
**Coord traci2omnet(Veins::TraCICoord coord) const;
std::list<Coord> traci2omnet(const std::list<Veins::TraCICoord>&) const;
Veins::TraCICoord omnet2traci(Coord coord) const;
std::list<Veins::TraCICoord> omnet2traci(const std::list<Coord>&) const;**
};
inline void doParsimPacking(omnetpp::cCommBuffer *b, const WaveShortMessage& obj) {obj.parsimPack(b);}
inline void doParsimUnpacking(omnetpp::cCommBuffer *b, WaveShortMessage& obj) {obj.parsimUnpack(b);}
#endif // ifndef __WAVESHORTMESSAGE_M_H
Any help would be very appreciated. Thanks!
Currently I am working with localization in VANETs and I was facing the same problem.
As you can see in veins FAQ SUMO and OMNeT++ use different coordinate systems, so when you call mobility->getCurrentPosition() you get omnet coordinates not sumo coordinates.
I make some tests with proj4 C library and the values not was matching...
As me, probably you looking for the real sumo coordinates and for this you need call TraCIConnection::omnet2traci. But the problem is that not exists in veins a direct interface to access the object connection via TraCICommandInterface.
To overcome this trick I implemented one public method directly in the class TraCICommandInterface the signature of the method is the same of getLonLat method the diference is that inside I return the sumo coordinates calling the method `omnet2traci'. Now I can get the real sumo coordinates and use this for work with my real GPS dataset and one deadreckoning technique that I've implemented.
Follows the code of the method:
std::pair<double, double> TraCICommandInterface::getTraCIXY(const Coord& coord){
TraCICoord newCoord;
newCoord = connection.omnet2traci(coord);
return std::make_pair(newCoord.x, newCoord.y);
}
In your application class call this method using one TracICommandInterface object:
TraCIMobility* mobility;
TraCICommandInterface* traci;
Now in your initialize method instantiate this objects getting the active modules and traci interface:
mobility = TraCIMobilityAccess().get(getParentModule());
traci = mobility->getCommandInterface();
Now you will have this:
These are omnet++ cordinates:
Coord coordOmnet = mobility->getCurrentPosition();
These are sumo coordinates calling our implement method:
std::pair<double,double> coordTraCI = traci->getTraCIXY(mobility->getCurrentPosition());
Best Regards,
Pedro.
What is the main reason to convert the positions?
Why not use the OMNet/Veins - SUMO/TraCi coordinate?

Write OLED driver for RaspberryPi

I am writing a driver module for my 128x64 OLED(ssd1306), which will be used on my raspberry pi. And it works in 4-wire SPI mode. Firstly, I read the datasheet of the ssd1306 and wrote some basic functions. Then I connected this OLED with an Arduino board, ran the codes to test its correctness and I found it worked quite well.
Here are my arduino code:
//oled.ino
#define clearPin(a) digitalWrite(a, LOW)
#define setPin(a) digitalWrite(a, HIGH)
char* hello = "Hello World!";
// visible ascii chars
const unsigned char F6x8[][6] =
{
//...
};
const unsigned char F8X16[]=
{
//...
};
// pin assignments
int CS = 53;
int DIN = 51;
int CLK = 52;
int DC = 3;
int RES = 2;
//***********************************
int writeCommand(byte command)
{
int i;
clearPin(CS);
clearPin(DC);
for(i = 0; i < 8; i++)
{
clearPin(CLK);
delay(1);
if((command >> (7-i)) & 0x1)
setPin(DIN);
else
clearPin(DIN);
delay(1);
setPin(CLK);
delay(1);
}
setPin(CS);
}
int writeData(byte data)
{
int i;
clearPin(CS);
setPin(DC);
for(i = 0; i < 8; i++)
{
clearPin(CLK);
delay(1);
if((data >> (7 - i)) & 0x1)
setPin(DIN);
else
clearPin(DIN);
delay(1);
setPin(CLK);
delay(1);
}
setPin(CS);
}
void setPostion(byte x, byte y)
{
writeCommand(0xB0 | y); // go to page y
writeCommand(0x00 | (x & 0x0f)); // setPin lower column address
writeCommand(0x10 | ((x >> 4) & 0x0f)); // setPin higher column address
}
void write6x8Char(byte x, byte y, char ch)
{
setPostion(x, y);
int i, c = ch - 32;
for(i = 0; i < 6; i++)
writeData(F6x8[c][i]);
}
void write6x8String(byte x, byte y, char* str)
{
//...
}
void write8x16Char(byte x, byte y, char ch)
{
setPostion(x, y);
int i, c = ch - 32;
for(i = 0; i < 8; i++)
writeData(F8X16[c * 16 + i]);
setPostion(x, y+1);
for(i = 8; i < 16; i++)
writeData(F8X16[c * 16 + i]);
}
void write8x16String(byte x, byte y, char* str)
{
//...
}
void clearScreen()
{
fill(0);
}
void fill(unsigned char bmp_data)
{
unsigned char y,x;
for(y = 0; y < 8; y++)
{
writeCommand(0xb0 + y);
writeCommand(0x00);
writeCommand(0x10);
for(x = 0; x < 128; x++)
writeData(bmp_data);
}
}
void setDisplayOn(byte on)
{
writeCommand(0xAE | on);
}
//***********************************************
void initialize()
{
setPin(CLK);
clearPin(RES);
delay(50);
setPin(RES);
setDisplayOn(1);
fill(0x00);
}
void setup()
{
pinMode(CS, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(DC, OUTPUT);
pinMode(RES, OUTPUT);
initialize();
}
void loop()
{
write8x16String(0, 0, hello);
}
So I moved them directly into my driver module file with few necessary changes. Here are my oled.c file and Makefile:
//oled.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#define DRIVER_NAME "OLED"
#define DEVICE_NAME "OLED"
#define clearGPIO(a) gpio_set_value(a, 0)
#define setGPIO(a) gpio_set_value(a, 1)
const int DIN = 5;
const int CLK = 6;
const int CS = 13;
const int DC = 19;
const int RES = 26;
const unsigned char F6x8[][6] =
{
//...
};
const unsigned char F8X16[]=
{
//...
};
//*****************************************
void delay(int ms)
{
int i, j;
for(i = 0; i < ms; i++)
{
j = 100000;
while(j--);
}
}
//...Same functions with the arduino program...
//*****************************************
static dev_t oled_devno;
static struct class *oled_class;
static struct cdev oled_dev;
static int flag = 0;
//open
static int oled_open(struct inode *inode, struct file *filp)
{
int err;
printk(KERN_INFO"Initializing GPIOs...\n");
err = gpio_request_one(CS, GPIOF_OUT_INIT_LOW, "CS");
if(err){
printk(KERN_ERR"[%s %d]:Request led gpio failed\n", __func__, __LINE__);
gpio_free(CS);
}
err = gpio_request_one(DC, GPIOF_OUT_INIT_LOW, "DC");
if(err){
printk(KERN_ERR"[%s %d]:Request led gpio failed\n", __func__, __LINE__);
gpio_free(DC);
}
err = gpio_request_one(RES, GPIOF_OUT_INIT_LOW, "RES");
if(err){
printk(KERN_ERR"[%s %d]:Request led gpio failed\n", __func__, __LINE__);
gpio_free(RES);
}
err = gpio_request_one(DIN, GPIOF_OUT_INIT_LOW, "DIN");
if(err){
printk(KERN_ERR"[%s %d]:Request led gpio failed\n", __func__, __LINE__);
gpio_free(DIN);
}
err = gpio_request_one(CLK, GPIOF_OUT_INIT_LOW, "CLK");
if(err){
printk(KERN_ERR"[%s %d]:Request led gpio failed\n", __func__, __LINE__);
gpio_free(CLK);
}
flag = 1;
printk(KERN_INFO"Initializing OLED...\n");
oled_initialize();
printk(KERN_INFO"OLED open\n");
return 0;
}
//release
static int oled_release(struct inode *inode, struct file *filp)
{
if(flag)
{
gpio_free(CS);
gpio_free(DC);
gpio_free(RES);
gpio_free(DIN);
gpio_free(CLK);
}
printk(KERN_INFO"OLED release\n");
return 0;
}
//write
ssize_t oled_write(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
char* hello = "Hello driver";
printk(KERN_INFO"I am writing data!\n");
write8x16String(0, 0, hello);
return 0;
}
static struct file_operations oled_fops = {
.owner = THIS_MODULE,
.open = oled_open,
.release = oled_release,
.write = oled_write,
};
static int __init oled_init(void)
{
int err;
printk(KERN_INFO"OLED Init \n");
err = alloc_chrdev_region(&oled_devno,0,1,DRIVER_NAME);
if(err < 0){
goto err;
}
cdev_init(&oled_dev,&oled_fops);
err = cdev_add(&oled_dev,oled_devno,1);
if(err < 0)
{
printk(KERN_ERR"[%s,%d]add cdev failed\n",__func__,__LINE__);
goto FREE_DEVNO;
}
//
oled_class = class_create(THIS_MODULE,DEVICE_NAME);
if(IS_ERR(oled_class))
{
printk(KERN_ERR"[%s,%d]class create failed\n",__func__,__LINE__);
goto DEV_FREE;
}
device_create(oled_class,NULL,oled_devno,NULL,DEVICE_NAME);
return 0;
DEV_FREE:
cdev_del(&oled_dev);
FREE_DEVNO:
unregister_chrdev_region(oled_devno, 1);
err:
return err;
}
static void oled_exit(void)
{
if(flag)
{
gpio_free(CS);
gpio_free(DC);
gpio_free(RES);
gpio_free(DIN);
gpio_free(CLK);
}
device_destroy(oled_class,oled_devno);
class_destroy(oled_class);
cdev_del(&oled_dev);
unregister_chrdev_region(oled_devno, 1);
printk(KERN_INFO"OLED exit\n");
}
module_init(oled_init);
module_exit(oled_exit);
MODULE_LICENSE("GPL");
Makefile:
//Makefile
ifneq ($(KERNELRELEASE),)
obj-m := oled.o
else
KERNELDIR:=/home/rpi/linux/
PWD := $(shell pwd)
CROSS_COMPILE := arm-linux-gnueabihf-
default:
$(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) ARCH=arm -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.c *.order *.symvers
endif
However, when I wrote a program to open the device and write characters into it, there was no response from this OLED. And no error was logged into kern.log. What I really don't understand is why they behaved differently with the same control functions? Is there something fatal that I ignored?

Kernel call_usermodehelper fail to open GUI application

I use call_usermodehelper to open qt why I can't open? How to solve this problem? Or other way use kernel to open user-space application?
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kmod.h>
MODULE_LICENSE("GPL");
static int umh_test( void ) {
char *argv[] = { "/usr/bin/qtcreator", NULL };
static char *envp[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin",
NULL
};
return call_usermodehelper( argv[0], argv, envp, UMH_WAIT_PROC);
}
static int hello_init(void)
{
int ret = 0;
ret = umh_test();
printk(KERN_INFO "retval11: %d\n", ret);
return 0;
}
static void hello_exit(void)
{
printk(KERN_INFO "BYE\n");
}
module_init(hello_init);
module_exit(hello_exit);
Picture showing the error picture:

Resources