c-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] = '';
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。我可以在diagnostic_request/topic上查看何时发送发布。唯一的问题是将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, PAYLOAD_LEN);
if (ERR_STRING_TOO_LONG != decodeResult) { return -1; }
decodeResult = preparePayload(testStr[2], payload, PAYLOAD_LEN);
if (ERR_INVALID_CHAR != decodeResult) { return -1; }
// here we are checking the character decoding
decodeResult = preparePayload(testStr[3], payload, 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, 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
}
}

最新更新