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