MQTT 上的 CAN 帧需要将十六进制字符串转换为字节数组

如何解决MQTT 上的 CAN 帧需要将十六进制字符串转换为字节数组

我正在实施 MQTT 通信。我想通过图形界面(在 python 中实现)通过 MQTT 发送 CAN 帧。我能够从 GUI 向一个主题发送消息,并且当我使用该板时,我能够看到到达同一主题的消息(使用 paho 库)。函数在下面,主题diagnostic_request/topic

 void onMessageArrived
(
    const char* topic,const uint8_t* payload,size_t payloadLen,void* context
)
{
    //LE_FATAL("The publisher received a message!");
    //GIMP
    char payloadStr[payloadLen + 1];
    memcpy(payloadStr,payload,payloadLen);
    payloadStr[payloadLen] = '\0';
    LE_INFO("Received message! topic: \"%s\",payload: \"%s\"",topic,payloadStr);
    //GIMP principio di conversione

    if (strcmp(subscribetopic,topic)==0)
        LE_INFO("Sei sul topic di richiesta diagnostica!");
        can_send();        
  }

在这一点上我有困难。我的 can_send 函数(有效!)是:

int can_send(void)
{
    const char* subscribetopic = "diagnostic_request/topic";
    LE_FATAL_IF(
            mqtt_Subscribe(MQTTSession,subscribetopic,MQTT_QOS0_TRANSMIT_ONCE) != LE_OK,"Failed to subscribe to %s",subscribetopic);
    LE_INFO("Subscribed to topic (%s)",subscribetopic);


           
        
int nbytesWrite;

// USE SEND STANDARD FRAME
frameWrite.can_id = 0x750; //codice identificativo di una richiesta diagnostica per centralina simulata
frameWrite.can_id &= CAN_SFF_MASK;

frameWrite.can_dlc = 8;
 //strcpy((char *)frameWrite.data,"MGATE");
frameWrite.data[0] = 0x03;
frameWrite.data[1] = 0x22;
frameWrite.data[2] = 0xF1;
frameWrite.data[3] = 0x89;
frameWrite.data[4] = 0x00;
frameWrite.data[5] = 0x00;
frameWrite.data[6] = 0x00;
frameWrite.data[7] = 0x00;
if ((nbytesWrite = write(sdw,&frameWrite,sizeof(frameWrite))) != sizeof(frameWrite))
{
    canwrite = false;
    LE_INFO ("Writing error,nbytesWrite = %d",nbytesWrite);
    return SOCK_WRITING_ERROR;
}

canwrite = true;
return 0;
}

所以当 is 语句正常时,我必须在 onMessageArrived 函数调用 can_send。我可以看到我何时发送关于诊断请求/主题的发布。唯一的问题是将payloadStr 值发送到can_send 函数并在frameWrite.data[] 中解包。 有人可以帮我了解如何修改 can_send 函数以使值

frameWrite.data[0] = 0x03;
frameWrite.data[1] = 0x22;
frameWrite.data[2] = 0xF1;
frameWrite.data[3] = 0x89;
frameWrite.data[4] = 0x00;
frameWrite.data[5] = 0x00;
frameWrite.data[6] = 0x00;
frameWrite.data[7] = 0x00;

是我在 payloadStr 中通过 mqtt 发送的值吗?我发送了一个 8 字节的字符串,但无法解包。 任何帮助将不胜感激 问候

解决方法

采取“先写测试”的方法......

int convertNybble (char const hex) 
{
    if (hex >= '0' && hex <= '9')
    {
        return hex - '0';
    }
    else if (hex >= 'a' && hex <= 'f')
    {
        return 10 + (hex - 'a');
    }
    else if (hex >= 'A' && hex <= 'F')
    {
        return 10 + (hex - 'A');
    }
    
    return -1; // invalid hex character
}


#define ERR_NOT_EVEN_NUMBER_OF_DIGITS   -1
#define ERR_STRING_TOO_LONG             -2
#define ERR_INVALID_CHAR                -3


int preparePayload(char const* hexString,unsigned char* canBuffer,size_t const bufLen)
{
    size_t hexLen = strlen(hexString);

    if (0 != (hexLen % 2))
    {
        // Expect an even number of digits.
        return ERR_NOT_EVEN_NUMBER_OF_DIGITS;
    }

    size_t payloadLen = hexLen / 2;

    // buffer will contain payload-length,followed by payload data.
    //  so payloadLen+1 must be able to fit into bufLen - fail if payloadLen+1 > bufLen,which is the same as payloadLen >= bufLen
    if (payloadLen >= bufLen)
    {
        // will not be able to fit the decoded string into the payload buffer
        return ERR_STRING_TOO_LONG;
    }

    unsigned char* bufEnd = canBuffer;
    bufEnd += bufLen;

    *canBuffer++ = (unsigned char)payloadLen;

    while (payloadLen > 0)
    {
        payloadLen--;

        int hexDigit[2];
        hexDigit[0] = convertNybble(*hexString++);
        hexDigit[1] = convertNybble(*hexString++);

        if ((hexDigit[0] < 0) || (hexDigit[1] < 0))
        {
            return ERR_INVALID_CHAR;
        }

        *canBuffer++ = (hexDigit[0] << 4) | hexDigit[1];
    }

    // fill any leftovers with zero
    while (canBuffer < bufEnd)
    {
        *canBuffer++ = 0;
    }

    return (0);
}



int performTests()
{
    char const* testStr[5] =
    {
        "12345","0123456789ABCDEF","@ABC","0AF9","0123456789ABCD"
    };

#define MARKER 0xFF
#define PAYLOAD_LEN 8
    unsigned char payload[PAYLOAD_LEN+1];
    payload[PAYLOAD_LEN] = MARKER;

    int decodeResult = preparePayload(testStr[0],payload,PAYLOAD_LEN);

    if (ERR_NOT_EVEN_NUMBER_OF_DIGITS != decodeResult) { return -1; }       //not expected result

    decodeResult = preparePayload(testStr[1],PAYLOAD_LEN);

    if (ERR_STRING_TOO_LONG != decodeResult) { return -1; }

    decodeResult = preparePayload(testStr[2],PAYLOAD_LEN);

    if (ERR_INVALID_CHAR != decodeResult) { return -1; }

    // here we are checking the character decoding
    decodeResult = preparePayload(testStr[3],PAYLOAD_LEN);

    if (0 != decodeResult) { return -1; }

    if (payload[0] != 2)    { return -1; }
    if (payload[1] != 0x0A) { return -1; }
    if (payload[2] != 0xF9) { return -1; }
    if (payload[3] != 0)    { return -1; }
    if (payload[7] != 0)    { return -1; }
    // payload contains - 02 0a f9 00 00 00 00 00 00

    // here we are checking the limit of the payload capacity
    decodeResult = preparePayload(testStr[4],PAYLOAD_LEN);

    if (0 != decodeResult) { return -1; }
    // payload contains - 07 01 23 45 67 89 ab cd


    // check we haven't overrun the buffer
    if (payload[8] != MARKER) { return -1; }


    // all tests pass
    return 0;
}


int main()
{
    int testResult = performTests();
    return testResult;
}

然后您可以按如下方式实现解码器:

convertNybble,preparePayload etc as above....


int canbusSend(unsigned char const* canbusPayload)
{
    //etc

    // - copy payloadBytes to frameWrite.data....

    //etc
}


void onMessageArrived
(
    const char* topic,const uint8_t* mqttPayload,size_t payloadLen,void* context
)
{
#define CANBUS_PAYLOAD_BUFFER_LEN   8
    unsigned char canbusPayload[CANBUS_PAYLOAD_BUFFER_LEN];
    int decodeResult = preparePayload((char const*)mqttPayload,canbusPayload,CANBUS_PAYLOAD_BUFFER_LEN);

    if (0 == decodeResult)
    {
        int canbusSendResult = canbusSend(canbusPayload);
        // TODO : report error if failed
    }
    else
    {
        //TODO : report error
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?