miyago

J1939-vcan

Apr 10th, 2020
1,140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.12 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5.  
  6. #include <stdint.h>
  7.  
  8. #include <net/if.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/socket.h>
  11.  
  12. #include <linux/can.h>
  13. #include <linux/can/raw.h>
  14. #include <linux/if.h>
  15. #include <errno.h>
  16.  
  17. #define FILTER_BC 0x00F00000                //83C
  18. #define MASK_BC   0x00FF0000                //3C
  19.  
  20. #define FILTER_CA 0x00002800
  21. #define MASK_CA   0x3C3FC00
  22. #define NODE_ID   0x0A
  23.  
  24. #define J_MASK_PGN 0x03FFFF00    
  25.  
  26.  
  27. void print_pdu_specifics(uint8_t j_pdu_format, uint8_t pdu_specific);
  28. void print_edp_dp(uint8_t edp_dp);
  29.  
  30. int main(int argc, char **argv)
  31. {
  32.     int s, i;
  33.     int nbytes;
  34.     struct sockaddr_can addr;
  35.  
  36.     // ifreq structure for configuring network device
  37.     struct ifreq ifr;
  38.     struct can_frame frame_receive;
  39.     struct can_frame frame_send;
  40.  
  41.  
  42.     if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
  43.         perror("Socket");
  44.         return 1;
  45.     }
  46.  
  47.     // Interface name
  48.     strcpy(ifr.ifr_name, "vcan0" );
  49.     // Get interface index
  50.     int ioctl_result = ioctl(s, SIOCGIFINDEX, &ifr);
  51.     if(ioctl_result < 0) {
  52.         perror("error with ioctl");
  53.         return 1;
  54.     } else {
  55.         printf("Interface index: [%d]\n", ifr.ifr_ifindex);
  56.     }
  57.  
  58.     memset(&addr, 0, sizeof(addr));
  59.     addr.can_family = AF_CAN;
  60.     addr.can_ifindex = ifr.ifr_ifindex;
  61.  
  62.  
  63.     if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
  64.         perror("Bind");
  65.         return 1;
  66.     }
  67.    
  68. //     struct can_filter sid_filter[2];
  69. //     sid_filter[0].can_id = 0x123;
  70. //     sid_filter[0].can_mask = (CAN_EFF_MASK | CAN_RTR_FLAG | CAN_SFF_MASK);
  71. //     sid_filter[1].can_id   = 0x12345678 | CAN_EFF_FLAG;
  72. //     sid_filter[1].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK);
  73. //    
  74. //     setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &sid_filter, sizeof(sid_filter));
  75.    
  76.    
  77.     int id, j_1939_pgn;
  78.     uint8_t j_edp_dp, j_pdu_format, j_pdu_specific;
  79.     while(1) {
  80.  
  81.         nbytes = read(s, &frame_receive, sizeof(struct can_frame));
  82.  
  83.         if (nbytes < 0) {
  84.             perror("Read");
  85.             return 1;
  86.         }
  87.        
  88.  
  89.         if(frame_receive.can_id & CAN_EFF_FLAG)
  90.         {
  91.             id = frame_receive.can_id & CAN_EFF_MASK;
  92.             printf("Extended ID: %08X DLC: %d\n", id, frame_receive.can_dlc);
  93.            
  94.             j_1939_pgn = id & J_MASK_PGN;
  95.             j_edp_dp = (j_1939_pgn & 0x03000000) >> 24;
  96.             j_pdu_format = (j_1939_pgn & 0x00FF0000) >> 16;
  97.             j_pdu_specific = (j_1939_pgn & 0x0000FF00) >> 8;
  98.            
  99.             printf("Message format J1939\n");
  100.             printf("PGN: %X\n", j_1939_pgn);
  101.             print_edp_dp(j_edp_dp);
  102.             printf("PDU Format: %X\n", j_pdu_format);
  103.             print_pdu_specifics(j_pdu_format, j_pdu_specific);
  104.            
  105.         } else {
  106.            id = frame_receive.can_id & CAN_SFF_MASK;
  107.             printf("Standard ID: %03X      DLC: %d", id, frame_receive.can_dlc);
  108.         }
  109.         if(frame_receive.can_id & CAN_RTR_FLAG)
  110.         {
  111.             printf("Received RTR frame! ");
  112.         }
  113.         if(frame_receive.can_id & CAN_ERR_FLAG)
  114.         {
  115.             printf("Received ERROR message frame! ");
  116.         }
  117.        
  118.        
  119.  
  120.         for (i = 0; i < frame_receive.can_dlc; i++) {
  121.             printf("%02X ",frame_receive.data[i]);
  122.         }
  123.         printf("\n----------------------------------");
  124.         printf("\r\n");
  125.     }
  126.     if (close(s) < 0) {
  127.         perror("Close");
  128.         return 1;
  129.     }
  130.  
  131.     return 0;
  132. }
  133.  
  134. void print_pdu_specifics(uint8_t j_pdu_format, uint8_t pdu_specific)
  135. {
  136.     if(j_pdu_format > 240){
  137.         printf("Broadcast message with group extension: %X\n", pdu_specific);
  138.     } else {
  139.         printf("Message with destination address: %X\n", pdu_specific);
  140.     }
  141. }
  142.  
  143. void print_edp_dp(uint8_t edp_dp)
  144. {
  145.     switch(edp_dp){
  146.         case 0: printf("SAE J1939 page 0 PGN\n"); break;
  147.         case 1: printf("SAE J1939 page 1 PGN\n"); break;
  148.         case 2: printf("SAE J1939 reserved\n"); break;
  149.         case 3: printf("ISO 15765-3 defined\n"); break;
  150.         default: break;
  151.     }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment