19
19
#define pnal_eth_get_status mock_pnal_eth_get_status
20
20
#endif
21
21
22
+ #define STRINGIFY (s ) STRINGIFIED (s)
23
+ #define STRINGIFIED (s ) #s
24
+
22
25
/**
23
26
* @file
24
27
* @brief Implements Link Layer Discovery Protocol (LLDP), for neighbourhood
@@ -280,27 +283,23 @@ static void pf_lldp_add_chassis_id_tlv (
280
283
/**
281
284
* @internal
282
285
* Insert the mandatory port_id TLV into a buffer.
283
- * @param p_port_cfg In: LLDP configuration for this port
286
+ * @param p_port_id In: Port Id
284
287
* @param p_buf InOut: The buffer.
285
288
* @param p_pos InOut: The position in the buffer.
286
289
*/
287
290
static void pf_lldp_add_port_id_tlv (
288
- const pnet_port_cfg_t * p_port_cfg ,
291
+ const pf_lldp_port_id_t * p_port_id ,
289
292
uint8_t * p_buf ,
290
293
uint16_t * p_pos )
291
294
{
292
- uint16_t len ;
293
-
294
- len = (uint16_t )strlen (p_port_cfg -> port_id );
295
-
296
- pf_lldp_add_tlv_header (p_buf , p_pos , LLDP_TYPE_PORT_ID , 1 + len );
297
-
298
- pf_put_byte (
299
- PF_LLDP_SUBTYPE_LOCALLY_ASSIGNED ,
295
+ pf_lldp_add_tlv_header (p_buf , p_pos , LLDP_TYPE_PORT_ID , 1 + p_port_id -> len );
296
+ pf_put_byte (p_port_id -> subtype , PF_FRAME_BUFFER_SIZE , p_buf , p_pos );
297
+ pf_put_mem (
298
+ p_port_id -> string ,
299
+ p_port_id -> len ,
300
300
PF_FRAME_BUFFER_SIZE ,
301
301
p_buf ,
302
302
p_pos );
303
- pf_put_mem (p_port_cfg -> port_id , len , PF_FRAME_BUFFER_SIZE , p_buf , p_pos );
304
303
}
305
304
306
305
/**
@@ -575,34 +574,42 @@ void pf_lldp_get_chassis_id (pnet_t * net, pf_lldp_chassis_id_t * p_chassis_id)
575
574
pf_cmina_get_device_macaddr (net );
576
575
char station_name [PNET_STATION_NAME_MAX_SIZE ]; /** Terminated */
577
576
578
- /* Try to use NameOfStation as Chassis ID.
579
- *
580
- * FIXME: Use of pf_cmina_get_station_name() is not thread-safe.
581
- * Fix this, e.g. using a mutex.
582
- *
583
- * TODO: Add option to use SystemIdentification as Chassis ID.
584
- * See IEC61158-6-10 table 361.
585
- */
586
- pf_cmina_get_station_name (net , station_name );
587
-
588
- p_chassis_id -> len = strlen (station_name );
589
- if (p_chassis_id -> len == 0 || p_chassis_id -> len >= PNET_LLDP_CHASSIS_ID_MAX_SIZE )
577
+ if (net -> interface .name_of_device_mode == PF_LLDP_NAME_OF_DEVICE_MODE_LEGACY )
590
578
{
591
- /* Use the device MAC address */
592
- p_chassis_id -> subtype = PF_LLDP_SUBTYPE_MAC ;
593
- p_chassis_id -> len = sizeof (pnet_ethaddr_t );
594
- memcpy (
595
- p_chassis_id -> string ,
596
- device_mac_address -> addr ,
597
- sizeof (pnet_ethaddr_t ));
579
+ /*
580
+ * FIXME: Use of pf_cmina_get_station_name() is not thread-safe.
581
+ * Fix this, e.g. using a mutex.
582
+ */
583
+ pf_cmina_get_station_name (net , station_name );
584
+ p_chassis_id -> len = strlen (station_name );
585
+
586
+ if (
587
+ p_chassis_id -> len == 0 ||
588
+ p_chassis_id -> len >= PNET_LLDP_CHASSIS_ID_MAX_SIZE )
589
+ {
590
+ /* Use the device MAC address */
591
+ p_chassis_id -> subtype = PF_LLDP_SUBTYPE_MAC ;
592
+ p_chassis_id -> len = sizeof (pnet_ethaddr_t );
593
+ memcpy (
594
+ p_chassis_id -> string ,
595
+ device_mac_address -> addr ,
596
+ sizeof (pnet_ethaddr_t ));
597
+ }
598
+ else
599
+ {
600
+ /* Use the station name (NameOfStation/NameOfInterface) */
601
+ p_chassis_id -> subtype = PF_LLDP_SUBTYPE_LOCALLY_ASSIGNED ;
602
+ memcpy (p_chassis_id -> string , station_name , p_chassis_id -> len );
603
+ }
598
604
}
599
- else
605
+ else /* PF_LLDP_NAME_OF_DEVICE_MODE_STANDARD */
600
606
{
601
- /* Use the locally assigned chassis ID name */
602
607
p_chassis_id -> subtype = PF_LLDP_SUBTYPE_LOCALLY_ASSIGNED ;
603
- memcpy (p_chassis_id -> string , station_name , p_chassis_id -> len );
608
+ p_chassis_id -> len = pf_lldp_get_system_description (
609
+ net ,
610
+ p_chassis_id -> string ,
611
+ sizeof (p_chassis_id -> string ));
604
612
}
605
-
606
613
p_chassis_id -> string [p_chassis_id -> len ] = '\0' ;
607
614
p_chassis_id -> is_valid = true;
608
615
}
@@ -627,12 +634,35 @@ void pf_lldp_get_port_id (
627
634
pf_lldp_port_id_t * p_port_id )
628
635
{
629
636
const pnet_port_cfg_t * p_port_cfg = pf_port_get_config (net , loc_port_num );
637
+ char station_name [PNET_STATION_NAME_MAX_SIZE ]; /** Terminated */
638
+
639
+ if (net -> interface .name_of_device_mode == PF_LLDP_NAME_OF_DEVICE_MODE_LEGACY )
640
+ {
641
+ snprintf (
642
+ p_port_id -> string ,
643
+ sizeof (p_port_id -> string ),
644
+ "%s" ,
645
+ p_port_cfg -> port_name );
646
+ }
647
+ else /* PF_LLDP_NAME_OF_DEVICE_MODE_STANDARD */
648
+ {
649
+ pf_cmina_get_station_name (net , station_name );
650
+ if (strlen (station_name ) == 0 )
651
+ {
652
+ pf_lldp_mac_address_to_string (
653
+ p_port_cfg -> phy_port .eth_addr .addr ,
654
+ station_name ,
655
+ sizeof (station_name ));
656
+ }
657
+
658
+ snprintf (
659
+ p_port_id -> string ,
660
+ sizeof (p_port_id -> string ),
661
+ "%s.%s" ,
662
+ p_port_cfg -> port_name ,
663
+ station_name );
664
+ }
630
665
631
- snprintf (
632
- p_port_id -> string ,
633
- sizeof (p_port_id -> string ),
634
- "%s" ,
635
- p_port_cfg -> port_id );
636
666
p_port_id -> subtype = PF_LLDP_SUBTYPE_LOCALLY_ASSIGNED ;
637
667
p_port_id -> len = strlen (p_port_id -> string );
638
668
p_port_id -> is_valid = true;
@@ -719,26 +749,100 @@ int pf_lldp_get_peer_station_name (
719
749
int loc_port_num ,
720
750
pf_lldp_station_name_t * p_station_name )
721
751
{
722
- bool is_received ;
752
+ pf_lldp_chassis_id_t chassis_id ;
753
+ pf_lldp_port_id_t port_id ;
754
+ char * p ;
755
+ bool found = false;
756
+
723
757
const pf_port_t * p_port_data = pf_port_get_state (net , loc_port_num );
758
+ memset (p_station_name , 0 , sizeof (* p_station_name ));
724
759
725
760
os_mutex_lock (net -> lldp_mutex );
761
+ port_id = p_port_data -> lldp .peer_info .port_id ;
762
+ chassis_id = p_port_data -> lldp .peer_info .chassis_id ;
763
+ os_mutex_unlock (net -> lldp_mutex );
764
+
765
+ if (port_id .is_valid )
766
+ {
767
+ p = strchr (port_id .string , '.' );
768
+ if (p != NULL )
769
+ {
770
+ /* PF_LLDP_NAME_OF_DEVICE_MODE_STANDARD
771
+ * Example: port-001.dut
772
+ */
773
+ snprintf (
774
+ p_station_name -> string ,
775
+ sizeof (p_station_name -> string ),
776
+ "%s" ,
777
+ p + 1 );
778
+ found = true;
779
+ }
780
+ }
781
+
782
+ if (!found && chassis_id .is_valid )
783
+ {
784
+ /* PF_LLDP_NAME_OF_DEVICE_MODE_LEGACY */
785
+ if (chassis_id .subtype != PF_LLDP_SUBTYPE_MAC )
786
+ {
787
+ snprintf (
788
+ p_station_name -> string ,
789
+ sizeof (p_station_name -> string ),
790
+ "%s" ,
791
+ chassis_id .string );
792
+ }
793
+ else
794
+ {
795
+ pf_lldp_mac_address_to_string (
796
+ (uint8_t * )chassis_id .string ,
797
+ p_station_name -> string ,
798
+ sizeof (p_station_name -> string ));
799
+ }
800
+ found = true;
801
+ }
802
+
803
+ /* Do not use peer mac address here since its status is unknown. */
726
804
727
- /* Assume that peer's NameOfStation is the same as its ChassisId.
728
- * TODO: Find out the correct way to choose what value to return.
729
- * Value should be part of either received Chassis ID or Port ID.
730
- */
731
- memset (p_station_name , 0 , sizeof (* p_station_name ));
732
- snprintf (
733
- p_station_name -> string ,
734
- sizeof (p_station_name -> string ),
735
- "%s" ,
736
- p_port_data -> lldp .peer_info .chassis_id .string );
737
805
p_station_name -> len = strlen (p_station_name -> string );
738
- is_received = p_port_data -> lldp .peer_info .chassis_id .is_valid ;
739
806
807
+ return p_station_name -> len ? 0 : -1 ;
808
+ }
809
+
810
+ int pf_lldp_get_peer_port_name (
811
+ pnet_t * net ,
812
+ int loc_port_num ,
813
+ pf_lldp_port_name_t * p_port_name )
814
+ {
815
+ pf_lldp_port_id_t port_id ;
816
+ uint16_t i ;
817
+ const pf_port_t * p_port_data = pf_port_get_state (net , loc_port_num );
818
+ memset (p_port_name , 0 , sizeof (* p_port_name ));
819
+
820
+ os_mutex_lock (net -> lldp_mutex );
821
+ port_id = p_port_data -> lldp .peer_info .port_id ;
740
822
os_mutex_unlock (net -> lldp_mutex );
741
- return is_received ? 0 : -1 ;
823
+
824
+ if (port_id .is_valid )
825
+ {
826
+ for (i = 0 ; (i < port_id .len ) && (port_id .string [i ] != '\0' ) &&
827
+ (i < (sizeof (p_port_name -> string ) - 1 ));
828
+ i ++ )
829
+ {
830
+ if (port_id .string [i ] == '.' )
831
+ {
832
+ /* PF_LLDP_NAME_OF_DEVICE_MODE_STANDARD */
833
+ break ;
834
+ }
835
+ p_port_name -> string [i ] = port_id .string [i ];
836
+ }
837
+
838
+ p_port_name -> len = strlen (p_port_name -> string );
839
+ }
840
+ else
841
+ {
842
+ return -1 ;
843
+ }
844
+
845
+ return p_port_name -> len ? 0 : -1 ;
742
846
}
743
847
744
848
void pf_lldp_get_signal_delays (
@@ -812,6 +916,48 @@ int pf_lldp_get_peer_link_status (
812
916
return p_link_status -> is_valid ? 0 : -1 ;
813
917
}
814
918
919
+ size_t pf_lldp_get_system_description (
920
+ const pnet_t * net ,
921
+ char * system_description ,
922
+ size_t system_description_max_len )
923
+ {
924
+ return snprintf (
925
+ system_description ,
926
+ system_description_max_len ,
927
+ /* clang-format off */
928
+ "%-" STRINGIFY (PNET_PRODUCT_NAME_MAX_LEN ) "s "
929
+ " %- " STRINGIFY (PNET_ORDER_ID_MAX_LEN) " s "
930
+ " %- " STRINGIFY (PNET_SERIAL_NUMBER_MAX_LEN) " s "
931
+ " %5u "
932
+ "%c%3u%3u%3u" ,
933
+ /* clang-format on */
934
+ net -> fspm_cfg .product_name ,
935
+ net -> fspm_cfg .im_0_data .im_order_id ,
936
+ net -> fspm_cfg .im_0_data .im_serial_number ,
937
+ net -> fspm_cfg .im_0_data .im_hardware_revision ,
938
+ net -> fspm_cfg .im_0_data .im_sw_revision_prefix ,
939
+ net -> fspm_cfg .im_0_data .im_sw_revision_functional_enhancement ,
940
+ net -> fspm_cfg .im_0_data .im_sw_revision_bug_fix ,
941
+ net -> fspm_cfg .im_0_data .im_sw_revision_internal_change );
942
+ }
943
+
944
+ void pf_lldp_mac_address_to_string (
945
+ const uint8_t * mac ,
946
+ char * mac_str ,
947
+ size_t mac_str_max_len )
948
+ {
949
+ snprintf (
950
+ mac_str ,
951
+ mac_str_max_len ,
952
+ "%02X-%02X-%02X-%02X-%02X-%02X" ,
953
+ mac [0 ],
954
+ mac [1 ],
955
+ mac [2 ],
956
+ mac [3 ],
957
+ mac [4 ],
958
+ mac [5 ]);
959
+ }
960
+
815
961
/**
816
962
* Construct Ethernet frame containing LLDP PDU as payload
817
963
*
@@ -830,6 +976,7 @@ size_t pf_lldp_construct_frame (pnet_t * net, int loc_port_num, uint8_t buf[])
830
976
pf_cmina_get_device_macaddr (net );
831
977
pf_lldp_link_status_t link_status ;
832
978
pf_lldp_chassis_id_t chassis_id ;
979
+ pf_lldp_port_id_t port_id ;
833
980
pf_lldp_management_address_t man_address ;
834
981
const pnet_port_cfg_t * p_port_cfg = pf_port_get_config (net , loc_port_num );
835
982
@@ -838,7 +985,9 @@ size_t pf_lldp_construct_frame (pnet_t * net, int loc_port_num, uint8_t buf[])
838
985
char ip_string [PNAL_INET_ADDRSTR_SIZE ] = {0 }; /** Terminated string */
839
986
const char * chassis_id_description = "<MAC address>" ;
840
987
#endif
988
+
841
989
pf_lldp_get_chassis_id (net , & chassis_id );
990
+ pf_lldp_get_port_id (net , loc_port_num , & port_id );
842
991
pf_lldp_get_link_status (net , loc_port_num , & link_status );
843
992
pf_lldp_get_management_address (net , & man_address );
844
993
#if LOG_DEBUG_ENABLED (PF_LLDP_LOG )
@@ -862,7 +1011,7 @@ size_t pf_lldp_construct_frame (pnet_t * net, int loc_port_num, uint8_t buf[])
862
1011
device_mac_address -> addr [5 ],
863
1012
ip_string ,
864
1013
chassis_id_description ,
865
- p_port_cfg -> port_id );
1014
+ port_id . string );
866
1015
#endif
867
1016
868
1017
pos = 0 ;
@@ -875,7 +1024,7 @@ size_t pf_lldp_construct_frame (pnet_t * net, int loc_port_num, uint8_t buf[])
875
1024
876
1025
/* Add mandatory parts */
877
1026
pf_lldp_add_chassis_id_tlv (& chassis_id , buf , & pos );
878
- pf_lldp_add_port_id_tlv (p_port_cfg , buf , & pos );
1027
+ pf_lldp_add_port_id_tlv (& port_id , buf , & pos );
879
1028
pf_lldp_add_ttl_tlv (buf , & pos );
880
1029
881
1030
/* Add optional parts */
0 commit comments