RP1210 Protect J1939 Address and Send Message

RP1210 Development Package and RP1210 Connectivity to PEAK CAN Interfaces
Post Reply
ToddA
Posts: 1
Joined: Thu 21. Nov 2024, 08:42

RP1210 Protect J1939 Address and Send Message

Post by ToddA » Thu 6. Mar 2025, 16:19

Hello,
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;
}

Thanks,
Todd

K.Wagner
Software Development
Software Development
Posts: 1080
Joined: Wed 22. Sep 2010, 13:36

Re: RP1210 Protect J1939 Address and Send Message

Post by K.Wagner » Mon 10. Mar 2025, 17:22

Hello,

we answered you by Email.
Best regards,
Keneth

Post Reply