-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathax25_util.cpp
146 lines (124 loc) · 3.3 KB
/
ax25_util.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
/*-------------------------------------------------------------------
*
* Name: AXCall2asc
*
* Purpose: Convert AX25 call in plain ASCII
*
* Inputs:
*
* Note:
*
*-----------------------------------------------------------------*/
char *AXCall2asc(unsigned char *buf) {
static char call[16];
/* GET CALLSIGN, SKIP SPACE */
memset(call, 0, 16);
for (int j=0; j<6; j++)
if (buf[j] != (' '<<1)) call[j] = (buf[j]>>1); // Not a space, store it
/* WRITE SSID AT THE END */
uint8_t ssid = (buf[6]>>1) & 0x0F;
if(ssid) sprintf(strrchr(call, 0), "-%u", ssid);
return call;
}
/*-------------------------------------------------------------------
*
* Name: DecodeAX25
*
* Purpose: Convert packet to readable ascii
*
* Inputs:
*
* Note:
*
*-----------------------------------------------------------------*/
void DecodeAX25(uint8_t *data, uint8_t length, char *out) {
strcpy(out, AXCall2asc(&data[7])); // SOURCE CALL
strcat(out, ">");
strcat(out, AXCall2asc(&data[0])); // DEST CALL
int i = 7;
while((data[i+6] & 1) == 0) { // DIGI PATH
i+=7;
strcat(out, ",");
strcat(out, AXCall2asc(&data[i]));
if(data[i+6] & 128) strcat(out, "*");
}
i+=7+2; // JUMP PID/DATA TYPE AND DISPLAY APRS PACKET
strcat(out, ":");
strncat(out, (char*)&data[i], length-i); // PACKET
}
/*-------------------------------------------------------------------
*
* Name: asc2AXCall
*
* Purpose: Convert ASCII call to AX25 callsign
*
* Inputs:
*
* Note:
*
*-----------------------------------------------------------------*/
void asc2AXcall(char *in, unsigned char *out) {
/* GET CALLSIGN, INSERT SPACE */
for(int i=0; i<6; i++) {
if(isalnum(*in)) {
*(out++) = *(in++)<<1;
} else {
*(out++) = ' '<<1;
}
}
/* SET SSID */
if(*in == '-') {
*out = 0x60 | ((atoi(++in)&15) <<1);
} else {
*out = 0x60;
}
/* SEARCH FOR DIGI * MARKER */
char* p = strpbrk(in, ",:*");
if(p!=0 && *p == '*') *out |= 0x80; // Hass-been-digipeated bit
}
/*-------------------------------------------------------------------
*
* Name: EncodeAX25
*
* Purpose: Convert ascii to AX25 packet
*
* Inputs:
*
* Note:
*
*-----------------------------------------------------------------*/
int EncodeAX25(char *in, uint8_t *out) {
char *p;
int pos;
/* CONVERT SOURCE CALL */
asc2AXcall(in, out+7);
/* CONVERT DEST ALL, AFTER THE > CARACTER */
p = strchr(in, '>');
if(p==NULL) return 0;
asc2AXcall(++p, out);
/* CONVERT PATH, SEPARATE WITH , UNTIL END OF PATH WITH : */
pos = 14; // Position of path in AX25 packet (pos-1 to set final bit)
p = in;
while(1) {
p = strpbrk(p, ",:");
if(p==NULL) return 0;
if(*p == ':') break;
p++;
asc2AXcall(p, out+pos);
pos+=7;
}
p++; // Skip : caracter
/* SET AX25 PATH FINAL BIT */
out[pos-1] |= 0x01;
/* SET UI PACKET AND PID */
out[pos++] = 0x03;
out[pos++] = 0xF0;
/* COPY PACKET DATA */
while(*p != 0) out[pos++] = *(p++);
return pos;
}