2 * cesend.c - simple command line tool to send CAN-frames via udp
3 * cesend is a fork of cansend from Socket-CAN project.
12 #include <sys/ioctl.h>
13 #include <arpa/inet.h>
15 #include <linux/can.h>
16 #include <linux/can/raw.h>
18 #define CANID_DELIM '#'
19 #define DATA_SEPERATOR '.'
21 unsigned char asc2nibble(char c) {
23 if ((c >= '0') && (c <= '9'))
26 if ((c >= 'A') && (c <= 'F'))
29 if ((c >= 'a') && (c <= 'f'))
32 return 16; /* error */
35 int parse_canframe(char *cs, struct can_frame *cf) {
36 /* documentation see lib.h */
42 //printf("'%s' len %d\n", cs, len);
44 memset(cf, 0, sizeof(*cf)); /* init CAN frame, e.g. DLC = 0 */
49 if (cs[3] == CANID_DELIM) { /* 3 digits */
53 if ((tmp = asc2nibble(cs[i])) > 0x0F)
55 cf->can_id |= (tmp << (2-i)*4);
58 } else if (cs[8] == CANID_DELIM) { /* 8 digits */
62 if ((tmp = asc2nibble(cs[i])) > 0x0F)
64 cf->can_id |= (tmp << (7-i)*4);
66 if (!(cf->can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe? */
67 cf->can_id |= CAN_EFF_FLAG; /* then it is an extended frame */
72 if((cs[idx] == 'R') || (cs[idx] == 'r')){ /* RTR frame */
73 cf->can_id |= CAN_RTR_FLAG;
77 for (i=0, dlc=0; i<8; i++){
79 if(cs[idx] == DATA_SEPERATOR) /* skip (optional) seperator */
82 if(idx >= len) /* end of string => end of data */
85 if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
87 cf->data[i] = (tmp << 4);
88 if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
99 int main(int argc, char **argv)
101 int s; /* can raw socket */
103 struct sockaddr_in addr;
104 struct can_frame frame;
106 /* check command line options */
108 fprintf(stderr, "Usage: %s <can_frame>.\n", argv[0]);
112 /* parse CAN frame */
113 if (parse_canframe(argv[1], &frame)){
114 fprintf(stderr, "\nWrong CAN-frame format!\n\n");
115 fprintf(stderr, "Try: <can_id>#{R|data}\n");
116 fprintf(stderr, "can_id can have 3 (SFF) or 8 (EFF) hex chars\n");
117 fprintf(stderr, "data has 0 to 8 hex-values that can (optionally)");
118 fprintf(stderr, " be seperated by '.'\n\n");
119 fprintf(stderr, "e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / ");
120 fprintf(stderr, "5AA# /\n 1F334455#1122334455667788 / 123#R ");
121 fprintf(stderr, "for remote transmission request.\n\n");
126 if(( s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
131 addr.sin_family = AF_INET;
132 inet_aton( "192.168.2.3", &addr.sin_addr );
133 addr.sin_port = htons( 10501 );
136 if ((nbytes = sendto(s, &frame, sizeof(frame), 0, (struct sockaddr*)&addr, sizeof(addr))) != sizeof(frame)) {