1. The PT_MQTT_WAIT_SEND() macro has several issues:
- It does not check the return value from process_post(), which
sometimes returns an error code. See next issue.
- Each time the macro is called, is posts an event to itself. The idea
seems to be that the event should be absorbed by the macro itself, so
when the macro terminates there is NOT a net growth of the event
queue. This does not work. The reason is that the
PROCESS_WAIT_EVENT() sometimes absorbs a broadcast event instead of
its own event, and then the number of events in the event queue
increases. This leads to event explosions and overflow in the event
queue.
- The macro cannot call PT_EXIT(). This will expand to a return
statement, causing a return from the function calling the macro
(mqtt_process), rather then exiting the protothread (which was
probably the intention). Protothreads have lexical scope...
Fixes: 1) Check return value from process_post() 2) Loop until the
event posted to itself is absorbed (rather than just absorbing the
next event) 3) Replace PT_EXIT() with PT_INIT() (doesn't really make a
difference, could probably just be removed).
2. Change order of the checks in the protothread-calling loops in
mqtt_process(). Reason: When a protothread has been cleared by
PT_MQTT_WAIT_SEND(), it will not return a value, so checking against
PT_EXITED does not make sense.
3. PT_MQTT_WRITE_BYTES() should initialize conn->out_write_pos to 0.
When PT_MQTT_WRITE_BYTES() does not finish (due to TCP disconnect for
instance), it may leave conn->out_write_pos with a non-zero
value. Next time PT_MQTT_WRITE_BYTES() is called, it will take data
from the wrong place.
4. Put MQTT_CONN_STATE_ABORT_IMMEDIATE before
MQTT_CONN_STATE_NOT_CONNECTED in the enum list, so that the check
if(conn->state > MQTT_CONN_STATE_NOT_CONNECTED) in mqtt_connect()
fails when in state MQTT_CONN_STATE_ABORT_IMMEDIATE. Otherwise, it
will deadlock and not reattempt connections while in this state.
The cc65 tool chain comes with V.24 drivers so it seems reasonable to use the existing Contiki SLIP driver to implement network access via SLIP as alternative to Ethernet.
Some notes:
- The Ethernet configuration was simplified in order to allow share it with SLIP.
- The Contiki SLIP driver presumes an interrupt driven serial receiver to write into the SLIP buffer. However the cc65 V.24 drivers aren't up to that. Therefore the main loops were extended to pull received data from the V.24 buffers and push it into the SLIP buffer.
- As far as I understand the serial sender is supposed to block until the data is sent. Therefore a loop calls the non-blocking V.24 driver until the data is sent.
On all platforms there's only one V.24 driver available. Therefore V.24 drivers are always loaded statically.
On the Apple][ the mouse driver is now loaded statically - independently from SLIP vs. Ethernet. After all there's only one mouse driver available. However there's a major benefit with SLIP: Here all drivers are loaded statically. Therefore the dynamic module loader isn't necessary at all. And without the loader the heap manager isn't necessary at all. This allows for a reduction in code size roughly compensating for the size of the SLIP buffer.