From 319029b456527124521b6a6a65c21edb321cdcb8 Mon Sep 17 00:00:00 2001 From: batt Date: Fri, 16 Apr 2010 15:34:14 +0000 Subject: [PATCH] AX25: refactor in order to add the possibility to specify a path for sent frames. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3441 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/net/ax25.c | 27 ++++++++++++++++----------- bertos/net/ax25.h | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/bertos/net/ax25.c b/bertos/net/ax25.c index d2c2639b..68a6ae56 100644 --- a/bertos/net/ax25.c +++ b/bertos/net/ax25.c @@ -193,7 +193,7 @@ static void ax25_putchar(AX25Ctx *ctx, uint8_t c) kfile_putc(c, ctx->ch); } -static void ax25_sendCall(AX25Ctx *ctx, const AX25Call *addr) +static void ax25_sendCall(AX25Ctx *ctx, const AX25Call *addr, bool last) { unsigned len = MIN(sizeof(addr->call), strlen(addr->call)); @@ -209,30 +209,35 @@ static void ax25_sendCall(AX25Ctx *ctx, const AX25Call *addr) if (len < sizeof(addr->call)) for (unsigned i = 0; i < sizeof(addr->call) - len; i++) ax25_putchar(ctx, ' ' << 1); + + /* The bit0 of last call SSID should be set to 1 */ + uint8_t ssid = addr->ssid << 1 | (last ? 0x01 : 0); + ax25_putchar(ctx, ssid); } /** - * Send an AX25 frame on the channel. + * Send an AX25 frame on the channel through a specific path. * \param ctx AX25 context to operate on. - * \param dst the destination callsign for the frame, \see AX25_CALL - * for a handy way to create a callsign on the fly. - * \param src the source callsign for the frame, \see AX25_CALL - * for a handy way to create a callsign on the fly. + * \param path An array of callsigns used as path, \see AX25_PATH for + * an handy way to create a path. + * \param path_len callsigns path lenght. * \param _buf payload buffer. * \param len length of the payload. */ -void ax25_send(AX25Ctx *ctx, const AX25Call *dst, const AX25Call *src, const void *_buf, size_t len) +void ax25_sendVia(AX25Ctx *ctx, const AX25Call *path, size_t path_len, const void *_buf, size_t len) { const uint8_t *buf = (const uint8_t *)_buf; + ASSERT(path); + ASSERT(path_len >= 2); ctx->crc_out = CRC_CCITT_INIT_VAL; kfile_putc(HDLC_FLAG, ctx->ch); - ax25_sendCall(ctx, dst); - ax25_putchar(ctx, dst->ssid << 1); - ax25_sendCall(ctx, src); - ax25_putchar(ctx, (src->ssid << 1) | 0x01); + /* Send call */ + for (size_t i = 0; i < path_len; i++) + ax25_sendCall(ctx, &path[i], (i == path_len - 1)); + ax25_putchar(ctx, AX25_CTRL_UI); ax25_putchar(ctx, AX25_PID_NOLAYER3); diff --git a/bertos/net/ax25.h b/bertos/net/ax25.h index da56b28b..ad11e466 100644 --- a/bertos/net/ax25.h +++ b/bertos/net/ax25.h @@ -96,11 +96,11 @@ typedef struct AX25Call } AX25Call; /** - * Create an AX25Call structure on the fly and return its pointer. + * Create an AX25Call structure on the fly. * \param str callsign, can be 6 characters or shorter. * \param id ssid associated with the callsign. */ -#define AX25_CALL(str, id) ({ static const AX25Call _call = { .call = (str), .ssid = (id) }; &_call; }) +#define AX25_CALL(str, id) {.call = (str), .ssid = (id) } /** * Maximum number of Repeaters in a AX25 message. @@ -141,9 +141,42 @@ typedef struct AX25Msg /* \} */ +/** + * Declare an AX25 path. + * \param dst the destination callsign for the path, \see AX25_CALL + * for a handy way to create a callsign on the fly. + * \param src the source callsign for the path, \see AX25_CALL + * for a handy way to create a callsign on the fly. + * + * Additional optional callsigns can be specified at the end of this macro + * in order to add repeater callsigns or specific unproto paths. + * + * This macro can be used to simply path array declaration. + * Should be used in this way: + * \code + * AX25Call path[] = AX25_PATH(AX25_CALL("abcdef", 0), AX25_CALL("ghjklm", 0), AX25_CALL("wide1", 1), AX25_CALL("wide2", 2)); + * \endcode + * + * The declared path can then be passed to ax25_sendVia(). + */ +#define AX25_PATH(dst, src, ...) { dst, src, ## __VA_ARGS__ } void ax25_poll(AX25Ctx *ctx); -void ax25_send(AX25Ctx *ctx, const AX25Call *dst, const AX25Call *src, const void *_buf, size_t len); +void ax25_sendVia(AX25Ctx *ctx, const AX25Call *path, size_t path_len, const void *_buf, size_t len); + +/** + * Send an AX25 frame on the channel. + * \param ctx AX25 context to operate on. + * \param dst the destination callsign for the frame, \see AX25_CALL + * for a handy way to create a callsign on the fly. + * \param src the source callsign for the frame, \see AX25_CALL + * for a handy way to create a callsign on the fly. + * \param buf payload buffer. + * \param len length of the payload. + * + * \see ax25_sendVia() if you want to send a frame with a specific path. + */ +#define ax25_send(ctx, dst, src, buf, len) ax25_sendVia(ctx, ({static AX25Call __path[]={dst, src}; __path;}), 2, buf, len) void ax25_init(AX25Ctx *ctx, KFile *channel, ax25_callback_t hook); int ax25_testSetup(void); -- 2.25.1