Convert "Tcl_Obj* const objv[]" to "char** argv" - c++11

I'm using Tcl 8.6 and I'm trying to do something like this to add functions to the tcl interpreter
Tcl_Interp* interp,
void init() {
interp = Tcl_CreateInterp();
}
void add_tcl_function(char* cmd, function<int(int,char**)> F) {
obj2argv* o2a = new obj2argv;
auto lambda_proc = [&](
ClientData cdata,
Tcl_Interp* interp,
int objc,
Tcl_Obj* const objv[])
{
o2a->set(objc, objv);
F(objc, o2a->get_argv());
};
auto lamba_delete = [&](
delete o2a;
};
Tcl_CreateObjCommand(interp, cmd, lamda_proc, NULL, lamda_delete);
}
What I'm wondering is how to convert "Tcl_Obj* const objv[]" to "char** argv"?
I was thinking about creating a class:
class obj2argv {
obj2argv();
void set(int objc, Tcl_Obj* const objv[]);
char** get_argv();
private:
//...
};
any ideas on how to implement set() and get_argv()?
Is there an easier way to do this?
Thanks.
obj2argv* o2a = new obj2argv;

If you're interfacing a function that's fundamentally working with const char** for arguments, you should register the function with Tcl_CreateCommand and let Tcl handle the mapping to strings for you. It already has all the mechanisms required.
More formally, you are dealing with a gluing function with this signature:
typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
int argc, CONST84 char *argv[]);
The CONST84 should be read as being plain const in all new code, and ClientData is a pointer-sized value that Tcl just hands around and never inspects (same as with your existing code).
If you are going to do the mapping yourself, Tcl_GetString takes a Tcl_Obj* and returns the char* representation of it. The representation should be usually treated as const; it simply isn't formally typed as such for historical reasons.

I wanted to add some more information:
I gave up on using lambda's because when I added capture list it won't convert the lambda to a function pointer for some reason. So I went with the traditional approach (see below). EXCEPT: I still have not idea why the TCL document says
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
const char *argv[]);
But the compiler requires this to compile:
typedef int Tcl_CmdProc(
ClientData clientData,
Tcl_Interp *interp,
int argc,
Tcl_Obj* const* argv);
The Code:
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* argv)
{
function<int(int,char**)> F = *(function<int(int,char**)>*)clientData;
return F(argc, (char**) argv); // <= CAST DOESN'T SEEM RIGHT
}
void cmd_delete(ClientData clientData)
{
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)&F, cmd_delete);
}
VERSION 2:
struct cmd_data {
//Tcl_Interp* interp,
function<int(int,char**)> F;
int argc;
char* argv[MAX_ARGS];
};
int cmd_dispatch(
ClientData clientData,
Tcl_Interp* interp,
int argc,
Tcl_Obj* const* objv)
{
auto cmd_data1 = (struct cmd_data*) clientData;
cmd_data1->argc = argc;
for(int i=0; ((i < argc) && (i < MAX_ARGS)); i++) {
cmd_data1->argv[i] = Tcl_GetString(objv[i]);
// Who owns object returned by Tcl_GetString?
// memory leak? or invalid after return from function?
// garbage collected by tcl interp?
}
return cmd_data1->F(argc, cmd_data1->argv);
}
void cmd_delete(ClientData clientData)
{
auto cmd_data1 = (struct cmd_data*) clientData;
if (cmd_data1) {
delete cmd_data1;
}
}
void add_tcl_function(const char* cmd, function<int(int,char**)> F) {
auto cmd_data1 = new struct cmd_data;
cmd_data1->F = F;
Tcl_CreateObjCommand(interp, cmd, cmd_dispatch, (void*)cmd_data1, cmd_delete);
}
void init_tcl_commands() {
auto lambda_hello = [&](int argc ,char** argv) -> int {
cout << "HELLO WORLD!\n";
return 0;
};
tcl_backend::add_tcl_function("hello", lambda_hello);
}

Related

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

Parsing strings at compile-time - if possible

I am trying to make compile time checks over the format of the printf. Here is the code.
#include <type_traits>
#include <iostream>
template <typename CHAR, typename ...ARGS>
constexpr size_t trace_cond(CHAR fmt, ARGS&&... args) {
//always needs to pass
return 1;
}
template <size_t N, typename ...ARGS>
constexpr size_t trace_cond(const char (&fmt)[N], ARGS&&... args) {
//return parse(fmt) == args;
return sizeof...(args) != 0;
}
#define TRACE(fmt, ...) { \
static_assert(trace_cond(fmt, __VA_ARGS__), "Wrong ARGS"); \
printf(fmt, ##__VA_ARGS__); \
}
int main(int argc, char* argv[]) {
//working fine
TRACE("%d %d\n", 2, 3);
const char* format = "%d %d\n";
//error
TRACE(format, 2, 3);
}
So when the format is known at compile time I want to have a check(using static_assert) and if it is not known then the check should be not called or always to pass
Obs:
Currently the code is not compiling because const char *format is not declared constexpr
The main should not be change because TRACE macro is used in a large codebase but changes to TRACE are more than welcome
So my question is:
Is there a way to skip static_assert or make it pass when fmt type is const char *
I think you can do what you want by moving the static_assert to the trace_cond
#include <type_traits>
#include <iostream>
template <size_t C, typename CHAR>
size_t trace_cond(CHAR fmt) {
//always needs to pass
return 1;
}
template <typename ...ARGS>
constexpr size_t count_args(ARGS&&... args) {
return sizeof...(args);
}
template <size_t C, size_t N>
constexpr size_t trace_cond(const char (&fmt)[N]) {
// TODO, parse fmt and do the needed checks
static_assert(C == 3, "");
return 1;
}
#define TRACE(fmt, ...) { \
trace_cond<count_args(__VA_ARGS__)>(fmt); \
printf(fmt, ##__VA_ARGS__); \
}
int main(int argc, char* argv[]) {
// Static check - hard coded to check for 3 arguments
TRACE("%d %d %d\n", 2, 3, 4);
const char* format = "%d %d\n";
// No checks performed
TRACE(format, 2, 3);
}

Hash table of templated functor

I want to create a hastable to member templated functor, I explain.
Here is my exemple which does'nt work:
#include <iostream>
#include <unordered_map>
using namespace std;
class MyFirstClass
{
int i_;
public:
MyFirstClass(): i_(0) {}
void setI(int i) { i_ = i; }
int getI() { return i_; }
};
class MySecondClass
{
bool b_;
public:
MySecondClass(): b_(0) {}
void setB(bool b) { b_ = b; }
bool getB() { return b_; }
};
template<class X, void (X::*p)()>
class MyFunctor
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()() const { (_x.*p)(); }
};
int main(int argc, char *argv[])
{
unordered_map<string,MyFunctor> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = first::setI;
myHashTable["bool"] = second::setB;
//
string key = "bool";
int value = 1;
myHashTable[key](value);
return 0;
}
I have multiple class with their own setter . I would like to be able thanks to the has table and a command {string,int} change the value of the corresponding class.
The previous code is not working for the moment and I am stuck.
There are a few problems with your code, as it stands.
Firstly, from your example unordered_map<string,MyFunctor> doesn't name a type, because MyFunctor doesn't name a type. You could create a non-template base class with a virtual operator(), and then have MyFunctor inherit from it.
Second, you aren't using compatible method pointers, MyFirstClass::setI and MySecondClass::setB both take a parameter.
Third, related to the first, you have to specify the template parameters when constructing an object from a class template. (until c++17's class template deduction guides). You also have ungrammatical syntax that I assume is trying to specify the object argument to the MyFunctor constructor alongside the method-pointer template argument.
You would have something like
class MyFunctorBase {
virtual void operator()(void * i) const = 0;
}
template<class T, class X, void (X::*p)(T)>
class MyFunctor : public MyFunctorBase
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()(void * i) const override { (_x.*p)(*static_cast<T*>(i)); }
};
int main(int argc, char *argv[])
{
unordered_map<string,shared_ptr<MyFunctorBase>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = make_shared<MyFunctor<int, MyFirstClass, &MyFirstClass::setI>>(first);
myHashTable["bool"] = make_shared<MyFunctor<bool, MySecondClass, &MySecondClass::setB>>(second);
//
string key = "bool";
bool value = true;
(*myHashTable[key])(static_cast<void *>(&value));
return 0;
}
Or, much more easily, use the existing std::function, which does that for you
int main(int argc, char *argv[])
{
unordered_map<string,function<void(void *)>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = [first](void * i) { first.setI(*static_cast<int *>(i)); };
myHashTable["bool"] = [second](void * i) { second.setB(*static_cast<bool *>(i)); };
//
string key = "bool";
bool value = true;
myHashTable[key](static_cast<void *>(&value));
return 0;
}

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?

Cast a (void const *x) to a (unsigned char const *y)

I'm going through a source code analyzing its implementations where I have a method defined :
unsigned int rs_calc_weak_sum(void const *p, int len) {
unsigned char const *buf = (unsigned char const *) p;
}
What type of parameter should be passed into this method??
please help me.
thanks.
Any pointer can be passed to a void * parameter. What 'should' be passed, depends on what the code does with that parameter.
char array[12] = "Hello World";
unsigned in res = 0;
res = rs_calc_weak_sum(array, 12);
#include <stdio.h>
int main ( void )
{
char filename[] = "file.txt";
FILE *file = fopen ( filename, "r" );
if (file != NULL) {
char line [1000];
while(fgets(line,sizeof line,file)!= NULL) /* read a line from a file */ {
res = rs_calc_weak_sum(line, 1000);
}
fclose(file);
}
else {
perror(filename); //print the error message on stderr.
}
return 0;
}

Resources