forked from TheThingsNetwork/lorawan-stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessages.proto
More file actions
329 lines (288 loc) · 13.3 KB
/
messages.proto
File metadata and controls
329 lines (288 loc) · 13.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
// Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
import "github.com/envoyproxy/protoc-gen-validate/validate/validate.proto";
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "lorawan-stack/api/error.proto";
import "lorawan-stack/api/identifiers.proto";
import "lorawan-stack/api/keys.proto";
import "lorawan-stack/api/lorawan.proto";
import "lorawan-stack/api/metadata.proto";
package ttn.lorawan.v3;
option go_package = "go.thethings.network/lorawan-stack/v3/pkg/ttnpb";
// Uplink message from the end device to the network
message UplinkMessage {
option (gogoproto.populate) = false;
// Mapping from UDP message (other fields can be set in "advanced"):
//
// - time: rx_metadata.time
// - tmst: rx_metadata.timestamp
// - freq: settings.frequency
// - modu: settings.modulation
// - datr: settings.data_rate_index (and derived fields)
// - codr: settings.coding_rate
// - size: len(raw_payload)
// - data: raw_payload (and derived payload)
// - rsig: rx_metadata
// - ant: rx_metadata.antenna_index
// - chan: rx_metadata.channel_index
// - rssis: rx_metadata.rssi
// - lsnr: rx_metadata.snr
// Mapping from BACKEND message:
//
// - PHYPayload: raw_payload
// - FRMPayload: payload.mac_payload.frm_payload
// - DevEUI: end_device.dev_eui
// - DevAddr: end_device.dev_addr
// - ULMetadata:
// - DevEUI: end_device.dev_eui
// - DevAddr: end_device.dev_addr
// - FPort: payload.mac_payload.f_port
// - FCntUp: payload.mac_payload.f_hdr.f_cnt
// - Confirmed: payload.mhdr.m_type
// - DataRate: settings.data_rate_index (and derived fields)
// - ULFreq: settings.frequency
// - RecvTime: included in each rx_metadata
// - GWCnt: derived from rx_metadata contents
// - GWInfo:
// - ID: rx_metadata.gateway_id
// - RSSI: rx_metadata.rssi
// - SNR: rx_metadata.snr
// - Lat: rx_metadata.location.latitude
// - Lon: rx_metadata.location.longitude
bytes raw_payload = 1;
Message payload = 2;
TxSettings settings = 4 [(gogoproto.nullable) = false, (validate.rules).message.required = true];
repeated RxMetadata rx_metadata = 5;
// Server time when a component received the message.
// The Gateway Server and Network Server set this value to their local server time of reception.
google.protobuf.Timestamp received_at = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
repeated string correlation_ids = 7 [(gogoproto.customname) = "CorrelationIDs", (validate.rules).repeated.items.string.max_len = 100];
reserved 8; // gateway_channel_index (obsolete).
// Index of the device channel that received the message.
// Set by Network Server.
uint32 device_channel_index = 9 [(validate.rules).uint32 = {lte: 255}];
}
// Downlink message from the network to the end device
message DownlinkMessage {
option (gogoproto.populate) = false;
// Mapping from UDP message:
//
// imme: -
// tmst: scheduled.timestamp
// tmms: scheduled.time
// freq: scheduled.frequency
// rfch: (0)
// powe: scheduled.tx_power
// modu: scheduled.modulation
// datr: scheduled.data_rate_index (derived)
// codr: scheduled.coding_rate
// fdev: (derived from bandwidth)
// ipol: scheduled.invert_polarization
// prea: [scheduled.advanced]
// size: (derived from len(raw_payload))
// data: raw_payload
// ncrc: [scheduled.advanced]
// Mapping from BACKEND message:
//
// - PHYPayload: raw_payload
// - FRMPayload: payload.mac_payload.frm_payload
// - DevEUI: end_device_ids.dev_eui
// - DevAddr: end_device_ids.dev_addr
// - DLMetadata:
// - DevEUI: end_device_ids.dev_eui
// - DevAddr: end_device_ids.dev_addr
// - FPort: payload.mac_payload.f_port
// - FCntDown: payload.mac_payload.f_hdr.f_cnt
// - Confirmed: payload.mhdr.m_type
// - RxDelay1: request.rx1_delay
// - DLFreq1: request.rx1_frequency
// - DLFreq2: request.rx2_frequency
// - DataRate1: request_rx1_data_rate_index
// - DataRate2: request.rx2_data_rate_index
// - GWInfo:
// - ID: request.gateway_ids.gateway_id
// - HiPriorityFlag: request.priority >= HIGH
bytes raw_payload = 1;
Message payload = 2;
EndDeviceIdentifiers end_device_ids = 3 [(gogoproto.customname) = "EndDeviceIDs"];
oneof settings {
option (validate.required) = true;
TxRequest request = 4;
TxSettings scheduled = 5;
}
repeated string correlation_ids = 6 [(gogoproto.customname) = "CorrelationIDs", (validate.rules).repeated.items.string.max_len = 100];
}
message TxAcknowledgment {
repeated string correlation_ids = 1 [(gogoproto.customname) = "CorrelationIDs", (validate.rules).repeated.items.string.max_len = 100];
enum Result {
SUCCESS = 0;
UNKNOWN_ERROR = 1;
TOO_LATE = 2;
TOO_EARLY = 3;
COLLISION_PACKET = 4;
COLLISION_BEACON = 5;
TX_FREQ = 6;
TX_POWER = 7;
GPS_UNLOCKED = 8;
}
Result result = 2 [(validate.rules).enum.defined_only = true];
}
message GatewayUplinkMessage {
UplinkMessage message = 1 [(gogoproto.embed) = true, (validate.rules).message.required = true];
// LoRaWAN band ID of the gateway.
string band_id = 2 [(gogoproto.customname) = "BandID"];
}
message ApplicationUplink {
// Join Server issued identifier for the session keys used by this uplink.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
uint32 f_port = 2 [(validate.rules).uint32 = {gte: 1, lte: 255, not_in: [224]}];
uint32 f_cnt = 3;
// The frame payload of the uplink message.
// The payload is still encrypted if the skip_payload_crypto field of the EndDevice
// is true, which is indicated by the presence of the app_s_key field.
bytes frm_payload = 4 [(gogoproto.customname) = "FRMPayload"];
google.protobuf.Struct decoded_payload = 5;
// A list of metadata for each antenna of each gateway that received this message.
repeated RxMetadata rx_metadata = 6 [(validate.rules).repeated.min_items = 1];
// Settings for the transmission.
TxSettings settings = 7 [(gogoproto.nullable) = false, (validate.rules).message.required = true];
// Server time when the Network Server received the message.
google.protobuf.Timestamp received_at = 8 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// The AppSKey of the current session.
// This field is only present if the skip_payload_crypto field of the EndDevice
// is true.
// Can be used to decrypt uplink payloads and encrypt downlink payloads.
KeyEnvelope app_s_key = 9;
// The last AFCntDown of the current session.
// This field is only present if the skip_payload_crypto field of the EndDevice
// is true.
// Can be used with app_s_key to encrypt downlink payloads.
uint32 last_a_f_cnt_down = 10;
bool confirmed = 11;
// next: 12
}
message ApplicationLocation {
string service = 1;
Location location = 2 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
map<string,string> attributes = 3 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
}
message ApplicationJoinAccept {
// Join Server issued identifier for the session keys negotiated in this join.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
// Encrypted Application Session Key (if Join Server sent it to Network Server).
KeyEnvelope app_s_key = 2;
// Downlink messages in the queue that got invalidated because of the session change.
repeated ApplicationDownlink invalidated_downlinks = 3;
// Indicates whether the security context refers to the pending session, i.e. when this join-accept is an answer to a
// rejoin-request.
bool pending_session = 4;
// Server time when the Network Server received the message.
google.protobuf.Timestamp received_at = 8 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}
message ApplicationDownlink {
option (gogoproto.populate) = false;
// Join Server issued identifier for the session keys used by this downlink.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
uint32 f_port = 2 [(validate.rules).uint32 = {gte: 1, lte: 255, not_in: [224]}];
uint32 f_cnt = 3;
// The frame payload of the downlink message.
// The payload is encrypted if the skip_payload_crypto field of the EndDevice
// is true.
bytes frm_payload = 4 [(gogoproto.customname) = "FRMPayload"];
google.protobuf.Struct decoded_payload = 5;
bool confirmed = 6;
message ClassBC {
// Possible gateway identifiers and antenna index to use for this downlink message.
// The Network Server selects one of these gateways for downlink, based on connectivity, signal quality, channel utilization and an available slot.
// If none of the gateways can be selected, the downlink message fails.
// If empty, a gateway and antenna is selected automatically from the gateways seen in recent uplinks.
repeated GatewayAntennaIdentifiers gateways = 7 [(gogoproto.nullable) = false];
// Absolute time when the downlink message should be transmitted.
// This requires the gateway to have GPS time synchronization.
// If the time is in the past or if there is a scheduling conflict, the downlink message fails.
// If null, the time is selected based on slot availability. This is recommended in class B mode.
google.protobuf.Timestamp absolute_time = 8 [(gogoproto.stdtime) = true];
}
// Optional gateway and timing information for class B and C.
// If set, this downlink message will only be transmitted as class B or C downlink.
// If not set, this downlink message may be transmitted in class A, B and C.
ClassBC class_b_c = 7;
// Priority for scheduling the downlink message.
TxSchedulePriority priority = 8 [(validate.rules).enum.defined_only = true];
repeated string correlation_ids = 9 [(gogoproto.customname) = "CorrelationIDs", (validate.rules).repeated.items.string.max_len = 100];
}
message ApplicationDownlinks {
repeated ApplicationDownlink downlinks = 1;
}
message ApplicationDownlinkFailed {
ApplicationDownlink downlink = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
ErrorDetails error = 2 [(gogoproto.nullable) = false, (validate.rules).message.required = true];
}
message ApplicationInvalidatedDownlinks {
repeated ApplicationDownlink downlinks = 1 [(validate.rules).repeated.min_items = 1];
uint32 last_f_cnt_down = 2;
}
message ApplicationServiceData {
string service = 1;
google.protobuf.Struct data = 2;
}
message ApplicationUp {
EndDeviceIdentifiers end_device_ids = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
repeated string correlation_ids = 2 [(gogoproto.customname) = "CorrelationIDs", (validate.rules).repeated.items.string.max_len = 100];
// Server time when the Application Server received the message.
google.protobuf.Timestamp received_at = 12 [(gogoproto.stdtime) = true];
oneof up {
option (validate.required) = true;
ApplicationUplink uplink_message = 3;
ApplicationJoinAccept join_accept = 4;
ApplicationDownlink downlink_ack = 5;
ApplicationDownlink downlink_nack = 6;
ApplicationDownlink downlink_sent = 7;
ApplicationDownlinkFailed downlink_failed = 8;
ApplicationDownlink downlink_queued = 9;
ApplicationInvalidatedDownlinks downlink_queue_invalidated = 10;
ApplicationLocation location_solved = 11;
ApplicationServiceData service_data = 13;
}
}
enum PayloadFormatter {
// No payload formatter to work with raw payload only.
FORMATTER_NONE = 0;
// Use payload formatter for the end device type from a repository.
FORMATTER_REPOSITORY = 1;
// gRPC service payload formatter. The parameter is the host:port of the service.
FORMATTER_GRPC_SERVICE = 2;
// Custom payload formatter that executes Javascript code. The parameter is a JavaScript filename.
FORMATTER_JAVASCRIPT = 3;
// CayenneLPP payload formatter.
FORMATTER_CAYENNELPP = 4;
// More payload formatters can be added.
}
message MessagePayloadFormatters {
// Payload formatter for uplink messages, must be set together with its parameter.
PayloadFormatter up_formatter = 1 [(validate.rules).enum.defined_only = true];
// Parameter for the up_formatter, must be set together.
string up_formatter_parameter = 2;
// Payload formatter for downlink messages, must be set together with its parameter.
PayloadFormatter down_formatter = 3 [(validate.rules).enum.defined_only = true];
// Parameter for the down_formatter, must be set together.
string down_formatter_parameter = 4;
}
message DownlinkQueueRequest {
EndDeviceIdentifiers end_device_ids = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false];
repeated ApplicationDownlink downlinks = 2;
}