0

仕事

candumpの独自の小型バージョンを書きたかったのです。目的は本質的に似ていますが、唯一の機能は、1 つの CAN ID からの着信メッセージのみを表示したいということです。

コード

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

int
main(void) {

    int s;
    int nbytes;
    struct sockaddr_can addr;
    struct can_frame frame;
    struct ifreq ifr;
//  struct can_filter *rfilter; // how do work?

    const char *ifname = "vcan0";

    if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
        perror("Error while opening socket");
        return -1;
    }

    strcpy(ifr.ifr_name, ifname);
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family  = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("Error in socket bind");
        return -2;
    }

    nbytes = read(s, &frame, sizeof(struct can_frame));

    if(nbytes < 0) {
        perror("Error reading from socket.\n");
        return 1;
    }

    while(1) {
        if(read(s, &frame, sizeof(struct can_frame)) > 0) {
            //printf("Message...\n");
            printf("%X - [len] - %X %X %X %X %X %X %X %X\n", frame.can_id,
                frame.data[0], frame.data[1], frame.data[2], frame.data[3], 
                frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
        }
    }

    close(s);

    return 0;
}

問題

コマンドでcansendを使用していcansend vcan0 18DA40F1#1234ます。私のコードを実行すると、返される応答は、CAN ID の最初の文字が 8+ 大きい値であることを除けば、ほぼそこにあります。応答98DA40F1 - [len] - 12 34 0 0 0 0 0 0コードの実行に戻りました。

前述の candump のソース コードを見ると、何か関係があると思いますがrfilter、100% 確信があるわけではなく、SocketCANのドキュメントを確認しても、それほど明確ではありません。マスキングと関係あるの?私の問題を解決する方法の例をいただければ幸いです。私が言及していないことがあれば、遠慮なく質問してください。

4

1 に答える 1