<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Greg,<br>
<br>
please do the same test including the OVMS log output at log level
verbose with can trace on.<br>
<br>
Additionally, when it hangs, please issue<br>
<br>
<tt>can can3 rx standard 7df 02 01 00 00 00 00 00 ff</tt><br>
<tt>can can3 status<br>
</tt><tt>can can3 tx standard 7e8 06 41 00 18 19 00 01 ff<br>
</tt><tt>can can3 status<br>
<br>
</tt>…still with wireshark capturing and without any restart of the
obd2ecu process.<br>
<br>
Thanks,<br>
Michael<br>
<br>
<br>
<div class="moz-cite-prefix">Am 13.01.2018 um 19:44 schrieb Greg D.:<br>
</div>
<blockquote type="cite"
cite="mid:0516dd3c-818f-4514-18ec-def8641321eb@gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Hi Michael,<br>
<br>
Much better. Crash is solved, but unfortunately when I remove the
delays in the obd2ecu application (marked with "temporary" in the
comments), the bus still hangs as before. Actually, slightly
worse, because I used to be able to get by if I turned off the VIN
reporting; now that hangs too. But it was working by the slimmest
of margin before, so it could also be just by luck.<br>
<br>
Wireshark trace of the interaction, attached. Turning off privacy
(so I should reply to the VIN request) results in the same trace,
so the bus is hanging right around that point. Notably, the
receive side is hung too (i.e. I never got the VIN request), and
counting frames (5 Rx, 7 Tx = 12), we can see the hang occurred
right after the ECU Name was sent (frame 12), and before the VIN
request (frame 13), which I never received.<br>
<br>
Frame 13 in the trace is where the OBDWiz dongle is requesting the
VIN. The bus is apparently hung at this point, so there is no
reply. The next frame is the dongle re-connecting with the OVMS
module after a timeout. The OBDWiz dongle retries the connect a
few more times, then gives up. <br>
<br>
'can can3 status' at this point is:<br>
<br>
<tt>OVMS > can can3 status</tt><tt><br>
</tt><tt>CAN: can3</tt><tt><br>
</tt><tt>Mode: Active</tt><tt><br>
</tt><tt>Speed: 500000</tt><tt><br>
</tt><tt>Rx pkt: 5</tt><tt><br>
</tt><tt>Rx err: 0</tt><tt><br>
</tt><tt>Rx ovrflw: 0</tt><tt><br>
</tt><tt>Tx pkt: 7</tt><tt><br>
</tt><tt>Tx delays: 0</tt><tt><br>
</tt><tt>Tx err: 0</tt><tt><br>
</tt><tt>Tx ovrflw: 0</tt><tt><br>
</tt><tt>Err flags: 0</tt><tt><br>
</tt><tt>OVMS > </tt><br>
<br>
If I stop and restart the obd2ecu task, I can re-create this same
sequence, so a close/open properly resets the chip/driver.<br>
<br>
Hope this helps. Let me know what else I can do.<br>
<br>
Greg<br>
<br>
<br>
<br>
<div class="moz-cite-prefix">Michael Balzer wrote:<br>
</div>
<blockquote type="cite"
cite="mid:01a06c5b-9421-0d9b-3244-d9a4e1aa4070@expeedo.de">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
Just added an additional fix for this.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div class="moz-cite-prefix">Am 13.01.2018 um 19:03 schrieb
Michael Balzer:<br>
</div>
<blockquote type="cite"
cite="mid:0aec6e8b-1f85-b4dd-af45-fe8217ad350d@expeedo.de">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
Please check again.<br>
<br>
Thanks,<br>
Michael<br>
<br>
<br>
<div class="moz-cite-prefix">Am 13.01.2018 um 18:42 schrieb
Greg D.:<br>
</div>
<blockquote type="cite"
cite="mid:24d452bf-1ce8-5263-7b43-5c5d6c3cc245@gmail.com">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
Gave it a quick try, and got a crash... I'll see if I can
isolate it a bit, but here's something to start with.
Tombstone, attached. <br>
<br>
Greg<br>
<br>
<br>
<br>
<br>
<div class="moz-cite-prefix">Geir Øyvind Vælidalo wrote:<br>
</div>
<blockquote type="cite"
cite="mid:40A285C5-B816-4B4D-9B4F-6A8277A051C9@validalo.net">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
I currently don’t send anything on can2. I could try to
send something, but the car is away this weekend :-(
<div class=""><br class="">
</div>
<div class="">Geir<br class="">
<div class=""><br class="">
<div><br class="">
<blockquote type="cite" class="">
<div class="">13. jan. 2018 kl. 17:24 skrev
Michael Balzer <<a
href="mailto:dexter@expeedo.de" class=""
moz-do-not-send="true">dexter@expeedo.de</a>>:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div text="#000000" bgcolor="#FFFFFF" class="">
Part one (TX queue) done & pushed.<br
class="">
<br class="">
<tt class="">OVMS > can can1 status </tt><tt
class=""><br class="">
</tt><tt class="">CAN: can1</tt><tt
class=""><br class="">
</tt><tt class="">Mode: Active</tt><tt
class=""><br class="">
</tt><tt class="">Speed: 500000</tt><tt
class=""><br class="">
</tt><tt class="">Rx pkt:
236657</tt><tt class=""><br class="">
</tt><tt class="">Rx
err: 1</tt><tt
class=""><br class="">
</tt><tt class="">Rx
ovrflw: 0</tt><tt
class=""><br class="">
</tt><tt class="">Tx pkt:
106378</tt><tt class=""><br class="">
</tt><tt class="">Tx
delays: 4</tt><tt
class=""><br class="">
</tt><tt class="">Tx
err: 0</tt><tt
class=""><br class="">
</tt><tt class="">Tx
ovrflw: 0</tt><tt
class=""><br class="">
</tt><tt class="">Err flags: 0x800caa</tt><tt
class=""><br class="">
</tt><br class="">
TX performance is rock steady on can1 -- the
delays occurred when sending the stop charge
request (as expected). I can't test can2/3,
Greg & Geir, could you…?<br class="">
<br class="">
The TxCallback can't be used on the mcp2515.
The ISR can't query the IRQ register, so the
TX IRQs are now also handled by the
RxCallback(). As the TX IRQs need to be
cleared before loading the next frame, this
needs another SPI call. I hope that doesn't
introduce new problems.<br class="">
<br class="">
<br class="">
No changes are necessary to the application
code (well, except you can remove any hard
coded delays now). The TX queue has a length
of 20 frames and will automatically be used by
the drivers when no TX buffers are free.<br
class="">
<br class="">
If an application wants to know whether a
frame was sent immediately or gets delayed it
can check the return code of the Write()
method. Write() now also can take a second
parameter for the maximum wait time for space
in the TX queue to become available if it's
full (default 0 = fail immediately if queue is
full).<br class="">
<br class="">
<br class="">
I also added logging of CAN errors. It's
currently activated by "can … trace on", I
don't think this needs to be active by
default, just for CAN issue debugging.<br
class="">
<br class="">
<tt class="">E (45718) can: Error can1 rxpkt=3
txpkt=0 errflags=0x800caa rxerr=1 txerr=0
rxovr=0 txovr=0 txdelay=0</tt><tt class=""><br
class="">
</tt><tt class="">E (83528) can: Error can1
rxpkt=7483 txpkt=226 errflags=0x800caa
rxerr=1 txerr=0 rxovr=0 txovr=0 txdelay=0</tt><br
class="">
<br class="">
…that's also a first part of the logging
extension (part two).<br class="">
<br class="">
Regards,<br class="">
Michael<br class="">
<br class="">
<br class="">
<div class="moz-cite-prefix">Am 12.01.2018 um
19:01 schrieb Michael Balzer:<br class="">
</div>
<blockquote type="cite"
cite="mid:357384bc-b854-bf66-3cc5-55344c2b7c38@expeedo.de"
class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"
class="">
Yes, I had something like that in mind. On
TX IRQ, the drivers send CAN_txcallbacks to
the CAN_rxtask. The CAN_rxtask then fetches
frames from the TX queue and calls the
TxCallback until all TX buffers of the
driver are full. From the already existing
TxCallback() stubs I suppose you had planned
a scheme like that already? ;)<br class="">
<br class="">
Greg, can you create a pull request for your
MCP2515 change? I'd like to merge that
before beginning on the drivers.<br class="">
<br class="">
Thanks,<br class="">
Michael<br class="">
<br class="">
<br class="">
<div class="moz-cite-prefix">Am 12.01.2018
um 01:19 schrieb Mark Webb-Johnson:<br
class="">
</div>
<blockquote type="cite"
cite="mid:EB2639C4-0BF3-40C7-ACED-4364F2BDD606@webb-johnson.net"
class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"
class="">
Option B sounds like a good approach.
<div class=""><br class="">
</div>
<div class="">Presumably we are just
polling the tx queue in the existing
CAN_rxtask based on TxCallback?</div>
<div class=""><br class="">
</div>
<div class="">Regards, Mark.<br class="">
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">On 11 Jan 2018, at
8:42 PM, Michael Balzer <<a
href="mailto:dexter@expeedo.de"
class="" moz-do-not-send="true">dexter@expeedo.de</a>>
wrote:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type"
content="text/html;
charset=utf-8" class="">
<div text="#000000"
bgcolor="#FFFFFF" class="">
<div class="moz-cite-prefix">Greg,
Mark,<br class="">
<br class="">
I can check your new code
after work.<br class="">
<br class="">
For the TX
performance/overflow issue,
there are basically two
options:<br class="">
<ul class="">
<li class="">A: make all
application TX be aware of
overflows, i.e. check the
return value of the CAN
Write() call as necessary
and/or introduce
sufficient delays (very
ugly)<br class="">
</li>
<li class="">B: add a TX
queue to the CAN
framework, so the
application can just push
some frames as fast as it
likes, with an option to
wait/block/fail if the
queue is full</li>
<ul class="">
<li class="">→ the
framework checks for TX
buffers becoming
available <b class="">(i.e.
driver issuing a
TxCallback request)</b>
and delivers queued
frames only as fast as
the driver can handle
them<br class="">
</li>
</ul>
</ul>
Option B has been on my todo
list since removing the delay
from the MCP driver and
introducing the TX buffer
check in the esp32can driver,
as I don't think applications
should need to handle TX
overflows.<br class="">
<br class="">
I can try to implement that
this weekend if it's urgent
now.<br class="">
<br class="">
Regards,<br class="">
Michael<br class="">
<br class="">
<br class="">
Am 11.01.2018 um 05:55 schrieb
Greg D.:<br class="">
</div>
<blockquote type="cite"
cite="mid:b229b09f-ef72-c564-7839-fa8a815157cd@gmail.com"
class="">
<meta
http-equiv="Content-Type"
content="text/html;
charset=utf-8" class="">
Hi Mark, Micheal,<br class="">
<br class="">
Ok, good news and bad news.<br
class="">
<br class="">
Good news: Rx problem I
believe is fixed. Return is
true only if we received
something, else false. And
the other interrupt conditions
are handled at the same time,
so no hangs are seen when
restarting wifi. Rx overflow
counter does increment
properly. Yea! Code has been
pushed to my clone on Github.<br
class="">
<br class="">
Bad news: I am still able to
hang the bus, but I think it's
on the transmit side. The
obd2ecu process can send up to
3 frames back to back to
report the ECU Name, followed
soon after by several more
with to grab the VIN. Without
any flow control on the
transmit side, and with a
half-duplex CAN bus, that's
just too much. Turning off
the VIN reporting (config set
obd2ecu private yes) seems to
let everything run because I
don't respond to the VIN
request (which lets everything
drain as OBDWiz times out).
Also verified by putting
temporary delays in the
obd2ecu code to let things
drain a bit between frames.
So, the transmit side is still
a bit fragile, depending on
timing. Not sure quite what
to do here, as there is no
easy place to queue things...
Do we need to go back to the
old way with a delay in the
obd2ecu code (perhaps better
than in the driver, no?).
Architecturally it's ugly, but
this only occurs at startup,
and I don't mind the kludge.
Do any other uses of the MCP
busses do a burst of
transmitting? If not, I'll
put the delays in the obd2ecu
code and call it close
enough. Lemme know.<br
class="">
<br class="">
For receive, I'd go with what
I have for now, if Michael
would be so kind as to review
what I have done first. <a
class="moz-txt-link-freetext"
href="https://github.com/bitsofgreg/Open-Vehicle-Monitoring-System-3/blob/master/vehicle/OVMS.V3/components/mcp2515/mcp2515.cpp"
moz-do-not-send="true">https://github.com/bitsofgreg/Open-Vehicle-Monitoring-System-3/blob/master/vehicle/OVMS.V3/components/mcp2515/mcp2515.cpp</a>
Hopefully he'll be back on
line before I get up in the
morning. Wonderful how the
Earth's spin helps with the
teamwork.<br class="">
<br class="">
I'll keep poking at things
tonight, and take it out for a
spin in the car tomorrow, just
to see everything working
together. But as it is now,
it's much better than it was
before. Really, this time.
:)<br class="">
<br class="">
Greg<br class="">
<br class="">
<br class="">
<div class="moz-cite-prefix">Greg
D. wrote:<br class="">
</div>
<blockquote type="cite"
cite="mid:e1ebf1b2-15e2-fa7b-92e1-6ed2a4972b63@gmail.com"
class="">
<meta
http-equiv="Content-Type"
content="text/html;
charset=utf-8" class="">
Hi Mark,<br class="">
<br class="">
I believe you are right
about the multiple flags,
and the code only processing
Rx and "error" separately.
Fundamentally, a roll-over
from buffer 0 to buffer 1
isn't really an error, just
a statement of fact on what
happened. So, we should
have buffer 1 and the
rollover flag at the same
time, which in fact is what
I saw. I need to handle the
Rx overflow at the same time
as the buffer 1 receive, I
think...<br class="">
<br class="">
I need to grab some dinner,
but have a fix in the
works. Will report back in
a few hours, hopefully with
good news...<br class="">
<br class="">
Greg<br class="">
<br class="">
<br class="">
<div class="moz-cite-prefix">Mark
Webb-Johnson wrote:<br
class="">
</div>
<blockquote type="cite"
cite="mid:E10D22FC-01E4-4976-8A90-EA916B9CE7F1@webb-johnson.net"
class="">
<meta
http-equiv="Content-Type"
content="text/html;
charset=utf-8" class="">
<div class=""><br class="">
</div>
The design of the system
is as follows:
<div class=""><br class="">
</div>
<div class="">
<ul class="MailOutline">
<li class="">The can
object CAN_rxtask
listens on the rx
queue to receive
instructional
messages from canbus
drivers. These can
be:</li>
<ul class="">
<li class="">CAN_frame:
simply passes an
entire incoming
can frame to the
IncomingFrame
handler.</li>
<li class="">CAN_rxcallback:
an instruction for
the CAN_rxtask to
call
the RxCallback
task repeatedly.</li>
<li class="">CAN_txcallback:
an instruction for
the CAN_rxtask to
call
the TxCallback
once.</li>
</ul>
<li class="">In the
case of
CAN_rxcallback, the
canbus object
RxCallback function
is expected to
return FALSE to
indicate nothing
should be done and
RxCallback should
not be called again,
or TRUE to indicate
an incoming frame
has been received
and should be passed
to IncomingFrame.</li>
<li class="">The
system is arranged
so that individual
bus driver interrupt
implementations can
be fast and
efficient.</li>
<ul class="">
<li class="">The
driver can choose
to receive the
frame in the
interrupt handler
itself, and pass
it with CAN_frame
to CAN_rxtask. The
esp32 can driver
uses this option.</li>
<li class="">Or the
driver can choose
to delay the
reception of the
frame to the
RxCallback stage,
and merely pass an
indication with
CAN_rxcallback.
The mcp2515 driver
uses this option.</li>
</ul>
<li class="">The
true/false response
from RxCallback is
designed to allow
the callback to
signal it received a
frame or not. If it
received a frame,
then it is called
again.</li>
<li class="">This
approach is used in
order to be able to
centralise the
reception of CAN
frames to one single
task (avoiding
having to run
individual tasks for
each canbus, hence
saving stack RAM).</li>
</ul>
<div class=""><br
class="">
</div>
<div class="">The
RxCallback should
definitely ONLY return
true if an actual can
message has been
received, and is being
passed back in the
frame pointer
parameter.</div>
<div class=""><br
class="">
</div>
<div class="">I suspect
the issue is that the
mcp2515 RxCallback is
being faced with
multiple error flags.
Changing that to a
return true (as Greg
has done) has the
undesired side-effect
of issuing a spurious
IncomingFrame (with
garbage/blank frame),
but also causes the
RxCallback to be
called again (clearing
the error flag).
Perhaps the solution
is to put a loop in
RxCallback so that if
an error condition is
found, it should be
cleared, but then loop
again and keep
clearing errors until
no more are found,
then return false? I
think that in the
mcp2515 case, this
error clearing loop
can be simply handled
in the RxCallback
itself.</div>
<div class=""><br
class="">
</div>
<div class="">The
alternative is to
change the RxCallback
logic so that the
return bool value
means simply ‘loop’
(call me again,
please), and have the
RxCallback itself
call IncomingFrame(),
rather than passing a
frame as a parameter.
If Michael/Greg think
this is a better
approach, I am happy
to make that change -
it is pretty trivial.</div>
<div class=""><br
class="">
</div>
<div class="">Regards,
Mark.</div>
<br class="">
</div>
</blockquote>
</blockquote>
</blockquote>
<br class="">
<pre class="moz-signature" cols="144">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
</div>
_______________________________________________<br class="">
OvmsDev mailing list<br class="">
<a
href="mailto:OvmsDev@lists.teslaclub.hk"
class="" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a><br
class="">
<a class="moz-txt-link-freetext"
href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev"
moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a><br
class="">
</div>
</blockquote>
</div>
<br class="">
</div>
<br class="">
<fieldset class="mimeAttachmentHeader"></fieldset>
<br class="">
<pre class="" wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br class="">
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
<br class="">
<fieldset class="mimeAttachmentHeader"></fieldset>
<br class="">
<pre class="" wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br class="">
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
</div>
_______________________________________________<br
class="">
OvmsDev mailing list<br class="">
<a href="mailto:OvmsDev@lists.teslaclub.hk"
class="" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a><br
class="">
<a class="moz-txt-link-freetext"
href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev"
moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a><br
class="">
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk" moz-do-not-send="true">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a>
<a class="moz-txt-link-freetext" href="http://lists.teslaclub.hk/mailman/listinfo/ovmsdev">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
</body>
</html>