diff --git a/conf/modules/booz_extra_dl.xml b/conf/modules/booz_extra_dl.xml
new file mode 100644
index 0000000000..4fb4cddd9e
--- /dev/null
+++ b/conf/modules/booz_extra_dl.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sw/airborne/modules/core/extra_pprz_dl.c b/sw/airborne/modules/core/extra_pprz_dl.c
new file mode 100644
index 0000000000..9205a9c22c
--- /dev/null
+++ b/sw/airborne/modules/core/extra_pprz_dl.c
@@ -0,0 +1,33 @@
+/*
+ * Paparazzi mcu0 $Id: pprz_transport.c 929 2006-06-02 12:11:37Z poine $
+ *
+ * Copyright (C) 2006 Pascal Brisset, Antoine Drouin
+ * Copyright (C) 2010 ENAC
+ *
+ * This file is part of paparazzi.
+ *
+ * paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include
+#include "extra_pprz_dl.h"
+#include "uart.h"
+
+volatile bool_t extra_pprz_msg_received = FALSE;
+uint8_t extra_pprz_ovrn, extra_pprz_error;
+volatile uint8_t extra_pprz_payload_len;
+uint8_t extra_pprz_payload[PPRZ_PAYLOAD_LEN];
diff --git a/sw/airborne/modules/core/extra_pprz_dl.h b/sw/airborne/modules/core/extra_pprz_dl.h
new file mode 100644
index 0000000000..255c3d650c
--- /dev/null
+++ b/sw/airborne/modules/core/extra_pprz_dl.h
@@ -0,0 +1,226 @@
+/*
+ * Paparazzi $Id: pprz_transport.h 4870 2010-04-24 03:02:39Z poine $
+ *
+ * Copyright (C) 2010 ENAC
+ *
+ * This file is part of paparazzi.
+ *
+ * paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/** \file pprz_transport.h
+ * \brief Extra datalink using PPRZ protocol
+ *
+ * Pprz frame:
+ *
+ * |STX|length|... payload=(length-4) bytes ...|Checksum A|Checksum B|
+ *
+ * where checksum is computed over length and payload:
+ * ck_A = ck_B = length
+ * for each byte b in payload
+ * ck_A += b; ck_b += ck_A
+ */
+
+#ifndef EXTRA_PPRZ_DL_H
+#define EXTRA_PPRZ_DL_H
+
+#include "pprz_transport.h"
+
+#define __ExtraLink(dev, _x) dev##_x
+#define _ExtraLink(dev, _x) __ExtraLink(dev, _x)
+#define ExtraLink(_x) _ExtraLink(EXTRA_DOWNLINK_DEVICE, _x)
+
+/** 4 = STX + len + ck_a + ck_b */
+#define ExtraPprzTransportSizeOf(_payload) (_payload+4)
+
+#define ExtraPprzTransportCheckFreeSpace(_x) ExtraLink(CheckFreeSpace(_x))
+
+#define ExtraPprzTransportPut1Byte(_x) ExtraLink(Transmit(_x))
+#define ExtraPprzTransportSendMessage() ExtraLink(SendMessage())
+
+#define ExtraPprzTransportHeader(payload_len) { \
+ ExtraPprzTransportPut1Byte(STX); \
+ uint8_t msg_len = ExtraPprzTransportSizeOf(payload_len); \
+ ExtraPprzTransportPut1Byte(msg_len); \
+ ck_a = msg_len; ck_b = msg_len; \
+}
+
+#define ExtraPprzTransportTrailer() { \
+ ExtraPprzTransportPut1Byte(ck_a); \
+ ExtraPprzTransportPut1Byte(ck_b); \
+ ExtraPprzTransportSendMessage() \
+}
+
+#define ExtraPprzTransportPutUint8(_byte) { \
+ ck_a += _byte; \
+ ck_b += ck_a; \
+ ExtraPprzTransportPut1Byte(_byte); \
+ }
+
+#define ExtraPprzTransportPutNamedUint8(_name, _byte) ExtraPprzTransportPutUint8(_byte)
+
+#define ExtraPprzTransportPut1ByteByAddr(_byte) { \
+ uint8_t _x = *(_byte); \
+ ExtraPprzTransportPutUint8(_x); \
+ }
+
+#define ExtraPprzTransportPut2ByteByAddr(_byte) { \
+ ExtraPprzTransportPut1ByteByAddr(_byte); \
+ ExtraPprzTransportPut1ByteByAddr((const uint8_t*)_byte+1); \
+ }
+
+#define ExtraPprzTransportPut4ByteByAddr(_byte) { \
+ ExtraPprzTransportPut2ByteByAddr(_byte); \
+ ExtraPprzTransportPut2ByteByAddr((const uint8_t*)_byte+2); \
+ }
+
+#ifdef __IEEE_BIG_ENDIAN /* From machine/ieeefp.h */
+#define ExtraPprzTransportPutDoubleByAddr(_byte) { \
+ ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_byte+4); \
+ ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_byte); \
+ }
+#else
+#define ExtraPprzTransportPutDoubleByAddr(_byte) { \
+ ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_byte); \
+ ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_byte+4); \
+ }
+#endif
+
+
+#define ExtraPprzTransportPutInt8ByAddr(_x) ExtraPprzTransportPut1ByteByAddr(_x)
+#define ExtraPprzTransportPutUint8ByAddr(_x) ExtraPprzTransportPut1ByteByAddr((const uint8_t*)_x)
+#define ExtraPprzTransportPutInt16ByAddr(_x) ExtraPprzTransportPut2ByteByAddr((const uint8_t*)_x)
+#define ExtraPprzTransportPutUint16ByAddr(_x) ExtraPprzTransportPut2ByteByAddr((const uint8_t*)_x)
+#define ExtraPprzTransportPutInt32ByAddr(_x) ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_x)
+#define ExtraPprzTransportPutUint32ByAddr(_x) ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_x)
+#define ExtraPprzTransportPutFloatByAddr(_x) ExtraPprzTransportPut4ByteByAddr((const uint8_t*)_x)
+
+#define ExtraPprzTransportPutArray(_put, _n, _x) { \
+ uint8_t _i; \
+ ExtraPprzTransportPutUint8(_n); \
+ for(_i = 0; _i < _n; _i++) { \
+ _put(&_x[_i]); \
+ } \
+}
+
+#define ExtraPprzTransportPutFloatArray(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutFloatByAddr, _n, _x)
+#define ExtraPprzTransportPutDoubleArray(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutDoubleByAddr, _n, _x)
+
+#define ExtraPprzTransportPutInt16Array(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutInt16ByAddr, _n, _x)
+#define ExtraPprzTransportPutUint16Array(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutUint16ByAddr, _n, _x)
+
+#define ExtraPprzTransportPutInt32Array(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutInt32ByAddr, _n, _x)
+#define ExtraPprzTransportPutUint32Array(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutUint32ByAddr, _n, _x)
+
+#define ExtraPprzTransportPutUint8Array(_n, _x) ExtraPprzTransportPutArray(ExtraPprzTransportPutUint8ByAddr, _n, _x)
+
+
+/** Receiving pprz messages */
+
+extern uint8_t extra_pprz_payload[PPRZ_PAYLOAD_LEN];
+
+extern volatile bool_t extra_pprz_msg_received;
+extern uint8_t extra_pprz_ovrn, extra_pprz_error;
+extern volatile uint8_t extra_pprz_payload_len;
+
+#include "led.h"
+//#include "uart.h"
+//#include "messages.h"
+//#include "downlink.h"
+static inline void parse_extra_pprz( uint8_t c ) {
+ static uint8_t pprz_status = UNINIT;
+ static uint8_t _ck_a, _ck_b, payload_idx;
+
+ //uint8_t tab[] = { c };
+ //DOWNLINK_SEND_DEBUG(DefaultChannel,1,tab);
+ switch (pprz_status) {
+ case UNINIT:
+ if (c == STX)
+ pprz_status++;
+ break;
+ case GOT_STX:
+ if (extra_pprz_msg_received) {
+ extra_pprz_ovrn++;
+ goto error;
+ }
+ extra_pprz_payload_len = c-4; /* Counting STX, LENGTH and CRC1 and CRC2 */
+ _ck_a = _ck_b = c;
+ pprz_status++;
+ payload_idx = 0;
+ break;
+ case GOT_LENGTH:
+ extra_pprz_payload[payload_idx] = c;
+ _ck_a += c; _ck_b += _ck_a;
+ payload_idx++;
+ if (payload_idx == extra_pprz_payload_len)
+ pprz_status++;
+ break;
+ case GOT_PAYLOAD:
+ if (c != _ck_a)
+ goto error;
+ pprz_status++;
+ break;
+ case GOT_CRC1:
+ if (c != _ck_b)
+ goto error;
+ extra_pprz_msg_received = TRUE;
+ goto restart;
+ default:
+ goto error;
+ }
+ return;
+ error:
+ extra_pprz_error++;
+ restart:
+ pprz_status = UNINIT;
+ return;
+}
+
+static inline void extra_pprz_parse_payload(void) {
+ uint8_t i;
+ for(i = 0; i < extra_pprz_payload_len; i++)
+ dl_buffer[i] = extra_pprz_payload[i];
+ dl_msg_available = TRUE;
+}
+
+#define __ExtraPprzLink(dev, _x) dev##_x
+#define _ExtraPprzLink(dev, _x) __ExtraPprzLink(dev, _x)
+#define ExtraPprzLink(_x) _ExtraPprzLink(EXTRA_PPRZ_UART, _x)
+
+#define ExtraPprzBuffer() ExtraPprzLink(ChAvailable())
+#define ReadExtraPprzBuffer() { while (ExtraPprzLink(ChAvailable())&&!extra_pprz_msg_received) parse_extra_pprz(ExtraPprzLink(Getch())); }
+
+
+/* Datalink Event */
+
+#define ExtraDatalinkEvent() { \
+ if (ExtraPprzBuffer()) { \
+ ReadExtraPprzBuffer(); \
+ if (extra_pprz_msg_received) { \
+ extra_pprz_parse_payload(); \
+ extra_pprz_msg_received = FALSE; \
+ } \
+ } \
+ if (dl_msg_available) { \
+ dl_parse_msg(); \
+ dl_msg_available = FALSE; \
+ } \
+}
+
+
+#endif /* EXTRA_PPRZ_DL_H */
+