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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
|
/* packet-llrp.c
* Routines for Low Level Reader Protocol dissection
* Copyright 2012, Evan Huus <eapache@gmail.com>
*
* http://www.gs1.org/gsmp/kc/epcglobal/llrp
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <glib.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#define LLRP_PORT 5084
/* Initialize the protocol and registered fields */
static int proto_llrp = -1;
static int hf_llrp_version = -1;
static int hf_llrp_type = -1;
static int hf_llrp_length = -1;
static int hf_llrp_id = -1;
static int hf_llrp_cur_ver = -1;
static int hf_llrp_sup_ver = -1;
static int hf_llrp_req_cap = -1;
static int hf_llrp_req_conf = -1;
static int hf_llrp_rospec = -1;
static int hf_llrp_antenna_id = -1;
static int hf_llrp_gpi_port = -1;
static int hf_llrp_gpo_port = -1;
static int hf_llrp_rest_fact = -1;
static int hf_llrp_accessspec = -1;
static int hf_llrp_vendor = -1;
static int hf_llrp_tlv_type = -1;
static int hf_llrp_tv_type = -1;
static int hf_llrp_tlv_len = -1;
static int hf_llrp_param = -1;
/* Initialize the subtree pointers */
static gint ett_llrp = -1;
static gint ett_llrp_param = -1;
/* Message Types */
#define LLRP_TYPE_GET_READER_CAPABILITES 1
#define LLRP_TYPE_GET_READER_CONFIG 2
#define LLRP_TYPE_SET_READER_CONFIG 3
#define LLRP_TYPE_CLOSE_CONNECTION_RESPONSE 4
#define LLRP_TYPE_GET_READER_CAPABILITES_RESPONSE 11
#define LLRP_TYPE_GET_READER_CONFIG_RESPONSE 12
#define LLRP_TYPE_SET_READER_CONFIG_RESPONSE 13
#define LLRP_TYPE_CLOSE_CONNECTION 14
#define LLRP_TYPE_ADD_ROSPEC 20
#define LLRP_TYPE_DELETE_ROSPEC 21
#define LLRP_TYPE_START_ROSPEC 22
#define LLRP_TYPE_STOP_ROSPEC 23
#define LLRP_TYPE_ENABLE_ROSPEC 24
#define LLRP_TYPE_DISABLE_ROSPEC 25
#define LLRP_TYPE_GET_ROSPECS 26
#define LLRP_TYPE_ADD_ROSPEC_RESPONSE 30
#define LLRP_TYPE_DELETE_ROSPEC_RESPONSE 31
#define LLRP_TYPE_START_ROSPEC_RESPONSE 32
#define LLRP_TYPE_STOP_ROSPEC_RESPONSE 33
#define LLRP_TYPE_ENABLE_ROSPEC_RESPONSE 34
#define LLRP_TYPE_DISABLE_ROSPEC_RESPONSE 35
#define LLRP_TYPE_GET_ROSPECS_RESPONSE 36
#define LLRP_TYPE_ADD_ACCESSSPEC 40
#define LLRP_TYPE_DELETE_ACCESSSPEC 41
#define LLRP_TYPE_ENABLE_ACCESSSPEC 42
#define LLRP_TYPE_DISABLE_ACCESSSPEC 43
#define LLRP_TYPE_GET_ACCESSSPECS 44
#define LLRP_TYPE_CLIENT_REQUEST_OP 45
#define LLRP_TYPE_GET_SUPPORTED_VERSION 46
#define LLRP_TYPE_SET_PROTOCOL_VERSION 47
#define LLRP_TYPE_ADD_ACCESSSPEC_RESPONSE 50
#define LLRP_TYPE_DELETE_ACCESSSPEC_RESPONSE 51
#define LLRP_TYPE_ENABLE_ACCESSSPEC_RESPONSE 52
#define LLRP_TYPE_DISABLE_ACCESSSPEC_RESPONSE 53
#define LLRP_TYPE_GET_ACCESSSPECS_RESPONSE 54
#define LLRP_TYPE_CLIENT_RESQUEST_OP_RESPONSE 55
#define LLRP_TYPE_GET_SUPPORTED_VERSION_RESPONSE 56
#define LLRP_TYPE_SET_PROTOCOL_VERSION_RESPONSE 57
#define LLRP_TYPE_GET_REPORT 60
#define LLRP_TYPE_RO_ACCESS_REPORT 61
#define LLRP_TYPE_KEEPALIVE 62
#define LLRP_TYPE_READER_EVENT_NOTIFICATION 63
#define LLRP_TYPE_ENABLE_EVENTS_AND_REPORTS 64
#define LLRP_TYPE_KEEPALIVE_ACK 72
#define LLRP_TYPE_ERROR_MESSAGE 100
#define LLRP_TYPE_CUSTOM_MESSAGE 1023
static const value_string message_types[] = {
{ LLRP_TYPE_GET_READER_CAPABILITES, "Get Reader Capabilites" },
{ LLRP_TYPE_GET_READER_CONFIG, "Get Reader Config" },
{ LLRP_TYPE_SET_READER_CONFIG, "Set Reader Config" },
{ LLRP_TYPE_CLOSE_CONNECTION_RESPONSE, "Close Connection Response" },
{ LLRP_TYPE_GET_READER_CAPABILITES_RESPONSE, "Get Reader Capabilites Response" },
{ LLRP_TYPE_GET_READER_CONFIG_RESPONSE, "Get Reader Config Response" },
{ LLRP_TYPE_SET_READER_CONFIG_RESPONSE, "Set Reader Config Response" },
{ LLRP_TYPE_CLOSE_CONNECTION, "Close Connection" },
{ LLRP_TYPE_ADD_ROSPEC, "Add ROSpec" },
{ LLRP_TYPE_DELETE_ROSPEC, "Delete ROSpec" },
{ LLRP_TYPE_START_ROSPEC, "Start ROSpec" },
{ LLRP_TYPE_STOP_ROSPEC, "Stop ROSpec" },
{ LLRP_TYPE_ENABLE_ROSPEC, "Enable ROSpec" },
{ LLRP_TYPE_DISABLE_ROSPEC, "Disable ROSpec" },
{ LLRP_TYPE_GET_ROSPECS, "Get ROSpecs" },
{ LLRP_TYPE_ADD_ROSPEC_RESPONSE, "Add ROSpec Response" },
{ LLRP_TYPE_DELETE_ROSPEC_RESPONSE, "Delete ROSpec Response" },
{ LLRP_TYPE_START_ROSPEC_RESPONSE, "Start ROSpec Response" },
{ LLRP_TYPE_STOP_ROSPEC_RESPONSE, "Stop ROSpec Response" },
{ LLRP_TYPE_ENABLE_ROSPEC_RESPONSE, "Enable ROSpec Response" },
{ LLRP_TYPE_DISABLE_ROSPEC_RESPONSE, "Disable ROSpec Response" },
{ LLRP_TYPE_GET_ROSPECS_RESPONSE, "Get ROSpecs Response" },
{ LLRP_TYPE_ADD_ACCESSSPEC, "Add AccessSpec" },
{ LLRP_TYPE_DELETE_ACCESSSPEC, "Delete AccessSpec" },
{ LLRP_TYPE_ENABLE_ACCESSSPEC, "Enable AccessSpec" },
{ LLRP_TYPE_DISABLE_ACCESSSPEC, "Disable AccessSpec" },
{ LLRP_TYPE_GET_ACCESSSPECS, "Get AccessSpecs" },
{ LLRP_TYPE_CLIENT_REQUEST_OP, "Client Request OP" },
{ LLRP_TYPE_GET_SUPPORTED_VERSION, "Get Supported Version" },
{ LLRP_TYPE_SET_PROTOCOL_VERSION, "Set Protocol Version" },
{ LLRP_TYPE_ADD_ACCESSSPEC_RESPONSE, "Add AccessSpec Response" },
{ LLRP_TYPE_DELETE_ACCESSSPEC_RESPONSE, "Delete AccessSpec Response" },
{ LLRP_TYPE_ENABLE_ACCESSSPEC_RESPONSE, "Enable AccessSpec Response" },
{ LLRP_TYPE_DISABLE_ACCESSSPEC_RESPONSE, "Disable AccessSpec Response" },
{ LLRP_TYPE_GET_ACCESSSPECS_RESPONSE, "Get AccessSpecs Response" },
{ LLRP_TYPE_CLIENT_RESQUEST_OP_RESPONSE, "Client Resquest OP Response" },
{ LLRP_TYPE_GET_SUPPORTED_VERSION_RESPONSE, "Get Supported Version Response" },
{ LLRP_TYPE_SET_PROTOCOL_VERSION_RESPONSE, "Set Protocol Version Response" },
{ LLRP_TYPE_GET_REPORT, "Get Report" },
{ LLRP_TYPE_RO_ACCESS_REPORT, "RO Access Report" },
{ LLRP_TYPE_KEEPALIVE, "Keepalive" },
{ LLRP_TYPE_READER_EVENT_NOTIFICATION, "Reader Event Notification" },
{ LLRP_TYPE_ENABLE_EVENTS_AND_REPORTS, "Enable Events And Reports" },
{ LLRP_TYPE_KEEPALIVE_ACK, "Keepalive Ack" },
{ LLRP_TYPE_ERROR_MESSAGE, "Error Message" },
{ LLRP_TYPE_CUSTOM_MESSAGE, "Custom Message" },
{ 0, NULL }
};
/* Versions */
#define LLRP_VERS_1_0_1 0x01
#define LLRP_VERS_1_1 0x02
static const value_string llrp_versions[] = {
{ LLRP_VERS_1_0_1, "1.0.1" },
{ LLRP_VERS_1_1, "1.1" },
{ 0, NULL }
};
/* Capabilities */
#define LLRP_CAP_ALL 0
#define LLRP_CAP_GENERAL_DEVICE 1
#define LLRP_CAP_LLRP 2
#define LLRP_CAP_REGULATORY 3
#define LLRP_CAP_AIR_PROTOCOL 4
static const value_string capabilities_request[] = {
{ LLRP_CAP_ALL, "All" },
{ LLRP_CAP_GENERAL_DEVICE, "General Device Capabilities" },
{ LLRP_CAP_LLRP, "LLRP Capabilites" },
{ LLRP_CAP_REGULATORY, "Regulatory Capabilities" },
{ LLRP_CAP_AIR_PROTOCOL, "Air Protocol LLRP Capabilities" },
{ 0, NULL }
};
/* Configurations */
#define LLRP_CONF_ALL 0
#define LLRP_CONF_IDENTIFICATION 1
#define LLRP_CONF_ANTENNA_PROPERTIES 2
#define LLRP_CONF_ANTENNA_CONFIGURATION 3
#define LLRP_CONF_RO_REPORT_SPEC 4
#define LLRP_CONF_READER_EVENT_NOTIFICATION_SPEC 5
#define LLRP_CONF_ACCESS_REPORT_SPEC 6
#define LLRP_CONF_LLRP_CONFIGURATION_STATE 7
#define LLRP_CONF_KEEPALIVE_SPEC 8
#define LLRP_CONF_GPI_PORT_CURRENT_STATE 9
#define LLRP_CONF_GPO_WRITE_DATA 10
#define LLRP_CONF_EVENTS_AND_REPORTS 11
static const value_string config_request[] = {
{ LLRP_CONF_ALL, "All" },
{ LLRP_CONF_IDENTIFICATION, "Identification" },
{ LLRP_CONF_ANTENNA_PROPERTIES, "Antenna Properties" },
{ LLRP_CONF_ANTENNA_CONFIGURATION, "Antenna Configuration" },
{ LLRP_CONF_RO_REPORT_SPEC, "RO Report Spec" },
{ LLRP_CONF_READER_EVENT_NOTIFICATION_SPEC, "Reader Event Notification Spec" },
{ LLRP_CONF_ACCESS_REPORT_SPEC, "Access Report Spec" },
{ LLRP_CONF_LLRP_CONFIGURATION_STATE, "LLRP Configuration State" },
{ LLRP_CONF_KEEPALIVE_SPEC, "Keepalive Spec" },
{ LLRP_CONF_GPI_PORT_CURRENT_STATE, "GPI Port Current State" },
{ LLRP_CONF_GPO_WRITE_DATA, "GPO Write Data" },
{ LLRP_CONF_EVENTS_AND_REPORTS, "Events and Reports" },
{ 0, NULL }
};
/* TLV Parameter Types */
#define LLRP_TLV_UTC_TIMESTAMP 128
#define LLRP_TLV_UPTIME 129
#define LLRP_TLV_GENERAL_DEVICE_CAP 137
#define LLRP_TLV_RECEIVE_SENSE_ENTRY 139
#define LLRP_TLV_ANTENNA_AIR_PROTO 140
#define LLRP_TLV_GPIO_CAPABILITIES 141
#define LLRP_TLV_LLRP_CAPABILITIES 142
#define LLRP_TLV_REGU_CAPABILITIES 143
#define LLRP_TLV_UHF_CAPABILITIES 144
#define LLRP_TLV_XMIT_POWER_LEVEL_ENTRY 145
#define LLRP_TLV_FREQ_INFORMATION 146
#define LLRP_TLV_FREQ_HOP_TABLE 147
#define LLRP_TLV_FIXED_FREQ_TABLE 148
#define LLRP_TLV_ANTENNA_RCV_SENSE_RANGE 149
#define LLRP_TLV_RO_SPEC 177
#define LLRP_TLV_RO_BOUND_SPEC 178
#define LLRP_TLV_RO_SPEC_START_TRIGGER 179
#define LLRP_TLV_PER_TRIGGER_VAL 180
#define LLRP_TLV_GPI_TRIGGER_VAL 181
#define LLRP_TLV_RO_SPEC_STOP_TRIGGER 182
#define LLRP_TLV_AI_SPEC 183
#define LLRP_TLV_AI_SPEC_STOP 184
#define LLRP_TLV_TAG_OBSERV_TRIGGER 185
#define LLRP_TLV_INVENTORY_PARAM_SPEC 186
#define LLRP_TLV_RF_SURVEY_SPEC 187
#define LLRP_TLV_RF_SURVEY_SPEC_STOP_TR 188
#define LLRP_TLV_ACCESS_SPEC 207
#define LLRP_TLV_ACCESS_SPEC_STOP_TRIG 208
#define LLRP_TLV_ACCESS_COMMAND 209
#define LLRP_TLV_CLIENT_REQ_OP_SPEC 210
#define LLRP_TLV_CLIENT_REQ_RESPONSE 211
#define LLRP_TLV_LLRP_CONF_STATE_VAL 217
#define LLRP_TLV_IDENT 218
#define LLRP_TLV_GPO_WRITE_DATA 219
#define LLRP_TLV_KEEPALIVE_SPEC 220
#define LLRP_TLV_ANTENNA_PROPS 221
#define LLRP_TLV_ANTENNA_CONF 222
#define LLRP_TLV_RF_RECEIVER 223
#define LLRP_TLV_RF_TRANSMITTER 224
#define LLRP_TLV_GPI_PORT_CURRENT_STATE 225
#define LLRP_TLV_EVENTS_AND_REPORTS 226
#define LLRP_TLV_RO_REPORT_SPEC 237
#define LLRP_TLV_TAG_REPORT_CONTENT_SEL 238
#define LLRP_TLV_ACCESS_REPORT_SPEC 239
#define LLRP_TLV_TAG_REPORT_DATA 240
#define LLRP_TLV_EPC_DATA 241
#define LLRP_TLV_RF_SURVEY_REPORT_DATA 242
#define LLRP_TLV_FREQ_RSSI_LEVEL_ENTRY 243
#define LLRP_TLV_READER_EVENT_NOTI_SPEC 244
#define LLRP_TLV_EVENT_NOTIF_STATE 245
#define LLRP_TLV_READER_EVENT_NOTI_DATA 246
#define LLRP_TLV_HOPPING_EVENT 247
#define LLRP_TLV_GPI_EVENT 248
#define LLRP_TLV_RO_SPEC_EVENT 249
#define LLRP_TLV_REPORT_BUF_LEVEL_WARN 250
#define LLRP_TLV_REPORT_BUF_OVERFLOW_ERR 251
#define LLRP_TLV_READER_EXCEPTION_EVENT 252
#define LLRP_TLV_RF_SURVEY_EVENT 253
#define LLRP_TLV_AI_SPEC_EVENT 254
#define LLRP_TLV_ANTENNA_EVENT 255
#define LLRP_TLV_CONN_ATTEMPT_EVENT 256
#define LLRP_TLV_CONN_CLOSE_EVENT 257
#define LLRP_TLV_LLRP_STATUS 287
#define LLRP_TLV_FIELD_ERROR 288
#define LLRP_TLV_PARAM_ERROR 289
#define LLRP_TLV_C1G2_LLRP_CAP 327
#define LLRP_TLV_C1G2_UHF_RF_MD_TBL 328
#define LLRP_TLV_C1G2_UHF_RF_MD_TBL_ENT 329
#define LLRP_TLV_C1G2_INVENTORY_COMMAND 330
#define LLRP_TLV_C1G2_FILTER 331
#define LLRP_TLV_C1G2_TAG_INV_MASK 332
#define LLRP_TLV_C1G2_TAG_INV_AWARE_FLTR 333
#define LLRP_TLV_C1G2_TAG_INV_UNAWR_FLTR 334
#define LLRP_TLV_C1G2_RF_CONTROL 335
#define LLRP_TLV_C1G2_SINGULATION_CTRL 336
#define LLRP_TLV_C1G2_TAG_INV_AWARE_SING 337
#define LLRP_TLV_C1G2_TAG_SPEC 338
#define LLRP_TLV_C1G2_TARGET_TAG 339
#define LLRP_TLV_C1G2_READ 341
#define LLRP_TLV_C1G2_WRITE 342
#define LLRP_TLV_C1G2_KILL 343
#define LLRP_TLV_C1G2_LOCK 344
#define LLRP_TLV_C1G2_LOCK_PAYLOAD 345
#define LLRP_TLV_C1G2_BLK_ERASE 346
#define LLRP_TLV_C1G2_BLK_WRITE 347
#define LLRP_TLV_C1G2_EPC_MEMORY_SLCTOR 348
#define LLRP_TLV_C1G2_READ_OP_SPEC_RES 349
#define LLRP_TLV_C1G2_WRT_OP_SPEC_RES 350
#define LLRP_TLV_C1G2_KILL_OP_SPEC_RES 351
#define LLRP_TLV_C1G2_LOCK_OP_SPEC_RES 352
#define LLRP_TLV_C1G2_BLK_ERS_OP_SPC_RES 353
#define LLRP_TLV_C1G2_BLK_WRT_OP_SPC_RES 354
#define LLRP_TLV_LOOP_SPEC 355
#define LLRP_TLV_MAX_RECEIVE_SENSE 363
#define LLRP_TLV_RF_SURVEY_FREQ_CAP 365
static const value_string tlv_type[] = {
{ LLRP_TLV_UTC_TIMESTAMP, "UTC Timestamp" },
{ LLRP_TLV_UPTIME, "Uptime" },
{ LLRP_TLV_GENERAL_DEVICE_CAP, "General Device Capabilities" },
{ LLRP_TLV_RECEIVE_SENSE_ENTRY, "Receive Sensitivity Entry" },
{ LLRP_TLV_ANTENNA_AIR_PROTO, "Antenna Air Protocol" },
{ LLRP_TLV_GPIO_CAPABILITIES, "GPIO Capabilities" },
{ LLRP_TLV_LLRP_CAPABILITIES, "LLRP Capabilities" },
{ LLRP_TLV_REGU_CAPABILITIES, "REGU Capabilities" },
{ LLRP_TLV_UHF_CAPABILITIES, "UHF Capabilities" },
{ LLRP_TLV_XMIT_POWER_LEVEL_ENTRY, "Transmit Power Level Entry" },
{ LLRP_TLV_FREQ_INFORMATION, "Frequency Information" },
{ LLRP_TLV_FREQ_HOP_TABLE, "Frequenct Hop Table" },
{ LLRP_TLV_FIXED_FREQ_TABLE, "Fixed Frequency Table" },
{ LLRP_TLV_ANTENNA_RCV_SENSE_RANGE, "Antenna RCV Sensitivity Range" },
{ LLRP_TLV_RO_SPEC, "RO Spec" },
{ LLRP_TLV_RO_BOUND_SPEC, "RO Bound Spec" },
{ LLRP_TLV_RO_SPEC_START_TRIGGER, "RO Spec Start Trigger" },
{ LLRP_TLV_PER_TRIGGER_VAL, "PER Trigger Value" },
{ LLRP_TLV_GPI_TRIGGER_VAL, "GPI Trigger Value" },
{ LLRP_TLV_RO_SPEC_STOP_TRIGGER, "RO Spec Stop Trigger" },
{ LLRP_TLV_AI_SPEC, "AI Spec" },
{ LLRP_TLV_AI_SPEC_STOP, "AI Spec Stop" },
{ LLRP_TLV_TAG_OBSERV_TRIGGER, "Tag Observation Trigger" },
{ LLRP_TLV_INVENTORY_PARAM_SPEC, "Inventory Parameter Spec ID" },
{ LLRP_TLV_RF_SURVEY_SPEC, "RF Survey Spec" },
{ LLRP_TLV_RF_SURVEY_SPEC_STOP_TR, "RF Survey Spec Stop Trigger" },
{ LLRP_TLV_ACCESS_SPEC, "Access Spec" },
{ LLRP_TLV_ACCESS_SPEC_STOP_TRIG, "Access Spec Stop Trigger" },
{ LLRP_TLV_ACCESS_COMMAND, "Access Command" },
{ LLRP_TLV_CLIENT_REQ_OP_SPEC, "Client Request Op Spec" },
{ LLRP_TLV_CLIENT_REQ_RESPONSE, "Client Request Response" },
{ LLRP_TLV_LLRP_CONF_STATE_VAL, "LLRP Configuration State Value" },
{ LLRP_TLV_IDENT, "Identification" },
{ LLRP_TLV_GPO_WRITE_DATA, "GPO Write Data" },
{ LLRP_TLV_KEEPALIVE_SPEC, "Keepalive Spec" },
{ LLRP_TLV_ANTENNA_PROPS, "Antenna Properties" },
{ LLRP_TLV_ANTENNA_CONF, "Antenna Configuration" },
{ LLRP_TLV_RF_RECEIVER, "RF Receiver" },
{ LLRP_TLV_RF_TRANSMITTER, "RF Transmitter" },
{ LLRP_TLV_GPI_PORT_CURRENT_STATE, "GPI Port Current State" },
{ LLRP_TLV_EVENTS_AND_REPORTS, "Events And Reports" },
{ LLRP_TLV_RO_REPORT_SPEC, "RO Report Spec" },
{ LLRP_TLV_TAG_REPORT_CONTENT_SEL, "Tag Report Content Selector" },
{ LLRP_TLV_ACCESS_REPORT_SPEC, "Access Report Spec" },
{ LLRP_TLV_TAG_REPORT_DATA, "Tag Report Data" },
{ LLRP_TLV_EPC_DATA, "EPC Data" },
{ LLRP_TLV_RF_SURVEY_REPORT_DATA, "RF Survey Report Data" },
{ LLRP_TLV_FREQ_RSSI_LEVEL_ENTRY, "Frequency RSSI Level Entry" },
{ LLRP_TLV_READER_EVENT_NOTI_SPEC, "Reader Event Notification Spec" },
{ LLRP_TLV_EVENT_NOTIF_STATE, "Event Notification State" },
{ LLRP_TLV_READER_EVENT_NOTI_DATA, "Reader Event Notification Data" },
{ LLRP_TLV_HOPPING_EVENT, "Hopping Event" },
{ LLRP_TLV_GPI_EVENT, "GPI Event" },
{ LLRP_TLV_RO_SPEC_EVENT, "RO Spec Event" },
{ LLRP_TLV_REPORT_BUF_LEVEL_WARN, "Report Buffer Level Warning Event" },
{ LLRP_TLV_REPORT_BUF_OVERFLOW_ERR, "Report Buffer Overflow Error Event" },
{ LLRP_TLV_READER_EXCEPTION_EVENT, "Reader Exception Event" },
{ LLRP_TLV_RF_SURVEY_EVENT, "RF Survey Event" },
{ LLRP_TLV_AI_SPEC_EVENT, "AI Spec Event" },
{ LLRP_TLV_ANTENNA_EVENT, "ANTENNA Event" },
{ LLRP_TLV_CONN_ATTEMPT_EVENT, "CONN Attempt Event" },
{ LLRP_TLV_CONN_CLOSE_EVENT, "CONN Close Event" },
{ LLRP_TLV_LLRP_STATUS, "LLRP Status" },
{ LLRP_TLV_FIELD_ERROR, "Field Error" },
{ LLRP_TLV_PARAM_ERROR, "Param Error" },
{ LLRP_TLV_C1G2_LLRP_CAP, "C1G2 LLRP Capabilities" },
{ LLRP_TLV_C1G2_UHF_RF_MD_TBL, "C1G2 UHF RF Mode Table" },
{ LLRP_TLV_C1G2_UHF_RF_MD_TBL_ENT, "C1G2 UHF RF Mode Table Entry" },
{ LLRP_TLV_C1G2_INVENTORY_COMMAND, "C1G2 Inventory Command" },
{ LLRP_TLV_C1G2_FILTER, "C1G2 Filter" },
{ LLRP_TLV_C1G2_TAG_INV_MASK, "C1G2 Tag Inventory Mask" },
{ LLRP_TLV_C1G2_TAG_INV_AWARE_FLTR, "C1G2 Tag Inventory State-Aware Filtre Action" },
{ LLRP_TLV_C1G2_TAG_INV_UNAWR_FLTR, "C1G2 Tag Inventory State-Unaware Filter Action" },
{ LLRP_TLV_C1G2_RF_CONTROL, "C1G2 RF Control" },
{ LLRP_TLV_C1G2_SINGULATION_CTRL, "C1G2 Singulation Control" },
{ LLRP_TLV_C1G2_TAG_INV_AWARE_SING, "C1G2 Tag Inventory State-Aware Singulation" },
{ LLRP_TLV_C1G2_TAG_SPEC, "C1G2 Tag Spec" },
{ LLRP_TLV_C1G2_TARGET_TAG, "C1G2 Target Tag" },
{ LLRP_TLV_C1G2_READ, "C1G2 Read" },
{ LLRP_TLV_C1G2_WRITE, "C1G2 Write" },
{ LLRP_TLV_C1G2_KILL, "C1G2 Kill" },
{ LLRP_TLV_C1G2_LOCK, "C1G2 Lock" },
{ LLRP_TLV_C1G2_LOCK_PAYLOAD, "C1G2 Lock Payload" },
{ LLRP_TLV_C1G2_BLK_ERASE, "C1G2 Block Erase" },
{ LLRP_TLV_C1G2_BLK_WRITE, "C1G2 Block Write" },
{ LLRP_TLV_C1G2_EPC_MEMORY_SLCTOR, "C1G2 EPC Memory Selector" },
{ LLRP_TLV_C1G2_READ_OP_SPEC_RES, "C1G2 Read Op Spec Result" },
{ LLRP_TLV_C1G2_WRT_OP_SPEC_RES, "C1G2 Write Op Spec Result" },
{ LLRP_TLV_C1G2_KILL_OP_SPEC_RES, "C1G2 Kill Op Spec Result" },
{ LLRP_TLV_C1G2_LOCK_OP_SPEC_RES, "C1G2 Lock Op Spec Result" },
{ LLRP_TLV_C1G2_BLK_ERS_OP_SPC_RES, "C1G2 Block Erase Op Spec Result" },
{ LLRP_TLV_C1G2_BLK_WRT_OP_SPC_RES, "C1G2 Block Write Op Spec Result" },
{ LLRP_TLV_LOOP_SPEC, "Loop Spec" },
{ LLRP_TLV_MAX_RECEIVE_SENSE, "Maximum Receive Sensitivity" },
{ LLRP_TLV_RF_SURVEY_FREQ_CAP, "RF Survey Frequency Capabilities" },
{ 0, NULL }
};
/* TV Parameter Types */
#define LLRP_TV_ANTENNA_ID 1
#define LLRP_TV_FIRST_SEEN_TIME_UTC 2
#define LLRP_TV_FIRST_SEEN_TIME_UPTIME 3
#define LLRP_TV_LAST_SEEN_TIME_UTC 4
#define LLRP_TV_LAST_SEEN_TIME_UPTIME 5
#define LLRP_TV_PEAK_RSSI 6
#define LLRP_TV_CHANNEL_INDEX 7
#define LLRP_TV_TAG_SEEN_COUNT 8
#define LLRP_TV_RO_SPEC_ID 9
#define LLRP_TV_INVENTORY_PARAM_SPEC_ID 10
#define LLRP_TV_C1G2_CRC 11
#define LLRP_TV_C1G2_PC 12
#define LLRP_TV_EPC96 13
#define LLRP_TV_SPEC_INDEX 14
#define LLRP_TV_CLIENT_REQ_OP_SPEC_RES 15
#define LLRP_TV_ACCESS_SPEC_ID 16
#define LLRP_TV_OP_SPEC_ID 17
#define LLRP_TV_C1G2_SINGULATION_DET 18
#define LLRP_TV_C1G2_XPC_W1 19
#define LLRP_TV_C1G2_XPC_W2 20
/* Since TV's don't have a length field,
* use these values instead */
#define LLRP_TV_LEN_ANTENNA_ID 2
#define LLRP_TV_LEN_FIRST_SEEN_TIME_UTC 8
#define LLRP_TV_LEN_FIRST_SEEN_TIME_UPTIME 8
#define LLRP_TV_LEN_LAST_SEEN_TIME_UTC 8
#define LLRP_TV_LEN_LAST_SEEN_TIME_UPTIME 8
#define LLRP_TV_LEN_PEAK_RSSI 1
#define LLRP_TV_LEN_CHANNEL_INDEX 2
#define LLRP_TV_LEN_TAG_SEEN_COUNT 2
#define LLRP_TV_LEN_RO_SPEC_ID 4
#define LLRP_TV_LEN_INVENTORY_PARAM_SPEC_ID 2
#define LLRP_TV_LEN_C1G2_CRC 2
#define LLRP_TV_LEN_C1G2_PC 2
#define LLRP_TV_LEN_EPC96 2
#define LLRP_TV_LEN_SPEC_INDEX 2
#define LLRP_TV_LEN_CLIENT_REQ_OP_SPEC_RES 2
#define LLRP_TV_LEN_ACCESS_SPEC_ID 4
#define LLRP_TV_LEN_OP_SPEC_ID 2
#define LLRP_TV_LEN_C1G2_SINGULATION_DET 4
#define LLRP_TV_LEN_C1G2_XPC_W1 2
#define LLRP_TV_LEN_C1G2_XPC_W2 2
static const value_string tv_type[] = {
{ LLRP_TV_ANTENNA_ID, "Antenna ID" },
{ LLRP_TV_FIRST_SEEN_TIME_UTC, "First Seen Timestamp UTC" },
{ LLRP_TV_FIRST_SEEN_TIME_UPTIME, "First Seen Timestamp Uptime" },
{ LLRP_TV_LAST_SEEN_TIME_UTC, "Last Seen Timestamp UTC" },
{ LLRP_TV_LAST_SEEN_TIME_UPTIME, "Last Seen Timestamp Uptime" },
{ LLRP_TV_PEAK_RSSI, "Peak RSSI" },
{ LLRP_TV_CHANNEL_INDEX, "Channel Index" },
{ LLRP_TV_TAG_SEEN_COUNT, "Tag Seen Count" },
{ LLRP_TV_RO_SPEC_ID, "RO Spec ID" },
{ LLRP_TV_INVENTORY_PARAM_SPEC_ID, "Inventory Parameter Spec ID" },
{ LLRP_TV_C1G2_CRC, "C1G2 CRC" },
{ LLRP_TV_C1G2_PC, "C1G2 PC" },
{ LLRP_TV_EPC96, "EPC-96" },
{ LLRP_TV_SPEC_INDEX, "Spec Index" },
{ LLRP_TV_CLIENT_REQ_OP_SPEC_RES, "Client Request Op Spec Result" },
{ LLRP_TV_ACCESS_SPEC_ID, "Access Spec ID" },
{ LLRP_TV_OP_SPEC_ID, "Op Spec ID" },
{ LLRP_TV_C1G2_SINGULATION_DET, "C1G2 Singulation Details" },
{ LLRP_TV_C1G2_XPC_W1, "C1G2 XPC W1" },
{ LLRP_TV_C1G2_XPC_W2, "C1G2 XPC W2" },
{ 0, NULL }
};
/* Misc */
#define LLRP_ROSPEC_ALL 0
#define LLRP_ANTENNA_ALL 0
#define LLRP_GPI_PORT_ALL 0
#define LLRP_GPO_PORT_ALL 0
#define LLRP_ACCESSSPEC_ALL 0
#define LLRP_TLV_LEN_MIN 4
#define LLRP_LEN_MIN 10
static void
dissect_llrp_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint offset)
{
guint8 has_length;
guint16 len, type;
guint real_len;
proto_item *ti;
proto_tree *param_tree;
while (tvb_reported_length_remaining(tvb, offset) > 0)
{
has_length = !(tvb_get_guint8(tvb, offset) & 0x80);
if (has_length)
{
len = tvb_get_ntohs(tvb, offset + 2);
if (len < LLRP_TLV_LEN_MIN)
real_len = LLRP_TLV_LEN_MIN;
else if (len > tvb_reported_length_remaining(tvb, offset))
real_len = tvb_reported_length_remaining(tvb, offset);
else
real_len = len;
ti = proto_tree_add_none_format(tree, hf_llrp_param, tvb,
offset, real_len, "TLV Parameter");
param_tree = proto_item_add_subtree(ti, ett_llrp_param);
proto_tree_add_item(param_tree, hf_llrp_tlv_type, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
ti = proto_tree_add_item(param_tree, hf_llrp_tlv_len, tvb,
offset, 2, ENC_BIG_ENDIAN);
if (len != real_len)
expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
"Invalid length field: claimed %u, should be %u.",
len, real_len);
offset += 2;
/* TODO: Decode actual TLV parameter fields */
/* The len field includes the 4-byte parameter header that we've
* already accounted for in offset */
offset += real_len - 4;
}
else
{
type = tvb_get_guint8(tvb, offset) & 0x7F;
/* TODO: Decode actual TV fields rather than just jumping
* ahead the correct length */
switch (type)
{
case LLRP_TV_ANTENNA_ID:
real_len = LLRP_TV_LEN_ANTENNA_ID; break;
case LLRP_TV_FIRST_SEEN_TIME_UTC:
real_len = LLRP_TV_LEN_FIRST_SEEN_TIME_UTC; break;
case LLRP_TV_FIRST_SEEN_TIME_UPTIME:
real_len = LLRP_TV_LEN_FIRST_SEEN_TIME_UPTIME; break;
case LLRP_TV_LAST_SEEN_TIME_UTC:
real_len = LLRP_TV_LEN_LAST_SEEN_TIME_UTC; break;
case LLRP_TV_LAST_SEEN_TIME_UPTIME:
real_len = LLRP_TV_LEN_LAST_SEEN_TIME_UPTIME; break;
case LLRP_TV_PEAK_RSSI:
real_len = LLRP_TV_LEN_PEAK_RSSI; break;
case LLRP_TV_CHANNEL_INDEX:
real_len = LLRP_TV_LEN_CHANNEL_INDEX; break;
case LLRP_TV_TAG_SEEN_COUNT:
real_len = LLRP_TV_LEN_TAG_SEEN_COUNT; break;
case LLRP_TV_RO_SPEC_ID:
real_len = LLRP_TV_LEN_RO_SPEC_ID; break;
case LLRP_TV_INVENTORY_PARAM_SPEC_ID:
real_len = LLRP_TV_LEN_INVENTORY_PARAM_SPEC_ID; break;
case LLRP_TV_C1G2_CRC:
real_len = LLRP_TV_LEN_C1G2_CRC; break;
case LLRP_TV_C1G2_PC:
real_len = LLRP_TV_LEN_C1G2_PC; break;
case LLRP_TV_EPC96:
real_len = LLRP_TV_LEN_EPC96; break;
case LLRP_TV_SPEC_INDEX:
real_len = LLRP_TV_LEN_SPEC_INDEX; break;
case LLRP_TV_CLIENT_REQ_OP_SPEC_RES:
real_len = LLRP_TV_LEN_CLIENT_REQ_OP_SPEC_RES; break;
case LLRP_TV_ACCESS_SPEC_ID:
real_len = LLRP_TV_LEN_ACCESS_SPEC_ID; break;
case LLRP_TV_OP_SPEC_ID:
real_len = LLRP_TV_LEN_OP_SPEC_ID; break;
case LLRP_TV_C1G2_SINGULATION_DET:
real_len = LLRP_TV_LEN_C1G2_SINGULATION_DET; break;
case LLRP_TV_C1G2_XPC_W1:
real_len = LLRP_TV_LEN_C1G2_XPC_W1; break;
case LLRP_TV_C1G2_XPC_W2:
real_len = LLRP_TV_LEN_C1G2_XPC_W2; break;
default:
/* ???
* No need to mark it, since the hf_llrp_tv_type field
* will already show up as 'unknown'. */
real_len = 0;
break;
};
ti = proto_tree_add_none_format(tree, hf_llrp_param, tvb,
offset, real_len + 1, "TV Parameter");
param_tree = proto_item_add_subtree(ti, ett_llrp_param);
proto_tree_add_item(param_tree, hf_llrp_tv_type, tvb,
offset, 1, ENC_NA);
offset++;
/* Unlike for TLV's, real_len for TV's doesn't include the standard
* header length, so just add it straight to the offset. */
offset += real_len;
}
}
}
static void
dissect_llrp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint16 type, guint offset)
{
guint8 requested_data;
guint16 antenna_id, gpi_port, gpo_port;
guint32 spec_id;
proto_item *ti;
switch (type)
{
/* Simple cases just have normal TLV or TV parameters */
case LLRP_TYPE_CLOSE_CONNECTION_RESPONSE:
case LLRP_TYPE_GET_READER_CAPABILITES_RESPONSE:
case LLRP_TYPE_ADD_ROSPEC:
case LLRP_TYPE_ADD_ROSPEC_RESPONSE:
case LLRP_TYPE_DELETE_ROSPEC_RESPONSE:
case LLRP_TYPE_START_ROSPEC_RESPONSE:
case LLRP_TYPE_STOP_ROSPEC_RESPONSE:
case LLRP_TYPE_ENABLE_ROSPEC_RESPONSE:
case LLRP_TYPE_DISABLE_ROSPEC_RESPONSE:
case LLRP_TYPE_GET_ROSPECS_RESPONSE:
case LLRP_TYPE_ADD_ACCESSSPEC:
case LLRP_TYPE_ADD_ACCESSSPEC_RESPONSE:
case LLRP_TYPE_DELETE_ACCESSSPEC_RESPONSE:
case LLRP_TYPE_ENABLE_ACCESSSPEC_RESPONSE:
case LLRP_TYPE_DISABLE_ACCESSSPEC_RESPONSE:
case LLRP_TYPE_GET_ACCESSSPECS:
case LLRP_TYPE_CLIENT_REQUEST_OP:
case LLRP_TYPE_CLIENT_RESQUEST_OP_RESPONSE:
case LLRP_TYPE_RO_ACCESS_REPORT:
case LLRP_TYPE_READER_EVENT_NOTIFICATION:
case LLRP_TYPE_ERROR_MESSAGE:
case LLRP_TYPE_GET_READER_CONFIG_RESPONSE:
case LLRP_TYPE_SET_READER_CONFIG_RESPONSE:
case LLRP_TYPE_SET_PROTOCOL_VERSION_RESPONSE:
case LLRP_TYPE_GET_ACCESSSPECS_RESPONSE:
case LLRP_TYPE_GET_REPORT:
case LLRP_TYPE_ENABLE_EVENTS_AND_REPORTS:
dissect_llrp_parameters(tvb, pinfo, tree, offset);
break;
/* Some just have an ROSpec ID */
case LLRP_TYPE_START_ROSPEC:
case LLRP_TYPE_STOP_ROSPEC:
case LLRP_TYPE_ENABLE_ROSPEC:
case LLRP_TYPE_DISABLE_ROSPEC:
case LLRP_TYPE_DELETE_ROSPEC:
spec_id = tvb_get_ntohl(tvb, offset);
if (spec_id == LLRP_ROSPEC_ALL)
proto_tree_add_uint_format(tree, hf_llrp_rospec, tvb,
offset, 4, spec_id, "All ROSpecs (%u)", spec_id);
else
proto_tree_add_item(tree, hf_llrp_rospec, tvb,
offset, 4, ENC_BIG_ENDIAN);
break;
/* Some just have an AccessSpec ID */
case LLRP_TYPE_ENABLE_ACCESSSPEC:
case LLRP_TYPE_DELETE_ACCESSSPEC:
case LLRP_TYPE_DISABLE_ACCESSSPEC:
spec_id = tvb_get_ntohl(tvb, offset);
if (spec_id == LLRP_ACCESSSPEC_ALL)
proto_tree_add_uint_format(tree, hf_llrp_accessspec, tvb,
offset, 4, spec_id, "All Access Specs (%u)", spec_id);
else
proto_tree_add_item(tree, hf_llrp_accessspec, tvb,
offset, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_llrp_accessspec, tvb, offset, 4, ENC_BIG_ENDIAN);
break;
case LLRP_TYPE_GET_READER_CAPABILITES:
proto_tree_add_item(tree, hf_llrp_req_cap, tvb, offset, 1, ENC_NA);
offset++;
dissect_llrp_parameters(tvb, pinfo, tree, offset);
break;
/* GET_READER_CONFIG is complicated */
case LLRP_TYPE_GET_READER_CONFIG:
requested_data = tvb_get_guint8(tvb, offset + 2);
switch (requested_data)
{
case LLRP_CONF_ALL:
antenna_id = tvb_get_ntohs(tvb, offset);
if (antenna_id == LLRP_ANTENNA_ALL)
proto_tree_add_uint_format(tree, hf_llrp_antenna_id, tvb,
offset, 2, antenna_id, "All Antennas (%u)", antenna_id);
else
proto_tree_add_item(tree, hf_llrp_antenna_id, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_llrp_req_conf, tvb,
offset, 1, ENC_NA);
offset++;
gpi_port = tvb_get_ntohs(tvb, offset);
if (gpi_port == LLRP_GPI_PORT_ALL)
proto_tree_add_uint_format(tree, hf_llrp_gpi_port, tvb,
offset, 2, gpi_port, "All GPI Ports (%u)", gpi_port);
else
proto_tree_add_item(tree, hf_llrp_gpi_port, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
gpo_port = tvb_get_ntohs(tvb, offset);
if (gpo_port == LLRP_GPO_PORT_ALL)
proto_tree_add_uint_format(tree, hf_llrp_gpo_port, tvb,
offset, 2, gpo_port, "All GPO Ports (%u)", gpo_port);
else
proto_tree_add_item(tree, hf_llrp_gpo_port, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
case LLRP_CONF_ANTENNA_PROPERTIES:
case LLRP_CONF_ANTENNA_CONFIGURATION:
antenna_id = tvb_get_ntohs(tvb, offset);
if (antenna_id == LLRP_ANTENNA_ALL)
proto_tree_add_uint_format(tree, hf_llrp_antenna_id, tvb,
offset, 2, antenna_id, "All Antennas (%u)", antenna_id);
else
proto_tree_add_item(tree, hf_llrp_antenna_id, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_llrp_req_conf, tvb,
offset, 1, ENC_NA);
offset++;
offset += 4; /* Skip both GPI and GPO ports */
break;
case LLRP_CONF_IDENTIFICATION:
case LLRP_CONF_RO_REPORT_SPEC:
case LLRP_CONF_READER_EVENT_NOTIFICATION_SPEC:
case LLRP_CONF_ACCESS_REPORT_SPEC:
case LLRP_CONF_LLRP_CONFIGURATION_STATE:
case LLRP_CONF_KEEPALIVE_SPEC:
case LLRP_CONF_EVENTS_AND_REPORTS:
offset += 2; /* Skip antenna ID */
proto_tree_add_item(tree, hf_llrp_req_conf, tvb,
offset, 1, ENC_NA);
offset++;
offset += 4; /* Skip both GPI and GPO ports */
break;
case LLRP_CONF_GPI_PORT_CURRENT_STATE:
offset += 2; /* Skip antenna ID */
proto_tree_add_item(tree, hf_llrp_req_conf, tvb,
offset, 1, ENC_NA);
offset++;
gpi_port = tvb_get_ntohs(tvb, offset);
if (gpi_port == LLRP_GPI_PORT_ALL)
proto_tree_add_uint_format(tree, hf_llrp_gpi_port, tvb,
offset, 2, gpi_port, "All GPI Ports (%u)", gpi_port);
else
proto_tree_add_item(tree, hf_llrp_gpi_port, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
offset += 2; /* Skip GPO Port */
break;
case LLRP_CONF_GPO_WRITE_DATA:
offset += 2; /* Skip antenna ID */
proto_tree_add_item(tree, hf_llrp_req_conf, tvb,
offset, 1, ENC_NA);
offset++;
offset += 2; /* Skip GPI Port */
gpo_port = tvb_get_ntohs(tvb, offset);
if (gpo_port == LLRP_GPO_PORT_ALL)
proto_tree_add_uint_format(tree, hf_llrp_gpo_port, tvb,
offset, 2, gpo_port, "All GPO Ports (%u)", gpo_port);
else
proto_tree_add_item(tree, hf_llrp_gpo_port, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
break;
default:
offset += 2; /* Skip antenna ID */
ti = proto_tree_add_item(tree, hf_llrp_req_conf, tvb,
offset, 1, ENC_NA);
expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
"Unrecognized configuration request: %u",
requested_data);
offset++;
offset += 4; /* Skip both GPI and GPO ports */
break;
};
dissect_llrp_parameters(tvb, pinfo, tree, offset);
break;
/* END GET_READER_CONFIG */
/* Misc */
case LLRP_TYPE_SET_READER_CONFIG:
proto_tree_add_item(tree, hf_llrp_rest_fact, tvb, offset, 1, ENC_NA);
offset++;
dissect_llrp_parameters(tvb, pinfo, tree, offset);
break;
case LLRP_TYPE_SET_PROTOCOL_VERSION:
proto_tree_add_item(tree, hf_llrp_version, tvb, offset, 1, ENC_NA);
break;
case LLRP_TYPE_GET_SUPPORTED_VERSION_RESPONSE:
proto_tree_add_item(tree, hf_llrp_cur_ver, tvb, offset, 1, ENC_NA);
offset++;
proto_tree_add_item(tree, hf_llrp_sup_ver, tvb, offset, 1, ENC_NA);
offset++;
dissect_llrp_parameters(tvb, pinfo, tree, offset);
break;
case LLRP_TYPE_CUSTOM_MESSAGE:
proto_tree_add_item(tree, hf_llrp_vendor, tvb, offset, 4, ENC_BIG_ENDIAN);
break;
/* Some have no extra data expected */
case LLRP_TYPE_KEEPALIVE:
case LLRP_TYPE_KEEPALIVE_ACK:
case LLRP_TYPE_CLOSE_CONNECTION:
case LLRP_TYPE_GET_ROSPECS:
case LLRP_TYPE_GET_SUPPORTED_VERSION:
break;
default:
/* We shouldn't be called if we don't already recognize the value */
DISSECTOR_ASSERT_NOT_REACHED();
};
}
/* Code to actually dissect the packets */
static int
dissect_llrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_tree *llrp_tree;
guint16 type;
guint32 len;
guint offset = 0;
/* Check that there's enough data */
if (tvb_reported_length(tvb) < LLRP_LEN_MIN)
return 0;
/* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLRP");
col_set_str(pinfo->cinfo, COL_INFO, "LLRP Message");
type = tvb_get_ntohs(tvb, offset) & 0x03FF;
col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
val_to_str(type, message_types, "Unknown Type: %d"));
if (tree)
{
ti = proto_tree_add_item(tree, proto_llrp, tvb, offset, -1, ENC_NA);
llrp_tree = proto_item_add_subtree(ti, ett_llrp);
proto_tree_add_item(llrp_tree, hf_llrp_version, tvb, offset, 1, ENC_NA);
proto_tree_add_item(llrp_tree, hf_llrp_type, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
ti = proto_tree_add_item(llrp_tree, hf_llrp_length, tvb, offset, 4, ENC_BIG_ENDIAN);
len = tvb_get_ntohl(tvb, offset);
if (len > tvb_reported_length(tvb))
{
expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
"Incorrect length field: claimed %u, but only have %u.",
len, tvb_reported_length(tvb));
}
offset += 4;
proto_tree_add_item(llrp_tree, hf_llrp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
if (match_strval(type, message_types))
dissect_llrp_message(tvb, pinfo, llrp_tree, type, offset);
}
return tvb_length(tvb);
}
void
proto_register_llrp(void)
{
/* Setup list of header fields See Section 1.6.1 for details*/
static hf_register_info hf[] = {
{ &hf_llrp_version,
{ "Version", "llrp.version", FT_UINT8, BASE_DEC, VALS(llrp_versions), 0x1C,
NULL, HFILL }},
{ &hf_llrp_type,
{ "Type", "llrp.type", FT_UINT16, BASE_DEC, VALS(message_types), 0x03FF,
NULL, HFILL }},
{ &hf_llrp_length,
{ "Length", "llrp.length", FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_id,
{ "ID", "llrp.id", FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_cur_ver,
{ "Current Version", "llrp.cur_ver", FT_UINT8, BASE_DEC, VALS(llrp_versions), 0,
NULL, HFILL }},
{ &hf_llrp_sup_ver,
{ "Supported Version", "llrp.sup_ver", FT_UINT8, BASE_DEC, VALS(llrp_versions), 0,
"The max supported protocol version.", HFILL }},
{ &hf_llrp_req_cap,
{ "Requested Capabilities", "llrp.req_cap", FT_UINT8, BASE_DEC, VALS(capabilities_request), 0,
NULL, HFILL }},
{ &hf_llrp_req_conf,
{ "Requested Configuration", "llrp.req_conf", FT_UINT8, BASE_DEC, VALS(config_request), 0,
NULL, HFILL }},
{ &hf_llrp_rospec,
{ "ROSpec ID", "llrp.rospec", FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_antenna_id,
{ "Antenna ID", "llrp.antenna_id", FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_gpi_port,
{ "GPI Port Number", "llrp.gpi_port", FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_gpo_port,
{ "GPO Port Number", "llrp.gpo_port", FT_UINT16, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_rest_fact,
{ "Restore Factory Settings", "llrp.rest_fact", FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x80,
NULL, HFILL }},
{ &hf_llrp_accessspec,
{ "Access Spec ID", "llrp.accessspec", FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_vendor,
{ "Vendor ID", "llrp.vendor", FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
{ &hf_llrp_tlv_type,
{ "Type", "llrp.tlv_type", FT_UINT16, BASE_DEC, VALS(tlv_type), 0x03FF,
"The type of TLV.", HFILL }},
{ &hf_llrp_tv_type,
{ "Type", "llrp.tv_type", FT_UINT8, BASE_DEC, VALS(tv_type), 0x7F,
"The type of TV.", HFILL }},
{ &hf_llrp_tlv_len,
{ "Length", "llrp.tlv_len", FT_UINT16, BASE_DEC, NULL, 0,
"The length of this TLV.", HFILL }},
{ &hf_llrp_param,
{ "Parameter", "llrp.param", FT_NONE, BASE_NONE, NULL, 0,
NULL, HFILL }}
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_llrp,
&ett_llrp_param
};
/* Register the protocol name and description */
proto_llrp = proto_register_protocol("Low Level Reader Protocol",
"LLRP", "llrp");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_llrp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_llrp(void)
{
dissector_handle_t llrp_handle;
llrp_handle = new_create_dissector_handle(dissect_llrp, proto_llrp);
dissector_add_uint("tcp.port", LLRP_PORT, llrp_handle);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=4 expandtab:
* :indentSize=4:tabSize=4:noTabs=true:
*/
|