Refactor to use new protocol module and sipo.
[bertos.git] / bertos / net / ax25.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  * \brief Simple AX25 data link layer implementation.
33  *
34  * For now, only UI frames without any Layer 3 protocol are handled.
35  * This however is enough to send/receive APRS packets.
36  *
37  * \author Francesco Sacchi <batt@develer.com>
38  *
39  * $WIZ$ module_name = "ax25"
40  * $WIZ$ module_configuration = "bertos/cfg/cfg_ax25.h"
41  * $WIZ$ module_depends = "kfile", "crc-ccitt"
42  */
43
44
45 #ifndef NET_AX25_H
46 #define NET_AX25_H
47
48 #include "cfg/cfg_ax25.h"
49
50 #include <cfg/compiler.h>
51 #include <io/kfile.h>
52
53 /**
54  * Maximum size of a AX25 frame.
55  */
56 #define AX25_MIN_FRAME_LEN 18
57
58 /**
59  * CRC computation on correct AX25 packets should
60  * give this result (don't ask why).
61  */
62 #define AX25_CRC_CORRECT 0xF0B8
63
64 struct AX25Msg; // fwd declaration
65
66 /**
67  * Type for AX25 messages callback.
68  */
69 typedef void (*ax25_callback_t)(struct AX25Msg *msg);
70
71
72 /**
73  * AX25 Protocol context.
74  */
75 typedef struct AX25Ctx
76 {
77         uint8_t buf[CONFIG_AX25_FRAME_BUF_LEN]; ///< buffer for received chars
78         KFile *ch;        ///< KFile used to access the physical medium
79         size_t frm_len;   ///< received frame length.
80         uint16_t crc_in;  ///< CRC for current received frame
81         uint16_t crc_out; ///< CRC of current sent frame
82         ax25_callback_t hook; ///< Hook function to be called when a message is received
83         bool sync;   ///< True if we have received a HDLC flag.
84         bool escape; ///< True when we have to escape the following char.
85 } AX25Ctx;
86
87
88 /**
89  * AX25 Call sign.
90  */
91 typedef struct AX25Call
92 {
93         char call[6]; ///< Call string, max 6 character
94         uint8_t ssid; ///< SSID (secondary station ID) for the call
95 } AX25Call;
96
97 /**
98  * Create an AX25Call structure on the fly.
99  * \param str callsign, can be 6 characters or shorter.
100  * \param id  ssid associated with the callsign.
101  */
102 #define AX25_CALL(str, id) {.call = (str), .ssid = (id) }
103
104 /**
105  * Maximum number of Repeaters in a AX25 message.
106  */
107 #define AX25_MAX_RPT 8
108
109 /*
110  * Has to be lesser than 8 in order to fit in one byte
111  * change AX25Msg.rpt_flags if you need more repeaters.
112  */
113 STATIC_ASSERT(AX25_MAX_RPT <= 8);
114
115 /**
116  * AX25 Message.
117  * Used to handle AX25 sent/received messages.
118  */
119 typedef struct AX25Msg
120 {
121         AX25Call src;  ///< Source adress
122         AX25Call dst;  ///< Destination address
123         #if CONFIG_AX25_RPT_LST
124         AX25Call rpt_lst[AX25_MAX_RPT]; ///< List of repeaters
125         uint8_t rpt_cnt; ///< Number of repeaters in this message
126         uint8_t rpt_flags; ///< Has-been-repeated flags for each repeater (bit-mapped)
127         #define AX25_REPEATED(msg, idx) ((msg)->rpt_flags & BV(idx))
128         #endif
129         uint16_t ctrl; ///< AX25 control field
130         uint8_t pid;   ///< AX25 PID field
131         const uint8_t *info; ///< Pointer to the info field (payload) of the message
132         size_t len;    ///< Payload length
133 } AX25Msg;
134
135
136 #define AX25_CTRL_UI      0x03
137 #define AX25_PID_NOLAYER3 0xF0
138
139 /**
140  * \name HDLC flags.
141  * These should be moved in
142  * a separated HDLC related file one day...
143  * \{
144  */
145 #define HDLC_FLAG  0x7E
146 #define HDLC_RESET 0x7F
147 #define AX25_ESC   0x1B
148 /* \} */
149
150
151 /**
152  * Declare an AX25 path.
153  * \param dst the destination callsign for the path, \see AX25_CALL
154  *        for a handy way to create a callsign on the fly.
155  * \param src the source callsign for the path, \see AX25_CALL
156  *        for a handy way to create a callsign on the fly.
157  *
158  * Additional optional callsigns can be specified at the end of this macro
159  * in order to add repeater callsigns or specific unproto paths.
160  *
161  * This macro can be used to simply path array declaration.
162  * Should be used in this way:
163  * \code
164  * AX25Call path[] = AX25_PATH(AX25_CALL("abcdef", 0), AX25_CALL("ghjklm", 0), AX25_CALL("wide1", 1), AX25_CALL("wide2", 2));
165  * \endcode
166  *
167  * The declared path can then be passed to ax25_sendVia().
168  */
169 #define AX25_PATH(dst, src, ...) { dst, src, ## __VA_ARGS__ }
170
171 void ax25_poll(AX25Ctx *ctx);
172 void ax25_sendVia(AX25Ctx *ctx, const AX25Call *path, size_t path_len, const void *_buf, size_t len);
173
174 /**
175  * Send an AX25 frame on the channel.
176  * \param ctx AX25 context to operate on.
177  * \param dst the destination callsign for the frame, \see AX25_CALL
178  *        for a handy way to create a callsign on the fly.
179  * \param src the source callsign for the frame, \see AX25_CALL
180  *        for a handy way to create a callsign on the fly.
181  * \param buf payload buffer.
182  * \param len length of the payload.
183  *
184  * \see ax25_sendVia() if you want to send a frame with a specific path.
185  */
186 #define ax25_send(ctx, dst, src, buf, len) ax25_sendVia(ctx, ({static AX25Call __path[]={dst, src}; (AX25Call *)&__path;}), 2, buf, len)
187 void ax25_init(AX25Ctx *ctx, KFile *channel, ax25_callback_t hook);
188
189 void ax25_print(KFile *ch, const AX25Msg *msg);
190
191 int ax25_testSetup(void);
192 int ax25_testTearDown(void);
193 int ax25_testRun(void);
194
195 #endif /* NET_AX25_H */