]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - doc/tpsocket.tex
Add kernel version depency for Kernel 3.1.x which extended __rtnl_register().
[socketcan-devel.git] / doc / tpsocket.tex
1 % $Id$
2
3 \newpage
4 \section{Sockets für Transport-Protokolle}
5 \label{tpsocket}
6
7 Die betrachteten CAN-Transport-Protokolle bilden auf dem CAN-Bus
8 auf zwei CAN-IDs eine virtuelle Punkt-zu-Punkt-Verbindung ab. Dazu
9 wird im Ersten der Acht in einem CAN-Frame vorhandenen Nutzbytes die
10 protokollspezifische Information übertragen, die das korrekte
11 Segmentieren von Nutzdaten gewährleistet. Die restlichen (maximal)
12 sieben Nutzbytes des CAN-Frames enthalten die segmentierten Nutzdaten.\\
13
14 Für die Transport-Protokolle TP1.6, TP2.0, etc. wird ein Socket vom
15 Typ SEQPACKET geöffnet unter Angabe des zu verwendenden Protokolls:
16
17 \begin{code}
18 s = socket(PF_CAN, SOCK_SEQPACKET, CAN_TP16);
19 s = socket(PF_CAN, SOCK_SEQPACKET, CAN_TP20);
20 s = socket(PF_CAN, SOCK_SEQPACKET, CAN_MCNET);
21 \end{code}
22
23    Protokollspezifische Parameter können nach dem Öffnen eines Sockets
24    mit \man{setsockopt}{2} und \man{getsockopt}{2} gesetzt bzw.
25    gelesen werden. Siehe dazu auch die protokollspezifischen Hinweise
26    am Ende dieses Kapitels ab Seite \pageref{tp20}.
27
28    Der Verbindungsaufbau erfolgt ähnlich wie mit TCP/IP-Sockets.  Der
29    wesentliche Unterschied besteht darin, dass ein Prozess, der auf
30    einen Verbindungsaufbau wartet, also die Rolle eines Servers
31    spielt, angeben muss, von welchem Client er Verbindungen annehmen
32    möchte, d.h. er muss die CAN-ID von CAN-Frames angeben, die er auf
33    diesem Socket empfangen möchte.  Zusätzlich muss er dem 
34    Socket-Layer gegenüber angeben, welche CAN-ID in den von ihm gesendeten
35    CAN-Frames zu verwenden ist.
36
37    Analog muss der Client beim Verbindungsaufbau nicht nur die CAN-ID
38    seines Kommunikationspartners, sondern auch seine eigene angeben.
39    Die bei \man{bind}{2} und \man{connect}{2} verwendeten
40    Strukturen vom Typ
41    \verb|struct sockaddr_can| enthalten daher im Gegensatz zu TCP/IP nicht
42    nur eine Adresse, sondern immer die "`Adressen"' beider
43    Kommunikationspartner.  Weil die CAN-Architektur kein Routing
44    anhand von netzweiten Adressen kennt, muss außerdem zusätzlich auch
45    immer das CAN-Interface angegeben werden, auf dem die Kommunikation
46    stattfinden soll.  Die Struktur ist daher folgendermaßen definiert:
47
48 \begin{code}
49 struct sockaddr_can {
50     sa_family_t   can_family;
51     int           can_ifindex;
52     union {
53         struct { canid_t rx_id, tx_id; } tp16;
54         struct { canid_t rx_id, tx_id; } tp20;
55         struct { canid_t rx_id, tx_id; } mcnet;
56     } can_addr;
57 };
58 \end{code}
59
60    Im Folgenden werden zwei kurze Code-Beispiele angegeben, die die
61    Verwendung von Sockets auf der Server- und der Client-Seite
62    verdeutlichen sollen.  Im Beispiel soll eine TP2.0-Verbindung
63    aufgebaut werden, wobei der Client die CAN-ID 0x740 und der Server
64    die CAN-ID 0x760 verwendet. Dieses Beispiel ist
65    dahingehend vereinfacht, dass auf eine Fehlerbehandlung verzichtet
66    wird. Eine mögliche Fehlerbehandlung ist aber in den
67    Beispielprogrammen in Kapitel \ref{tptestprogs} realisiert.
68
69 \begin{code}
70 /* This is the server code */
71
72 int s, n, nbytes, sizeofpeer=sizeof(struct sockaddr_can);
73 struct sockaddr_can addr, peer;
74 struct ifreq ifr;
75
76 s = socket(PF_CAN, SOCK_SEQPACKET, CAN_TP20);
77
78 addr.can_family = AF_CAN;
79 strcpy(ifr.ifr_name, "can0");
80 ioctl(s, SIOCGIFINDEX, &ifr);
81 addr.can_ifindex = ifr.ifr_ifindex;
82 addr.can_addr.tp20.tx_id  = 0x760;
83 addr.can_addr.tp20.rx_id  = 0x440;
84
85 bind(s, (struct sockaddr *)&addr, sizeof(addr));
86 listen(s, 1);
87
88 n = accept(s, (struct sockaddr *)&peer, sizeof(peer));
89
90 read(n, data, nbytes);
91 write(n, data, nbytes);
92
93 close(n);
94 close(s);
95
96
97
98
99 /* This is the client code */
100
101 int s, nbytes;
102 struct sockaddr_can addr;
103 struct ifreq ifr;
104
105 s = socket(PF_CAN, SOCK_SEQPACKET, CAN_TP20);
106
107 addr.can_family = AF_CAN;
108 strcpy(ifr.ifr_name, "can0");
109 ioctl(s, SIOCGIFINDEX, &ifr);
110 addr.can_ifindex = ifr.ifr_ifindex;
111 addr.can_addr.tp20.tx_id  = 0x440;
112 addr.can_addr.tp20.rx_id  = 0x760;
113
114 connect(s, (struct sockaddr *)&addr, sizeof(addr));
115
116 write(s, data, nbytes);
117 read(s, data, nbytes);
118
119 close(s);
120 \end{code}
121
122 \subsection{Tracemode}
123 \label{tracemode}
124
125 Wie schon beim RAW-Socket (Kapitel \ref{rawsocket}) besteht auch bei
126 den Transport-Protokoll-Sockets (TP-Sockets) die Möglichkeit über
127 \man{setsockopt}{2} die Eigenschaften des Sockets zu
128 beeinflussen. Diese sind zumeist spezifisch für das jeweilige
129 Protokoll. Beim \LL\ besteht die bisher in allen
130 Transportprotokollen realisierte Möglichkeit, die TP-Sockets mit der
131 Socketoption \verb+TRACE_MODE+ in einen Nur-Lese-Modus zu schalten,
132 bei dem der empfangene, segmentierte Datenstrom zusammengesetzt wird,
133 ohne dem Sender Bestätigungen zu senden. Für das Mitschneiden einer
134 bi-direktionalen Verbindung müssen daher zwei Sockets mit 'verdrehten'
135 CAN-IDs \verb+tx_id+ und \verb+rx_id+ geöffnet werden.\\
136
137 Vereinfachtes Beispiel (ohne Fehlerbehandlung) aus einer älteren
138 Version vom Testprogramm \verb+mcnet-sniffer.c+:
139
140 \begin{code}
141 int s, t;
142 struct sockaddr_can addr1, addr2;
143 struct can_mcnet_options opts;
144
145 s = socket(PF_CAN, SOCK_SEQPACKET, CAN_MCNET);
146 t = socket(PF_CAN, SOCK_SEQPACKET, CAN_MCNET);
147
148 opts.blocksize = 15;
149 opts.config = TRACE_MODE;
150 setsockopt(s, SOL_CAN_MCNET, CAN_MCNET_OPT, &opts, sizeof(opts));
151 setsockopt(t, SOL_CAN_MCNET, CAN_MCNET_OPT, &opts, sizeof(opts));
152
153 addr1.can_family = AF_CAN;
154 strcpy(ifr.ifr_name, "can0");
155 ioctl(s, SIOCGIFINDEX, &ifr);
156 addr1.can_ifindex = ifr.ifr_ifindex;
157 addr1.can_tx_id  = 0x248;
158 addr1.can_rx_id  = 0x448;
159
160 addr2.can_family = AF_CAN;
161 addr2.can_ifindex = ifr.ifr_ifindex; /* also can0 */
162 addr2.can_tx_id  = 0x448;
163 addr2.can_rx_id  = 0x248;
164
165 connect(s, (struct sockaddr *)&addr1, sizeof(addr1));
166 connect(t, (struct sockaddr *)&addr2, sizeof(addr2));
167
168 (..)
169 \end{code}
170
171 Mit \man{select}{2} kann nun auf beiden Sockets auf eintreffende Daten
172 ressourcenschonend gewartet werden.
173
174 \subsection{Besonderheiten des VAG TP1.6}
175 \label{tp16}
176
177 Das VAG Transportprotokoll TP1.6 besitzt 6 konfigurierbare
178 Parameter, die mit \man{setsockopt}{2} gesetzt werden können.
179 Dazu gehören die Timer T1 bis T4, die Blocksize und ein
180 Konfigurationswert, der z.B. angibt, ob ein Kommunikationskanal nach
181 einer bestimmten Zeit automatisch geschlossen werden soll oder
182 nicht. Diese Parameter können beispielsweise wie folgt gesetzt werden:
183
184 \begin{code}
185 struct can_tp16_options opts;
186
187 opts.t1.tv_sec       = 0; /* ACK timeout 100ms */ 
188 opts.t1.tv_usec      = 100000;
189 opts.t2.tv_sec       = 0; /* unused */
190 opts.t3.tv_sec       = 0; /* transmit delay 10ms */ 
191 opts.t3.tv_usec      = 10000;
192 opts.t4.tv_sec       = TP16_T4_DISABLED; /* disabled */
193 opts.blocksize       = 11;
194
195 opts.config = USE_DISCONNECT | HALF_DUPLEX | ENABLE_BREAK;
196
197 setsockopt(s, SOL_CAN_TP16, CAN_TP16_OPT, &opts, sizeof(opts));
198 \end{code}
199
200 Die für das Transportprotokoll TP1.6 relevanten Optionen finden
201 sich in den Dateien \verb+tp16.h+ und \verb+tp_conf.h+.\\
202
203 Die Struktur \verb+can_tp16_options+ ist definiert als
204 \begin{code}
205 struct can_tp16_options {
206
207   struct timeval t1;       /* ACK timeout for DT TPDU. VAG: T1 */
208   struct timeval t2;       /* max. time between two DT TPDU's. VAG: T2 (NOT IMPLEMENTED!) */
209   struct timeval t3;       /* transmit delay for DT TPDU's. VAG: T3 */
210   struct timeval t4;       /* receive timeout for automatic disconnect. VAG: T4 */
211
212   unsigned char blocksize; /* max number of unacknowledged DT TPDU's (1 ..15) */
213   unsigned int  config;    /* analogue tp_user_data.conf see tp_gen.h */
214
215 };
216 \end{code}
217
218 Die bei \man{setsockopt}{2} für VAG TP1.6 gesetzten Werte werden dem
219 Kommunikationspartner im Rahmen des Channel-Setup (CS/CA) mitgeteilt
220 und beeinflussen somit ausschließlich die Kommunikationsparameter des
221 Kommunikationspartners.
222
223 Eine weitere Besonderheit beim VAG TP1.6 ist der 'dynamische
224 Kanalaufbau', bei dem vor der eigentlichen Kommunikation die
225 CAN-Identifier für den Transportkanal ermittelt werden. Dabei
226 existieren auch zeitliche Anforderungen, die eine maximale Zeitspanne
227 zwischen dem Aushandeln der Identifier und der Eröffnung des
228 Transportkanals festlegen. Siehe dazu auch die Hinweise zur Variablen
229 \verb+PROBE+ in Kapitel \ref{probe}.\\
230
231 Entgegen bisherigen Implementierungen unterstützt diese Realisierung für
232 das \LLCF\ die dynamische Identifiervergabe nicht im Rahmen der
233 TP2.0-Implementierung. Übertragen auf die IT-Welt entspräche eine
234 solche Implementierung der Integration des Domain-Name-Service in das
235 IP-Protokoll. Das o.g. Verfahren wird im \LL\ über Broadcastnachrichten
236 auf der Benutzerebene realisiert. Siehe dazu die protokollspezifischen
237 Testprogramme in Kapitel \ref{tptestprogs}.
238
239 \subsection{Besonderheiten des VAG TP2.0}
240 \label{tp20}
241
242 Das VAG Transportprotokoll TP2.0 besitzt 6 konfigurierbare
243 Parameter, die mit \man{setsockopt}{2} gesetzt werden können.
244 Dazu gehören die Timer T1 bis T4, die Blocksize und ein
245 Konfigurationswert, der z.B. angibt, ob ein regelmäßiger Connection Test durchgeführt
246 werden soll oder nicht. Diese Parameter können beispielsweise wie folgt gesetzt
247 werden:
248
249 \begin{code}
250 struct can_tp20_options opts;
251
252 opts.t1.tv_sec       = 0; /* ACK timeout 100ms */ 
253 opts.t1.tv_usec      = 100000;
254 opts.t2.tv_sec       = 0; /* unused */
255 opts.t3.tv_sec       = 0; /* transmit delay 10ms */ 
256 opts.t3.tv_usec      = 10000;
257 opts.t4.tv_sec       = 0; /* unused */
258 opts.blocksize       = 11;
259 opts.config = USE_CONNECTIONTEST | USE_DISCONNECT | ENABLE_BREAK;
260
261 setsockopt(s, SOL_CAN_TP20, CAN_TP20_OPT, &opts, sizeof(opts));
262 \end{code}
263
264 Die für das Transportprotokoll TP2.0 relevanten Optionen finden
265 sich in den Dateien \verb+tp20.h+ und \verb+tp_conf.h+.\\
266
267 Die Struktur \verb+can_tp20_options+ ist definiert als
268 \begin{code}
269 struct can_tp20_options {
270
271   struct timeval t1;       /* ACK timeout for DT TPDU. VAG: T1 */
272   struct timeval t2;       /* unused */
273   struct timeval t3;       /* transmit delay for DT TPDU's. VAG: T3 */
274   struct timeval t4;       /* unused */
275
276   unsigned char blocksize; /* max number of unacknowledged DT TPDU's (1 ..15) */
277   unsigned int  config;    /* analogue tp_user_data.conf see tp_gen.h */
278
279 };
280 \end{code}
281
282 Die bei \man{setsockopt}{2} für VAG TP2.0 gesetzten Werte werden dem
283 Kommunikationspartner im Rahmen des Channel-Setup (CS/CA) mitgeteilt
284 und beeinflussen somit ausschließlich die Kommunikationsparameter des
285 Kommunikationspartners.
286
287 Eine weitere Besonderheit beim VAG TP2.0 ist der 'dynamische
288 Kanalaufbau', bei dem vor der eigentlichen Kommunikation die
289 CAN-Identifier für den Transportkanal ermittelt werden. Dabei
290 existieren auch zeitliche Anforderungen, die eine maximale Zeitspanne
291 zwischen dem Aushandeln der Identifier und der Eröffnung des
292 Transportkanals festlegen. Siehe dazu auch die Hinweise zur Variablen
293 \verb+PROBE+ in Kapitel \ref{probe}.\\
294
295 Entgegen bisherigen Implementierungen unterstützt diese Realisierung für
296 das \LLCF\ die dynamische Identifiervergabe nicht im Rahmen der
297 TP2.0-Implementierung. Übertragen auf die IT-Welt entspräche eine
298 solche Implementierung der Integration des Domain-Name-Service in das
299 IP-Protokoll. Das o.g. Verfahren wird im \LL\ über Broadcastnachrichten
300 auf der Benutzerebene realisiert. Siehe dazu die protokollspezifischen
301 Testprogramme in Kapitel \ref{tptestprogs}.
302
303 \subsection{Besonderheiten des Bosch MCNet}
304 \label{mcnet}
305
306 Das Transportprotokoll MCNet besitzt 3 konfigurierbare
307 Parameter, die mit \man{setsockopt}{2} gesetzt werden können.
308 Dazu gehören die Blocksize und ein Konfigurationswert, der
309 z.B. angibt, ob ein regelmäßiger Connection Test durchgeführt 
310 werden soll oder nicht. Diese Parameter können beispielsweise wie folgt gesetzt
311 werden:
312
313 \begin{code}
314 struct can_mcnet_options opts;
315
316 opts.blocksize  = 11;
317 opts.td.tv_sec  = 0; /* no transmit delay */
318 opts.td.tv_usec = 0;
319 opts.config     = USE_CONNECTIONTEST;
320
321 setsockopt(s, SOL_CAN_MCNET, CAN_MCNET_OPT, &opts, sizeof(opts));
322 \end{code}
323
324 Die für das Transportprotokoll MCNet relevanten Optionen finden
325 sich in den Dateien \verb+mcnet.h+ und \verb+tp_conf.h+.\\
326
327 Die Struktur \verb+can_mcnet_options+ ist definiert als
328 \begin{code}
329 struct can_mcnet_options {
330
331   unsigned char blocksize; /* max number of unacknowledged DT TPDU's (1 ..15) */
332   struct timeval td;       /* transmit delay for DT TPDU's */
333   unsigned int  config;    /* analogue tp_user_data.conf see tp_gen.h */
334
335 };
336 \end{code}
337
338 Die bei \man{setsockopt}{2} für MCNet gesetzten Werte beeinflussen die
339 lokalen Kommunikationsparameter.
340
341 \subsection{ISO-Transportprotokoll}
342 \label{isotp}
343 Eine Implementierung des CAN-Transportprotokolls nach ISO/DIS 15765
344 ist in Arbeit und wird unter BSD/GPL-Lizenz von Volkswagen zur
345 Verfügung gestellt werden.
346
347 \subsection{Testprogramme}
348 \label{tptestprogs}
349 \begin{description}
350 \item[tp16-client] ist ein Programm, dass aktiv eine TP1.6 Verbindung
351 eröffnet und dann Daten sendet und empfängt. Es wird auch gezeigt wie
352 man mit Hilfe des \BCM\ die dynamische Kanaleröffnung des TP1.6-Clients
353 mit dem \LL\ realisiert.
354 \item[tp16-server] ist ein Programm, dass passiv auf eine von einem
355 \verb+tp16-client+ zu initiierende TP1.6 Verbindung wartet und dann
356 Daten empfängt und zurücksendet. Es wird auch gezeigt wie
357 man mit Hilfe des RAW-Sockets die dynamische
358 Kanaleröffnung eines TP1.6-Servers mit dem \LL\ realisiert.
359 \item[tp20-client] ist ein Programm, dass aktiv eine TP2.0 Verbindung
360 eröffnet und dann Daten sendet und empfängt. Es wird auch gezeigt wie
361 man mit Hilfe des \BCM\ die dynamische Kanaleröffnung des TP2.0-Clients
362 mit dem \LL\ realisiert.
363 \item[tp20-server] ist ein Programm, dass passiv auf eine von einem
364 \verb+tp20-client+ zu initiierende TP2.0 Verbindung wartet und dann
365 Daten empfängt und zurücksendet. Es wird auch gezeigt wie
366 man mit Hilfe des RAW-Sockets die dynamische
367 Kanaleröffnung eines TP2.0-Servers mit dem \LL\ realisiert.
368 \item[tp20-sniffer] ist ein Programm, mit dem man eine
369 TP2.0-Verbindung mitlesen kann (siehe Tracemode-Beschreibung in
370 Kapitel \ref{tracemode}). Anhand der Kommandozeilen-Parameter kann man
371 dabei konkrete CAN-IDs oder auch logische Gerätenummern zur Bestimmung
372 der mitzulesenden TP-Kanals angeben.
373 \item[mcnet-sniffer] ist ein Programm, mit dem man eine
374 MCNet-Verbindung mitlesen kann (siehe Tracemode-Beschreibung in
375 Kapitel \ref{tracemode}).
376 \item[mcnet-vit-emu] ist ein Programm, mit dem ein MCNet-TV-Tuner
377 emuliert werden kann. Angeschlossen an den CAN-Bus eines
378 Volkswagen RNS MFD (altes 2DIN-Gerät) wird hier die Kommunikation
379 nachgebildet, die ein TV-Tuner mit dem Bedienteil durchführt, wodurch
380 die Tasteninformationen zur Bedienung des TV-Tuners ausgelesen werden
381 können.
382 \end{description}