├── LICENSE ├── README.md ├── basicstation ├── Makefile ├── files │ ├── reset_sx1301 │ ├── station.conf │ ├── station.config │ ├── station.init │ └── uci2station └── patches │ ├── 001-remove_original_makefile.patch │ ├── 002-add_header.patch │ ├── 003-change_compile_option.patch │ ├── 004-using_local_mbedtls.patch │ └── 005-change_branch_in_sx1302.patch ├── chirpstack-application-server ├── Makefile └── files │ ├── chirpstack-application-server.init │ └── lora-app-server.toml ├── chirpstack-gateway-bridge ├── Makefile └── files │ ├── chirpstack-gateway-bridge.init │ └── chirpstack-gateway-bridge.toml ├── chirpstack-geolocation-server ├── Makefile └── files │ ├── chirpstack-geolocation-server.init │ └── chirpstack-geolocation-server.toml ├── chirpstack-network-server ├── Makefile └── files │ ├── chirpstack-network-server.init │ └── chirpstack-network-server.toml ├── lora-gateway-hal ├── Config.in ├── Makefile └── patches │ ├── 0001-add-cmake-support.patch │ ├── 0002-add-preprocessing-for-SPI_DEV_PATH-and-SPI_SPEED.patch │ ├── 0003-add-SPI_DEV_PATH-and-SPI_SPEED-to-cmake.patch │ └── 0004-add-new-functions-for-basicstation.patch ├── lora-packet-forwarder ├── Makefile ├── files │ ├── gen_lora_global_conf │ ├── lora-global.config │ └── lora_pkt_fwd.init └── patches │ ├── 001-relocate_config_files_into_etc.patch │ ├── 002-using_qsort.patch │ └── 003-add-CMake-support.patch ├── lora-picogw-hal ├── Makefile └── patches │ └── 0001-add-CMake-support.patch ├── lora-picogw-packet-forwarder ├── Makefile └── patches │ ├── 0001-add-CMake-support.patch │ └── 0002-qsort_r.patch ├── lora-sx1302-hal ├── Makefile └── patches │ └── 001-using-qsort.patch ├── lorawan-stack ├── Makefile └── patches │ └── 001-remove_hook_install.patch ├── lua-toml └── Makefile ├── luci-app-basicstation ├── Makefile └── files │ └── usr │ ├── lib │ └── lua │ │ └── luci │ │ ├── controller │ │ └── lora │ │ │ └── station.lua │ │ ├── model │ │ └── cbi │ │ │ └── lora │ │ │ └── station.lua │ │ └── view │ │ └── admin_status │ │ └── stationlog.htm │ └── share │ └── rpcd │ └── acl.d │ └── luci-app-basicstation.json ├── luci-app-pkg-fwd ├── Makefile └── files │ └── usr │ └── lib │ └── lua │ └── luci │ ├── controller │ └── lora │ │ └── lora.lua │ └── model │ └── cbi │ └── lora │ └── lora_gateway.lua └── luci-lora-gateway.png /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lora-feed 2 | Semtech and LoRaServer packages for OpenWRT. 3 | 4 | ![luci](luci-lora-gateway.png) 5 | 6 | ## Table of Contents 7 | 8 | - [ToDo](#todo) 9 | - [Prerequisites](#prerequisites) 10 | - [Install](#install) 11 | - [Contribute](#contribute) 12 | - [License](#license) 13 | - [Donation](#donation) 14 | 15 | ## ToDo 16 | - [ ] chirpstack server test 17 | - [ ] chirpstack toml configuration files 18 | - [ ] chirpstack toml configuration generation 19 | - [ ] chirpstack toml configuration with UCI 20 | - [x] lorawan-stack build for front-end 21 | - [ ] lorawan-stack LuCI interface 22 | 23 | ## Prerequisites 24 | 25 | In addition to packages required by [OpenWRT](https://openwrt.org/docs/guide-developer/build-system/install-buildsystem), 26 | extra packages should be installed if you want to install the LoRaServer: 27 | 28 | sudo apt install go-bindata 29 | sudo apt install nodejs 30 | sudo apt install npm 31 | 32 | ## Install 33 | 34 | Edit your feeds.conf or feed.conf.default and add the following to it: 35 | 36 | # Semtech 37 | src-git lora https://github.com/xueliu/lora-feed 38 | 39 | Update your build environment and install the packages: 40 | 41 | $ ./scripts/feeds update lora 42 | $ ./scripts/feeds install -a -p lora 43 | $ make menuconfig 44 | 45 | Most programs are located in `Network -> LoRaWAN` 46 | 47 | Exit, save and build 48 | 49 | $ make -j4 50 | 51 | ## Contribute 52 | 53 | Found a bug? Please create an issue on GitHub: 54 | https://github.com/xueliu/lora-feed/issues 55 | 56 | Further tests and PR's are welcome and appreciated. 57 | 58 | ## Donation 59 | 60 | In order to fully test of functions, donations of LoRa gateway boards with GPS and Pico gateways are appreciated 61 | 62 | ## License 63 | 64 | GPLv2 65 | -------------------------------------------------------------------------------- /basicstation/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=basicstation 11 | PKG_VERSION:=2.0.5 12 | PKG_REV:=9bcdf0e12e4568e96011a3910e6d460ec9384f8c 13 | PKG_RELEASE:=$(AUTORELEASE) 14 | 15 | PKG_SOURCE_PROTO:=git 16 | PKG_SOURCE_URL=https://github.com/xueliu/basicstation.git 17 | PKG_SOURCE_VERSION:=$(PKG_REV) 18 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_REV).tar.gz 19 | 20 | PKG_MAINTAINER:=Xue Liu 21 | PKG_LICENSE:=BSD 22 | 23 | include $(INCLUDE_DIR)/package.mk 24 | include $(INCLUDE_DIR)/cmake.mk 25 | 26 | define Package/basicstation/Default 27 | SECTION:=net 28 | CATEGORY:=Network 29 | SUBMENU:=LoRaWAN 30 | TITLE:=a LoRaWAN Gateway implementation from Semtech 31 | DEPENDS:= +libmbedtls 32 | PROVIDES:=basicstation 33 | endef 34 | 35 | define Package/basicstation-linux 36 | $(call Package/basicstation/Default) 37 | TITLE+= (linux) 38 | VARIANT:=linux 39 | endef 40 | 41 | define Package/basicstation-linuxpico 42 | $(call Package/basicstation/Default) 43 | TITLE+= (linuxpico) 44 | VARIANT:=linuxpico 45 | endef 46 | 47 | define Package/basicstation-corecell 48 | $(call Package/basicstation/Default) 49 | TITLE+= (corecell) 50 | VARIANT:=corecell 51 | endef 52 | 53 | define Package/basicstation/description 54 | Basic Station is an implementation of a LoRa packet forwarder, 55 | which is a program running on the host of a LoRa gateway (with or 56 | without GPS), forwarding RF packets received by the 57 | concentrator (uplinks) to a LoRaWAN Network Server (LNS) 58 | through some secured IP link and transmitting RF packets sent by the 59 | LNS (downlinks) through the same secured IP to some device. 60 | endef 61 | 62 | # set additional CMake options 63 | CMAKE_OPTIONS += -Dbasicstation_VERSION_SHORT=$(PKG_VERSION) 64 | CMAKE_OPTIONS += -Dbasicstation_VERSION_FULL=$(PKG_VERSION) 65 | CMAKE_OPTIONS += -DPLATFORM:STRING=$(VARIANT) 66 | 67 | define Package/basicstation-linux/install 68 | $(INSTALL_DIR) $(1)/usr/sbin 69 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/station $(1)/usr/sbin/ 70 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/crc32 $(1)/usr/sbin/crc32 71 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/genkwcrcs $(1)/usr/sbin/genkwcrcs 72 | $(INSTALL_BIN) ./files/uci2station $(1)/usr/sbin/uci2station 73 | $(INSTALL_BIN) ./files/reset_sx1301 $(1)/usr/sbin/reset_sx1301 74 | 75 | $(INSTALL_DIR) $(1)/etc/init.d 76 | $(INSTALL_BIN) ./files/station.init $(1)/etc/init.d/station 77 | 78 | $(INSTALL_DIR) $(1)/etc/config 79 | $(INSTALL_DATA) ./files/station.config $(1)/etc/config/station 80 | 81 | # temporally add a fix configuration file 82 | $(INSTALL_DIR) $(1)/etc/station 83 | $(INSTALL_DATA) ./files/station.conf $(1)/etc/station/station.conf 84 | endef 85 | 86 | Package/basicstation-linuxpico/install = $(Package/basicstation-linux/install) 87 | Package/basicstation-corecell/install = $(Package/basicstation-linux/install) 88 | 89 | $(eval $(call BuildPackage,basicstation-linux)) 90 | $(eval $(call BuildPackage,basicstation-linuxpico)) 91 | $(eval $(call BuildPackage,basicstation-corecell)) 92 | -------------------------------------------------------------------------------- /basicstation/files/reset_sx1301: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (C) 2020 Xue Liu 3 | 4 | . $IPKG_INSTROOT/lib/functions.sh 5 | 6 | config_load station 7 | 8 | config_get reset_enable SX1301_conf enable_reset_pin 9 | 10 | echo "sx1301 reset enable: $reset_enable" 11 | 12 | if [ $reset_enable != "1" ] 13 | then 14 | exit 15 | fi 16 | 17 | config_get pin SX1301_conf reset_pin 18 | 19 | echo "sx1301 resetpin: $pin" 20 | 21 | echo "sx1301 is resetting" 22 | 23 | if [ -d "/sys/class/gpio/gpio${pin}" ] 24 | then 25 | echo 1 > /dev/null 26 | else 27 | echo ${pin} > /sys/class/gpio/export 28 | fi 29 | 30 | echo "out" > /sys/class/gpio/gpio${pin}/direction 31 | echo "1" > /sys/class/gpio/gpio${pin}/value 32 | echo "0" > /sys/class/gpio/gpio${pin}/value 33 | echo "in" > /sys/class/gpio/gpio${pin}/direction 34 | 35 | echo "sx1301 is resetted" 36 | -------------------------------------------------------------------------------- /basicstation/files/station.conf: -------------------------------------------------------------------------------- 1 | { 2 | /* If slave-X.conf present this acts as default settings */ 3 | "SX1301_conf": { /* Actual channel plan is controlled by server */ 4 | "lorawan_public": true, /* is default */ 5 | "clksrc": 1, /* radio_1 provides clock to concentrator */ 6 | /* path to the SPI device, un-comment if not specified on the command line e.g., RADIODEV=/dev/spidev0.0 */ 7 | /*"device": "/dev/spidev0.0",*/ 8 | /* freq/enable provided by LNS - only HW specific settings listed here */ 9 | "radio_0": { 10 | "type": "SX1257", 11 | "rssi_offset": -166.0, 12 | "tx_enable": true, 13 | "antenna_gain": 0 14 | }, 15 | "radio_1": { 16 | "type": "SX1257", 17 | "rssi_offset": -166.0, 18 | "tx_enable": false 19 | } 20 | /* chan_multiSF_X, chan_Lora_std, chan_FSK provided by LNS */ 21 | }, 22 | "station_conf": { 23 | "log_file": "stderr", 24 | "log_level": "DEBUG", /* XDEBUG,DEBUG,VERBOSE,INFO,NOTICE,WARNING,ERROR,CRITICAL */ 25 | "log_size": 10000000, 26 | "log_rotate": 3, 27 | "CUPS_RESYNC_INTV": "1s" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /basicstation/files/station.config: -------------------------------------------------------------------------------- 1 | 2 | config sx1301 'SX1301_conf' 3 | option clksrc '1' 4 | option antenna_gain '0' 5 | option enable_reset_pin '1' 6 | option reset_pin '25' 7 | option lorawan_public 'true' 8 | 9 | config radio 'radio_0' 10 | option enable 'true' 11 | option rssi_offset '-166.0' 12 | option tx_enable 'true' 13 | option type 'SX1257'l 14 | 15 | config radio 'radio_1' 16 | option enable 'true' 17 | option freq '868500000' 18 | option rssi_offset '-166.0' 19 | option type 'SX1257' 20 | option tx_enable 'false' 21 | 22 | config station 'station_conf' 23 | option log_file 'stderr' 24 | option log_level 'DEBUG' 25 | option log_size '10000000' 26 | option log_rotate '3' 27 | 28 | -------------------------------------------------------------------------------- /basicstation/files/station.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | START=99 3 | STOP=10 4 | 5 | USE_PROCD=1 6 | 7 | PROG=/usr/sbin/station 8 | CONFIGFILE=/etc/station/station.conf 9 | 10 | start_service() 11 | { 12 | include /lib/functions 13 | 14 | logger "basicstation: Start" 15 | 16 | config_load station 17 | 18 | # generate_conf 19 | 20 | procd_open_instance 21 | procd_set_param command $PROG --home /etc/station 22 | procd_set_param file ${CONFIGFILE} 23 | procd_set_param file /etc/config/station 24 | procd_set_param respawn 25 | 26 | procd_set_param stdout 1 27 | procd_set_param stderr 1 28 | 29 | procd_close_instance 30 | } 31 | 32 | stop_service() { 33 | logger "basicstation: Stop" 34 | killall station 35 | } 36 | -------------------------------------------------------------------------------- /basicstation/files/uci2station: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- SPDX-License-Identifier: GPL-2.0 4 | -- 5 | -- Copyright (c) 2019 Xue Liu 6 | -- 7 | 8 | require("uloop") 9 | require("ubus") 10 | local json = require("dkjson") 11 | local uci = require("uci") 12 | 13 | x = uci.cursor() 14 | 15 | uloop.init() 16 | 17 | local conn = ubus.connect() 18 | if not conn then 19 | error("Failed to connect to ubus") 20 | end 21 | 22 | local station_ubus = conn:call( "uci", "get", { config = "station" } ) 23 | 24 | local station_table = station_ubus["values"] 25 | 26 | local station_global = {} 27 | local sx1301_conf = {} 28 | local radio_0 = {} 29 | local radio_1 = {} 30 | local station_conf = {} 31 | 32 | -- 33 | -- radio_0 34 | -- 35 | if station_table["radio_0"] then 36 | for k, v in pairs(station_table["radio_0"]) do 37 | if string.match(k, '%.[%a]*', 1) == nil then 38 | if tonumber(v) then 39 | radio_0[k] = tonumber(v) 40 | elseif v == "true" then 41 | radio_0[k] = true 42 | elseif v == "false" then 43 | radio_0[k] = false 44 | else 45 | radio_0[k] = v 46 | end 47 | end 48 | end 49 | else 50 | error("UCI configuration has no item radio_0, Please check your configuration") 51 | end 52 | 53 | -- 54 | -- radio_1 55 | -- 56 | if station_table["radio_1"] then 57 | for k, v in pairs(station_table["radio_1"]) do 58 | if string.match(k, '%.[%a]*', 1) == nil then 59 | if tonumber(v) then 60 | radio_1[k] = tonumber(v) 61 | elseif v == "true" then 62 | radio_1[k] = true 63 | elseif v == "false" then 64 | radio_1[k] = false 65 | else 66 | radio_1[k] = v 67 | end 68 | end 69 | end 70 | else 71 | error("UCI configuration has no item radio_1, Please check your configuration") 72 | end 73 | 74 | -- 75 | -- SX1301_conf 76 | -- 77 | if station_table["SX1301_conf"] then 78 | for k, v in pairs(station_table["SX1301_conf"]) do 79 | if string.match(k, '%.[%a]*', 1) == nil then 80 | if tonumber(v) then 81 | sx1301_conf[k] = tonumber(v) 82 | elseif v == "true" then 83 | sx1301_conf[k] = true 84 | elseif v == "false" then 85 | sx1301_conf[k] = false 86 | else 87 | sx1301_conf[k] = v 88 | end 89 | end 90 | end 91 | else 92 | error("UCI configuration has no item SX1301_conf, Please check your configuration") 93 | end 94 | 95 | -- 96 | -- station_conf 97 | if station_table["station_conf"] then 98 | for k, v in pairs(station_table["station_conf"]) do 99 | if string.match(k, '%.[%a]*', 1) == nil then 100 | if tonumber(v) then 101 | station_conf[k] = tonumber(v) 102 | elseif v == "true" then 103 | station_conf[k] = true 104 | elseif v == "false" then 105 | station_conf[k] = false 106 | else 107 | station_conf[k] = v 108 | end 109 | end 110 | end 111 | else 112 | error("UCI configuration has no item station_conf, Please check your configuration") 113 | end 114 | 115 | sx1301_conf["radio_0"] = radio_0 116 | sx1301_conf["radio_1"] = radio_1 117 | station_global["SX1301_conf"] = sx1301_conf 118 | station_global["station_conf"] = station_conf 119 | 120 | local station_global_text = json.encode(station_global, { indent = true }) 121 | 122 | print(station_global_text) 123 | 124 | -------------------------------------------------------------------------------- /basicstation/patches/001-remove_original_makefile.patch: -------------------------------------------------------------------------------- 1 | From 807250cd908dc41210f59c2b886e76491e6e5a74 Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Wed, 24 Jun 2020 14:06:33 +0200 4 | Subject: [PATCH 1/1] cmake: remove local makefile 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | makefile | 79 -------------------------------------------------------- 9 | 1 file changed, 79 deletions(-) 10 | delete mode 100644 makefile 11 | 12 | diff --git a/makefile b/makefile 13 | deleted file mode 100644 14 | index 3530e4e..0000000 15 | --- a/makefile 16 | +++ /dev/null 17 | @@ -1,79 +0,0 @@ 18 | -# --- Revised 3-Clause BSD License --- 19 | -# Copyright Semtech Corporation 2020. All rights reserved. 20 | -# 21 | -# Redistribution and use in source and binary forms, with or without modification, 22 | -# are permitted provided that the following conditions are met: 23 | -# 24 | -# * Redistributions of source code must retain the above copyright notice, 25 | -# this list of conditions and the following disclaimer. 26 | -# * Redistributions in binary form must reproduce the above copyright notice, 27 | -# this list of conditions and the following disclaimer in the documentation 28 | -# and/or other materials provided with the distribution. 29 | -# * Neither the name of the Semtech corporation nor the names of its 30 | -# contributors may be used to endorse or promote products derived from this 31 | -# software without specific prior written permission. 32 | -# 33 | -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 34 | -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35 | -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 36 | -# DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION. BE LIABLE FOR ANY DIRECT, 37 | -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 38 | -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 | -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 40 | -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 41 | -# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 42 | -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | - 44 | -TD=. 45 | -include ${TD}/setup.gmk 46 | - 47 | -.PHONY: all 48 | -all: build-local/bin/crc32 \ 49 | - src/kwcrc.h \ 50 | - deps \ 51 | - s-all 52 | - 53 | -# Shortcuts to run station specific goals 54 | -.PHONY: s-all s-load s-clean 55 | -s-all s-load s-clean: ${BD}/s2core/makefile 56 | - ${MAKE} -C ${ makefile 65 | - 66 | -src/kwcrc.h: build-local/bin/genkwcrcs src/kwlist.txt 67 | - build-local/bin/genkwcrcs $$(cat src/kwlist.txt | sed -e '/^#/d;s/[ \t]\+#.*//') > build-local/temp-kwcrc.h 68 | - mv build-local/temp-kwcrc.h $@ 69 | - 70 | -build-local/bin/genkwcrcs: src/genkwcrcs.c src/uj.h 71 | - mkdir -p ${@D} 72 | - gcc -std=gnu11 -Isrc -DCFG_prog_genkwcrcs $< -o $@ 73 | - 74 | -build-local/bin/crc32: src/crc32.c 75 | - mkdir -p ${@D} 76 | - gcc -std=gnu11 -Isrc -DCFG_prog_crc32 $< -o $@ 77 | - 78 | -DEPS.goals = $(patsubst %, deps/%, ${DEPS}) 79 | - 80 | -.PHONY: deps ${DEPS.goals} 81 | -deps: ${DEPS.goals} 82 | - 83 | -${DEPS.goals}: 84 | - platform=${platform} variant=${variant} ${MAKE} -C $@ 85 | - 86 | -.PHONY: build-clean 87 | -clean-build: 88 | - for d in build-*/s2core; do \ 89 | - if [ -d $$d ]; then ${MAKE} -C $$d clean; fi \ 90 | - done 91 | - 92 | -.PHONY: clean super-clean 93 | -clean super-clean: clean-build 94 | - for d in deps/*; do \ 95 | - ${MAKE} -C $$d $@; \ 96 | - done 97 | -- 98 | 2.17.1 99 | 100 | -------------------------------------------------------------------------------- /basicstation/patches/002-add_header.patch: -------------------------------------------------------------------------------- 1 | Index: basicstation-2.0.5/src/aio.c 2 | =================================================================== 3 | --- basicstation-2.0.5.orig/src/aio.c 4 | +++ basicstation-2.0.5/src/aio.c 5 | @@ -32,6 +32,7 @@ 6 | #include 7 | #include "rt.h" 8 | 9 | +#include 10 | 11 | enum { N_AIO_HANDLES = 10 }; 12 | static aio_t aioHandles[N_AIO_HANDLES]; 13 | -------------------------------------------------------------------------------- /basicstation/patches/003-change_compile_option.patch: -------------------------------------------------------------------------------- 1 | From 642e52fe0563e589c2e40c424d6237a75d65044a Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Wed, 24 Jun 2020 13:59:04 +0200 4 | Subject: [PATCH 1/1] openwrt: add -DCFG_argp and remove -DCFG_tlsdebug 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | CMakeLists.txt | 2 +- 9 | 1 file changed, 1 insertion(+), 1 deletion(-) 10 | 11 | Index: basicstation-2.0.5/CMakeLists.txt 12 | =================================================================== 13 | --- basicstation-2.0.5.orig/CMakeLists.txt 14 | +++ basicstation-2.0.5/CMakeLists.txt 15 | @@ -83,8 +83,8 @@ target_compile_options( 16 | -DCFG_linux 17 | -DCFG_no_leds 18 | -DCFG_lgw1 19 | - -DCFG_tlsdebug 20 | 21 | + -DCFG_argp 22 | -DCFG_platform_${PLATFORM} 23 | -DCFG_platform="${PLATFORM}" 24 | -DCFG_variant_${VARIANT} 25 | -------------------------------------------------------------------------------- /basicstation/patches/004-using_local_mbedtls.patch: -------------------------------------------------------------------------------- 1 | Index: basicstation-2.0.5/CMakeLists.txt 2 | =================================================================== 3 | --- basicstation-2.0.5.orig/CMakeLists.txt 4 | +++ basicstation-2.0.5/CMakeLists.txt 5 | @@ -63,7 +63,8 @@ else() 6 | add_subdirectory(deps/lgw) 7 | endif() 8 | 9 | -add_subdirectory(deps/mbedtls) 10 | +#add_subdirectory(deps/mbedtls) 11 | +find_package(mbedTLS) 12 | 13 | set(LIB s2core) 14 | set(APP station) 15 | -------------------------------------------------------------------------------- /basicstation/patches/005-change_branch_in_sx1302.patch: -------------------------------------------------------------------------------- 1 | Index: basicstation-2.0.5/deps/lgw1302/CMakeLists.txt.in 2 | =================================================================== 3 | --- basicstation-2.0.5.orig/deps/lgw1302/CMakeLists.txt.in 4 | +++ basicstation-2.0.5/deps/lgw1302/CMakeLists.txt.in 5 | @@ -7,7 +7,7 @@ include(ExternalProject) 6 | ExternalProject_Add( 7 | lora_gateway 8 | GIT_REPOSITORY "https://github.com/xueliu/sx1302_hal.git" 9 | - GIT_TAG "feature/basicstation" 10 | + GIT_TAG "feature/openwrt" 11 | UPDATE_COMMAND "" 12 | PATCH_COMMAND "" 13 | SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/sx1302_hal-src" 14 | -------------------------------------------------------------------------------- /chirpstack-application-server/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=chirpstack-application-server 4 | PKG_VERSION:=3.5.1 5 | PKG_RELEASE:=1 6 | 7 | PKG_SOURCE_URL:=https://codeload.github.com/brocaar/chirpstack-application-server/tar.gz/v$(PKG_VERSION)? 8 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 9 | 10 | PKG_HASH:=a775aaf0b773efe87b043942d9038a50c3dc96d1a91b2aa8def5487f0aa1c4a5 11 | PKG_MAINTAINER:=Xue Liu 12 | PKG_LICENSE:MIT 13 | PKG_LICENSE_FILES:=LICENSE 14 | 15 | PKG_BUILD_DEPENDS:=golang/host 16 | PKG_BUILD_PARALLEL:=1 17 | PKG_USE_MIPS16:=0 18 | 19 | GO_PKG:=github.com/brocaar/chirpstack-application-server 20 | GO_PKG_BUILD_PKG:=github.com/brocaar/chirpstack-application-server/cmd/chirpstack-application-server 21 | 22 | include $(INCLUDE_DIR)/package.mk 23 | # golang-package.mk should be relocate regarding the env 24 | include $(INCLUDE_DIR)/../feeds/packages/lang/golang/golang-package.mk 25 | 26 | define Package/chirpstack-application-server 27 | SECTION:=net 28 | CATEGORY:=Network 29 | SUBMENU:=LoRaWAN 30 | TITLE:=LoRa App Server 31 | DEPENDS:=$(GO_ARCH_DEPENDS) 32 | PKGARCH:=all 33 | endef 34 | 35 | define Package/chirpstack-application-server/description 36 | ChirpStack Application Server is an open-source LoRaWAN Application Server, 37 | part of the ChirpStack open-source LoRaWAN Network Server stack. 38 | It is responsible for the node "inventory" part of a LoRaWAN infrastructure, handling of 39 | received application payloads and the downlink application payload queue. 40 | It comes with a web-interface and API (RESTful JSON and gRPC) and supports authorization by 41 | using JWT tokens (optional). Received payloads are published over MQTT and payloads 42 | can be enqueued by using MQTT or the API. 43 | endef 44 | 45 | GO_PKG_LDFLAGS:=-s -w 46 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) 47 | 48 | define Build/Prepare 49 | $(call Build/Prepare/Default) 50 | @echo "Installing UI requirements" 51 | @cd $(PKG_BUILD_DIR)/ui && npm install 52 | 53 | @echo "Building ui" 54 | @cd $(PKG_BUILD_DIR)/ui && npm run build 55 | @mv $(PKG_BUILD_DIR)/ui/build/* $(PKG_BUILD_DIR)/static 56 | 57 | @echo "Generating combined Swagger JSON" 58 | @GOOS="" GOARCH="" go run $(PKG_BUILD_DIR)/api/swagger/main.go $(PKG_BUILD_DIR)/api/swagger > $(PKG_BUILD_DIR)/static/swagger/api.swagger.json 59 | @cp $(PKG_BUILD_DIR)/api/swagger/*.json $(PKG_BUILD_DIR)/static/swagger 60 | 61 | @echo "Generating static files" 62 | @go generate $(PKG_BUILD_DIR)/internal/migrations/migrations.go 63 | @go generate $(PKG_BUILD_DIR)/internal/static/static.go 64 | endef 65 | 66 | define Package/chirpstack-application-server/install 67 | $(call GoPackage/Package/Install/Bin,$(1)) 68 | 69 | $(INSTALL_DIR) $(1)/etc/init.d/ 70 | $(INSTALL_BIN) ./files/chirpstack-application-server.init $(1)/etc/init.d/chirpstack-application-server 71 | endef 72 | 73 | $(eval $(call GoBinPackage,chirpstack-application-server)) 74 | $(eval $(call BuildPackage,chirpstack-application-server)) 75 | -------------------------------------------------------------------------------- /chirpstack-application-server/files/chirpstack-application-server.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=90 4 | STOP=10 5 | 6 | USE_PROCD=1 7 | PROG=/usr/bin/chirpstack-application-server 8 | 9 | start_service() { 10 | procd_open_instance 11 | procd_set_param command ${PROG} 12 | procd_set_param respawn 13 | procd_set_param stdout 1 # forward stdout of the command to logd 14 | procd_set_param stderr 1 # same for stderr 15 | procd_close_instance 16 | } 17 | -------------------------------------------------------------------------------- /chirpstack-application-server/files/lora-app-server.toml: -------------------------------------------------------------------------------- 1 | [general] 2 | # Log level 3 | # 4 | # debug=5, info=4, warning=3, error=2, fatal=1, panic=0 5 | log_level=4 6 | 7 | # The number of times passwords must be hashed. A higher number is safer as 8 | # an attack takes more time to perform. 9 | password_hash_iterations=100000 10 | 11 | 12 | # PostgreSQL settings. 13 | # 14 | # Please note that PostgreSQL 9.5+ is required. 15 | [postgresql] 16 | # PostgreSQL dsn (e.g.: postgres://user:password@hostname/database?sslmode=disable). 17 | # 18 | # Besides using an URL (e.g. 'postgres://user:password@hostname/database?sslmode=disable') 19 | # it is also possible to use the following format: 20 | # 'user=loraserver dbname=loraserver sslmode=disable'. 21 | # 22 | # The following connection parameters are supported: 23 | # 24 | # * dbname - The name of the database to connect to 25 | # * user - The user to sign in as 26 | # * password - The user's password 27 | # * host - The host to connect to. Values that start with / are for unix domain sockets. (default is localhost) 28 | # * port - The port to bind to. (default is 5432) 29 | # * sslmode - Whether or not to use SSL (default is require, this is not the default for libpq) 30 | # * fallback_application_name - An application_name to fall back to if one isn't provided. 31 | # * connect_timeout - Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely. 32 | # * sslcert - Cert file location. The file must contain PEM encoded data. 33 | # * sslkey - Key file location. The file must contain PEM encoded data. 34 | # * sslrootcert - The location of the root certificate file. The file must contain PEM encoded data. 35 | # 36 | # Valid values for sslmode are: 37 | # 38 | # * disable - No SSL 39 | # * require - Always SSL (skip verification) 40 | # * verify-ca - Always SSL (verify that the certificate presented by the server was signed by a trusted CA) 41 | # * verify-full - Always SSL (verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate) 42 | dsn="postgres://localhost/loraserver_as?sslmode=disable" 43 | 44 | # Automatically apply database migrations. 45 | # 46 | # It is possible to apply the database-migrations by hand 47 | # (see https://github.com/brocaar/lora-app-server/tree/master/migrations) 48 | # or let LoRa App Server migrate to the latest state automatically, by using 49 | # this setting. Make sure that you always make a backup when upgrading Lora 50 | # App Server and / or applying migrations. 51 | automigrate=true 52 | 53 | 54 | # Redis settings 55 | # 56 | # Please note that Redis 2.6.0+ is required. 57 | [redis] 58 | # Redis url (e.g. redis://user:password@hostname/0) 59 | # 60 | # For more information about the Redis URL format, see: 61 | # https://www.iana.org/assignments/uri-schemes/prov/redis 62 | url="redis://localhost:6379" 63 | 64 | # Max idle connections in the pool. 65 | max_idle=10 66 | 67 | # Idle timeout. 68 | # 69 | # Close connections after remaining idle for this duration. If the value 70 | # is zero, then idle connections are not closed. You should set 71 | # the timeout to a value less than the server's timeout. 72 | idle_timeout="5m0s" 73 | 74 | 75 | # Application-server settings. 76 | [application_server] 77 | # Application-server identifier. 78 | # 79 | # Random UUID defining the id of the application-server installation (used by 80 | # LoRa Server as routing-profile id). 81 | # For now it is recommended to not change this id. 82 | id="6d5db27e-4ce2-4b2b-b5d7-91f069397978" 83 | 84 | 85 | # JavaScript codec settings. 86 | [application_server.codec.js] 87 | # Maximum execution time. 88 | max_execution_time="100ms" 89 | 90 | 91 | # Integration configures the data integration. 92 | # 93 | # This is the data integration which is available for all applications, 94 | # besides the extra integrations that can be added on a per-application 95 | # basis. 96 | [application_server.integration] 97 | # Enabled integrations. 98 | # 99 | # Enabled integrations are enabled for all applications. Multiple 100 | # integrations can be configured. 101 | # Do not forget to configure the related configuration section below for 102 | # the enabled integrations. Integrations that can be enabled are: 103 | # * mqtt - MQTT broker 104 | # * aws_sns - AWS Simple Notification Service (SNS) 105 | # * azure_service_bus - Azure Service-Bus 106 | # * gcp_pub_sub - Google Cloud Pub/Sub 107 | # * postgresql - PostgreSQL database 108 | enabled=["mqtt"] 109 | 110 | 111 | # MQTT integration backend. 112 | [application_server.integration.mqtt] 113 | # MQTT topic templates for the different MQTT topics. 114 | # 115 | # The meaning of these topics are documented at: 116 | # https://www.loraserver.io/lora-app-server/integrate/data/ 117 | # 118 | # The following substitutions can be used: 119 | # * "{{ .ApplicationID }}" for the application id. 120 | # * "{{ .DevEUI }}" for the DevEUI of the device. 121 | # 122 | # Note: the downlink_topic_template must contain both the application id and 123 | # DevEUI substitution! 124 | uplink_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/rx" 125 | downlink_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/tx" 126 | join_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/join" 127 | ack_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/ack" 128 | error_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/error" 129 | status_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/status" 130 | location_topic_template="application/{{ .ApplicationID }}/device/{{ .DevEUI }}/location" 131 | 132 | # Retained messages configuration. 133 | # 134 | # The MQTT broker will store the last publised message, when retained message is set 135 | # to true. When a client subscribes to a topic with retained message set to true, it will 136 | # always receive the last published message. 137 | uplink_retained_message=false 138 | join_retained_message=false 139 | ack_retained_message=false 140 | error_retained_message=false 141 | status_retained_message=false 142 | location_retained_message=false 143 | 144 | # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) 145 | server="tcp://localhost:1883" 146 | 147 | # Connect with the given username (optional) 148 | username="" 149 | 150 | # Connect with the given password (optional) 151 | password="" 152 | 153 | # Quality of service level 154 | # 155 | # 0: at most once 156 | # 1: at least once 157 | # 2: exactly once 158 | # 159 | # Note: an increase of this value will decrease the performance. 160 | # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels 161 | qos=0 162 | 163 | # Clean session 164 | # 165 | # Set the "clean session" flag in the connect message when this client 166 | # connects to an MQTT broker. By setting this flag you are indicating 167 | # that no messages saved by the broker for this client should be delivered. 168 | clean_session=true 169 | 170 | # Client ID 171 | # 172 | # Set the client id to be used by this client when connecting to the MQTT 173 | # broker. A client id must be no longer than 23 characters. When left blank, 174 | # a random id will be generated. This requires clean_session=true. 175 | client_id="" 176 | 177 | # CA certificate file (optional) 178 | # 179 | # Use this when setting up a secure connection (when server uses ssl://...) 180 | # but the certificate used by the server is not trusted by any CA certificate 181 | # on the server (e.g. when self generated). 182 | ca_cert="" 183 | 184 | # TLS certificate file (optional) 185 | tls_cert="" 186 | 187 | # TLS key file (optional) 188 | tls_key="" 189 | 190 | 191 | # AWS Simple Notification Service (SNS) 192 | [application_server.integration.aws_sns] 193 | # AWS region. 194 | # 195 | # Example: "eu-west-1". 196 | # See also: https://docs.aws.amazon.com/general/latest/gr/rande.html. 197 | aws_region="" 198 | 199 | # AWS Access Key ID. 200 | aws_access_key_id="" 201 | 202 | # AWS Secret Access Key. 203 | aws_secret_access_key="" 204 | 205 | # Topic ARN (SNS). 206 | topic_arn="" 207 | 208 | 209 | # Azure Service-Bus integration. 210 | [application_server.integration.azure_service_bus] 211 | # Connection string. 212 | # 213 | # The connection string can be found / created in the Azure console under 214 | # Settings -> Shared access policies. The policy must contain Manage & Send. 215 | connection_string="" 216 | 217 | # Publish mode. 218 | # 219 | # Select either "topic", or "queue". 220 | publish_mode="" 221 | 222 | # Publish name. 223 | # 224 | # The name of the topic or queue. 225 | publish_name="" 226 | 227 | 228 | # Google Cloud Pub/Sub integration. 229 | [application_server.integration.gcp_pub_sub] 230 | # Path to the IAM service-account credentials file. 231 | # 232 | # Note: this service-account must have the following Pub/Sub roles: 233 | # * Pub/Sub Editor 234 | credentials_file="" 235 | 236 | # Google Cloud project id. 237 | project_id="" 238 | 239 | # Pub/Sub topic name. 240 | topic_name="" 241 | 242 | 243 | # PostgreSQL database integration. 244 | [application_server.integration.postgresql] 245 | # PostgreSQL dsn (e.g.: postgres://user:password@hostname/database?sslmode=disable). 246 | dsn="" 247 | 248 | 249 | # Settings for the "internal api" 250 | # 251 | # This is the API used by LoRa Server to communicate with LoRa App Server 252 | # and should not be exposed to the end-user. 253 | [application_server.api] 254 | # ip:port to bind the api server 255 | bind="0.0.0.0:8001" 256 | 257 | # ca certificate used by the api server (optional) 258 | ca_cert="" 259 | 260 | # tls certificate used by the api server (optional) 261 | tls_cert="" 262 | 263 | # tls key used by the api server (optional) 264 | tls_key="" 265 | 266 | # Public ip:port of the application-server API. 267 | # 268 | # This is used by LoRa Server to connect to LoRa App Server. When running 269 | # LoRa App Server on a different host than LoRa Server, make sure to set 270 | # this to the host:ip on which LoRa Server can reach LoRa App Server. 271 | # The port must be equal to the port configured by the 'bind' flag 272 | # above. 273 | public_host="localhost:8001" 274 | 275 | 276 | # Settings for the "external api" 277 | # 278 | # This is the API and web-interface exposed to the end-user. 279 | [application_server.external_api] 280 | # ip:port to bind the (user facing) http server to (web-interface and REST / gRPC api) 281 | bind="0.0.0.0:8080" 282 | 283 | # http server TLS certificate (optional) 284 | tls_cert="" 285 | 286 | # http server TLS key (optional) 287 | tls_key="" 288 | 289 | # JWT secret used for api authentication / authorization 290 | # You could generate this by executing 'openssl rand -base64 32' for example 291 | jwt_secret="" 292 | 293 | # Allow origin header (CORS). 294 | # 295 | # Set this to allows cross-domain communication from the browser (CORS). 296 | # Example value: https://example.com. 297 | # When left blank (default), CORS will not be used. 298 | cors_allow_origin="" 299 | 300 | # when set, existing users can't be re-assigned (to avoid exposure of all users to an organization admin)" 301 | disable_assign_existing_users=false 302 | 303 | 304 | # Settings for the remote multicast setup. 305 | [application_server.remote_multicast_setup] 306 | # Synchronization interval. 307 | sync_interval="1s" 308 | 309 | # Synchronization retries. 310 | sync_retries=3 311 | 312 | # Synchronization batch-size. 313 | sync_batch_size=100 314 | 315 | 316 | # Settings for the fragmentation-session setup. 317 | [application_server.fragmentation_session] 318 | # Synchronization interval. 319 | sync_interval="1s" 320 | 321 | # Synchronization retries. 322 | sync_retries=3 323 | 324 | # Synchronization batch-size. 325 | sync_batch_size=100 326 | 327 | 328 | 329 | # Join-server configuration. 330 | # 331 | # LoRa App Server implements a (subset) of the join-api specified by the 332 | # LoRaWAN Backend Interfaces specification. This API is used by LoRa Server 333 | # to handle join-requests. 334 | [join_server] 335 | # ip:port to bind the join-server api interface to 336 | bind="0.0.0.0:8003" 337 | 338 | # CA certificate (optional). 339 | # 340 | # When set, the server requires a client-certificate and will validate this 341 | # certificate on incoming requests. 342 | ca_cert="" 343 | 344 | # TLS server-certificate (optional). 345 | # 346 | # Set this to enable TLS. 347 | tls_cert="" 348 | 349 | # TLS server-certificate key (optional). 350 | # 351 | # Set this to enable TLS. 352 | tls_key="" 353 | 354 | 355 | # Key Encryption Key (KEK) configuration. 356 | # 357 | # The KEK meganism is used to encrypt the session-keys sent from the 358 | # join-server to the network-server. 359 | # 360 | # The LoRa App Server join-server will use the NetID of the requesting 361 | # network-server as the KEK label. When no such label exists in the set, 362 | # the session-keys will be sent unencrypted (which can be fine for 363 | # private networks). 364 | # 365 | # Please refer to the LoRaWAN Backend Interface specification 366 | # 'Key Transport Security' section for more information. 367 | [join_server.kek] 368 | 369 | # Application-server KEK label. 370 | # 371 | # This defines the KEK label used to encrypt the AppSKey (note that the 372 | # AppSKey is signaled to the NS and on the first received uplink from the 373 | # NS to the AS). 374 | # 375 | # When left blank, the AppSKey will be sent unencrypted (which can be fine 376 | # for private networks). 377 | as_kek_label="" 378 | 379 | # KEK set. 380 | # 381 | # Example (the [[join_server.kek.set]] can be repeated): 382 | # [[join_server.kek.set]] 383 | # # KEK label. 384 | # label="000000" 385 | 386 | # # Key Encryption Key. 387 | # kek="01020304050607080102030405060708" 388 | 389 | 390 | # Metrics collection settings. 391 | [metrics] 392 | # Metrics stored in Prometheus. 393 | # 394 | # These metrics expose information about the state of the LoRa Server 395 | # instance. 396 | [metrics.prometheus] 397 | # Enable Prometheus metrics endpoint. 398 | endpoint_enabled=false 399 | 400 | # The ip:port to bind the Prometheus metrics server to for serving the 401 | # metrics endpoint. 402 | bind="" 403 | 404 | # API timing histogram. 405 | # 406 | # By setting this to true, the API request timing histogram will be enabled. 407 | # See also: https://github.com/grpc-ecosystem/go-grpc-prometheus#histograms 408 | api_timing_histogram=false 409 | -------------------------------------------------------------------------------- /chirpstack-gateway-bridge/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=chirpstack-gateway-bridge 4 | PKG_VERSION:=3.4.1 5 | PKG_RELEASE:=1 6 | 7 | PKG_SOURCE_URL:=https://codeload.github.com/brocaar/chirpstack-gateway-bridge/tar.gz/v$(PKG_VERSION)? 8 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 9 | 10 | PKG_HASH:=8ae9e34c55ea776a780cb24f748c9eff0a1bc3dc522e25e89142ea554aacaca8 11 | PKG_MAINTAINER:=Xue Liu 12 | PKG_LICENSE:MIT 13 | PKG_LICENSE_FILES:=LICENSE 14 | 15 | PKG_BUILD_DEPENDS:=golang/host 16 | PKG_BUILD_PARALLEL:=1 17 | PKG_USE_MIPS16:=0 18 | 19 | GO_PKG:=github.com/brocaar/chirpstack-gateway-bridge 20 | GO_PKG_BUILD_PKG:=github.com/brocaar/chirpstack-gateway-bridge/cmd/chirpstack-gateway-bridge 21 | 22 | include $(INCLUDE_DIR)/package.mk 23 | # golang-package.mk should be relocate regarding the env 24 | include $(INCLUDE_DIR)/../feeds/packages/lang/golang/golang-package.mk 25 | 26 | define Package/chirpstack-gateway-bridge 27 | SECTION:=net 28 | CATEGORY:=Network 29 | SUBMENU:=LoRaWAN 30 | TITLE:=Chirpstack Gateway Bridge 31 | DEPENDS:=$(GO_ARCH_DEPENDS) +mosquitto-ssl 32 | PKGARCH:=all 33 | endef 34 | 35 | define Package/chirpstack-gateway-bridge/description 36 | ChirpStack Gateway Bridge is a service which converts LoRa packet-forwarder 37 | protocols into a ChirpStack Network Server common protocol (JSON and Protobuf). 38 | endef 39 | 40 | GO_PKG_LDFLAGS:=-s -w 41 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) 42 | 43 | define Package/chirpstack-gateway-bridge/install 44 | $(call GoPackage/Package/Install/Bin,$(1)) 45 | 46 | $(INSTALL_DIR) $(1)/etc/init.d/ 47 | $(INSTALL_BIN) ./files/chirpstack-gateway-bridge.init $(1)/etc/init.d/chirpstack-gateway-bridge 48 | 49 | $(INSTALL_DIR) $(1)/etc/chirpstack-gateway-bridge 50 | $(INSTALL_DATA) ./files/chirpstack-gateway-bridge.toml $(1)/etc/chirpstack-gateway-bridge/ 51 | endef 52 | 53 | $(eval $(call GoBinPackage,chirpstack-gateway-bridge)) 54 | $(eval $(call BuildPackage,chirpstack-gateway-bridge)) 55 | -------------------------------------------------------------------------------- /chirpstack-gateway-bridge/files/chirpstack-gateway-bridge.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=90 4 | STOP=10 5 | 6 | USE_PROCD=1 7 | PROG=/usr/bin/chirpstack-gateway-bridge 8 | 9 | start_service() { 10 | procd_open_instance 11 | procd_set_param command ${PROG} 12 | procd_set_param respawn 13 | procd_set_param stdout 1 # forward stdout of the command to logd 14 | procd_set_param stderr 1 # same for stderr 15 | procd_close_instance 16 | } 17 | -------------------------------------------------------------------------------- /chirpstack-gateway-bridge/files/chirpstack-gateway-bridge.toml: -------------------------------------------------------------------------------- 1 | [general] 2 | # debug=5, info=4, warning=3, error=2, fatal=1, panic=0 3 | log_level = 4 4 | 5 | 6 | # Filters. 7 | # 8 | # These can be used to filter LoRaWAN frames to reduce bandwith usage between 9 | # the gateway and LoRa Gateway Bride. Depending the used backend, filtering 10 | # will be performed by the Packet Forwarder or LoRa Gateway Bridge. 11 | [filters] 12 | 13 | # NetIDs filters. 14 | # 15 | # The configured NetIDs will be used to filter uplink data frames. 16 | # When left blank, no filtering will be performed on NetIDs. 17 | # 18 | # Example: 19 | # net_ids=[ 20 | # "000000", 21 | # "000001", 22 | # ] 23 | net_ids=[ 24 | ] 25 | 26 | # JoinEUI filters. 27 | # 28 | # The configured JoinEUI ranges will be used to filter join-requests. 29 | # When left blank, no filtering will be performed on JoinEUIs. 30 | # 31 | # Example: 32 | # join_euis=[ 33 | # ["0000000000000000", "00000000000000ff"], 34 | # ["000000000000ff00", "000000000000ffff"], 35 | # ] 36 | join_euis=[ 37 | ] 38 | 39 | 40 | # Gateway backend configuration. 41 | [backend] 42 | 43 | # Backend type. 44 | # 45 | # Valid options are: 46 | # * semtech_udp 47 | # * basic_station 48 | type="semtech_udp" 49 | 50 | 51 | # Semtech UDP packet-forwarder backend. 52 | [backend.semtech_udp] 53 | 54 | # ip:port to bind the UDP listener to 55 | # 56 | # Example: 0.0.0.0:1700 to listen on port 1700 for all network interfaces. 57 | # This is the listeren to which the packet-forwarder forwards its data 58 | # so make sure the 'serv_port_up' and 'serv_port_down' from your 59 | # packet-forwarder matches this port. 60 | udp_bind = "0.0.0.0:1700" 61 | 62 | # Skip the CRC status-check of received packets 63 | # 64 | # This is only has effect when the packet-forwarder is configured to forward 65 | # LoRa frames with CRC errors. 66 | skip_crc_check = false 67 | 68 | # Fake RX timestamp. 69 | # 70 | # Fake the RX time when the gateway does not have GPS, in which case 71 | # the time would otherwise be unset. 72 | fake_rx_time=false 73 | 74 | 75 | 76 | # Basic Station backend. 77 | [backend.basic_station] 78 | 79 | # ip:port to bind the Websocket listener to. 80 | bind=":3001" 81 | 82 | # TLS certificate and key files. 83 | # 84 | # When set, the websocket listener will use TLS to secure the connections 85 | # between the gateways and LoRa Gateway Bridge (optional). 86 | tls_cert="" 87 | tls_key="" 88 | 89 | # TLS CA certificate. 90 | # 91 | # When configured, LoRa Gateway Bridge will validate that the client 92 | # certificate of the gateway has been signed by this CA certificate. 93 | ca_cert="" 94 | 95 | # Ping interval. 96 | ping_interval="1m0s" 97 | 98 | # Read timeout. 99 | # 100 | # This interval must be greater than the configured ping interval. 101 | read_timeout="1m5s" 102 | 103 | # Write timeout. 104 | write_timeout="1s" 105 | 106 | # Region. 107 | # 108 | # Please refer to the LoRaWAN Regional Parameters specification 109 | # for the complete list of common region names. 110 | region="EU868" 111 | 112 | # Minimal frequency (Hz). 113 | frequency_min=863000000 114 | 115 | # Maximum frequency (Hz). 116 | frequency_max=870000000 117 | 118 | 119 | # Integration configuration. 120 | [integration] 121 | # Payload marshaler. 122 | # 123 | # This defines how the MQTT payloads are encoded. Valid options are: 124 | # * protobuf: Protobuf encoding (this will become the LoRa Gateway Bridge v3 default) 125 | # * json: JSON encoding (easier for debugging, but less compact than 'protobuf') 126 | marshaler="protobuf" 127 | 128 | # MQTT integration configuration. 129 | [integration.mqtt] 130 | # Event topic template. 131 | event_topic_template="gateway/{{ .GatewayID }}/event/{{ .EventType }}" 132 | 133 | # Command topic template. 134 | command_topic_template="gateway/{{ .GatewayID }}/command/#" 135 | 136 | # Maximum interval that will be waited between reconnection attempts when connection is lost. 137 | # Valid units are 'ms', 's', 'm', 'h'. Note that these values can be combined, e.g. '24h30m15s'. 138 | max_reconnect_interval="10m0s" 139 | 140 | 141 | # MQTT authentication. 142 | [integration.mqtt.auth] 143 | # Type defines the MQTT authentication type to use. 144 | # 145 | # Set this to the name of one of the sections below. 146 | type="generic" 147 | 148 | # Generic MQTT authentication. 149 | [integration.mqtt.auth.generic] 150 | # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) 151 | server="tcp://127.0.0.1:1883" 152 | 153 | # Connect with the given username (optional) 154 | username="" 155 | 156 | # Connect with the given password (optional) 157 | password="" 158 | 159 | # Quality of service level 160 | # 161 | # 0: at most once 162 | # 1: at least once 163 | # 2: exactly once 164 | # 165 | # Note: an increase of this value will decrease the performance. 166 | # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels 167 | qos=0 168 | 169 | # Clean session 170 | # 171 | # Set the "clean session" flag in the connect message when this client 172 | # connects to an MQTT broker. By setting this flag you are indicating 173 | # that no messages saved by the broker for this client should be delivered. 174 | clean_session=true 175 | 176 | # Client ID 177 | # 178 | # Set the client id to be used by this client when connecting to the MQTT 179 | # broker. A client id must be no longer than 23 characters. When left blank, 180 | # a random id will be generated. This requires clean_session=true. 181 | client_id="" 182 | 183 | # CA certificate file (optional) 184 | # 185 | # Use this when setting up a secure connection (when server uses ssl://...) 186 | # but the certificate used by the server is not trusted by any CA certificate 187 | # on the server (e.g. when self generated). 188 | ca_cert="" 189 | 190 | # mqtt TLS certificate file (optional) 191 | tls_cert="" 192 | 193 | # mqtt TLS key file (optional) 194 | tls_key="" 195 | 196 | 197 | # Google Cloud Platform Cloud IoT Core authentication. 198 | # 199 | # Please note that when using this authentication type, the MQTT topics 200 | # will be automatically set to match the MQTT topics as expected by 201 | # Cloud IoT Core. 202 | [integration.mqtt.auth.gcp_cloud_iot_core] 203 | # MQTT server. 204 | server="ssl://mqtt.googleapis.com:8883" 205 | 206 | # Google Cloud IoT Core Device id. 207 | device_id="" 208 | 209 | # Google Cloud project id. 210 | project_id="" 211 | 212 | # Google Cloud region. 213 | cloud_region="" 214 | 215 | # Google Cloud IoT registry id. 216 | registry_id="" 217 | 218 | # JWT token expiration time. 219 | jwt_expiration="24h0m0s" 220 | 221 | # JWT token key-file. 222 | # 223 | # Example command to generate a key-pair: 224 | # $ ssh-keygen -t rsa -b 4096 -f private-key.pem 225 | # $ openssl rsa -in private-key.pem -pubout -outform PEM -out public-key.pem 226 | # 227 | # Then point the setting below to the private-key.pem and associate the 228 | # public-key.pem with this device / gateway in Google Cloud IoT Core. 229 | jwt_key_file="" 230 | 231 | 232 | # Azure IoT Hub 233 | # 234 | # This setting will preset uplink and downlink topics that will only 235 | # work with Azure IoT Hub service. 236 | [integration.mqtt.auth.azure_iot_hub] 237 | 238 | # Device connection string (symmetric key authentication). 239 | # 240 | # This connection string can be retrieved from the Azure IoT Hub device 241 | # details when using the symmetric key authentication type. 242 | device_connection_string="" 243 | 244 | # Token expiration (symmetric key authentication). 245 | # 246 | # LoRa Gateway Bridge will generate a SAS token with the given expiration. 247 | # After the token has expired, it will generate a new one and trigger a 248 | # re-connect (only for symmetric key authentication). 249 | sas_token_expiration="24h0m0s" 250 | 251 | # Device ID (X.509 authentication). 252 | # 253 | # This will be automatically set when a device connection string is given. 254 | # It must be set for X.509 authentication. 255 | device_id="" 256 | 257 | # IoT Hub hostname (X.509 authentication). 258 | # 259 | # This will be automatically set when a device connection string is given. 260 | # It must be set for X.509 authentication. 261 | # Example: iot-hub-name.azure-devices.net 262 | hostname="" 263 | 264 | # Client certificates (X.509 authentication). 265 | # 266 | # Configure the tls_cert (certificate file) and tls_key (private-key file) 267 | # when the device is configured with X.509 authentication. 268 | tls_cert="" 269 | tls_key="" 270 | 271 | 272 | # Metrics configuration. 273 | [metrics] 274 | 275 | # Metrics stored in Prometheus. 276 | # 277 | # These metrics expose information about the state of the LoRa Gateway Bridge 278 | # instance like number of messages processed, number of function calls, etc. 279 | [metrics.prometheus] 280 | # Expose Prometheus metrics endpoint. 281 | endpoint_enabled=false 282 | 283 | # The ip:port to bind the Prometheus metrics server to for serving the 284 | # metrics endpoint. 285 | bind="" 286 | 287 | 288 | # Gateway meta-data. 289 | # 290 | # The meta-data will be added to every stats message sent by the LoRa Gateway 291 | # Bridge. 292 | [meta_data] 293 | 294 | # Static. 295 | # 296 | # Static key (string) / value (string) meta-data. 297 | [meta_data.static] 298 | # Example: 299 | # serial_number="A1B21234" 300 | 301 | 302 | 303 | # Dynamic meta-data. 304 | # 305 | # Dynamic meta-data is retrieved by executing external commands. 306 | # This makes it possible to for example execute an external command to 307 | # read the gateway temperature. 308 | [meta_data.dynamic] 309 | 310 | # Execution interval of the commands. 311 | execution_interval="1m0s" 312 | 313 | # Max. execution duration. 314 | max_execution_duration="1s" 315 | 316 | # Commands to execute. 317 | # 318 | # The value of the stdout will be used as the key value (string). 319 | # In case the command failed, it is ignored. In case the same key is defined 320 | # both as static and dynamic, the dynamic value has priority (as long as the) 321 | # command does not fail. 322 | [meta_data.dynamic.commands] 323 | # Example: 324 | # temperature="/opt/gateway-temperature/gateway-temperature.sh" 325 | 326 | 327 | # Executable commands. 328 | # 329 | # The configured commands can be triggered by sending a message to the 330 | # LoRa Gateway Bridge. 331 | [commands] 332 | # Example: 333 | # [commands.commands.reboot] 334 | # max_execution_duration="1s" 335 | # command="/usr/bin/reboot" 336 | 337 | -------------------------------------------------------------------------------- /chirpstack-geolocation-server/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=chirpstack-geolocation-server 4 | PKG_VERSION:=3.3.1 5 | PKG_RELEASE:=1 6 | 7 | PKG_SOURCE_URL:=https://codeload.github.com/brocaar/chirpstack-geolocation-server/tar.gz/v$(PKG_VERSION)? 8 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 9 | 10 | PKG_HASH:=d8dee3455b748a1944624327311eedd3d7fd9f8915ecd0a148fa0a3f7cff3c1e 11 | PKG_MAINTAINER:=Xue Liu 12 | PKG_LICENSE:MIT 13 | PKG_LICENSE_FILES:=LICENSE 14 | 15 | PKG_BUILD_DEPENDS:=golang/host 16 | PKG_BUILD_PARALLEL:=1 17 | PKG_USE_MIPS16:=0 18 | 19 | GO_PKG:=github.com/brocaar/chirpstack-geolocation-server 20 | GO_PKG_BUILD_PKG:=github.com/brocaar/chirpstack-geolocation-server/cmd/chirpstack-geolocation-server 21 | 22 | include $(INCLUDE_DIR)/package.mk 23 | # golang-package.mk should be relocate regarding the env 24 | include $(INCLUDE_DIR)/../feeds/packages/lang/golang/golang-package.mk 25 | 26 | define Package/chirpstack-geolocation-server 27 | SECTION:=net 28 | CATEGORY:=Network 29 | SUBMENU:=LoRaWAN 30 | TITLE:=ChirpStack Geolocation Server 31 | DEPENDS:=$(GO_ARCH_DEPENDS) 32 | PKGARCH:=all 33 | endef 34 | 35 | define Package/chirpstack-geolocation-server/description 36 | ChirpStack Geolocation Server provides a geolocation server for geolocation of LoRaWAN devices. 37 | It is part of the ChirpStack open-source LoRaWAN Network Server stack.. 38 | endef 39 | 40 | GO_PKG_LDFLAGS:=-s -w 41 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) 42 | 43 | define Package/chirpstack-geolocation-server/install 44 | $(call GoPackage/Package/Install/Bin,$(1)) 45 | 46 | $(INSTALL_DIR) $(1)/etc/init.d/ 47 | $(INSTALL_BIN) ./files/chirpstack-geolocation-server.init $(1)/etc/init.d/chirpstack-geolocation-server 48 | endef 49 | 50 | $(eval $(call GoBinPackage,chirpstack-geolocation-server)) 51 | $(eval $(call BuildPackage,chirpstack-geolocation-server)) 52 | -------------------------------------------------------------------------------- /chirpstack-geolocation-server/files/chirpstack-geolocation-server.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=90 4 | STOP=10 5 | 6 | USE_PROCD=1 7 | PROG=/usr/bin/chirpstack-geolocation-server 8 | 9 | start_service() { 10 | procd_open_instance 11 | procd_set_param command ${PROG} 12 | procd_set_param respawn 13 | procd_set_param stdout 1 # forward stdout of the command to logd 14 | procd_set_param stderr 1 # same for stderr 15 | procd_close_instance 16 | } 17 | -------------------------------------------------------------------------------- /chirpstack-geolocation-server/files/chirpstack-geolocation-server.toml: -------------------------------------------------------------------------------- 1 | [general] 2 | # Log level 3 | # 4 | # debug=5, info=4, warning=3, error=2, fatal=1, panic=0 5 | log_level=4 6 | 7 | # Geolocation-server configuration. 8 | [geo_server] 9 | # Geolocation API. 10 | # 11 | # This is the geolocation API that can be used by LoRa Server. 12 | [geo_server.api] 13 | # ip:port to bind the api server 14 | bind="0.0.0.0:8005" 15 | 16 | # CA certificate used by the api server (optional) 17 | ca_cert="" 18 | 19 | # TLS certificate used by the api server (optional) 20 | tls_cert="" 21 | 22 | # TLS key used by the api server (optional) 23 | tls_key="" 24 | 25 | 26 | # Geolocation backend configuration. 27 | [geo_server.backend] 28 | # Name. 29 | # 30 | # The name of the geolocation backend to use. 31 | name="collos" 32 | 33 | [geo_server.backend.collos] 34 | # Collos subscription key. 35 | # 36 | # This key can be retrieved after creating a Collos account at: 37 | # http://preview.collos.org/ 38 | subscription_key="" 39 | 40 | # Request timeout. 41 | # 42 | # This defines the request timeout when making calls to the Collos API. 43 | request_timeout="1s" 44 | -------------------------------------------------------------------------------- /chirpstack-network-server/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=chirpstack-network-server 4 | PKG_VERSION:=3.4.1 5 | PKG_RELEASE:=1 6 | 7 | PKG_SOURCE_URL:=https://codeload.github.com/brocaar/chirpstack-network-server/tar.gz/v$(PKG_VERSION)? 8 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 9 | 10 | PKG_HASH:=20e7c03c8f9b3bedde91e3b078b86b6cab2b470853374262e8ccbef012f78165 11 | PKG_MAINTAINER:=Xue Liu 12 | PKG_LICENSE:MIT 13 | PKG_LICENSE_FILES:=LICENSE 14 | 15 | PKG_BUILD_DEPENDS:=golang/host 16 | PKG_BUILD_PARALLEL:=1 17 | PKG_USE_MIPS16:=0 18 | 19 | GO_PKG:=github.com/brocaar/chirpstack-network-server 20 | GO_PKG_BUILD_PKG:=github.com/brocaar/chirpstack-network-server/cmd/chirpstack-network-server 21 | 22 | include $(INCLUDE_DIR)/package.mk 23 | # golang-package.mk should be relocate regarding the env 24 | include $(INCLUDE_DIR)/../feeds/packages/lang/golang/golang-package.mk 25 | 26 | define Package/chirpstack-network-server 27 | SECTION:=net 28 | CATEGORY:=Network 29 | SUBMENU:=LoRaWAN 30 | TITLE:=LoRa Server 31 | DEPENDS:=$(GO_ARCH_DEPENDS) 32 | PKGARCH:=all 33 | endef 34 | 35 | define Package/chirpstack-network-server/description 36 | ChirpStack Network Server is an open-source LoRaWAN network-server, part of ChirpStack. 37 | It is responsible for handling (and de-duplication) of uplink data received by the gateway(s) 38 | and the scheduling of downlink data transmissions. 39 | endef 40 | 41 | GO_PKG_LDFLAGS:=-s -w 42 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) 43 | 44 | define Build/Prepare 45 | $(call Build/Prepare/Default) 46 | # statics 47 | go generate $(PKG_BUILD_DIR)/internal/migrations/migrations.go 48 | endef 49 | 50 | define Package/chirpstack-network-server/install 51 | $(call GoPackage/Package/Install/Bin,$(1)) 52 | 53 | $(INSTALL_DIR) $(1)/etc/init.d/ 54 | $(INSTALL_BIN) ./files/chirpstack-network-server.init $(1)/etc/init.d/chirpstack-network-server 55 | endef 56 | 57 | $(eval $(call GoBinPackage,chirpstack-network-server)) 58 | $(eval $(call BuildPackage,chirpstack-network-server)) 59 | -------------------------------------------------------------------------------- /chirpstack-network-server/files/chirpstack-network-server.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=90 4 | STOP=10 5 | 6 | USE_PROCD=1 7 | PROG=/usr/bin/chirpstack-network-server 8 | 9 | start_service() { 10 | procd_open_instance 11 | procd_set_param command ${PROG} 12 | procd_set_param respawn 13 | procd_set_param stdout 1 # forward stdout of the command to logd 14 | procd_set_param stderr 1 # same for stderr 15 | procd_close_instance 16 | } 17 | -------------------------------------------------------------------------------- /lora-gateway-hal/Config.in: -------------------------------------------------------------------------------- 1 | # libloragw configuration 2 | 3 | if PACKAGE_libloragw 4 | 5 | config SX1301_SPI_PATH 6 | string "SPI Dev Path" 7 | default /dev/spidev0.0 8 | 9 | config SX1301_SPI_SPEED 10 | string "SPI Speed (Hz)" 11 | default 8000000 12 | 13 | endif 14 | -------------------------------------------------------------------------------- /lora-gateway-hal/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=lora-gateway-hal 11 | PKG_VERSION:=5.0.1 12 | PKG_RELEASE:=2 13 | 14 | PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/lora_gateway/tar.gz/v$(PKG_VERSION)? 15 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 16 | PKG_HASH:=1a0447d5e8183d08e6dce5f739f6872b9c57824b98f4078830d5ee21b15782c1 17 | PKG_MAINTAINER:=Xue Liu 18 | PKG_LICENSE_FILES:=LICENSE 19 | PKG_BUILD_DIR:=$(BUILD_DIR)/lora_gateway-$(PKG_VERSION) 20 | 21 | include $(INCLUDE_DIR)/package.mk 22 | include $(INCLUDE_DIR)/cmake.mk 23 | 24 | define Package/libloragw 25 | SECTION:=libs 26 | CATEGORY:=Libraries 27 | TITLE:=Driver/HAL library for Semtech SX1301 28 | URL:=https://www.semtech.com/products/wireless-rf/lora-gateways/sx1301 29 | DEPENDS:=+kmod-spi-dev 30 | endef 31 | 32 | define Package/libloragw/description 33 | Driver/HAL library for Semtech SX1301 multi-channel modem and 34 | SX1257/SX1255 RF transceivers. 35 | endef 36 | 37 | define Package/libloragw/config 38 | source "$(SOURCE)/Config.in" 39 | endef 40 | 41 | define Package/libloragw-tests 42 | SECTION:=net 43 | CATEGORY:=Network 44 | SUBMENU:=LoRaWAN 45 | TITLE:=Test programs for libloragw to check functionality 46 | DEPENDS:=libloragw 47 | endef 48 | 49 | define Package/libloragw-utils 50 | SECTION:=net 51 | CATEGORY:=Network 52 | SUBMENU:=LoRaWAN 53 | TITLE:=Utility programs for libloragw 54 | DEPENDS:=libloragw 55 | endef 56 | 57 | CMAKE_OPTIONS += \ 58 | -DSPI_DEV_PATH:FILEPATH=$(CONFIG_SX1301_SPI_PATH) \ 59 | -DSPI_SPEED:STRING=$(CONFIG_SX1301_SPI_SPEED) \ 60 | -Dlora_gateway_build_shared_libs=ON 61 | 62 | define Build/InstallDev 63 | $(INSTALL_DIR) $(1)/usr/include/libloragw 64 | $(CP) $(PKG_BUILD_DIR)/libloragw/inc/loragw_* $(1)/usr/include/libloragw 65 | $(CP) $(PKG_BUILD_DIR)/libloragw/config.h $(1)/usr/include/libloragw 66 | $(INSTALL_DIR) $(1)/usr/lib 67 | $(CP) $(PKG_BUILD_DIR)/libloragw/libloragw.so* $(1)/usr/lib/ 68 | $(LN) libloragw.so.0 $(1)/usr/lib/libloragw.so 69 | $(INSTALL_DIR) $(1)/usr/lib/pkgconfig 70 | $(CP) $(PKG_BUILD_DIR)/loragw.pc $(1)/usr/lib/pkgconfig/ 71 | endef 72 | 73 | define Package/libloragw/install 74 | $(INSTALL_DIR) $(1)/usr/lib 75 | $(CP) $(PKG_BUILD_DIR)/libloragw/libloragw.so.* $(1)/usr/lib/ 76 | endef 77 | 78 | define Package/libloragw-tests/install 79 | $(INSTALL_DIR) $(1)/usr/sbin 80 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/libloragw/test* $(1)/usr/sbin 81 | endef 82 | 83 | define Package/libloragw-utils/install 84 | $(INSTALL_DIR) $(1)/usr/sbin 85 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_lbt_test $(1)/usr/sbin 86 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_pkt_logger $(1)/usr/sbin 87 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_spectral_scan $(1)/usr/sbin 88 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_continuous $(1)/usr/sbin 89 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_spi_stress $(1)/usr/sbin 90 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_test $(1)/usr/sbin 91 | endef 92 | 93 | $(eval $(call BuildPackage,libloragw)) 94 | $(eval $(call BuildPackage,libloragw-tests)) 95 | $(eval $(call BuildPackage,libloragw-utils)) 96 | -------------------------------------------------------------------------------- /lora-gateway-hal/patches/0001-add-cmake-support.patch: -------------------------------------------------------------------------------- 1 | From d49e5ea2988b2086c7deaa40d3e077531e449844 Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Thu, 21 Feb 2019 00:27:42 +0100 4 | Subject: [PATCH 1/3] - add cmake support 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | CMakeLists.txt | 77 +++++++++++++++ 9 | cmake/loragw-config.cmake | 1 + 10 | libloragw/CMakeLists.txt | 150 ++++++++++++++++++++++++++++++ 11 | libloragw/loragw.pc.in | 10 ++ 12 | libloragw/loragw_config.h.in | 14 +++ 13 | util_lbt_test/CMakeLists.txt | 23 +++++ 14 | util_pkt_logger/CMakeLists.txt | 29 ++++++ 15 | util_spectral_scan/CMakeLists.txt | 23 +++++ 16 | util_spi_stress/CMakeLists.txt | 23 +++++ 17 | util_tx_continuous/CMakeLists.txt | 23 +++++ 18 | util_tx_test/CMakeLists.txt | 23 +++++ 19 | 11 files changed, 396 insertions(+) 20 | create mode 100644 CMakeLists.txt 21 | create mode 100644 cmake/loragw-config.cmake 22 | create mode 100644 libloragw/CMakeLists.txt 23 | create mode 100644 libloragw/loragw.pc.in 24 | create mode 100644 libloragw/loragw_config.h.in 25 | create mode 100644 util_lbt_test/CMakeLists.txt 26 | create mode 100644 util_pkt_logger/CMakeLists.txt 27 | create mode 100644 util_spectral_scan/CMakeLists.txt 28 | create mode 100644 util_spi_stress/CMakeLists.txt 29 | create mode 100644 util_tx_continuous/CMakeLists.txt 30 | create mode 100644 util_tx_test/CMakeLists.txt 31 | 32 | diff --git a/CMakeLists.txt b/CMakeLists.txt 33 | new file mode 100644 34 | index 0000000..b112150 35 | --- /dev/null 36 | +++ b/CMakeLists.txt 37 | @@ -0,0 +1,77 @@ 38 | +# -- Minimum required version 39 | +cmake_minimum_required (VERSION 3.2) 40 | + 41 | +# -- Project name 42 | +project (lora_gateway) 43 | + 44 | +# -- Various includes 45 | +include (CMakePackageConfigHelpers) 46 | +include (GNUInstallDirs) 47 | +include (CheckFunctionExists) 48 | + 49 | +# -- set c99 standard default 50 | +set(CMAKE_C_STANDARD 99) 51 | + 52 | +# -- options for shared lib (defaults off) 53 | +option(lora_gateway_build_shared_libs "build as a shared library" OFF) 54 | +set(BUILD_SHARED_LIBS ${lora_gateway_build_shared_libs}) 55 | + 56 | +# -- Required to build 57 | +set(CMAKE_THREAD_PREFER_PTHREAD TRUE) 58 | +set(THREADS_PREFER_PTHREAD_FLAG TRUE) 59 | +find_package(Threads REQUIRED) 60 | + 61 | +# -- Versioning with git tag 62 | +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 63 | + execute_process( 64 | + COMMAND git describe --tags --always 65 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 66 | + OUTPUT_VARIABLE "lora_gateway_VERSION" 67 | + ERROR_QUIET 68 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 69 | + if(lora_gateway_VERSION STREQUAL "") 70 | + set(lora_gateway_VERSION 0) 71 | + endif(lora_gateway_VERSION STREQUAL "") 72 | + message( STATUS "Git full version: ${lora_gateway_VERSION}" ) 73 | + execute_process( 74 | + COMMAND /bin/bash -c "git describe --tags --abbrev=0 | cut --delimiter='v' --fields=2" 75 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 76 | + OUTPUT_VARIABLE "lora_gateway_VERSION_SHORT" 77 | + ERROR_QUIET 78 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 79 | + if(lora_gateway_VERSION_SHORT STREQUAL "") 80 | + set(lora_gateway_VERSION_SHORT 0) 81 | + endif(lora_gateway_VERSION_SHORT STREQUAL "") 82 | + message( STATUS "Git version: ${lora_gateway_VERSION_SHORT}" ) 83 | +else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 84 | + set(lora_gateway_VERSION_SHORT 0) 85 | + set(lora_gateway_VERSION 0) 86 | +endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 87 | + 88 | +# when building, don't use the install RPATH already 89 | +# (but later on when installing) 90 | +SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 91 | +if (NOT (${CMAKE_INSTALL_PREFIX} STREQUAL "/usr" ) ) 92 | + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") 93 | +endif() 94 | + 95 | +# -- add the core library 96 | +add_subdirectory(libloragw) 97 | + 98 | +# -- add util_lbt_test 99 | +add_subdirectory(util_lbt_test) 100 | + 101 | +# -- add util_pkt_logger 102 | +add_subdirectory(util_pkt_logger) 103 | + 104 | +# -- add util_pkt_logger 105 | +add_subdirectory(util_spectral_scan) 106 | + 107 | +# -- add util_spi_stress 108 | +add_subdirectory(util_spi_stress) 109 | + 110 | +# -- add util_tx_continuous 111 | +add_subdirectory(util_tx_continuous) 112 | + 113 | +# -- add util_tx_test 114 | +add_subdirectory(util_tx_test) 115 | diff --git a/cmake/loragw-config.cmake b/cmake/loragw-config.cmake 116 | new file mode 100644 117 | index 0000000..ee8687b 118 | --- /dev/null 119 | +++ b/cmake/loragw-config.cmake 120 | @@ -0,0 +1 @@ 121 | +include("${CMAKE_CURRENT_LIST_DIR}/loragw-targets.cmake") 122 | diff --git a/libloragw/CMakeLists.txt b/libloragw/CMakeLists.txt 123 | new file mode 100644 124 | index 0000000..b2102ae 125 | --- /dev/null 126 | +++ b/libloragw/CMakeLists.txt 127 | @@ -0,0 +1,150 @@ 128 | +set(TARGET loragw) 129 | + 130 | +add_library(${TARGET} "") 131 | + 132 | +# -- add additional debug options 133 | +# Set the DEBUG_* to 1 to activate debug mode in individual modules. 134 | +# Warning: that makes the module *very verbose*, do not use for production 135 | +option(DEBUG_AUX "Active debug mode in AUX module" OFF) 136 | +option(DEBUG_SPI "Active debug mode in SPI module" OFF) 137 | +option(DEBUG_REG "Active debug mode in REG module" OFF) 138 | +option(DEBUG_HAL "Active debug mode in HAL module" OFF) 139 | +option(DEBUG_GPIO "Active debug mode in GPIO module" OFF) 140 | +option(DEBUG_LBT "Active debug mode in LBT module" OFF) 141 | +option(DEBUG_GPS "Active debug mode in GPS module" OFF) 142 | + 143 | +message("-- Build with debug AUX: ${DEBUG_AUX}") 144 | +message("-- Build with debug SPI: ${DEBUG_SPI}") 145 | +message("-- Build with debug REG: ${DEBUG_REG}") 146 | +message("-- Build with debug HAL: ${DEBUG_HAL}") 147 | +message("-- Build with debug GPIO: ${DEBUG_GPIO}") 148 | +message("-- Build with debug LBT: ${DEBUG_LBT}") 149 | +message("-- Build with debug GPS: ${DEBUG_GPS}") 150 | + 151 | +# -- add the compile options 152 | +target_compile_options( 153 | + ${TARGET} 154 | + PRIVATE 155 | + -Werror 156 | + -Wall 157 | + -Wextra 158 | +) 159 | + 160 | +target_sources(${TARGET} 161 | + PRIVATE 162 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_aux.c 163 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_fpga.c 164 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_gps.c 165 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_hal.c 166 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_lbt.c 167 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_radio.c 168 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_reg.c 169 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_spi.native.c 170 | +) 171 | + 172 | +# -- add the public headers 173 | +set (${TARGET}_PUBLIC_HEADERS 174 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_aux.h 175 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_fpga.h 176 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_gps.h 177 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_hal.h 178 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_lbt.h 179 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_radio.h 180 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_reg.h 181 | +) 182 | + 183 | +target_include_directories(${TARGET} 184 | + PRIVATE 185 | + ${CMAKE_CURRENT_LIST_DIR} 186 | + ${CMAKE_CURRENT_LIST_DIR}/inc 187 | + PUBLIC 188 | + $ 189 | + $ 190 | + $ 191 | +) 192 | + 193 | +configure_file(${CMAKE_CURRENT_LIST_DIR}/${TARGET}_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) 194 | + 195 | +target_link_libraries(${TARGET} 196 | + PUBLIC 197 | + Threads::Threads 198 | + m 199 | +) 200 | + 201 | +set_target_properties(${TARGET} PROPERTIES VERSION ${lora_gateway_VERSION_SHORT}) 202 | +set_target_properties(${TARGET} PROPERTIES SOVERSION ${lora_gateway_VERSION_SHORT}) 203 | +set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_BINARY_DIR}/config.h;${${TARGET}_PUBLIC_HEADERS}") 204 | + 205 | +# -- add the install targets 206 | +install (TARGETS ${TARGET} 207 | + EXPORT ${TARGET}_targets 208 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 209 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 210 | + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET} 211 | + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET} 212 | +) 213 | + 214 | +# -- add pkg config file 215 | +configure_file ("${CMAKE_CURRENT_LIST_DIR}/${TARGET}.pc.in" "${PROJECT_BINARY_DIR}/${TARGET}.pc" @ONLY) 216 | +install (FILES ${PROJECT_BINARY_DIR}/${TARGET}.pc DESTINATION lib/pkgconfig) 217 | + 218 | +# -- write cmake package config file 219 | +write_basic_package_version_file( 220 | + "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-config-version.cmake" 221 | + VERSION ${lora_gateway_VERSION} 222 | + COMPATIBILITY AnyNewerVersion 223 | +) 224 | + 225 | +export(EXPORT ${TARGET}_targets 226 | + FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-targets.cmake" 227 | + NAMESPACE Semtech:: 228 | +) 229 | + 230 | +configure_file(${PROJECT_SOURCE_DIR}/cmake/${TARGET}-config.cmake 231 | + "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-config.cmake" 232 | + COPYONLY 233 | +) 234 | + 235 | +set(ConfigPackageLocation lib/cmake/${TARGET}) 236 | + 237 | +install(EXPORT ${TARGET}_targets 238 | + FILE ${TARGET}-targets.cmake 239 | + NAMESPACE Semtech:: 240 | + DESTINATION ${ConfigPackageLocation} 241 | +) 242 | + 243 | +install( 244 | + FILES ${PROJECT_SOURCE_DIR}/cmake/${TARGET}-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-config-version.cmake" 245 | + DESTINATION ${ConfigPackageLocation} 246 | + COMPONENT Devel 247 | +) 248 | + 249 | +# -- add test programs 250 | +foreach(TEST test_loragw_spi test_loragw_gps test_loragw_reg test_loragw_hal test_loragw_cal) 251 | + add_executable(${TEST} "") 252 | + 253 | + target_sources(${TEST} 254 | + PRIVATE 255 | + ${CMAKE_CURRENT_LIST_DIR}/tst/${TEST}.c 256 | + ) 257 | + 258 | + target_include_directories(${TEST} 259 | + PRIVATE 260 | + $ 261 | + $ 262 | + ${CMAKE_CURRENT_LIST_DIR}/inc 263 | + ${CMAKE_CURRENT_BINARY_DIR} 264 | + ) 265 | + 266 | + target_link_libraries(${TEST} 267 | + PRIVATE 268 | + loragw 269 | + ) 270 | + 271 | + install ( 272 | + TARGETS ${TEST} 273 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 274 | + ) 275 | + 276 | +endforeach() 277 | + 278 | diff --git a/libloragw/loragw.pc.in b/libloragw/loragw.pc.in 279 | new file mode 100644 280 | index 0000000..01bb3cf 281 | --- /dev/null 282 | +++ b/libloragw/loragw.pc.in 283 | @@ -0,0 +1,10 @@ 284 | +prefix=@CMAKE_INSTALL_PREFIX@ 285 | +exec_prefix=${prefix}/bin 286 | +includedir=${prefix}/include/libloragw 287 | +libdir=${prefix}/lib 288 | + 289 | +Name: LIBLORAGW 290 | +Description: BLANK_TEXT 291 | +Version: @lora_gateway_VERSION@ 292 | +Cflags: -I${includedir} 293 | +Libs: -L${libdir} -lloragw 294 | diff --git a/libloragw/loragw_config.h.in b/libloragw/loragw_config.h.in 295 | new file mode 100644 296 | index 0000000..76ad35a 297 | --- /dev/null 298 | +++ b/libloragw/loragw_config.h.in 299 | @@ -0,0 +1,14 @@ 300 | +#ifndef _LORAGW_CONFIGURATION_H 301 | +#define _LORAGW_CONFIGURATION_H 302 | + 303 | +#define LIBLORAGW_VERSION "@lora_gateway_VERSION_SHORT@" 304 | + 305 | +#cmakedefine01 DEBUG_AUX 306 | +#cmakedefine01 DEBUG_SPI 307 | +#cmakedefine01 DEBUG_REG 308 | +#cmakedefine01 DEBUG_HAL 309 | +#cmakedefine01 DEBUG_GPS 310 | +#cmakedefine01 DEBUG_GPIO 311 | +#cmakedefine01 DEBUG_LBT 312 | + 313 | +#endif 314 | diff --git a/util_lbt_test/CMakeLists.txt b/util_lbt_test/CMakeLists.txt 315 | new file mode 100644 316 | index 0000000..f184b82 317 | --- /dev/null 318 | +++ b/util_lbt_test/CMakeLists.txt 319 | @@ -0,0 +1,23 @@ 320 | + 321 | +add_executable(util_lbt_test "") 322 | +target_sources(util_lbt_test 323 | + PRIVATE 324 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_lbt_test.c 325 | +) 326 | + 327 | +target_link_libraries(util_lbt_test 328 | + PUBLIC 329 | + loragw 330 | +) 331 | + 332 | +set_target_properties(util_lbt_test PROPERTIES 333 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 334 | +) 335 | + 336 | +# add the install targets 337 | +install ( 338 | + TARGETS util_lbt_test 339 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 340 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 341 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 342 | +) 343 | diff --git a/util_pkt_logger/CMakeLists.txt b/util_pkt_logger/CMakeLists.txt 344 | new file mode 100644 345 | index 0000000..82cfc86 346 | --- /dev/null 347 | +++ b/util_pkt_logger/CMakeLists.txt 348 | @@ -0,0 +1,29 @@ 349 | + 350 | +add_executable(util_pkt_logger "") 351 | +target_sources(util_pkt_logger 352 | + PRIVATE 353 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_pkt_logger.c 354 | + ${CMAKE_CURRENT_LIST_DIR}/src/parson.c 355 | +) 356 | + 357 | +target_include_directories(util_pkt_logger 358 | + PRIVATE 359 | + ${CMAKE_CURRENT_LIST_DIR}/inc 360 | +) 361 | + 362 | +target_link_libraries(util_pkt_logger 363 | + PUBLIC 364 | + loragw 365 | +) 366 | + 367 | +set_target_properties(util_pkt_logger PROPERTIES 368 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 369 | +) 370 | + 371 | +# add the install targets 372 | +install ( 373 | + TARGETS util_pkt_logger 374 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 375 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 376 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 377 | +) 378 | diff --git a/util_spectral_scan/CMakeLists.txt b/util_spectral_scan/CMakeLists.txt 379 | new file mode 100644 380 | index 0000000..3cec2a9 381 | --- /dev/null 382 | +++ b/util_spectral_scan/CMakeLists.txt 383 | @@ -0,0 +1,23 @@ 384 | + 385 | +add_executable(util_spectral_scan "") 386 | +target_sources(util_spectral_scan 387 | + PRIVATE 388 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_spectral_scan.c 389 | +) 390 | + 391 | +target_link_libraries(util_spectral_scan 392 | + PUBLIC 393 | + loragw 394 | +) 395 | + 396 | +set_target_properties(util_spectral_scan PROPERTIES 397 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 398 | +) 399 | + 400 | +# add the install targets 401 | +install ( 402 | + TARGETS util_spectral_scan 403 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 404 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 405 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 406 | +) 407 | diff --git a/util_spi_stress/CMakeLists.txt b/util_spi_stress/CMakeLists.txt 408 | new file mode 100644 409 | index 0000000..d5f0eea 410 | --- /dev/null 411 | +++ b/util_spi_stress/CMakeLists.txt 412 | @@ -0,0 +1,23 @@ 413 | + 414 | +add_executable(util_spi_stress "") 415 | +target_sources(util_spi_stress 416 | + PRIVATE 417 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_spi_stress.c 418 | +) 419 | + 420 | +target_link_libraries(util_spi_stress 421 | + PUBLIC 422 | + loragw 423 | +) 424 | + 425 | +set_target_properties(util_spi_stress PROPERTIES 426 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 427 | +) 428 | + 429 | +# add the install targets 430 | +install ( 431 | + TARGETS util_spi_stress 432 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 433 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 434 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 435 | +) 436 | diff --git a/util_tx_continuous/CMakeLists.txt b/util_tx_continuous/CMakeLists.txt 437 | new file mode 100644 438 | index 0000000..97c70e5 439 | --- /dev/null 440 | +++ b/util_tx_continuous/CMakeLists.txt 441 | @@ -0,0 +1,23 @@ 442 | + 443 | +add_executable(util_tx_continuous "") 444 | +target_sources(util_tx_continuous 445 | + PRIVATE 446 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_tx_continuous.c 447 | +) 448 | + 449 | +target_link_libraries(util_tx_continuous 450 | + PUBLIC 451 | + loragw 452 | +) 453 | + 454 | +set_target_properties(util_tx_continuous PROPERTIES 455 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 456 | +) 457 | + 458 | +# add the install targets 459 | +install ( 460 | + TARGETS util_tx_continuous 461 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 462 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 463 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 464 | +) 465 | diff --git a/util_tx_test/CMakeLists.txt b/util_tx_test/CMakeLists.txt 466 | new file mode 100644 467 | index 0000000..6cc0e04 468 | --- /dev/null 469 | +++ b/util_tx_test/CMakeLists.txt 470 | @@ -0,0 +1,23 @@ 471 | + 472 | +add_executable(util_tx_test "") 473 | +target_sources(util_tx_test 474 | + PRIVATE 475 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_tx_test.c 476 | +) 477 | + 478 | +target_link_libraries(util_tx_test 479 | + PUBLIC 480 | + loragw 481 | +) 482 | + 483 | +set_target_properties(util_tx_test PROPERTIES 484 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 485 | +) 486 | + 487 | +# add the install targets 488 | +install ( 489 | + TARGETS util_tx_test 490 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 491 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 492 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 493 | +) 494 | -- 495 | 2.20.1 496 | 497 | -------------------------------------------------------------------------------- /lora-gateway-hal/patches/0002-add-preprocessing-for-SPI_DEV_PATH-and-SPI_SPEED.patch: -------------------------------------------------------------------------------- 1 | From ea2a7752295ab734464c2877e1f484a9bf08d58d Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Sun, 24 Feb 2019 01:03:48 +0100 4 | Subject: [PATCH 2/3] - add preprocessing for SPI_DEV_PATH and SPI_SPEED 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | libloragw/src/loragw_spi.native.c | 11 +++++++++-- 9 | 1 file changed, 9 insertions(+), 2 deletions(-) 10 | 11 | diff --git a/libloragw/src/loragw_spi.native.c b/libloragw/src/loragw_spi.native.c 12 | index c01ed1c..fe251e3 100644 13 | --- a/libloragw/src/loragw_spi.native.c 14 | +++ b/libloragw/src/loragw_spi.native.c 15 | @@ -53,8 +53,15 @@ Maintainer: Sylvain Miermont 16 | 17 | #define READ_ACCESS 0x00 18 | #define WRITE_ACCESS 0x80 19 | -#define SPI_SPEED 8000000 20 | -#define SPI_DEV_PATH "/dev/spidev0.0" 21 | + 22 | +#ifndef SPI_SPEED 23 | +#error SPI_SPEED is not defined 24 | +#endif 25 | + 26 | +#ifndef SPI_DEV_PATH 27 | +#error SPI_DEV_PATH is not defined 28 | +#endif 29 | + 30 | //#define SPI_DEV_PATH "/dev/spidev32766.0" 31 | 32 | /* -------------------------------------------------------------------------- */ 33 | -- 34 | 2.20.1 35 | 36 | -------------------------------------------------------------------------------- /lora-gateway-hal/patches/0003-add-SPI_DEV_PATH-and-SPI_SPEED-to-cmake.patch: -------------------------------------------------------------------------------- 1 | From 81cd227c04ccb615cffaaa7b6372affb7964df2e Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Sun, 24 Feb 2019 01:04:29 +0100 4 | Subject: [PATCH 3/3] - add SPI_DEV_PATH and SPI_SPEED to cmake 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | libloragw/CMakeLists.txt | 7 +++++++ 9 | 1 file changed, 7 insertions(+) 10 | 11 | diff --git a/libloragw/CMakeLists.txt b/libloragw/CMakeLists.txt 12 | index b2102ae..32abf51 100644 13 | --- a/libloragw/CMakeLists.txt 14 | +++ b/libloragw/CMakeLists.txt 15 | @@ -13,6 +13,9 @@ option(DEBUG_GPIO "Active debug mode in GPIO module" OFF) 16 | option(DEBUG_LBT "Active debug mode in LBT module" OFF) 17 | option(DEBUG_GPS "Active debug mode in GPS module" OFF) 18 | 19 | +set(SPI_DEV_PATH "/dev/spidev0.0" CACHE FILEPATH "Path of spi-dev") 20 | +set(SPI_SPEED 8000000 CACHE STRING "SPI clock frequency") 21 | + 22 | message("-- Build with debug AUX: ${DEBUG_AUX}") 23 | message("-- Build with debug SPI: ${DEBUG_SPI}") 24 | message("-- Build with debug REG: ${DEBUG_REG}") 25 | @@ -20,6 +23,8 @@ message("-- Build with debug HAL: ${DEBUG_HAL}") 26 | message("-- Build with debug GPIO: ${DEBUG_GPIO}") 27 | message("-- Build with debug LBT: ${DEBUG_LBT}") 28 | message("-- Build with debug GPS: ${DEBUG_GPS}") 29 | +message("-- Build with SPI_DEV_PATH: ${SPI_DEV_PATH}") 30 | +message("-- Build with SPI_SPEED: ${SPI_SPEED}") 31 | 32 | # -- add the compile options 33 | target_compile_options( 34 | @@ -28,6 +33,8 @@ target_compile_options( 35 | -Werror 36 | -Wall 37 | -Wextra 38 | + -DSPI_DEV_PATH="${SPI_DEV_PATH}" 39 | + -DSPI_SPEED=${SPI_SPEED} 40 | ) 41 | 42 | target_sources(${TARGET} 43 | -- 44 | 2.20.1 45 | 46 | -------------------------------------------------------------------------------- /lora-gateway-hal/patches/0004-add-new-functions-for-basicstation.patch: -------------------------------------------------------------------------------- 1 | diff --git a/libloragw/Makefile b/libloragw/Makefile 2 | index 53c33d9..a8a09a2 100644 3 | --- a/libloragw/Makefile 4 | +++ b/libloragw/Makefile 5 | @@ -7,6 +7,7 @@ include library.cfg 6 | 7 | ARCH ?= 8 | CROSS_COMPILE ?= 9 | + 10 | CC := $(CROSS_COMPILE)gcc 11 | AR := $(CROSS_COMPILE)ar 12 | 13 | diff --git a/libloragw/inc/loragw_hal.h b/libloragw/inc/loragw_hal.h 14 | index d5f9ade..57927c4 100644 15 | --- a/libloragw/inc/loragw_hal.h 16 | +++ b/libloragw/inc/loragw_hal.h 17 | @@ -414,6 +414,12 @@ const char* lgw_version_info(void); 18 | */ 19 | uint32_t lgw_time_on_air(struct lgw_pkt_tx_s *packet); 20 | 21 | +extern uint8_t lgwx_device_mode; 22 | +extern uint8_t lgwx_beacon_len; 23 | +extern uint8_t lgwx_beacon_sf; 24 | +extern uint8_t lgwx_lbt_mode; 25 | +enum { LGWX_LBT_MODE_DFLT=0, LGWX_LBT_MODE_OFF = 1 }; 26 | + 27 | #endif 28 | 29 | /* --- EOF ------------------------------------------------------------------ */ 30 | diff --git a/libloragw/src/loragw_hal.c b/libloragw/src/loragw_hal.c 31 | index 8103751..d3ec1fb 100644 32 | --- a/libloragw/src/loragw_hal.c 33 | +++ b/libloragw/src/loragw_hal.c 34 | @@ -226,11 +226,18 @@ int load_firmware(uint8_t target, uint8_t *firmware, uint16_t size) { 35 | 36 | /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 37 | 38 | +uint8_t lgwx_device_mode = 0; 39 | +uint8_t lgwx_beacon_len = 0; 40 | +uint8_t lgwx_beacon_sf = 0; 41 | +uint8_t lgwx_lbt_mode = 0; 42 | + 43 | void lgw_constant_adjust(void) { 44 | 45 | /* I/Q path setup */ 46 | // lgw_reg_w(LGW_RX_INVERT_IQ,0); /* default 0 */ 47 | // lgw_reg_w(LGW_MODEM_INVERT_IQ,1); /* default 1 */ 48 | + if( lgwx_device_mode ) 49 | + lgw_reg_w(LGW_MODEM_INVERT_IQ,0); 50 | // lgw_reg_w(LGW_CHIRP_INVERT_RX,1); /* default 1 */ 51 | // lgw_reg_w(LGW_RX_EDGE_SELECT,0); /* default 0 */ 52 | // lgw_reg_w(LGW_MBWSSF_MODEM_INVERT_IQ,0); /* default 0 */ 53 | @@ -280,6 +287,8 @@ void lgw_constant_adjust(void) { 54 | 55 | // lgw_reg_w(LGW_PREAMBLE_FINE_TIMING_GAIN,1); /* default 1 */ 56 | // lgw_reg_w(LGW_ONLY_CRC_EN,1); /* default 1 */ 57 | + if( lgwx_device_mode ) 58 | + lgw_reg_w(LGW_ONLY_CRC_EN,0); 59 | // lgw_reg_w(LGW_PAYLOAD_FINE_TIMING_GAIN,2); /* default 2 */ 60 | // lgw_reg_w(LGW_TRACKING_INTEGRAL,0); /* default 0 */ 61 | // lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_RDX8,0); /* default 0 */ 62 | @@ -300,11 +309,24 @@ void lgw_constant_adjust(void) { 63 | lgw_reg_w(LGW_MBWSSF_FRAME_SYNCH_PEAK2_POS,2); /* default 2 */ 64 | } 65 | // lgw_reg_w(LGW_MBWSSF_ONLY_CRC_EN,1); /* default 1 */ 66 | + if( lgwx_device_mode ) 67 | + lgw_reg_w(LGW_MBWSSF_ONLY_CRC_EN,0); 68 | // lgw_reg_w(LGW_MBWSSF_PAYLOAD_FINE_TIMING_GAIN,2); /* default 2 */ 69 | // lgw_reg_w(LGW_MBWSSF_PREAMBLE_FINE_TIMING_GAIN,1); /* default 1 */ 70 | // lgw_reg_w(LGW_MBWSSF_TRACKING_INTEGRAL,0); /* default 0 */ 71 | // lgw_reg_w(LGW_MBWSSF_AGC_FREEZE_ON_DETECT,1); /* default 1 */ 72 | 73 | + if( lgwx_device_mode && lgwx_beacon_len ) { 74 | + lgw_reg_w(LGW_MBWSSF_MODEM_INVERT_IQ,0); 75 | + lgw_reg_w(LGW_MBWSSF_RATE_SF, lgwx_beacon_sf); 76 | + lgw_reg_w(LGW_MBWSSF_IMPLICIT_HEADER,1); /* no header */ 77 | + lgw_reg_w(LGW_MBWSSF_IMPLICIT_CRC_EN,0); 78 | + lgw_reg_w(LGW_MBWSSF_IMPLICIT_CODING_RATE,1); 79 | + lgw_reg_w(LGW_MBWSSF_IMPLICIT_PAYLOAD_LENGHT, lgwx_beacon_len); 80 | + } else { 81 | + lgw_reg_w(LGW_MBWSSF_MODEM_INVERT_IQ,1); //XXX:? correct? 82 | + } 83 | + 84 | /* Improvement of reference clock frequency error tolerance */ 85 | lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_RDX4, 1); /* default 0 */ 86 | lgw_reg_w(LGW_ADJUST_MODEM_START_OFFSET_SF12_RDX4, 4094); /* default 4092 */ 87 | @@ -1452,6 +1474,11 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) { 88 | break; 89 | } 90 | 91 | + if( lgwx_device_mode ) { 92 | + pkt_data.invert_pol = false; 93 | + pkt_data.no_crc = false; 94 | + } 95 | + 96 | buff[0] = 0xFF & part_int; /* Most Significant Byte */ 97 | buff[1] = 0xFF & (part_frac >> 8); /* middle byte */ 98 | buff[2] = 0xFF & part_frac; /* Least Significant Byte */ 99 | @@ -1600,10 +1627,17 @@ int lgw_send(struct lgw_pkt_tx_s pkt_data) { 100 | lgw_reg_wb(LGW_TX_DATA_BUF_DATA, buff, transfer_size); 101 | DEBUG_ARRAY(i, transfer_size, buff); 102 | 103 | - x = lbt_is_channel_free(&pkt_data, tx_start_delay, &tx_allowed); 104 | - if (x != LGW_LBT_SUCCESS) { 105 | - DEBUG_MSG("ERROR: Failed to check channel availability for TX\n"); 106 | - return LGW_HAL_ERROR; 107 | + if( lgwx_lbt_mode == LGWX_LBT_MODE_OFF ) { 108 | + tx_allowed = true; 109 | + } else { 110 | + //XXX:TBD: if( lgwx_lbt_mode == LGWX_LBT_MODE_EU868 ) { 111 | + //XXX:TBD: // change txend time so that lbt_is_channel_free checks if dead gap is within 5ms (PSA rules) 112 | + //XXX:TBD: } 113 | + x = lbt_is_channel_free(&pkt_data, tx_start_delay, &tx_allowed); 114 | + if (x != LGW_LBT_SUCCESS) { 115 | + DEBUG_MSG("ERROR: Failed to check channel availability for TX\n"); 116 | + return LGW_HAL_ERROR; 117 | + } 118 | } 119 | if (tx_allowed == true) { 120 | switch(pkt_data.tx_mode) { 121 | 122 | /* -------------------------------------------------------------------------- */ 123 | -------------------------------------------------------------------------------- /lora-packet-forwarder/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=lora-packet-forwarder 11 | PKG_VERSION:=4.0.1 12 | PKG_RELEASE:=1 13 | 14 | PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/packet_forwarder/tar.gz/v$(PKG_VERSION)? 15 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 16 | PKG_HASH:=e68fadf6f1d2e5e7b601e504d5efb48b0a8f374c2c29c0476ab2fe9db68d33ae 17 | PKG_MAINTAINER:=Xue Liu 18 | PKG_LICENSE_FILES:=LICENSE 19 | PKG_BUILD_DIR:=$(BUILD_DIR)/packet_forwarder-$(PKG_VERSION) 20 | 21 | include $(INCLUDE_DIR)/package.mk 22 | include $(INCLUDE_DIR)/cmake.mk 23 | 24 | define Package/lora-packet-forwarder 25 | SECTION:=net 26 | CATEGORY:=Network 27 | SUBMENU:=LoRaWAN 28 | TITLE:=Semtech packet-forwarder program 29 | DEPENDS:=+libloragw +libubox-lua +libuci-lua +dkjson 30 | endef 31 | 32 | define Package/lora-packet-forwarder/description 33 | A LoRa packet forwarder is a program running on the host of a LoRa gateway 34 | that forwards RF packets receive by the concentrator to a server through a 35 | IP/UDP link, and emits RF packets that are sent by the server. 36 | endef 37 | 38 | define Package/lora-packet-forwarder-utils 39 | SECTION:=net 40 | CATEGORY:=Network 41 | SUBMENU:=LoRaWAN 42 | TITLE:=Utilities for lora pakcet forwarder 43 | DEPENDS:=lora-packet-forwarder 44 | endef 45 | 46 | define Package/lora-packet-forwarder/install 47 | $(INSTALL_DIR) $(1)/usr/sbin 48 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/lora_pkt_fwd/lora_pkt_fwd $(1)/usr/sbin 49 | $(INSTALL_BIN) ./files/gen_lora_global_conf $(1)/usr/sbin 50 | $(INSTALL_DIR) $(1)/etc/init.d 51 | $(INSTALL_BIN) ./files/lora_pkt_fwd.init $(1)/etc/init.d/lora_pkt_fwd 52 | $(INSTALL_DIR) $(1)/etc/config 53 | $(INSTALL_DATA) ./files/lora-global.config $(1)/etc/config/lora-global 54 | endef 55 | 56 | define Package/lora-packet-forwarder-utils/install 57 | $(INSTALL_DIR) $(1)/usr/sbin 58 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_ack $(1)/usr/sbin 59 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_sink $(1)/usr/sbin 60 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_test $(1)/usr/sbin/pkg_fwd_util_tx_test 61 | endef 62 | 63 | $(eval $(call BuildPackage,lora-packet-forwarder)) 64 | $(eval $(call BuildPackage,lora-packet-forwarder-utils)) 65 | -------------------------------------------------------------------------------- /lora-packet-forwarder/files/gen_lora_global_conf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- SPDX-License-Identifier: GPL-2.0 4 | -- 5 | -- Copyright (c) 2019 Xue Liu 6 | -- 7 | 8 | require("uloop") 9 | require("ubus") 10 | local json = require("dkjson") 11 | local uci = require("uci") 12 | 13 | x = uci.cursor() 14 | 15 | uloop.init() 16 | 17 | local conn = ubus.connect() 18 | if not conn then 19 | error("Failed to connect to ubus") 20 | end 21 | 22 | local lora_global_ubus = conn:call("uci", "get", {config = "lora-global"}) 23 | 24 | local lora_global_table = lora_global_ubus["values"] 25 | 26 | local lora_global = {} 27 | local gateway_conf = {} 28 | local sx1301_conf = {} 29 | local radio_0 = {} 30 | local radio_1 = {} 31 | 32 | -- 33 | -- chan_x 34 | -- 35 | for key, val in pairs(lora_global_table) do 36 | if string.match(key, 'chan_[%a]*', 1) then 37 | local chan = {} 38 | for k, v in pairs(val) do 39 | if string.match(k, '%.[%a]*', 1) == nil then 40 | if tonumber(v) then 41 | chan[k] = tonumber(v) 42 | elseif v == "true" then 43 | chan[k] = true 44 | elseif v == "false" then 45 | chan[k] = false 46 | else 47 | chan[k] = v 48 | end 49 | end 50 | end 51 | sx1301_conf[key] = chan 52 | end 53 | end 54 | 55 | -- 56 | -- tx_lut_x 57 | -- 58 | for key, val in pairs(lora_global_table) do 59 | if string.match(key, 'tx_lut_[%d]?', 1) then 60 | local tx_lut = {} 61 | for k, v in pairs(val) do 62 | if string.match(k, '%.[%a]*', 1) == nil then 63 | if tonumber(v) then 64 | tx_lut[k] = tonumber(v) 65 | elseif v == "true" then 66 | tx_lut[k] = true 67 | elseif v == "false" then 68 | tx_lut[k] = false 69 | else 70 | tx_lut[k] = v 71 | end 72 | end 73 | end 74 | sx1301_conf[key] = tx_lut 75 | end 76 | end 77 | 78 | -- 79 | -- radio_0 80 | -- 81 | if lora_global_table["radio_0"] then 82 | for k, v in pairs(lora_global_table["radio_0"]) do 83 | if string.match(k, '%.[%a]*', 1) == nil then 84 | if tonumber(v) then 85 | radio_0[k] = tonumber(v) 86 | elseif v == "true" then 87 | radio_0[k] = true 88 | elseif v == "false" then 89 | radio_0[k] = false 90 | else 91 | radio_0[k] = v 92 | end 93 | end 94 | end 95 | else 96 | error("UCI configuration has no item radio_0, Please check your configuration") 97 | end 98 | 99 | -- 100 | -- radio_1 101 | -- 102 | if lora_global_table["radio_1"] then 103 | for k, v in pairs(lora_global_table["radio_1"]) do 104 | if string.match(k, '%.[%a]*', 1) == nil then 105 | if tonumber(v) then 106 | radio_1[k] = tonumber(v) 107 | elseif v == "true" then 108 | radio_1[k] = true 109 | elseif v == "false" then 110 | radio_1[k] = false 111 | else 112 | radio_1[k] = v 113 | end 114 | end 115 | end 116 | else 117 | error("UCI configuration has no item radio_1, Please check your configuration") 118 | end 119 | 120 | -- 121 | -- gateway_conf 122 | -- 123 | if lora_global_table["gateway_conf"] then 124 | for k, v in pairs(lora_global_table["gateway_conf"]) do 125 | -- filter out internal uci options 126 | if string.match(k, '%.[%a]*', 1) == nil then 127 | if tonumber(v) then 128 | gateway_conf[k] = tonumber(v) 129 | elseif v == "true" then 130 | gateway_conf[k] = true 131 | elseif v == "false" then 132 | gateway_conf[k] = false 133 | else 134 | gateway_conf[k] = v 135 | end 136 | end 137 | end 138 | else 139 | error("UCI configuration has no item gateway_conf, Please check your configuration") 140 | end 141 | 142 | -- 143 | -- SX1301_conf 144 | -- 145 | if lora_global_table["SX1301_conf"] then 146 | for k, v in pairs(lora_global_table["SX1301_conf"]) do 147 | if string.match(k, '%.[%a]*', 1) == nil then 148 | if tonumber(v) then 149 | sx1301_conf[k] = tonumber(v) 150 | elseif v == "true" then 151 | sx1301_conf[k] = true 152 | elseif v == "false" then 153 | sx1301_conf[k] = false 154 | else 155 | sx1301_conf[k] = v 156 | end 157 | end 158 | end 159 | else 160 | error("UCI configuration has no item SX1301_conf, Please check your configuration") 161 | end 162 | 163 | sx1301_conf["radio_0"] = radio_0 164 | sx1301_conf["radio_1"] = radio_1 165 | lora_global["gateway_conf"] = gateway_conf 166 | lora_global["SX1301_conf"] = sx1301_conf 167 | 168 | local lora_global_text = json.encode(lora_global, { indent = true }) 169 | 170 | print(lora_global_text) 171 | -------------------------------------------------------------------------------- /lora-packet-forwarder/files/lora-global.config: -------------------------------------------------------------------------------- 1 | 2 | config gateway 'gateway_conf' 3 | option keepalive_interval '10' 4 | option stat_interval '30' 5 | option push_timeout_ms '100' 6 | option forward_crc_valid 'true' 7 | option forward_crc_error 'false' 8 | option serv_port_up '1700' 9 | option serv_port_down '1700' 10 | option gateway_ID 'aabbccddeeffaabb' 11 | option server_address 'router.eu.thethings.network' 12 | option forward_crc_disabled 'false' 13 | option gps_enable 'false' 14 | option beacon_enable 'false' 15 | 16 | config sx1301 'SX1301_conf' 17 | option clksrc '1' 18 | option antenna_gain '0' 19 | option enable_reset_pin '1' 20 | option reset_pin '25' 21 | option lorawan_public 'true' 22 | 23 | config radio 'radio_0' 24 | option enable 'true' 25 | option freq '867500000' 26 | option rssi_offset '-166.0' 27 | option tx_enable 'true' 28 | option tx_freq_min '863000000' 29 | option tx_freq_max '870000000' 30 | option type 'SX1257' 31 | option tx_notch_freq '129000' 32 | 33 | config radio 'radio_1' 34 | option enable 'true' 35 | option freq '868500000' 36 | option rssi_offset '-166.0' 37 | option type 'SX1257' 38 | option tx_enable 'false' 39 | 40 | config chan 'chan_multiSF_0' 41 | option enable 'true' 42 | option radio '1' 43 | option if '-400000' 44 | option desc 'Lora MAC, 125kHz, all SF, 868.1 MHz' 45 | 46 | config chan 'chan_multiSF_1' 47 | option enable 'true' 48 | option radio '1' 49 | option desc 'Lora MAC channel, 125kHz, all SF, 868.3 MHz' 50 | option if '-200000' 51 | 52 | config chan 'chan_multiSF_2' 53 | option enable 'true' 54 | option radio '1' 55 | option desc 'Lora MAC channel, 125kHz, all SF, 868.5 MHz' 56 | option if '0' 57 | 58 | config chan 'chan_multiSF_3' 59 | option enable 'true' 60 | option radio '0' 61 | option if '-400000' 62 | option desc 'Lora MAC channel, 125kHz, all SF, 867.1 MHz' 63 | 64 | config chan 'chan_multiSF_4' 65 | option enable 'true' 66 | option radio '0' 67 | option if '-200000' 68 | option desc 'Lora MAC channel, 125kHz, all SF, 867.3 MHz' 69 | 70 | config chan 'chan_multiSF_5' 71 | option enable 'true' 72 | option radio '0' 73 | option if '0' 74 | option desc 'Lora MAC channel, 125kHz, all SF, 867.5 MHz' 75 | 76 | config chan 'chan_multiSF_6' 77 | option enable 'true' 78 | option radio '0' 79 | option if '200000' 80 | option desc 'Lora MAC channel, 125kHz, all SF, 867.7 MHz' 81 | 82 | config chan 'chan_multiSF_7' 83 | option enable 'true' 84 | option radio '0' 85 | option if '400000' 86 | option desc 'Lora MAC channel, 125kHz, all SF, 867.9 MHz' 87 | 88 | config chan 'chan_Lora_std' 89 | option enable 'true' 90 | option radio '1' 91 | option if '-200000' 92 | option desc 'Lora MAC channel, 250kHz, SF7, 868.3 MHz' 93 | option bandwidth '250000' 94 | option spread_factor '7' 95 | 96 | config chan 'chan_FSK' 97 | option enable 'true' 98 | option radio '1' 99 | option if '300000' 100 | option desc 'FSK 50kbps channel, 868.8 MHz' 101 | option bandwidth '125000' 102 | option datarate '50000' 103 | 104 | config lut 'tx_lut_0' 105 | option pa_gain '0' 106 | option mix_gain '8' 107 | option rf_power '-6' 108 | option dig_gain '0' 109 | 110 | config lut 'tx_lut_1' 111 | option pa_gain '0' 112 | option mix_gain '10' 113 | option rf_power '-3' 114 | option dig_gain '0' 115 | 116 | config lut 'tx_lut_2' 117 | option pa_gain '0' 118 | option mix_gain '12' 119 | option rf_power '0' 120 | option dig_gain '0' 121 | 122 | config lut 'tx_lut_3' 123 | option pa_gain '1' 124 | option mix_gain '8' 125 | option rf_power '3' 126 | option dig_gain '0' 127 | 128 | config lut 'tx_lut_4' 129 | option pa_gain '1' 130 | option mix_gain '10' 131 | option rf_power '6' 132 | option dig_gain '0' 133 | 134 | config lut 'tx_lut_5' 135 | option pa_gain '1' 136 | option mix_gain '12' 137 | option rf_power '10' 138 | option dig_gain '0' 139 | 140 | config lut 'tx_lut_6' 141 | option pa_gain '1' 142 | option mix_gain '13' 143 | option rf_power '11' 144 | option dig_gain '0' 145 | 146 | config lut 'tx_lut_7' 147 | option pa_gain '2' 148 | option mix_gain '9' 149 | option rf_power '12' 150 | option dig_gain '0' 151 | 152 | config lut 'tx_lut_8' 153 | option pa_gain '1' 154 | option mix_gain '15' 155 | option rf_power '13' 156 | option dig_gain '0' 157 | 158 | config lut 'tx_lut_9' 159 | option pa_gain '2' 160 | option mix_gain '10' 161 | option rf_power '14' 162 | option dig_gain '0' 163 | 164 | config lut 'tx_lut_10' 165 | option pa_gain '2' 166 | option mix_gain '11' 167 | option rf_power '16' 168 | option dig_gain '0' 169 | 170 | config lut 'tx_lut_11' 171 | option pa_gain '3' 172 | option mix_gain '9' 173 | option rf_power '20' 174 | option dig_gain '0' 175 | 176 | config lut 'tx_lut_12' 177 | option pa_gain '3' 178 | option mix_gain '10' 179 | option rf_power '23' 180 | option dig_gain '0' 181 | 182 | config lut 'tx_lut_13' 183 | option pa_gain '3' 184 | option mix_gain '11' 185 | option rf_power '25' 186 | option dig_gain '0' 187 | 188 | config lut 'tx_lut_14' 189 | option pa_gain '3' 190 | option mix_gain '12' 191 | option rf_power '26' 192 | option dig_gain '0' 193 | 194 | config lut 'tx_lut_15' 195 | option pa_gain '3' 196 | option mix_gain '14' 197 | option rf_power '27' 198 | option dig_gain '0' 199 | -------------------------------------------------------------------------------- /lora-packet-forwarder/files/lora_pkt_fwd.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | START=99 3 | STOP=10 4 | 5 | USE_PROCD=1 6 | 7 | PROG=/usr/sbin/lora_pkt_fwd 8 | CONFIGFILE=/etc/global_conf.json 9 | 10 | reset_sx1301_board () 11 | { 12 | local pin=$1 13 | 14 | logger "lora_pkt_fwd: Reset SX1301 with pin ${pin}" 15 | 16 | if [ -d "/sys/class/gpio/gpio${pin}" ] 17 | then 18 | echo 1 > /dev/null 19 | else 20 | echo ${pin} > /sys/class/gpio/export 21 | echo "out" > /sys/class/gpio/gpio${pin}/direction 22 | sleep 1 23 | fi 24 | 25 | echo "1" > /sys/class/gpio/gpio${pin}/value 26 | sleep 5 27 | echo "0" > /sys/class/gpio/gpio${pin}/value 28 | sleep 1 29 | echo "0" > /sys/class/gpio/gpio${pin}/value 30 | sleep 1 31 | echo "in" > /sys/class/gpio/gpio${pin}/direction 32 | sleep 1 33 | 34 | logger "lora_pkt_fwd: SX1301 reset completed" 35 | } 36 | 37 | generate_global_conf() 38 | { 39 | logger "lora_pkt_fwd: Generate ${CONFIGFILE}" 40 | gen_lora_global_conf > ${CONFIGFILE} 41 | } 42 | 43 | start_service() 44 | { 45 | include /lib/functions 46 | 47 | logger "lora_pkt_fwd: Start" 48 | 49 | config_load lora_pkt_fwd 50 | 51 | generate_global_conf 52 | 53 | local reset_enable=$(uci get lora-global.SX1301_conf.enable_reset_pin) 54 | 55 | if [ ${reset_enable} == 1 ]; then 56 | reset_sx1301_board $(uci get lora-global.SX1301_conf.reset_pin) 57 | fi 58 | 59 | procd_open_instance 60 | procd_set_param command $PROG 61 | procd_set_param file ${CONFIGFILE} 62 | procd_set_param file /etc/config/lora-global 63 | procd_set_param respawn 64 | 65 | procd_set_param stdout 1 66 | procd_set_param stderr 1 67 | 68 | procd_close_instance 69 | } 70 | 71 | stop_service() { 72 | logger "lora_pkt_fwd: Stop" 73 | killall lora_pkt_fwd 74 | } 75 | -------------------------------------------------------------------------------- /lora-packet-forwarder/patches/001-relocate_config_files_into_etc.patch: -------------------------------------------------------------------------------- 1 | --- a/lora_pkt_fwd/src/lora_pkt_fwd.c 2 | +++ b/lora_pkt_fwd/src/lora_pkt_fwd.c 3 | @@ -980,9 +980,9 @@ int main(void) 4 | int x; 5 | 6 | /* configuration file related */ 7 | - char *global_cfg_path= "global_conf.json"; /* contain global (typ. network-wide) configuration */ 8 | - char *local_cfg_path = "local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */ 9 | - char *debug_cfg_path = "debug_conf.json"; /* if present, all other configuration files are ignored */ 10 | + char *global_cfg_path= "/etc/global_conf.json"; /* contain global (typ. network-wide) configuration */ 11 | + char *local_cfg_path = "/etc/local_conf.json"; /* contain node specific configuration, overwrite global parameters for parameters that are defined in both */ 12 | + char *debug_cfg_path = "/etc/debug_conf.json"; /* if present, all other configuration files are ignored */ 13 | 14 | /* threads */ 15 | pthread_t thrid_up; 16 | -------------------------------------------------------------------------------- /lora-packet-forwarder/patches/002-using_qsort.patch: -------------------------------------------------------------------------------- 1 | Index: packet_forwarder-4.0.1/lora_pkt_fwd/src/jitqueue.c 2 | =================================================================== 3 | --- packet_forwarder-4.0.1.orig/lora_pkt_fwd/src/jitqueue.c 4 | +++ packet_forwarder-4.0.1/lora_pkt_fwd/src/jitqueue.c 5 | @@ -16,8 +16,7 @@ Maintainer: Michael Coracin 6 | /* -------------------------------------------------------------------------- */ 7 | /* --- DEPENDANCIES --------------------------------------------------------- */ 8 | 9 | -#define _GNU_SOURCE /* needed for qsort_r to be defined */ 10 | -#include /* qsort_r */ 11 | +#include 12 | #include /* printf, fprintf, snprintf, fopen, fputs */ 13 | #include /* memset, memcpy */ 14 | #include 15 | @@ -91,32 +90,27 @@ void jit_queue_init(struct jit_queue_s * 16 | pthread_mutex_unlock(&mx_jit_queue); 17 | } 18 | 19 | -int compare(const void *a, const void *b, void *arg) 20 | +int compare(const void *a, const void *b) 21 | { 22 | struct jit_node_s *p = (struct jit_node_s *)a; 23 | struct jit_node_s *q = (struct jit_node_s *)b; 24 | - int *counter = (int *)arg; 25 | int p_count, q_count; 26 | 27 | p_count = p->pkt.count_us; 28 | q_count = q->pkt.count_us; 29 | 30 | - if (p_count > q_count) 31 | - *counter = *counter + 1; 32 | - 33 | return p_count - q_count; 34 | } 35 | 36 | void jit_sort_queue(struct jit_queue_s *queue) { 37 | - int counter = 0; 38 | 39 | if (queue->num_pkt == 0) { 40 | return; 41 | } 42 | 43 | MSG_DEBUG(DEBUG_JIT, "sorting queue in ascending order packet timestamp - queue size:%u\n", queue->num_pkt); 44 | - qsort_r(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare, &counter); 45 | - MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped:%d\n", counter); 46 | + qsort(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare); 47 | + MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped\n"); 48 | } 49 | 50 | bool jit_collision_test(uint32_t p1_count_us, uint32_t p1_pre_delay, uint32_t p1_post_delay, uint32_t p2_count_us, uint32_t p2_pre_delay, uint32_t p2_post_delay) { 51 | -------------------------------------------------------------------------------- /lora-packet-forwarder/patches/003-add-CMake-support.patch: -------------------------------------------------------------------------------- 1 | From fa1fe7115ebe60bcfe61d31fcb1201fcf79b38a5 Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Thu, 21 Feb 2019 15:06:52 +0100 4 | Subject: [PATCH 1/1] - add CMake support 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | CMakeLists.txt | 81 +++++++++++++++++++++++++++++++++++++ 9 | lora_pkt_fwd/CMakeLists.txt | 68 +++++++++++++++++++++++++++++++ 10 | util_ack/CMakeLists.txt | 36 +++++++++++++++++ 11 | util_sink/CMakeLists.txt | 37 +++++++++++++++++ 12 | util_tx_test/CMakeLists.txt | 43 ++++++++++++++++++++ 13 | 5 files changed, 265 insertions(+) 14 | create mode 100644 CMakeLists.txt 15 | create mode 100644 lora_pkt_fwd/CMakeLists.txt 16 | create mode 100644 util_ack/CMakeLists.txt 17 | create mode 100644 util_sink/CMakeLists.txt 18 | create mode 100644 util_tx_test/CMakeLists.txt 19 | 20 | Index: packet_forwarder-4.0.1/CMakeLists.txt 21 | =================================================================== 22 | --- /dev/null 23 | +++ packet_forwarder-4.0.1/CMakeLists.txt 24 | @@ -0,0 +1,90 @@ 25 | +# -- Minimum required version 26 | +cmake_minimum_required (VERSION 3.2) 27 | + 28 | +# -- Project name 29 | +project (packet_forwarder) 30 | + 31 | +# -- Various includes 32 | +include (CMakePackageConfigHelpers) 33 | +include (GNUInstallDirs) 34 | +include (CheckFunctionExists) 35 | + 36 | +# -- set c99 standard default 37 | +set(CMAKE_C_STANDARD 99) 38 | + 39 | +# -- Required to build 40 | +set(CMAKE_THREAD_PREFER_PTHREAD TRUE) 41 | +set(THREADS_PREFER_PTHREAD_FLAG TRUE) 42 | +find_package(Threads REQUIRED) 43 | + 44 | +# -- Versioning with git tag 45 | +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 46 | + execute_process( 47 | + COMMAND git describe --tags --always 48 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 49 | + OUTPUT_VARIABLE "packet_forwarder_VERSION" 50 | + ERROR_QUIET 51 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 52 | + if(packet_forwarder_VERSION STREQUAL "") 53 | + set(packet_forwarder_VERSION 0) 54 | + endif(packet_forwarder_VERSION STREQUAL "") 55 | + message( STATUS "Git full version: ${packet_forwarder_VERSION}" ) 56 | + execute_process( 57 | + COMMAND /bin/bash -c "git describe --tags --abbrev=0 | cut --delimiter='v' --fields=2" 58 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 59 | + OUTPUT_VARIABLE "packet_forwarder_VERSION_SHORT" 60 | + ERROR_QUIET 61 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 62 | + if(packet_forwarder_VERSION_SHORT STREQUAL "") 63 | + set(packet_forwarder_VERSION_SHORT 0) 64 | + endif(packet_forwarder_VERSION_SHORT STREQUAL "") 65 | + message( STATUS "Git version: ${packet_forwarder_VERSION_SHORT}" ) 66 | +else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 67 | + set(packet_forwarder_VERSION_SHORT 0) 68 | + set(packet_forwarder_VERSION 0) 69 | +endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 70 | + 71 | +# -- find packages 72 | +find_package(loragw QUIET) 73 | +if(NOT loragw_FOUND) 74 | + find_package(PkgConfig) 75 | + pkg_search_module(LORAGW loragw) 76 | + 77 | + if(LORAGW_FOUND AND LORAGW_LINK_LIBRARIES) 78 | + message("-- pkg_config: libloragw is found") 79 | + message("-- libloragw include: ${LORAGW_INCLUDE_DIRS}") 80 | + message("-- libloragw library: ${LORAGW_LINK_LIBRARIES}") 81 | + else() 82 | + # a workaround for https://github.com/xueliu/lora-feed/issues/6 83 | + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") 84 | + find_package(loragw QUIET) 85 | + if(LORAGW_FOUND) 86 | + message("-- Findloragw: libloragw is found") 87 | + message("-- libloragw include: ${LORAGW_INCLUDE_DIRS}") 88 | + message("-- libloragw library: ${LORAGW_LINK_LIBRARIES}") 89 | + else() 90 | + message(FATAL_ERROR "-- CMake: libloragw is not found") 91 | + endif() 92 | + endif() 93 | +else() 94 | + message("-- CMake: libloragw is found") 95 | +endif() 96 | + 97 | +# when building, don't use the install RPATH already 98 | +# (but later on when installing) 99 | +SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 100 | +if (NOT (${CMAKE_INSTALL_PREFIX} STREQUAL "/usr" ) ) 101 | + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") 102 | +endif() 103 | + 104 | +# -- add the lora_pkt_fwd 105 | +add_subdirectory(lora_pkt_fwd) 106 | + 107 | +# -- add the util_ack 108 | +add_subdirectory(util_ack) 109 | + 110 | +# -- add the util_sink 111 | +add_subdirectory(util_sink) 112 | + 113 | +# -- add the util_tx_test 114 | +add_subdirectory(util_tx_test) 115 | Index: packet_forwarder-4.0.1/lora_pkt_fwd/CMakeLists.txt 116 | =================================================================== 117 | --- /dev/null 118 | +++ packet_forwarder-4.0.1/lora_pkt_fwd/CMakeLists.txt 119 | @@ -0,0 +1,68 @@ 120 | +set(TARGET lora_pkt_fwd) 121 | + 122 | +add_executable(${TARGET} "") 123 | + 124 | +# -- add the compile options 125 | +target_compile_options( 126 | + ${TARGET} 127 | + PRIVATE 128 | + -Wall 129 | + -Wextra 130 | +) 131 | + 132 | +target_compile_definitions( 133 | + ${TARGET} 134 | + PRIVATE 135 | + VERSION_STRING="${packet_forwarder_VERSION_SHORT}" 136 | +) 137 | + 138 | +target_sources(${TARGET} 139 | + PRIVATE 140 | + ${CMAKE_CURRENT_LIST_DIR}/src/base64.c 141 | + ${CMAKE_CURRENT_LIST_DIR}/src/jitqueue.c 142 | + ${CMAKE_CURRENT_LIST_DIR}/src/lora_pkt_fwd.c 143 | + ${CMAKE_CURRENT_LIST_DIR}/src/parson.c 144 | + ${CMAKE_CURRENT_LIST_DIR}/src/timersync.c 145 | +) 146 | + 147 | +target_include_directories(${TARGET} 148 | + PRIVATE 149 | + ${CMAKE_CURRENT_LIST_DIR} 150 | + ${CMAKE_CURRENT_LIST_DIR}/inc 151 | +) 152 | + 153 | +target_link_libraries(${TARGET} 154 | + PUBLIC 155 | + Threads::Threads 156 | + m 157 | +) 158 | + 159 | +if(LORAGW_FOUND) 160 | +target_include_directories(${TARGET} 161 | + PRIVATE 162 | + ${LORAGW_INCLUDE_DIRS} 163 | +) 164 | + 165 | +target_link_libraries(${TARGET} 166 | + PRIVATE 167 | + ${LORAGW_LINK_LIBRARIES} 168 | +) 169 | + 170 | +elseif(loragw_FOUND) 171 | + 172 | +target_link_libraries(${TARGET} 173 | + PRIVATE 174 | + Semtech::loragw 175 | +) 176 | +endif() 177 | + 178 | +set_target_properties(${TARGET} PROPERTIES VERSION ${packet_forwarder_VERSION}) 179 | +set_target_properties(${TARGET} PROPERTIES SOVERSION ${packet_forwarder_VERSION_SHORT}) 180 | + 181 | +# add the install targets 182 | +install ( 183 | + TARGETS ${TARGET} 184 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 185 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 186 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 187 | +) 188 | Index: packet_forwarder-4.0.1/util_ack/CMakeLists.txt 189 | =================================================================== 190 | --- /dev/null 191 | +++ packet_forwarder-4.0.1/util_ack/CMakeLists.txt 192 | @@ -0,0 +1,36 @@ 193 | + 194 | +add_executable(util_ack "") 195 | +target_sources(util_ack 196 | + PRIVATE 197 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_ack.c 198 | +) 199 | + 200 | +if(LORAGW_FOUND) 201 | +target_include_directories(util_ack 202 | + PRIVATE 203 | + ${LORAGW_INCLUDE_DIRS} 204 | +) 205 | + 206 | +target_link_libraries(util_ack 207 | + PRIVATE 208 | + ${LORAGW_LINK_LIBRARIES} 209 | +) 210 | + 211 | +elseif(loragw_FOUND) 212 | + 213 | +target_link_libraries(util_ack 214 | + PRIVATE 215 | + Semtech::loragw 216 | +) 217 | +endif() 218 | +set_target_properties(util_ack PROPERTIES 219 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 220 | +) 221 | + 222 | +# add the install targets 223 | +install ( 224 | + TARGETS util_ack 225 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 226 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 227 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 228 | +) 229 | Index: packet_forwarder-4.0.1/util_sink/CMakeLists.txt 230 | =================================================================== 231 | --- /dev/null 232 | +++ packet_forwarder-4.0.1/util_sink/CMakeLists.txt 233 | @@ -0,0 +1,37 @@ 234 | + 235 | +add_executable(util_sink "") 236 | +target_sources(util_sink 237 | + PRIVATE 238 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_sink.c 239 | +) 240 | + 241 | +if(LORAGW_FOUND) 242 | +target_include_directories(util_sink 243 | + PRIVATE 244 | + ${LORAGW_INCLUDE_DIRS} 245 | +) 246 | + 247 | +target_link_libraries(util_sink 248 | + PRIVATE 249 | + ${LORAGW_LINK_LIBRARIES} 250 | +) 251 | + 252 | +elseif(loragw_FOUND) 253 | + 254 | +target_link_libraries(util_sink 255 | + PRIVATE 256 | + Semtech::loragw 257 | +) 258 | +endif() 259 | + 260 | +set_target_properties(util_sink PROPERTIES 261 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 262 | +) 263 | + 264 | +# add the install targets 265 | +install ( 266 | + TARGETS util_sink 267 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 268 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 269 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 270 | +) 271 | Index: packet_forwarder-4.0.1/util_tx_test/CMakeLists.txt 272 | =================================================================== 273 | --- /dev/null 274 | +++ packet_forwarder-4.0.1/util_tx_test/CMakeLists.txt 275 | @@ -0,0 +1,43 @@ 276 | + 277 | +add_executable(util_tx_test "") 278 | +target_sources(util_tx_test 279 | + PRIVATE 280 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_tx_test.c 281 | + ${CMAKE_CURRENT_LIST_DIR}/src/base64.c 282 | +) 283 | + 284 | +target_include_directories(util_tx_test 285 | + PRIVATE 286 | + ${CMAKE_CURRENT_LIST_DIR}/inc 287 | +) 288 | + 289 | +if(LORAGW_FOUND) 290 | +target_include_directories(util_tx_test 291 | + PRIVATE 292 | + ${LORAGW_INCLUDE_DIRS} 293 | +) 294 | + 295 | +target_link_libraries(util_tx_test 296 | + PRIVATE 297 | + ${LORAGW_LINK_LIBRARIES} 298 | +) 299 | + 300 | +elseif(loragw_FOUND) 301 | + 302 | +target_link_libraries(util_tx_test 303 | + PRIVATE 304 | + Semtech::loragw 305 | +) 306 | +endif() 307 | + 308 | +set_target_properties(util_tx_test PROPERTIES 309 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 310 | +) 311 | + 312 | +# add the install targets 313 | +install ( 314 | + TARGETS util_tx_test 315 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 316 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 317 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 318 | +) 319 | Index: packet_forwarder-4.0.1/cmake/Modules/Findloragw.cmake 320 | =================================================================== 321 | --- /dev/null 322 | +++ packet_forwarder-4.0.1/cmake/Modules/Findloragw.cmake 323 | @@ -0,0 +1,36 @@ 324 | +# Find loragw 325 | +# 326 | +# Find the loragw includes and library 327 | +# 328 | +# if you need to add a custom library search path, do it via CMAKE_PREFIX_PATH 329 | +# 330 | +# This module defines 331 | +# LORAGW_INCLUDE_DIRS, where to find header, etc. 332 | +# LORAGW_LIBRARIES, the libraries needed to use loragw. 333 | +# LORAGW_LINK_LIBRARIES, the libraries needed to use loragw. 334 | +# LORAGW_FOUND, If false, do not try to use loragw. 335 | + 336 | +# only look in default directories 337 | +find_path( 338 | + LORAGW_INCLUDE_DIR 339 | + NAMES loragw_hal.h # only one of those head files 340 | + PATH_SUFFIXES "libloragw" 341 | + DOC "loragw include dir" 342 | +) 343 | + 344 | +find_library( 345 | + LORAGW_LIBRARY 346 | + NAMES loragw libloragw 347 | + DOC "loragw library" 348 | +) 349 | + 350 | +set(LORAGW_INCLUDE_DIRS ${LORAGW_INCLUDE_DIR}) 351 | +set(LORAGW_LIBRARIES ${LORAGW_LIBRARY}) 352 | +set(LORAGW_LINK_LIBRARIES ${LORAGW_LIBRARY}) 353 | + 354 | +# handle the QUIETLY and REQUIRED arguments and set USATCK_FOUND to TRUE 355 | +# if all listed variables are TRUE, hide their existence from configuration view 356 | +include(FindPackageHandleStandardArgs) 357 | +find_package_handle_standard_args(loragw DEFAULT_MSG 358 | + LORAGW_LIBRARY LORAGW_INCLUDE_DIR ) 359 | +mark_as_advanced (LORAGW_INCLUDE_DIR LORAGW_LIBRARY) 360 | -------------------------------------------------------------------------------- /lora-picogw-hal/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=lora-picogw-hal 11 | PKG_VERSION:=0.2.2 12 | PKG_RELEASE:=1 13 | 14 | PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/picoGW_hal/tar.gz/V$(PKG_VERSION)? 15 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 16 | PKG_HASH:=4841940f621342ba55767f79b738669417a7e572d7143d94e2b512ae8c45d05f 17 | PKG_MAINTAINER:=Xue Liu 18 | PKG_LICENSE_FILES:=LICENSE 19 | PKG_BUILD_DIR:=$(BUILD_DIR)/picoGW_hal-$(PKG_VERSION) 20 | 21 | include $(INCLUDE_DIR)/package.mk 22 | include $(INCLUDE_DIR)/cmake.mk 23 | 24 | define Package/libpicogw 25 | SECTION:=libs 26 | CATEGORY:=Libraries 27 | TITLE:=Driver/HAL library for Semtech SX1308 Picocell Gateway 28 | URL:=https://www.semtech.com/products/wireless-rf/lora-gateways/sx1308 29 | DEPENDS:=+kmod-usb-acm 30 | endef 31 | 32 | define Package/libpicogw/description 33 | Host driver/HAL to build a LoRa Picocell Gateway which communicates 34 | through USB with a concentrator board based on Semtech SX1308 35 | multi-channel modem and SX1257/SX1255 RF transceivers. 36 | endef 37 | 38 | define Package/libpicogw-tests 39 | SECTION:=net 40 | CATEGORY:=Network 41 | SUBMENU:=LoRaWAN 42 | TITLE:=Test programs for libpicogw to check functionality 43 | DEPENDS:=libpicogw 44 | endef 45 | 46 | define Package/libpicogw-utils 47 | SECTION:=net 48 | CATEGORY:=Network 49 | SUBMENU:=LoRaWAN 50 | TITLE:=Utility programs for libpicogw 51 | DEPENDS:=libpicogw 52 | endef 53 | 54 | CMAKE_OPTIONS += \ 55 | -Dpicogw_hal_build_shared_libs=ON 56 | 57 | define Build/InstallDev 58 | $(INSTALL_DIR) $(1)/usr/include/libpicogw 59 | $(CP) $(PKG_BUILD_DIR)/libloragw/inc/loragw_* $(1)/usr/include/libpicogw 60 | $(CP) $(PKG_BUILD_DIR)/libloragw/config.h $(1)/usr/include/libpicogw 61 | $(INSTALL_DIR) $(1)/usr/lib 62 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/libloragw/libpicogw.so* $(1)/usr/lib/ 63 | $(LN) libpicogw.so.0 $(1)/usr/lib/libpicogw.so 64 | $(INSTALL_DIR) $(1)/usr/lib/pkgconfig 65 | $(CP) $(PKG_BUILD_DIR)/picogw.pc $(1)/usr/lib/pkgconfig/ 66 | endef 67 | 68 | define Package/libpicogw/install 69 | $(INSTALL_DIR) $(1)/usr/lib 70 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/libloragw/libpicogw.so.* $(1)/usr/lib/ 71 | endef 72 | 73 | define Package/libpicogw-tests/install 74 | $(INSTALL_DIR) $(1)/usr/sbin 75 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/libloragw/test* $(1)/usr/sbin 76 | endef 77 | 78 | define Package/libpicogw-utils/install 79 | $(INSTALL_DIR) $(1)/usr/sbin 80 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_boot $(1)/usr/sbin 81 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_chip_id $(1)/usr/sbin 82 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_com_stress $(1)/usr/sbin 83 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_pkt_logger $(1)/usr/sbin 84 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_continuous $(1)/usr/sbin 85 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_test $(1)/usr/sbin 86 | endef 87 | 88 | $(eval $(call BuildPackage,libpicogw)) 89 | $(eval $(call BuildPackage,libpicogw-tests)) 90 | $(eval $(call BuildPackage,libpicogw-utils)) 91 | -------------------------------------------------------------------------------- /lora-picogw-hal/patches/0001-add-CMake-support.patch: -------------------------------------------------------------------------------- 1 | From cd72aa8e9b8dc5fe1ac87ef319b8ccb206d268f6 Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Thu, 28 Feb 2019 16:31:45 +0100 4 | Subject: [PATCH 1/1] add CMake support 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | CMakeLists.txt | 77 +++++++++++++ 9 | cmake/picogw-config.cmake | 1 + 10 | libloragw/CMakeLists.txt | 183 ++++++++++++++++++++++++++++++ 11 | libloragw/picogw.pc.in | 10 ++ 12 | libloragw/picogw_config.h.in | 12 ++ 13 | util_boot/CMakeLists.txt | 23 ++++ 14 | util_chip_id/CMakeLists.txt | 23 ++++ 15 | util_com_stress/CMakeLists.txt | 23 ++++ 16 | util_pkt_logger/CMakeLists.txt | 29 +++++ 17 | util_tx_continuous/CMakeLists.txt | 23 ++++ 18 | util_tx_test/CMakeLists.txt | 23 ++++ 19 | 11 files changed, 427 insertions(+) 20 | create mode 100644 CMakeLists.txt 21 | create mode 100644 cmake/picogw-config.cmake 22 | create mode 100644 libloragw/CMakeLists.txt 23 | create mode 100644 libloragw/picogw.pc.in 24 | create mode 100644 libloragw/picogw_config.h.in 25 | create mode 100644 util_boot/CMakeLists.txt 26 | create mode 100644 util_chip_id/CMakeLists.txt 27 | create mode 100644 util_com_stress/CMakeLists.txt 28 | create mode 100644 util_pkt_logger/CMakeLists.txt 29 | create mode 100644 util_tx_continuous/CMakeLists.txt 30 | create mode 100644 util_tx_test/CMakeLists.txt 31 | 32 | diff --git a/CMakeLists.txt b/CMakeLists.txt 33 | new file mode 100644 34 | index 0000000..9b491bb 35 | --- /dev/null 36 | +++ b/CMakeLists.txt 37 | @@ -0,0 +1,77 @@ 38 | +# -- Minimum required version 39 | +cmake_minimum_required (VERSION 3.2) 40 | + 41 | +# -- Project name 42 | +project (picogw_hal) 43 | + 44 | +# -- Various includes 45 | +include (CMakePackageConfigHelpers) 46 | +include (GNUInstallDirs) 47 | +#include (CheckFunctionExists) 48 | + 49 | +# -- set c99 standard default 50 | +set(CMAKE_C_STANDARD 99) 51 | + 52 | +# -- options for shared lib (defaults off) 53 | +option(picogw_hal_build_shared_libs "build as a shared library" OFF) 54 | +set(BUILD_SHARED_LIBS ${picogw_hal_build_shared_libs}) 55 | + 56 | +# -- Required to build 57 | +set(CMAKE_THREAD_PREFER_PTHREAD TRUE) 58 | +set(THREADS_PREFER_PTHREAD_FLAG TRUE) 59 | +find_package(Threads REQUIRED) 60 | + 61 | +# -- Versioning with git tag 62 | +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 63 | + execute_process( 64 | + COMMAND git describe --tags --always 65 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 66 | + OUTPUT_VARIABLE "picogw_hal_VERSION" 67 | + ERROR_QUIET 68 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 69 | + if(picogw_hal_VERSION STREQUAL "") 70 | + set(picogw_hal_VERSION 0) 71 | + endif(picogw_hal_VERSION STREQUAL "") 72 | + message( STATUS "Git full version: ${picogw_hal_VERSION}" ) 73 | + execute_process( 74 | + COMMAND /bin/bash -c "git describe --tags --abbrev=0 | cut --delimiter='v' --fields=2" 75 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 76 | + OUTPUT_VARIABLE "picogw_hal_VERSION_SHORT" 77 | + ERROR_QUIET 78 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 79 | + if(picogw_hal_VERSION_SHORT STREQUAL "") 80 | + set(picogw_hal_VERSION_SHORT 0) 81 | + endif(picogw_hal_VERSION_SHORT STREQUAL "") 82 | + message( STATUS "Git version: ${picogw_hal_VERSION_SHORT}" ) 83 | +else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 84 | + set(picogw_hal_VERSION_SHORT 0) 85 | + set(picogw_hal_VERSION 0) 86 | +endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 87 | + 88 | +# when building, don't use the install RPATH already 89 | +# (but later on when installing) 90 | +SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 91 | +if (NOT (${CMAKE_INSTALL_PREFIX} STREQUAL "/usr" ) ) 92 | + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") 93 | +endif() 94 | + 95 | +# -- add the core library 96 | +add_subdirectory(libloragw) 97 | + 98 | +# -- add util_boot 99 | +add_subdirectory(util_boot) 100 | + 101 | +# -- add util_chip_id 102 | +add_subdirectory(util_chip_id) 103 | + 104 | +# -- add util_pkt_logger 105 | +add_subdirectory(util_pkt_logger) 106 | + 107 | +# -- add util_com_stress 108 | +add_subdirectory(util_com_stress) 109 | + 110 | +# -- add util_tx_continuous 111 | +add_subdirectory(util_tx_continuous) 112 | + 113 | +# -- add util_tx_test 114 | +add_subdirectory(util_tx_test) 115 | diff --git a/cmake/picogw-config.cmake b/cmake/picogw-config.cmake 116 | new file mode 100644 117 | index 0000000..5313ea0 118 | --- /dev/null 119 | +++ b/cmake/picogw-config.cmake 120 | @@ -0,0 +1 @@ 121 | +include("${CMAKE_CURRENT_LIST_DIR}/picogw-targets.cmake") 122 | diff --git a/libloragw/CMakeLists.txt b/libloragw/CMakeLists.txt 123 | new file mode 100644 124 | index 0000000..7dc3082 125 | --- /dev/null 126 | +++ b/libloragw/CMakeLists.txt 127 | @@ -0,0 +1,183 @@ 128 | +set(TARGET picogw) 129 | + 130 | +add_library(${TARGET} "") 131 | + 132 | +# -- add additional debug options 133 | +# Set the DEBUG_* to 1 to activate debug mode in individual modules. 134 | +# Warning: that makes the module *very verbose*, do not use for production 135 | +option(DEBUG_AUX "Active debug mode in AUX module" OFF) 136 | +option(DEBUG_COM "Active debug mode in COM module" OFF) 137 | +option(DEBUG_REG "Active debug mode in REG module" OFF) 138 | +option(DEBUG_MCU "Active debug mode in MCU module" OFF) 139 | +option(DEBUG_HAL "Active debug mode in HAL module" OFF) 140 | + 141 | +message("-- Build with debug AUX: ${DEBUG_AUX}") 142 | +message("-- Build with debug COM: ${DEBUG_COM}") 143 | +message("-- Build with debug REG: ${DEBUG_REG}") 144 | +message("-- Build with debug MCU: ${DEBUG_MCU}") 145 | +message("-- Build with debug HAL: ${DEBUG_HAL}") 146 | + 147 | +# -- add the compile options 148 | +target_compile_options( 149 | + ${TARGET} 150 | + PRIVATE 151 | + -Werror 152 | + -Wall 153 | + -Wextra 154 | +) 155 | + 156 | +target_sources(${TARGET} 157 | + PRIVATE 158 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_aux.c 159 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_com.c 160 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_com_linux.c 161 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_hal.c 162 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_mcu.c 163 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_radio.c 164 | + ${CMAKE_CURRENT_LIST_DIR}/src/loragw_reg.c 165 | +) 166 | + 167 | +# -- add the public headers 168 | +set (${TARGET}_PUBLIC_HEADERS 169 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_aux.h 170 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_com.h 171 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_com_linux.h 172 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_hal.h 173 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_mcu.h 174 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_radio.h 175 | + ${CMAKE_CURRENT_LIST_DIR}/inc/loragw_reg.h 176 | +) 177 | + 178 | +target_include_directories(${TARGET} 179 | + PRIVATE 180 | + ${CMAKE_CURRENT_LIST_DIR} 181 | + ${CMAKE_CURRENT_LIST_DIR}/inc 182 | + PUBLIC 183 | + $ 184 | + $ 185 | + $ 186 | +) 187 | + 188 | +configure_file(${CMAKE_CURRENT_LIST_DIR}/${TARGET}_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) 189 | + 190 | +target_link_libraries(${TARGET} 191 | + PUBLIC 192 | + Threads::Threads 193 | + m 194 | +) 195 | + 196 | +set_target_properties(${TARGET} PROPERTIES VERSION ${picogw_hal_VERSION_SHORT}) 197 | +set_target_properties(${TARGET} PROPERTIES SOVERSION ${picogw_hal_VERSION_SHORT}) 198 | +set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_BINARY_DIR}/config.h;${${TARGET}_PUBLIC_HEADERS}") 199 | + 200 | +# -- add the install targets 201 | +install (TARGETS ${TARGET} 202 | + EXPORT ${TARGET}_targets 203 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 204 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 205 | + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET} 206 | + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET} 207 | +) 208 | + 209 | +# -- add pkg config file 210 | +configure_file ("${CMAKE_CURRENT_LIST_DIR}/${TARGET}.pc.in" "${PROJECT_BINARY_DIR}/${TARGET}.pc" @ONLY) 211 | +install (FILES ${PROJECT_BINARY_DIR}/${TARGET}.pc DESTINATION lib/pkgconfig) 212 | + 213 | +# -- write cmake package config file 214 | +write_basic_package_version_file( 215 | + "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-config-version.cmake" 216 | + VERSION ${picogw_hal_VERSION} 217 | + COMPATIBILITY AnyNewerVersion 218 | +) 219 | + 220 | +export(EXPORT ${TARGET}_targets 221 | + FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-targets.cmake" 222 | + NAMESPACE Semtech:: 223 | +) 224 | + 225 | +configure_file(${PROJECT_SOURCE_DIR}/cmake/${TARGET}-config.cmake 226 | + "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-config.cmake" 227 | + COPYONLY 228 | +) 229 | + 230 | +set(ConfigPackageLocation lib/cmake/${TARGET}) 231 | + 232 | +install(EXPORT ${TARGET}_targets 233 | + FILE ${TARGET}-targets.cmake 234 | + NAMESPACE Semtech:: 235 | + DESTINATION ${ConfigPackageLocation} 236 | +) 237 | + 238 | +install( 239 | + FILES ${PROJECT_SOURCE_DIR}/cmake/${TARGET}-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}/${TARGET}-config-version.cmake" 240 | + DESTINATION ${ConfigPackageLocation} 241 | + COMPONENT Devel 242 | +) 243 | + 244 | +add_executable(test_loragw_reg "") 245 | +target_sources(test_loragw_reg 246 | + PRIVATE 247 | + ${CMAKE_CURRENT_LIST_DIR}/tst/test_loragw_reg.c 248 | +) 249 | + 250 | +target_include_directories(test_loragw_reg 251 | + PRIVATE 252 | + $ 253 | + $ 254 | + ${CMAKE_CURRENT_LIST_DIR}/inc 255 | + ${CMAKE_CURRENT_BINARY_DIR} 256 | +) 257 | + 258 | +target_link_libraries(test_loragw_reg 259 | + PRIVATE 260 | + picogw 261 | +) 262 | + 263 | +add_executable(test_loragw_hal "") 264 | +target_sources(test_loragw_hal 265 | + PRIVATE 266 | + ${CMAKE_CURRENT_LIST_DIR}/tst/test_loragw_hal.c 267 | +) 268 | + 269 | +target_include_directories(test_loragw_hal 270 | + PRIVATE 271 | + $ 272 | + $ 273 | + ${CMAKE_CURRENT_LIST_DIR}/inc 274 | + ${CMAKE_CURRENT_BINARY_DIR} 275 | +) 276 | + 277 | +target_link_libraries(test_loragw_hal 278 | + PRIVATE 279 | + picogw 280 | +) 281 | + 282 | +add_executable(test_loragw_cal "") 283 | +target_sources(test_loragw_cal 284 | + PRIVATE 285 | + ${CMAKE_CURRENT_LIST_DIR}/tst/test_loragw_cal.c 286 | +) 287 | + 288 | +target_include_directories(test_loragw_cal 289 | + PRIVATE 290 | + $ 291 | + $ 292 | + ${CMAKE_CURRENT_LIST_DIR}/inc 293 | + ${CMAKE_CURRENT_BINARY_DIR} 294 | +) 295 | + 296 | +target_link_libraries(test_loragw_cal 297 | + PRIVATE 298 | + picogw 299 | +) 300 | + 301 | +# add the install targets 302 | +install ( 303 | + TARGETS 304 | + test_loragw_reg 305 | + test_loragw_hal 306 | + test_loragw_cal 307 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 308 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 309 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 310 | +) 311 | diff --git a/libloragw/picogw.pc.in b/libloragw/picogw.pc.in 312 | new file mode 100644 313 | index 0000000..83f9b9e 314 | --- /dev/null 315 | +++ b/libloragw/picogw.pc.in 316 | @@ -0,0 +1,10 @@ 317 | +prefix=@CMAKE_INSTALL_PREFIX@ 318 | +exec_prefix=${prefix}/bin 319 | +includedir=${prefix}/include/libpicogw 320 | +libdir=${prefix}/lib 321 | + 322 | +Name: LIBLORAGW 323 | +Description: BLANK_TEXT 324 | +Version: @picogw_hal_VERSION@ 325 | +Cflags: -I${includedir} 326 | +Libs: -L${libdir} -lpicogw 327 | diff --git a/libloragw/picogw_config.h.in b/libloragw/picogw_config.h.in 328 | new file mode 100644 329 | index 0000000..057aece 330 | --- /dev/null 331 | +++ b/libloragw/picogw_config.h.in 332 | @@ -0,0 +1,12 @@ 333 | +#ifndef _LORAGW_CONFIGURATION_H 334 | +#define _LORAGW_CONFIGURATION_H 335 | + 336 | +#define LIBLORAGW_VERSION "@picogw_hal_VERSION_SHORT@" 337 | + 338 | +#cmakedefine01 DEBUG_AUX 339 | +#cmakedefine01 DEBUG_COM 340 | +#cmakedefine01 DEBUG_REG 341 | +#cmakedefine01 DEBUG_MCU 342 | +#cmakedefine01 DEBUG_HAL 343 | + 344 | +#endif 345 | diff --git a/util_boot/CMakeLists.txt b/util_boot/CMakeLists.txt 346 | new file mode 100644 347 | index 0000000..a5a0017 348 | --- /dev/null 349 | +++ b/util_boot/CMakeLists.txt 350 | @@ -0,0 +1,23 @@ 351 | + 352 | +add_executable(util_boot "") 353 | +target_sources(util_boot 354 | + PRIVATE 355 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_boot.c 356 | +) 357 | + 358 | +target_link_libraries(util_boot 359 | + PUBLIC 360 | + picogw 361 | +) 362 | + 363 | +set_target_properties(util_boot PROPERTIES 364 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 365 | +) 366 | + 367 | +# add the install targets 368 | +install ( 369 | + TARGETS util_boot 370 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 371 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 372 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 373 | +) 374 | diff --git a/util_chip_id/CMakeLists.txt b/util_chip_id/CMakeLists.txt 375 | new file mode 100644 376 | index 0000000..e7a15bc 377 | --- /dev/null 378 | +++ b/util_chip_id/CMakeLists.txt 379 | @@ -0,0 +1,23 @@ 380 | + 381 | +add_executable(util_chip_id "") 382 | +target_sources(util_chip_id 383 | + PRIVATE 384 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_chip_id.c 385 | +) 386 | + 387 | +target_link_libraries(util_chip_id 388 | + PUBLIC 389 | + picogw 390 | +) 391 | + 392 | +set_target_properties(util_chip_id PROPERTIES 393 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 394 | +) 395 | + 396 | +# add the install targets 397 | +install ( 398 | + TARGETS util_chip_id 399 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 400 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 401 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 402 | +) 403 | diff --git a/util_com_stress/CMakeLists.txt b/util_com_stress/CMakeLists.txt 404 | new file mode 100644 405 | index 0000000..cde6528 406 | --- /dev/null 407 | +++ b/util_com_stress/CMakeLists.txt 408 | @@ -0,0 +1,23 @@ 409 | + 410 | +add_executable(util_com_stress "") 411 | +target_sources(util_com_stress 412 | + PRIVATE 413 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_com_stress.c 414 | +) 415 | + 416 | +target_link_libraries(util_com_stress 417 | + PUBLIC 418 | + picogw 419 | +) 420 | + 421 | +set_target_properties(util_com_stress PROPERTIES 422 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 423 | +) 424 | + 425 | +# add the install targets 426 | +install ( 427 | + TARGETS util_com_stress 428 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 429 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 430 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 431 | +) 432 | diff --git a/util_pkt_logger/CMakeLists.txt b/util_pkt_logger/CMakeLists.txt 433 | new file mode 100644 434 | index 0000000..e0882bc 435 | --- /dev/null 436 | +++ b/util_pkt_logger/CMakeLists.txt 437 | @@ -0,0 +1,29 @@ 438 | + 439 | +add_executable(util_pkt_logger "") 440 | +target_sources(util_pkt_logger 441 | + PRIVATE 442 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_pkt_logger.c 443 | + ${CMAKE_CURRENT_LIST_DIR}/src/parson.c 444 | +) 445 | + 446 | +target_include_directories(util_pkt_logger 447 | + PRIVATE 448 | + ${CMAKE_CURRENT_LIST_DIR}/inc 449 | +) 450 | + 451 | +target_link_libraries(util_pkt_logger 452 | + PUBLIC 453 | + picogw 454 | +) 455 | + 456 | +set_target_properties(util_pkt_logger PROPERTIES 457 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 458 | +) 459 | + 460 | +# add the install targets 461 | +install ( 462 | + TARGETS util_pkt_logger 463 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 464 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 465 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 466 | +) 467 | diff --git a/util_tx_continuous/CMakeLists.txt b/util_tx_continuous/CMakeLists.txt 468 | new file mode 100644 469 | index 0000000..12010a2 470 | --- /dev/null 471 | +++ b/util_tx_continuous/CMakeLists.txt 472 | @@ -0,0 +1,23 @@ 473 | + 474 | +add_executable(util_tx_continuous "") 475 | +target_sources(util_tx_continuous 476 | + PRIVATE 477 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_tx_continuous.c 478 | +) 479 | + 480 | +target_link_libraries(util_tx_continuous 481 | + PUBLIC 482 | + picogw 483 | +) 484 | + 485 | +set_target_properties(util_tx_continuous PROPERTIES 486 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 487 | +) 488 | + 489 | +# add the install targets 490 | +install ( 491 | + TARGETS util_tx_continuous 492 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 493 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 494 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 495 | +) 496 | diff --git a/util_tx_test/CMakeLists.txt b/util_tx_test/CMakeLists.txt 497 | new file mode 100644 498 | index 0000000..8041b3c 499 | --- /dev/null 500 | +++ b/util_tx_test/CMakeLists.txt 501 | @@ -0,0 +1,23 @@ 502 | + 503 | +add_executable(util_tx_test "") 504 | +target_sources(util_tx_test 505 | + PRIVATE 506 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_tx_test.c 507 | +) 508 | + 509 | +target_link_libraries(util_tx_test 510 | + PUBLIC 511 | + picogw 512 | +) 513 | + 514 | +set_target_properties(util_tx_test PROPERTIES 515 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 516 | +) 517 | + 518 | +# add the install targets 519 | +install ( 520 | + TARGETS util_tx_test 521 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 522 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 523 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 524 | +) 525 | -- 526 | 2.22.0 527 | 528 | -------------------------------------------------------------------------------- /lora-picogw-packet-forwarder/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=lora-picogw-packet-forwarder 11 | PKG_VERSION:=0.1.0 12 | PKG_RELEASE:=1 13 | 14 | PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/picoGW_packet_forwarder/tar.gz/V$(PKG_VERSION)? 15 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 16 | PKG_HASH:=cc6f15be9b95e9b5c28dae97c96244cff651e303b3991b254ef4dcba3f59f562 17 | PKG_MAINTAINER:=Xue Liu 18 | PKG_LICENSE_FILES:=LICENSE 19 | PKG_BUILD_DIR:=$(BUILD_DIR)/picoGW_packet_forwarder-$(PKG_VERSION) 20 | 21 | include $(INCLUDE_DIR)/package.mk 22 | include $(INCLUDE_DIR)/cmake.mk 23 | 24 | define Package/lora-picogw-packet-forwarder 25 | SECTION:=net 26 | CATEGORY:=Network 27 | SUBMENU:=LoRaWAN 28 | TITLE:=Semtech packet-forwarder program 29 | DEPENDS:=+libpicogw 30 | endef 31 | 32 | define Package/lora-picogw-packet-forwarder/description 33 | A LoRa packet forwarder is a program running on the host of a LoRa 34 | Picocell (USB) gateway that forwards RF packets receive by the 35 | concentrator to a server through a IP/UDP link, and emits RF packets 36 | that are sent by the server. 37 | endef 38 | 39 | define Package/lora-picogw-packet-forwarder-utils 40 | SECTION:=net 41 | CATEGORY:=Network 42 | SUBMENU:=LoRaWAN 43 | TITLE:=Utilities for lora packet forwarder 44 | DEPENDS:=lora-picogw-packet-forwarder 45 | endef 46 | 47 | define Package/lora-picogw-packet-forwarder/install 48 | $(INSTALL_DIR) $(1)/usr/sbin 49 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/lora_pkt_fwd/pico_pkt_fwd $(1)/usr/sbin 50 | endef 51 | 52 | define Package/lora-picogw-packet-forwarder-utils/install 53 | $(INSTALL_DIR) $(1)/usr/sbin 54 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_ack $(1)/usr/sbin 55 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_sink $(1)/usr/sbin 56 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/util_tx_test $(1)/usr/sbin 57 | endef 58 | 59 | $(eval $(call BuildPackage,lora-picogw-packet-forwarder)) 60 | $(eval $(call BuildPackage,lora-picogw-packet-forwarder-utils)) 61 | -------------------------------------------------------------------------------- /lora-picogw-packet-forwarder/patches/0001-add-CMake-support.patch: -------------------------------------------------------------------------------- 1 | From e8145c9726aac1c1251213d2e87a2e2aec34d455 Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Fri, 8 Mar 2019 14:49:41 +0100 4 | Subject: [PATCH 1/1] - add CMake support 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | CMakeLists.txt | 90 ++++++++++++++++++++++++++++++++++ 9 | cmake/Modules/Findpicogw.cmake | 36 ++++++++++++++ 10 | lora_pkt_fwd/CMakeLists.txt | 68 +++++++++++++++++++++++++ 11 | util_ack/CMakeLists.txt | 38 ++++++++++++++ 12 | util_sink/CMakeLists.txt | 38 ++++++++++++++ 13 | util_tx_test/CMakeLists.txt | 44 +++++++++++++++++ 14 | 6 files changed, 314 insertions(+) 15 | create mode 100644 CMakeLists.txt 16 | create mode 100644 cmake/Modules/Findpicogw.cmake 17 | create mode 100644 lora_pkt_fwd/CMakeLists.txt 18 | create mode 100644 util_ack/CMakeLists.txt 19 | create mode 100644 util_sink/CMakeLists.txt 20 | create mode 100644 util_tx_test/CMakeLists.txt 21 | 22 | diff --git a/CMakeLists.txt b/CMakeLists.txt 23 | new file mode 100644 24 | index 0000000..ab6ff33 25 | --- /dev/null 26 | +++ b/CMakeLists.txt 27 | @@ -0,0 +1,90 @@ 28 | +# -- Minimum required version 29 | +cmake_minimum_required (VERSION 3.2) 30 | + 31 | +# -- Project name 32 | +project (picogw_packet_forwarder) 33 | + 34 | +# -- Various includes 35 | +include (CMakePackageConfigHelpers) 36 | +include (GNUInstallDirs) 37 | +include (CheckFunctionExists) 38 | + 39 | +# -- set c99 standard default 40 | +set(CMAKE_C_STANDARD 99) 41 | + 42 | +# -- Required to build 43 | +set(CMAKE_THREAD_PREFER_PTHREAD TRUE) 44 | +set(THREADS_PREFER_PTHREAD_FLAG TRUE) 45 | +find_package(Threads REQUIRED) 46 | + 47 | +# -- Versioning with git tag 48 | +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 49 | + execute_process( 50 | + COMMAND git describe --tags --always 51 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 52 | + OUTPUT_VARIABLE "packet_forwarder_VERSION" 53 | + ERROR_QUIET 54 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 55 | + if(packet_forwarder_VERSION STREQUAL "") 56 | + set(packet_forwarder_VERSION 0) 57 | + endif(packet_forwarder_VERSION STREQUAL "") 58 | + message( STATUS "Git full version: ${packet_forwarder_VERSION}" ) 59 | + execute_process( 60 | + COMMAND /bin/bash -c "git describe --tags --abbrev=0 | cut --delimiter='v' --fields=2" 61 | + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 62 | + OUTPUT_VARIABLE "packet_forwarder_VERSION_SHORT" 63 | + ERROR_QUIET 64 | + OUTPUT_STRIP_TRAILING_WHITESPACE) 65 | + if(packet_forwarder_VERSION_SHORT STREQUAL "") 66 | + set(packet_forwarder_VERSION_SHORT 0) 67 | + endif(packet_forwarder_VERSION_SHORT STREQUAL "") 68 | + message( STATUS "Git version: ${packet_forwarder_VERSION_SHORT}" ) 69 | +else(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 70 | + set(packet_forwarder_VERSION_SHORT 0) 71 | + set(packet_forwarder_VERSION 0) 72 | +endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) 73 | + 74 | +# -- find packages 75 | +find_package(picogw QUIET) 76 | +if(NOT picogw_FOUND) 77 | + find_package(PkgConfig) 78 | + pkg_search_module(PICOGW picogw) 79 | + 80 | + if(PICOGW_FOUND AND PICOGW_LINK_LIBRARIES) 81 | + message("-- pkg_config: libpicogw is found") 82 | + message("-- libpicogw include: ${PICOGW_INCLUDE_DIRS}") 83 | + message("-- libpicogw library: ${PICOGW_LINK_LIBRARIES}") 84 | + else() 85 | + # a workaround for https://github.com/xueliu/lora-feed/issues/#9 86 | + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") 87 | + find_package(picogw QUIET) 88 | + if(PICOGW_FOUND) 89 | + message("-- Findpicogw: libpicogw is found") 90 | + message("-- libpicogw include: ${PICOGW_INCLUDE_DIRS}") 91 | + message("-- libpicogw library: ${PICOGW_LINK_LIBRARIES}") 92 | + else() 93 | + message(FATAL_ERROR "-- CMake: libpicogw is not found") 94 | + endif() 95 | + endif() 96 | +else() 97 | + message("-- CMake: libpicogw is found") 98 | +endif() 99 | + 100 | +# when building, don't use the install RPATH already 101 | +# (but later on when installing) 102 | +SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 103 | +if (NOT (${CMAKE_INSTALL_PREFIX} STREQUAL "/usr" ) ) 104 | + SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") 105 | +endif() 106 | + 107 | +# -- add the lora_pkt_fwd 108 | +add_subdirectory(lora_pkt_fwd) 109 | + 110 | +# -- add the util_ack 111 | +add_subdirectory(util_ack) 112 | + 113 | +# -- add the util_sink 114 | +add_subdirectory(util_sink) 115 | + 116 | +# -- add the util_tx_test 117 | +add_subdirectory(util_tx_test) 118 | diff --git a/cmake/Modules/Findpicogw.cmake b/cmake/Modules/Findpicogw.cmake 119 | new file mode 100644 120 | index 0000000..4973c5c 121 | --- /dev/null 122 | +++ b/cmake/Modules/Findpicogw.cmake 123 | @@ -0,0 +1,36 @@ 124 | +# Find picogw 125 | +# 126 | +# Find the picogw includes and library 127 | +# 128 | +# if you need to add a custom library search path, do it via CMAKE_PREFIX_PATH 129 | +# 130 | +# This module defines 131 | +# PICOGW_INCLUDE_DIRS, where to find header, etc. 132 | +# PICOGW_LIBRARIES, the libraries needed to use picogw. 133 | +# PICOGW_LINK_LIBRARIES, the libraries needed to use picogw. 134 | +# PICOGW_FOUND, If false, do not try to use picogw. 135 | + 136 | +# only look in default directories 137 | +find_path( 138 | + PICOGW_INCLUDE_DIR 139 | + NAMES loragw_hal.h # only one of those head files 140 | + PATH_SUFFIXES "libpicogw" 141 | + DOC "picogw include dir" 142 | +) 143 | + 144 | +find_library( 145 | + PICOGW_LIBRARY 146 | + NAMES picogw libpicogw 147 | + DOC "picogw library" 148 | +) 149 | + 150 | +set(PICOGW_INCLUDE_DIRS ${PICOGW_INCLUDE_DIR}) 151 | +set(PICOGW_LIBRARIES ${PICOGW_LIBRARY}) 152 | +set(PICOGW_LINK_LIBRARIES ${PICOGW_LIBRARY}) 153 | + 154 | +# handle the QUIETLY and REQUIRED arguments and set USATCK_FOUND to TRUE 155 | +# if all listed variables are TRUE, hide their existence from configuration view 156 | +include(FindPackageHandleStandardArgs) 157 | +find_package_handle_standard_args(picogw DEFAULT_MSG 158 | + PICOGW_LIBRARY PICOGW_INCLUDE_DIR ) 159 | +mark_as_advanced (PICOGW_INCLUDE_DIR PICOGW_LIBRARY) 160 | diff --git a/lora_pkt_fwd/CMakeLists.txt b/lora_pkt_fwd/CMakeLists.txt 161 | new file mode 100644 162 | index 0000000..c58e306 163 | --- /dev/null 164 | +++ b/lora_pkt_fwd/CMakeLists.txt 165 | @@ -0,0 +1,68 @@ 166 | +set(TARGET pico_pkt_fwd) 167 | + 168 | +add_executable(${TARGET} "") 169 | + 170 | +# -- add the compile options 171 | +target_compile_options( 172 | + ${TARGET} 173 | + PRIVATE 174 | + -Wall 175 | + -Wextra 176 | +) 177 | + 178 | +target_compile_definitions( 179 | + ${TARGET} 180 | + PRIVATE 181 | + VERSION_STRING="${packet_forwarder_VERSION_SHORT}" 182 | +) 183 | + 184 | +target_sources(${TARGET} 185 | + PRIVATE 186 | + ${CMAKE_CURRENT_LIST_DIR}/src/base64.c 187 | + ${CMAKE_CURRENT_LIST_DIR}/src/jitqueue.c 188 | + ${CMAKE_CURRENT_LIST_DIR}/src/lora_pkt_fwd.c 189 | + ${CMAKE_CURRENT_LIST_DIR}/src/parson.c 190 | + ${CMAKE_CURRENT_LIST_DIR}/src/timersync.c 191 | +) 192 | + 193 | +target_include_directories(${TARGET} 194 | + PRIVATE 195 | + ${CMAKE_CURRENT_LIST_DIR} 196 | + ${CMAKE_CURRENT_LIST_DIR}/inc 197 | +) 198 | + 199 | +target_link_libraries(${TARGET} 200 | + PUBLIC 201 | + Threads::Threads 202 | + m 203 | +) 204 | + 205 | +if(PICOGW_FOUND) 206 | +target_include_directories(${TARGET} 207 | + PRIVATE 208 | + ${PICOGW_INCLUDE_DIRS} 209 | +) 210 | + 211 | +target_link_libraries(${TARGET} 212 | + PRIVATE 213 | + ${PICOGW_LINK_LIBRARIES} 214 | +) 215 | + 216 | +elseif(picogw_FOUND) 217 | + 218 | +target_link_libraries(${TARGET} 219 | + PRIVATE 220 | + Semtech::picogw 221 | +) 222 | +endif() 223 | + 224 | +set_target_properties(${TARGET} PROPERTIES VERSION ${packet_forwarder_VERSION}) 225 | +set_target_properties(${TARGET} PROPERTIES SOVERSION ${packet_forwarder_VERSION_SHORT}) 226 | + 227 | +# add the install targets 228 | +install ( 229 | + TARGETS ${TARGET} 230 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 231 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 232 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 233 | +) 234 | diff --git a/util_ack/CMakeLists.txt b/util_ack/CMakeLists.txt 235 | new file mode 100644 236 | index 0000000..95826c2 237 | --- /dev/null 238 | +++ b/util_ack/CMakeLists.txt 239 | @@ -0,0 +1,38 @@ 240 | +set(TARGET util_ack) 241 | + 242 | +add_executable(${TARGET} "") 243 | +target_sources(${TARGET} 244 | + PRIVATE 245 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_ack.c 246 | +) 247 | + 248 | +if(PICOGW_FOUND) 249 | +target_include_directories(${TARGET} 250 | + PRIVATE 251 | + ${PICOGW_INCLUDE_DIRS} 252 | +) 253 | + 254 | +target_link_libraries(${TARGET} 255 | + PRIVATE 256 | + ${PICOGW_LINK_LIBRARIES} 257 | +) 258 | + 259 | +elseif(picogw_FOUND) 260 | + 261 | +target_link_libraries(${TARGET} 262 | + PRIVATE 263 | + Semtech::picogw 264 | +) 265 | +endif() 266 | + 267 | +set_target_properties(${TARGET} PROPERTIES 268 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 269 | +) 270 | + 271 | +# add the install targets 272 | +install ( 273 | + TARGETS ${TARGET} 274 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 275 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 276 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 277 | +) 278 | diff --git a/util_sink/CMakeLists.txt b/util_sink/CMakeLists.txt 279 | new file mode 100644 280 | index 0000000..d7ff0e7 281 | --- /dev/null 282 | +++ b/util_sink/CMakeLists.txt 283 | @@ -0,0 +1,38 @@ 284 | +set(TARGET util_sink) 285 | + 286 | +add_executable(${TARGET} "") 287 | +target_sources(${TARGET} 288 | + PRIVATE 289 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_sink.c 290 | +) 291 | + 292 | +if(PICOGW_FOUND) 293 | +target_include_directories(${TARGET} 294 | + PRIVATE 295 | + ${PICOGW_INCLUDE_DIRS} 296 | +) 297 | + 298 | +target_link_libraries(${TARGET} 299 | + PRIVATE 300 | + ${PICOGW_LINK_LIBRARIES} 301 | +) 302 | + 303 | +elseif(picogw_FOUND) 304 | + 305 | +target_link_libraries(${TARGET} 306 | + PRIVATE 307 | + Semtech::picogw 308 | +) 309 | +endif() 310 | + 311 | +set_target_properties(${TARGET} PROPERTIES 312 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 313 | +) 314 | + 315 | +# add the install targets 316 | +install ( 317 | + TARGETS ${TARGET} 318 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 319 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 320 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 321 | +) 322 | diff --git a/util_tx_test/CMakeLists.txt b/util_tx_test/CMakeLists.txt 323 | new file mode 100644 324 | index 0000000..3a26925 325 | --- /dev/null 326 | +++ b/util_tx_test/CMakeLists.txt 327 | @@ -0,0 +1,44 @@ 328 | +set(TARGET util_tx_test) 329 | + 330 | +add_executable(${TARGET} "") 331 | +target_sources(${TARGET} 332 | + PRIVATE 333 | + ${CMAKE_CURRENT_LIST_DIR}/src/util_tx_test.c 334 | + ${CMAKE_CURRENT_LIST_DIR}/src/base64.c 335 | +) 336 | + 337 | +target_include_directories(${TARGET} 338 | + PRIVATE 339 | + ${CMAKE_CURRENT_LIST_DIR}/inc 340 | +) 341 | + 342 | +if(PICOGW_FOUND) 343 | +target_include_directories(${TARGET} 344 | + PRIVATE 345 | + ${PICOGW_INCLUDE_DIRS} 346 | +) 347 | + 348 | +target_link_libraries(${TARGET} 349 | + PRIVATE 350 | + ${PICOGW_LINK_LIBRARIES} 351 | +) 352 | + 353 | +elseif(picogw_FOUND) 354 | + 355 | +target_link_libraries(${TARGET} 356 | + PRIVATE 357 | + Semtech::picogw 358 | +) 359 | +endif() 360 | + 361 | +set_target_properties(${TARGET} PROPERTIES 362 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin 363 | +) 364 | + 365 | +# add the install targets 366 | +install ( 367 | + TARGETS ${TARGET} 368 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shlib 369 | + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 370 | + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 371 | +) 372 | -- 373 | 2.17.0 374 | 375 | -------------------------------------------------------------------------------- /lora-picogw-packet-forwarder/patches/0002-qsort_r.patch: -------------------------------------------------------------------------------- 1 | Index: picoGW_packet_forwarder-0.1.0/lora_pkt_fwd/src/jitqueue.c 2 | =================================================================== 3 | --- picoGW_packet_forwarder-0.1.0.orig/lora_pkt_fwd/src/jitqueue.c 4 | +++ picoGW_packet_forwarder-0.1.0/lora_pkt_fwd/src/jitqueue.c 5 | @@ -115,7 +115,15 @@ void jit_sort_queue(struct jit_queue_s * 6 | } 7 | 8 | MSG_DEBUG(DEBUG_JIT, "sorting queue in ascending order packet timestamp - queue size:%u\n", queue->num_pkt); 9 | - qsort_r(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare, &counter); 10 | + // Not sure if replacing qsort for its re-entrant counterpart qsort_r is safe in this context, but there's 11 | + // precedent in OpenWRT: 12 | + // 13 | + // https://gitlab.labs.nic.cz/turris/openwrt/commit/51e3d8b8aab90471212373283736548c64804e7e 14 | + // 15 | + // If it starts failing, here's a possible suitable candidate: 16 | + // https://github.com/noporpoise/sort_r 17 | + //qsort_r(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare, &counter); 18 | + qsort(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare); 19 | MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped:%d\n", counter); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /lora-sx1302-hal/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=lora-sx1302-hal 11 | PKG_VERSION:=2.0.1 12 | PKG_RELEASE:=1 13 | 14 | #PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/sx1302_hal/tar.gz/V$(PKG_VERSION)? 15 | #PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 16 | #PKG_HASH:=1a0447d5e8183d08e6dce5f739f6872b9c57824b98f4078830d5ee21b15782c1 17 | 18 | PKG_SOURCE_PROTO:=git 19 | PKG_SOURCE_URL:=https://github.com/xueliu/sx1302_hal 20 | PKG_SOURCE_VERSION:=26d478c4d0539e965de4a9e759c28e74be35677b 21 | 22 | PKG_MAINTAINER:=Xue Liu 23 | PKG_LICENSE_FILES:=LICENSE 24 | #PKG_BUILD_DIR:=$(BUILD_DIR)/sx1302_hal-$(PKG_VERSION) 25 | 26 | include $(INCLUDE_DIR)/package.mk 27 | include $(INCLUDE_DIR)/cmake.mk 28 | 29 | define Package/libsx1302 30 | SECTION:=libs 31 | CATEGORY:=Libraries 32 | TITLE:=Driver/HAL library for Semtech SX1302 33 | URL:=https://www.semtech.com/products/wireless-rf/lora-gateways/sx1302 34 | DEPENDS:=+kmod-spi-dev 35 | endef 36 | 37 | 38 | $(eval $(call BuildPackage,libsx1302)) 39 | -------------------------------------------------------------------------------- /lora-sx1302-hal/patches/001-using-qsort.patch: -------------------------------------------------------------------------------- 1 | From 17173223c2284c7379c49a3d3ef580b1fea96b30 Mon Sep 17 00:00:00 2001 2 | From: Xue Liu 3 | Date: Sun, 21 Feb 2021 00:32:59 +0100 4 | Subject: [PATCH 1/1] - using qsort 5 | 6 | Signed-off-by: Xue Liu 7 | --- 8 | packet_forwarder/src/jitqueue.c | 12 +++--------- 9 | 1 file changed, 3 insertions(+), 9 deletions(-) 10 | 11 | Index: lora-sx1302-hal-2.0.1/packet_forwarder/src/jitqueue.c 12 | =================================================================== 13 | --- lora-sx1302-hal-2.0.1.orig/packet_forwarder/src/jitqueue.c 14 | +++ lora-sx1302-hal-2.0.1/packet_forwarder/src/jitqueue.c 15 | @@ -15,7 +15,6 @@ License: Revised BSD License, see LICENS 16 | /* -------------------------------------------------------------------------- */ 17 | /* --- DEPENDANCIES --------------------------------------------------------- */ 18 | 19 | -#define _GNU_SOURCE /* needed for qsort_r to be defined */ 20 | #include /* qsort_r */ 21 | #include /* printf, fprintf, snprintf, fopen, fputs */ 22 | #include /* memset, memcpy */ 23 | @@ -88,32 +87,27 @@ void jit_queue_init(struct jit_queue_s * 24 | pthread_mutex_unlock(&mx_jit_queue); 25 | } 26 | 27 | -int compare(const void *a, const void *b, void *arg) 28 | +int compare(const void *a, const void *b) 29 | { 30 | struct jit_node_s *p = (struct jit_node_s *)a; 31 | struct jit_node_s *q = (struct jit_node_s *)b; 32 | - int *counter = (int *)arg; 33 | int p_count, q_count; 34 | 35 | p_count = p->pkt.count_us; 36 | q_count = q->pkt.count_us; 37 | 38 | - if (p_count > q_count) 39 | - *counter = *counter + 1; 40 | - 41 | return p_count - q_count; 42 | } 43 | 44 | void jit_sort_queue(struct jit_queue_s *queue) { 45 | - int counter = 0; 46 | 47 | if (queue->num_pkt == 0) { 48 | return; 49 | } 50 | 51 | MSG_DEBUG(DEBUG_JIT, "sorting queue in ascending order packet timestamp - queue size:%u\n", queue->num_pkt); 52 | - qsort_r(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare, &counter); 53 | - MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped:%d\n", counter); 54 | + qsort(queue->nodes, queue->num_pkt, sizeof(queue->nodes[0]), compare); 55 | + MSG_DEBUG(DEBUG_JIT, "sorting queue done - swapped\n"); 56 | } 57 | 58 | bool jit_collision_test(uint32_t p1_count_us, uint32_t p1_pre_delay, uint32_t p1_post_delay, uint32_t p2_count_us, uint32_t p2_pre_delay, uint32_t p2_post_delay) { 59 | Index: lora-sx1302-hal-2.0.1/libloragw/src/loragw_hal.c 60 | =================================================================== 61 | --- lora-sx1302-hal-2.0.1.orig/libloragw/src/loragw_hal.c 62 | +++ lora-sx1302-hal-2.0.1/libloragw/src/loragw_hal.c 63 | @@ -295,20 +295,15 @@ static int remove_pkt(struct lgw_pkt_rx_ 64 | 65 | /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 66 | 67 | -int compare_pkt_tmst(const void *a, const void *b, void *arg) 68 | +int compare_pkt_tmst(const void *a, const void *b) 69 | { 70 | struct lgw_pkt_rx_s *p = (struct lgw_pkt_rx_s *)a; 71 | struct lgw_pkt_rx_s *q = (struct lgw_pkt_rx_s *)b; 72 | - int *counter = (int *)arg; 73 | int p_count, q_count; 74 | 75 | p_count = p->count_us; 76 | q_count = q->count_us; 77 | 78 | - if (p_count > q_count) { 79 | - *counter = *counter + 1; 80 | - } 81 | - 82 | return (p_count - q_count); 83 | } 84 | 85 | @@ -321,7 +316,6 @@ static int merge_packets(struct lgw_pkt_ 86 | int pkt_idx; 87 | #endif 88 | bool dup_restart = false; 89 | - int counter_qsort_swap = 0; 90 | 91 | /* Check input parameters */ 92 | CHECK_NULL(p); 93 | @@ -415,8 +409,7 @@ static int merge_packets(struct lgw_pkt_ 94 | } 95 | 96 | /* Sort the packet array by ascending counter_us value */ 97 | - qsort_r(p, cpt, sizeof(p[0]), compare_pkt_tmst, &counter_qsort_swap); 98 | - DEBUG_PRINTF("%d elements swapped during sorting...\n", counter_qsort_swap); 99 | + qsort(p, cpt, sizeof(p[0]), compare_pkt_tmst); 100 | 101 | /* --------------------------------------------- */ 102 | /* ---------- For Debug only - START ----------- */ 103 | -------------------------------------------------------------------------------- /lorawan-stack/Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=lorawan-stack 4 | PKG_VERSION:=3.9.0 5 | PKG_RELEASE:=1 6 | 7 | PKG_SOURCE_URL:=https://codeload.github.com/TheThingsNetwork/lorawan-stack/tar.gz/v$(PKG_VERSION)? 8 | 9 | #PKG_SOURCE_PROTO:=git 10 | #PKG_SOURCE_VERSION:=HEAD # dev for dev branch, HEAD for master 11 | #PKG_SOURCE_URL:=https://github.com/TheThingsNetwork/lorawan-stack 12 | #PKG_SOURCE_SUBDIR:=$(PKG_NAME) 13 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 14 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) 15 | 16 | PKG_HASH:=1b8e3c6eca7f838418c8c98cfc538ad42527c419c57aa05d66be7d442fea687b 17 | PKG_MAINTAINER:=Xue Liu 18 | PKG_LICENSE:MIT 19 | PKG_LICENSE_FILES:=LICENSE 20 | 21 | PKG_BUILD_DEPENDS:=golang/host 22 | PKG_BUILD_PARALLEL:=1 23 | PKG_USE_MIPS16:=0 24 | 25 | GO_PKG:=github.com/TheThingsNetwork/lorawan-stack 26 | GO_PKG_BUILD_PKG:=github.com/TheThingsNetwork/lorawan-stack/cmd/ttn-lw-cli 27 | 28 | include $(INCLUDE_DIR)/package.mk 29 | # golang-package.mk should be relocate regarding the env 30 | include $(INCLUDE_DIR)/../feeds/packages/lang/golang/golang-package.mk 31 | 32 | define Package/lorawan-stack 33 | SECTION:=net 34 | CATEGORY:=Network 35 | SUBMENU:=LoRaWAN 36 | TITLE:=The Things Stack 37 | DEPENDS:=$(GO_ARCH_DEPENDS) 38 | PKGARCH:=all 39 | endef 40 | 41 | define Package/lorawan-stack/description 42 | The Things Stack for LoRaWAN is an open source LoRaWAN network stack suitable for large, 43 | global and geo-distributed public and private networks as well as smaller networks. 44 | The architecture follows the LoRaWAN Network Reference Model for standards compliancy 45 | and interoperability. 46 | endef 47 | 48 | GO_PKG_LDFLAGS:=-s -w 49 | GO_PKG_LDFLAGS_X:=main.version=$(PKG_VERSION) 50 | 51 | define GoPackage/Build/Compile 52 | @echo "make init" 53 | @make init -C $(PKG_BUILD_DIR) 54 | ( \ 55 | cd $(PKG_BUILD_DIR) \ 56 | && echo "build front-end" \ 57 | && ./tools/bin/mage js:build \ 58 | ) 59 | ( \ 60 | export GOPATH=$(GO_PKG_BUILD_DIR) \ 61 | GOCACHE=$(GO_PKG_CACHE_DIR) \ 62 | GOTMPDIR=$(GO_PKG_TMP_DIR) \ 63 | GOROOT_FINAL=$(GO_TARGET_ROOT) \ 64 | CC=$(TARGET_CC) \ 65 | CXX=$(TARGET_CXX) \ 66 | $(call GoPackage/Environment) \ 67 | \ 68 | && cd $(PKG_BUILD_DIR) \ 69 | && echo "Compiling CLI..." \ 70 | && go build ./cmd/ttn-lw-cli \ 71 | && echo "Compiling Stack..." \ 72 | && go build ./cmd/ttn-lw-stack \ 73 | ) 74 | endef 75 | 76 | define Package/lorawan-stack/install 77 | $(call GoPackage/Package/Install/Bin,$(1)) 78 | endef 79 | 80 | $(eval $(call GoBinPackage,lorawan-stack)) 81 | $(eval $(call BuildPackage,lorawan-stack)) 82 | -------------------------------------------------------------------------------- /lorawan-stack/patches/001-remove_hook_install.patch: -------------------------------------------------------------------------------- 1 | Index: lorawan-stack-3.9.0/tools/mage/git.go 2 | =================================================================== 3 | --- lorawan-stack-3.9.0.orig/tools/mage/git.go 4 | +++ lorawan-stack-3.9.0/tools/mage/git.go 5 | @@ -62,7 +62,7 @@ func (g Git) InstallHooks() error { 6 | } 7 | 8 | func init() { 9 | - initDeps = append(initDeps, Git.InstallHooks) 10 | +// initDeps = append(initDeps, Git.InstallHooks) 11 | } 12 | 13 | // UninstallHooks uninstalls git hooks. 14 | -------------------------------------------------------------------------------- /lua-toml/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=lua-toml 11 | PKG_VERSION:=2.0.0 12 | PKG_RELEASE:=1 13 | 14 | PKG_SOURCE_URL=https://codeload.github.com/jonstoler/lua-toml/tar.gz/v$(PKG_VERSION)? 15 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz 16 | 17 | PKG_HASH:=723fc73f8ff25efa574dff3c1c41c94691ed09b92945f6c1d24ce58f2b908256 18 | PKG_MAINTAINER:=Xue Liu 19 | PKG_LICENSE:=MIT 20 | PKG_LICENSE_FILES:=LICENSE 21 | 22 | include $(INCLUDE_DIR)/package.mk 23 | 24 | define Package/lua-toml 25 | SECTION:=lang 26 | CATEGORY:=Languages 27 | SUBMENU:=Lua 28 | TITLE:=TOML decoder/encoder for Lua 29 | URL:=https://github.com/jonstoler/lua-toml 30 | DEPENDS:=+lua 31 | endef 32 | 33 | define Package/lua-toml/description 34 | TOML decoder/encoder for Lua 35 | endef 36 | 37 | define Build/Compile 38 | endef 39 | 40 | define Package/lua-toml/install 41 | $(INSTALL_DIR) $(1)/usr/lib/lua 42 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/toml.lua $(1)/usr/lib/lua/ 43 | endef 44 | 45 | $(eval $(call BuildPackage,lua-toml)) 46 | -------------------------------------------------------------------------------- /luci-app-basicstation/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | 6 | include $(TOPDIR)/rules.mk 7 | 8 | PKG_NAME:=luci-app-basicstation 9 | PKG_VERSION:=1.0 10 | PKG_RELEASE:=1 11 | 12 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) 13 | 14 | include $(INCLUDE_DIR)/package.mk 15 | 16 | define Package/luci-app-basicstation 17 | SECTION:=luci 18 | CATEGORY:=LuCI 19 | SUBMENU:=3. Applications 20 | TITLE:=Semtech Basicstation Configuration Interface 21 | PKGARCH:=all 22 | DEPENDS:=+basicstation +luci-compat 23 | endef 24 | 25 | define Build/Compile 26 | endef 27 | 28 | define Package/luci-app-basicstation/install 29 | $(INSTALL_DIR) $(1)/ 30 | $(CP) ./files/* $(1)/ 31 | endef 32 | 33 | $(eval $(call BuildPackage,luci-app-basicstation)) 34 | -------------------------------------------------------------------------------- /luci-app-basicstation/files/usr/lib/lua/luci/controller/lora/station.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.lora.station",package.seeall) 2 | 3 | function index() 4 | entry({"admin","network","station"}, cbi("lora/station"),_("LoRaWAN Basicstion"),99).index=true 5 | entry({"admin","status","station"}, call("action_stationlog"),_("Basicstion Log"), 99).index=true 6 | end 7 | 8 | function action_stationlog() 9 | local stationlog = luci.sys.exec("cat /tmp/stationlog") 10 | luci.template.render("admin_status/stationlog", {stationlog=stationlog}) 11 | end 12 | -------------------------------------------------------------------------------- /luci-app-basicstation/files/usr/lib/lua/luci/model/cbi/lora/station.lua: -------------------------------------------------------------------------------- 1 | local fs = require "nixio.fs" 2 | m=Map("station",translate("Basicstation"),translate("Here you can configure the Semtech basicstation")) 3 | 4 | function string.tohex(str) 5 | return (str:gsub('.', function (c) 6 | return string.format('0x%02X ', string.byte(c)) 7 | end)) 8 | end 9 | 10 | -- 11 | -- CUPS Bootstrap Configuration 12 | -- 13 | local cups_bootstrap = m:section(NamedSection, "cups_bootstrap", "server", translate("CUPS Bootstrap")) 14 | cups_bootstrap.addremove = true 15 | cups_bootstrap.anonymous = false 16 | 17 | -- 18 | -- CUPS Bootstrap URI 19 | -- 20 | local cups_bootstrap_uri = cups_bootstrap:option(Value, "uri", translate("URI")) 21 | cups_bootstrap_uri.optional = false; 22 | cups_bootstrap_uri.rmempty = true; 23 | 24 | -- 25 | -- CUPS Bootstrap Port 26 | -- 27 | local cups_bootstrap_port = cups_bootstrap:option(Value, "port", translate("Port")) 28 | cups_bootstrap_port.optional = false; 29 | cups_bootstrap_port.rmempty = true; 30 | 31 | -- 32 | -- CUPS Bootstrap Authentication Mode 33 | -- 34 | local cups_bootstrap_auth_mode = cups_bootstrap:option(ListValue, "auth_mode", translate("Authentication Mode")) 35 | cups_bootstrap_auth_mode:value("none", "No Authentication") 36 | cups_bootstrap_auth_mode:value("tls-server","TLS Server Authentication") 37 | cups_bootstrap_auth_mode:value("tls-server-client", "TLS Server and Client Authentication") 38 | cups_bootstrap_auth_mode:value("tls-server-token","TLS Server Authentication and Client Token") 39 | 40 | -- 41 | -- CUPS Bootstrap Server CA certificate 42 | -- 43 | local cups_bootstrap_trust = cups_bootstrap:option(TextValue, "_trust", translate("Server’s CA certificate")) 44 | cups_bootstrap_trust.wrap = "off" 45 | cups_bootstrap_trust.rows = 4 46 | cups_bootstrap_trust:depends("auth_mode","tls-server") 47 | cups_bootstrap_trust:depends("auth_mode","tls-server-client") 48 | cups_bootstrap_trust:depends("auth_mode","tls-server-token") 49 | 50 | function cups_bootstrap_trust.cfgvalue() 51 | return fs.readfile("/etc/station/cups-boot.trust") or "" 52 | end 53 | 54 | function cups_bootstrap_trust.write(self, section, value) 55 | if value then 56 | fs.writefile("/etc/station/cups-boot.trust", value:gsub("\r\n", "\n")) 57 | m:set(section, "trust", "/etc/station/cups-boot.trust") 58 | end 59 | end 60 | 61 | function cups_bootstrap_trust.remove(self, section) 62 | fs.remove("/etc/station/cups-boot.trust") 63 | m:del(section, "trust") 64 | end 65 | 66 | -- 67 | -- CUPS Bootstrap Station Certificate 68 | -- 69 | local cups_bootstrap_crt = cups_bootstrap:option(TextValue, "_crt", translate("Station’s Own Certificate")) 70 | cups_bootstrap_crt.wrap = "off" 71 | cups_bootstrap_crt.rows = 4 72 | cups_bootstrap_crt:depends("auth_mode","tls-server-client") 73 | 74 | function cups_bootstrap_crt.cfgvalue() 75 | return fs.readfile("/etc/station/cups-boot.crt") or "" 76 | end 77 | 78 | function cups_bootstrap_crt.write(self, section, value) 79 | if value then 80 | fs.writefile("/etc/station/cups-boot.crt", value:gsub("\r\n", "\n")) 81 | m:set(section, "crt", "/etc/station/cups-boot.crt") 82 | end 83 | end 84 | 85 | function cups_bootstrap_crt.remove(self, section) 86 | fs.remove("/etc/station/cups-boot.crt") 87 | m:del(section, "crt") 88 | end 89 | 90 | -- 91 | -- CUPS Bootstrap Station Private Key 92 | -- 93 | local cups_bootstrap_key = cups_bootstrap:option(TextValue, "_key", translate("Station’s Private Key")) 94 | cups_bootstrap_key.wrap = "off" 95 | cups_bootstrap_key.rows = 4 96 | cups_bootstrap_key:depends("auth_mode","tls-server-client") 97 | 98 | function cups_bootstrap_key.cfgvalue() 99 | return fs.readfile("/etc/station/cups-boot.key") or "" 100 | end 101 | 102 | function cups_bootstrap_key.write(self, section, value) 103 | if value then 104 | fs.writefile("/etc/station/cups-boot.key", value:gsub("\r\n", "\n")) 105 | m:set(section, "key", "/etc/station/cups-boot.key") 106 | end 107 | end 108 | 109 | function cups_bootstrap_key.remove(self, section) 110 | fs.remove("/etc/station/cups-boot.key") 111 | m:del(section, "key") 112 | end 113 | 114 | -- 115 | -- CUPS Bootstrap Station Token 116 | -- 117 | local cups_bootstrap_token = cups_bootstrap:option(Value, "token", translate("Station’s Token")) 118 | cups_bootstrap_token:depends("auth_mode","tls-server-token") 119 | 120 | 121 | -- 122 | -- CUPS Server Configuration 123 | -- 124 | local cups = m:section(NamedSection, "cups", "server", translate("CUPS Server")) 125 | cups.addremove = true 126 | cups.anonymous = false 127 | 128 | -- 129 | -- CUPS Server URI 130 | -- 131 | local cups_uri=cups:option(Value, "uri", translate("URI")) 132 | cups_uri.optional = false; 133 | cups_uri.rmempty = true; 134 | 135 | -- 136 | -- CUPS Server Port 137 | -- 138 | local cups_port=cups:option(Value, "port", translate("Port")) 139 | cups_port.optional = false; 140 | cups_port.rmempty = true; 141 | 142 | -- 143 | -- CUPS Authentication Mode 144 | -- 145 | local cups_auth_mode = cups:option(ListValue, "auth_mode", translate("Authentication Mode")) 146 | cups_auth_mode:value("none", "No Authentication") 147 | cups_auth_mode:value("tls-server","TLS Server Authentication") 148 | cups_auth_mode:value("tls-server-client", "TLS Server and Client Authentication") 149 | cups_auth_mode:value("tls-server-token","TLS Server Authentication and Client Token") 150 | 151 | -- 152 | -- CUPS Server Certificate 153 | -- 154 | local cups_trust = cups:option(TextValue, "_trust", translate("Server’s CA certificate")) 155 | cups_trust.wrap = "off" 156 | cups_trust.rows = 4 157 | cups_trust:depends("auth_mode","tls-server") 158 | cups_trust:depends("auth_mode","tls-server-client") 159 | cups_trust:depends("auth_mode","tls-server-token") 160 | 161 | function cups_trust.cfgvalue() 162 | return fs.readfile("/etc/station/cups.trust") or "" 163 | end 164 | 165 | function cups_trust.write(self, section, value) 166 | if value then 167 | fs.writefile("/etc/station/cups.trust", value:gsub("\r\n", "\n")) 168 | m:set(section, "trust", "/etc/station/cups.trust") 169 | end 170 | end 171 | 172 | function cups_trust.remove(self, section) 173 | fs.remove("/etc/station/cups.trust") 174 | m:del(section, "trust") 175 | end 176 | 177 | -- 178 | -- CUPS Station Certificate 179 | -- 180 | local cups_crt = cups:option(TextValue, "_crt", translate("Station’s Own Certificate")) 181 | cups_crt.wrap = "off" 182 | cups_crt.rows = 10 183 | cups_crt:depends("auth_mode","tls-server-client") 184 | 185 | function cups_crt.cfgvalue() 186 | return fs.readfile("/etc/station/cups.crt") or "" 187 | end 188 | 189 | function cups_crt.write(self, section, value) 190 | if value then 191 | fs.writefile("/etc/station/cups.crt", value:gsub("\r\n", "\n")) 192 | m:set(section, "crt", "/etc/station/cups.crt") 193 | end 194 | end 195 | 196 | function cups_crt.remove(self, section) 197 | fs.remove("/etc/station/cups.crt") 198 | m:del(section, "crt") 199 | end 200 | 201 | -- 202 | -- CUPS Station Private Key 203 | -- 204 | local cups_key = cups:option(TextValue, "_key", translate("Station’s Private Key")) 205 | cups_key.wrap = "off" 206 | cups_key.rows = 10 207 | cups_key:depends("auth_mode","tls-server-client") 208 | 209 | function cups_key.cfgvalue() 210 | return fs.readfile("/etc/station/cups.key") or "" 211 | end 212 | 213 | function cups_key.write(self, section, value) 214 | if value then 215 | fs.writefile("/etc/station/cups.key", value:gsub("\r\n", "\n")) 216 | m:set(section, "key", "/etc/station/cups.key") 217 | end 218 | end 219 | 220 | function cups_key.remove(self, section) 221 | fs.remove("/etc/station/cups.key") 222 | m:del(section, "key") 223 | end 224 | 225 | -- 226 | -- CUPS Station Token 227 | -- 228 | local cups_token = cups:option(Value, "token", translate("Station's Token")) 229 | cups_token:depends("auth_mode","tls-server-token") 230 | 231 | 232 | -- 233 | -- LNS Server Configuration 234 | -- 235 | local lns = m:section(NamedSection, "tc", "server", translate("LNS Server")) 236 | lns.addremove = true 237 | lns.anonymous = false 238 | 239 | -- 240 | -- LNS Server URI 241 | -- 242 | local lns_uri = lns:option(Value, "uri", translate("URI")) 243 | lns_uri.optional = false; 244 | lns_uri.rmempty = true; 245 | 246 | -- 247 | -- LNS Server Port 248 | -- 249 | local lns_port = lns:option(Value, "port", translate("Port")) 250 | lns_port.optional = false; 251 | lns_port.rmempty = true; 252 | 253 | -- 254 | -- LNS Authentication Mode 255 | -- 256 | local lns_auth_mode = lns:option(ListValue, "auth_mode", translate("Authentication Mode")) 257 | lns_auth_mode:value("none", "No Authentication") 258 | lns_auth_mode:value("tls-server", "TLS Server Authentication") 259 | lns_auth_mode:value("tls-server-client", "TLS Server and Client Authentication") 260 | lns_auth_mode:value("tls-server-token", "TLS Server Authentication and Client Token") 261 | 262 | 263 | -- 264 | -- LNS Server CA Certificate 265 | -- 266 | local lns_trust = lns:option(TextValue, "_trust", translate("Server’s CA certificate")) 267 | lns_trust.wrap = "off" 268 | lns_trust.rows = 4 269 | lns_trust:depends("auth_mode", "tls-server") 270 | lns_trust:depends("auth_mode", "tls-server-client") 271 | lns_trust:depends("auth_mode", "tls-server-token") 272 | 273 | function lns_trust.cfgvalue() 274 | return fs.readfile("/etc/station/tc.trust") or "" 275 | end 276 | 277 | function lns_trust.write(self, section, value) 278 | if value then 279 | fs.writefile("/etc/station/tc.trust", value:gsub("\r\n", "\n")) 280 | m:set(section, "trust", "/etc/station/tc.trust") 281 | end 282 | end 283 | 284 | function lns_trust.remove(self, section) 285 | fs.remove("/etc/station/tc.trust") 286 | m:del(section, "trust") 287 | end 288 | 289 | -- 290 | -- LNS Station Certificate 291 | -- 292 | local lns_crt = lns:option(TextValue, "_crt", translate("Station’s Own Certificate")) 293 | lns_crt.wrap = "off" 294 | lns_crt.rows = 4 295 | lns_crt:depends("auth_mode","tls-server-client") 296 | 297 | function lns_crt.cfgvalue() 298 | return fs.readfile("/etc/station/tc.crt") or "" 299 | end 300 | 301 | function lns_crt.write(self, section, value) 302 | if value then 303 | fs.writefile("/etc/station/tc.crt", value:gsub("\r\n", "\n")) 304 | m:set(section, "crt", "/etc/station/tc.crt") 305 | end 306 | end 307 | 308 | function lns_crt.remove(self, section) 309 | fs.remove("/etc/station/tc.crt") 310 | m:del(section, "crt") 311 | end 312 | 313 | -- 314 | -- LNS Station Private Key 315 | -- 316 | local lns_key = lns:option(TextValue, "_key", translate("Station’s Private Key")) 317 | lns_key.wrap = "off" 318 | lns_key.rows = 4 319 | lns_key:depends("auth_mode","tls-server-client") 320 | 321 | function lns_key.cfgvalue() 322 | return fs.readfile("/etc/station/tc.crt") or "" 323 | end 324 | 325 | function lns_key.write(self, section, value) 326 | if value then 327 | fs.writefile("/etc/station/tc.key", value:gsub("\r\n", "\n")) 328 | m:set(section, "key", "/etc/station/tc.key") 329 | end 330 | end 331 | 332 | function lns_key.remove(self, section) 333 | fs.remove("/etc/station/tc.key") 334 | m:del(section, "key") 335 | end 336 | 337 | -- 338 | -- LNS Station Token 339 | -- 340 | local lns_token = lns:option(Value, "token", translate("Station's Token")) 341 | lns_token:depends("auth_mode","tls-server-token") 342 | 343 | 344 | -- 345 | -- SX1301 configuration for SX1301_conf 346 | -- 347 | local sx1301=m:section(TypedSection,"sx1301","SX1301 Parameters") 348 | sx1301.addremove = true 349 | sx1301.anonymous = false 350 | 351 | local lorawan_pb = sx1301:option(ListValue,"lorawan_public",translate("LoRaWAN is public")) 352 | lorawan_pb.optional = false; 353 | lorawan_pb.rmempty = false; 354 | lorawan_pb.default = false 355 | lorawan_pb.datatype = "bool" 356 | lorawan_pb:value(true, translate("True")) 357 | lorawan_pb:value(false, translate("False")) 358 | 359 | local clkscr = sx1301:option(ListValue,"clksrc",translate("Clock Source"), "radio_1 provides clock to concentrator for most devices except MultiTech. For MultiTech set to 0.") 360 | clkscr.optional = false; 361 | clkscr.rmempty = false; 362 | clkscr.datatype = "integer" 363 | clkscr:value(1, translate("from radio_1")) 364 | clkscr:value(0, translate("from radio_0")) 365 | 366 | -- 367 | -- Radio Parameters 368 | -- 369 | local radio=m:section(TypedSection,"radio","Radio Parameters") 370 | radio.addremove=true 371 | radio.anonymous=false 372 | 373 | -- 374 | -- Radio enable 375 | -- 376 | local enable = radio:option(ListValue,"enable",translate("Enable")) 377 | enable.optional = false; 378 | enable.rmempty = false; 379 | enable.default = false 380 | enable.datatype = "bool" 381 | enable:value(true, translate("True")) 382 | enable:value(false, translate("False")) 383 | 384 | -- 385 | -- Radio RF frontend 386 | -- 387 | local type = radio:option(ListValue,"type",translate("Type")) 388 | type.optional = false; 389 | type.rmempty = false; 390 | type.datatype = "string" 391 | type:value("SX1257", translate("SX1257")) 392 | type:value("SX1255", translate("SX1255")) 393 | 394 | -- 395 | -- Radio Frequency 396 | -- 397 | local freq = radio:option(Value,"freq",translate("Frequency"), "Hz") 398 | freq.optional = true; 399 | freq.rmempty = false; 400 | 401 | -- 402 | -- RSSI offset 403 | -- 404 | local rssi_offset = radio:option(Value,"rssi_offset",translate("RSSI Offset"), "dB") 405 | rssi_offset.optional = true; 406 | rssi_offset.rmempty = false; 407 | 408 | -- 409 | -- Tx Enable 410 | -- 411 | local tx_enable = radio:option(ListValue,"tx_enable",translate("Tx Enable")) 412 | tx_enable.optional = false; 413 | tx_enable.rmempty = false; 414 | tx_enable.default = false 415 | tx_enable.datatype = "bool" 416 | tx_enable:value(true, translate("True")) 417 | tx_enable:value(false, translate("False")) 418 | 419 | -- 420 | -- Station Parameters 421 | -- 422 | local station=m:section(TypedSection,"station","Station Parameters") 423 | station.addremove=true 424 | station.anonymous=false 425 | 426 | -- 427 | -- Device 428 | -- 429 | local device = station:option(Value,"device",translate("SPI Device")) 430 | device.optional = true; 431 | device.rmempty = false; 432 | device:value("spidev0.0", "spidev0.0") 433 | device:value("spidev0.1", "spidev0.1") 434 | device:value("spidev?.0", "spidev?.0") 435 | 436 | -- 437 | -- Radio Init 438 | -- 439 | 440 | local radio_init = station:option(Value,"radio_init",translate("Radio Initlization File")) 441 | radio_init.optional = true; 442 | radio_init.rmempty = false; 443 | 444 | -- 445 | -- GPS 446 | -- 447 | local gps = station:option(ListValue,"gps",translate("GPS")) 448 | gps.optional = true; 449 | gps.rmempty = true; 450 | gps:value("DEVICEFILE", "DEVICEFILE") 451 | gps:value("FIFO", "FIFO") 452 | 453 | -- 454 | -- PPS 455 | -- 456 | local pps = station:option(ListValue,"pps",translate("PPS"), "") 457 | pps.optional = true; 458 | pps.rmempty = false; 459 | pps:value("GPS", "gps") 460 | pps:value("Fuzzy", "fuzzy") 461 | 462 | -- 463 | -- Log File 464 | -- 465 | local log_file = station:option(Value,"log_file",translate("Log file location")) 466 | log_file.optional = false; 467 | log_file.rmempty = false; 468 | log_file:value("stderr", "stderr") 469 | log_file:value("/tmp/stationlog", "/tmp/stationlog") 470 | 471 | -- 472 | -- Log Level 473 | -- 474 | local log_level = station:option(ListValue,"log_level",translate("Log Level")) 475 | log_level.optional = false; 476 | log_level.rmempty = false; 477 | log_level:value("DEBUG", "Debug") 478 | log_level:value("XDEBUG", "XDebug") 479 | log_level:value("VERBOSE", "Verbose") 480 | log_level:value("INFO", "Info") 481 | log_level:value("NOTICE", "Notice") 482 | log_level:value("WARNING", "Warning") 483 | log_level:value("ERROR", "Error") 484 | log_level:value("CRITICAL", "Critical") 485 | 486 | -- 487 | -- Log Size 488 | -- 489 | local log_size = station:option(Value,"log_size",translate("Log Size"), "Byte") 490 | log_size.optional = false; 491 | log_size.rmempty = false; 492 | 493 | -- 494 | -- Log Roteate 495 | -- 496 | local log_rotate = station:option(Value,"log_rotate",translate("Log Rotate")) 497 | log_rotate.optional = false; 498 | log_rotate.rmempty = false; 499 | 500 | return m 501 | -------------------------------------------------------------------------------- /luci-app-basicstation/files/usr/lib/lua/luci/view/admin_status/stationlog.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2020 Xue Liu 3 | 4 | based on https://forum.archive.openwrt.org/viewtopic.php?id=58715 5 | -%> 6 | 7 | <%+header%> 8 | 9 |

<%:Basicstation Log%>

10 |
11 | 12 |
13 | 14 | <%+footer%> 15 | -------------------------------------------------------------------------------- /luci-app-basicstation/files/usr/share/rpcd/acl.d/luci-app-basicstation.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-basicstation": { 3 | "description": "Grant UCI access for luci-app-basicstation", 4 | "read": { 5 | "uci": [ "station" ] 6 | }, 7 | "write": { 8 | "uci": [ "station" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /luci-app-pkg-fwd/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2017 Xue Liu 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | 6 | include $(TOPDIR)/rules.mk 7 | 8 | PKG_NAME:=luci-app-pkt-fwd 9 | PKG_VERSION:=1.0 10 | PKG_RELEASE:=1 11 | 12 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) 13 | 14 | include $(INCLUDE_DIR)/package.mk 15 | 16 | define Package/luci-app-pkt-fwd 17 | SECTION:=luci 18 | CATEGORY:=LuCI 19 | SUBMENU:=3. Applications 20 | TITLE:=Semtech LoRa Packet Forward Configuration Interface 21 | PKGARCH:=all 22 | DEPENDS:=+lora-packet-forwarder +luci-compat 23 | endef 24 | 25 | define Build/Compile 26 | endef 27 | 28 | define Package/luci-app-pkt-fwd/install 29 | $(INSTALL_DIR) $(1)/ 30 | $(CP) ./files/* $(1)/ 31 | endef 32 | 33 | $(eval $(call BuildPackage,luci-app-pkt-fwd)) 34 | -------------------------------------------------------------------------------- /luci-app-pkg-fwd/files/usr/lib/lua/luci/controller/lora/lora.lua: -------------------------------------------------------------------------------- 1 | 2 | module("luci.controller.lora.lora",package.seeall) 3 | 4 | function index() 5 | entry({"admin","network","lora"}, cbi("lora/lora_gateway"),_("LoRa Gateway"),99).index=true 6 | end 7 | -------------------------------------------------------------------------------- /luci-app-pkg-fwd/files/usr/lib/lua/luci/model/cbi/lora/lora_gateway.lua: -------------------------------------------------------------------------------- 1 | 2 | m=Map("lora-global",translate("LoRa Gateway"),translate("Here you can configure the LoRa gateway and pakcet forwarder")) 3 | 4 | -- 5 | -- LoRa Gateway config for gateway_conf 6 | -- 7 | gateway=m:section(TypedSection,"gateway","Gateway Parameters") 8 | gateway.addremove=false 9 | gateway.anonymous=true 10 | 11 | gateway:tab("general", translate("General Settings")) 12 | gateway:tab("lbt", translate("LBT Settings")) 13 | gateway:tab("forward", translate("Forward Rules")) 14 | gateway:tab("gps", translate("GPS Settings")) 15 | gateway:tab("beacon", translate("Beacon Settings")) 16 | 17 | gateway:taboption("general", Value,"gateway_ID",translate("Gateway ID")) 18 | 19 | local ttn_addr = gateway:taboption("general", Value,"server_address",translate("Server Address")) 20 | ttn_addr:value("router.eu.thethings.network", "ttn-router-eu") 21 | ttn_addr:value("router.us.thethings.network", "ttn-router-us-west") 22 | ttn_addr:value("router.cn.thethings.network", "ttn-router-cn") 23 | ttn_addr:value("router.as.thethings.network", "ttn-router-asia-se") 24 | ttn_addr:value("router.as1.thethings.network", "ttn-router-asia-se-1") 25 | ttn_addr:value("router.as2.thethings.network", "ttn-router-asia-se-2") 26 | ttn_addr:value("router.kr.thethings.network", "ttn-router-kr") 27 | ttn_addr:value("router.jp.thethings.network", "ttn-router-jp") 28 | ttn_addr:value("thethings.meshed.com.au", "ttn-router-asia-se") 29 | ttn_addr:value("as923.thethings.meshed.com.au", "meshed-router") 30 | ttn_addr:value("ttn.opennetworkinfrastructure.org", "switch-router") 31 | 32 | gateway:taboption("general", Value,"serv_port_up",translate("Server Port (Up)")) 33 | gateway:taboption("general", Value,"serv_port_down",translate("Server Port (Down)")) 34 | gateway:taboption("general", Value,"keepalive_interval",translate("Keep Alive Interval")) 35 | gateway:taboption("general", Value,"push_timeout_ms",translate("Push Timeout")) 36 | 37 | -- 38 | -- forward_crc_valid 39 | -- 40 | forward_crc_valid = gateway:taboption("forward", ListValue,"forward_crc_valid",translate("Forward When CRC Valid")) 41 | forward_crc_valid.optional = false 42 | forward_crc_valid.rmempty = false 43 | forward_crc_valid.default = true 44 | forward_crc_valid.datatype = "bool" 45 | forward_crc_valid:value(true, translate("True")) 46 | forward_crc_valid:value(false, translate("False")) 47 | 48 | -- 49 | -- forward_crc_error 50 | -- 51 | forward_crc_error = gateway:taboption("forward", ListValue,"forward_crc_error",translate("Forward When CRC Error")); 52 | forward_crc_error.optional = false; 53 | forward_crc_error.rmempty = false; 54 | forward_crc_error.default = false 55 | forward_crc_error.datatype = "bool" 56 | forward_crc_error:value(true, translate("True")) 57 | forward_crc_error:value(false, translate("False")) 58 | 59 | -- 60 | -- forward_crc_disabled 61 | -- 62 | forward_crc_disabled = gateway:taboption("forward", ListValue,"forward_crc_disabled",translate("Forward When CRC Disabled")) 63 | forward_crc_disabled.optional = false; 64 | forward_crc_disabled.rmempty = false; 65 | forward_crc_disabled.default = false 66 | forward_crc_disabled.datatype = "bool" 67 | forward_crc_disabled:value(true, translate("True")) 68 | forward_crc_disabled:value(false, translate("False")) 69 | 70 | -- 71 | -- LBT Enable 72 | -- 73 | lbt_enable = gateway:taboption("lbt", ListValue,"lbt_enable",translate("LBT Enable")) 74 | lbt_enable.optional = false; 75 | lbt_enable.rmempty = false; 76 | lbt_enable.default = false 77 | lbt_enable.datatype = "bool" 78 | lbt_enable:value(true, translate("True")) 79 | lbt_enable:value(false, translate("False")) 80 | 81 | -- 82 | -- RSSI Target 83 | -- 84 | lbt_rssi_target = gateway:taboption("lbt", Value,"rssi_target",translate("RSSI Target Value")) 85 | lbt_rssi_target.optional = true; 86 | lbt_rssi_target.rmempty = true; 87 | lbt_rssi_target.default = '-80' 88 | lbt_rssi_target.datatype = "float" 89 | lbt_rssi_target:depends("lbt_enable", "true") 90 | 91 | -- 92 | -- sx127x RSSI Offset 93 | -- 94 | sx127x_rssi_offset = gateway:taboption("lbt", Value,"sx127x_rssi_offset",translate("SX127x RSSI Offset")) 95 | sx127x_rssi_offset.optional = true; 96 | sx127x_rssi_offset.rmempty = true; 97 | sx127x_rssi_offset.default = '-4' 98 | sx127x_rssi_offset.datatype = "float" 99 | sx127x_rssi_offset:depends("lbt_enable", "true") 100 | 101 | -- 102 | -- GPS Enable 103 | -- 104 | gps_enable = gateway:taboption("gps", ListValue,"gps_enable",translate("GPS Enable")) 105 | gps_enable.optional = false; 106 | gps_enable.rmempty = false; 107 | gps_enable.default = false 108 | gps_enable.datatype = "bool" 109 | gps_enable:value(true, translate("True")) 110 | gps_enable:value(false, translate("False")) 111 | 112 | -- 113 | -- TTY path for GPS 114 | -- 115 | gps_tty_path = gateway:taboption("gps", Value,"gps_tty_path",translate("TTY path for GPS")) 116 | gps_tty_path.optional = true; 117 | gps_tty_path.rmempty = true; 118 | gps_tty_path.default = false 119 | gps_tty_path.datatype = "string" 120 | gps_tty_path:depends("gps_enable", "true") 121 | 122 | -- 123 | -- GPS reference coordinates: latitude 124 | -- 125 | gps_latitude = gateway:taboption("gps", Value,"ref_latitude",translate("GPS Reference Latitude")) 126 | gps_latitude.optional = true; 127 | gps_latitude.rmempty = true; 128 | gps_latitude.default = '1.0' 129 | gps_latitude.datatype = "float" 130 | gps_latitude:depends("gps_enable", "true") 131 | 132 | -- 133 | -- GPS reference coordinates: longitude 134 | -- 135 | gps_longitude = gateway:taboption("gps", Value,"ref_longitude",translate("GPS Reference Longitude")) 136 | gps_longitude.optional = true; 137 | gps_longitude.rmempty = true; 138 | gps_longitude.default = '1.0' 139 | gps_longitude.datatype = "float" 140 | gps_longitude:depends("gps_enable", "true") 141 | 142 | -- 143 | -- GPS reference coordinates: altitude 144 | -- 145 | gps_altitude = gateway:taboption("gps", Value,"ref_altitude",translate("GPS Reference Altitude")) 146 | gps_altitude.optional = true; 147 | gps_altitude.rmempty = true; 148 | gps_altitude.default = '1.0' 149 | gps_altitude.datatype = "float" 150 | gps_altitude:depends("gps_enable", "true") 151 | 152 | -- 153 | -- Beacon enable 154 | -- 155 | beacon_enable = gateway:taboption("beacon", ListValue,"beacon_enable",translate("Beacon Enable")) 156 | beacon_enable.optional = false; 157 | beacon_enable.rmempty = false; 158 | beacon_enable.default = false 159 | beacon_enable.datatype = "bool" 160 | beacon_enable:value(true, translate("True")) 161 | beacon_enable:value(false, translate("False")) 162 | 163 | -- 164 | -- Beacon period 165 | -- 166 | beacon_period = gateway:taboption("beacon", Value,"beacon_period",translate("Beacon Period"), "in second") 167 | beacon_period.optional = true; 168 | beacon_period.rmempty = true; 169 | beacon_period.default = '128' 170 | beacon_period.datatype = "uinteger" 171 | beacon_period:depends("beacon_enable", "true") 172 | 173 | -- 174 | -- Beacon channel frequency 175 | -- 176 | beacon_frequency = gateway:taboption("beacon", Value,"beacon_frequency",translate("Beacon Channel Frequency"), "in Hz") 177 | beacon_frequency.optional = true; 178 | beacon_frequency.rmempty = true; 179 | beacon_frequency.default = '869525000' 180 | beacon_frequency.datatype = "uinteger" 181 | beacon_frequency:depends("beacon_enable", "true") 182 | 183 | -- 184 | -- Beacon channel datarate 185 | -- 186 | beacon_datarate = gateway:taboption("beacon", Value,"beacon_datarate",translate("Beacon Channel Datarate")) 187 | beacon_datarate.optional = true; 188 | beacon_datarate.rmempty = true; 189 | beacon_datarate.default = '9' 190 | beacon_datarate.datatype = "uinteger" 191 | beacon_datarate:depends("beacon_enable", "true") 192 | 193 | -- 194 | -- Beacon channel bandwidth 195 | -- 196 | beacon_bandwidth = gateway:taboption("beacon", Value,"beacon_bandwidth",translate("Beacon Channel Bandwidth"), "in Hz") 197 | beacon_bandwidth.optional = true; 198 | beacon_bandwidth.rmempty = true; 199 | beacon_bandwidth.default = '125000' 200 | beacon_bandwidth.datatype = "uinteger" 201 | beacon_bandwidth:depends("beacon_enable", "true") 202 | 203 | -- 204 | -- Beacon signal strength 205 | -- 206 | beacon_power = gateway:taboption("beacon", Value,"beacon_power",translate("Beacon Signal Strength"), "in dBm") 207 | beacon_power.optional = true; 208 | beacon_power.rmempty = true; 209 | beacon_power.default = '14' 210 | beacon_power.datatype = "uinteger" 211 | beacon_power:depends("beacon_enable", "true") 212 | 213 | -- 214 | -- Beacon info description 215 | -- 216 | beacon_infodesc = gateway:taboption("beacon", Value,"beacon_infodesc",translate("Beacon Info Description")) 217 | beacon_infodesc.optional = true; 218 | beacon_infodesc.rmempty = true; 219 | beacon_infodesc.default = '0' 220 | beacon_infodesc.datatype = "uinteger" 221 | beacon_infodesc:depends("beacon_enable", "true") 222 | 223 | -- 224 | -- SX1301 configuration for SX1301_conf 225 | -- 226 | sx1301=m:section(TypedSection,"sx1301","SX1301 Parameters") 227 | sx1301.addremove=false 228 | sx1301.anonymous=true 229 | 230 | lorawan_pb = sx1301:option(ListValue,"lorawan_public",translate("LoRaWAN is public")) 231 | lorawan_pb.optional = false; 232 | lorawan_pb.rmempty = false; 233 | lorawan_pb.default = false 234 | lorawan_pb.datatype = "bool" 235 | lorawan_pb:value(true, translate("True")) 236 | lorawan_pb:value(false, translate("False")) 237 | 238 | clkscr = sx1301:option(ListValue,"clksrc",translate("Clock Source"), "radio_1 provides clock to concentrator for most devices except MultiTech. For MultiTech set to 0.") 239 | clkscr.optional = false; 240 | clkscr.rmempty = false; 241 | clkscr.datatype = "integer" 242 | clkscr:value(1, translate("From radio_1")) 243 | clkscr:value(0, translate("From radio_0")) 244 | 245 | antenna_gain = sx1301:option(Value,"antenna_gain",translate("Antenne Gain"), "Antenna Gain, in dBi") 246 | antenna_gain.optional = false; 247 | antenna_gain.rmempty = false; 248 | 249 | enable_reset_pin = sx1301:option(Flag,"enable_reset_pin",translate("Enable Reset Pin ?"), "Some SX1301 boards like iC880A require to reset every time after restart") 250 | enable_reset_pin.optional = false; 251 | enable_reset_pin.rmempty = false; 252 | enable_reset_pin.disabled = 0 253 | enable_reset_pin.enable = 1 254 | 255 | reset_pin = sx1301:option(Value,"reset_pin",translate("Reset Pin"), "Reset SX1301 board") 256 | reset_pin.optional = false; 257 | reset_pin.rmempty = true; 258 | reset_pin.default = 21 259 | reset_pin:depends("enable_reset_pin", "1") 260 | 261 | -- 262 | -- Radio Parameters 263 | -- 264 | radio=m:section(TypedSection,"radio","Radio Parameters") 265 | radio.addremove=false 266 | radio.anonymous=false 267 | 268 | -- 269 | -- Radio enable 270 | -- 271 | enable = radio:option(ListValue,"enable",translate("Enable")) 272 | enable.optional = false; 273 | enable.rmempty = false; 274 | enable.default = false 275 | enable.datatype = "bool" 276 | enable:value(true, translate("True")) 277 | enable:value(false, translate("False")) 278 | 279 | -- 280 | -- Radio RF frontend 281 | -- 282 | type = radio:option(ListValue,"type",translate("Type")) 283 | type.optional = false; 284 | type.rmempty = false; 285 | type.datatype = "string" 286 | type:value("SX1257", translate("SX1257")) 287 | type:value("SX1255", translate("SX1255")) 288 | 289 | -- 290 | -- Radio Frequency 291 | -- 292 | freq = radio:option(Value,"freq",translate("Frequency"), "Hz") 293 | freq.optional = false; 294 | freq.rmempty = false; 295 | 296 | -- 297 | -- RSSI offset 298 | -- 299 | rssi_offset = radio:option(Value,"rssi_offset",translate("RSSI Offset"), "dB") 300 | rssi_offset.optional = false; 301 | rssi_offset.rmempty = false; 302 | 303 | -- 304 | -- Tx Enable 305 | -- 306 | tx_enable = radio:option(ListValue,"tx_enable",translate("Tx Enable")) 307 | tx_enable.optional = false; 308 | tx_enable.rmempty = false; 309 | tx_enable.default = false 310 | tx_enable.datatype = "bool" 311 | tx_enable:value(true, translate("True")) 312 | tx_enable:value(false, translate("False")) 313 | 314 | tx_notch_freq= radio:option(Value,"tx_notch_freq",translate("Tx Notch Frequency"), "[126..250] KHz") 315 | tx_notch_freq.optional = false; 316 | tx_notch_freq.rmempty = true; 317 | tx_notch_freq:depends("tx_enable", "true") 318 | 319 | tx_freq_min= radio:option(Value,"tx_freq_min",translate("Minimum Tx Frequency"), "Hz") 320 | tx_freq_min.optional = false; 321 | tx_freq_min.rmempty = true; 322 | tx_freq_min:depends("tx_enable", "true") 323 | 324 | tx_freq_max= radio:option(Value,"tx_freq_max",translate("Maximum Tx Frequency"), "Hz") 325 | tx_freq_max.optional = false; 326 | tx_freq_max.rmempty = true; 327 | tx_freq_max:depends("tx_enable", "true") 328 | 329 | -- 330 | -- chann 331 | -- 332 | chan=m:section(TypedSection,"chan","Channel Parameters") 333 | chan.addremove=true 334 | chan.anonymous=false 335 | 336 | description = chan:option(Value ,"desc",translate("Description")) 337 | enable.optional = false; 338 | enable.rmempty = false; 339 | 340 | enable = chan:option(ListValue,"enable",translate("Enable")) 341 | enable.optional = false; 342 | enable.rmempty = false; 343 | enable.default = true 344 | enable.datatype = "bool" 345 | enable:value(true, translate("True")) 346 | enable:value(false, translate("False")) 347 | 348 | radio = chan:option(Value,"radio",translate("Radio")) 349 | radio.optional = false; 350 | radio.rmempty = false; 351 | 352 | interface = chan:option(Value,"if",translate("IF"), "Hz") 353 | interface.optional = false; 354 | interface.rmempty = false; 355 | 356 | bandwidth = chan:option(Value,"bandwidth",translate("Bandwidth")) 357 | bandwidth.optional = true; 358 | bandwidth.rmempty = false; 359 | 360 | spread_factor = chan:option(Value,"spread_factor",translate("Spread Factor")) 361 | spread_factor.optional = true; 362 | spread_factor.rmempty =false; 363 | 364 | datarate = chan:option(Value,"datarate",translate("Datarate")) 365 | datarate.optional = true; 366 | datarate.rmempty = false; 367 | 368 | -- 369 | -- TX gain tables 370 | -- 371 | lut=m:section(TypedSection,"lut","Tx LUT Parameters") 372 | lut.addremove=true 373 | lut.anonymous=false 374 | 375 | pa_gain = lut:option(Value,"pa_gain",translate("PA Gain")) 376 | pa_gain.optional = false; 377 | pa_gain.rmempty = false; 378 | 379 | mix_gain = lut:option(Value,"mix_gain",translate("Minimum Gain")) 380 | mix_gain.optional = false; 381 | mix_gain.rmempty = false; 382 | 383 | rf_power = lut:option(Value,"rf_power",translate("RF Power")) 384 | rf_power.optional = false; 385 | rf_power.rmempty = false; 386 | 387 | dig_gain = lut:option(Value,"dig_gain",translate("Dig Gain")) 388 | dig_gain.optional = false; 389 | dig_gain.rmempty = false; 390 | 391 | m.on_after_commit = function(self) 392 | 393 | io.popen("/etc/init.d/lora_pkt_fwd restart") 394 | end 395 | 396 | return m 397 | 398 | -------------------------------------------------------------------------------- /luci-lora-gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xueliu/lora-feed/7bf1be1efe717a1b9abf13886f4a98466a4137c2/luci-lora-gateway.png --------------------------------------------------------------------------------