├── .gitattributes ├── .github ├── pull_request_template.md └── workflows │ ├── ci.yml │ ├── create_tag.yml │ ├── publish.yml │ └── pull_request.yml ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── LICENSE ├── README.md ├── buf.yaml ├── meshtastic ├── admin.options ├── admin.proto ├── apponly.options ├── apponly.proto ├── atak.options ├── atak.proto ├── cannedmessages.options ├── cannedmessages.proto ├── channel.options ├── channel.proto ├── clientonly.options ├── clientonly.proto ├── config.options ├── config.proto ├── connection_status.options ├── connection_status.proto ├── device_ui.options ├── device_ui.proto ├── deviceonly.options ├── deviceonly.proto ├── interdevice.options ├── interdevice.proto ├── localonly.proto ├── mesh.options ├── mesh.proto ├── module_config.options ├── module_config.proto ├── mqtt.options ├── mqtt.proto ├── paxcount.proto ├── portnums.proto ├── powermon.proto ├── remote_hardware.proto ├── rtttl.options ├── rtttl.proto ├── storeforward.options ├── storeforward.proto ├── telemetry.options ├── telemetry.proto ├── xmodem.options └── xmodem.proto └── nanopb.proto /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.{cmd,[cC][mM][dD]} text eol=crlf 3 | *.{bat,[bB][aA][tT]} text eol=crlf 4 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # What does this PR do? 4 | 5 | 6 | 7 | > [Related Issue](https://github.com/meshtastic/protobufs/issues/0) 8 | 9 | ## Checklist before merging 10 | 11 | - [ ] All top level messages commented 12 | - [ ] All enum members have unique descriptions 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Push commit to schema registry 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | push: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | push_to_registry: 13 | name: Push to schema registry 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: Setup Buf 20 | uses: bufbuild/buf-setup-action@v1.30.0 21 | with: 22 | github_token: ${{ github.token }} 23 | 24 | - name: Push to schema registry 25 | uses: bufbuild/buf-push-action@v1.2.0 26 | with: 27 | buf_token: ${{ secrets.BUF_TOKEN }} 28 | -------------------------------------------------------------------------------- /.github/workflows/create_tag.yml: -------------------------------------------------------------------------------- 1 | name: Create tag 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | workflow_dispatch: 8 | inputs: 9 | increment_type: 10 | type: choice 11 | description: Select the type of version increment 12 | required: true 13 | options: 14 | - patch 15 | - minor 16 | - major 17 | 18 | jobs: 19 | increment_version: 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - name: Checkout code 24 | uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | - id: version 28 | name: Get current version 29 | run: | 30 | VERSION=$(git describe --abbrev=0 --tags) 31 | 32 | # Split version into major, minor, and patch 33 | MAJOR=$(echo $VERSION | awk -F '.' '{print $1}' | cut -c 2-) 34 | MINOR=$(echo $VERSION | awk -F '.' '{print $2}') 35 | PATCH=$(echo $VERSION | awk -F '.' '{print $3}') 36 | 37 | # Increment the appropriate part of the version 38 | if [[ ${{ inputs.increment_type }} == "patch" ]]; then 39 | PATCH=$((PATCH + 1)) 40 | elif [[ ${{ inputs.increment_type }} == "minor" ]]; then 41 | MINOR=$((MINOR + 1)) 42 | PATCH=0 43 | elif [[ ${{ inputs.increment_type }} == "major" ]]; then 44 | MAJOR=$((MAJOR + 1)) 45 | MINOR=0 46 | PATCH=0 47 | fi 48 | 49 | # Update the version 50 | echo "NEW_VERSION=v$MAJOR.$MINOR.$PATCH" >> $GITHUB_OUTPUT 51 | 52 | - name: Create release 53 | uses: ncipollo/release-action@v1 54 | with: 55 | name: Meshtastic Protobufs ${{ steps.version.outputs.NEW_VERSION }} 56 | tag: ${{ steps.version.outputs.NEW_VERSION }} 57 | generateReleaseNotes: true 58 | token: ${{ github.token }} 59 | 60 | - name: Setup Buf 61 | uses: bufbuild/buf-setup-action@v1.30.0 62 | with: 63 | github_token: ${{ github.token }} 64 | 65 | - name: Push to schema registry 66 | # uses: bufbuild/buf-push-action@v1 67 | # with: 68 | # buf_token: ${{ secrets.BUF_TOKEN }} 69 | run: | 70 | export BUF_TOKEN=${{ secrets.BUF_TOKEN }} 71 | buf push --tag ${{ steps.version.outputs.NEW_VERSION }} 72 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Push new version to schema registry 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | push: 8 | tags: 9 | - "**" 10 | 11 | jobs: 12 | push_to_registry: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: Setup Buf 20 | uses: bufbuild/buf-setup-action@v1.30.0 21 | with: 22 | github_token: ${{ github.token }} 23 | 24 | - name: Push to schema registry 25 | # uses: bufbuild/buf-push-action@v1 26 | # with: 27 | # buf_token: ${{ secrets.BUF_TOKEN }} 28 | run: | 29 | export BUF_TOKEN=${{ secrets.BUF_TOKEN }} 30 | buf push --tag ${{ github.ref_name }} 31 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: pull-request 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: pull_request 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Buf 16 | uses: bufbuild/buf-setup-action@v1.30.0 17 | with: 18 | github_token: ${{ github.token }} 19 | 20 | - name: Lint 21 | uses: bufbuild/buf-lint-action@v1.1.1 22 | 23 | - name: Push to schema registry 24 | uses: bufbuild/buf-push-action@v1.2.0 25 | if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} 26 | with: 27 | buf_token: ${{ secrets.BUF_TOKEN }} 28 | draft: ${{ github.ref_name != 'master'}} 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["pbkit.vscode-pbkit", "bufbuild.vscode-buf"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.defaultFormatter": "pbkit.vscode-pbkit" 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Meshtastic Protobuf Definitions 2 | 3 | [![CI](https://img.shields.io/github/actions/workflow/status/meshtastic/protobufs/ci.yml?branch=master&label=actions&logo=github&color=yellow)](https://github.com/meshtastic/protobufs/actions/workflows/ci.yml) 4 | [![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/protobufs)](https://cla-assistant.io/meshtastic/protobufs) 5 | [![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/) 6 | [![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss) 7 | 8 | ## Overview 9 | 10 | The [Protobuf](https://developers.google.com/protocol-buffers) message definitions for the Meshtastic project (used by apps and the device firmware). 11 | 12 | **[Documentation/API Reference](https://buf.build/meshtastic/protobufs)** 13 | 14 | ## Stats 15 | 16 | ![Alt](https://repobeats.axiom.co/api/embed/47e9ee1d81d9c0fdd2b4b5b4c673adb1756f6db5.svg "Repobeats analytics image") 17 | 18 | -------------------------------------------------------------------------------- /buf.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | name: buf.build/meshtastic/protobufs 3 | deps: [] 4 | build: 5 | excludes: [] 6 | breaking: 7 | use: 8 | - FILE 9 | lint: 10 | ignore_only: 11 | PACKAGE_DEFINED: 12 | - nanopb.proto 13 | use: 14 | - MINIMAL 15 | -------------------------------------------------------------------------------- /meshtastic/admin.options: -------------------------------------------------------------------------------- 1 | *AdminMessage.payload_variant anonymous_oneof:true 2 | 3 | *AdminMessage.session_passkey max_size:8 4 | 5 | *AdminMessage.set_canned_message_module_messages max_size:201 6 | *AdminMessage.get_canned_message_module_messages_response max_size:201 7 | *AdminMessage.delete_file_request max_size:201 8 | 9 | *AdminMessage.set_ringtone_message max_size:231 10 | *AdminMessage.get_ringtone_response max_size:231 11 | 12 | *HamParameters.call_sign max_size:8 13 | *HamParameters.short_name max_size:5 14 | *NodeRemoteHardwarePinsResponse.node_remote_hardware_pins max_count:16 15 | -------------------------------------------------------------------------------- /meshtastic/admin.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/channel.proto"; 6 | import "meshtastic/config.proto"; 7 | import "meshtastic/connection_status.proto"; 8 | import "meshtastic/mesh.proto"; 9 | import "meshtastic/module_config.proto"; 10 | import "meshtastic/device_ui.proto"; 11 | 12 | option csharp_namespace = "Meshtastic.Protobufs"; 13 | option go_package = "github.com/meshtastic/go/generated"; 14 | option java_outer_classname = "AdminProtos"; 15 | option java_package = "com.geeksville.mesh"; 16 | option swift_prefix = ""; 17 | 18 | /* 19 | * This message is handled by the Admin module and is responsible for all settings/channel read/write operations. 20 | * This message is used to do settings operations to both remote AND local nodes. 21 | * (Prior to 1.2 these operations were done via special ToRadio operations) 22 | */ 23 | message AdminMessage { 24 | 25 | /* 26 | * The node generates this key and sends it with any get_x_response packets. 27 | * The client MUST include the same key with any set_x commands. Key expires after 300 seconds. 28 | * Prevents replay attacks for admin messages. 29 | */ 30 | bytes session_passkey = 101; 31 | 32 | /* 33 | * TODO: REPLACE 34 | */ 35 | enum ConfigType { 36 | /* 37 | * TODO: REPLACE 38 | */ 39 | DEVICE_CONFIG = 0; 40 | 41 | /* 42 | * TODO: REPLACE 43 | */ 44 | POSITION_CONFIG = 1; 45 | 46 | /* 47 | * TODO: REPLACE 48 | */ 49 | POWER_CONFIG = 2; 50 | 51 | /* 52 | * TODO: REPLACE 53 | */ 54 | NETWORK_CONFIG = 3; 55 | 56 | /* 57 | * TODO: REPLACE 58 | */ 59 | DISPLAY_CONFIG = 4; 60 | 61 | /* 62 | * TODO: REPLACE 63 | */ 64 | LORA_CONFIG = 5; 65 | 66 | /* 67 | * TODO: REPLACE 68 | */ 69 | BLUETOOTH_CONFIG = 6; 70 | 71 | /* 72 | * TODO: REPLACE 73 | */ 74 | SECURITY_CONFIG = 7; 75 | 76 | /* 77 | * Session key config 78 | */ 79 | SESSIONKEY_CONFIG = 8; 80 | 81 | /* 82 | * device-ui config 83 | */ 84 | DEVICEUI_CONFIG = 9; 85 | } 86 | 87 | /* 88 | * TODO: REPLACE 89 | */ 90 | enum ModuleConfigType { 91 | /* 92 | * TODO: REPLACE 93 | */ 94 | MQTT_CONFIG = 0; 95 | 96 | /* 97 | * TODO: REPLACE 98 | */ 99 | SERIAL_CONFIG = 1; 100 | 101 | /* 102 | * TODO: REPLACE 103 | */ 104 | EXTNOTIF_CONFIG = 2; 105 | 106 | /* 107 | * TODO: REPLACE 108 | */ 109 | STOREFORWARD_CONFIG = 3; 110 | 111 | /* 112 | * TODO: REPLACE 113 | */ 114 | RANGETEST_CONFIG = 4; 115 | 116 | /* 117 | * TODO: REPLACE 118 | */ 119 | TELEMETRY_CONFIG = 5; 120 | 121 | /* 122 | * TODO: REPLACE 123 | */ 124 | CANNEDMSG_CONFIG = 6; 125 | 126 | /* 127 | * TODO: REPLACE 128 | */ 129 | AUDIO_CONFIG = 7; 130 | 131 | /* 132 | * TODO: REPLACE 133 | */ 134 | REMOTEHARDWARE_CONFIG = 8; 135 | 136 | /* 137 | * TODO: REPLACE 138 | */ 139 | NEIGHBORINFO_CONFIG = 9; 140 | 141 | /* 142 | * TODO: REPLACE 143 | */ 144 | AMBIENTLIGHTING_CONFIG = 10; 145 | 146 | /* 147 | * TODO: REPLACE 148 | */ 149 | DETECTIONSENSOR_CONFIG = 11; 150 | 151 | /* 152 | * TODO: REPLACE 153 | */ 154 | PAXCOUNTER_CONFIG = 12; 155 | } 156 | 157 | enum BackupLocation { 158 | /* 159 | * Backup to the internal flash 160 | */ 161 | FLASH = 0; 162 | 163 | /* 164 | * Backup to the SD card 165 | */ 166 | SD = 1; 167 | } 168 | 169 | /* 170 | * TODO: REPLACE 171 | */ 172 | oneof payload_variant { 173 | /* 174 | * Send the specified channel in the response to this message 175 | * NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) 176 | */ 177 | uint32 get_channel_request = 1; 178 | 179 | /* 180 | * TODO: REPLACE 181 | */ 182 | Channel get_channel_response = 2; 183 | 184 | /* 185 | * Send the current owner data in the response to this message. 186 | */ 187 | bool get_owner_request = 3; 188 | 189 | /* 190 | * TODO: REPLACE 191 | */ 192 | User get_owner_response = 4; 193 | 194 | /* 195 | * Ask for the following config data to be sent 196 | */ 197 | ConfigType get_config_request = 5; 198 | 199 | /* 200 | * Send the current Config in the response to this message. 201 | */ 202 | Config get_config_response = 6; 203 | 204 | /* 205 | * Ask for the following config data to be sent 206 | */ 207 | ModuleConfigType get_module_config_request = 7; 208 | 209 | /* 210 | * Send the current Config in the response to this message. 211 | */ 212 | ModuleConfig get_module_config_response = 8; 213 | 214 | /* 215 | * Get the Canned Message Module messages in the response to this message. 216 | */ 217 | bool get_canned_message_module_messages_request = 10; 218 | 219 | /* 220 | * Get the Canned Message Module messages in the response to this message. 221 | */ 222 | string get_canned_message_module_messages_response = 11; 223 | 224 | /* 225 | * Request the node to send device metadata (firmware, protobuf version, etc) 226 | */ 227 | bool get_device_metadata_request = 12; 228 | 229 | /* 230 | * Device metadata response 231 | */ 232 | DeviceMetadata get_device_metadata_response = 13; 233 | 234 | /* 235 | * Get the Ringtone in the response to this message. 236 | */ 237 | bool get_ringtone_request = 14; 238 | 239 | /* 240 | * Get the Ringtone in the response to this message. 241 | */ 242 | string get_ringtone_response = 15; 243 | 244 | /* 245 | * Request the node to send it's connection status 246 | */ 247 | bool get_device_connection_status_request = 16; 248 | 249 | /* 250 | * Device connection status response 251 | */ 252 | DeviceConnectionStatus get_device_connection_status_response = 17; 253 | 254 | /* 255 | * Setup a node for licensed amateur (ham) radio operation 256 | */ 257 | HamParameters set_ham_mode = 18; 258 | 259 | /* 260 | * Get the mesh's nodes with their available gpio pins for RemoteHardware module use 261 | */ 262 | bool get_node_remote_hardware_pins_request = 19; 263 | 264 | /* 265 | * Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use 266 | */ 267 | NodeRemoteHardwarePinsResponse get_node_remote_hardware_pins_response = 20; 268 | 269 | /* 270 | * Enter (UF2) DFU mode 271 | * Only implemented on NRF52 currently 272 | */ 273 | bool enter_dfu_mode_request = 21; 274 | 275 | /* 276 | * Delete the file by the specified path from the device 277 | */ 278 | string delete_file_request = 22; 279 | 280 | /* 281 | * Set zero and offset for scale chips 282 | */ 283 | uint32 set_scale = 23; 284 | 285 | /* 286 | * Backup the node's preferences 287 | */ 288 | BackupLocation backup_preferences = 24; 289 | 290 | /* 291 | * Restore the node's preferences 292 | */ 293 | BackupLocation restore_preferences = 25; 294 | 295 | /* 296 | * Remove backups of the node's preferences 297 | */ 298 | BackupLocation remove_backup_preferences = 26; 299 | /* 300 | * Set the owner for this node 301 | */ 302 | User set_owner = 32; 303 | 304 | /* 305 | * Set channels (using the new API). 306 | * A special channel is the "primary channel". 307 | * The other records are secondary channels. 308 | * Note: only one channel can be marked as primary. 309 | * If the client sets a particular channel to be primary, the previous channel will be set to SECONDARY automatically. 310 | */ 311 | Channel set_channel = 33; 312 | 313 | /* 314 | * Set the current Config 315 | */ 316 | Config set_config = 34; 317 | 318 | /* 319 | * Set the current Config 320 | */ 321 | ModuleConfig set_module_config = 35; 322 | 323 | /* 324 | * Set the Canned Message Module messages text. 325 | */ 326 | string set_canned_message_module_messages = 36; 327 | 328 | /* 329 | * Set the ringtone for ExternalNotification. 330 | */ 331 | string set_ringtone_message = 37; 332 | 333 | /* 334 | * Remove the node by the specified node-num from the NodeDB on the device 335 | */ 336 | uint32 remove_by_nodenum = 38; 337 | 338 | /* 339 | * Set specified node-num to be favorited on the NodeDB on the device 340 | */ 341 | uint32 set_favorite_node = 39; 342 | 343 | /* 344 | * Set specified node-num to be un-favorited on the NodeDB on the device 345 | */ 346 | uint32 remove_favorite_node = 40; 347 | 348 | /* 349 | * Set fixed position data on the node and then set the position.fixed_position = true 350 | */ 351 | Position set_fixed_position = 41; 352 | 353 | /* 354 | * Clear fixed position coordinates and then set position.fixed_position = false 355 | */ 356 | bool remove_fixed_position = 42; 357 | 358 | /* 359 | * Set time only on the node 360 | * Convenience method to set the time on the node (as Net quality) without any other position data 361 | */ 362 | fixed32 set_time_only = 43; 363 | 364 | /* 365 | * Tell the node to send the stored ui data. 366 | */ 367 | bool get_ui_config_request = 44; 368 | 369 | /* 370 | * Reply stored device ui data. 371 | */ 372 | DeviceUIConfig get_ui_config_response = 45; 373 | 374 | /* 375 | * Tell the node to store UI data persistently. 376 | */ 377 | DeviceUIConfig store_ui_config = 46; 378 | 379 | /* 380 | * Set specified node-num to be ignored on the NodeDB on the device 381 | */ 382 | uint32 set_ignored_node = 47; 383 | 384 | /* 385 | * Set specified node-num to be un-ignored on the NodeDB on the device 386 | */ 387 | uint32 remove_ignored_node = 48; 388 | 389 | /* 390 | * Begins an edit transaction for config, module config, owner, and channel settings changes 391 | * This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) 392 | */ 393 | bool begin_edit_settings = 64; 394 | 395 | /* 396 | * Commits an open transaction for any edits made to config, module config, owner, and channel settings 397 | */ 398 | bool commit_edit_settings = 65; 399 | 400 | /* 401 | * Add a contact (User) to the nodedb 402 | */ 403 | SharedContact add_contact = 66; 404 | 405 | /* 406 | * Initiate or respond to a key verification request 407 | */ 408 | KeyVerificationAdmin key_verification = 67; 409 | 410 | /* 411 | * Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. 412 | */ 413 | int32 factory_reset_device = 94; 414 | 415 | /* 416 | * Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) 417 | * Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. 418 | */ 419 | int32 reboot_ota_seconds = 95; 420 | 421 | /* 422 | * This message is only supported for the simulator Portduino build. 423 | * If received the simulator will exit successfully. 424 | */ 425 | bool exit_simulator = 96; 426 | 427 | /* 428 | * Tell the node to reboot in this many seconds (or <0 to cancel reboot) 429 | */ 430 | int32 reboot_seconds = 97; 431 | 432 | /* 433 | * Tell the node to shutdown in this many seconds (or <0 to cancel shutdown) 434 | */ 435 | int32 shutdown_seconds = 98; 436 | 437 | /* 438 | * Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved. 439 | */ 440 | int32 factory_reset_config = 99; 441 | 442 | /* 443 | * Tell the node to reset the nodedb. 444 | */ 445 | int32 nodedb_reset = 100; 446 | } 447 | } 448 | 449 | /* 450 | * Parameters for setting up Meshtastic for ameteur radio usage 451 | */ 452 | message HamParameters { 453 | /* 454 | * Amateur radio call sign, eg. KD2ABC 455 | */ 456 | string call_sign = 1; 457 | 458 | /* 459 | * Transmit power in dBm at the LoRA transceiver, not including any amplification 460 | */ 461 | int32 tx_power = 2; 462 | 463 | /* 464 | * The selected frequency of LoRA operation 465 | * Please respect your local laws, regulations, and band plans. 466 | * Ensure your radio is capable of operating of the selected frequency before setting this. 467 | */ 468 | float frequency = 3; 469 | 470 | /* 471 | * Optional short name of user 472 | */ 473 | string short_name = 4; 474 | } 475 | 476 | /* 477 | * Response envelope for node_remote_hardware_pins 478 | */ 479 | message NodeRemoteHardwarePinsResponse { 480 | /* 481 | * Nodes and their respective remote hardware GPIO pins 482 | */ 483 | repeated NodeRemoteHardwarePin node_remote_hardware_pins = 1; 484 | } 485 | 486 | message SharedContact { 487 | /* 488 | * The node number of the contact 489 | */ 490 | uint32 node_num = 1; 491 | 492 | /* 493 | * The User of the contact 494 | */ 495 | User user = 2; 496 | } 497 | 498 | /* 499 | * This message is used by a client to initiate or complete a key verification 500 | */ 501 | message KeyVerificationAdmin { 502 | /* 503 | * Three stages of this request. 504 | */ 505 | enum MessageType { 506 | 507 | /* 508 | * This is the first stage, where a client initiates 509 | */ 510 | INITIATE_VERIFICATION = 0; 511 | 512 | /* 513 | * After the nonce has been returned over the mesh, the client prompts for the security number 514 | * And uses this message to provide it to the node. 515 | */ 516 | PROVIDE_SECURITY_NUMBER = 1; 517 | 518 | /* 519 | * Once the user has compared the verification message, this message notifies the node. 520 | */ 521 | DO_VERIFY = 2; 522 | 523 | /* 524 | * This is the cancel path, can be taken at any point 525 | */ 526 | DO_NOT_VERIFY = 3; 527 | 528 | } 529 | 530 | MessageType message_type = 1; 531 | 532 | /* 533 | * The nodenum we're requesting 534 | */ 535 | uint32 remote_nodenum = 2; 536 | 537 | /* 538 | * The nonce is used to track the connection 539 | */ 540 | uint64 nonce = 3; 541 | 542 | /* 543 | * The 4 digit code generated by the remote node, and communicated outside the mesh 544 | */ 545 | optional uint32 security_number = 4; 546 | } 547 | -------------------------------------------------------------------------------- /meshtastic/apponly.options: -------------------------------------------------------------------------------- 1 | *ChannelSet.settings max_count:8 2 | -------------------------------------------------------------------------------- /meshtastic/apponly.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/channel.proto"; 6 | import "meshtastic/config.proto"; 7 | 8 | option csharp_namespace = "Meshtastic.Protobufs"; 9 | option go_package = "github.com/meshtastic/go/generated"; 10 | option java_outer_classname = "AppOnlyProtos"; 11 | option java_package = "com.geeksville.mesh"; 12 | option swift_prefix = ""; 13 | 14 | /* 15 | * This is the most compact possible representation for a set of channels. 16 | * It includes only one PRIMARY channel (which must be first) and 17 | * any SECONDARY channels. 18 | * No DISABLED channels are included. 19 | * This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL 20 | */ 21 | message ChannelSet { 22 | /* 23 | * Channel list with settings 24 | */ 25 | repeated ChannelSettings settings = 1; 26 | 27 | /* 28 | * LoRa config 29 | */ 30 | Config.LoRaConfig lora_config = 2; 31 | } 32 | -------------------------------------------------------------------------------- /meshtastic/atak.options: -------------------------------------------------------------------------------- 1 | *Contact.callsign max_size:120 2 | *Contact.device_callsign max_size:120 3 | *Status.battery int_size:8 4 | *PLI.course int_size:16 5 | *GeoChat.message max_size:200 6 | *GeoChat.to max_size:120 7 | *GeoChat.to_callsign max_size:120 8 | *TAKPacket.detail max_size:220 -------------------------------------------------------------------------------- /meshtastic/atak.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "ATAKProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * Packets for the official ATAK Plugin 13 | */ 14 | message TAKPacket { 15 | /* 16 | * Are the payloads strings compressed for LoRA transport? 17 | */ 18 | bool is_compressed = 1; 19 | /* 20 | * The contact / callsign for ATAK user 21 | */ 22 | Contact contact = 2; 23 | /* 24 | * The group for ATAK user 25 | */ 26 | Group group = 3; 27 | /* 28 | * The status of the ATAK EUD 29 | */ 30 | Status status = 4; 31 | /* 32 | * The payload of the packet 33 | */ 34 | oneof payload_variant { 35 | /* 36 | * TAK position report 37 | */ 38 | PLI pli = 5; 39 | /* 40 | * ATAK GeoChat message 41 | */ 42 | GeoChat chat = 6; 43 | 44 | /* 45 | * Generic CoT detail XML 46 | * May be compressed / truncated by the sender (EUD) 47 | */ 48 | bytes detail = 7; 49 | } 50 | } 51 | 52 | /* 53 | * ATAK GeoChat message 54 | */ 55 | message GeoChat { 56 | /* 57 | * The text message 58 | */ 59 | string message = 1; 60 | 61 | /* 62 | * Uid recipient of the message 63 | */ 64 | optional string to = 2; 65 | 66 | /* 67 | * Callsign of the recipient for the message 68 | */ 69 | optional string to_callsign = 3; 70 | } 71 | 72 | /* 73 | * ATAK Group 74 | * <__group role='Team Member' name='Cyan'/> 75 | */ 76 | message Group { 77 | /* 78 | * Role of the group member 79 | */ 80 | MemberRole role = 1; 81 | /* 82 | * Team (color) 83 | * Default Cyan 84 | */ 85 | Team team = 2; 86 | } 87 | 88 | enum Team { 89 | /* 90 | * Unspecifed 91 | */ 92 | Unspecifed_Color = 0; 93 | /* 94 | * White 95 | */ 96 | White = 1; 97 | /* 98 | * Yellow 99 | */ 100 | Yellow = 2; 101 | /* 102 | * Orange 103 | */ 104 | Orange = 3; 105 | /* 106 | * Magenta 107 | */ 108 | Magenta = 4; 109 | /* 110 | * Red 111 | */ 112 | Red = 5; 113 | /* 114 | * Maroon 115 | */ 116 | Maroon = 6; 117 | /* 118 | * Purple 119 | */ 120 | Purple = 7; 121 | /* 122 | * Dark Blue 123 | */ 124 | Dark_Blue = 8; 125 | /* 126 | * Blue 127 | */ 128 | Blue = 9; 129 | /* 130 | * Cyan 131 | */ 132 | Cyan = 10; 133 | /* 134 | * Teal 135 | */ 136 | Teal = 11; 137 | /* 138 | * Green 139 | */ 140 | Green = 12; 141 | /* 142 | * Dark Green 143 | */ 144 | Dark_Green = 13; 145 | /* 146 | * Brown 147 | */ 148 | Brown = 14; 149 | } 150 | 151 | /* 152 | * Role of the group member 153 | */ 154 | enum MemberRole { 155 | /* 156 | * Unspecifed 157 | */ 158 | Unspecifed = 0; 159 | /* 160 | * Team Member 161 | */ 162 | TeamMember = 1; 163 | /* 164 | * Team Lead 165 | */ 166 | TeamLead = 2; 167 | /* 168 | * Headquarters 169 | */ 170 | HQ = 3; 171 | /* 172 | * Airsoft enthusiast 173 | */ 174 | Sniper = 4; 175 | /* 176 | * Medic 177 | */ 178 | Medic = 5; 179 | /* 180 | * ForwardObserver 181 | */ 182 | ForwardObserver = 6; 183 | /* 184 | * Radio Telephone Operator 185 | */ 186 | RTO = 7; 187 | /* 188 | * Doggo 189 | */ 190 | K9 = 8; 191 | } 192 | 193 | /* 194 | * ATAK EUD Status 195 | * 196 | */ 197 | message Status { 198 | /* 199 | * Battery level 200 | */ 201 | uint32 battery = 1; 202 | } 203 | 204 | /* 205 | * ATAK Contact 206 | * 207 | */ 208 | message Contact { 209 | /* 210 | * Callsign 211 | */ 212 | string callsign = 1; 213 | 214 | /* 215 | * Device callsign 216 | */ 217 | string device_callsign = 2; 218 | /* 219 | * IP address of endpoint in integer form (0.0.0.0 default) 220 | */ 221 | // fixed32 enpoint_address = 3; 222 | /* 223 | * Port of endpoint (4242 default) 224 | */ 225 | // uint32 endpoint_port = 4; 226 | /* 227 | * Phone represented as integer 228 | * Terrible practice, but we really need the wire savings 229 | */ 230 | // uint32 phone = 4; 231 | } 232 | 233 | /* 234 | * Position Location Information from ATAK 235 | */ 236 | message PLI { 237 | /* 238 | * The new preferred location encoding, multiply by 1e-7 to get degrees 239 | * in floating point 240 | */ 241 | sfixed32 latitude_i = 1; 242 | 243 | /* 244 | * The new preferred location encoding, multiply by 1e-7 to get degrees 245 | * in floating point 246 | */ 247 | sfixed32 longitude_i = 2; 248 | 249 | /* 250 | * Altitude (ATAK prefers HAE) 251 | */ 252 | int32 altitude = 3; 253 | 254 | /* 255 | * Speed 256 | */ 257 | uint32 speed = 4; 258 | 259 | /* 260 | * Course in degrees 261 | */ 262 | uint32 course = 5; 263 | } 264 | -------------------------------------------------------------------------------- /meshtastic/cannedmessages.options: -------------------------------------------------------------------------------- 1 | *CannedMessageModuleConfig.messages max_size:201 2 | -------------------------------------------------------------------------------- /meshtastic/cannedmessages.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "CannedMessageConfigProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * Canned message module configuration. 13 | */ 14 | message CannedMessageModuleConfig { 15 | /* 16 | * Predefined messages for canned message module separated by '|' characters. 17 | */ 18 | string messages = 1; 19 | } 20 | -------------------------------------------------------------------------------- /meshtastic/channel.options: -------------------------------------------------------------------------------- 1 | *Channel.index int_size:8 2 | 3 | # 256 bit or 128 bit psk key 4 | *ChannelSettings.psk max_size:32 5 | *ChannelSettings.name max_size:12 6 | -------------------------------------------------------------------------------- /meshtastic/channel.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "ChannelProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * This information can be encoded as a QRcode/url so that other users can configure 13 | * their radio to join the same channel. 14 | * A note about how channel names are shown to users: channelname-X 15 | * poundsymbol is a prefix used to indicate this is a channel name (idea from @professr). 16 | * Where X is a letter from A-Z (base 26) representing a hash of the PSK for this 17 | * channel - so that if the user changes anything about the channel (which does 18 | * force a new PSK) this letter will also change. Thus preventing user confusion if 19 | * two friends try to type in a channel name of "BobsChan" and then can't talk 20 | * because their PSKs will be different. 21 | * The PSK is hashed into this letter by "0x41 + [xor all bytes of the psk ] modulo 26" 22 | * This also allows the option of someday if people have the PSK off (zero), the 23 | * users COULD type in a channel name and be able to talk. 24 | * FIXME: Add description of multi-channel support and how primary vs secondary channels are used. 25 | * FIXME: explain how apps use channels for security. 26 | * explain how remote settings and remote gpio are managed as an example 27 | */ 28 | message ChannelSettings { 29 | /* 30 | * Deprecated in favor of LoraConfig.channel_num 31 | */ 32 | uint32 channel_num = 1 [deprecated = true]; 33 | 34 | /* 35 | * A simple pre-shared key for now for crypto. 36 | * Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256). 37 | * A special shorthand is used for 1 byte long psks. 38 | * These psks should be treated as only minimally secure, 39 | * because they are listed in this source code. 40 | * Those bytes are mapped using the following scheme: 41 | * `0` = No crypto 42 | * `1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01} 43 | * `2` through 10 = The default channel key, except with 1 through 9 added to the last byte. 44 | * Shown to user as simple1 through 10 45 | */ 46 | bytes psk = 2; 47 | 48 | /* 49 | * A SHORT name that will be packed into the URL. 50 | * Less than 12 bytes. 51 | * Something for end users to call the channel 52 | * If this is the empty string it is assumed that this channel 53 | * is the special (minimally secure) "Default"channel. 54 | * In user interfaces it should be rendered as a local language translation of "X". 55 | * For channel_num hashing empty string will be treated as "X". 56 | * Where "X" is selected based on the English words listed above for ModemPreset 57 | */ 58 | string name = 3; 59 | 60 | /* 61 | * Used to construct a globally unique channel ID. 62 | * The full globally unique ID will be: "name.id" where ID is shown as base36. 63 | * Assuming that the number of meshtastic users is below 20K (true for a long time) 64 | * the chance of this 64 bit random number colliding with anyone else is super low. 65 | * And the penalty for collision is low as well, it just means that anyone trying to decrypt channel messages might need to 66 | * try multiple candidate channels. 67 | * Any time a non wire compatible change is made to a channel, this field should be regenerated. 68 | * There are a small number of 'special' globally known (and fairly) insecure standard channels. 69 | * Those channels do not have a numeric id included in the settings, but instead it is pulled from 70 | * a table of well known IDs. 71 | * (see Well Known Channels FIXME) 72 | */ 73 | fixed32 id = 4; 74 | 75 | /* 76 | * If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe 77 | */ 78 | bool uplink_enabled = 5; 79 | 80 | /* 81 | * If true, messages seen on the internet will be forwarded to the local mesh. 82 | */ 83 | bool downlink_enabled = 6; 84 | 85 | /* 86 | * Per-channel module settings. 87 | */ 88 | ModuleSettings module_settings = 7; 89 | } 90 | 91 | /* 92 | * This message is specifically for modules to store per-channel configuration data. 93 | */ 94 | message ModuleSettings { 95 | /* 96 | * Bits of precision for the location sent in position packets. 97 | */ 98 | uint32 position_precision = 1; 99 | 100 | /* 101 | * Controls whether or not the phone / clients should mute the current channel 102 | * Useful for noisy public channels you don't necessarily want to disable 103 | */ 104 | bool is_client_muted = 2; 105 | } 106 | 107 | /* 108 | * A pair of a channel number, mode and the (sharable) settings for that channel 109 | */ 110 | message Channel { 111 | /* 112 | * How this channel is being used (or not). 113 | * Note: this field is an enum to give us options for the future. 114 | * In particular, someday we might make a 'SCANNING' option. 115 | * SCANNING channels could have different frequencies and the radio would 116 | * occasionally check that freq to see if anything is being transmitted. 117 | * For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow 118 | * cross band routing as needed. 119 | * If a device has only a single radio (the common case) only one channel can be PRIMARY at a time 120 | * (but any number of SECONDARY channels can't be sent received on that common frequency) 121 | */ 122 | enum Role { 123 | /* 124 | * This channel is not in use right now 125 | */ 126 | DISABLED = 0; 127 | 128 | /* 129 | * This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY 130 | */ 131 | PRIMARY = 1; 132 | 133 | /* 134 | * Secondary channels are only used for encryption/decryption/authentication purposes. 135 | * Their radio settings (freq etc) are ignored, only psk is used. 136 | */ 137 | SECONDARY = 2; 138 | } 139 | 140 | /* 141 | * The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1) 142 | * (Someday - not currently implemented) An index of -1 could be used to mean "set by name", 143 | * in which case the target node will find and set the channel by settings.name. 144 | */ 145 | int32 index = 1; 146 | 147 | /* 148 | * The new settings, or NULL to disable that channel 149 | */ 150 | ChannelSettings settings = 2; 151 | 152 | /* 153 | * TODO: REPLACE 154 | */ 155 | Role role = 3; 156 | } 157 | -------------------------------------------------------------------------------- /meshtastic/clientonly.options: -------------------------------------------------------------------------------- 1 | *DeviceProfile.long_name max_size:40 2 | *DeviceProfile.short_name max_size:5 3 | *DeviceProfile.ringtone max_size:231 4 | *DeviceProfile.canned_messages max_size:201 -------------------------------------------------------------------------------- /meshtastic/clientonly.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/localonly.proto"; 6 | import "meshtastic/mesh.proto"; 7 | 8 | option csharp_namespace = "Meshtastic.Protobufs"; 9 | option go_package = "github.com/meshtastic/go/generated"; 10 | option java_outer_classname = "ClientOnlyProtos"; 11 | option java_package = "com.geeksville.mesh"; 12 | option swift_prefix = ""; 13 | 14 | /* 15 | * This abstraction is used to contain any configuration for provisioning a node on any client. 16 | * It is useful for importing and exporting configurations. 17 | */ 18 | message DeviceProfile { 19 | /* 20 | * Long name for the node 21 | */ 22 | optional string long_name = 1; 23 | 24 | /* 25 | * Short name of the node 26 | */ 27 | optional string short_name = 2; 28 | 29 | /* 30 | * The url of the channels from our node 31 | */ 32 | optional string channel_url = 3; 33 | 34 | /* 35 | * The Config of the node 36 | */ 37 | optional LocalConfig config = 4; 38 | 39 | /* 40 | * The ModuleConfig of the node 41 | */ 42 | optional LocalModuleConfig module_config = 5; 43 | 44 | /* 45 | * Fixed position data 46 | */ 47 | optional Position fixed_position = 6; 48 | 49 | /* 50 | * Ringtone for ExternalNotification 51 | */ 52 | optional string ringtone = 7; 53 | 54 | /* 55 | * Predefined messages for CannedMessage 56 | */ 57 | optional string canned_messages = 8; 58 | } 59 | -------------------------------------------------------------------------------- /meshtastic/config.options: -------------------------------------------------------------------------------- 1 | # longest current is 45 chars, plan with a bit of buffer 2 | *DeviceConfig.tzdef max_size:65 3 | 4 | *NetworkConfig.wifi_ssid max_size:33 5 | *NetworkConfig.wifi_psk max_size:65 6 | *NetworkConfig.ntp_server max_size:33 7 | *NetworkConfig.rsyslog_server max_size:33 8 | 9 | # Max of three ignored nodes for our testing 10 | *LoRaConfig.ignore_incoming max_count:3 11 | 12 | *LoRaConfig.tx_power int_size:8 13 | *LoRaConfig.bandwidth int_size:16 14 | *LoRaConfig.coding_rate int_size:8 15 | *LoRaConfig.channel_num int_size:16 16 | 17 | *PowerConfig.device_battery_ina_address int_size:8 18 | 19 | *SecurityConfig.public_key max_size:32 20 | *SecurityConfig.private_key max_size:32 21 | *SecurityConfig.admin_key max_size:32 22 | *SecurityConfig.admin_key max_count:3 23 | -------------------------------------------------------------------------------- /meshtastic/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/device_ui.proto"; 6 | 7 | option csharp_namespace = "Meshtastic.Protobufs"; 8 | option go_package = "github.com/meshtastic/go/generated"; 9 | option java_outer_classname = "ConfigProtos"; 10 | option java_package = "com.geeksville.mesh"; 11 | option swift_prefix = ""; 12 | 13 | message Config { 14 | /* 15 | * Configuration 16 | */ 17 | message DeviceConfig { 18 | /* 19 | * Defines the device's role on the Mesh network 20 | */ 21 | enum Role { 22 | /* 23 | * Description: App connected or stand alone messaging device. 24 | * Technical Details: Default Role 25 | */ 26 | CLIENT = 0; 27 | /* 28 | * Description: Device that does not forward packets from other devices. 29 | */ 30 | CLIENT_MUTE = 1; 31 | 32 | /* 33 | * Description: Infrastructure node for extending network coverage by relaying messages. Visible in Nodes list. 34 | * Technical Details: Mesh packets will prefer to be routed over this node. This node will not be used by client apps. 35 | * The wifi radio and the oled screen will be put to sleep. 36 | * This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. 37 | */ 38 | ROUTER = 2; 39 | 40 | /* 41 | * Description: Combination of both ROUTER and CLIENT. Not for mobile devices. 42 | * Deprecated in v2.3.15 because improper usage is impacting public meshes: Use ROUTER or CLIENT instead. 43 | */ 44 | 45 | ROUTER_CLIENT = 3 [deprecated = true]; 46 | 47 | /* 48 | * Description: Infrastructure node for extending network coverage by relaying messages with minimal overhead. Not visible in Nodes list. 49 | * Technical Details: Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry 50 | * or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate. 51 | */ 52 | REPEATER = 4; 53 | 54 | /* 55 | * Description: Broadcasts GPS position packets as priority. 56 | * Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default. 57 | * When used in conjunction with power.is_power_saving = true, nodes will wake up, 58 | * send position, and then sleep for position.position_broadcast_secs seconds. 59 | */ 60 | TRACKER = 5; 61 | 62 | /* 63 | * Description: Broadcasts telemetry packets as priority. 64 | * Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default. 65 | * When used in conjunction with power.is_power_saving = true, nodes will wake up, 66 | * send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. 67 | */ 68 | SENSOR = 6; 69 | 70 | /* 71 | * Description: Optimized for ATAK system communication and reduces routine broadcasts. 72 | * Technical Details: Used for nodes dedicated for connection to an ATAK EUD. 73 | * Turns off many of the routine broadcasts to favor CoT packet stream 74 | * from the Meshtastic ATAK plugin -> IMeshService -> Node 75 | */ 76 | TAK = 7; 77 | 78 | /* 79 | * Description: Device that only broadcasts as needed for stealth or power savings. 80 | * Technical Details: Used for nodes that "only speak when spoken to" 81 | * Turns all of the routine broadcasts but allows for ad-hoc communication 82 | * Still rebroadcasts, but with local only rebroadcast mode (known meshes only) 83 | * Can be used for clandestine operation or to dramatically reduce airtime / power consumption 84 | */ 85 | CLIENT_HIDDEN = 8; 86 | 87 | /* 88 | * Description: Broadcasts location as message to default channel regularly for to assist with device recovery. 89 | * Technical Details: Used to automatically send a text message to the mesh 90 | * with the current position of the device on a frequent interval: 91 | * "I'm lost! Position: lat / long" 92 | */ 93 | LOST_AND_FOUND = 9; 94 | 95 | /* 96 | * Description: Enables automatic TAK PLI broadcasts and reduces routine broadcasts. 97 | * Technical Details: Turns off many of the routine broadcasts to favor ATAK CoT packet stream 98 | * and automatic TAK PLI (position location information) broadcasts. 99 | * Uses position module configuration to determine TAK PLI broadcast interval. 100 | */ 101 | TAK_TRACKER = 10; 102 | 103 | /* 104 | * Description: Will always rebroadcast packets, but will do so after all other modes. 105 | * Technical Details: Used for router nodes that are intended to provide additional coverage 106 | * in areas not already covered by other routers, or to bridge around problematic terrain, 107 | * but should not be given priority over other routers in order to avoid unnecessaraily 108 | * consuming hops. 109 | */ 110 | ROUTER_LATE = 11; 111 | } 112 | 113 | /* 114 | * Defines the device's behavior for how messages are rebroadcast 115 | */ 116 | enum RebroadcastMode { 117 | /* 118 | * Default behavior. 119 | * Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params. 120 | */ 121 | ALL = 0; 122 | 123 | /* 124 | * Same as behavior as ALL but skips packet decoding and simply rebroadcasts them. 125 | * Only available in Repeater role. Setting this on any other roles will result in ALL behavior. 126 | */ 127 | ALL_SKIP_DECODING = 1; 128 | 129 | /* 130 | * Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. 131 | * Only rebroadcasts message on the nodes local primary / secondary channels. 132 | */ 133 | LOCAL_ONLY = 2; 134 | 135 | /* 136 | * Ignores observed messages from foreign meshes like LOCAL_ONLY, 137 | * but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB) 138 | */ 139 | KNOWN_ONLY = 3; 140 | 141 | /* 142 | * Only permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role. 143 | */ 144 | NONE = 4; 145 | 146 | /* 147 | * Ignores packets from non-standard portnums such as: TAK, RangeTest, PaxCounter, etc. 148 | * Only rebroadcasts packets with standard portnums: NodeInfo, Text, Position, Telemetry, and Routing. 149 | */ 150 | CORE_PORTNUMS_ONLY = 5; 151 | } 152 | 153 | /* 154 | * Sets the role of node 155 | */ 156 | Role role = 1; 157 | 158 | /* 159 | * Disabling this will disable the SerialConsole by not initilizing the StreamAPI 160 | * Moved to SecurityConfig 161 | */ 162 | bool serial_enabled = 2[deprecated = true]; 163 | 164 | /* 165 | * For boards without a hard wired button, this is the pin number that will be used 166 | * Boards that have more than one button can swap the function with this one. defaults to BUTTON_PIN if defined. 167 | */ 168 | uint32 button_gpio = 4; 169 | 170 | /* 171 | * For boards without a PWM buzzer, this is the pin number that will be used 172 | * Defaults to PIN_BUZZER if defined. 173 | */ 174 | uint32 buzzer_gpio = 5; 175 | 176 | /* 177 | * Sets the role of node 178 | */ 179 | RebroadcastMode rebroadcast_mode = 6; 180 | 181 | /* 182 | * Send our nodeinfo this often 183 | * Defaults to 900 Seconds (15 minutes) 184 | */ 185 | uint32 node_info_broadcast_secs = 7; 186 | 187 | /* 188 | * Treat double tap interrupt on supported accelerometers as a button press if set to true 189 | */ 190 | bool double_tap_as_button_press = 8; 191 | 192 | /* 193 | * If true, device is considered to be "managed" by a mesh administrator 194 | * Clients should then limit available configuration and administrative options inside the user interface 195 | * Moved to SecurityConfig 196 | */ 197 | bool is_managed = 9[deprecated = true]; 198 | 199 | /* 200 | * Disables the triple-press of user button to enable or disable GPS 201 | */ 202 | bool disable_triple_click = 10; 203 | 204 | /* 205 | * POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. 206 | */ 207 | string tzdef = 11; 208 | 209 | /* 210 | * If true, disable the default blinking LED (LED_PIN) behavior on the device 211 | */ 212 | bool led_heartbeat_disabled = 12; 213 | } 214 | 215 | /* 216 | * Position Config 217 | */ 218 | message PositionConfig { 219 | /* 220 | * Bit field of boolean configuration options, indicating which optional 221 | * fields to include when assembling POSITION messages. 222 | * Longitude, latitude, altitude, speed, heading, and DOP 223 | * are always included (also time if GPS-synced) 224 | * NOTE: the more fields are included, the larger the message will be - 225 | * leading to longer airtime and a higher risk of packet loss 226 | */ 227 | enum PositionFlags { 228 | /* 229 | * Required for compilation 230 | */ 231 | UNSET = 0x0000; 232 | 233 | /* 234 | * Include an altitude value (if available) 235 | */ 236 | ALTITUDE = 0x0001; 237 | 238 | /* 239 | * Altitude value is MSL 240 | */ 241 | ALTITUDE_MSL = 0x0002; 242 | 243 | /* 244 | * Include geoidal separation 245 | */ 246 | GEOIDAL_SEPARATION = 0x0004; 247 | 248 | /* 249 | * Include the DOP value ; PDOP used by default, see below 250 | */ 251 | DOP = 0x0008; 252 | 253 | /* 254 | * If POS_DOP set, send separate HDOP / VDOP values instead of PDOP 255 | */ 256 | HVDOP = 0x0010; 257 | 258 | /* 259 | * Include number of "satellites in view" 260 | */ 261 | SATINVIEW = 0x0020; 262 | 263 | /* 264 | * Include a sequence number incremented per packet 265 | */ 266 | SEQ_NO = 0x0040; 267 | 268 | /* 269 | * Include positional timestamp (from GPS solution) 270 | */ 271 | TIMESTAMP = 0x0080; 272 | 273 | /* 274 | * Include positional heading 275 | * Intended for use with vehicle not walking speeds 276 | * walking speeds are likely to be error prone like the compass 277 | */ 278 | HEADING = 0x0100; 279 | 280 | /* 281 | * Include positional speed 282 | * Intended for use with vehicle not walking speeds 283 | * walking speeds are likely to be error prone like the compass 284 | */ 285 | SPEED = 0x0200; 286 | } 287 | 288 | enum GpsMode { 289 | /* 290 | * GPS is present but disabled 291 | */ 292 | DISABLED = 0; 293 | 294 | /* 295 | * GPS is present and enabled 296 | */ 297 | ENABLED = 1; 298 | 299 | /* 300 | * GPS is not present on the device 301 | */ 302 | NOT_PRESENT = 2; 303 | } 304 | 305 | /* 306 | * We should send our position this often (but only if it has changed significantly) 307 | * Defaults to 15 minutes 308 | */ 309 | uint32 position_broadcast_secs = 1; 310 | 311 | /* 312 | * Adaptive position braoadcast, which is now the default. 313 | */ 314 | bool position_broadcast_smart_enabled = 2; 315 | 316 | /* 317 | * If set, this node is at a fixed position. 318 | * We will generate GPS position updates at the regular interval, but use whatever the last lat/lon/alt we have for the node. 319 | * The lat/lon/alt can be set by an internal GPS or with the help of the app. 320 | */ 321 | bool fixed_position = 3; 322 | 323 | /* 324 | * Is GPS enabled for this node? 325 | */ 326 | bool gps_enabled = 4 [deprecated = true]; 327 | 328 | /* 329 | * How often should we try to get GPS position (in seconds) 330 | * or zero for the default of once every 30 seconds 331 | * or a very large value (maxint) to update only once at boot. 332 | */ 333 | uint32 gps_update_interval = 5; 334 | 335 | /* 336 | * Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time 337 | */ 338 | uint32 gps_attempt_time = 6 [deprecated = true]; 339 | 340 | /* 341 | * Bit field of boolean configuration options for POSITION messages 342 | * (bitwise OR of PositionFlags) 343 | */ 344 | uint32 position_flags = 7; 345 | 346 | /* 347 | * (Re)define GPS_RX_PIN for your board. 348 | */ 349 | uint32 rx_gpio = 8; 350 | 351 | /* 352 | * (Re)define GPS_TX_PIN for your board. 353 | */ 354 | uint32 tx_gpio = 9; 355 | 356 | /* 357 | * The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled 358 | */ 359 | uint32 broadcast_smart_minimum_distance = 10; 360 | 361 | /* 362 | * The minimum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled 363 | */ 364 | uint32 broadcast_smart_minimum_interval_secs = 11; 365 | 366 | /* 367 | * (Re)define PIN_GPS_EN for your board. 368 | */ 369 | uint32 gps_en_gpio = 12; 370 | 371 | /* 372 | * Set where GPS is enabled, disabled, or not present 373 | */ 374 | GpsMode gps_mode = 13; 375 | } 376 | 377 | /* 378 | * Power Config\ 379 | * See [Power Config](/docs/settings/config/power) for additional power config details. 380 | */ 381 | message PowerConfig { 382 | /* 383 | * Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. 384 | * Don't use this setting if you want to use your device with the phone apps or are using a device without a user button. 385 | * Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles 386 | */ 387 | bool is_power_saving = 1; 388 | 389 | /* 390 | * Description: If non-zero, the device will fully power off this many seconds after external power is removed. 391 | */ 392 | uint32 on_battery_shutdown_after_secs = 2; 393 | 394 | /* 395 | * Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) 396 | * Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. 397 | * https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override 398 | * Should be set to floating point value between 2 and 6 399 | */ 400 | float adc_multiplier_override = 3; 401 | 402 | /* 403 | * Description: The number of seconds for to wait before turning off BLE in No Bluetooth states 404 | * Technical Details: ESP32 Only 0 for default of 1 minute 405 | */ 406 | uint32 wait_bluetooth_secs = 4; 407 | 408 | /* 409 | * Super Deep Sleep Seconds 410 | * While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep 411 | * for this value (default 1 year) or a button press 412 | * 0 for default of one year 413 | */ 414 | uint32 sds_secs = 6; 415 | 416 | /* 417 | * Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on 418 | * Technical Details: ESP32 Only 0 for default of 300 419 | */ 420 | uint32 ls_secs = 7; 421 | 422 | /* 423 | * Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value 424 | * Technical Details: ESP32 Only 0 for default of 10 seconds 425 | */ 426 | uint32 min_wake_secs = 8; 427 | 428 | /* 429 | * I2C address of INA_2XX to use for reading device battery voltage 430 | */ 431 | uint32 device_battery_ina_address = 9; 432 | 433 | /* 434 | * If non-zero, we want powermon log outputs. With the particular (bitfield) sources enabled. 435 | * Note: we picked an ID of 32 so that lower more efficient IDs can be used for more frequently used options. 436 | */ 437 | uint64 powermon_enables = 32; 438 | } 439 | 440 | /* 441 | * Network Config 442 | */ 443 | message NetworkConfig { 444 | enum AddressMode { 445 | /* 446 | * obtain ip address via DHCP 447 | */ 448 | DHCP = 0; 449 | 450 | /* 451 | * use static ip address 452 | */ 453 | STATIC = 1; 454 | } 455 | 456 | message IpV4Config { 457 | /* 458 | * Static IP address 459 | */ 460 | fixed32 ip = 1; 461 | 462 | /* 463 | * Static gateway address 464 | */ 465 | fixed32 gateway = 2; 466 | 467 | /* 468 | * Static subnet mask 469 | */ 470 | fixed32 subnet = 3; 471 | 472 | /* 473 | * Static DNS server address 474 | */ 475 | fixed32 dns = 4; 476 | } 477 | 478 | /* 479 | * Enable WiFi (disables Bluetooth) 480 | */ 481 | bool wifi_enabled = 1; 482 | 483 | /* 484 | * If set, this node will try to join the specified wifi network and 485 | * acquire an address via DHCP 486 | */ 487 | string wifi_ssid = 3; 488 | 489 | /* 490 | * If set, will be use to authenticate to the named wifi 491 | */ 492 | string wifi_psk = 4; 493 | 494 | /* 495 | * NTP server to use if WiFi is conneced, defaults to `meshtastic.pool.ntp.org` 496 | */ 497 | string ntp_server = 5; 498 | 499 | /* 500 | * Enable Ethernet 501 | */ 502 | bool eth_enabled = 6; 503 | 504 | /* 505 | * acquire an address via DHCP or assign static 506 | */ 507 | AddressMode address_mode = 7; 508 | 509 | /* 510 | * struct to keep static address 511 | */ 512 | IpV4Config ipv4_config = 8; 513 | 514 | /* 515 | * rsyslog Server and Port 516 | */ 517 | string rsyslog_server = 9; 518 | 519 | /* 520 | * Flags for enabling/disabling network protocols 521 | */ 522 | uint32 enabled_protocols = 10; 523 | 524 | /* 525 | * Enable/Disable ipv6 support 526 | */ 527 | bool ipv6_enabled = 11; 528 | 529 | /* 530 | * Available flags auxiliary network protocols 531 | */ 532 | enum ProtocolFlags { 533 | /* 534 | * Do not broadcast packets over any network protocol 535 | */ 536 | NO_BROADCAST = 0x0000; 537 | 538 | /* 539 | * Enable broadcasting packets via UDP over the local network 540 | */ 541 | UDP_BROADCAST = 0x0001; 542 | } 543 | } 544 | 545 | /* 546 | * Display Config 547 | */ 548 | message DisplayConfig { 549 | /* 550 | * How the GPS coordinates are displayed on the OLED screen. 551 | */ 552 | enum GpsCoordinateFormat { 553 | /* 554 | * GPS coordinates are displayed in the normal decimal degrees format: 555 | * DD.DDDDDD DDD.DDDDDD 556 | */ 557 | DEC = 0; 558 | 559 | /* 560 | * GPS coordinates are displayed in the degrees minutes seconds format: 561 | * DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant 562 | */ 563 | DMS = 1; 564 | 565 | /* 566 | * Universal Transverse Mercator format: 567 | * ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing 568 | */ 569 | UTM = 2; 570 | 571 | /* 572 | * Military Grid Reference System format: 573 | * ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square, 574 | * E is easting, N is northing 575 | */ 576 | MGRS = 3; 577 | 578 | /* 579 | * Open Location Code (aka Plus Codes). 580 | */ 581 | OLC = 4; 582 | 583 | /* 584 | * Ordnance Survey Grid Reference (the National Grid System of the UK). 585 | * Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, 586 | * E is the easting, N is the northing 587 | */ 588 | OSGR = 5; 589 | } 590 | 591 | /* 592 | * Unit display preference 593 | */ 594 | enum DisplayUnits { 595 | /* 596 | * Metric (Default) 597 | */ 598 | METRIC = 0; 599 | 600 | /* 601 | * Imperial 602 | */ 603 | IMPERIAL = 1; 604 | } 605 | 606 | /* 607 | * Override OLED outo detect with this if it fails. 608 | */ 609 | enum OledType { 610 | /* 611 | * Default / Autodetect 612 | */ 613 | OLED_AUTO = 0; 614 | 615 | /* 616 | * Default / Autodetect 617 | */ 618 | OLED_SSD1306 = 1; 619 | 620 | /* 621 | * Default / Autodetect 622 | */ 623 | OLED_SH1106 = 2; 624 | 625 | /* 626 | * Can not be auto detected but set by proto. Used for 128x128 screens 627 | */ 628 | OLED_SH1107 = 3; 629 | 630 | /* 631 | * Can not be auto detected but set by proto. Used for 128x64 screens 632 | */ 633 | OLED_SH1107_128_64 = 4; 634 | } 635 | 636 | /* 637 | * Number of seconds the screen stays on after pressing the user button or receiving a message 638 | * 0 for default of one minute MAXUINT for always on 639 | */ 640 | uint32 screen_on_secs = 1; 641 | 642 | /* 643 | * How the GPS coordinates are formatted on the OLED screen. 644 | */ 645 | GpsCoordinateFormat gps_format = 2; 646 | 647 | /* 648 | * Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds. 649 | * Potentially useful for devices without user buttons. 650 | */ 651 | uint32 auto_screen_carousel_secs = 3; 652 | 653 | /* 654 | * If this is set, the displayed compass will always point north. if unset, the old behaviour 655 | * (top of display is heading direction) is used. 656 | */ 657 | bool compass_north_top = 4; 658 | 659 | /* 660 | * Flip screen vertically, for cases that mount the screen upside down 661 | */ 662 | bool flip_screen = 5; 663 | 664 | /* 665 | * Perferred display units 666 | */ 667 | DisplayUnits units = 6; 668 | 669 | /* 670 | * Override auto-detect in screen 671 | */ 672 | OledType oled = 7; 673 | 674 | enum DisplayMode { 675 | /* 676 | * Default. The old style for the 128x64 OLED screen 677 | */ 678 | DEFAULT = 0; 679 | 680 | /* 681 | * Rearrange display elements to cater for bicolor OLED displays 682 | */ 683 | TWOCOLOR = 1; 684 | 685 | /* 686 | * Same as TwoColor, but with inverted top bar. Not so good for Epaper displays 687 | */ 688 | INVERTED = 2; 689 | 690 | /* 691 | * TFT Full Color Displays (not implemented yet) 692 | */ 693 | COLOR = 3; 694 | } 695 | /* 696 | * Display Mode 697 | */ 698 | DisplayMode displaymode = 8; 699 | 700 | /* 701 | * Print first line in pseudo-bold? FALSE is original style, TRUE is bold 702 | */ 703 | bool heading_bold = 9; 704 | 705 | /* 706 | * Should we wake the screen up on accelerometer detected motion or tap 707 | */ 708 | bool wake_on_tap_or_motion = 10; 709 | 710 | enum CompassOrientation { 711 | /* 712 | * The compass and the display are in the same orientation. 713 | */ 714 | DEGREES_0 = 0; 715 | 716 | /* 717 | * Rotate the compass by 90 degrees. 718 | */ 719 | DEGREES_90 = 1; 720 | 721 | /* 722 | * Rotate the compass by 180 degrees. 723 | */ 724 | DEGREES_180 = 2; 725 | 726 | /* 727 | * Rotate the compass by 270 degrees. 728 | */ 729 | DEGREES_270 = 3; 730 | 731 | /* 732 | * Don't rotate the compass, but invert the result. 733 | */ 734 | DEGREES_0_INVERTED = 4; 735 | 736 | /* 737 | * Rotate the compass by 90 degrees and invert. 738 | */ 739 | DEGREES_90_INVERTED = 5; 740 | 741 | /* 742 | * Rotate the compass by 180 degrees and invert. 743 | */ 744 | DEGREES_180_INVERTED = 6; 745 | 746 | /* 747 | * Rotate the compass by 270 degrees and invert. 748 | */ 749 | DEGREES_270_INVERTED = 7; 750 | } 751 | 752 | /* 753 | * Indicates how to rotate or invert the compass output to accurate display on the display. 754 | */ 755 | CompassOrientation compass_orientation = 11; 756 | 757 | /* 758 | * If false (default), the device will display the time in 24-hour format on screen. 759 | * If true, the device will display the time in 12-hour format on screen. 760 | */ 761 | bool use_12h_clock = 12; 762 | } 763 | 764 | /* 765 | * Lora Config 766 | */ 767 | message LoRaConfig { 768 | enum RegionCode { 769 | /* 770 | * Region is not set 771 | */ 772 | UNSET = 0; 773 | 774 | /* 775 | * United States 776 | */ 777 | US = 1; 778 | 779 | /* 780 | * European Union 433mhz 781 | */ 782 | EU_433 = 2; 783 | 784 | /* 785 | * European Union 868mhz 786 | */ 787 | EU_868 = 3; 788 | 789 | /* 790 | * China 791 | */ 792 | CN = 4; 793 | 794 | /* 795 | * Japan 796 | */ 797 | JP = 5; 798 | 799 | /* 800 | * Australia / New Zealand 801 | */ 802 | ANZ = 6; 803 | 804 | /* 805 | * Korea 806 | */ 807 | KR = 7; 808 | 809 | /* 810 | * Taiwan 811 | */ 812 | TW = 8; 813 | 814 | /* 815 | * Russia 816 | */ 817 | RU = 9; 818 | 819 | /* 820 | * India 821 | */ 822 | IN = 10; 823 | 824 | /* 825 | * New Zealand 865mhz 826 | */ 827 | NZ_865 = 11; 828 | 829 | /* 830 | * Thailand 831 | */ 832 | TH = 12; 833 | 834 | /* 835 | * WLAN Band 836 | */ 837 | LORA_24 = 13; 838 | 839 | /* 840 | * Ukraine 433mhz 841 | */ 842 | UA_433 = 14; 843 | 844 | /* 845 | * Ukraine 868mhz 846 | */ 847 | UA_868 = 15; 848 | 849 | /* 850 | * Malaysia 433mhz 851 | */ 852 | MY_433 = 16; 853 | 854 | /* 855 | * Malaysia 919mhz 856 | */ 857 | MY_919 = 17; 858 | 859 | /* 860 | * Singapore 923mhz 861 | */ 862 | SG_923 = 18; 863 | 864 | /* 865 | * Philippines 433mhz 866 | */ 867 | PH_433 = 19; 868 | 869 | /* 870 | * Philippines 868mhz 871 | */ 872 | PH_868 = 20; 873 | 874 | /* 875 | * Philippines 915mhz 876 | */ 877 | PH_915 = 21; 878 | } 879 | 880 | /* 881 | * Standard predefined channel settings 882 | * Note: these mappings must match ModemPreset Choice in the device code. 883 | */ 884 | enum ModemPreset { 885 | /* 886 | * Long Range - Fast 887 | */ 888 | LONG_FAST = 0; 889 | 890 | /* 891 | * Long Range - Slow 892 | */ 893 | LONG_SLOW = 1; 894 | 895 | /* 896 | * Very Long Range - Slow 897 | * Deprecated in 2.5: Works only with txco and is unusably slow 898 | */ 899 | VERY_LONG_SLOW = 2 [deprecated = true]; 900 | 901 | /* 902 | * Medium Range - Slow 903 | */ 904 | MEDIUM_SLOW = 3; 905 | 906 | /* 907 | * Medium Range - Fast 908 | */ 909 | MEDIUM_FAST = 4; 910 | 911 | /* 912 | * Short Range - Slow 913 | */ 914 | SHORT_SLOW = 5; 915 | 916 | /* 917 | * Short Range - Fast 918 | */ 919 | SHORT_FAST = 6; 920 | 921 | /* 922 | * Long Range - Moderately Fast 923 | */ 924 | LONG_MODERATE = 7; 925 | 926 | /* 927 | * Short Range - Turbo 928 | * This is the fastest preset and the only one with 500kHz bandwidth. 929 | * It is not legal to use in all regions due to this wider bandwidth. 930 | */ 931 | SHORT_TURBO = 8; 932 | } 933 | 934 | /* 935 | * When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate` 936 | * will be taked from their respective manually defined fields 937 | */ 938 | bool use_preset = 1; 939 | 940 | /* 941 | * Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. 942 | * As a heuristic: If bandwidth is specified, do not use modem_config. 943 | * Because protobufs take ZERO space when the value is zero this works out nicely. 944 | * This value is replaced by bandwidth/spread_factor/coding_rate. 945 | * If you'd like to experiment with other options add them to MeshRadio.cpp in the device code. 946 | */ 947 | ModemPreset modem_preset = 2; 948 | 949 | /* 950 | * Bandwidth in MHz 951 | * Certain bandwidth numbers are 'special' and will be converted to the 952 | * appropriate floating point value: 31 -> 31.25MHz 953 | */ 954 | uint32 bandwidth = 3; 955 | 956 | /* 957 | * A number from 7 to 12. 958 | * Indicates number of chirps per symbol as 1< 7 results in the default 984 | */ 985 | uint32 hop_limit = 8; 986 | 987 | /* 988 | * Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests. 989 | * Defaults to false 990 | */ 991 | bool tx_enabled = 9; 992 | 993 | /* 994 | * If zero, then use default max legal continuous power (ie. something that won't 995 | * burn out the radio hardware) 996 | * In most cases you should use zero here. 997 | * Units are in dBm. 998 | */ 999 | int32 tx_power = 10; 1000 | 1001 | /* 1002 | * This controls the actual hardware frequency the radio transmits on. 1003 | * Most users should never need to be exposed to this field/concept. 1004 | * A channel number between 1 and NUM_CHANNELS (whatever the max is in the current region). 1005 | * If ZERO then the rule is "use the old channel name hash based 1006 | * algorithm to derive the channel number") 1007 | * If using the hash algorithm the channel number will be: hash(channel_name) % 1008 | * NUM_CHANNELS (Where num channels depends on the regulatory region). 1009 | */ 1010 | uint32 channel_num = 11; 1011 | 1012 | /* 1013 | * If true, duty cycle limits will be exceeded and thus you're possibly not following 1014 | * the local regulations if you're not a HAM. 1015 | * Has no effect if the duty cycle of the used region is 100%. 1016 | */ 1017 | bool override_duty_cycle = 12; 1018 | 1019 | /* 1020 | * If true, sets RX boosted gain mode on SX126X based radios 1021 | */ 1022 | bool sx126x_rx_boosted_gain = 13; 1023 | 1024 | /* 1025 | * This parameter is for advanced users and licensed HAM radio operators. 1026 | * Ignore Channel Calculation and use this frequency instead. The frequency_offset 1027 | * will still be applied. This will allow you to use out-of-band frequencies. 1028 | * Please respect your local laws and regulations. If you are a HAM, make sure you 1029 | * enable HAM mode and turn off encryption. 1030 | */ 1031 | float override_frequency = 14; 1032 | 1033 | /* 1034 | * If true, disable the build-in PA FAN using pin define in RF95_FAN_EN. 1035 | */ 1036 | bool pa_fan_disabled = 15; 1037 | 1038 | /* 1039 | * For testing it is useful sometimes to force a node to never listen to 1040 | * particular other nodes (simulating radio out of range). All nodenums listed 1041 | * in ignore_incoming will have packets they send dropped on receive (by router.cpp) 1042 | */ 1043 | repeated uint32 ignore_incoming = 103; 1044 | 1045 | /* 1046 | * If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it. 1047 | */ 1048 | bool ignore_mqtt = 104; 1049 | 1050 | /* 1051 | * Sets the ok_to_mqtt bit on outgoing packets 1052 | */ 1053 | bool config_ok_to_mqtt = 105; 1054 | } 1055 | 1056 | message BluetoothConfig { 1057 | enum PairingMode { 1058 | /* 1059 | * Device generates a random PIN that will be shown on the screen of the device for pairing 1060 | */ 1061 | RANDOM_PIN = 0; 1062 | 1063 | /* 1064 | * Device requires a specified fixed PIN for pairing 1065 | */ 1066 | FIXED_PIN = 1; 1067 | 1068 | /* 1069 | * Device requires no PIN for pairing 1070 | */ 1071 | NO_PIN = 2; 1072 | } 1073 | 1074 | /* 1075 | * Enable Bluetooth on the device 1076 | */ 1077 | bool enabled = 1; 1078 | 1079 | /* 1080 | * Determines the pairing strategy for the device 1081 | */ 1082 | PairingMode mode = 2; 1083 | 1084 | /* 1085 | * Specified PIN for PairingMode.FixedPin 1086 | */ 1087 | uint32 fixed_pin = 3; 1088 | } 1089 | 1090 | message SecurityConfig { 1091 | 1092 | /* 1093 | * The public key of the user's device. 1094 | * Sent out to other nodes on the mesh to allow them to compute a shared secret key. 1095 | */ 1096 | bytes public_key = 1; 1097 | 1098 | /* 1099 | * The private key of the device. 1100 | * Used to create a shared key with a remote device. 1101 | */ 1102 | bytes private_key = 2; 1103 | 1104 | /* 1105 | * The public key authorized to send admin messages to this node. 1106 | */ 1107 | repeated bytes admin_key = 3; 1108 | 1109 | /* 1110 | * If true, device is considered to be "managed" by a mesh administrator via admin messages 1111 | * Device is managed by a mesh administrator. 1112 | */ 1113 | bool is_managed = 4; 1114 | 1115 | /* 1116 | * Serial Console over the Stream API." 1117 | */ 1118 | bool serial_enabled = 5; 1119 | 1120 | /* 1121 | * By default we turn off logging as soon as an API client connects (to keep shared serial link quiet). 1122 | * Output live debug logging over serial or bluetooth is set to true. 1123 | */ 1124 | bool debug_log_api_enabled = 6; 1125 | 1126 | /* 1127 | * Allow incoming device control over the insecure legacy admin channel. 1128 | */ 1129 | bool admin_channel_enabled = 8; 1130 | } 1131 | 1132 | /* 1133 | * Blank config request, strictly for getting the session key 1134 | */ 1135 | message SessionkeyConfig {} 1136 | 1137 | /* 1138 | * Payload Variant 1139 | */ 1140 | oneof payload_variant { 1141 | DeviceConfig device = 1; 1142 | PositionConfig position = 2; 1143 | PowerConfig power = 3; 1144 | NetworkConfig network = 4; 1145 | DisplayConfig display = 5; 1146 | LoRaConfig lora = 6; 1147 | BluetoothConfig bluetooth = 7; 1148 | SecurityConfig security = 8; 1149 | SessionkeyConfig sessionkey = 9; 1150 | DeviceUIConfig device_ui = 10; 1151 | } 1152 | } 1153 | -------------------------------------------------------------------------------- /meshtastic/connection_status.options: -------------------------------------------------------------------------------- 1 | *WifiConnectionStatus.ssid max_size:33 2 | -------------------------------------------------------------------------------- /meshtastic/connection_status.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "ConnStatusProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | message DeviceConnectionStatus { 12 | /* 13 | * WiFi Status 14 | */ 15 | optional WifiConnectionStatus wifi = 1; 16 | /* 17 | * WiFi Status 18 | */ 19 | optional EthernetConnectionStatus ethernet = 2; 20 | 21 | /* 22 | * Bluetooth Status 23 | */ 24 | optional BluetoothConnectionStatus bluetooth = 3; 25 | 26 | /* 27 | * Serial Status 28 | */ 29 | optional SerialConnectionStatus serial = 4; 30 | } 31 | 32 | /* 33 | * WiFi connection status 34 | */ 35 | message WifiConnectionStatus { 36 | /* 37 | * Connection status 38 | */ 39 | NetworkConnectionStatus status = 1; 40 | 41 | /* 42 | * WiFi access point SSID 43 | */ 44 | string ssid = 2; 45 | 46 | /* 47 | * RSSI of wireless connection 48 | */ 49 | int32 rssi = 3; 50 | } 51 | 52 | /* 53 | * Ethernet connection status 54 | */ 55 | message EthernetConnectionStatus { 56 | /* 57 | * Connection status 58 | */ 59 | NetworkConnectionStatus status = 1; 60 | } 61 | 62 | /* 63 | * Ethernet or WiFi connection status 64 | */ 65 | message NetworkConnectionStatus { 66 | /* 67 | * IP address of device 68 | */ 69 | fixed32 ip_address = 1; 70 | 71 | /* 72 | * Whether the device has an active connection or not 73 | */ 74 | bool is_connected = 2; 75 | 76 | /* 77 | * Whether the device has an active connection to an MQTT broker or not 78 | */ 79 | bool is_mqtt_connected = 3; 80 | 81 | /* 82 | * Whether the device is actively remote syslogging or not 83 | */ 84 | bool is_syslog_connected = 4; 85 | } 86 | 87 | /* 88 | * Bluetooth connection status 89 | */ 90 | message BluetoothConnectionStatus { 91 | /* 92 | * The pairing PIN for bluetooth 93 | */ 94 | uint32 pin = 1; 95 | 96 | /* 97 | * RSSI of bluetooth connection 98 | */ 99 | int32 rssi = 2; 100 | 101 | /* 102 | * Whether the device has an active connection or not 103 | */ 104 | bool is_connected = 3; 105 | } 106 | 107 | /* 108 | * Serial connection status 109 | */ 110 | message SerialConnectionStatus { 111 | /* 112 | * Serial baud rate 113 | */ 114 | uint32 baud = 1; 115 | 116 | /* 117 | * Whether the device has an active connection or not 118 | */ 119 | bool is_connected = 2; 120 | } 121 | -------------------------------------------------------------------------------- /meshtastic/device_ui.options: -------------------------------------------------------------------------------- 1 | *DeviceUIConfig.screen_brightness int_size:8 2 | *DeviceUIConfig.screen_timeout int_size:16 3 | *DeviceUIConfig.ring_tone_id int_size:8 4 | *DeviceUIConfig.calibration_data max_size:16 5 | *NodeFilter.node_name max_size:16 6 | *NodeFilter.hops_away int_size:8 7 | *NodeFilter.channel int_size:8 8 | *NodeHighlight.node_name max_size:16 9 | *GeoPoint.zoom int_size:8 10 | *Map.style max_size:20 11 | -------------------------------------------------------------------------------- /meshtastic/device_ui.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "DeviceUIProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * Protobuf structures for device-ui persistency 13 | */ 14 | 15 | message DeviceUIConfig { 16 | /* 17 | * A version integer used to invalidate saved files when we make incompatible changes. 18 | */ 19 | uint32 version = 1; 20 | 21 | /* 22 | * TFT display brightness 1..255 23 | */ 24 | uint32 screen_brightness = 2; 25 | 26 | /* 27 | * Screen timeout 0..900 28 | */ 29 | uint32 screen_timeout = 3; 30 | 31 | /* 32 | * Screen/Settings lock enabled 33 | */ 34 | bool screen_lock = 4; 35 | bool settings_lock = 5; 36 | uint32 pin_code = 6; 37 | 38 | /* 39 | * Color theme 40 | */ 41 | Theme theme = 7; 42 | 43 | /* 44 | * Audible message, banner and ring tone 45 | */ 46 | bool alert_enabled = 8; 47 | bool banner_enabled = 9; 48 | uint32 ring_tone_id = 10; 49 | 50 | /* 51 | * Localization 52 | */ 53 | Language language = 11; 54 | 55 | /* 56 | * Node list filter 57 | */ 58 | NodeFilter node_filter = 12; 59 | 60 | /* 61 | * Node list highlightening 62 | */ 63 | NodeHighlight node_highlight = 13; 64 | 65 | /* 66 | * 8 integers for screen calibration data 67 | */ 68 | bytes calibration_data = 14; 69 | 70 | /* 71 | * Map related data 72 | */ 73 | Map map_data = 15; 74 | } 75 | 76 | 77 | message NodeFilter { 78 | /* 79 | * Filter unknown nodes 80 | */ 81 | bool unknown_switch = 1; 82 | 83 | /* 84 | * Filter offline nodes 85 | */ 86 | bool offline_switch = 2; 87 | 88 | /* 89 | * Filter nodes w/o public key 90 | */ 91 | bool public_key_switch = 3; 92 | 93 | /* 94 | * Filter based on hops away 95 | */ 96 | int32 hops_away = 4; 97 | 98 | /* 99 | * Filter nodes w/o position 100 | */ 101 | bool position_switch = 5; 102 | 103 | /* 104 | * Filter nodes by matching name string 105 | */ 106 | string node_name = 6; 107 | 108 | /* 109 | * Filter based on channel 110 | */ 111 | int32 channel = 7; 112 | 113 | } 114 | 115 | message NodeHighlight { 116 | /* 117 | * Hightlight nodes w/ active chat 118 | */ 119 | bool chat_switch = 1; 120 | 121 | /* 122 | * Highlight nodes w/ position 123 | */ 124 | bool position_switch = 2; 125 | 126 | /* 127 | * Highlight nodes w/ telemetry data 128 | */ 129 | bool telemetry_switch = 3; 130 | 131 | /* 132 | * Highlight nodes w/ iaq data 133 | */ 134 | bool iaq_switch = 4; 135 | 136 | /* 137 | * Highlight nodes by matching name string 138 | */ 139 | string node_name = 5; 140 | 141 | } 142 | 143 | message GeoPoint { 144 | /* 145 | * Zoom level 146 | */ 147 | int32 zoom = 1; 148 | 149 | /* 150 | * Coordinate: latitude 151 | */ 152 | int32 latitude = 2; 153 | 154 | /* 155 | * Coordinate: longitude 156 | */ 157 | int32 longitude = 3; 158 | } 159 | 160 | message Map { 161 | /* 162 | * Home coordinates 163 | */ 164 | GeoPoint home = 1; 165 | 166 | /* 167 | * Map tile style 168 | */ 169 | string style = 2; 170 | 171 | /* 172 | * Map scroll follows GPS 173 | */ 174 | bool follow_gps = 3; 175 | } 176 | 177 | enum Theme { 178 | /* 179 | * Dark 180 | */ 181 | DARK = 0; 182 | /* 183 | * Light 184 | */ 185 | LIGHT = 1; 186 | /* 187 | * Red 188 | */ 189 | RED = 2; 190 | } 191 | 192 | /* 193 | * Localization 194 | */ 195 | enum Language { 196 | /* 197 | * English 198 | */ 199 | ENGLISH = 0; 200 | 201 | /* 202 | * French 203 | */ 204 | FRENCH = 1; 205 | 206 | /* 207 | * German 208 | */ 209 | GERMAN = 2; 210 | 211 | /* 212 | * Italian 213 | */ 214 | ITALIAN = 3; 215 | 216 | /* 217 | * Portuguese 218 | */ 219 | PORTUGUESE = 4; 220 | 221 | /* 222 | * Spanish 223 | */ 224 | SPANISH = 5; 225 | 226 | /* 227 | * Swedish 228 | */ 229 | SWEDISH = 6; 230 | 231 | /* 232 | * Finnish 233 | */ 234 | FINNISH = 7; 235 | 236 | /* 237 | * Polish 238 | */ 239 | POLISH = 8; 240 | 241 | /* 242 | * Turkish 243 | */ 244 | TURKISH = 9; 245 | 246 | /* 247 | * Serbian 248 | */ 249 | SERBIAN = 10; 250 | 251 | /* 252 | * Russian 253 | */ 254 | RUSSIAN = 11; 255 | 256 | /* 257 | * Dutch 258 | */ 259 | DUTCH = 12; 260 | 261 | /* 262 | * Greek 263 | */ 264 | GREEK = 13; 265 | 266 | /* 267 | * Norwegian 268 | */ 269 | NORWEGIAN = 14; 270 | 271 | /* 272 | * Slovenian 273 | */ 274 | SLOVENIAN = 15; 275 | 276 | /* 277 | * Ukrainian 278 | */ 279 | UKRAINIAN = 16; 280 | 281 | /* 282 | * Bulgarian 283 | */ 284 | BULGARIAN = 17; 285 | 286 | /* 287 | * Simplified Chinese (experimental) 288 | */ 289 | SIMPLIFIED_CHINESE = 30; 290 | 291 | /* 292 | * Traditional Chinese (experimental) 293 | */ 294 | TRADITIONAL_CHINESE = 31; 295 | } 296 | -------------------------------------------------------------------------------- /meshtastic/deviceonly.options: -------------------------------------------------------------------------------- 1 | # options for nanopb 2 | # https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options 3 | 4 | # FIXME - max_count is actually 32 but we save/load this as one long string of preencoded MeshPacket bytes - not a big array in RAM 5 | *DeviceState.receive_queue max_count:1 6 | 7 | *ChannelFile.channels max_count:8 8 | 9 | *DeviceState.node_remote_hardware_pins max_count:12 10 | 11 | *NodeInfoLite.channel int_size:8 12 | *NodeInfoLite.hops_away int_size:8 13 | *NodeInfoLite.next_hop int_size:8 14 | 15 | *UserLite.long_name max_size:40 16 | *UserLite.short_name max_size:5 17 | *UserLite.public_key max_size:32 # public key 18 | *UserLite.macaddr max_size:6 fixed_length:true -------------------------------------------------------------------------------- /meshtastic/deviceonly.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/channel.proto"; 6 | import "meshtastic/mesh.proto"; 7 | import "meshtastic/telemetry.proto"; 8 | import "meshtastic/config.proto"; 9 | import "meshtastic/localonly.proto"; 10 | import "nanopb.proto"; 11 | 12 | option csharp_namespace = "Meshtastic.Protobufs"; 13 | option go_package = "github.com/meshtastic/go/generated"; 14 | option java_outer_classname = "DeviceOnly"; 15 | option java_package = "com.geeksville.mesh"; 16 | option swift_prefix = ""; 17 | option (nanopb_fileopt).include = ""; 18 | 19 | 20 | /* 21 | * Position with static location information only for NodeDBLite 22 | */ 23 | message PositionLite { 24 | /* 25 | * The new preferred location encoding, multiply by 1e-7 to get degrees 26 | * in floating point 27 | */ 28 | sfixed32 latitude_i = 1; 29 | 30 | /* 31 | * TODO: REPLACE 32 | */ 33 | sfixed32 longitude_i = 2; 34 | 35 | /* 36 | * In meters above MSL (but see issue #359) 37 | */ 38 | int32 altitude = 3; 39 | 40 | /* 41 | * This is usually not sent over the mesh (to save space), but it is sent 42 | * from the phone so that the local device can set its RTC If it is sent over 43 | * the mesh (because there are devices on the mesh without GPS), it will only 44 | * be sent by devices which has a hardware GPS clock. 45 | * seconds since 1970 46 | */ 47 | fixed32 time = 4; 48 | 49 | /* 50 | * TODO: REPLACE 51 | */ 52 | Position.LocSource location_source = 5; 53 | } 54 | 55 | message UserLite { 56 | /* 57 | * This is the addr of the radio. 58 | */ 59 | bytes macaddr = 1 [deprecated = true]; 60 | 61 | /* 62 | * A full name for this user, i.e. "Kevin Hester" 63 | */ 64 | string long_name = 2; 65 | 66 | /* 67 | * A VERY short name, ideally two characters. 68 | * Suitable for a tiny OLED screen 69 | */ 70 | string short_name = 3; 71 | 72 | /* 73 | * TBEAM, HELTEC, etc... 74 | * Starting in 1.2.11 moved to hw_model enum in the NodeInfo object. 75 | * Apps will still need the string here for older builds 76 | * (so OTA update can find the right image), but if the enum is available it will be used instead. 77 | */ 78 | HardwareModel hw_model = 4; 79 | 80 | /* 81 | * In some regions Ham radio operators have different bandwidth limitations than others. 82 | * If this user is a licensed operator, set this flag. 83 | * Also, "long_name" should be their licence number. 84 | */ 85 | bool is_licensed = 5; 86 | 87 | /* 88 | * Indicates that the user's role in the mesh 89 | */ 90 | Config.DeviceConfig.Role role = 6; 91 | 92 | /* 93 | * The public key of the user's device. 94 | * This is sent out to other nodes on the mesh to allow them to compute a shared secret key. 95 | */ 96 | bytes public_key = 7; 97 | 98 | /* 99 | * Whether or not the node can be messaged 100 | */ 101 | optional bool is_unmessagable = 9; 102 | } 103 | 104 | message NodeInfoLite { 105 | /* 106 | * The node number 107 | */ 108 | uint32 num = 1; 109 | 110 | /* 111 | * The user info for this node 112 | */ 113 | UserLite user = 2; 114 | 115 | /* 116 | * This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true. 117 | * Position.time now indicates the last time we received a POSITION from that node. 118 | */ 119 | PositionLite position = 3; 120 | 121 | /* 122 | * Returns the Signal-to-noise ratio (SNR) of the last received message, 123 | * as measured by the receiver. Return SNR of the last received message in dB 124 | */ 125 | float snr = 4; 126 | 127 | /* 128 | * Set to indicate the last time we received a packet from this node 129 | */ 130 | fixed32 last_heard = 5; 131 | /* 132 | * The latest device metrics for the node. 133 | */ 134 | DeviceMetrics device_metrics = 6; 135 | 136 | /* 137 | * local channel index we heard that node on. Only populated if its not the default channel. 138 | */ 139 | uint32 channel = 7; 140 | 141 | /* 142 | * True if we witnessed the node over MQTT instead of LoRA transport 143 | */ 144 | bool via_mqtt = 8; 145 | 146 | /* 147 | * Number of hops away from us this node is (0 if direct neighbor) 148 | */ 149 | optional uint32 hops_away = 9; 150 | 151 | /* 152 | * True if node is in our favorites list 153 | * Persists between NodeDB internal clean ups 154 | */ 155 | bool is_favorite = 10; 156 | 157 | /* 158 | * True if node is in our ignored list 159 | * Persists between NodeDB internal clean ups 160 | */ 161 | bool is_ignored = 11; 162 | 163 | /* 164 | * Last byte of the node number of the node that should be used as the next hop to reach this node. 165 | */ 166 | uint32 next_hop = 12; 167 | 168 | /* 169 | * Bitfield for storing booleans. 170 | * LSB 0 is_key_manually_verified 171 | */ 172 | uint32 bitfield = 13; 173 | } 174 | 175 | /* 176 | * This message is never sent over the wire, but it is used for serializing DB 177 | * state to flash in the device code 178 | * FIXME, since we write this each time we enter deep sleep (and have infinite 179 | * flash) it would be better to use some sort of append only data structure for 180 | * the receive queue and use the preferences store for the other stuff 181 | */ 182 | message DeviceState { 183 | /* 184 | * Read only settings/info about this node 185 | */ 186 | MyNodeInfo my_node = 2; 187 | 188 | /* 189 | * My owner info 190 | */ 191 | User owner = 3; 192 | 193 | /* 194 | * Received packets saved for delivery to the phone 195 | */ 196 | repeated MeshPacket receive_queue = 5; 197 | 198 | /* 199 | * A version integer used to invalidate old save files when we make 200 | * incompatible changes This integer is set at build time and is private to 201 | * NodeDB.cpp in the device code. 202 | */ 203 | uint32 version = 8; 204 | 205 | /* 206 | * We keep the last received text message (only) stored in the device flash, 207 | * so we can show it on the screen. 208 | * Might be null 209 | */ 210 | MeshPacket rx_text_message = 7; 211 | 212 | /* 213 | * Used only during development. 214 | * Indicates developer is testing and changes should never be saved to flash. 215 | * Deprecated in 2.3.1 216 | */ 217 | bool no_save = 9 [deprecated = true]; 218 | 219 | /* 220 | * Previously used to manage GPS factory resets. 221 | * Deprecated in 2.5.23 222 | */ 223 | bool did_gps_reset = 11 [deprecated = true]; 224 | 225 | /* 226 | * We keep the last received waypoint stored in the device flash, 227 | * so we can show it on the screen. 228 | * Might be null 229 | */ 230 | MeshPacket rx_waypoint = 12; 231 | 232 | /* 233 | * The mesh's nodes with their available gpio pins for RemoteHardware module 234 | */ 235 | repeated NodeRemoteHardwarePin node_remote_hardware_pins = 13; 236 | } 237 | 238 | message NodeDatabase { 239 | /* 240 | * A version integer used to invalidate old save files when we make 241 | * incompatible changes This integer is set at build time and is private to 242 | * NodeDB.cpp in the device code. 243 | */ 244 | uint32 version = 1; 245 | 246 | /* 247 | * New lite version of NodeDB to decrease memory footprint 248 | */ 249 | repeated NodeInfoLite nodes = 2 [(nanopb).callback_datatype = "std::vector"]; 250 | } 251 | 252 | /* 253 | * The on-disk saved channels 254 | */ 255 | message ChannelFile { 256 | /* 257 | * The channels our node knows about 258 | */ 259 | repeated Channel channels = 1; 260 | 261 | /* 262 | * A version integer used to invalidate old save files when we make 263 | * incompatible changes This integer is set at build time and is private to 264 | * NodeDB.cpp in the device code. 265 | */ 266 | uint32 version = 2; 267 | } 268 | 269 | /* 270 | * The on-disk backup of the node's preferences 271 | */ 272 | message BackupPreferences { 273 | /* 274 | * The version of the backup 275 | */ 276 | uint32 version = 1; 277 | 278 | /* 279 | * The timestamp of the backup (if node has time) 280 | */ 281 | fixed32 timestamp = 2; 282 | 283 | /* 284 | * The node's configuration 285 | */ 286 | LocalConfig config = 3; 287 | 288 | /* 289 | * The node's module configuration 290 | */ 291 | LocalModuleConfig module_config = 4; 292 | 293 | /* 294 | * The node's channels 295 | */ 296 | ChannelFile channels = 5; 297 | 298 | /* 299 | * The node's user (owner) information 300 | */ 301 | User owner = 6; 302 | } 303 | -------------------------------------------------------------------------------- /meshtastic/interdevice.options: -------------------------------------------------------------------------------- 1 | *InterdeviceMessage.nmea max_size:1024 2 | -------------------------------------------------------------------------------- /meshtastic/interdevice.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "InterdeviceProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | // encapsulate up to 1k of NMEA string data 12 | 13 | enum MessageType { 14 | ACK = 0; 15 | COLLECT_INTERVAL = 160; // in ms 16 | BEEP_ON = 161; // duration ms 17 | BEEP_OFF = 162; // cancel prematurely 18 | SHUTDOWN = 163; 19 | POWER_ON = 164; 20 | SCD41_TEMP = 176; 21 | SCD41_HUMIDITY = 177; 22 | SCD41_CO2 = 178; 23 | AHT20_TEMP = 179; 24 | AHT20_HUMIDITY = 180; 25 | TVOC_INDEX = 181; 26 | } 27 | 28 | message SensorData { 29 | // The message type 30 | MessageType type = 1; 31 | // The sensor data, either as a float or an uint32 32 | oneof data { 33 | float float_value = 2; 34 | uint32 uint32_value = 3; 35 | } 36 | } 37 | 38 | message InterdeviceMessage { 39 | // The message data 40 | oneof data { 41 | string nmea = 1; 42 | SensorData sensor = 2; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /meshtastic/localonly.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/config.proto"; 6 | import "meshtastic/module_config.proto"; 7 | 8 | option csharp_namespace = "Meshtastic.Protobufs"; 9 | option go_package = "github.com/meshtastic/go/generated"; 10 | option java_outer_classname = "LocalOnlyProtos"; 11 | option java_package = "com.geeksville.mesh"; 12 | option swift_prefix = ""; 13 | 14 | /* 15 | * Protobuf structures common to apponly.proto and deviceonly.proto 16 | * This is never sent over the wire, only for local use 17 | */ 18 | 19 | message LocalConfig { 20 | /* 21 | * The part of the config that is specific to the Device 22 | */ 23 | Config.DeviceConfig device = 1; 24 | 25 | /* 26 | * The part of the config that is specific to the GPS Position 27 | */ 28 | Config.PositionConfig position = 2; 29 | 30 | /* 31 | * The part of the config that is specific to the Power settings 32 | */ 33 | Config.PowerConfig power = 3; 34 | 35 | /* 36 | * The part of the config that is specific to the Wifi Settings 37 | */ 38 | Config.NetworkConfig network = 4; 39 | 40 | /* 41 | * The part of the config that is specific to the Display 42 | */ 43 | Config.DisplayConfig display = 5; 44 | 45 | /* 46 | * The part of the config that is specific to the Lora Radio 47 | */ 48 | Config.LoRaConfig lora = 6; 49 | 50 | /* 51 | * The part of the config that is specific to the Bluetooth settings 52 | */ 53 | Config.BluetoothConfig bluetooth = 7; 54 | 55 | /* 56 | * A version integer used to invalidate old save files when we make 57 | * incompatible changes This integer is set at build time and is private to 58 | * NodeDB.cpp in the device code. 59 | */ 60 | uint32 version = 8; 61 | 62 | /* 63 | * The part of the config that is specific to Security settings 64 | */ 65 | Config.SecurityConfig security = 9; 66 | } 67 | 68 | message LocalModuleConfig { 69 | /* 70 | * The part of the config that is specific to the MQTT module 71 | */ 72 | ModuleConfig.MQTTConfig mqtt = 1; 73 | 74 | /* 75 | * The part of the config that is specific to the Serial module 76 | */ 77 | ModuleConfig.SerialConfig serial = 2; 78 | 79 | /* 80 | * The part of the config that is specific to the ExternalNotification module 81 | */ 82 | ModuleConfig.ExternalNotificationConfig external_notification = 3; 83 | 84 | /* 85 | * The part of the config that is specific to the Store & Forward module 86 | */ 87 | ModuleConfig.StoreForwardConfig store_forward = 4; 88 | 89 | /* 90 | * The part of the config that is specific to the RangeTest module 91 | */ 92 | ModuleConfig.RangeTestConfig range_test = 5; 93 | 94 | /* 95 | * The part of the config that is specific to the Telemetry module 96 | */ 97 | ModuleConfig.TelemetryConfig telemetry = 6; 98 | 99 | /* 100 | * The part of the config that is specific to the Canned Message module 101 | */ 102 | ModuleConfig.CannedMessageConfig canned_message = 7; 103 | 104 | /* 105 | * The part of the config that is specific to the Audio module 106 | */ 107 | ModuleConfig.AudioConfig audio = 9; 108 | 109 | /* 110 | * The part of the config that is specific to the Remote Hardware module 111 | */ 112 | ModuleConfig.RemoteHardwareConfig remote_hardware = 10; 113 | 114 | /* 115 | * The part of the config that is specific to the Neighbor Info module 116 | */ 117 | ModuleConfig.NeighborInfoConfig neighbor_info = 11; 118 | 119 | /* 120 | * The part of the config that is specific to the Ambient Lighting module 121 | */ 122 | ModuleConfig.AmbientLightingConfig ambient_lighting = 12; 123 | 124 | /* 125 | * The part of the config that is specific to the Detection Sensor module 126 | */ 127 | ModuleConfig.DetectionSensorConfig detection_sensor = 13; 128 | 129 | /* 130 | * Paxcounter Config 131 | */ 132 | ModuleConfig.PaxcounterConfig paxcounter = 14; 133 | 134 | /* 135 | * A version integer used to invalidate old save files when we make 136 | * incompatible changes This integer is set at build time and is private to 137 | * NodeDB.cpp in the device code. 138 | */ 139 | uint32 version = 8; 140 | } 141 | -------------------------------------------------------------------------------- /meshtastic/mesh.options: -------------------------------------------------------------------------------- 1 | # options for nanopb 2 | # https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options 3 | 4 | *macaddr max_size:6 fixed_length:true # macaddrs 5 | *id max_size:16 # node id strings 6 | *public_key max_size:32 # public key 7 | 8 | *User.long_name max_size:40 9 | *User.short_name max_size:5 10 | 11 | *RouteDiscovery.route max_count:8 12 | *RouteDiscovery.snr_towards max_count:8 13 | *RouteDiscovery.snr_towards int_size:8 14 | *RouteDiscovery.route_back max_count:8 15 | *RouteDiscovery.snr_back max_count:8 16 | *RouteDiscovery.snr_back int_size:8 17 | 18 | # note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is 19 | # outside of this envelope 20 | *Data.payload max_size:233 21 | *Data.bitfield int_size:8 22 | 23 | *NodeInfo.channel int_size:8 24 | *NodeInfo.hops_away int_size:8 25 | 26 | # Big enough for 1.2.28.568032c-d 27 | *MyNodeInfo.firmware_version max_size:18 28 | *MyNodeInfo.device_id max_size:16 29 | *MyNodeInfo.pio_env max_size:40 30 | 31 | *MyNodeInfo.air_period_tx max_count:8 32 | *MyNodeInfo.air_period_rx max_count:8 33 | 34 | # Note: the actual limit (because of header bytes) on the size of encrypted payloads is 251 bytes, but I use 256 35 | # here because we might need to fill with zeros for padding to encryption block size (16 bytes per block) 36 | *MeshPacket.encrypted max_size:256 37 | *MeshPacket.payload_variant anonymous_oneof:true 38 | *MeshPacket.hop_limit int_size:8 39 | *MeshPacket.hop_start int_size:8 40 | *MeshPacket.channel int_size:8 41 | *MeshPacket.next_hop int_size:8 42 | *MeshPacket.relay_node int_size:8 43 | 44 | *QueueStatus.res int_size:8 45 | *QueueStatus.free int_size:8 46 | *QueueStatus.maxlen int_size:8 47 | 48 | *ToRadio.payload_variant anonymous_oneof:true 49 | 50 | *FromRadio.payload_variant anonymous_oneof:true 51 | 52 | *Routing.variant anonymous_oneof:true 53 | 54 | *LogRecord.message max_size:384 55 | *LogRecord.source max_size:32 56 | 57 | *FileInfo.file_name max_size:228 58 | 59 | *ClientNotification.message max_size:400 60 | 61 | *KeyVerificationNumberInform.remote_longname max_size:40 62 | *KeyVerificationNumberRequest.remote_longname max_size:40 63 | *KeyVerificationFinal.remote_longname max_size:40 64 | *KeyVerificationFinal.verification_characters max_size:10 65 | 66 | *KeyVerification.hash1 max_size:32 67 | *KeyVerification.hash2 max_size:32 68 | 69 | 70 | # MyMessage.name max_size:40 71 | # or fixed_length or fixed_count, or max_count 72 | 73 | #This value may want to be a few bytes smaller to compensate for the parent fields. 74 | *Compressed.data max_size:233 75 | 76 | *Waypoint.name max_size:30 77 | *Waypoint.description max_size:100 78 | 79 | *NeighborInfo.neighbors max_count:10 80 | 81 | *DeviceMetadata.firmware_version max_size:18 82 | 83 | *MqttClientProxyMessage.topic max_size:60 84 | *MqttClientProxyMessage.data max_size:435 85 | *MqttClientProxyMessage.text max_size:435 86 | 87 | *ChunkedPayload.chunk_count int_size:16 88 | *ChunkedPayload.chunk_index int_size:16 89 | *ChunkedPayload.payload_chunk max_size:228 -------------------------------------------------------------------------------- /meshtastic/module_config.options: -------------------------------------------------------------------------------- 1 | *CannedMessageConfig.allow_input_source max_size:16 2 | 3 | *MQTTConfig.address max_size:64 4 | *MQTTConfig.username max_size:64 5 | *MQTTConfig.password max_size:32 6 | *MQTTConfig.root max_size:32 7 | 8 | *AudioConfig.ptt_pin int_size:8 9 | *AudioConfig.i2s_ws int_size:8 10 | *AudioConfig.i2s_sd int_size:8 11 | *AudioConfig.i2s_din int_size:8 12 | *AudioConfig.i2s_sck int_size:8 13 | 14 | *ExternalNotificationConfig.output_vibra int_size:8 15 | *ExternalNotificationConfig.output_buzzer int_size:8 16 | *ExternalNotificationConfig.nag_timeout int_size:16 17 | 18 | *RemoteHardwareConfig.available_pins max_count:4 19 | *RemoteHardwarePin.name max_size:15 20 | *RemoteHardwarePin.gpio_pin int_size:8 21 | 22 | *AmbientLightingConfig.current int_size:8 23 | *AmbientLightingConfig.red int_size:8 24 | *AmbientLightingConfig.green int_size:8 25 | *AmbientLightingConfig.blue int_size:8 26 | 27 | *DetectionSensorConfig.monitor_pin int_size:8 28 | *DetectionSensorConfig.name max_size:20 29 | *DetectionSensorConfig.detection_trigger_type max_size:8 30 | -------------------------------------------------------------------------------- /meshtastic/module_config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "ModuleConfigProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * Module Config 13 | */ 14 | message ModuleConfig { 15 | /* 16 | * MQTT Client Config 17 | */ 18 | message MQTTConfig { 19 | /* 20 | * If a meshtastic node is able to reach the internet it will normally attempt to gateway any channels that are marked as 21 | * is_uplink_enabled or is_downlink_enabled. 22 | */ 23 | bool enabled = 1; 24 | 25 | /* 26 | * The server to use for our MQTT global message gateway feature. 27 | * If not set, the default server will be used 28 | */ 29 | string address = 2; 30 | 31 | /* 32 | * MQTT username to use (most useful for a custom MQTT server). 33 | * If using a custom server, this will be honoured even if empty. 34 | * If using the default server, this will only be honoured if set, otherwise the device will use the default username 35 | */ 36 | string username = 3; 37 | 38 | /* 39 | * MQTT password to use (most useful for a custom MQTT server). 40 | * If using a custom server, this will be honoured even if empty. 41 | * If using the default server, this will only be honoured if set, otherwise the device will use the default password 42 | */ 43 | string password = 4; 44 | 45 | /* 46 | * Whether to send encrypted or decrypted packets to MQTT. 47 | * This parameter is only honoured if you also set server 48 | * (the default official mqtt.meshtastic.org server can handle encrypted packets) 49 | * Decrypted packets may be useful for external systems that want to consume meshtastic packets 50 | */ 51 | bool encryption_enabled = 5; 52 | 53 | /* 54 | * Whether to send / consume json packets on MQTT 55 | */ 56 | bool json_enabled = 6; 57 | 58 | /* 59 | * If true, we attempt to establish a secure connection using TLS 60 | */ 61 | bool tls_enabled = 7; 62 | 63 | /* 64 | * The root topic to use for MQTT messages. Default is "msh". 65 | * This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs 66 | */ 67 | string root = 8; 68 | 69 | /* 70 | * If true, we can use the connected phone / client to proxy messages to MQTT instead of a direct connection 71 | */ 72 | bool proxy_to_client_enabled = 9; 73 | 74 | /* 75 | * If true, we will periodically report unencrypted information about our node to a map via MQTT 76 | */ 77 | bool map_reporting_enabled = 10; 78 | 79 | /* 80 | * Settings for reporting information about our node to a map via MQTT 81 | */ 82 | MapReportSettings map_report_settings = 11; 83 | } 84 | 85 | /* 86 | * Settings for reporting unencrypted information about our node to a map via MQTT 87 | */ 88 | message MapReportSettings { 89 | /* 90 | * How often we should report our info to the map (in seconds) 91 | */ 92 | uint32 publish_interval_secs = 1; 93 | 94 | /* 95 | * Bits of precision for the location sent (default of 32 is full precision). 96 | */ 97 | uint32 position_precision = 2; 98 | 99 | /* 100 | * Whether we have opted-in to report our location to the map 101 | */ 102 | bool should_report_location = 3; 103 | } 104 | 105 | /* 106 | * RemoteHardwareModule Config 107 | */ 108 | message RemoteHardwareConfig { 109 | /* 110 | * Whether the Module is enabled 111 | */ 112 | bool enabled = 1; 113 | 114 | /* 115 | * Whether the Module allows consumers to read / write to pins not defined in available_pins 116 | */ 117 | bool allow_undefined_pin_access = 2; 118 | 119 | /* 120 | * Exposes the available pins to the mesh for reading and writing 121 | */ 122 | repeated RemoteHardwarePin available_pins = 3; 123 | } 124 | 125 | /* 126 | * NeighborInfoModule Config 127 | */ 128 | message NeighborInfoConfig { 129 | /* 130 | * Whether the Module is enabled 131 | */ 132 | bool enabled = 1; 133 | 134 | /* 135 | * Interval in seconds of how often we should try to send our 136 | * Neighbor Info (minimum is 14400, i.e., 4 hours) 137 | */ 138 | uint32 update_interval = 2; 139 | 140 | /* 141 | * Whether in addition to sending it to MQTT and the PhoneAPI, our NeighborInfo should be transmitted over LoRa. 142 | * Note that this is not available on a channel with default key and name. 143 | */ 144 | bool transmit_over_lora = 3; 145 | } 146 | 147 | /* 148 | * Detection Sensor Module Config 149 | */ 150 | message DetectionSensorConfig { 151 | 152 | enum TriggerType { 153 | // Event is triggered if pin is low 154 | LOGIC_LOW = 0; 155 | // Event is triggered if pin is high 156 | LOGIC_HIGH = 1; 157 | // Event is triggered when pin goes high to low 158 | FALLING_EDGE = 2; 159 | // Event is triggered when pin goes low to high 160 | RISING_EDGE = 3; 161 | // Event is triggered on every pin state change, low is considered to be 162 | // "active" 163 | EITHER_EDGE_ACTIVE_LOW = 4; 164 | // Event is triggered on every pin state change, high is considered to be 165 | // "active" 166 | EITHER_EDGE_ACTIVE_HIGH = 5; 167 | } 168 | /* 169 | * Whether the Module is enabled 170 | */ 171 | bool enabled = 1; 172 | 173 | /* 174 | * Interval in seconds of how often we can send a message to the mesh when a 175 | * trigger event is detected 176 | */ 177 | uint32 minimum_broadcast_secs = 2; 178 | 179 | /* 180 | * Interval in seconds of how often we should send a message to the mesh 181 | * with the current state regardless of trigger events When set to 0, only 182 | * trigger events will be broadcasted Works as a sort of status heartbeat 183 | * for peace of mind 184 | */ 185 | uint32 state_broadcast_secs = 3; 186 | 187 | /* 188 | * Send ASCII bell with alert message 189 | * Useful for triggering ext. notification on bell 190 | */ 191 | bool send_bell = 4; 192 | 193 | /* 194 | * Friendly name used to format message sent to mesh 195 | * Example: A name "Motion" would result in a message "Motion detected" 196 | * Maximum length of 20 characters 197 | */ 198 | string name = 5; 199 | 200 | /* 201 | * GPIO pin to monitor for state changes 202 | */ 203 | uint32 monitor_pin = 6; 204 | 205 | /* 206 | * The type of trigger event to be used 207 | */ 208 | TriggerType detection_trigger_type = 7; 209 | 210 | /* 211 | * Whether or not use INPUT_PULLUP mode for GPIO pin 212 | * Only applicable if the board uses pull-up resistors on the pin 213 | */ 214 | bool use_pullup = 8; 215 | } 216 | 217 | /* 218 | * Audio Config for codec2 voice 219 | */ 220 | message AudioConfig { 221 | /* 222 | * Baudrate for codec2 voice 223 | */ 224 | enum Audio_Baud { 225 | CODEC2_DEFAULT = 0; 226 | CODEC2_3200 = 1; 227 | CODEC2_2400 = 2; 228 | CODEC2_1600 = 3; 229 | CODEC2_1400 = 4; 230 | CODEC2_1300 = 5; 231 | CODEC2_1200 = 6; 232 | CODEC2_700 = 7; 233 | CODEC2_700B = 8; 234 | } 235 | 236 | /* 237 | * Whether Audio is enabled 238 | */ 239 | bool codec2_enabled = 1; 240 | 241 | /* 242 | * PTT Pin 243 | */ 244 | uint32 ptt_pin = 2; 245 | 246 | /* 247 | * The audio sample rate to use for codec2 248 | */ 249 | Audio_Baud bitrate = 3; 250 | 251 | /* 252 | * I2S Word Select 253 | */ 254 | uint32 i2s_ws = 4; 255 | 256 | /* 257 | * I2S Data IN 258 | */ 259 | uint32 i2s_sd = 5; 260 | 261 | /* 262 | * I2S Data OUT 263 | */ 264 | uint32 i2s_din = 6; 265 | 266 | /* 267 | * I2S Clock 268 | */ 269 | uint32 i2s_sck = 7; 270 | } 271 | 272 | /* 273 | * Config for the Paxcounter Module 274 | */ 275 | message PaxcounterConfig { 276 | /* 277 | * Enable the Paxcounter Module 278 | */ 279 | bool enabled = 1; 280 | 281 | /* 282 | * Interval in seconds of how often we should try to send our 283 | * metrics to the mesh 284 | */ 285 | 286 | uint32 paxcounter_update_interval = 2; 287 | 288 | /* 289 | * WiFi RSSI threshold. Defaults to -80 290 | */ 291 | int32 wifi_threshold = 3; 292 | 293 | /* 294 | * BLE RSSI threshold. Defaults to -80 295 | */ 296 | int32 ble_threshold = 4; 297 | 298 | } 299 | 300 | /* 301 | * Serial Config 302 | */ 303 | message SerialConfig { 304 | /* 305 | * TODO: REPLACE 306 | */ 307 | enum Serial_Baud { 308 | BAUD_DEFAULT = 0; 309 | BAUD_110 = 1; 310 | BAUD_300 = 2; 311 | BAUD_600 = 3; 312 | BAUD_1200 = 4; 313 | BAUD_2400 = 5; 314 | BAUD_4800 = 6; 315 | BAUD_9600 = 7; 316 | BAUD_19200 = 8; 317 | BAUD_38400 = 9; 318 | BAUD_57600 = 10; 319 | BAUD_115200 = 11; 320 | BAUD_230400 = 12; 321 | BAUD_460800 = 13; 322 | BAUD_576000 = 14; 323 | BAUD_921600 = 15; 324 | } 325 | 326 | /* 327 | * TODO: REPLACE 328 | */ 329 | enum Serial_Mode { 330 | DEFAULT = 0; 331 | SIMPLE = 1; 332 | PROTO = 2; 333 | TEXTMSG = 3; 334 | NMEA = 4; 335 | // NMEA messages specifically tailored for CalTopo 336 | CALTOPO = 5; 337 | // Ecowitt WS85 weather station 338 | WS85 = 6; 339 | // VE.Direct is a serial protocol used by Victron Energy products 340 | // https://beta.ivc.no/wiki/index.php/Victron_VE_Direct_DIY_Cable 341 | VE_DIRECT = 7; 342 | } 343 | 344 | /* 345 | * Preferences for the SerialModule 346 | */ 347 | bool enabled = 1; 348 | 349 | /* 350 | * TODO: REPLACE 351 | */ 352 | bool echo = 2; 353 | 354 | /* 355 | * RX pin (should match Arduino gpio pin number) 356 | */ 357 | uint32 rxd = 3; 358 | 359 | /* 360 | * TX pin (should match Arduino gpio pin number) 361 | */ 362 | uint32 txd = 4; 363 | 364 | /* 365 | * Serial baud rate 366 | */ 367 | Serial_Baud baud = 5; 368 | 369 | /* 370 | * TODO: REPLACE 371 | */ 372 | uint32 timeout = 6; 373 | 374 | /* 375 | * Mode for serial module operation 376 | */ 377 | Serial_Mode mode = 7; 378 | 379 | /* 380 | * Overrides the platform's defacto Serial port instance to use with Serial module config settings 381 | * This is currently only usable in output modes like NMEA / CalTopo and may behave strangely or not work at all in other modes 382 | * Existing logging over the Serial Console will still be present 383 | */ 384 | bool override_console_serial_port = 8; 385 | } 386 | 387 | /* 388 | * External Notifications Config 389 | */ 390 | message ExternalNotificationConfig { 391 | /* 392 | * Enable the ExternalNotificationModule 393 | */ 394 | bool enabled = 1; 395 | 396 | /* 397 | * When using in On/Off mode, keep the output on for this many 398 | * milliseconds. Default 1000ms (1 second). 399 | */ 400 | uint32 output_ms = 2; 401 | 402 | /* 403 | * Define the output pin GPIO setting Defaults to 404 | * EXT_NOTIFY_OUT if set for the board. 405 | * In standalone devices this pin should drive the LED to match the UI. 406 | */ 407 | uint32 output = 3; 408 | 409 | /* 410 | * Optional: Define a secondary output pin for a vibra motor 411 | * This is used in standalone devices to match the UI. 412 | */ 413 | uint32 output_vibra = 8; 414 | 415 | /* 416 | * Optional: Define a tertiary output pin for an active buzzer 417 | * This is used in standalone devices to to match the UI. 418 | */ 419 | uint32 output_buzzer = 9; 420 | 421 | /* 422 | * IF this is true, the 'output' Pin will be pulled active high, false 423 | * means active low. 424 | */ 425 | bool active = 4; 426 | 427 | /* 428 | * True: Alert when a text message arrives (output) 429 | */ 430 | bool alert_message = 5; 431 | 432 | /* 433 | * True: Alert when a text message arrives (output_vibra) 434 | */ 435 | bool alert_message_vibra = 10; 436 | 437 | /* 438 | * True: Alert when a text message arrives (output_buzzer) 439 | */ 440 | bool alert_message_buzzer = 11; 441 | 442 | /* 443 | * True: Alert when the bell character is received (output) 444 | */ 445 | bool alert_bell = 6; 446 | 447 | /* 448 | * True: Alert when the bell character is received (output_vibra) 449 | */ 450 | bool alert_bell_vibra = 12; 451 | 452 | /* 453 | * True: Alert when the bell character is received (output_buzzer) 454 | */ 455 | bool alert_bell_buzzer = 13; 456 | 457 | /* 458 | * use a PWM output instead of a simple on/off output. This will ignore 459 | * the 'output', 'output_ms' and 'active' settings and use the 460 | * device.buzzer_gpio instead. 461 | */ 462 | bool use_pwm = 7; 463 | 464 | /* 465 | * The notification will toggle with 'output_ms' for this time of seconds. 466 | * Default is 0 which means don't repeat at all. 60 would mean blink 467 | * and/or beep for 60 seconds 468 | */ 469 | uint32 nag_timeout = 14; 470 | 471 | /* 472 | * When true, enables devices with native I2S audio output to use the RTTTL over speaker like a buzzer 473 | * T-Watch S3 and T-Deck for example have this capability 474 | */ 475 | bool use_i2s_as_buzzer = 15; 476 | } 477 | 478 | /* 479 | * Store and Forward Module Config 480 | */ 481 | message StoreForwardConfig { 482 | /* 483 | * Enable the Store and Forward Module 484 | */ 485 | bool enabled = 1; 486 | 487 | /* 488 | * TODO: REPLACE 489 | */ 490 | bool heartbeat = 2; 491 | 492 | /* 493 | * TODO: REPLACE 494 | */ 495 | uint32 records = 3; 496 | 497 | /* 498 | * TODO: REPLACE 499 | */ 500 | uint32 history_return_max = 4; 501 | 502 | /* 503 | * TODO: REPLACE 504 | */ 505 | uint32 history_return_window = 5; 506 | 507 | /* 508 | * Set to true to let this node act as a server that stores received messages and resends them upon request. 509 | */ 510 | bool is_server = 6; 511 | } 512 | 513 | /* 514 | * Preferences for the RangeTestModule 515 | */ 516 | message RangeTestConfig { 517 | /* 518 | * Enable the Range Test Module 519 | */ 520 | bool enabled = 1; 521 | 522 | /* 523 | * Send out range test messages from this node 524 | */ 525 | uint32 sender = 2; 526 | 527 | /* 528 | * Bool value indicating that this node should save a RangeTest.csv file. 529 | * ESP32 Only 530 | */ 531 | bool save = 3; 532 | } 533 | 534 | /* 535 | * Configuration for both device and environment metrics 536 | */ 537 | message TelemetryConfig { 538 | /* 539 | * Interval in seconds of how often we should try to send our 540 | * device metrics to the mesh 541 | */ 542 | uint32 device_update_interval = 1; 543 | 544 | /* 545 | * Interval in seconds of how often we should try to send our 546 | * environment measurements to the mesh 547 | */ 548 | 549 | uint32 environment_update_interval = 2; 550 | 551 | /* 552 | * Preferences for the Telemetry Module (Environment) 553 | * Enable/Disable the telemetry measurement module measurement collection 554 | */ 555 | bool environment_measurement_enabled = 3; 556 | 557 | /* 558 | * Enable/Disable the telemetry measurement module on-device display 559 | */ 560 | bool environment_screen_enabled = 4; 561 | 562 | /* 563 | * We'll always read the sensor in Celsius, but sometimes we might want to 564 | * display the results in Fahrenheit as a "user preference". 565 | */ 566 | bool environment_display_fahrenheit = 5; 567 | 568 | /* 569 | * Enable/Disable the air quality metrics 570 | */ 571 | bool air_quality_enabled = 6; 572 | 573 | /* 574 | * Interval in seconds of how often we should try to send our 575 | * air quality metrics to the mesh 576 | */ 577 | uint32 air_quality_interval = 7; 578 | 579 | /* 580 | * Enable/disable Power metrics 581 | */ 582 | bool power_measurement_enabled = 8; 583 | 584 | /* 585 | * Interval in seconds of how often we should try to send our 586 | * power metrics to the mesh 587 | */ 588 | uint32 power_update_interval = 9; 589 | 590 | /* 591 | * Enable/Disable the power measurement module on-device display 592 | */ 593 | bool power_screen_enabled = 10; 594 | 595 | /* 596 | * Preferences for the (Health) Telemetry Module 597 | * Enable/Disable the telemetry measurement module measurement collection 598 | */ 599 | bool health_measurement_enabled = 11; 600 | 601 | /* 602 | * Interval in seconds of how often we should try to send our 603 | * health metrics to the mesh 604 | */ 605 | uint32 health_update_interval = 12; 606 | 607 | /* 608 | * Enable/Disable the health telemetry module on-device display 609 | */ 610 | bool health_screen_enabled = 13; 611 | } 612 | 613 | /* 614 | * Canned Messages Module Config 615 | */ 616 | message CannedMessageConfig { 617 | /* 618 | * TODO: REPLACE 619 | */ 620 | enum InputEventChar { 621 | /* 622 | * TODO: REPLACE 623 | */ 624 | NONE = 0; 625 | 626 | /* 627 | * TODO: REPLACE 628 | */ 629 | UP = 17; 630 | 631 | /* 632 | * TODO: REPLACE 633 | */ 634 | DOWN = 18; 635 | 636 | /* 637 | * TODO: REPLACE 638 | */ 639 | LEFT = 19; 640 | 641 | /* 642 | * TODO: REPLACE 643 | */ 644 | RIGHT = 20; 645 | 646 | /* 647 | * '\n' 648 | */ 649 | SELECT = 10; 650 | 651 | /* 652 | * TODO: REPLACE 653 | */ 654 | BACK = 27; 655 | 656 | /* 657 | * TODO: REPLACE 658 | */ 659 | CANCEL = 24; 660 | } 661 | 662 | /* 663 | * Enable the rotary encoder #1. This is a 'dumb' encoder sending pulses on both A and B pins while rotating. 664 | */ 665 | bool rotary1_enabled = 1; 666 | 667 | /* 668 | * GPIO pin for rotary encoder A port. 669 | */ 670 | uint32 inputbroker_pin_a = 2; 671 | 672 | /* 673 | * GPIO pin for rotary encoder B port. 674 | */ 675 | uint32 inputbroker_pin_b = 3; 676 | 677 | /* 678 | * GPIO pin for rotary encoder Press port. 679 | */ 680 | uint32 inputbroker_pin_press = 4; 681 | 682 | /* 683 | * Generate input event on CW of this kind. 684 | */ 685 | InputEventChar inputbroker_event_cw = 5; 686 | 687 | /* 688 | * Generate input event on CCW of this kind. 689 | */ 690 | InputEventChar inputbroker_event_ccw = 6; 691 | 692 | /* 693 | * Generate input event on Press of this kind. 694 | */ 695 | InputEventChar inputbroker_event_press = 7; 696 | 697 | /* 698 | * Enable the Up/Down/Select input device. Can be RAK rotary encoder or 3 buttons. Uses the a/b/press definitions from inputbroker. 699 | */ 700 | bool updown1_enabled = 8; 701 | 702 | /* 703 | * Enable/disable CannedMessageModule. 704 | */ 705 | bool enabled = 9; 706 | 707 | /* 708 | * Input event origin accepted by the canned message module. 709 | * Can be e.g. "rotEnc1", "upDownEnc1", "scanAndSelect", "cardkb", "serialkb", or keyword "_any" 710 | */ 711 | string allow_input_source = 10; 712 | 713 | /* 714 | * CannedMessageModule also sends a bell character with the messages. 715 | * ExternalNotificationModule can benefit from this feature. 716 | */ 717 | bool send_bell = 11; 718 | } 719 | 720 | /* 721 | Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. 722 | Initially created for the RAK14001 RGB LED module. 723 | */ 724 | message AmbientLightingConfig { 725 | /* 726 | * Sets LED to on or off. 727 | */ 728 | bool led_state = 1; 729 | 730 | /* 731 | * Sets the current for the LED output. Default is 10. 732 | */ 733 | uint32 current = 2; 734 | 735 | /* 736 | * Sets the red LED level. Values are 0-255. 737 | */ 738 | uint32 red = 3; 739 | 740 | /* 741 | * Sets the green LED level. Values are 0-255. 742 | */ 743 | uint32 green = 4; 744 | 745 | /* 746 | * Sets the blue LED level. Values are 0-255. 747 | */ 748 | uint32 blue = 5; 749 | } 750 | 751 | /* 752 | * TODO: REPLACE 753 | */ 754 | oneof payload_variant { 755 | /* 756 | * TODO: REPLACE 757 | */ 758 | MQTTConfig mqtt = 1; 759 | 760 | /* 761 | * TODO: REPLACE 762 | */ 763 | SerialConfig serial = 2; 764 | 765 | /* 766 | * TODO: REPLACE 767 | */ 768 | ExternalNotificationConfig external_notification = 3; 769 | 770 | /* 771 | * TODO: REPLACE 772 | */ 773 | StoreForwardConfig store_forward = 4; 774 | 775 | /* 776 | * TODO: REPLACE 777 | */ 778 | RangeTestConfig range_test = 5; 779 | 780 | /* 781 | * TODO: REPLACE 782 | */ 783 | TelemetryConfig telemetry = 6; 784 | 785 | /* 786 | * TODO: REPLACE 787 | */ 788 | CannedMessageConfig canned_message = 7; 789 | 790 | /* 791 | * TODO: REPLACE 792 | */ 793 | AudioConfig audio = 8; 794 | 795 | /* 796 | * TODO: REPLACE 797 | */ 798 | RemoteHardwareConfig remote_hardware = 9; 799 | 800 | /* 801 | * TODO: REPLACE 802 | */ 803 | NeighborInfoConfig neighbor_info = 10; 804 | 805 | /* 806 | * TODO: REPLACE 807 | */ 808 | AmbientLightingConfig ambient_lighting = 11; 809 | 810 | /* 811 | * TODO: REPLACE 812 | */ 813 | DetectionSensorConfig detection_sensor = 12; 814 | 815 | /* 816 | * TODO: REPLACE 817 | */ 818 | PaxcounterConfig paxcounter = 13; 819 | } 820 | } 821 | 822 | /* 823 | * A GPIO pin definition for remote hardware module 824 | */ 825 | message RemoteHardwarePin { 826 | /* 827 | * GPIO Pin number (must match Arduino) 828 | */ 829 | uint32 gpio_pin = 1; 830 | 831 | /* 832 | * Name for the GPIO pin (i.e. Front gate, mailbox, etc) 833 | */ 834 | string name = 2; 835 | 836 | /* 837 | * Type of GPIO access available to consumers on the mesh 838 | */ 839 | RemoteHardwarePinType type = 3; 840 | } 841 | 842 | enum RemoteHardwarePinType { 843 | /* 844 | * Unset/unused 845 | */ 846 | UNKNOWN = 0; 847 | 848 | /* 849 | * GPIO pin can be read (if it is high / low) 850 | */ 851 | DIGITAL_READ = 1; 852 | 853 | /* 854 | * GPIO pin can be written to (high / low) 855 | */ 856 | DIGITAL_WRITE = 2; 857 | } 858 | -------------------------------------------------------------------------------- /meshtastic/mqtt.options: -------------------------------------------------------------------------------- 1 | *ServiceEnvelope.packet type:FT_POINTER 2 | *ServiceEnvelope.channel_id type:FT_POINTER 3 | *ServiceEnvelope.gateway_id type:FT_POINTER 4 | 5 | *MapReport.long_name max_size:40 6 | *MapReport.short_name max_size:5 7 | *MapReport.firmware_version max_size:18 8 | *MapReport.num_online_local_nodes int_size:16 -------------------------------------------------------------------------------- /meshtastic/mqtt.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | import "meshtastic/config.proto"; 6 | import "meshtastic/mesh.proto"; 7 | 8 | option csharp_namespace = "Meshtastic.Protobufs"; 9 | option go_package = "github.com/meshtastic/go/generated"; 10 | option java_outer_classname = "MQTTProtos"; 11 | option java_package = "com.geeksville.mesh"; 12 | option swift_prefix = ""; 13 | 14 | /* 15 | * This message wraps a MeshPacket with extra metadata about the sender and how it arrived. 16 | */ 17 | message ServiceEnvelope { 18 | /* 19 | * The (probably encrypted) packet 20 | */ 21 | MeshPacket packet = 1; 22 | 23 | /* 24 | * The global channel ID it was sent on 25 | */ 26 | string channel_id = 2; 27 | 28 | /* 29 | * The sending gateway node ID. Can we use this to authenticate/prevent fake 30 | * nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as 31 | * the globally trusted nodenum 32 | */ 33 | string gateway_id = 3; 34 | } 35 | 36 | /* 37 | * Information about a node intended to be reported unencrypted to a map using MQTT. 38 | */ 39 | message MapReport { 40 | /* 41 | * A full name for this user, i.e. "Kevin Hester" 42 | */ 43 | string long_name = 1; 44 | 45 | /* 46 | * A VERY short name, ideally two characters. 47 | * Suitable for a tiny OLED screen 48 | */ 49 | string short_name = 2; 50 | 51 | /* 52 | * Role of the node that applies specific settings for a particular use-case 53 | */ 54 | Config.DeviceConfig.Role role = 3; 55 | 56 | /* 57 | * Hardware model of the node, i.e. T-Beam, Heltec V3, etc... 58 | */ 59 | HardwareModel hw_model = 4; 60 | 61 | /* 62 | * Device firmware version string 63 | */ 64 | string firmware_version = 5; 65 | 66 | /* 67 | * The region code for the radio (US, CN, EU433, etc...) 68 | */ 69 | Config.LoRaConfig.RegionCode region = 6; 70 | 71 | /* 72 | * Modem preset used by the radio (LongFast, MediumSlow, etc...) 73 | */ 74 | Config.LoRaConfig.ModemPreset modem_preset = 7; 75 | 76 | /* 77 | * Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...) 78 | * and it uses the default frequency slot given the region and modem preset. 79 | */ 80 | bool has_default_channel = 8; 81 | 82 | /* 83 | * Latitude: multiply by 1e-7 to get degrees in floating point 84 | */ 85 | sfixed32 latitude_i = 9; 86 | 87 | /* 88 | * Longitude: multiply by 1e-7 to get degrees in floating point 89 | */ 90 | sfixed32 longitude_i = 10; 91 | 92 | /* 93 | * Altitude in meters above MSL 94 | */ 95 | int32 altitude = 11; 96 | 97 | /* 98 | * Indicates the bits of precision for latitude and longitude set by the sending node 99 | */ 100 | uint32 position_precision = 12; 101 | 102 | /* 103 | * Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT) 104 | */ 105 | uint32 num_online_local_nodes = 13; 106 | 107 | /* 108 | * User has opted in to share their location (map report) with the mqtt server 109 | * Controlled by map_report.should_report_location 110 | */ 111 | bool has_opted_report_location = 14; 112 | } 113 | -------------------------------------------------------------------------------- /meshtastic/paxcount.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "PaxcountProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * TODO: REPLACE 13 | */ 14 | message Paxcount { 15 | /* 16 | * seen Wifi devices 17 | */ 18 | uint32 wifi = 1; 19 | 20 | /* 21 | * Seen BLE devices 22 | */ 23 | uint32 ble = 2; 24 | 25 | /* 26 | * Uptime in seconds 27 | */ 28 | uint32 uptime = 3; 29 | } 30 | -------------------------------------------------------------------------------- /meshtastic/portnums.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "Portnums"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a 13 | * unique 'portnum' for their application. 14 | * If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to this 15 | * master table. 16 | * PortNums should be assigned in the following range: 17 | * 0-63 Core Meshtastic use, do not use for third party apps 18 | * 64-127 Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application 19 | * 256-511 Use one of these portnums for your private applications that you don't want to register publically 20 | * All other values are reserved. 21 | * Note: This was formerly a Type enum named 'typ' with the same id # 22 | * We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. 23 | * This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. 24 | */ 25 | enum PortNum { 26 | /* 27 | * Deprecated: do not use in new code (formerly called OPAQUE) 28 | * A message sent from a device outside of the mesh, in a form the mesh does not understand 29 | * NOTE: This must be 0, because it is documented in IMeshService.aidl to be so 30 | * ENCODING: binary undefined 31 | */ 32 | UNKNOWN_APP = 0; 33 | 34 | /* 35 | * A simple UTF-8 text message, which even the little micros in the mesh 36 | * can understand and show on their screen eventually in some circumstances 37 | * even signal might send messages in this form (see below) 38 | * ENCODING: UTF-8 Plaintext (?) 39 | */ 40 | TEXT_MESSAGE_APP = 1; 41 | 42 | /* 43 | * Reserved for built-in GPIO/example app. 44 | * See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number 45 | * ENCODING: Protobuf 46 | */ 47 | REMOTE_HARDWARE_APP = 2; 48 | 49 | /* 50 | * The built-in position messaging app. 51 | * Payload is a Position message. 52 | * ENCODING: Protobuf 53 | */ 54 | POSITION_APP = 3; 55 | 56 | /* 57 | * The built-in user info app. 58 | * Payload is a User message. 59 | * ENCODING: Protobuf 60 | */ 61 | NODEINFO_APP = 4; 62 | 63 | /* 64 | * Protocol control packets for mesh protocol use. 65 | * Payload is a Routing message. 66 | * ENCODING: Protobuf 67 | */ 68 | ROUTING_APP = 5; 69 | 70 | /* 71 | * Admin control packets. 72 | * Payload is a AdminMessage message. 73 | * ENCODING: Protobuf 74 | */ 75 | ADMIN_APP = 6; 76 | 77 | /* 78 | * Compressed TEXT_MESSAGE payloads. 79 | * ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression 80 | * NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed 81 | * payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress 82 | * any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP. 83 | */ 84 | TEXT_MESSAGE_COMPRESSED_APP = 7; 85 | 86 | /* 87 | * Waypoint payloads. 88 | * Payload is a Waypoint message. 89 | * ENCODING: Protobuf 90 | */ 91 | WAYPOINT_APP = 8; 92 | 93 | /* 94 | * Audio Payloads. 95 | * Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now 96 | * ENCODING: codec2 audio frames 97 | * NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate. 98 | * This marker comes from the 'moduleConfig.audio.bitrate' enum minus one. 99 | */ 100 | AUDIO_APP = 9; 101 | 102 | /* 103 | * Same as Text Message but originating from Detection Sensor Module. 104 | * NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 105 | */ 106 | DETECTION_SENSOR_APP = 10; 107 | 108 | /* 109 | * Same as Text Message but used for critical alerts. 110 | */ 111 | ALERT_APP = 11; 112 | 113 | /* 114 | * Module/port for handling key verification requests. 115 | */ 116 | KEY_VERIFICATION_APP = 12; 117 | 118 | /* 119 | * Provides a 'ping' service that replies to any packet it receives. 120 | * Also serves as a small example module. 121 | * ENCODING: ASCII Plaintext 122 | */ 123 | REPLY_APP = 32; 124 | 125 | /* 126 | * Used for the python IP tunnel feature 127 | * ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on. 128 | */ 129 | IP_TUNNEL_APP = 33; 130 | 131 | /* 132 | * Paxcounter lib included in the firmware 133 | * ENCODING: protobuf 134 | */ 135 | PAXCOUNTER_APP = 34; 136 | 137 | /* 138 | * Provides a hardware serial interface to send and receive from the Meshtastic network. 139 | * Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic 140 | * network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network. 141 | * Maximum packet size of 240 bytes. 142 | * Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp. 143 | * ENCODING: binary undefined 144 | */ 145 | SERIAL_APP = 64; 146 | 147 | /* 148 | * STORE_FORWARD_APP (Work in Progress) 149 | * Maintained by Jm Casler (MC Hamster) : jm@casler.org 150 | * ENCODING: Protobuf 151 | */ 152 | STORE_FORWARD_APP = 65; 153 | 154 | /* 155 | * Optional port for messages for the range test module. 156 | * ENCODING: ASCII Plaintext 157 | * NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9 158 | */ 159 | RANGE_TEST_APP = 66; 160 | 161 | /* 162 | * Provides a format to send and receive telemetry data from the Meshtastic network. 163 | * Maintained by Charles Crossan (crossan007) : crossan007@gmail.com 164 | * ENCODING: Protobuf 165 | */ 166 | TELEMETRY_APP = 67; 167 | 168 | /* 169 | * Experimental tools for estimating node position without a GPS 170 | * Maintained by Github user a-f-G-U-C (a Meshtastic contributor) 171 | * Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS 172 | * ENCODING: arrays of int64 fields 173 | */ 174 | ZPS_APP = 68; 175 | 176 | /* 177 | * Used to let multiple instances of Linux native applications communicate 178 | * as if they did using their LoRa chip. 179 | * Maintained by GitHub user GUVWAF. 180 | * Project files at https://github.com/GUVWAF/Meshtasticator 181 | * ENCODING: Protobuf (?) 182 | */ 183 | SIMULATOR_APP = 69; 184 | 185 | /* 186 | * Provides a traceroute functionality to show the route a packet towards 187 | * a certain destination would take on the mesh. Contains a RouteDiscovery message as payload. 188 | * ENCODING: Protobuf 189 | */ 190 | TRACEROUTE_APP = 70; 191 | 192 | /* 193 | * Aggregates edge info for the network by sending out a list of each node's neighbors 194 | * ENCODING: Protobuf 195 | */ 196 | NEIGHBORINFO_APP = 71; 197 | 198 | /* 199 | * ATAK Plugin 200 | * Portnum for payloads from the official Meshtastic ATAK plugin 201 | */ 202 | ATAK_PLUGIN = 72; 203 | 204 | /* 205 | * Provides unencrypted information about a node for consumption by a map via MQTT 206 | */ 207 | MAP_REPORT_APP = 73; 208 | 209 | /* 210 | * PowerStress based monitoring support (for automated power consumption testing) 211 | */ 212 | POWERSTRESS_APP = 74; 213 | 214 | /* 215 | * Reticulum Network Stack Tunnel App 216 | * ENCODING: Fragmented RNS Packet. Handled by Meshtastic RNS interface 217 | */ 218 | RETICULUM_TUNNEL_APP = 76; 219 | 220 | /* 221 | * Private applications should use portnums >= 256. 222 | * To simplify initial development and testing you can use "PRIVATE_APP" 223 | * in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh)) 224 | */ 225 | PRIVATE_APP = 256; 226 | 227 | /* 228 | * ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder 229 | * ENCODING: libcotshrink 230 | */ 231 | ATAK_FORWARDER = 257; 232 | 233 | /* 234 | * Currently we limit port nums to no higher than this value 235 | */ 236 | MAX = 511; 237 | } 238 | -------------------------------------------------------------------------------- /meshtastic/powermon.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option csharp_namespace = "Meshtastic.Protobufs"; 4 | option go_package = "github.com/meshtastic/go/generated"; 5 | option java_outer_classname = "PowerMonProtos"; 6 | option java_package = "com.geeksville.mesh"; 7 | option swift_prefix = ""; 8 | 9 | package meshtastic; 10 | 11 | /* Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). 12 | But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) 13 | */ 14 | message PowerMon { 15 | /* Any significant power changing event in meshtastic should be tagged with a powermon state transition. 16 | If you are making new meshtastic features feel free to add new entries at the end of this definition. 17 | */ 18 | enum State { 19 | None = 0; 20 | 21 | CPU_DeepSleep = 0x01; 22 | CPU_LightSleep = 0x02; 23 | 24 | /* 25 | The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only 26 | occasionally. In cases where that rail has multiple devices on it we usually want to have logging on 27 | the state of that rail as an independent record. 28 | For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen. 29 | 30 | The log messages will be short and complete (see PowerMon.Event in the protobufs for details). 31 | something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states. 32 | (We use a bitmask for states so that if a log message gets lost it won't be fatal) 33 | */ 34 | Vext1_On = 0x04; 35 | 36 | Lora_RXOn = 0x08; 37 | Lora_TXOn = 0x10; 38 | Lora_RXActive = 0x20; 39 | BT_On = 0x40; 40 | LED_On = 0x80; 41 | 42 | Screen_On = 0x100; 43 | Screen_Drawing = 0x200; 44 | Wifi_On = 0x400; 45 | 46 | /* 47 | GPS is actively trying to find our location 48 | See GPSPowerState for more details 49 | */ 50 | GPS_Active = 0x800; 51 | } 52 | } 53 | 54 | 55 | /* 56 | * PowerStress testing support via the C++ PowerStress module 57 | */ 58 | message PowerStressMessage { 59 | /* 60 | * What operation would we like the UUT to perform. 61 | note: senders should probably set want_response in their request packets, so that they can know when the state 62 | machine has started processing their request 63 | */ 64 | enum Opcode { 65 | /* 66 | * Unset/unused 67 | */ 68 | UNSET = 0; 69 | 70 | PRINT_INFO = 1; // Print board version slog and send an ack that we are alive and ready to process commands 71 | FORCE_QUIET = 2; // Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation) 72 | END_QUIET = 3; // Stop powerstress processing - probably by just rebooting the board 73 | 74 | SCREEN_ON = 16; // Turn the screen on 75 | SCREEN_OFF = 17; // Turn the screen off 76 | 77 | CPU_IDLE = 32; // Let the CPU run but we assume mostly idling for num_seconds 78 | CPU_DEEPSLEEP = 33; // Force deep sleep for FIXME seconds 79 | CPU_FULLON = 34; // Spin the CPU as fast as possible for num_seconds 80 | 81 | LED_ON = 48; // Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes) 82 | LED_OFF = 49; // Force the LED off for num_seconds 83 | 84 | LORA_OFF = 64; // Completely turn off the LORA radio for num_seconds 85 | LORA_TX = 65; // Send Lora packets for num_seconds 86 | LORA_RX = 66; // Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel) 87 | 88 | BT_OFF = 80; // Turn off the BT radio for num_seconds 89 | BT_ON = 81; // Turn on the BT radio for num_seconds 90 | 91 | WIFI_OFF = 96; // Turn off the WIFI radio for num_seconds 92 | WIFI_ON = 97; // Turn on the WIFI radio for num_seconds 93 | 94 | GPS_OFF = 112; // Turn off the GPS radio for num_seconds 95 | GPS_ON = 113; // Turn on the GPS radio for num_seconds 96 | } 97 | 98 | /* 99 | * What type of HardwareMessage is this? 100 | */ 101 | Opcode cmd = 1; 102 | 103 | float num_seconds = 2; 104 | } 105 | -------------------------------------------------------------------------------- /meshtastic/remote_hardware.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "RemoteHardware"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * An example app to show off the module system. This message is used for 13 | * REMOTE_HARDWARE_APP PortNums. 14 | * Also provides easy remote access to any GPIO. 15 | * In the future other remote hardware operations can be added based on user interest 16 | * (i.e. serial output, spi/i2c input/output). 17 | * FIXME - currently this feature is turned on by default which is dangerous 18 | * because no security yet (beyond the channel mechanism). 19 | * It should be off by default and then protected based on some TBD mechanism 20 | * (a special channel once multichannel support is included?) 21 | */ 22 | message HardwareMessage { 23 | /* 24 | * TODO: REPLACE 25 | */ 26 | enum Type { 27 | /* 28 | * Unset/unused 29 | */ 30 | UNSET = 0; 31 | 32 | /* 33 | * Set gpio gpios based on gpio_mask/gpio_value 34 | */ 35 | WRITE_GPIOS = 1; 36 | 37 | /* 38 | * We are now interested in watching the gpio_mask gpios. 39 | * If the selected gpios change, please broadcast GPIOS_CHANGED. 40 | * Will implicitly change the gpios requested to be INPUT gpios. 41 | */ 42 | WATCH_GPIOS = 2; 43 | 44 | /* 45 | * The gpios listed in gpio_mask have changed, the new values are listed in gpio_value 46 | */ 47 | GPIOS_CHANGED = 3; 48 | 49 | /* 50 | * Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated 51 | */ 52 | READ_GPIOS = 4; 53 | 54 | /* 55 | * A reply to READ_GPIOS. gpio_mask and gpio_value will be populated 56 | */ 57 | READ_GPIOS_REPLY = 5; 58 | } 59 | 60 | /* 61 | * What type of HardwareMessage is this? 62 | */ 63 | Type type = 1; 64 | 65 | /* 66 | * What gpios are we changing. Not used for all MessageTypes, see MessageType for details 67 | */ 68 | uint64 gpio_mask = 2; 69 | 70 | /* 71 | * For gpios that were listed in gpio_mask as valid, what are the signal levels for those gpios. 72 | * Not used for all MessageTypes, see MessageType for details 73 | */ 74 | uint64 gpio_value = 3; 75 | } 76 | -------------------------------------------------------------------------------- /meshtastic/rtttl.options: -------------------------------------------------------------------------------- 1 | *RTTTLConfig.ringtone max_size:231 2 | -------------------------------------------------------------------------------- /meshtastic/rtttl.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "RTTTLConfigProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * Canned message module configuration. 13 | */ 14 | message RTTTLConfig { 15 | /* 16 | * Ringtone for PWM Buzzer in RTTTL Format. 17 | */ 18 | string ringtone = 1; 19 | } 20 | -------------------------------------------------------------------------------- /meshtastic/storeforward.options: -------------------------------------------------------------------------------- 1 | *StoreAndForward.text max_size:233 -------------------------------------------------------------------------------- /meshtastic/storeforward.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "StoreAndForwardProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * TODO: REPLACE 13 | */ 14 | message StoreAndForward { 15 | /* 16 | * 001 - 063 = From Router 17 | * 064 - 127 = From Client 18 | */ 19 | enum RequestResponse { 20 | /* 21 | * Unset/unused 22 | */ 23 | UNSET = 0; 24 | 25 | /* 26 | * Router is an in error state. 27 | */ 28 | ROUTER_ERROR = 1; 29 | 30 | /* 31 | * Router heartbeat 32 | */ 33 | ROUTER_HEARTBEAT = 2; 34 | 35 | /* 36 | * Router has requested the client respond. This can work as a 37 | * "are you there" message. 38 | */ 39 | ROUTER_PING = 3; 40 | 41 | /* 42 | * The response to a "Ping" 43 | */ 44 | ROUTER_PONG = 4; 45 | 46 | /* 47 | * Router is currently busy. Please try again later. 48 | */ 49 | ROUTER_BUSY = 5; 50 | 51 | /* 52 | * Router is responding to a request for history. 53 | */ 54 | ROUTER_HISTORY = 6; 55 | 56 | /* 57 | * Router is responding to a request for stats. 58 | */ 59 | ROUTER_STATS = 7; 60 | 61 | /* 62 | * Router sends a text message from its history that was a direct message. 63 | */ 64 | ROUTER_TEXT_DIRECT = 8; 65 | 66 | /* 67 | * Router sends a text message from its history that was a broadcast. 68 | */ 69 | ROUTER_TEXT_BROADCAST = 9; 70 | 71 | /* 72 | * Client is an in error state. 73 | */ 74 | CLIENT_ERROR = 64; 75 | 76 | /* 77 | * Client has requested a replay from the router. 78 | */ 79 | CLIENT_HISTORY = 65; 80 | 81 | /* 82 | * Client has requested stats from the router. 83 | */ 84 | CLIENT_STATS = 66; 85 | 86 | /* 87 | * Client has requested the router respond. This can work as a 88 | * "are you there" message. 89 | */ 90 | CLIENT_PING = 67; 91 | 92 | /* 93 | * The response to a "Ping" 94 | */ 95 | CLIENT_PONG = 68; 96 | 97 | /* 98 | * Client has requested that the router abort processing the client's request 99 | */ 100 | CLIENT_ABORT = 106; 101 | } 102 | 103 | /* 104 | * TODO: REPLACE 105 | */ 106 | message Statistics { 107 | /* 108 | * Number of messages we have ever seen 109 | */ 110 | uint32 messages_total = 1; 111 | 112 | /* 113 | * Number of messages we have currently saved our history. 114 | */ 115 | uint32 messages_saved = 2; 116 | 117 | /* 118 | * Maximum number of messages we will save 119 | */ 120 | uint32 messages_max = 3; 121 | 122 | /* 123 | * Router uptime in seconds 124 | */ 125 | uint32 up_time = 4; 126 | 127 | /* 128 | * Number of times any client sent a request to the S&F. 129 | */ 130 | uint32 requests = 5; 131 | 132 | /* 133 | * Number of times the history was requested. 134 | */ 135 | uint32 requests_history = 6; 136 | 137 | /* 138 | * Is the heartbeat enabled on the server? 139 | */ 140 | bool heartbeat = 7; 141 | 142 | /* 143 | * Maximum number of messages the server will return. 144 | */ 145 | uint32 return_max = 8; 146 | 147 | /* 148 | * Maximum history window in minutes the server will return messages from. 149 | */ 150 | uint32 return_window = 9; 151 | } 152 | 153 | /* 154 | * TODO: REPLACE 155 | */ 156 | message History { 157 | /* 158 | * Number of that will be sent to the client 159 | */ 160 | uint32 history_messages = 1; 161 | 162 | /* 163 | * The window of messages that was used to filter the history client requested 164 | */ 165 | uint32 window = 2; 166 | 167 | /* 168 | * Index in the packet history of the last message sent in a previous request to the server. 169 | * Will be sent to the client before sending the history and can be set in a subsequent request to avoid getting packets the server already sent to the client. 170 | */ 171 | uint32 last_request = 3; 172 | } 173 | 174 | /* 175 | * TODO: REPLACE 176 | */ 177 | message Heartbeat { 178 | /* 179 | * Period in seconds that the heartbeat is sent out that will be sent to the client 180 | */ 181 | uint32 period = 1; 182 | 183 | /* 184 | * If set, this is not the primary Store & Forward router on the mesh 185 | */ 186 | uint32 secondary = 2; 187 | } 188 | 189 | /* 190 | * TODO: REPLACE 191 | */ 192 | RequestResponse rr = 1; 193 | 194 | /* 195 | * TODO: REPLACE 196 | */ 197 | oneof variant { 198 | /* 199 | * TODO: REPLACE 200 | */ 201 | Statistics stats = 2; 202 | 203 | /* 204 | * TODO: REPLACE 205 | */ 206 | History history = 3; 207 | 208 | /* 209 | * TODO: REPLACE 210 | */ 211 | Heartbeat heartbeat = 4; 212 | 213 | /* 214 | * Text from history message. 215 | */ 216 | bytes text = 5; 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /meshtastic/telemetry.options: -------------------------------------------------------------------------------- 1 | # options for nanopb 2 | # https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options 3 | 4 | *EnvironmentMetrics.iaq int_size:16 5 | *EnvironmentMetrics.wind_direction int_size:16 6 | *EnvironmentMetrics.soil_moisture int_size:8 7 | 8 | *LocalStats.num_online_nodes int_size:16 9 | *LocalStats.num_total_nodes int_size:16 10 | 11 | *HealthMetrics.heart_bpm int_size:8 12 | *HealthMetrics.spO2 int_size:8 13 | 14 | *HostMetrics.load1 int_size:16 15 | *HostMetrics.load5 int_size:16 16 | *HostMetrics.load15 int_size:16 17 | *HostMetrics.user_string max_size:200 18 | -------------------------------------------------------------------------------- /meshtastic/telemetry.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "TelemetryProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | /* 12 | * Key native device metrics such as battery level 13 | */ 14 | message DeviceMetrics { 15 | /* 16 | * 0-100 (>100 means powered) 17 | */ 18 | optional uint32 battery_level = 1; 19 | 20 | /* 21 | * Voltage measured 22 | */ 23 | optional float voltage = 2; 24 | 25 | /* 26 | * Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). 27 | */ 28 | optional float channel_utilization = 3; 29 | 30 | /* 31 | * Percent of airtime for transmission used within the last hour. 32 | */ 33 | optional float air_util_tx = 4; 34 | 35 | /* 36 | * How long the device has been running since the last reboot (in seconds) 37 | */ 38 | optional uint32 uptime_seconds = 5; 39 | } 40 | 41 | /* 42 | * Weather station or other environmental metrics 43 | */ 44 | message EnvironmentMetrics { 45 | /* 46 | * Temperature measured 47 | */ 48 | optional float temperature = 1; 49 | 50 | /* 51 | * Relative humidity percent measured 52 | */ 53 | optional float relative_humidity = 2; 54 | 55 | /* 56 | * Barometric pressure in hPA measured 57 | */ 58 | optional float barometric_pressure = 3; 59 | 60 | /* 61 | * Gas resistance in MOhm measured 62 | */ 63 | optional float gas_resistance = 4; 64 | 65 | /* 66 | * Voltage measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) 67 | */ 68 | optional float voltage = 5; 69 | 70 | /* 71 | * Current measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) 72 | */ 73 | optional float current = 6; 74 | 75 | /* 76 | * relative scale IAQ value as measured by Bosch BME680 . value 0-500. 77 | * Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here. 78 | */ 79 | optional uint32 iaq = 7; 80 | 81 | /* 82 | * RCWL9620 Doppler Radar Distance Sensor, used for water level detection. Float value in mm. 83 | */ 84 | optional float distance = 8; 85 | 86 | /* 87 | * VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. 88 | */ 89 | optional float lux = 9; 90 | 91 | /* 92 | * VEML7700 high accuracy white light(irradiance) not calibrated digital 16-bit resolution sensor. 93 | */ 94 | optional float white_lux = 10; 95 | 96 | /* 97 | * Infrared lux 98 | */ 99 | optional float ir_lux = 11; 100 | 101 | /* 102 | * Ultraviolet lux 103 | */ 104 | optional float uv_lux = 12; 105 | 106 | /* 107 | * Wind direction in degrees 108 | * 0 degrees = North, 90 = East, etc... 109 | */ 110 | optional uint32 wind_direction = 13; 111 | 112 | /* 113 | * Wind speed in m/s 114 | */ 115 | optional float wind_speed = 14; 116 | 117 | /* 118 | * Weight in KG 119 | */ 120 | optional float weight = 15; 121 | 122 | /* 123 | * Wind gust in m/s 124 | */ 125 | optional float wind_gust = 16; 126 | 127 | /* 128 | * Wind lull in m/s 129 | */ 130 | optional float wind_lull = 17; 131 | 132 | /* 133 | * Radiation in µR/h 134 | */ 135 | optional float radiation = 18; 136 | 137 | /* 138 | * Rainfall in the last hour in mm 139 | */ 140 | optional float rainfall_1h = 19; 141 | 142 | /* 143 | * Rainfall in the last 24 hours in mm 144 | */ 145 | optional float rainfall_24h = 20; 146 | 147 | /* 148 | * Soil moisture measured (% 1-100) 149 | */ 150 | optional uint32 soil_moisture = 21; 151 | 152 | /* 153 | * Soil temperature measured (*C) 154 | */ 155 | optional float soil_temperature = 22; 156 | } 157 | 158 | /* 159 | * Power Metrics (voltage / current / etc) 160 | */ 161 | message PowerMetrics { 162 | /* 163 | * Voltage (Ch1) 164 | */ 165 | optional float ch1_voltage = 1; 166 | 167 | /* 168 | * Current (Ch1) 169 | */ 170 | optional float ch1_current = 2; 171 | 172 | /* 173 | * Voltage (Ch2) 174 | */ 175 | optional float ch2_voltage = 3; 176 | 177 | /* 178 | * Current (Ch2) 179 | */ 180 | optional float ch2_current = 4; 181 | 182 | /* 183 | * Voltage (Ch3) 184 | */ 185 | optional float ch3_voltage = 5; 186 | 187 | /* 188 | * Current (Ch3) 189 | */ 190 | optional float ch3_current = 6; 191 | } 192 | 193 | /* 194 | * Air quality metrics 195 | */ 196 | message AirQualityMetrics { 197 | /* 198 | * Concentration Units Standard PM1.0 199 | */ 200 | optional uint32 pm10_standard = 1; 201 | 202 | /* 203 | * Concentration Units Standard PM2.5 204 | */ 205 | optional uint32 pm25_standard = 2; 206 | 207 | /* 208 | * Concentration Units Standard PM10.0 209 | */ 210 | optional uint32 pm100_standard = 3; 211 | 212 | /* 213 | * Concentration Units Environmental PM1.0 214 | */ 215 | optional uint32 pm10_environmental = 4; 216 | 217 | /* 218 | * Concentration Units Environmental PM2.5 219 | */ 220 | optional uint32 pm25_environmental = 5; 221 | 222 | /* 223 | * Concentration Units Environmental PM10.0 224 | */ 225 | optional uint32 pm100_environmental = 6; 226 | 227 | /* 228 | * 0.3um Particle Count 229 | */ 230 | optional uint32 particles_03um = 7; 231 | 232 | /* 233 | * 0.5um Particle Count 234 | */ 235 | optional uint32 particles_05um = 8; 236 | 237 | /* 238 | * 1.0um Particle Count 239 | */ 240 | optional uint32 particles_10um = 9; 241 | 242 | /* 243 | * 2.5um Particle Count 244 | */ 245 | optional uint32 particles_25um = 10; 246 | 247 | /* 248 | * 5.0um Particle Count 249 | */ 250 | optional uint32 particles_50um = 11; 251 | 252 | /* 253 | * 10.0um Particle Count 254 | */ 255 | optional uint32 particles_100um = 12; 256 | 257 | /* 258 | * CO2 concentration in ppm 259 | */ 260 | optional uint32 co2 = 13; 261 | } 262 | 263 | /* 264 | * Local device mesh statistics 265 | */ 266 | message LocalStats { 267 | /* 268 | * How long the device has been running since the last reboot (in seconds) 269 | */ 270 | uint32 uptime_seconds = 1; 271 | /* 272 | * Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). 273 | */ 274 | float channel_utilization = 2; 275 | /* 276 | * Percent of airtime for transmission used within the last hour. 277 | */ 278 | float air_util_tx = 3; 279 | 280 | /* 281 | * Number of packets sent 282 | */ 283 | uint32 num_packets_tx = 4; 284 | 285 | /* 286 | * Number of packets received (both good and bad) 287 | */ 288 | uint32 num_packets_rx = 5; 289 | 290 | /* 291 | * Number of packets received that are malformed or violate the protocol 292 | */ 293 | uint32 num_packets_rx_bad = 6; 294 | 295 | /* 296 | * Number of nodes online (in the past 2 hours) 297 | */ 298 | uint32 num_online_nodes = 7; 299 | 300 | /* 301 | * Number of nodes total 302 | */ 303 | uint32 num_total_nodes = 8; 304 | 305 | /* 306 | * Number of received packets that were duplicates (due to multiple nodes relaying). 307 | * If this number is high, there are nodes in the mesh relaying packets when it's unnecessary, for example due to the ROUTER/REPEATER role. 308 | */ 309 | uint32 num_rx_dupe = 9; 310 | 311 | /* 312 | * Number of packets we transmitted that were a relay for others (not originating from ourselves). 313 | */ 314 | uint32 num_tx_relay = 10; 315 | 316 | /* 317 | * Number of times we canceled a packet to be relayed, because someone else did it before us. 318 | * This will always be zero for ROUTERs/REPEATERs. If this number is high, some other node(s) is/are relaying faster than you. 319 | */ 320 | uint32 num_tx_relay_canceled = 11; 321 | 322 | /* 323 | * Number of bytes used in the heap 324 | */ 325 | uint32 heap_total_bytes = 12; 326 | 327 | /* 328 | * Number of bytes free in the heap 329 | */ 330 | uint32 heap_free_bytes = 13; 331 | } 332 | 333 | /* 334 | * Health telemetry metrics 335 | */ 336 | message HealthMetrics { 337 | /* 338 | * Heart rate (beats per minute) 339 | */ 340 | optional uint32 heart_bpm = 1; 341 | 342 | /* 343 | * SpO2 (blood oxygen saturation) level 344 | */ 345 | optional uint32 spO2 = 2; 346 | 347 | /* 348 | * Body temperature in degrees Celsius 349 | */ 350 | optional float temperature = 3; 351 | } 352 | 353 | /* 354 | * Linux host metrics 355 | */ 356 | message HostMetrics { 357 | /* 358 | * Host system uptime 359 | */ 360 | uint32 uptime_seconds = 1; 361 | 362 | /* 363 | * Host system free memory 364 | */ 365 | uint64 freemem_bytes = 2; 366 | 367 | /* 368 | * Host system disk space free for / 369 | */ 370 | uint64 diskfree1_bytes = 3; 371 | 372 | /* 373 | * Secondary system disk space free 374 | */ 375 | optional uint64 diskfree2_bytes = 4; 376 | 377 | /* 378 | * Tertiary disk space free 379 | */ 380 | optional uint64 diskfree3_bytes = 5; 381 | 382 | /* 383 | * Host system one minute load in 1/100ths 384 | */ 385 | uint32 load1 = 6; 386 | 387 | /* 388 | * Host system five minute load in 1/100ths 389 | */ 390 | uint32 load5 = 7; 391 | 392 | /* 393 | * Host system fifteen minute load in 1/100ths 394 | */ 395 | uint32 load15 = 8; 396 | 397 | /* 398 | * Optional User-provided string for arbitrary host system information 399 | * that doesn't make sense as a dedicated entry. 400 | */ 401 | optional string user_string = 9; 402 | } 403 | 404 | 405 | /* 406 | * Types of Measurements the telemetry module is equipped to handle 407 | */ 408 | message Telemetry { 409 | /* 410 | * Seconds since 1970 - or 0 for unknown/unset 411 | */ 412 | fixed32 time = 1; 413 | 414 | oneof variant { 415 | /* 416 | * Key native device metrics such as battery level 417 | */ 418 | DeviceMetrics device_metrics = 2; 419 | 420 | /* 421 | * Weather station or other environmental metrics 422 | */ 423 | EnvironmentMetrics environment_metrics = 3; 424 | 425 | /* 426 | * Air quality metrics 427 | */ 428 | AirQualityMetrics air_quality_metrics = 4; 429 | 430 | /* 431 | * Power Metrics 432 | */ 433 | PowerMetrics power_metrics = 5; 434 | 435 | /* 436 | * Local device mesh statistics 437 | */ 438 | LocalStats local_stats = 6; 439 | 440 | /* 441 | * Health telemetry metrics 442 | */ 443 | HealthMetrics health_metrics = 7; 444 | 445 | /* 446 | * Linux host metrics 447 | */ 448 | HostMetrics host_metrics = 8; 449 | } 450 | } 451 | 452 | /* 453 | * Supported I2C Sensors for telemetry in Meshtastic 454 | */ 455 | enum TelemetrySensorType { 456 | /* 457 | * No external telemetry sensor explicitly set 458 | */ 459 | SENSOR_UNSET = 0; 460 | 461 | /* 462 | * High accuracy temperature, pressure, humidity 463 | */ 464 | BME280 = 1; 465 | 466 | /* 467 | * High accuracy temperature, pressure, humidity, and air resistance 468 | */ 469 | BME680 = 2; 470 | 471 | /* 472 | * Very high accuracy temperature 473 | */ 474 | MCP9808 = 3; 475 | 476 | /* 477 | * Moderate accuracy current and voltage 478 | */ 479 | INA260 = 4; 480 | 481 | /* 482 | * Moderate accuracy current and voltage 483 | */ 484 | INA219 = 5; 485 | 486 | /* 487 | * High accuracy temperature and pressure 488 | */ 489 | BMP280 = 6; 490 | 491 | /* 492 | * High accuracy temperature and humidity 493 | */ 494 | SHTC3 = 7; 495 | 496 | /* 497 | * High accuracy pressure 498 | */ 499 | LPS22 = 8; 500 | 501 | /* 502 | * 3-Axis magnetic sensor 503 | */ 504 | QMC6310 = 9; 505 | 506 | /* 507 | * 6-Axis inertial measurement sensor 508 | */ 509 | QMI8658 = 10; 510 | 511 | /* 512 | * 3-Axis magnetic sensor 513 | */ 514 | QMC5883L = 11; 515 | 516 | /* 517 | * High accuracy temperature and humidity 518 | */ 519 | SHT31 = 12; 520 | 521 | /* 522 | * PM2.5 air quality sensor 523 | */ 524 | PMSA003I = 13; 525 | 526 | /* 527 | * INA3221 3 Channel Voltage / Current Sensor 528 | */ 529 | INA3221 = 14; 530 | 531 | /* 532 | * BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280) 533 | */ 534 | BMP085 = 15; 535 | 536 | /* 537 | * RCWL-9620 Doppler Radar Distance Sensor, used for water level detection 538 | */ 539 | RCWL9620 = 16; 540 | 541 | /* 542 | * Sensirion High accuracy temperature and humidity 543 | */ 544 | SHT4X = 17; 545 | 546 | /* 547 | * VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor. 548 | */ 549 | VEML7700 = 18; 550 | 551 | /* 552 | * MLX90632 non-contact IR temperature sensor. 553 | */ 554 | MLX90632 = 19; 555 | 556 | /* 557 | * TI OPT3001 Ambient Light Sensor 558 | */ 559 | OPT3001 = 20; 560 | 561 | /* 562 | * Lite On LTR-390UV-01 UV Light Sensor 563 | */ 564 | LTR390UV = 21; 565 | 566 | /* 567 | * AMS TSL25911FN RGB Light Sensor 568 | */ 569 | TSL25911FN = 22; 570 | 571 | /* 572 | * AHT10 Integrated temperature and humidity sensor 573 | */ 574 | AHT10 = 23; 575 | 576 | /* 577 | * DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) 578 | */ 579 | DFROBOT_LARK = 24; 580 | 581 | /* 582 | * NAU7802 Scale Chip or compatible 583 | */ 584 | NAU7802 = 25; 585 | 586 | /* 587 | * BMP3XX High accuracy temperature and pressure 588 | */ 589 | BMP3XX = 26; 590 | 591 | /* 592 | * ICM-20948 9-Axis digital motion processor 593 | */ 594 | ICM20948 = 27; 595 | 596 | /* 597 | * MAX17048 1S lipo battery sensor (voltage, state of charge, time to go) 598 | */ 599 | MAX17048 = 28; 600 | 601 | /* 602 | * Custom I2C sensor implementation based on https://github.com/meshtastic/i2c-sensor 603 | */ 604 | CUSTOM_SENSOR = 29; 605 | 606 | /* 607 | * MAX30102 Pulse Oximeter and Heart-Rate Sensor 608 | */ 609 | MAX30102 = 30; 610 | 611 | /* 612 | * MLX90614 non-contact IR temperature sensor 613 | */ 614 | MLX90614 = 31; 615 | 616 | /* 617 | * SCD40/SCD41 CO2, humidity, temperature sensor 618 | */ 619 | SCD4X = 32; 620 | 621 | /* 622 | * ClimateGuard RadSens, radiation, Geiger-Muller Tube 623 | */ 624 | RADSENS = 33; 625 | 626 | /* 627 | * High accuracy current and voltage 628 | */ 629 | INA226 = 34; 630 | 631 | /* 632 | * DFRobot Gravity tipping bucket rain gauge 633 | */ 634 | DFROBOT_RAIN = 35; 635 | 636 | /* 637 | * Infineon DPS310 High accuracy pressure and temperature 638 | */ 639 | DPS310 = 36; 640 | 641 | /* 642 | * RAKWireless RAK12035 Soil Moisture Sensor Module 643 | */ 644 | RAK12035 = 37; 645 | 646 | /* 647 | * MAX17261 lipo battery gauge 648 | */ 649 | MAX17261 = 38; 650 | 651 | /* 652 | * PCT2075 Temperature Sensor 653 | */ 654 | PCT2075 = 39; 655 | } 656 | 657 | /* 658 | * NAU7802 Telemetry configuration, for saving to flash 659 | */ 660 | message Nau7802Config { 661 | /* 662 | * The offset setting for the NAU7802 663 | */ 664 | int32 zeroOffset = 1; 665 | 666 | /* 667 | * The calibration factor for the NAU7802 668 | */ 669 | float calibrationFactor = 2; 670 | } 671 | -------------------------------------------------------------------------------- /meshtastic/xmodem.options: -------------------------------------------------------------------------------- 1 | # options for nanopb 2 | # https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options 3 | 4 | *XModem.buffer max_size:128 5 | *XModem.seq int_size:16 6 | *XModem.crc16 int_size:16 7 | -------------------------------------------------------------------------------- /meshtastic/xmodem.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package meshtastic; 4 | 5 | option csharp_namespace = "Meshtastic.Protobufs"; 6 | option go_package = "github.com/meshtastic/go/generated"; 7 | option java_outer_classname = "XmodemProtos"; 8 | option java_package = "com.geeksville.mesh"; 9 | option swift_prefix = ""; 10 | 11 | message XModem { 12 | enum Control { 13 | NUL = 0; 14 | SOH = 1; 15 | STX = 2; 16 | EOT = 4; 17 | ACK = 6; 18 | NAK = 21; 19 | CAN = 24; 20 | CTRLZ = 26; 21 | } 22 | 23 | Control control = 1; 24 | uint32 seq = 2; 25 | uint32 crc16 = 3; 26 | bytes buffer = 4; 27 | } 28 | -------------------------------------------------------------------------------- /nanopb.proto: -------------------------------------------------------------------------------- 1 | // Custom options for defining: 2 | // - Maximum size of string/bytes 3 | // - Maximum number of elements in array 4 | // 5 | // These are used by nanopb to generate statically allocable structures 6 | // for memory-limited environments. 7 | 8 | syntax = "proto2"; 9 | 10 | import "google/protobuf/descriptor.proto"; 11 | 12 | option go_package = "github.com/meshtastic/go/generated"; 13 | option java_package = "fi.kapsi.koti.jpa.nanopb"; 14 | 15 | enum FieldType { 16 | FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible. 17 | FT_CALLBACK = 1; // Always generate a callback field. 18 | FT_POINTER = 4; // Always generate a dynamically allocated field. 19 | FT_STATIC = 2; // Generate a static field or raise an exception if not possible. 20 | FT_IGNORE = 3; // Ignore the field completely. 21 | FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead 22 | } 23 | 24 | enum IntSize { 25 | IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto 26 | IS_8 = 8; 27 | IS_16 = 16; 28 | IS_32 = 32; 29 | IS_64 = 64; 30 | } 31 | 32 | enum TypenameMangling { 33 | M_NONE = 0; // Default, no typename mangling 34 | M_STRIP_PACKAGE = 1; // Strip current package name 35 | M_FLATTEN = 2; // Only use last path component 36 | M_PACKAGE_INITIALS = 3; // Replace the package name by the initials 37 | } 38 | 39 | enum DescriptorSize { 40 | DS_AUTO = 0; // Select minimal size based on field type 41 | DS_1 = 1; // 1 word; up to 15 byte fields, no arrays 42 | DS_2 = 2; // 2 words; up to 4095 byte fields, 4095 entry arrays 43 | DS_4 = 4; // 4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays 44 | DS_8 = 8; // 8 words; up to 2^32-1 entry arrays 45 | } 46 | 47 | // This is the inner options message, which basically defines options for 48 | // a field. When it is used in message or file scope, it applies to all 49 | // fields. 50 | message NanoPBOptions { 51 | // Allocated size for 'bytes' and 'string' fields. 52 | // For string fields, this should include the space for null terminator. 53 | optional int32 max_size = 1; 54 | 55 | // Maximum length for 'string' fields. Setting this is equivalent 56 | // to setting max_size to a value of length+1. 57 | optional int32 max_length = 14; 58 | 59 | // Allocated number of entries in arrays ('repeated' fields) 60 | optional int32 max_count = 2; 61 | 62 | // Size of integer fields. Can save some memory if you don't need 63 | // full 32 bits for the value. 64 | optional IntSize int_size = 7 [default = IS_DEFAULT]; 65 | 66 | // Force type of field (callback or static allocation) 67 | optional FieldType type = 3 [default = FT_DEFAULT]; 68 | 69 | // Use long names for enums, i.e. EnumName_EnumValue. 70 | optional bool long_names = 4 [default = true]; 71 | 72 | // Add 'packed' attribute to generated structs. 73 | // Note: this cannot be used on CPUs that break on unaligned 74 | // accesses to variables. 75 | optional bool packed_struct = 5 [default = false]; 76 | 77 | // Add 'packed' attribute to generated enums. 78 | optional bool packed_enum = 10 [default = false]; 79 | 80 | // Skip this message 81 | optional bool skip_message = 6 [default = false]; 82 | 83 | // Generate oneof fields as normal optional fields instead of union. 84 | optional bool no_unions = 8 [default = false]; 85 | 86 | // integer type tag for a message 87 | optional uint32 msgid = 9; 88 | 89 | // decode oneof as anonymous union 90 | optional bool anonymous_oneof = 11 [default = false]; 91 | 92 | // Proto3 singular field does not generate a "has_" flag 93 | optional bool proto3 = 12 [default = false]; 94 | 95 | // Force proto3 messages to have no "has_" flag. 96 | // This was default behavior until nanopb-0.4.0. 97 | optional bool proto3_singular_msgs = 21 [default = false]; 98 | 99 | // Generate an enum->string mapping function (can take up lots of space). 100 | optional bool enum_to_string = 13 [default = false]; 101 | 102 | // Generate bytes arrays with fixed length 103 | optional bool fixed_length = 15 [default = false]; 104 | 105 | // Generate repeated field with fixed count 106 | optional bool fixed_count = 16 [default = false]; 107 | 108 | // Generate message-level callback that is called before decoding submessages. 109 | // This can be used to set callback fields for submsgs inside oneofs. 110 | optional bool submsg_callback = 22 [default = false]; 111 | 112 | // Shorten or remove package names from type names. 113 | // This option applies only on the file level. 114 | optional TypenameMangling mangle_names = 17 [default = M_NONE]; 115 | 116 | // Data type for storage associated with callback fields. 117 | optional string callback_datatype = 18 [default = "pb_callback_t"]; 118 | 119 | // Callback function used for encoding and decoding. 120 | // Prior to nanopb-0.4.0, the callback was specified in per-field pb_callback_t 121 | // structure. This is still supported, but does not work inside e.g. oneof or pointer 122 | // fields. Instead, a new method allows specifying a per-message callback that 123 | // will be called for all callback fields in a message type. 124 | optional string callback_function = 19 [default = "pb_default_field_callback"]; 125 | 126 | // Select the size of field descriptors. This option has to be defined 127 | // for the whole message, not per-field. Usually automatic selection is 128 | // ok, but if it results in compilation errors you can increase the field 129 | // size here. 130 | optional DescriptorSize descriptorsize = 20 [default = DS_AUTO]; 131 | 132 | // Set default value for has_ fields. 133 | optional bool default_has = 23 [default = false]; 134 | 135 | // Extra files to include in generated `.pb.h` 136 | repeated string include = 24; 137 | 138 | // Automatic includes to exclude from generated `.pb.h` 139 | // Same as nanopb_generator.py command line flag -x. 140 | repeated string exclude = 26; 141 | 142 | // Package name that applies only for nanopb. 143 | optional string package = 25; 144 | 145 | // Override type of the field in generated C code. Only to be used with related field types 146 | optional google.protobuf.FieldDescriptorProto.Type type_override = 27; 147 | 148 | // Due to historical reasons, nanopb orders fields in structs by their tag number 149 | // instead of the order in .proto. Set this to false to keep the .proto order. 150 | // The default value will probably change to false in nanopb-0.5.0. 151 | optional bool sort_by_tag = 28 [default = true]; 152 | 153 | // Set the FT_DEFAULT field conversion strategy. 154 | // A field that can become a static member of a c struct (e.g. int, bool, etc) 155 | // will be a a static field. 156 | // Fields with dynamic length are converted to either a pointer or a callback. 157 | optional FieldType fallback_type = 29 [default = FT_CALLBACK]; 158 | } 159 | 160 | // Extensions to protoc 'Descriptor' type in order to define options 161 | // inside a .proto file. 162 | // 163 | // Protocol Buffers extension number registry 164 | // -------------------------------- 165 | // Project: Nanopb 166 | // Contact: Petteri Aimonen 167 | // Web site: http://kapsi.fi/~jpa/nanopb 168 | // Extensions: 1010 (all types) 169 | // -------------------------------- 170 | 171 | extend google.protobuf.FileOptions { 172 | optional NanoPBOptions nanopb_fileopt = 1010; 173 | } 174 | 175 | extend google.protobuf.MessageOptions { 176 | optional NanoPBOptions nanopb_msgopt = 1010; 177 | } 178 | 179 | extend google.protobuf.EnumOptions { 180 | optional NanoPBOptions nanopb_enumopt = 1010; 181 | } 182 | 183 | extend google.protobuf.FieldOptions { 184 | optional NanoPBOptions nanopb = 1010; 185 | } 186 | --------------------------------------------------------------------------------