0

I received a function that i need to implement in my code. The function is working on it's own self tester. Here it is with struct associated (i can make an executable example if needed) :

    #define STEERINGCMD_MSG_BUFFERLENGTH    40

typedef struct GLOBAL_MSG
{
    u1 starter;
    u1 frameID;
    u1 length;
    u1 msgData[STEERINGCMD_MSG_BUFFERLENGTH];
    u4 CRYPTO;
};

GLOBAL_MSG  steeringCmdMsg;

struct SteeringData
{
    int                 isL1;
    int                 isL5;
    unsigned long long  CoPR;
    unsigned long long  CoPA;
    unsigned long long  CaPR;
    unsigned long long  CaPA;

};

void generateNextSteeringCmdMsg(SteeringData stData)
{
    steeringCmdMsg.starter = 0xAA;
    steeringCmdMsg.frameID = 68;
    steeringCmdMsg.length = STEERINGCMD_MSG_BUFFERLENGTH;

    if()
    {
        steeringCmdMsg.msgData[0] = 0x0F;
    }
    else if( )
    {
        steeringCmdMsg.msgData[0] = 0xF0;
    }
    steeringCmdMsg.msgData[1] = stData.CoPR & 0xFF;
    steeringCmdMsg.msgData[2] = stData.CoPR >> 8 & 0xFF;
    steeringCmdMsg.msgData[3] = stData.CoPR >> 16 & 0xFF;
    steeringCmdMsg.msgData[4] = stData.CoPR >> 24 & 0xFF;
    steeringCmdMsg.msgData[5] = stData.CoPR >> 32 & 0xFF;
    steeringCmdMsg.msgData[6] = stData.CoPR >> 40 & 0xFF;
    steeringCmdMsg.msgData[7] = stData.CoPR >> 48 & 0xFF;
    steeringCmdMsg.msgData[8] = stData.CoPR >> 56 & 0xFF;
    steeringCmdMsg.msgData[9] = stData.CoPA & 0xFF;
    steeringCmdMsg.msgData[10] = stData.CoPA >> 8 & 0xFF;
    steeringCmdMsg.msgData[11] = stData.CoPA >> 16 & 0xFF;
    steeringCmdMsg.msgData[12] = stData.CoPA >> 24 & 0xFF;
    steeringCmdMsg.msgData[13] = stData.CoPA >> 32 & 0xFF;
    steeringCmdMsg.msgData[14] = stData.CoPA >> 40 & 0xFF;
    steeringCmdMsg.msgData[15] = stData.CoPA >> 48 & 0xFF;
    steeringCmdMsg.msgData[16] = stData.CoPA >> 56 & 0xFF;
    steeringCmdMsg.msgData[17] = stData.CaPR & 0xFF;
    steeringCmdMsg.msgData[18] = stData.CaPR >> 8 & 0xFF;
    steeringCmdMsg.msgData[19] = stData.CaPR >> 16 & 0xFF;
    steeringCmdMsg.msgData[20] = stData.CaPR >> 24 & 0xFF;
    steeringCmdMsg.msgData[21] = stData.CaPR >> 32 & 0xFF;
    steeringCmdMsg.msgData[22] = stData.CaPR >> 40 & 0xFF;
    steeringCmdMsg.msgData[23] = stData.CaPR >> 48 & 0xFF;
    steeringCmdMsg.msgData[24] = stData.CaPR >> 56 & 0xFF;
    steeringCmdMsg.msgData[25] = stData.CaPA & 0xFF;
    steeringCmdMsg.msgData[26] = stData.CaPA >> 8 & 0xFF;
    steeringCmdMsg.msgData[27] = stData.CaPA >> 16 & 0xFF;
    steeringCmdMsg.msgData[28] = stData.CaPA >> 24 & 0xFF;
    steeringCmdMsg.msgData[29] = stData.CaPA >> 32 & 0xFF;
    steeringCmdMsg.msgData[30] = stData.CaPA >> 40 & 0xFF;
    steeringCmdMsg.msgData[31] = stData.CaPA >> 48 & 0xFF;
    steeringCmdMsg.msgData[32] = stData.CaPA >> 56 & 0xFF;

    char* actMsg =(char*) &steeringCmdMsg;
    steeringCmdMsg.crc32 = calculateCRYPTOForBuf(actMsg, STEERINGCMD_MSG_BUFFERLENGTH - 4);
}

void getSteeringMsg(i1 msg[STEERINGCMD_MSG_BUFFERLENGTH])
{
    char* actMsgData =(char*) &steeringCmdMsg.msgData;
    msg[0] =  steeringCmdMsg.starter;
    msg[1] =  steeringCmdMsg.frameID;
    msg[2] =  steeringCmdMsg.length;
    memcpy( &msg[3], actMsgData, STEERINGCMD_MSG_BUFFERLENGTH - 7);

    msg[39] = steeringCmdMsg.CRYPTO >>24;
    msg[38] = steeringCmdMsg.CRYPTO >>16;
    msg[37] = steeringCmdMsg.CRYPTO >>8;
    msg[36] = steeringCmdMsg.CRYPTO;

}

//used like this in the main
int main {

    i1 tmpMsg[STEERINGCMD_MSG_BUFFERLENGTH + 1];
    memset(tmpMsg, 0, STEERINGCMD_MSG_BUFFERLENGTH + 1);
    generateNextSteeringCmdMsg(steeringDataL1);
    getSteeringMsg(tmpMsg);
    write(tmpMsg, STEERINGCMD_MSG_BUFFERLENGTH);

    return 0;
}

Context : I have an equipment that need to receive what we call "steering msg" in binary, that contains basic header and all parameters contained into SteeringData struct. At the end, with all parameters concatenated in msgData, i calculate what we call CRYPTO. And add it to the end of the message.

The problem is that in this code stData.CoPR/CoPA... are unsigned long long (size = 8) and in my code this is a double (struct.CoPR - and can't be modified because coming from a struct).

So i'm looking for the best way to modify this function and replace this unsigned long long by my double struct. Either a simple cast, or another way to directly translate my double struct into the char array. But i don't know where to look at and what will be the most secure and safe way to do it.

Feel free to ask for more explanation, thank you !

HacHac
  • 147
  • 11
  • 1
    all the lines `steeringCmdMsg.msgData[1] = stData.CoPR >> ...` look like it should take ~5 lines of code. – KamilCuk Jan 08 '19 at 11:48
  • 1
    What is the code you show coming from? It's not *your* code, as you claim to have structures with `double` members instead. And *why* can't you change your code to have `unsigned long long` members in the structure? – Some programmer dude Jan 08 '19 at 11:49
  • @Someprogrammerdude this code comes from the creator of the equipment and shows how he sends SteeringMsg to his equipment. The other code containing the double struct comes from a bigger architecture of equipments that puts values into this double struct after lot of calculus. And i need to integrate this new equipment into this big architecture. – HacHac Jan 08 '19 at 11:54
  • 1
    Then it seems that you need two structures: One for your internal data that the "big architecture" uses, and one for sending data to the "equipment". External "equipment" could mean that the communication protocol is fixed, and you should not attempt to change it. – Some programmer dude Jan 08 '19 at 11:57
  • @Someprogrammerdude that's what i want to avoid as much as possible to change the external equipment code. My utopia would have been to change "steeringCmdMsg.msgData[1] = stData.CoPR & 0xFF;" to "steeringCmdMsg.msgData[1] =(unsigned long long) biggerStruct.CoPR & 0xFF;".... – HacHac Jan 08 '19 at 12:03
  • Of course `steeringCmdMsg.msgData[1] =(unsigned long long) biggerStruct.CoPR & 0xFF;` will work, but maybe not do what you expect (the floating point value will be *truncated* making you lose the fractional part). – Some programmer dude Jan 08 '19 at 12:13
  • @Someprogrammerdude yes, not useful to loose this. I was thinking of using maybe ceil fonction (something like `if( (ceil(value)-value<0.5)&&(ceil(value)-value!=0) )` or maybe a memcpy of the double struct directly into my msgData[i] ... but not sure that's the good way to do it. – HacHac Jan 08 '19 at 13:52
  • If the "equipment" is not expecting anything other than an unsigned 64-bit integer in a specific byte order, trying to send anything else is not going to work, and there's simply no way around it. – Some programmer dude Jan 08 '19 at 13:56
  • Recommend a [mcve] with sample data. You may only need `union { unsigned long long ul; double d;) } CaPR;` Yet the goal is not clear enough for me. – chux - Reinstate Monica Jan 08 '19 at 14:17

0 Answers0