Skip to content

Commit 0892761

Browse files
committed
1 parent 150fc50 commit 0892761

2 files changed

Lines changed: 282 additions & 0 deletions

File tree

can_transmit.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#define _DEFAULT_SOURCE
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.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+
15+
int main(int argc, char **argv)
16+
{
17+
int fdSocketCAN;
18+
struct sockaddr_can addr;
19+
struct ifreq ifr;
20+
struct can_frame frame;
21+
int option;
22+
/*
23+
La première étape est de créer un socket.
24+
Cette fonction accepte trois paramètres :
25+
domaine/famille de protocoles (PF_CAN),
26+
type de socket (raw ou datagram) et
27+
protocole de socket.
28+
la fonction retourne un descripteur de fichier.
29+
*/
30+
if ((fdSocketCAN = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
31+
perror("Socket");
32+
return -1;
33+
}
34+
35+
/*
36+
Ensuite, récupérer l'index de l'interface pour le nom de l'interface (can0, can1, vcan0, etc.)
37+
que nous souhaitons utiliser. Envoyer un appel de contrôle d'entrée/sortie et
38+
passer une structure ifreq contenant le nom de l'interface
39+
*/
40+
if(argc == 2)
41+
strcpy(ifr.ifr_name, argv[1]);
42+
else strcpy(ifr.ifr_name, "vcan0" );
43+
44+
ioctl(fdSocketCAN, SIOCGIFINDEX, &ifr);
45+
/* Alternativement, zéro comme index d'interface, permet de récupérer les paquets de toutes les interfaces CAN.
46+
Avec l'index de l'interface, maintenant lier le socket à l'interface CAN
47+
*/
48+
49+
/*
50+
51+
*/
52+
memset(&addr, 0, sizeof(addr));
53+
addr.can_family = AF_CAN;
54+
addr.can_ifindex = ifr.ifr_ifindex;
55+
56+
if (bind(fdSocketCAN, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
57+
perror("Bind");
58+
return -1;
59+
}
60+
frame.can_id = 0x145;
61+
frame.can_dlc = 7;
62+
63+
while (1)
64+
{
65+
printf("\n=== Menu ===\n");
66+
printf("1. Envoyer un message CAN\n");
67+
printf("2. Quitter\n");
68+
printf("Choix : ");
69+
scanf("%d", &option);
70+
if(option == 1)
71+
{
72+
// Préparation des données (exemple arbitraire)
73+
for (int i = 0; i < frame.can_dlc; i++)
74+
{
75+
frame.data[i] = i;
76+
}
77+
78+
// Envoi du message CAN
79+
int nbytes = write(fdSocketCAN, &frame, sizeof(struct can_frame));
80+
if (nbytes < 0)
81+
{
82+
perror("Erreur lors de l'envoi du message CAN");
83+
}
84+
else
85+
{
86+
printf("[Père] Message CAN envoyé : ID=0x%X, Data= ", frame.can_id);
87+
for (int i = 0; i < frame.can_dlc; i++)
88+
{
89+
printf("%02X ", frame.data[i]);
90+
}
91+
printf("\n");
92+
}
93+
}
94+
else if (option == 2)
95+
{
96+
printf("Arrêt du programme.\n");
97+
break;
98+
option = 0 ;
99+
}
100+
}
101+
close(fdSocketCAN);
102+
}

processus_can.c

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#define _DEFAULT_SOURCE
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <unistd.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+
15+
#include <signal.h>
16+
17+
void vCanReceive(int fdSocketCAN, struct can_frame frame);
18+
void vCantransmit(int fdSocketCAN, struct can_frame frame, pid_t pid);
19+
20+
int main(int argc, char **argv)
21+
{
22+
int fdSocketCAN;
23+
struct sockaddr_can addr;
24+
struct ifreq ifr;
25+
struct can_frame frame;
26+
27+
/*
28+
La première étape est de créer un socket.
29+
Cette fonction accepte trois paramètres :
30+
domaine/famille de protocoles (PF_CAN),
31+
type de socket (raw ou datagram) et
32+
protocole de socket.
33+
la fonction retourne un descripteur de fichier.
34+
*/
35+
if ((fdSocketCAN = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
36+
perror("Socket");
37+
return -1;
38+
}
39+
40+
/*
41+
Ensuite, récupérer l'index de l'interface pour le nom de l'interface (can0, can1, vcan0, etc.)
42+
que nous souhaitons utiliser. Envoyer un appel de contrôle d'entrée/sortie et
43+
passer une structure ifreq contenant le nom de l'interface
44+
*/
45+
if(argc == 2)
46+
strcpy(ifr.ifr_name, argv[1]);
47+
else strcpy(ifr.ifr_name, "vcan0" );
48+
49+
ioctl(fdSocketCAN, SIOCGIFINDEX, &ifr);
50+
/* Alternativement, zéro comme index d'interface, permet de récupérer les paquets de toutes les interfaces CAN.
51+
Avec l'index de l'interface, maintenant lier le socket à l'interface CAN
52+
*/
53+
54+
/*
55+
56+
*/
57+
memset(&addr, 0, sizeof(addr));
58+
addr.can_family = AF_CAN;
59+
addr.can_ifindex = ifr.ifr_ifindex;
60+
61+
if (bind(fdSocketCAN, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
62+
perror("Bind");
63+
return -1;
64+
}
65+
66+
pid_t pid = fork();
67+
if(pid <0)
68+
{
69+
perror("Erreur lors de la création du processus fils");
70+
}
71+
72+
if(pid == 0)
73+
{
74+
vCanReceive(fdSocketCAN, frame);
75+
close(fdSocketCAN);
76+
exit(EXIT_SUCCESS);
77+
}
78+
else
79+
{
80+
vCantransmit(fdSocketCAN, frame, pid);
81+
//kill(pid, SIGKILL); // Terminer le processus fils
82+
//close(fdSocketCAN);
83+
}
84+
return 0 ;
85+
}
86+
87+
void vCanReceive(int fdSocketCAN, struct can_frame frame)
88+
{
89+
int nbytes, i;
90+
nbytes = read(fdSocketCAN, &frame, sizeof(struct can_frame));
91+
92+
if (nbytes < 0)
93+
{
94+
perror("Read");
95+
//return -1;
96+
}
97+
printf("Je suis le processus, voici ce que je reçois: \r");
98+
printf("0x%03X [%d] ",frame.can_id, frame.can_dlc);
99+
for (i = 0; i < frame.can_dlc; i++)
100+
printf("%02X ",frame.data[i]);
101+
printf("\r\n");
102+
103+
if (close(fdSocketCAN) < 0)
104+
{
105+
perror("Close");
106+
//return -1;
107+
}
108+
}
109+
110+
void vCantransmit(int fdSocketCAN, struct can_frame frame, pid_t pid)
111+
{
112+
frame.can_id = 0x145;
113+
frame.can_dlc = 7;
114+
int option;
115+
while (1)
116+
{
117+
printf("\n=== Menu ===\n");
118+
printf("1. Envoyer un message CAN\n");
119+
printf("2. Quitter\n");
120+
printf("Choix : ");
121+
scanf("%d", &option);
122+
if(option == 1)
123+
{
124+
// Préparation des données (exemple arbitraire)
125+
for (int i = 0; i < frame.can_dlc; i++)
126+
{
127+
frame.data[i] = getchar();
128+
}
129+
130+
// Envoi du message CAN
131+
int nbytes = write(fdSocketCAN, &frame, sizeof(struct can_frame));
132+
if (nbytes < 0)
133+
{
134+
perror("Erreur lors de l'envoi du message CAN");
135+
}
136+
else
137+
{
138+
printf("[Père] Message CAN envoyé : ID=0x%X, Data= ", frame.can_id);
139+
for (int i = 0; i < frame.can_dlc; i++)
140+
{
141+
printf("%02X ", frame.data[i]);
142+
}
143+
printf("\n");
144+
}
145+
//printf("Je suis le processus père, voici ce que j'envoie \r");
146+
/*
147+
Envoyer une trame CAN, initialiser une structure can_frame et la remplir avec des données.
148+
La structure can_frame de base est définie dans include/linux/can.h
149+
*/
150+
//frame.can_id = 0x145; // identifiant CAN, exemple: 247 = 0x0F7
151+
//frame.can_dlc = 7; // nombre d'octets de données
152+
//sprintf(frame.data, "616-TGE"); // données
153+
154+
//if (write(fdSocketCAN, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame))
155+
//{
156+
// perror("Write");
157+
//return -1;
158+
// }
159+
160+
// if (close(fdSocketCAN) < 0)
161+
//{
162+
//perror("Close");
163+
//return -1;
164+
//}
165+
}
166+
else if (option == 2)
167+
{
168+
printf("Arrêt du programme.\n");
169+
kill(pid, SIGKILL); // Terminer le processus fils
170+
option = 0;
171+
break;
172+
}
173+
else
174+
{
175+
printf("Option invalide, veuillez réessayer.\n");
176+
}
177+
}
178+
close(fdSocketCAN);
179+
180+
}

0 commit comments

Comments
 (0)