I'm having problems sending messages after using Protect J1939 Address in RP1210. If I don't protect the address, messages go through fine. But if I do, I get error 159 "Returned if blocking is used and the message was not sent." when calling "SendMessage". I'm confused by this error as according to the documentation, blocking is no longer supported by SendMessage and I'm passing 0 for blocking in any case.
Below is the code that reproduces this problem. Please note that I am using PCAN-USB X6 and channel 2 and 5 are wired together.
Code: Select all
#include <iostream>
#include <windows.h>
#include <vector>
#include <sstream>
#include "PEAK_RP1210.h"
// Connection
typedef short(__stdcall* fpRP1210_ClientConnect) (HWND, short, char*, long, long, short);
typedef short(__stdcall* fpRP1210_ClientDisconnect) (short);
// Configuration
typedef short(__stdcall* fpRP1210_SendCommand) (short, short, char*, short);
typedef short(__stdcall* fpRP1210_Ioctl) (short, long, void*, void*);
// Information
typedef void(__stdcall* fpRP1210_ReadVersion) (char*, char*, char*, char*);
typedef short(__stdcall* fpRP1210_ReadDetailedVersion) (short, char*, char*, char*);
typedef short(__stdcall* fpRP1210_GetErrorMsg) (short, char*);
typedef short(__stdcall* fpRP1210_GetLastErrorMsg) (short, int*, char*, short);
typedef short(__stdcall* fpRP1210_GetHardwareStatus) (short, char*, short, short);
// Communication
typedef short(__stdcall* fpRP1210_ReadMessage) (short, char*, short, short);
typedef short(__stdcall* fpRP1210_SendMessage) (short, char*, short, short, short);
HMODULE _dll = 0;
void ThrowFailure(const char* action, int code)
{
std::stringstream ss;
ss << action << " failed with: " << code;
throw std::exception(ss.str().c_str());
}
void SimpleTest()
{
std::cout << "Starting\n";
_dll = LoadLibraryA(DLL_NAME);
fpRP1210_ClientConnect fConnect = (fpRP1210_ClientConnect)GetProcAddress(_dll, "RP1210_ClientConnect");
fpRP1210_SendCommand fSendCommand = (fpRP1210_SendCommand)GetProcAddress(_dll, "RP1210_SendCommand");
fpRP1210_SendMessage fSendMessage = (fpRP1210_SendMessage)GetProcAddress(_dll, "RP1210_SendMessage");
fpRP1210_ReadMessage fReadMessage = (fpRP1210_ReadMessage)GetProcAddress(_dll, "RP1210_ReadMessage");
int deviceID = 1;
int noAutoPackageLargeMsg = 0;
int txBufferSize = 0;
int rcvBufferSize = 0;
int sendClientID = fConnect(0, deviceID, (char*)"J1939:Channel=2", txBufferSize, rcvBufferSize, noAutoPackageLargeMsg);
int result = fSendCommand(RPCMD_SET_ALL_FILTERS_STATES_TO_PASS, sendClientID, NULL, 0);
if (result != 0)
ThrowFailure("Set all filters to pass for sender", result);
// If this step is skipped, this works. But can't send longer messages
const unsigned char protectSender[] = { 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, BLOCK_UNTIL_DONE };
result = fSendCommand(RPCMD_PROTECT_J1939_ADDRESS, sendClientID, (char*)protectSender, sizeof(protectSender));
if(result > 0)
ThrowFailure("Protect Address sender", result);
int recvClientID = fConnect(0, deviceID, (char*)"J1939:Channel=5", txBufferSize, rcvBufferSize, noAutoPackageLargeMsg);
result = fSendCommand(RPCMD_SET_ALL_FILTERS_STATES_TO_PASS, recvClientID, NULL, 0);
if (result != 0)
ThrowFailure("Set all filters to pass for receiver", result);
const unsigned char protectReceiver[] = { 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xBB, BLOCK_UNTIL_DONE };
result = fSendCommand(RPCMD_PROTECT_J1939_ADDRESS, recvClientID, (char*)protectReceiver, sizeof(protectReceiver));
if (result > 0)
ThrowFailure("Protect Address receiver", result);
unsigned char sendData[] =
{
0x00, 0xB1, 0x00, // PGN = 00B100, Little endian, uses only 18 bits of the 24
0x08, // How = 80 (BAM and 0 Priority)
0x82, // Source
0xFF, // Destination (Broadcast)
0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, // Data
};
// ****** Error 159 happens here *******
// Error 157: J1939 client never issued a protect address.
// Happens if protect isn't called and msg is longer than 8 bytes
// Error 159: Returned if blocking is used and the message was not sent.
// Happens if protect is called under any condition
result = fSendMessage(sendClientID, (char*)sendData, sizeof(sendData), 0, 0);
if (result != 0)
ThrowFailure("Send Message", result);
std::cout << "Success\n";
}
int main()
{
try
{
SimpleTest();
return 0;
}
catch (std::exception& ex)
{
std::cout << ex.what();
}
catch (...)
{
std::cout << "Unknown error!";
}
return 1;
}
Todd