Skip to content

Commit d0226ea

Browse files
committed
v4.0.1
* Class-B: Added xtal error correction to beacon frequency * Class-B: Added support for all regions to beacon frame format (various datarates imply different frame sizes), as defined by LoRaWAN v1.0.2/v1.1
1 parent c05eb0e commit d0226ea

File tree

4 files changed

+53
-53
lines changed

4 files changed

+53
-53
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.0.0
1+
4.0.1

lora_pkt_fwd/cfg/global_conf.json.US902.beacon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
"beacon_freq_hz": 923300000,
111111
"beacon_freq_nb": 8,
112112
"beacon_freq_step": 600000,
113-
"beacon_datarate": 10,
113+
"beacon_datarate": 12,
114114
"beacon_bw_hz": 500000,
115115
"beacon_power": 14,
116116
"beacon_infodesc": 0

lora_pkt_fwd/src/lora_pkt_fwd.c

Lines changed: 45 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ static int parse_gateway_configuration(const char * conf_file) {
786786
val = json_object_get_value(conf_obj, "beacon_period");
787787
if (val != NULL) {
788788
beacon_period = (uint32_t)json_value_get_number(val);
789-
if (beacon_period < 6) {
789+
if ((beacon_period > 0) && (beacon_period < 6)) {
790790
MSG("ERROR: invalid configuration for Beacon period, must be >= 6s\n");
791791
return -1;
792792
} else {
@@ -819,24 +819,14 @@ static int parse_gateway_configuration(const char * conf_file) {
819819
val = json_object_get_value(conf_obj, "beacon_datarate");
820820
if (val != NULL) {
821821
beacon_datarate = (uint8_t)json_value_get_number(val);
822-
if ((beacon_datarate != 9) && (beacon_datarate != 10)) {
823-
MSG("ERROR: invalid configuration for Beacon datarate\n");
824-
return -1;
825-
} else {
826-
MSG("INFO: Beaconing datarate is set to SF%d\n", beacon_datarate);
827-
}
822+
MSG("INFO: Beaconing datarate is set to SF%d\n", beacon_datarate);
828823
}
829824

830825
/* Beacon modulation bandwidth (optional) */
831826
val = json_object_get_value(conf_obj, "beacon_bw_hz");
832827
if (val != NULL) {
833828
beacon_bw_hz = (uint32_t)json_value_get_number(val);
834-
if ((beacon_bw_hz != 125000) && (beacon_bw_hz != 500000)) {
835-
MSG("ERROR: invalid configuration for Beacon modulation bandwidth\n");
836-
return -1;
837-
} else {
838-
MSG("INFO: Beaconing modulation bandwidth is set to %dHz\n", beacon_bw_hz);
839-
}
829+
MSG("INFO: Beaconing modulation bandwidth is set to %dHz\n", beacon_bw_hz);
840830
}
841831

842832
/* Beacon TX power (optional) */
@@ -1931,7 +1921,8 @@ void thread_down(void) {
19311921
struct lgw_pkt_tx_s beacon_pkt;
19321922
uint8_t beacon_chan;
19331923
uint8_t beacon_loop;
1934-
uint8_t beacon_padding = 0;
1924+
size_t beacon_RFU1_size = 0;
1925+
size_t beacon_RFU2_size = 0;
19351926
uint8_t beacon_pyld_idx = 0;
19361927
time_t diff_beacon_time;
19371928
struct timespec next_beacon_gps_time; /* gps time of next beacon packet */
@@ -1987,39 +1978,46 @@ void thread_down(void) {
19871978
exit(EXIT_FAILURE);
19881979
}
19891980
switch (beacon_datarate) {
1981+
case 8:
1982+
beacon_pkt.datarate = DR_LORA_SF8;
1983+
beacon_RFU1_size = 1;
1984+
beacon_RFU2_size = 3;
1985+
break;
19901986
case 9:
19911987
beacon_pkt.datarate = DR_LORA_SF9;
1992-
beacon_pkt.size = 17;
1993-
beacon_padding = 0;
1988+
beacon_RFU1_size = 2;
1989+
beacon_RFU2_size = 0;
19941990
break;
19951991
case 10:
19961992
beacon_pkt.datarate = DR_LORA_SF10;
1997-
beacon_pkt.size = 19;
1998-
beacon_padding = 1;
1993+
beacon_RFU1_size = 3;
1994+
beacon_RFU2_size = 1;
1995+
break;
1996+
case 12:
1997+
beacon_pkt.datarate = DR_LORA_SF12;
1998+
beacon_RFU1_size = 5;
1999+
beacon_RFU2_size = 3;
19992000
break;
20002001
default:
20012002
/* should not happen */
20022003
MSG("ERROR: unsupported datarate for beacon\n");
20032004
exit(EXIT_FAILURE);
20042005
}
2006+
beacon_pkt.size = beacon_RFU1_size + 4 + 2 + 7 + beacon_RFU2_size + 2;
20052007
beacon_pkt.coderate = CR_LORA_4_5;
20062008
beacon_pkt.invert_pol = false;
20072009
beacon_pkt.preamble = 10;
20082010
beacon_pkt.no_crc = true;
20092011
beacon_pkt.no_header = true;
20102012

20112013
/* network common part beacon fields (little endian) */
2012-
beacon_pyld_idx = 0;
2013-
beacon_pkt.payload[beacon_pyld_idx++] = 0x0; /* RFU */
2014-
beacon_pkt.payload[beacon_pyld_idx++] = 0x0; /* RFU */
2015-
if (beacon_padding == 1) {
2016-
beacon_pkt.payload[beacon_pyld_idx++] = 0x0; /* RFU */
2014+
for (i = 0; i < (int)beacon_RFU1_size; i++) {
2015+
beacon_pkt.payload[beacon_pyld_idx++] = 0x0;
20172016
}
20182017

2019-
/* time (variable), filled later */
2020-
beacon_pyld_idx += 4;
2021-
/* crc1 (variable), filled later */
2022-
beacon_pyld_idx += 2;
2018+
/* network common part beacon fields (little endian) */
2019+
beacon_pyld_idx += 4; /* time (variable), filled later */
2020+
beacon_pyld_idx += 2; /* crc1 (variable), filled later */
20232021

20242022
/* calculate the latitude and longitude that must be publicly reported */
20252023
field_latitude = (int32_t)((reference_coord.lat / 90.0) * (double)(1<<23));
@@ -2043,12 +2041,14 @@ void thread_down(void) {
20432041
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & field_longitude;
20442042
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (field_longitude >> 8);
20452043
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (field_longitude >> 16);
2046-
if (beacon_padding == 1) {
2047-
beacon_pkt.payload[beacon_pyld_idx++] = 0x0; /* RFU */
2044+
2045+
/* RFU */
2046+
for (i = 0; i < (int)beacon_RFU2_size; i++) {
2047+
beacon_pkt.payload[beacon_pyld_idx++] = 0x0;
20482048
}
20492049

20502050
/* CRC of the beacon gateway specific part fields */
2051-
field_crc2 = crc16((beacon_pkt.payload + 8 + beacon_padding), 7 + beacon_padding);
2051+
field_crc2 = crc16((beacon_pkt.payload + 6 + beacon_RFU1_size), 7 + beacon_RFU2_size);
20522052
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & field_crc2;
20532053
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (field_crc2 >> 8);
20542054

@@ -2136,23 +2136,16 @@ void thread_down(void) {
21362136
}
21372137
/* Compute beacon frequency */
21382138
beacon_pkt.freq_hz = beacon_freq_hz + (beacon_chan * beacon_freq_step);
2139-
#if 0
2140-
/* Compensate breacon frequency with xtal error */
2141-
pthread_mutex_lock(&mx_xcorr);
2142-
beacon_pkt.freq_hz = (uint32_t)(xtal_correct * (double)beacon_pkt.freq_hz);
2143-
printf("beacon_pkt.freq_hz=%u (xtal_correct=%.15lf)\n", beacon_pkt.freq_hz, xtal_correct);
2144-
pthread_mutex_unlock(&mx_xcorr);
2145-
#endif
21462139

21472140
/* load time in beacon payload */
2148-
beacon_pyld_idx = 2 + beacon_padding;
2141+
beacon_pyld_idx = beacon_RFU1_size;
21492142
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & next_beacon_gps_time.tv_sec;
21502143
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (next_beacon_gps_time.tv_sec >> 8);
21512144
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (next_beacon_gps_time.tv_sec >> 16);
21522145
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (next_beacon_gps_time.tv_sec >> 24);
21532146

21542147
/* calculate CRC */
2155-
field_crc1 = crc16(beacon_pkt.payload, 6 + beacon_padding); /* CRC for the network common part */
2148+
field_crc1 = crc16(beacon_pkt.payload, 4 + beacon_RFU1_size); /* CRC for the network common part */
21562149
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & field_crc1;
21572150
beacon_pkt.payload[beacon_pyld_idx++] = 0xFF & (field_crc1 >> 8);
21582151

@@ -2172,19 +2165,12 @@ void thread_down(void) {
21722165
last_beacon_gps_time.tv_sec = next_beacon_gps_time.tv_sec; /* keep this beacon time as reference for next one to be programmed */
21732166

21742167
/* display beacon payload */
2175-
MSG("--- Beacon queued (count_us=%u, freq_hz=%u) - payload: ---\n", beacon_pkt.count_us, beacon_pkt.freq_hz);
2176-
for (i=0; i<beacon_pkt.size; ++i) {
2177-
MSG("0x%02X", beacon_pkt.payload[i]);
2178-
if (i%8 == 7) {
2179-
MSG("\n");
2180-
} else {
2181-
MSG(" - ");
2182-
}
2183-
}
2184-
if (i%8 != 0) {
2185-
MSG("\n");
2168+
MSG("INFO: Beacon queued (count_us=%u, freq_hz=%u, size=%u):\n", beacon_pkt.count_us, beacon_pkt.freq_hz, beacon_pkt.size);
2169+
printf( " => " );
2170+
for (i = 0; i < beacon_pkt.size; ++i) {
2171+
MSG("%02X ", beacon_pkt.payload[i]);
21862172
}
2187-
MSG("--- end of payload ---\n");
2173+
MSG("\n");
21882174
} else {
21892175
MSG_DEBUG(DEBUG_BEACON, "--> beacon queuing failed with %d\n", jit_result);
21902176
/* update stats */
@@ -2608,9 +2594,17 @@ void thread_jit(void) {
26082594
if (jit_result == JIT_ERROR_OK) {
26092595
/* update beacon stats */
26102596
if (pkt_type == JIT_PKT_TYPE_BEACON) {
2597+
/* Compensate breacon frequency with xtal error */
2598+
pthread_mutex_lock(&mx_xcorr);
2599+
pkt.freq_hz = (uint32_t)(xtal_correct * (double)pkt.freq_hz);
2600+
MSG_DEBUG(DEBUG_BEACON, "beacon_pkt.freq_hz=%u (xtal_correct=%.15lf)\n", pkt.freq_hz, xtal_correct);
2601+
pthread_mutex_unlock(&mx_xcorr);
2602+
2603+
/* Update statistics */
26112604
pthread_mutex_lock(&mx_meas_dw);
26122605
meas_nb_beacon_sent += 1;
26132606
pthread_mutex_unlock(&mx_meas_dw);
2607+
MSG("INFO: Beacon dequeued (count_us=%u)\n", pkt.count_us);
26142608
}
26152609

26162610
/* check if concentrator is free for sending new packet */

readme.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ Please refer to the script header for more details.
8383
5. Changelog
8484
-------------
8585

86+
### v4.0.1 - 2017-03-16 ###
87+
88+
* Class-B: Added xtal error correction to beacon frequency
89+
* Class-B: Added support for all regions to beacon frame format (various
90+
datarates imply different frame sizes), as defined by LoRaWAN v1.1.
91+
8692
### v4.0.0 - 2017-01-10 ###
8793

8894
* Added Class-B support, as defined in LoRaWAN v1.1

0 commit comments

Comments
 (0)