Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Inject data into a struct

Status
Not open for further replies.

abcd12344445555

Programmer
May 10, 2009
24
BR
I’ve got an equipment that receives some data from the network and map it to the structures below:

Code:
struct a_s{
u_int16_t cmd;
u_int16_t dataSize;
u_int8_t  data[MAX_DATA_SIZE];
};
typedef struct a_s   a_t;

struct b_s {
 u_int16_t part;
 u_int16_t serial;
 a_t       payload;
};
typedef struct b_s   b_t;

At some point, the received info is routed to another equipment using the following functions:

Code:
int checkSet(void * ne,  b_t * msg)
{
   (…)
   send(ne->position, msg->payload.cmd, msg->payload.dataSize, msg->payload.data)
   (...)
}

int send(u_int8_t pos, u_int16_t cmd, size_t len, void * payload)
{
   assert( ((payload != NULL) && (len != 0)) || ((payload == NULL) && (len == 0)) );
   assert( pre(Serial) != NULL );  

  (...)
}

The problem is that now I need to generate one message locally invoking checkSet() with something like :

Code:
struct b_s localMsg;
localMsg.part = 1;
localMsg.serial = 2;
localMsg.payload.cmd=3;
[COLOR=red] localMsg.dataSize = 0; [/color]

I don't know how to make this message not to fail at the assert of the function send();
The message must have size 0 and no data.
How can I create a message with msg->payload.data == NULL?

Im trying something like this, but it still fails at the assert, cause msg->payload.data != NULL and msg->payload.datasize == 0

Code:
unsigned char buffer[sizeof(b_t )];
memset(buffer,0,sizeof(b_t ));

b_t   *msg;
msg = (b_t  *) buffer;
msg->tlv.cmd = 0x00A0;
msg->tlv.dataSize = 0;

checkSet(something, msg);




Best Regards,
P.
 
Hi P.

You are trying to use payload as a pointer, when it is not. You are going to have to do one of two things:

1. re-write the b_s struct to make payload become a pointer to a_t i.e.

Code:
struct b_s {
 u_int16_t part;
 u_int16_t serial;
 a_t       *payload;
};

You then need to change all the code that refers to the structure and ensure it correctly dereferences the pointer. This is probably a lot of work.

2. Change the assert to check for sane values rather than a pointer:

Code:
assert(payload.dataSize == len)

Cheers,
Scott
 
doh... I missread the post.

forget my previous.

You need to allocate the data element in a_t and not define it as an array in the struct:

Code:
struct a_s{
u_int16_t cmd;
u_int16_t dataSize;
u_int8_t  *data;
};
typedef struct a_s   a_t;

Then you can either stick it on the stack if it's small and will not be used after the send() or malloc() if it will be used again i.e.

Code:
u_int8_t dataBuf[MAX_DATA_SIZE];
localmsg.data = dataBuf;
localmsg.dataSize = size;

then you can set it to NULL when required.


Sorry,
Scott

 
Thanks Scott, but that’s the point. I can’t change things like that. Unfortunately this is a legacy code and I need to figure out a way to use those structures as they are. Would be very nice to have u_int8_t *data instead of u_int8_t data[MAX_DATA_SIZE].

Best Regards,
P.
 
ah... interesting... unfortunately you are at the mercy of the compiler - who ever wrote the original code for the assert must have assumed a_t.data would be a pointer. Whilst it looks like it is, the code produced by the compiler isn't going to use it like that at all, so it will not allow you to set it to NULL. Find the original author and give him a big slap...

When you say it's legacy code, do you still have the ability to re-compile everything? If so, can you attack the assert? This is the only other approach I can think of for the moment, since you can redefine it to look for messages cmd's that are valid 0 length.

Good luck,
Scott

 
hmmm.. my description of a_t.data was misleading. It can be used as a pointer, (i.e. in memcpy etc.) but it will be calculated as an offset from the base of the a_t struct, so the compiler will still prevent you from setting it to NULL.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top