]> rtime.felk.cvut.cz Git - can-eth-gw.git/blob - ppc/cesend/cesend.c
PowerPC benchmark
[can-eth-gw.git] / ppc / cesend / cesend.c
1 /*
2  * cesend.c - simple command line tool to send CAN-frames via udp
3  * cesend is a fork of cansend from Socket-CAN project.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10
11 #include <net/if.h>
12 #include <sys/ioctl.h>
13 #include <arpa/inet.h>
14
15 #include <linux/can.h>
16 #include <linux/can/raw.h>
17
18 #define CANID_DELIM '#'
19 #define DATA_SEPERATOR '.'
20
21 unsigned char asc2nibble(char c) {
22
23         if ((c >= '0') && (c <= '9'))
24                 return c - '0';
25
26         if ((c >= 'A') && (c <= 'F'))
27                 return c - 'A' + 10;
28
29         if ((c >= 'a') && (c <= 'f'))
30                 return c - 'a' + 10;
31
32         return 16; /* error */
33 }
34
35 int parse_canframe(char *cs, struct can_frame *cf) {
36         /* documentation see lib.h */
37
38         int i, idx, dlc, len;
39         unsigned char tmp;
40
41         len = strlen(cs);
42         //printf("'%s' len %d\n", cs, len);
43
44         memset(cf, 0, sizeof(*cf)); /* init CAN frame, e.g. DLC = 0 */
45
46         if (len < 4)
47                 return 1;
48
49         if (cs[3] == CANID_DELIM) { /* 3 digits */
50
51                 idx = 4;
52                 for (i=0; i<3; i++){
53                         if ((tmp = asc2nibble(cs[i])) > 0x0F)
54                                 return 1;
55                         cf->can_id |= (tmp << (2-i)*4);
56                 }
57
58         } else if (cs[8] == CANID_DELIM) { /* 8 digits */
59
60                 idx = 9;
61                 for (i=0; i<8; i++){
62                         if ((tmp = asc2nibble(cs[i])) > 0x0F)
63                                 return 1;
64                         cf->can_id |= (tmp << (7-i)*4);
65                 }
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 */
68
69         } else
70                 return 1;
71
72         if((cs[idx] == 'R') || (cs[idx] == 'r')){ /* RTR frame */
73                 cf->can_id |= CAN_RTR_FLAG;
74                 return 0;
75         }
76
77         for (i=0, dlc=0; i<8; i++){
78
79                 if(cs[idx] == DATA_SEPERATOR) /* skip (optional) seperator */
80                         idx++;
81
82                 if(idx >= len) /* end of string => end of data */
83                         break;
84
85                 if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
86                         return 1;
87                 cf->data[i] = (tmp << 4);
88                 if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
89                         return 1;
90                 cf->data[i] |= tmp;
91                 dlc++;
92         }
93
94         cf->can_dlc = dlc;
95
96         return 0;
97 }
98
99 int main(int argc, char **argv)
100 {
101         int s; /* can raw socket */ 
102         int nbytes;
103         struct sockaddr_in addr;
104         struct can_frame frame;
105
106         /* check command line options */
107         if (argc != 2) {
108                 fprintf(stderr, "Usage: %s <can_frame>.\n", argv[0]);
109                 return 1;
110         }
111
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");
122                 return 1;
123         }
124
125         /* open socket */
126         if(( s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
127                 perror("socket");
128                 return 1;
129         }
130
131         addr.sin_family = AF_INET;
132         inet_aton( "192.168.2.3", &addr.sin_addr );
133         addr.sin_port = htons( 10501 );
134
135         /* send frame */
136         if ((nbytes = sendto(s, &frame, sizeof(frame), 0, (struct sockaddr*)&addr, sizeof(addr))) != sizeof(frame)) {
137                 perror("write");
138                 return 1;
139         }
140
141         close(s);
142
143         return 0;
144 }
145