ad11e4665671fb10edc6edb2eb8128080aa2303f
[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  * \version $Id$
38  * \author Francesco Sacchi <batt@develer.com>
39  *
40  * $WIZ$ module_name = "ax25"
41  * $WIZ$ module_configuration = "bertos/cfg/cfg_ax25.h"
42  * $WIZ$ module_depends = "kfile", "crc-ccitt"
43  */
44
45
46 #ifndef NET_AX25_H
47 #define NET_AX25_H
48
49 #include "cfg/cfg_ax25.h"
50
51 #include <cfg/compiler.h>
52 #include <kern/kfile.h>
53
54 /**
55  * Maximum size of a AX25 frame.
56  */
57 #define AX25_MIN_FRAME_LEN 18
58
59 /**
60  * CRC computation on correct AX25 packets should
61  * give this result (don't ask why).
62  */
63 #define AX25_CRC_CORRECT 0xF0B8
64
65 struct AX25Msg; // fwd declaration
66
67 /**
68  * Type for AX25 messages callback.
69  */
70 typedef void (*ax25_callback_t)(struct AX25Msg *msg);
71
72
73 /**
74  * AX25 Protocol context.
75  */
76 typedef struct AX25Ctx
77 {
78         uint8_t buf[CONFIG_AX25_FRAME_BUF_LEN]; ///< buffer for received chars
79         KFile *ch;        ///< KFile used to access the physical medium
80         size_t frm_len;   ///< received frame length.
81         uint16_t crc_in;  ///< CRC for current received frame
82         uint16_t crc_out; ///< CRC of current sent frame
83         ax25_callback_t hook; ///< Hook function to be called when a message is received
84         bool sync;   ///< True if we have received a HDLC flag.
85         bool escape; ///< True when we have to escape the following char.
86 } AX25Ctx;
87
88
89 /**
90  * AX25 Call sign.
91  */
92 typedef struct AX25Call
93 {
94         char call[6]; ///< Call string, max 6 character
95         uint8_t ssid; ///< SSID (secondary station ID) for the call
96 } AX25Call;
97
98 /**
99  * Create an AX25Call structure on the fly.
100  * \param str callsign, can be 6 characters or shorter.
101  * \param id  ssid associated with the callsign.
102  */
103 #define AX25_CALL(str, id) {.call = (str), .ssid = (id) }
104
105 /**
106  * Maximum number of Repeaters in a AX25 message.
107  */
108 #define AX25_MAX_RPT 8
109
110
111 /**
112  * AX25 Message.
113  * Used to handle AX25 sent/received messages.
114  */
115 typedef struct AX25Msg
116 {
117         AX25Call src;  ///< Source adress
118         AX25Call dst;  ///< Destination address
119         #if CONFIG_AX25_RPT_LST
120         AX25Call rpt_lst[AX25_MAX_RPT]; ///< List of repeaters
121         uint8_t rpt_cnt; ///< Number of repeaters in this message
122         #endif
123         uint16_t ctrl; ///< AX25 control field
124         uint8_t pid;   ///< AX25 PID field
125         const uint8_t *info; ///< Pointer to the info field (payload) of the message
126         size_t len;    ///< Payload length
127 } AX25Msg;
128
129 #define AX25_CTRL_UI      0x03
130 #define AX25_PID_NOLAYER3 0xF0
131
132 /**
133  * \name HDLC flags.
134  * These should be moved in
135  * a separated HDLC related file one day...
136  * \{
137  */
138 #define HDLC_FLAG  0x7E
139 #define HDLC_RESET 0x7F
140 #define AX25_ESC   0x1B
141 /* \} */
142
143
144 /**
145  * Declare an AX25 path.
146  * \param dst the destination callsign for the path, \see AX25_CALL
147  *        for a handy way to create a callsign on the fly.
148  * \param src the source callsign for the path, \see AX25_CALL
149  *        for a handy way to create a callsign on the fly.
150  *
151  * Additional optional callsigns can be specified at the end of this macro
152  * in order to add repeater callsigns or specific unproto paths.
153  *
154  * This macro can be used to simply path array declaration.
155  * Should be used in this way:
156  * \code
157  * AX25Call path[] = AX25_PATH(AX25_CALL("abcdef", 0), AX25_CALL("ghjklm", 0), AX25_CALL("wide1", 1), AX25_CALL("wide2", 2));
158  * \endcode
159  *
160  * The declared path can then be passed to ax25_sendVia().
161  */
162 #define AX25_PATH(dst, src, ...) { dst, src, ## __VA_ARGS__ }
163
164 void ax25_poll(AX25Ctx *ctx);
165 void ax25_sendVia(AX25Ctx *ctx, const AX25Call *path, size_t path_len, const void *_buf, size_t len);
166
167 /**
168  * Send an AX25 frame on the channel.
169  * \param ctx AX25 context to operate on.
170  * \param dst the destination callsign for the frame, \see AX25_CALL
171  *        for a handy way to create a callsign on the fly.
172  * \param src the source callsign for the frame, \see AX25_CALL
173  *        for a handy way to create a callsign on the fly.
174  * \param buf payload buffer.
175  * \param len length of the payload.
176  *
177  * \see ax25_sendVia() if you want to send a frame with a specific path.
178  */
179 #define ax25_send(ctx, dst, src, buf, len) ax25_sendVia(ctx, ({static AX25Call __path[]={dst, src}; __path;}), 2, buf, len)
180 void ax25_init(AX25Ctx *ctx, KFile *channel, ax25_callback_t hook);
181
182 int ax25_testSetup(void);
183 int ax25_testTearDown(void);
184 int ax25_testRun(void);
185
186 #endif /* NET_AX25_H */