6 |
7 | enum switch_phy
8 | {
9 | switch_phy_0 = 0,
10 | switch_phy_1 = 1,
11 | switch_phy_2 = 2,
12 | switch_phy_3 = 3,
13 | switch_phy_4 = 4,
14 | switch_phy_serdes = 15,
15 | };
16 |
17 | enum switch_dev_addr
18 | {
19 | switch_dev_addr_port0 = 0x10,
20 | switch_dev_addr_port1 = 0x11,
21 | switch_dev_addr_port2 = 0x12,
22 | switch_dev_addr_port3 = 0x13,
23 | switch_dev_addr_port4 = 0x14,
24 | switch_dev_addr_port5 = 0x15,
25 | switch_dev_addr_port6 = 0x16,
26 | switch_dev_addr_global1 = 0x1B,
27 | switch_dev_addr_global2 = 0x1C,
28 | switch_dev_addr_global3 = 0x1D,
29 | };
30 |
31 | void switch_power_up_phys (uint32_t mdio_addr);
32 | uint32_t switch_read_register (uint32_t mdio_addr, switch_dev_addr dev_addr, uint32_t reg_addr);
33 | void switch_write_register (uint32_t mdio_addr, switch_dev_addr dev_addr, uint32_t reg_addr, uint32_t value);
34 | uint32_t switch_read_phy_register (uint32_t mdio_addr, switch_phy phy, uint32_t reg_addr);
35 | void switch_write_phy_register (uint32_t mdio_addr, switch_phy phy, uint32_t reg_addr, uint32_t value);
36 | #endif
37 |
--------------------------------------------------------------------------------
/TestAppTM4C129+88E6352/test.c:
--------------------------------------------------------------------------------
1 |
2 | #include "../mstp-lib/stp.h"
3 |
--------------------------------------------------------------------------------
/_help/BlankForm.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Untitled Page
7 |
8 |
9 | name
10 |
11 |
12 | void __stdcall
13 | (
14 | unsigned int
15 | );
16 |
17 |
18 | Summary
19 |
20 |
21 |
22 | Parameters
23 |
24 |
25 |
26 |
27 |
28 | Return value
29 |
30 | If the function succeeds: STATUS_SUCCESS
.
31 | If the function fails: a STATUS
enumeration value
32 | other than STATUS_SUCCESS
.
33 |
34 |
35 | Remarks
36 |
37 |
38 | Function information
39 |
40 |
41 | Include header
42 | aaa.h
43 |
44 |
45 | Required source code
46 | aaa.cpp
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/_help/STP_CALLBACKS.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_CALLBACKS
7 |
8 |
9 | STP_CALLBACKS
10 |
11 |
12 | struct STP_CALLBACKS
13 | {
14 | STP_CALLBACK_ENABLE_BPDU_TRAPPING enableBpduTrapping ;
15 | STP_CALLBACK_ENABLE_LEARNING enableLearning ;
16 | STP_CALLBACK_ENABLE_FORWARDING enableForwarding ;
17 | STP_CALLBACK_TRANSMIT_GET_BUFFER transmitGetBuffer ;
18 | STP_CALLBACK_TRANSMIT_RELEASE_BUFFER transmitReleaseBuffer ;
19 | STP_CALLBACK_FLUSH_FDB flushFdb ;
20 | STP_CALLBACK_DEBUG_STR_OUT debugStrOut ;
21 | STP_CALLBACK_ON_TOPOLOGY_CHANGE onTopologyChange ;
22 | STP_CALLBACK_PORT_ROLE_CHANGED onPortRoleChanged ;
23 | STP_CALLBACK_ALLOC_AND_ZERO_MEMORY allocAndZeroMemory ;
24 | STP_CALLBACK_FREE_MEMORY freeMemory ;
25 | };
26 |
27 | Summary
28 |
29 | Structure containing pointers to application-defined STP callbacks. These callbacks
30 | implement the hardware-specific and platform-specific functionality required by STP, such
31 | as enabling forwarding on a physical port, or allocating memory, or displaying debug text
32 | generated by the STP library.
33 |
34 | Members
35 |
36 |
37 |
38 | Remarks
39 |
40 | All these callbacks are called from within library functions such as
41 | STP_CreateBridge , STP_SetPortPriority ,
42 | STP_OnBpduReceived etc. With other words,
43 | first the application calls some library function, then that function calls application's
44 | STP callbacks to do hardware-specific work, and then the function returns.
45 |
46 | The application is allowed to call from within these callbacks only Get-type library functions.
47 | Set-type library functions (those that alter the STP operation) must not be
48 | called from within these callbacks.
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/_help/STP_DestroyBridge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_DestroyBridge
7 |
8 |
9 | STP_DestroyBridge
10 |
11 | void STP_DestroyBridge (STP_BRIDGE* bridge)
12 |
13 | Summary
14 |
15 | Releases all memory allocated for the given bridge.
16 |
17 | Parameters
18 |
19 | bridge
20 | Pointer to a STP_BRIDGE object, obtained from
21 | STP_CreateBridge .
22 |
23 |
24 | Remarks
25 |
26 | The bridge must be stopped when this function is called (i.e., must have never been
27 | started, or must have been stopped with STP_StopBridge ).
28 |
29 | This function may not be called from within an STP callback .
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/_help/STP_EnableLogging.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_EnableLogging
7 |
8 |
9 | STP_EnableLogging
10 |
11 |
12 | void STP_EnableLogging
13 | (
14 | STP_BRIDGE* bridge,
15 | bool enable
16 | );
17 |
18 |
19 | Summary
20 |
21 | Enables or disable debug logging on a bridge.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | enable
29 | true
to enable logging, false
to disable it.
30 |
31 |
32 | Remarks
33 |
34 | Support for debug logging can be disabled by defining STP_USE_LOG=0 in
35 | the compiler options. This excludes most logging-related code from compilation,
36 | and it saves about 9 KB of Flash in a GnuARM Release build, and about
37 | 14 KB of Flash in a GnuARM Debug build.
38 |
39 |
40 |
--------------------------------------------------------------------------------
/_help/STP_GetBridgeAddress.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetBridgeAddress
7 |
8 |
9 | STP_GetBridgeAddress
10 |
11 |
12 | const struct STP_BRIDGE_ADDRESS* STP_GetBridgeAddress
13 | (
14 | const STP_BRIDGE* bridge,
15 | );
16 |
17 |
18 | Summary
19 |
20 | Gets the bridge address that was set with
21 | STP_CreateBridge or STP_SetBridgeAddress .
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 |
29 |
30 | Return Value
31 |
32 | Pointer to the bridge address.
33 |
34 | Remarks
35 |
36 | See the Remarks section in STP_SetBridgePriority for information on how the bridge priority is calculated from the bridge address.
37 |
38 | It is allowed to call this function from within an STP callback .
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/_help/STP_GetBridgePriority.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetBridgePriority
7 |
8 |
9 | STP_GetBridgePriority
10 |
11 |
12 | unsigned short STP_GetBridgePriority
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int treeIndex
16 | );
17 |
18 |
19 | Summary
20 |
21 | Reads the bridge priority, that is, the priority component - most significant 4 bits - of
22 | the BridgeIdentifier (§13.26.2 in 802.1Q-2018).
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to a STP_BRIDGE object, obtained from
28 | STP_CreateBridge .
29 | treeIndex
30 | The zero-based index of the spanning tree for which the bridge priority is to be
31 | returned. For STP or RSTP, this must be zero. For MSTP, this must be zero for the CIST, or
32 | 1..64 for an MSTI.
33 |
34 |
35 | Return value
36 |
37 | The bridge priority. This is a number between 0 and 61440 (0xF000) hex, in steps of 4096
38 | (0x1000 hex).
39 |
40 |
41 | Remarks
42 |
43 | See the Remarks section at STP_SetBridgePriority
44 | for more information about the bridge priority and about the BridgeIndentifier.
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/_help/STP_GetMstConfigId.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetMstConfigId
7 |
8 |
9 | STP_GetMstConfigId
10 |
11 |
12 | const struct STP_MST_CONFIG_ID* STP_GetMstConfigId
13 | (
14 | const STP_BRIDGE* bridge,
15 | );
16 |
17 |
18 | Summary
19 |
20 | Retrieves a pointer to the MST Configuration Identifier.
21 |
22 | Parameters
23 |
24 | bridge
25 | Pointer to a STP_BRIDGE object.
26 | nameOut
27 | Pointer to an array of chars where this function will write the name.
28 |
29 |
30 | Remarks
31 |
32 | You can call this function even while the bridge is not running MSTP.
33 |
34 | See §13.8 in 802.1Q-2018 for more information about the MST Configuration Identifier.
35 |
36 | It is allowed to call this function from within an STP callback .
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/_help/STP_GetMstConfigTable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetMstConfigTable
7 |
8 |
9 | STP_GetMstConfigTable
10 |
11 |
12 | const struct STP_CONFIG_TABLE_ENTRY* STP_GetMstConfigTable
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int* entryCountOut
16 | );
17 |
18 |
19 | Summary
20 |
21 | Retrieves a pointer to the MST configuration table (the VLAN to tree mapping).
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to an STP_BRIDGE object.
27 | entryCountOut
28 | Pointer to a variable where this function writes the number
29 | of entries available. This is maxVlanNumber + 1
,
30 | where maxVlanNumber
is the parameter that was
31 | passed to STP_CreateBridge .
32 |
33 |
34 | Return Value
35 |
36 | The function returns a pointer to the table kept internally by the library.
37 |
38 | Remarks
39 |
40 | You can call this function even when the bridge is not running MSTP.
41 |
42 | Element at index 0 of the table is unused and contains the value 0. Element at index 1 corresponds to VLAN 1, element at index 1 corresponds to VLAN 2 and so on. The table can contain up to 4096 elements.
43 |
44 | See §13.8 in 802.1Q-2018 for more information about the MST Configuration Identifier.
45 |
46 | It is allowed to call this function from within an STP callback .
47 |
48 | See also STP_SetMstConfigTable .
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/_help/STP_GetMstiCount.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetMstiCount
7 |
8 |
9 | STP_GetMstiCount
10 |
11 |
12 | unsigned int STP_GetMstiCount (const STP_BRIDGE* bridge);
13 |
14 |
15 | Summary
16 |
17 | Returns the number of MSTIs on the bridge. This is the value passed to
18 | STP_CreateBridge .
19 |
20 | Parameters
21 |
22 | bridge
23 | Pointer to a STP_BRIDGE object.
24 |
25 |
26 | Return value
27 |
28 | The MSTI count.
29 |
30 | Remarks
31 | It is allowed to call this function from within an STP callback .
32 |
33 |
34 |
--------------------------------------------------------------------------------
/_help/STP_GetPortAdminPointToPointMAC.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortAdminPointToPointMAC
7 |
8 |
9 | STP_GetPortAdminPointToPointMAC
10 |
11 |
12 | STP_ADMIN_P2P STP_GetPortAdminPointToPointMAC
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | );
17 |
18 |
19 | Summary
20 |
21 | Gets the adminPointToPointMAC
variable for a given port.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | portIndex
29 | The index of the port.
30 |
31 |
32 | Remarks
33 |
34 | See §11.3 in 802.1AC-2016 for more information.
35 |
36 | This function may be called from within an STP callback .
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/_help/STP_GetPortAutoEdge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortAutoEdge
7 |
8 |
9 | STP_GetPortAutoEdge
10 |
11 |
12 | bool STP_GetPortAutoEdge
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | );
17 |
18 |
19 | Summary
20 |
21 | Gets the AutoEdge
variable for a given port.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | portIndex
29 | The index of the port.
30 |
31 |
32 | Remarks
33 |
34 | See §13.27.18 in 802.1Q-2018 for more information.
35 |
36 | The STP Library initializes this variable to TRUE, as recommended in the standard.
37 |
38 | This function may be called from within an STP callback .
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/_help/STP_GetPortCount.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortCount
7 |
8 |
9 | STP_GetPortCount
10 |
11 |
12 | unsigned int STP_GetPortCount (const STP_BRIDGE* bridge);
13 |
14 |
15 | Summary
16 |
17 | Returns the number of ports on the bridge. This is the value passed to
18 | STP_CreateBridge .
19 |
20 | Parameters
21 |
22 | bridge
23 | Pointer to a STP_BRIDGE object.
24 |
25 |
26 | Return value
27 |
28 | The port count.
29 |
30 |
31 | Remarks
32 |
33 | It is allowed to call this function from within an STP callback .
34 |
35 |
36 |
--------------------------------------------------------------------------------
/_help/STP_GetPortEnabled.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortEnabled
7 |
8 |
9 | STP_GetPortEnabled
10 |
11 |
12 | bool STP_GetPortEnabled
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex
16 | );
17 |
18 |
19 | Summary
20 |
21 | Reads the portEnabled
variable (§13.27.45 in 802.1Q-2018).
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | portIndex
29 | The zero-based index of the port.
30 |
31 |
32 | Return value
33 |
34 | This function returns true
if STP_OnPortEnabled was called last.
35 | It returns false
if STP_OnPortDisabled was called last,
36 | or the bridge was just created with STP_CreateBridge .
37 |
38 |
39 | Remarks
40 |
41 | It is allowed to call this function from within an STP callback .
42 |
43 |
44 |
--------------------------------------------------------------------------------
/_help/STP_GetPortIdentifier.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortIdentifier
7 |
8 |
9 | STP_GetPortIdentifier
10 |
11 |
12 | unsigned short STP_GetPortIdentifier
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex
17 | );
18 |
19 |
20 | Summary
21 |
22 | Returns the port identifier portId
for a given port and a given tree.
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to a STP_BRIDGE object.
28 | portIndex
29 | The zero-based index of the port.
30 | treeIndex
31 | The zero-based index of the spanning tree for which the portId is to be read. For
32 | STP or RSTP, this must be zero. For MSTP, this must be zero for the CIST, or 1..64 for an
33 | MSTI.
34 |
35 |
36 | Return value
37 |
38 | The port identifier. This is a number between 0 and 244, in steps of 16.
39 |
40 |
41 | Remarks
42 |
43 | See §13.27.46 in 802.1Q-2018 for more details.
44 |
45 | It is allowed to call this function from within an STP callback .
46 |
47 |
48 |
--------------------------------------------------------------------------------
/_help/STP_GetPortOperPointToPointMAC.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortOperPointToPointMAC
7 |
8 |
9 | STP_GetPortOperPointToPointMAC
10 |
11 |
12 | bool STP_GetPortOperPointToPointMAC
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | );
17 |
18 |
19 | Summary
20 |
21 | Gets the operPointToPointMAC
variable for a given port.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | portIndex
29 | The index of the port.
30 |
31 |
32 | Remarks
33 |
34 | See §11.3 in 802.1AC-2016 for more information.
35 |
36 | This function may be called from within an STP callback .
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/_help/STP_GetPortPriority.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetPortPriority
7 |
8 |
9 | STP_GetPortPriority
10 |
11 |
12 | unsigned char STP_GetPortPriority
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex
17 | );
18 |
19 |
20 | Summary
21 |
22 | Reads the priority component - most significant 4 bits - of the portId. See §13.27.46 in
23 | 802.1Q-2018 for more details.
24 |
25 | Parameters
26 |
27 | bridge
28 | Pointer to a STP_BRIDGE object, obtained from
29 | STP_CreateBridge .
30 | portIndex
31 | The zero-based index of the port.
32 | treeIndex
33 | The zero-based index of the spanning tree for which the port priority is to be read. For
34 | STP or RSTP, this must be zero. For MSTP, this must be zero for the CIST, or 1..64 for an
35 | MSTI.
36 |
37 |
38 | Return value
39 |
40 | The port priority. This is a number between 0 and 244, in steps of 16.
41 |
42 |
43 | Remarks
44 |
45 | It is allowed to call this function from within an STP callback .
46 |
47 |
48 |
--------------------------------------------------------------------------------
/_help/STP_GetTreeIndexFromVlanNumber.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetTreeIndexFromVlanNumber
7 |
8 |
9 | STP_GetTreeIndexFromVlanNumber
10 |
11 |
12 | unsigned int STP_GetTreeIndexFromVlanNumber
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int vlanNumber
16 | );
17 |
18 |
19 | Summary
20 |
21 | Retrieves a tree index mapped to a given VLAN.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object.
27 | vlanNumber
28 | The VLAN number. This must be between zero (inclusive) and the maxVlanNumber
29 | parameter that was passed to STP_CreateBridge (inclusive).
30 |
31 |
32 | Return value
33 |
34 | The tree index mapped to the specified VLAN.
35 |
36 |
37 | Remarks
38 |
39 | You can call this function from within an STP callback.
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/_help/STP_GetVersionString.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetVersionString
7 |
8 |
9 | STP_GetVersionString
10 |
11 |
12 | const char* STP_GetVersionString
13 | (
14 | enum STP_VERSION version
15 | );
16 |
17 |
18 | Summary
19 |
20 | Converts an STP_VERSION value to its string representation.
21 |
22 | Parameters
23 |
24 | version
25 | One of the STP_VERSION_XXX values.
26 |
27 |
28 | Remarks
29 |
30 | The function checks with an assertion that the parameter is a known enum value.
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/_help/STP_IsBridgeStarted.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_IsBridgeStarted
7 |
8 |
9 | STP_IsBridgeStarted
10 |
11 |
12 | bool STP_IsBridgeStarted (const STP_BRIDGE* bridge);
13 |
14 |
15 | Summary
16 |
17 | Checks whether a bridge is started or stopped.
18 |
19 | Parameters
20 |
21 | bridge
22 | Pointer to a STP_BRIDGE object, obtained from
23 | STP_CreateBridge .
24 |
25 |
26 | Return value
27 |
28 | true
if the bridge is started, false
if the bridge is stopped.
29 |
30 |
31 | Remarks
32 |
33 | A bridge can be started by calling STP_StartBridge , and
34 | stopped by calling STP_StopBridge .
35 |
36 | It is allowed to call this function from within an STP callback .
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/_help/STP_OnBpduReceived.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_OnBpduReceived
7 |
8 |
9 | STP_OnBpduReceived
10 |
11 |
12 | void STP_OnBpduReceived
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | const unsigned char* bpdu,
17 | unsigned int bpduSize,
18 | unsigned int timestamp
19 | );
20 |
21 |
22 | Summary
23 |
24 | Function which the application must call upon receiving a BPDU packet from a physical
25 | port.
26 |
27 | Parameters
28 |
29 | bridge
30 | Pointer to an STP_BRIDGE object, obtained from
31 | STP_CreateBridge .
32 | portIndex
33 | The index of the port from which this BPDU was received. This information is usually
34 | inserted by the switch IC into the Ethernet frame, after the switch IC was
35 | configured to do so by
36 | StpCallback_EnableBpduTrapping .
37 | bpdu
38 | Pointer to the BPDU payload, located in an Ethernet frame just after the LLC field.
39 | bpduSize
40 | Size of the BPDU payload.
41 | timestamp
42 | A timestamp used for the debug log.
43 |
44 |
45 | Remarks
46 |
47 | Execution of this function is a potentially lengthy process.
48 | It may call various callbacks multiple times.
49 |
50 |
51 | It is allowed to call this function for stopped bridges. In this case it will ignore the BPDU and return immediately.
52 |
53 | This function validates the length of the BPDU before processing its content. It ignores
54 | truncated BPDUs.
55 |
56 | It is recommended that the application, before passing a received BPDU frame to the STP
57 | library, performs a check for malformed frames by comparing the value in the
58 | EtherType/Size field of the frame to the length of the received frame. Such malformed
59 | frames should be discarded, not passed to the STP library.
60 |
61 |
62 | It is recommended that the application, after receiving a BPDU from the bridge IC
63 | and before passing the BPDU to this function, checks that it has up-to-date
64 | information about the "operational" status of the physical port from which it received the
65 | BPDU. Depending on the hardware particularities, it is possible that an application first
66 | 1) receives an Ethernet packet from a physical port, and then 2)
67 | receives information from that port about the link having just been established (e.g.,
68 | cable just connected). If the application finds itself in this condition upon receiving a
69 | BPDU, it should first call STP_OnPortEnabled , and
70 | only then STP_OnBpduReceived; the timestamp should be the same value for both calls.
71 |
72 | This function may not be called from within an STP callback .
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/_help/STP_OnOneSecondTick.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_OnOneSecondTick
7 |
8 |
9 | STP_OnOneSecondTick
10 |
11 |
12 | void STP_OnOneSecondTick
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int timestamp
16 | );
17 |
18 |
19 | Summary
20 |
21 | Function which the application must call approximately once every second.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | timestamp
29 | A timestamp used for the debug log.
30 |
31 |
32 | Remarks
33 |
34 | If the application runs multiple bridges, is it recommended that a single periodic timer
35 | is set up, and that this function is called for each bridge when this timer triggers, with the same
36 | value for timestamp
37 | for all bridges. This makes it easier to
38 | visualize in the debug log which tick triggered which actions on which
39 | bridge.
40 |
41 |
42 | Execution of this function is a potentially lengthy process.
43 | It may call various callbacks multiple times.
44 |
45 | It is allowed to call this function for stopped bridges. In this case it will return
46 | immediately.
47 |
48 | If many devices are wired in the same STP network, it is recommended that the timer
49 | period is not identical on all devices, but spread a little around the one-second value
50 | (for instance, between 950 and 1050 ms). This helps avoid bursts of STP activity occurring
51 | on all devices at the same time. Note that there's still a chance these bursts are
52 | once in a while synchronized accross the network, so the whole system must still be
53 | designed to handle them.
54 |
55 | This function may not be called from within an STP callback .
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/_help/STP_OnPortDisabled.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_OnPortDisabled
7 |
8 |
9 | STP_OnPortDisabled
10 |
11 |
12 | void STP_OnPortDisabled
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int timestampMilliseconds
17 | );
18 |
19 |
20 | Summary
21 |
22 | Function which the application must call when
23 | the operational state of a port changes to FALSE. See the Remarks section of this page for
24 | more details, and also the Remarks section of
25 | STP_OnPortEnabled .
26 |
27 | Parameters
28 |
29 | bridge
30 | Pointer to a STP_BRIDGE object, obtained from
31 | STP_CreateBridge .
32 | portIndex
33 | The index of the port whose operational state has just changed to FALSE.
34 | timestamp
35 | A timestamp used for the debug log.
36 |
37 |
38 | Remarks
39 |
40 | Also see the Remarks section of STP_OnPortEnabled .
41 |
42 | It is allowed to call this function for already disabled ports.
43 |
44 |
45 | Execution of this function is a potentially lengthy process.
46 | It may call various callbacks multiple times.
47 |
48 | This function may not be called from within an STP callback .
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/_help/STP_SetBridgeAddress.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetBridgeAddress
7 |
8 |
9 | STP_SetBridgeAddress
10 |
11 |
12 | void STP_SetBridgeAddress
13 | (
14 | STP_BRIDGE* bridge,
15 | const unsigned char* address,
16 | unsigned int timestamp
17 | );
18 |
19 |
20 | Summary
21 |
22 | Function which the application must call every time the MAC address
23 | of the management microcontroller/processor changes, for example when
24 | the end user changes it in a web interface or a CLI.
25 |
26 | Parameters
27 |
28 | bridge
29 | Pointer to an STP_BRIDGE object, obtained from
30 | STP_CreateBridge .
31 | address
32 | The new MAC address.
33 | timestamp
34 | A timestamp used for the debug log.
35 |
36 |
37 | Remarks
38 |
39 | Execution of this function is a potentially lengthy process.
40 | It may call various callbacks multiple times.
41 |
42 | See the Remarks section in STP_SetBridgePriority for information on how the bridge priority is calculated from the bridge address.
43 |
44 | This function may not be called from within an STP callback .
45 |
46 |
47 |
--------------------------------------------------------------------------------
/_help/STP_SetBridgePriority.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetBridgePriority
7 |
18 |
19 |
20 | STP_SetBridgePriority
21 |
22 |
23 | void STP_SetBridgePriority
24 | (
25 | STP_BRIDGE* bridge,
26 | unsigned int treeIndex,
27 | unsigned short bridgePriority,
28 | unsigned int timestamp
29 | );
30 |
31 |
32 | Summary
33 |
34 | Sets the settable priority component - most significant 4 bits - of the BridgeIdentifier
35 | (§13.26.2 in 802.1Q-2018).
36 |
37 | Parameters
38 |
39 | bridge
40 | Pointer to a STP_BRIDGE object, obtained from
41 | STP_CreateBridge .
42 | treeIndex
43 | The index of the spanning tree for which bridge priority is to be set. For STP or RSTP,
44 | this must be zero. For MSTP, this must be zero for the CIST, or 1..64 for an MSTI.
45 | bridgePriority
46 | A value specifiying the bridge priority. Must be between 0 and 61440 (0xF000 hex), in
47 | steps of 4096 (0x1000 hex).
48 | timestamp
49 | A timestamp used for the debug log.
50 |
51 |
52 | Remarks
53 |
54 | Default priority is 32768 (0x8000 hex). This default priority is assigned to a bridge when
55 | it is created with STP_CreateBridge .
56 |
57 | The BridgeIdentifier for a given spanning tree is usually represented as
58 | 8 000 .01-02-03-04-05-06 and consists of:
60 |
61 | 4 bits set by this function . These are the most
62 | significant bits.
63 | 12 bits with the "system ID extension" , which for
64 | STP and RSTP
65 | is zero, and for MSTP is populated by the library with the tree index (zero for the CIST,
66 | 1..64 for MSTIs)
67 | 48 bits with the MAC address . These are the least
68 | significant bits, and they are settable with
69 | STP_SetBridgeAddress .
70 |
71 |
72 | Execution of this function is a potentially lengthy process.
73 | It may call various callbacks multiple times.
74 |
75 | This function may not be called from within an STP callback .
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/_help/STP_SetMstConfigName.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetMstConfigName
7 |
8 |
9 | STP_SetMstConfigName
10 |
11 |
12 | void STP_SetMstConfigName
13 | (
14 | STP_BRIDGE* bridge,
15 | const char* name,
16 | unsigned int timestamp
17 | );
18 |
19 |
20 | Summary
21 |
22 | Sets the Name field of the MST Configuration Identifier.
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to a STP_BRIDGE object.
28 | name
29 | The new name. This must be a null-terminated string of up to 32 characters (up to 33
30 | with the null-terminator).
31 | timestamp
32 | A timestamp used for the debug log.
33 |
34 |
35 | Remarks
36 |
37 | This function may be called only for MSTP bridges (i.e., if STP_VERSION_MSTP
was passed
38 | to STP_CreateBridge or
39 | STP_SetStpVersion ).
40 |
41 | See §13.8 in 802.1Q-2018 for more information about the MST Configuration Identifier.
42 |
43 | If this function is not called, a default configuration name is used which is generated by
44 | STP_CreateBridge . See the Remarks section there for
45 | more information.
46 |
47 | This function may not be called from within an STP callback .
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/_help/STP_SetMstConfigRevisionLevel.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_GetMstConfigRevisionLevel
7 |
8 |
9 | STP_SetMstConfigRevisionLevel
10 |
11 |
12 | void STP_SetMstConfigRevisionLevel (STP_BRIDGE* bridge, unsigned short revisionLevel);
13 |
14 |
15 | Summary
16 |
17 | Sets the Revision Level field of the MST Configuration Identifier.
18 |
19 | Parameters
20 |
21 |
22 | bridge
23 | Pointer to a STP_BRIDGE object.
24 | revisionLevel
25 | The new Revision Level value.
26 |
27 |
28 |
29 |
30 | Remarks
31 |
32 | This function may be called only for MSTP bridges (i.e., if STP_VERSION_MSTP
was passed
33 | to STP_CreateBridge or
34 | STP_SetStpVersion ).
35 |
36 | See §13.8 in 802.1Q-2018 for more information about the MST Configuration Identifier.
37 |
38 | If this function is not called, a default revision level is used which is generated by
39 | STP_CreateBridge . See the Remarks section there for
40 | more information.
41 |
42 | This function may not be called from within an STP callback .
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/_help/STP_SetMstConfigTable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetMstConfigTable
7 |
8 |
9 | STP_SetMstConfigTable
10 |
11 |
12 | void STP_SetMstConfigTable
13 | (
14 | STP_BRIDGE* bridge,
15 | const STP_CONFIG_TABLE_ENTRY* entries,
16 | unsigned int entryCount,
17 | unsigned int timestamp
18 | );
19 |
20 |
21 | Summary
22 |
23 | Sets the
24 | MST Config Table (VLAN to MSTID mapping) and computes the Digest field of the MST Configuration Identifier.
25 |
26 | Parameters
27 |
28 | bridge
29 | Pointer to a STP_BRIDGE object.
30 | table
31 | Pointer to an array of STP_CONFIG_TABLE_ENTRY, where each entry specifies a mapping
32 | between a VLAN and its corresponding MSTID. First entry is unused and must be zero; second entry
33 | specifies the tree mapped to VLAN 1; third entry specifies the tree mapped to VLAN 2; and so on.
34 | entryCount
35 | The number of entries in table
. This must be equal to 1 + maxVlanNumber
,
36 | where maxVlanNumber
is the value that was passes to STP_CreateBridge.
37 | timestamp
38 | A timestamp used for the debug log.
39 |
40 |
41 | Remarks
42 |
43 | This function
44 | can be called also when the bridge isn't running MSTP.
45 |
46 | See §13.8 in 802.1Q-2018 for more information about the MST Configuration Identifier.
47 |
48 | The caller must not attempt to map a VLAN to a non-existent tree, i.e.,
49 | the table passed to this function must contain values in the treeIndex
field that are <=
50 | mstiCount
parameter that was specified in the
51 | call to STP_CreateBridge. The STP library raises assertions for invalid values.
52 |
53 | The STP library computes the Digest as described in 13.7.d) in 802.1Q-2018.
54 |
55 | If this function is not called, a default mapping is used which is generated by
56 | STP_CreateBridge . See the Remarks section there for
57 | more information.
58 |
59 | This function may not be called from within an STP callback .
60 |
61 | See also STP_GetMstConfigTable .
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/_help/STP_SetPortAdminEdge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetPortAdminEdge
7 |
8 |
9 | STP_SetPortAdminEdge
10 |
11 |
12 | void STP_SetPortAdminEdge
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | bool adminEdge
17 | );
18 |
19 |
20 | Summary
21 |
22 | Sets the AdminEdge parameter for a given port.
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to a STP_BRIDGE object, obtained from
28 | STP_CreateBridge .
29 | portIndex
30 | The index of the port for which the AdminEdge parameter is to be set.
31 | newAdminEdge
32 | The new value of the AdminEdge parameter.
33 |
34 |
35 | Remarks
36 |
37 | See §13.27.1 in 802.1Q-2018 for more information.
38 |
39 | The current library code was not tested in scenarios where this function is called after the bridge
40 | has been started. It was only tested in scenarios where this function is called once, after STP_CreateBridge is
41 | called, and before STP_StartBridge is called.
42 |
43 |
44 | Execution of this function is a potentially lengthy process.
45 | It may call various callbacks multiple times.
46 |
47 | When a port is configured as Edge by calling this function with adminEdge
true, the
48 | library will still be sending BPDUs to that port, and will still need to receive and
49 | process BPDUs from that port. This is not a characteristic of this particular library; it is a
50 | characteristic of the STP protocol itself. This behavior is useful in case the end user
51 | configures a port as Edge by mistake (e.g., correctly configures a port as Edge in one
52 | location but later moves the switch to another location and doesn't remember to
53 | reconfigure that port.)
54 |
55 | This function may not be called from within an STP callback .
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/_help/STP_SetPortAdminPointToPointMAC.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetPortAdminPointToPointMAC
7 |
8 |
9 | STP_SetPortAdminPointToPointMAC
10 |
11 |
12 | void STP_SetPortAdminPointToPointMAC
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | STP_ADMIN_P2P adminPointToPointMAC
17 | );
18 |
19 |
20 | Summary
21 |
22 | Sets the adminPointToPointMAC
variable for a given port.
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to a STP_BRIDGE object, obtained from
28 | STP_CreateBridge .
29 | portIndex
30 | The index of the port.
31 | adminPointToPointMAC
32 | One of the STP_ADMIN_P2P values.
33 |
34 |
35 | Remarks
36 |
37 | See §11.3 in 802.1AC-2016 for more information.
38 |
39 | Execution of this function is a potentially lengthy process.
40 | It may call various callbacks multiple times.
41 |
42 | This function may not be called from within an STP callback .
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/_help/STP_SetPortAutoEdge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetPortAutoEdge
7 |
8 |
9 | STP_SetPortAutoEdge
10 |
11 |
12 | void STP_SetPortAutoEdge
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | bool autoEdge
17 | );
18 |
19 |
20 | Summary
21 |
22 | Sets the AutoEdge parameter for a given port.
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to a STP_BRIDGE object, obtained from
28 | STP_CreateBridge .
29 | portIndex
30 | The index of the port for which the AutoEdge parameter is to be set.
31 | newAutoEdge
32 | The new value of the AutoEdge parameter.
33 |
34 |
35 | Remarks
36 |
37 | For more information, see §13.27.18 in 802.1Q-2018.
38 |
39 | The STP Library initializes this variable to TRUE, as recommended in the standard.
40 |
41 |
42 | Execution of this function is a potentially lengthy process.
43 | It may call various callbacks multiple times.
44 |
45 | This function may not be called from within an STP callback .
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/_help/STP_SetPortPriority.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetPortPriority
7 |
8 |
9 | STP_SetPortPriority
10 |
11 |
12 | void STP_SetPortPriority
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex,
17 | unsigned char portPriority,
18 | unsigned int timestamp
19 | );
20 |
21 |
22 | Summary
23 |
24 | Sets the priority component - most significant 4 bits - of the portId.
25 |
26 | Parameters
27 |
28 | bridge
29 | Pointer to a STP_BRIDGE object, obtained from
30 | STP_CreateBridge .
31 | portIndex
32 | The zero-based index of the port.
33 | treeIndex
34 | The zero-based index of the spanning tree for which the port priority is to be set. For
35 | STP or RSTP, this must be zero. For MSTP, this must be zero for the CIST, or 1..64 for an
36 | MSTI.
37 | portPriority
38 | A value between 0 and 240, in steps of 16.
39 | timestamp
40 | A timestamp used for the debug log.
41 |
42 |
43 | Remarks
44 |
45 | See §13.27.46 in
46 | 802.1Q-2018 for more details.
47 |
48 | Execution of this function is a potentially lengthy process.
49 | It may call various callbacks multiple times.
50 |
51 | This function may not be called from within an STP callback .
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/_help/STP_SetStpVersion.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_SetStpVersion
7 |
8 |
9 | STP_SetStpVersion
10 |
11 |
12 | void STP_SetStpVersion
13 | (
14 | STP_BRIDGE* bridge,
15 | enum STP_VERSION version
16 | );
17 |
18 |
19 | Summary
20 |
21 | Sets the STP version of the bridge, referred to as ForceProtocolVersion in the STP
22 | standard.
23 |
24 | Parameters
25 |
26 | bridge
27 | Pointer to an STP_BRIDGE object.
28 | protocolVersion
29 | One of the STP_VERSION values.
30 |
31 |
32 | Remarks
33 |
34 | See §13.7.2 in 801.1Q-2018 for more information.
35 |
36 | Execution of this function is a potentially lengthy process.
37 | It may call various callbacks multiple times.
38 |
39 | This function may not be called from within an STP callback .
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/_help/STP_StartBridge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_StartBridge
7 |
8 |
9 | STP_StartBridge
10 |
11 |
12 | void STP_StartBridge
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int timestamp
16 | );
17 |
18 |
19 | Summary
20 | Starts the Spanning Tree Protocol on a bridge.
21 |
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to a STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | timestamp
29 | A timestamp used for the debug log.
30 |
31 |
32 | Remarks
33 |
34 | Starting the Spanning Tree Protocol from application code is usually a
35 | three-step procedure:
36 |
37 | a call to STP_CreateBridge , which allocates
38 | internal structures and initializes all parameters to default values;
39 | various calls to functions such as STP_SetBridgePriority
40 | and STP_SetStpVersion , possibly with values
41 | read from a configuration file; the protocol is not yet started, so there won't
42 | be any STP activity with temporary parameters.
43 | a call to this function, which starts the protocol directly with
44 | application-specified parameters.
45 |
46 |
47 | The
48 | application must not call this function for already-started bridges.
49 |
50 |
51 | Execution of this function is a potentially lengthy process.
52 | It may call various callbacks multiple times.
53 |
54 | This function may not be called from within an STP callback .
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/_help/STP_StopBridge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | STP_StopBridge
7 |
8 |
9 | STP_StopBridge
10 |
11 |
12 | void STP_StopBridge
13 | (
14 | STP_BRIDGE* bridge,
15 | unsigned int timestamp
16 | );
17 |
18 |
19 | Summary
20 |
21 | Stops the Spanning Tree Protocol.
22 |
23 | Parameters
24 |
25 | bridge
26 | Pointer to an STP_BRIDGE object, obtained from
27 | STP_CreateBridge .
28 | timestamp
29 | A timestamp used for the debug log.
30 |
31 |
32 | Remarks
33 |
34 | This function calls StpCallback_EnableBpduTrapping
35 | to restore the switch to its default, non-STP-capable, state.
36 |
37 | This function re-enables learning and forwarding. It does so by calling
38 | StpCallback_EnableLearning and
39 | StpCallback_EnableForwarding
40 | for every tree of every port that had either of them disabled.
41 |
42 | This function may not be called from within an STP callback .
43 |
44 |
45 |
--------------------------------------------------------------------------------
/_help/Screen.css:
--------------------------------------------------------------------------------
1 | body
2 | {
3 | font-family: 'Calibri', 'Times New Roman'
4 | }
5 |
6 | dd
7 | {
8 | margin-bottom: 7px;
9 | }
10 |
11 | li
12 | {
13 | margin-bottom: 7px;
14 | }
15 | pre
16 | {
17 | background-color: #CCCCCC;
18 | }
19 |
20 | dt
21 | {
22 | font-family: monospace;
23 | }
24 |
25 | .function_information_table_left_cell
26 | {
27 | padding-right: 30px;
28 | background-color: #C0C0C0;
29 | vertical-align: top;
30 | }
31 |
--------------------------------------------------------------------------------
/_help/StpCallback_AllocAndZeroMemory.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_AllocAndZeroMemory
7 |
8 |
9 | StpCallback_AllocAndZeroMemory
10 |
11 |
12 | void* StpCallback_AllocAndZeroMemory (unsigned int size);
13 |
14 |
15 | Summary
16 |
17 | Application-defined function that allocates and zeroes-out memory for STP use.
18 | (The library does not call standard memory-allocation functions, because most embedded
19 | applications don't have a heap to allocate from.)
20 |
21 | StpCallback_AllocAndZeroMemory
is a placeholder name used throughout this documentation. The
22 | application may name this callback differently.
23 |
24 | Parameters
25 |
26 | size
27 | The application receives in this parameter the size of the required memory block.
28 |
29 |
30 | Return value
31 |
32 | The application must return a pointer to the allocated and zeroed-out memory block.
33 |
34 |
35 | Remarks
36 |
37 | The STP library does not currenly support out-of-memory conditions. It
38 | verifies with an assert() that the pointer returned by this callback is not NULL.
39 |
40 | See the remarks section in
41 | STP_CreateBridge , for information about how and when the STP library allocates memory.
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/_help/StpCallback_DebugStrOut.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_DebugStrOut
7 |
8 |
9 | StpCallback_DebugStrOut
10 |
11 |
12 | void StpCallback_DebugStrOut
13 | (
14 | const STP_BRIDGE* bridge,
15 | int portIndex,
16 | int treeIndex,
17 | const char* nullTerminatedString,
18 | unsigned int stringLength,
19 | bool flush
20 | );
21 |
22 | Summary
23 |
24 | Application-defined callback that processes debug text generated by the STP library. It
25 | usually sends this text to a PC for displaying in a program such as Hyperterminal.
26 |
27 |
28 | StpCallback_DebugStrOut
is a placeholder name used throughout this documentation. The
29 | application may name this callback differently.
30 | Parameters
31 |
32 | bridge
33 | The application receives in this parameter a pointer to the bridge object returned by
34 | STP_CreateBridge .
35 | portIndex
36 | The application receives in this parameter either:
37 |
38 | the zero-based index of a port, if the debug text is relevant only to that port, or
39 | -1 if the debug text is relevant to all ports (e.g., contains information about the
40 | bridge).
41 |
42 |
43 | treeIndex
44 | The application receives in this parameter either:
45 |
46 | the zero-based index of a spanning tree, if the debug text is relevant only to
47 | that spanning tree, or
48 | -1 if the debug text is relevant to all spanning trees.
49 |
50 |
51 | nullTerminatedString
52 | The application receives in this parameter a pointer to the null-terminated debug text.
53 | stringLength
54 | The length of the text (the value that strlen()
would return).
55 | flush
56 | The application receives in this parameter a value which can be used as a hint for
57 | flushing any debug text that the application might have buffered.
58 |
59 | Remarks
60 |
61 | The length of the debug text passed to this function, including the null terminator, is
62 | lower than or equal to the debugLogBufferSize
parameter specified in the call to
63 | STP_CreateBridge .
64 |
65 | Logging is enabled or disabled by calling
66 | STP_EnableLogging . When a bridge is created, logging for that bridge is disabled.
67 |
68 | Line ending used by the STP library is "\r\n".
69 |
70 | The application may choose to buffer the text it receives in this callback. If it does so,
71 | it should flush its buffer when the library passes true
in the flush
parameter.
72 |
73 | The library sometimes calls this callback only for flushing, without any text (so
74 | nullTerminatedString
pointing to a null character,
75 | stringLength
= 0, and flush
= true).
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/_help/StpCallback_EnableForwarding.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_EnableForwarding
7 |
8 |
9 | StpCallback_EnableForwarding
10 |
11 |
12 | void StpCallback_EnableForwarding
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex,
17 | bool enable,
18 | unsigned int timestamp
19 | );
20 |
21 |
22 | Summary
23 |
24 | Application-defined function that must enable or disable forwarding on a physical port.
25 |
26 | StpCallback_EnableForwarding
is a placeholder name used throughout this documentation. The
27 | application may name this callback differently.
28 |
29 | Parameters
30 |
31 | bridge
32 | The application receives in this parameter a pointer to the bridge object returned by
33 | STP_CreateBridge .
34 | portIndex
35 | The application receives in this parameter the zero-based index of the port for which
36 | forwarding is to be enabled or disabled.
37 | treeIndex
38 | The application receives in this parameter the zero-based index of the spanning tree for
39 | which forwarding is to be enabled or disabled. For STP or RSTP, this is always zero. For
40 | MSTP, this is zero for CIST, or 1..64 for a MSTI.
41 | enable
42 | The application receives in this parameter true
if forwarding is to be enabled,
43 | false
if the forwarding is to be disabled.
44 | timestamp
45 | The application receives in this parameter the timestamp that it passed to the function
46 | that called this callback (STP_OnBpduReceived, STP_OnPortEnabled etc.)
47 | Useful for debugging and troubleshooting.
48 |
49 |
50 | Remarks
51 | In complex networks, and especially in MSTP mode, the STP library can call
52 | this function dozens of times in a row, with various combinations of parameters.
53 | This is due to the protocol itself (i.e., it is not a characteristic of this
54 | particular library). For that reason, the implementation of this function
55 | should not take more than a few milliseconds. Usually all this function needs
56 | to do is write a few bytes to the internal registers of the switch IC.
57 | This function must wait until the hardware has finished enabling or disabling forwarding
58 | (i.e., it must not just initiate the hardware action and return).
59 |
60 |
61 |
--------------------------------------------------------------------------------
/_help/StpCallback_EnableLearning.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_EnableLearning
7 |
8 |
9 | StpCallback_EnableLearning
10 |
11 |
12 | void StpCallback_EnableLearning
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex,
17 | bool enable,
18 | unsigned int timestamp
19 | );
20 |
21 | Summary
22 |
23 | See StpCallback_EnableForwarding . All
24 | information from that callback applies to this callback as well, except that learning
25 | is enabled/disabled, not
26 | forwarding .
27 |
28 |
29 | StpCallback_EnableLearning
is a placeholder name used throughout this documentation. The
30 | application may name this callback differently.
31 |
32 |
33 |
--------------------------------------------------------------------------------
/_help/StpCallback_FlushFdb.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_FlushFdb
7 |
8 |
9 | StpCallback_FlushFdb
10 |
11 |
12 | void StpCallback_FlushFdb
13 | (
14 | const STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex,
17 | enum STP_FLUSH_FDB_TYPE flushType,
18 | unsigned int timestamp
19 | );
20 |
21 |
22 | Summary
23 | Application-defined function that flushes FDB entries (MAC-to-port associations)
24 | on a physical port.
25 |
26 |
27 | StpCallback_FlushFdb
is a placeholder name used throughout this documentation. The
28 | application may name this callback differently.
29 |
30 | Parameters
31 |
32 | bridge
33 | The application receives in this parameter a pointer to the bridge object returned by
34 | STP_CreateBridge .
35 | portIndex
36 | The application receives in this parameter the index of the port on which FDB entries are to be flushed.
37 | treeIndex
38 | The application receives in this parameter the index of the spanning tree for which FDB
39 | entries are to be flushed. For STP or RSTP, this is always zero. For MSTP, this is zero
40 | for CIST, or 1..64 for a MSTI.
41 | flushType
42 | The application receives in this parameter a value representing the type of flushing it
43 | must perform. See the Remarks section for more information.
44 | timestamp
45 | The application receives in this parameter the timestamp that it passed to the function
46 | that called this callback (STP_OnBpduReceived, STP_OnPortEnabled etc.)
47 | Useful for debugging and troubleshooting.
48 |
49 | Remarks
50 | In complex networks, and especially in MSTP mode, the STP library can call
51 | this function dozens of times in a row, with various combinations of parameters.
52 | This is due to the protocol itself (i.e., it is not a characteristic of this
53 | particular library). For that reason, the implementation of this function
54 | should not take more than a few milliseconds. Usually all this function needs
55 | to do is write a few bytes to the internal registers of the switch IC.
56 | If flushType
is STP_FLUSH_FDB_TYPE_IMMEDIATE
, the application must flush the FDB entries
57 | and return after the flush is completed in hardware. This value is received for RSTP and
58 | MSTP bridges (i.e., when STP_VERSION_RSTP
or STP_VERSION_MSTP
was passed to
59 | STP_CreateBridge or STP_SetStpVersion).
60 | If flushType
is STP_FLUSH_FDB_TYPE_RAPID_AGEING
, the application must initiate FDB
61 | flushing and return without waiting for flushing to be completed in hardware. This
62 | behavior is used in legacy STP (pre-RSTP) bridges (i.e., when STP_VERSION_LEGACY_STP
63 | was passed to STP_CreateBridge or
64 | STP_SetStpVersion ).
65 |
66 |
67 |
--------------------------------------------------------------------------------
/_help/StpCallback_FreeMemory.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_FreeMemory
7 |
8 |
9 | StpCallback_FreeMemory
10 |
11 |
12 | void StpCallback_FreeMemory (void* p);
13 |
14 |
15 | Summary
16 |
17 | Application-defined function that frees memory previously allocated with
18 | StpCallback_AllocAndZeroMemory .
19 |
20 | StpCallback_FreeMemory
is a placeholder name used throughout this documentation. The
21 | application may name this callback differently.
22 |
23 | Parameters
24 |
25 | p
26 | The application receives in this parameter a pointer to the memory block to be freed.
27 |
28 |
29 | Remarks
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/_help/StpCallback_OnPortRoleChanged.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_OnPortRoleChanged
7 |
8 |
9 | StpCallback_OnPortRoleChanged
10 |
11 |
12 | void StpCallback_OnPortRoleChanged
13 | (
14 | const struct STP_BRIDGE* bridge,
15 | unsigned int portIndex,
16 | unsigned int treeIndex,
17 | enum STP_PORT_ROLE role,
18 | unsigned int timestamp
19 | );
20 |
21 |
22 | Summary
23 |
24 | Application-defined function that is called by the STP library
25 | immediately after it changes a port role.
26 |
27 | Parameters
28 |
29 | bridge
30 | The application receives in this parameter a pointer to the STP_BRIDGE object.
31 | portIndex
32 | The application receives in this parameter the index of the port whose role has changed.
33 | treeIndex
34 | The application receives in this parameter the index of the spanning tree on which the port role changed (always 0 for LegacySTP and RSTP).
35 | role
36 | The new port role.
37 | timestamp
38 | The application receives in this parameter the timestamp that it passed to the function
39 | that called this callback (STP_OnBpduReceived, STP_OnPortEnabled etc.)
40 | Useful for debugging and troubleshooting.
41 |
42 |
43 | Remarks
44 |
45 | The application should implement this callback if it needs to update some user interface as ports change role. An Ethernet switch, for example, has a web interface where the user can inspect the state of each port; the code in this callback would refresh the displayed information to make sure the user sees up-to-date information about the port.
46 |
47 |
48 | StpCallback_OnTopologyChanged is a placeholder name used throughout this documentation. The
49 | application may name this callback differently.
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/_help/StpCallback_OnTopologyChange.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_OnTopologyChange
7 |
8 |
9 | StpCallback_OnTopologyChange
10 |
11 |
12 | void StpCallback_OnTopologyChange
13 | (
14 | const struct STP_BRIDGE* bridge,
15 | unsigned int treeIndex,
16 | unsigned int timestamp
17 | );
18 |
19 |
20 | Summary
21 |
22 | Application-defined function that is called by the STP library when it detects a change in the network topology on the local bridge.
23 |
24 | This callback allows the application to implement the following:
25 |
26 | from 802.1Q-2018: 12.8.1.2.3, c) and d) and 12.8.1.1.3, b) and c) ;
27 | from IEEE8021-SPANNING-TREE-MIB: ieee8021SpanningTreeTimeSinceTopologyChange and ieee8021SpanningTreeTopChanges .
28 |
29 |
30 | Parameters
31 |
32 | bridge
33 | The application receives in this parameter a pointer to an STP_BRIDGE object.
34 | treeIndex
35 | The application receives in this parameter the zero-based index of the spanning tree on which the topology change ocurred. For STP or RSTP, this is always zero. For
36 | MSTP, this is zero for CIST, or 1..64 for a MSTI.
37 | timestamp
38 | The application receives in this parameter the timestamp that it passed to the function
39 | that called this callback (STP_OnBpduReceived, STP_OnPortEnabled etc.)
40 | Useful for debugging and troubleshooting.
41 |
42 |
43 | Remarks
44 |
45 | The library calls this callback only as long as the bridge is running at least RSTP (see STP_CreateBridge , STP_SetStpVersion ). The detection of topology changes in LegacySTP mode (as per 8.5.3.12 in 802.1D-1998) is not yet implemented.
46 |
47 | The STP library calls this callback when it detects a topology change
48 | on the local bridge (i.e., a non-edge port transitioning to/from the forwarding state while the bridge is not isolated).
49 |
50 |
51 | StpCallback_OnTopologyChange is a placeholder name used throughout this documentation. The
52 | application may name this callback differently.
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/_help/StpCallback_TransmitReleaseBuffer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | StpCallback_TransmitReleaseBuffer
7 |
8 |
9 | StpCallback_TransmitReleaseBuffer
10 |
11 |
12 | void StpCallback_TransmitReleaseBuffer
13 | (
14 | const STP_BRIDGE* bridge,
15 | void* bufferReturnedByGetBuffer
16 | );
17 |
18 | Summary
19 |
20 | Used together with StpCallback_TransmitGetBuffer to transmit a BPDU generated by the STP library.
21 |
22 | Parameters
23 |
24 | bridge
25 | The application receives in this parameter a pointer to the bridge object returned by
26 | STP_CreateBridge .
27 | bufferReturnedByGetBuffer
28 | The application receives in this parameter the same value it returned from StpCallback_TransmitGetBuffer . The callback implementation may or may not need this value.
29 |
30 | Remarks
31 |
32 | This callback is called by the STP library only if StpCallback_TransmitGetBuffer returned a
33 | non-NULL address.
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/_help/Troubleshooting.txt:
--------------------------------------------------------------------------------
1 | - Make sure your switch (the hardware) isn't forwarding incoming BPDUs between ports. It must only forward BPDUs to the microcontroller running the STP.
2 |
3 |
4 | - Make sure your switch (the hardware) isn't broadcasting to all ports the BPDUs generated by the STP library.
5 |
6 |
7 | - Make sure your application is getting the incoming BPDUs. From your last mail I understand that the STP library works correctly while it is sending BPDUs (while it is the root), but isn't working right while the Cisco is sending BPDUs (while Cisco is the root). There's a possiblity your application isn't getting the incoming BPDUs.
8 |
9 |
10 | - Make sure you're correctly stripping the headers of the received BPDU frames (the VLAN tag should be striped too, if any).
11 |
12 |
13 | - Make sure you're not flooding the Ethernet communication driver of your device with incoming frames, from the office network for instance. This leads to BPDU loss, and then to STP malfunction. This was especially a problem for me in the early development stages of my Ethernet driver for LPC2000.
14 |
15 |
16 | - If you use IP-based communication to check connectivity to your device, make sure you flush the ARP table and send "gratuituous" ARPs whenever connectivity changes (forwarding and/or learning enabled/disabled on any port by STP). I am improving this in the new version of the library.
17 |
18 |
19 | - I don't know what Cisco switches you have there, but play a bit with the STP-related options. I once had some Cisco switches that sometimes wouldn't work with my devices, without any logic that I could see. The problem was some RSTP-related setting ("portfast" i.i.r.c.) which was conflicting with the RSTP functionality.
20 |
21 |
22 | - I don't know what compiler you're using, but make sure everything is byte-aligned in base_types.h and bpdu.h. The way I wrote that code, everything ends up byte-aligned on IAR and on VC++, but I'm not sure about other compilers.
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_base_types.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #include "stp_base_types.h"
6 | #include "stp_log.h"
7 |
8 | bool STP_BRIDGE_ADDRESS::operator== (const STP_BRIDGE_ADDRESS& rhs) const
9 | {
10 | return memcmp (this->bytes, rhs.bytes, 6) == 0;
11 | }
12 |
13 | bool STP_BRIDGE_ADDRESS::operator != (const STP_BRIDGE_ADDRESS& rhs) const
14 | {
15 | return memcmp (this->bytes, rhs.bytes, 6) != 0;
16 | }
17 |
18 | // ============================================================================
19 |
20 | const char* GetPortRoleName (STP_PORT_ROLE role)
21 | {
22 | if (role == STP_PORT_ROLE_MASTER)
23 | return "Master";
24 | else if (role == STP_PORT_ROLE_ROOT)
25 | return "Root";
26 | else if (role == STP_PORT_ROLE_DESIGNATED)
27 | return "Designated";
28 | else if (role == STP_PORT_ROLE_ALTERNATE)
29 | return "Alternate";
30 | else if (role == STP_PORT_ROLE_BACKUP)
31 | return "Backup";
32 | else if (role == STP_PORT_ROLE_DISABLED)
33 | return "Disabled";
34 | else
35 | {
36 | assert (false);
37 | return NULL;
38 | }
39 | }
40 |
41 | // ============================================================================
42 |
43 | void PORT_ID::Set (unsigned char priority, unsigned short portNumber)
44 | {
45 | assert ((priority & 0x0F) == 0);
46 | assert ((portNumber >= 1) && (portNumber <= 0xFFF));
47 |
48 | _high = priority | (unsigned char) (portNumber >> 8);
49 | _low = (unsigned char) portNumber;
50 | }
51 |
52 | void PORT_ID::Reset ()
53 | {
54 | _high = 0;
55 | _low = 0;
56 | }
57 |
58 | unsigned char PORT_ID::GetPriority () const
59 | {
60 | assert (_low != 0); // structure was not initialized; it must have been initialized with Set()
61 | return _high & 0xF0;
62 | }
63 |
64 | void PORT_ID::SetPriority (unsigned char priority)
65 | {
66 | assert (_low != 0); // structure was not initialized; it must have been initialized with Set()
67 | assert ((priority & 0x0F) == 0);
68 |
69 | _high = priority | (_high & 0x0F);
70 | }
71 |
72 | unsigned short PORT_ID::GetPortNumber () const
73 | {
74 | assert (_low != 0); // structure was not initialized; it must have been initialized with Set()
75 |
76 | return ((unsigned short) _high & 0x0F) | _low;
77 | }
78 |
79 | unsigned short PORT_ID::GetPortIdentifier () const
80 | {
81 | assert (_low != 0); // structure was not initialized; it must have been initialized with Set()
82 |
83 | unsigned short id = (((unsigned short) _high) << 8) | (unsigned short) _low;
84 | return id;
85 | }
86 |
87 | bool PORT_ID::IsBetterThan (const PORT_ID& rhs) const
88 | {
89 | assert (_low != 0); // structure was not initialized; it must have been initialized with Set()
90 |
91 | unsigned short lv = (((unsigned short) this->_high) << 8) | (unsigned short) this->_low;
92 | unsigned short rv = (((unsigned short) rhs._high) << 8) | (unsigned short) rhs._low;
93 |
94 | bool better = (lv < rv);
95 | return better;
96 | }
97 |
98 | bool TIMES::operator== (const TIMES& other) const
99 | {
100 | return (this->ForwardDelay == other.ForwardDelay)
101 | && (this->HelloTime == other.HelloTime)
102 | && (this->MaxAge == other.MaxAge)
103 | && (this->MessageAge == other.MessageAge)
104 | && (this->remainingHops == other.remainingHops);
105 | }
106 |
107 | bool TIMES::operator!= (const TIMES& other) const
108 | {
109 | return !this->operator==(other);
110 | }
111 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_conditions_and_params.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #ifndef MSTP_LIB_CONDS_AND_PARAMS_H
6 | #define MSTP_LIB_CONDS_AND_PARAMS_H
7 |
8 | #include "stp_base_types.h"
9 |
10 | // 13.28 State machine conditions and parameters
11 | bool allSptAgree (const STP_BRIDGE*);
12 | bool allSynced (const STP_BRIDGE*, PortIndex, TreeIndex);
13 | bool allTransmitReady (const STP_BRIDGE*, PortIndex);
14 | const PRIORITY_VECTOR& BestAgreementPriority();
15 | bool cist (const STP_BRIDGE*, TreeIndex);
16 | bool cistRootPort (const STP_BRIDGE*, PortIndex);
17 | bool cistDesignatedPort (const STP_BRIDGE*, PortIndex);
18 | unsigned short EdgeDelay (const STP_BRIDGE*, PortIndex);
19 | unsigned short forwardDelay (const STP_BRIDGE*, PortIndex);
20 | unsigned short FwdDelay (const STP_BRIDGE*, PortIndex);
21 | unsigned short HelloTime (const STP_BRIDGE*, PortIndex);
22 | unsigned short MaxAge (const STP_BRIDGE*, PortIndex);
23 | bool msti (const STP_BRIDGE*, TreeIndex);
24 | bool mstiDesignatedOrTCpropagatingRootPort (const STP_BRIDGE*, PortIndex);
25 | bool mstiMasterPort (const STP_BRIDGE*, PortIndex);
26 | bool operPointToPoint (const STP_BRIDGE*, PortIndex);
27 | bool rcvdAnyMsg (const STP_BRIDGE*, PortIndex);
28 | bool rcvdCistMsg (const STP_BRIDGE*, PortIndex);
29 | bool rcvdMstiMsg (const STP_BRIDGE*, PortIndex, TreeIndex);
30 | bool reRooted (const STP_BRIDGE*, PortIndex, TreeIndex);
31 | bool rstpVersion (const STP_BRIDGE*);
32 | bool spt (const STP_BRIDGE*);
33 | bool stpVersion (const STP_BRIDGE*);
34 | bool updtCistInfo (const STP_BRIDGE*, PortIndex);
35 | bool updtMstiInfo (const STP_BRIDGE*, PortIndex, TreeIndex);
36 | bool rcvdXstMsg (const STP_BRIDGE*, PortIndex, TreeIndex);
37 | bool updtXstInfo (const STP_BRIDGE*, PortIndex, TreeIndex);
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_log.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #ifndef MSTP_LIB_LOG_H
6 | #define MSTP_LIB_LOG_H
7 |
8 | #include "../stp.h"
9 |
10 | #if STP_USE_LOG
11 | struct STP_BRIDGE;
12 |
13 | void STP_Log (STP_BRIDGE* bridge, int port, int tree, const char* format, ...);
14 | void STP_FlushLog (STP_BRIDGE* bridge);
15 | void STP_Indent (STP_BRIDGE* bridge);
16 | void STP_Unindent (STP_BRIDGE* bridge);
17 |
18 | #define LOG(b,p,t,...) ((void) ( !(b)->loggingEnabled || (STP_Log(b,p,t,__VA_ARGS__), 0)))
19 | #define FLUSH_LOG(b) ((void) ( !(b)->loggingEnabled || (STP_FlushLog(b), 0)))
20 | #define LOG_INDENT(b) ((void) ( !(b)->loggingEnabled || (STP_Indent(b), 0)))
21 | #define LOG_UNINDENT(b) ((void) ( !(b)->loggingEnabled || (STP_Unindent(b), 0)))
22 | #else
23 | #define LOG(b,p,t,...) ((void)0)
24 | #define FLUSH_LOG(b) ((void)0)
25 | #define LOG_INDENT(b) ((void)0)
26 | #define LOG_UNINDENT(b) ((void)0)
27 | #endif
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_md5.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #ifndef MSTP_LIB_HMAC_MD5_H
6 | #define MSTP_LIB_HMAC_MD5_H
7 |
8 | // Data structure for MD5 (Message Digest) computation
9 | struct MD5_CTX
10 | {
11 | unsigned int i [2]; // number of _bits_ handled mod 2^64
12 | unsigned int buf [4]; // scratch buffer
13 | unsigned char in [64]; // input buffer
14 | };
15 |
16 | struct HMAC_MD5_CONTEXT : MD5_CTX
17 | {
18 | unsigned char digest[16]; // actual digest after HMAC_MD5_End call
19 | };
20 |
21 | void HMAC_MD5_Init (HMAC_MD5_CONTEXT* context);
22 | void HMAC_MD5_Update (HMAC_MD5_CONTEXT* context, const void* text, unsigned int text_len);
23 | void HMAC_MD5_End (HMAC_MD5_CONTEXT* context);
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_procedures.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #ifndef MSTP_LIB_PROCEDURES_H
6 | #define MSTP_LIB_PROCEDURES_H
7 |
8 | #include "stp_base_types.h"
9 |
10 | bool betterorsameInfo (STP_BRIDGE*, PortIndex, TreeIndex, INFO_IS newInfoIs);
11 | void clearAllRcvdMsgs (STP_BRIDGE*, PortIndex);
12 | void clearReselectTree (STP_BRIDGE*, TreeIndex);
13 | void disableForwarding (STP_BRIDGE*, PortIndex, TreeIndex, unsigned int timestamp);
14 | void disableLearning (STP_BRIDGE*, PortIndex, TreeIndex, unsigned int timestamp);
15 | void enableForwarding (STP_BRIDGE*, PortIndex, TreeIndex, unsigned int timestamp);
16 | void enableLearning (STP_BRIDGE*, PortIndex, TreeIndex, unsigned int timestamp);
17 | bool fromSameRegion (STP_BRIDGE*, PortIndex);
18 | void newTcDetected (STP_BRIDGE*, PortIndex, TreeIndex);
19 | void newTcWhile (STP_BRIDGE*, PortIndex, TreeIndex, unsigned int timestamp);
20 | void pseudoRcvMsgs (STP_BRIDGE*, PortIndex);
21 | RCVD_INFO rcvInfo (STP_BRIDGE*, PortIndex, TreeIndex);
22 | void rcvMsgs (STP_BRIDGE*, PortIndex);
23 | void rcvAgreements (STP_BRIDGE*, PortIndex);
24 | void recordAgreement (STP_BRIDGE*, PortIndex, TreeIndex);
25 | void recordDispute (STP_BRIDGE*, PortIndex, TreeIndex);
26 | void recordMastered (STP_BRIDGE*, PortIndex, TreeIndex);
27 | void recordPriority (STP_BRIDGE*, PortIndex, TreeIndex);
28 | void recordProposal (STP_BRIDGE*, PortIndex, TreeIndex);
29 | void recordTimes (STP_BRIDGE*, PortIndex, TreeIndex);
30 | void setReRootTree (STP_BRIDGE*, TreeIndex);
31 | void setSelectedTree (STP_BRIDGE*, TreeIndex);
32 | void setSyncTree (STP_BRIDGE*, TreeIndex);
33 | void setTcFlags (STP_BRIDGE*, PortIndex, TreeIndex);
34 | void setTcPropTree (STP_BRIDGE*, PortIndex, TreeIndex);
35 | void syncMaster (STP_BRIDGE*);
36 | void txConfig (STP_BRIDGE*, PortIndex, unsigned int timestamp);
37 | void txRstp (STP_BRIDGE*, PortIndex, unsigned int timestamp);
38 | void txTcn (STP_BRIDGE*, PortIndex, unsigned int timestamp);
39 | void updtAgreement (STP_BRIDGE*, PortIndex, TreeIndex);
40 | void updtBPDUVersion (STP_BRIDGE*, PortIndex);
41 | void updtDigest (STP_BRIDGE*, PortIndex);
42 | void updtRcvdInfoWhile (STP_BRIDGE*, PortIndex, TreeIndex);
43 | void updtRolesTree (STP_BRIDGE*, TreeIndex);
44 | void updtRolesDisabledTree (STP_BRIDGE*, TreeIndex);
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_sm_l2g_port_receive.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | // This file implements 13.40 from 802.1Q-2018.
6 |
7 | #include "stp_procedures.h"
8 | #include "stp_conditions_and_params.h"
9 | #include "stp_bridge.h"
10 | #include
11 |
12 | using namespace L2GPortReceive;
13 |
14 | #if STP_USE_LOG
15 | static const char* GetStateName (State state)
16 | {
17 | switch (state)
18 | {
19 | case INIT: return "INIT";
20 | case PSEUDO_RECEIVE: return "PSEUDO_RECEIVE";
21 | case DISCARD: return "DISCARD";
22 | case L2GP: return "L2GP";
23 | default: return "(undefined)";
24 | }
25 | }
26 | #endif
27 |
28 | // ============================================================================
29 |
30 | // Returns the new state, or 0 when no transition is to be made.
31 | static State CheckConditions (const STP_BRIDGE* bridge, PortIndex givenPort, State state)
32 | {
33 | PORT* port = bridge->ports [givenPort];
34 |
35 | // ------------------------------------------------------------------------
36 | // Check global conditions.
37 |
38 | if (bridge->BEGIN || !port->isL2gp || !port->portEnabled)
39 | {
40 | if (state == INIT)
41 | {
42 | // The entry block for this state has been executed already.
43 | return (State)0;
44 | }
45 |
46 | return INIT;
47 | }
48 |
49 | // ------------------------------------------------------------------------
50 | // Check exit conditions from each state.
51 |
52 | if (state == INIT)
53 | return L2GP;
54 |
55 | if (state == PSEUDO_RECEIVE)
56 | return L2GP;
57 |
58 | if (state == DISCARD)
59 | return L2GP;
60 |
61 | if (state == L2GP)
62 | {
63 | if (!port->enableBPDUrx && port->rcvdBpdu && !rcvdAnyMsg (bridge, givenPort))
64 | return DISCARD;
65 |
66 | if ((port->pseudoInfoHelloWhen == 0) && !rcvdAnyMsg (bridge, givenPort))
67 | return PSEUDO_RECEIVE;
68 |
69 | return (State)0;
70 | }
71 |
72 | assert (false);
73 | return (State)0;
74 | }
75 |
76 | static void InitState (STP_BRIDGE* bridge, PortIndex givenPort, State state, unsigned int timestamp)
77 | {
78 | PORT* port = bridge->ports[givenPort];
79 |
80 | if (state == INIT)
81 | {
82 | port->pseudoInfoHelloWhen = 0;
83 | }
84 | else if (state == PSEUDO_RECEIVE)
85 | {
86 | port->rcvdInternal = true;
87 | pseudoRcvMsgs (bridge, givenPort);
88 | port->edgeDelayWhile = bridge->MigrateTime;
89 | port->pseudoInfoHelloWhen = HelloTime (bridge, givenPort);
90 | }
91 | else if (state == DISCARD)
92 | {
93 | port->rcvdBpdu = false;
94 | }
95 | else if (state == L2GP)
96 | {
97 | }
98 | else
99 | assert (false);
100 | }
101 |
102 | const StateMachine L2GPortReceive::sm =
103 | {
104 | #if STP_USE_LOG
105 | "L2GPortReceive",
106 | &GetStateName,
107 | #endif
108 | &CheckConditions,
109 | &InitState
110 | };
111 |
112 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_sm_port_protocol_migration.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | // This file implements 13.32 from 802.1Q-2018
6 |
7 | #include "stp_procedures.h"
8 | #include "stp_conditions_and_params.h"
9 | #include "stp_bridge.h"
10 | #include
11 |
12 | using namespace PortProtocolMigration;
13 |
14 | #if STP_USE_LOG
15 | static const char* GetStateName (State state)
16 | {
17 | switch (state)
18 | {
19 | case CHECKING_RSTP: return "CHECKING_RSTP";
20 | case SELECTING_STP: return "SELECTING_STP";
21 | case SENSING: return "SENSING";
22 | default: return "(undefined)";
23 | }
24 | }
25 | #endif
26 |
27 | // ============================================================================
28 |
29 | // Returns the new state, or 0 when no transition is to be made.
30 | static State CheckConditions (const STP_BRIDGE* bridge, PortIndex givenPort, State state)
31 | {
32 | PORT* port = bridge->ports[givenPort];
33 |
34 | // ------------------------------------------------------------------------
35 | // Check global conditions.
36 |
37 | if (bridge->BEGIN)
38 | {
39 | if (state == CHECKING_RSTP)
40 | {
41 | // The entry block for this state has been executed already.
42 | return (State)0;
43 | }
44 |
45 | return CHECKING_RSTP;
46 | }
47 |
48 | // ------------------------------------------------------------------------
49 | // Check exit conditions from each state.
50 |
51 | if (state == CHECKING_RSTP)
52 | {
53 | if (port->mDelayWhile == 0)
54 | return SENSING;
55 |
56 | if ((port->mDelayWhile != bridge->MigrateTime) && !port->portEnabled)
57 | return CHECKING_RSTP;
58 |
59 | return (State)0;
60 | }
61 |
62 | if (state == SELECTING_STP)
63 | {
64 | if ((port->mDelayWhile == 0) || !port->portEnabled || port->mcheck)
65 | return SENSING;
66 |
67 | return (State)0;
68 | }
69 |
70 | if (state == SENSING)
71 | {
72 | if (port->sendRSTP && port->rcvdSTP)
73 | return SELECTING_STP;
74 |
75 | if (!port->portEnabled || port->mcheck || ((rstpVersion(bridge) && !port->sendRSTP && port->rcvdRSTP)))
76 | return CHECKING_RSTP;
77 |
78 | return (State)0;
79 | }
80 |
81 | assert (false);
82 | return (State)0;
83 | }
84 |
85 | // ============================================================================
86 |
87 | static void InitState (STP_BRIDGE* bridge, PortIndex givenPort, State state, unsigned int timestamp)
88 | {
89 | PORT* port = bridge->ports[givenPort];
90 |
91 | if (state == CHECKING_RSTP)
92 | {
93 | port->mcheck = false;
94 | port->sendRSTP = rstpVersion(bridge);
95 | port->mDelayWhile = bridge->MigrateTime;
96 | }
97 | else if (state == SELECTING_STP)
98 | {
99 | port->sendRSTP = false;
100 | port->mDelayWhile = bridge->MigrateTime;
101 | }
102 | else if (state == SENSING)
103 | {
104 | port->rcvdRSTP = port->rcvdSTP = false;
105 | }
106 | else
107 | assert (false);
108 | }
109 |
110 | const StateMachine PortProtocolMigration::sm =
111 | {
112 | #if STP_USE_LOG
113 | "PortProtocolMigration",
114 | &GetStateName,
115 | #endif
116 | &CheckConditions,
117 | &InitState
118 | };
119 |
120 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_sm_port_receive.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | // This file implements 13.31 from 802.1Q-2018.
6 |
7 | #include "stp_procedures.h"
8 | #include "stp_conditions_and_params.h"
9 | #include "stp_bridge.h"
10 | #include
11 |
12 | using namespace PortReceive;
13 |
14 | #if STP_USE_LOG
15 | static const char* GetStateName (State state)
16 | {
17 | switch (state)
18 | {
19 | case DISCARD: return "DISCARD";
20 | case RECEIVE: return "RECEIVE";
21 | default: return "(undefined)";
22 | }
23 | }
24 | #endif
25 |
26 | // ============================================================================
27 |
28 | // Returns the new state, or 0 when no transition is to be made.
29 | static State CheckConditions (const STP_BRIDGE* bridge, PortIndex givenPort, State state)
30 | {
31 | PORT* port = bridge->ports[givenPort];
32 |
33 | // ------------------------------------------------------------------------
34 | // Check global conditions.
35 |
36 | if (bridge->BEGIN
37 | || ((port->rcvdBpdu || (port->edgeDelayWhile != bridge->MigrateTime)) && !port->portEnabled))
38 | {
39 | if (state == DISCARD)
40 | {
41 | // The entry block for this state has been executed already.
42 | return (State)0;
43 | }
44 |
45 | return DISCARD;
46 | }
47 |
48 | // ------------------------------------------------------------------------
49 | // Check exit conditions from each state.
50 |
51 | if (state == DISCARD)
52 | {
53 | if (port->rcvdBpdu && port->portEnabled && port->enableBPDUrx)
54 | return RECEIVE;
55 |
56 | return (State)0;
57 | }
58 |
59 | if (state == RECEIVE)
60 | {
61 | if (port->rcvdBpdu && port->portEnabled && port->enableBPDUrx && !rcvdAnyMsg (bridge, givenPort))
62 | return RECEIVE;
63 |
64 | return (State)0;
65 | }
66 |
67 | assert (false);
68 | return (State)0;
69 | }
70 |
71 | // ============================================================================
72 |
73 | static void InitState (STP_BRIDGE* bridge, PortIndex givenPort, State state, unsigned int timestamp)
74 | {
75 | PORT* port = bridge->ports[givenPort];
76 |
77 | if (state == DISCARD)
78 | {
79 | port->rcvdBpdu = port->rcvdRSTP = port->rcvdSTP = false;
80 | port->agreedMisorder = true; port->agreedN = port->agreedND = port->agreeND = 0; port->agreeN = 1;
81 | clearAllRcvdMsgs (bridge, givenPort);
82 | port->edgeDelayWhile = bridge->MigrateTime;
83 | }
84 | else if (state == RECEIVE)
85 | {
86 | updtBPDUVersion (bridge, givenPort);
87 | port->rcvdInternal = fromSameRegion (bridge, givenPort);
88 | rcvMsgs (bridge, givenPort);
89 | port->operEdge = port->isolate = port->rcvdBpdu = false;
90 | port->edgeDelayWhile = bridge->MigrateTime;
91 | }
92 | else
93 | assert (false);
94 | }
95 |
96 | const StateMachine PortReceive::sm =
97 | {
98 | #if STP_USE_LOG
99 | "PortReceive",
100 | &GetStateName,
101 | #endif
102 | &CheckConditions,
103 | &InitState
104 | };
105 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_sm_port_role_selection.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | // This file implements 13.36 from 802.1Q-2018.
6 |
7 | #include "stp_procedures.h"
8 | #include "stp_bridge.h"
9 | #include
10 |
11 | using namespace PortRoleSelection;
12 |
13 | #if STP_USE_LOG
14 | static const char* GetStateName (State state)
15 | {
16 | switch (state)
17 | {
18 | case INIT_TREE: return "INIT_TREE";
19 | case ROLE_SELECTION:return "ROLE_SELECTION";
20 | default: return "(undefined)";
21 | }
22 | }
23 | #endif
24 |
25 | // ============================================================================
26 |
27 | // Returns the new state, or 0 when no transition is to be made.
28 | static State CheckConditions (const STP_BRIDGE* bridge, TreeIndex givenTree, State state)
29 | {
30 | // ------------------------------------------------------------------------
31 | // Check global conditions.
32 |
33 | if (bridge->BEGIN)
34 | {
35 | if (state == INIT_TREE)
36 | {
37 | // The entry block for this state has been executed already.
38 | return (State)0;
39 | }
40 |
41 | return INIT_TREE;
42 | }
43 |
44 | // ------------------------------------------------------------------------
45 | // Check exit conditions from each state.
46 |
47 | if (state == INIT_TREE)
48 | return ROLE_SELECTION;
49 |
50 | if (state == ROLE_SELECTION)
51 | {
52 | for (unsigned int portIndex = 0; portIndex < bridge->portCount; portIndex++)
53 | {
54 | if (bridge->ports [portIndex]->trees [givenTree]->reselect)
55 | return ROLE_SELECTION;
56 | }
57 |
58 | return (State)0;
59 | }
60 |
61 | assert (false);
62 | return (State)0;
63 | }
64 |
65 | // ============================================================================
66 |
67 | static void InitState (STP_BRIDGE* bridge, TreeIndex givenTree, State state, unsigned int timestamp)
68 | {
69 | if (state == INIT_TREE)
70 | {
71 | updtRolesDisabledTree (bridge, givenTree);
72 | }
73 | else if (state == ROLE_SELECTION)
74 | {
75 | clearReselectTree (bridge, givenTree);
76 | updtRolesTree (bridge, givenTree);
77 | setSelectedTree (bridge, givenTree);
78 | }
79 | else
80 | assert (false);
81 | }
82 |
83 | const StateMachine PortRoleSelection::sm =
84 | {
85 | #if STP_USE_LOG
86 | "PortRoleSelection",
87 | &GetStateName,
88 | #endif
89 | &CheckConditions,
90 | &InitState
91 | };
92 |
93 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_sm_port_state_transition.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | // This file implements 13.38 from 802.1Q-2018.
6 |
7 | #include "stp_procedures.h"
8 | #include "stp_bridge.h"
9 | #include
10 |
11 | using namespace PortStateTransition;
12 |
13 | #if STP_USE_LOG
14 | static const char* GetStateName (State state)
15 | {
16 | switch (state)
17 | {
18 | case DISCARDING: return "DISCARDING";
19 | case LEARNING: return "LEARNING";
20 | case FORWARDING: return "FORWARDING";
21 | default: return "(undefined)";
22 | }
23 | }
24 | #endif
25 |
26 | // ============================================================================
27 |
28 | // Returns the new state, or 0 when no transition is to be made.
29 | static State CheckConditions (const STP_BRIDGE* bridge, PortAndTree pt, State state)
30 | {
31 | PortIndex givenPort = pt.portIndex;
32 | TreeIndex givenTree = pt.treeIndex;
33 |
34 | PORT* port = bridge->ports [givenPort];
35 | PORT_TREE* tree = port->trees [givenTree];
36 |
37 | // ------------------------------------------------------------------------
38 | // Check global conditions.
39 |
40 | if (bridge->BEGIN)
41 | {
42 | if (state == DISCARDING)
43 | {
44 | // The entry block for this state has been executed already.
45 | return (State)0;
46 | }
47 |
48 | return DISCARDING;
49 | }
50 |
51 | // ------------------------------------------------------------------------
52 | // Check exit conditions from each state.
53 |
54 | if (state == DISCARDING)
55 | {
56 | if (tree->learn)
57 | return LEARNING;
58 |
59 | return (State)0;
60 | }
61 |
62 | if (state == LEARNING)
63 | {
64 | if (!tree->learn)
65 | return DISCARDING;
66 |
67 | if (tree->forward)
68 | return FORWARDING;
69 |
70 | return (State)0;
71 | }
72 |
73 | if (state == FORWARDING)
74 | {
75 | if (!tree->forward)
76 | return DISCARDING;
77 |
78 | return (State)0;
79 | }
80 |
81 | assert (false);
82 | return (State)0;
83 | }
84 |
85 | // ============================================================================
86 |
87 | static void InitState (STP_BRIDGE* bridge, PortAndTree pt, State state, unsigned int timestamp)
88 | {
89 | PortIndex givenPort = pt.portIndex;
90 | TreeIndex givenTree = pt.treeIndex;
91 |
92 | PORT* port = bridge->ports[givenPort];
93 | PORT_TREE* tree = port->trees [givenTree];
94 |
95 | if (state == DISCARDING)
96 | {
97 | disableLearning (bridge, givenPort, givenTree, timestamp);
98 | tree->learning = false;
99 | disableForwarding (bridge, givenPort, givenTree, timestamp);
100 | tree->forwarding = false;
101 | }
102 | else if (state == LEARNING)
103 | {
104 | enableLearning (bridge, givenPort, givenTree, timestamp);
105 | tree->learning = true;
106 | }
107 | else if (state == FORWARDING)
108 | {
109 | enableForwarding (bridge, givenPort, givenTree, timestamp);
110 | tree->forwarding = true;
111 | }
112 | else
113 | assert (false);
114 | }
115 |
116 | const StateMachine PortStateTransition::sm =
117 | {
118 | #if STP_USE_LOG
119 | "PortStateTransition",
120 | &GetStateName,
121 | #endif
122 | &CheckConditions,
123 | &InitState
124 | };
125 |
--------------------------------------------------------------------------------
/mstp-lib/internal/stp_sm_port_timers.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | // This file implements 13.30 from 802.1Q-2018.
6 |
7 | #include "stp_procedures.h"
8 | #include "stp_bridge.h"
9 | #include
10 |
11 | using namespace PortTimers;
12 |
13 | #if STP_USE_LOG
14 | static const char* GetStateName (State state)
15 | {
16 | switch (state)
17 | {
18 | case ONE_SECOND: return "ONE_SECOND";
19 | case TICK: return "TICK";
20 | default: return "(undefined)";
21 | }
22 | }
23 | #endif
24 |
25 | // ============================================================================
26 |
27 | // Returns the new state, or 0 when no transition is to be made.
28 | static State CheckConditions (const STP_BRIDGE* bridge, PortIndex givenPort, State state)
29 | {
30 | PORT* port = bridge->ports[givenPort];
31 |
32 | // ------------------------------------------------------------------------
33 | // Check global conditions.
34 |
35 | if (bridge->BEGIN)
36 | {
37 | if (state == ONE_SECOND)
38 | {
39 | // The entry block for this state has been executed already.
40 | return (State)0;
41 | }
42 |
43 | return ONE_SECOND;
44 | }
45 |
46 | // ------------------------------------------------------------------------
47 | // Check exit conditions from each state.
48 |
49 | if (state == ONE_SECOND)
50 | {
51 | if (port->tick)
52 | return TICK;
53 |
54 | return (State)0;
55 | }
56 |
57 | if (state == TICK)
58 | return ONE_SECOND;
59 |
60 | assert (false);
61 | return (State)0;
62 | }
63 |
64 | // ============================================================================
65 |
66 | static void InitState (STP_BRIDGE* bridge, PortIndex givenPort, State state, unsigned int timestamp)
67 | {
68 | PORT* port = bridge->ports[givenPort];
69 |
70 | if (state == ONE_SECOND)
71 | {
72 | port->tick = false;
73 | }
74 | else if (state == TICK)
75 | {
76 | if (port->helloWhen > 0) port->helloWhen--;
77 | if (port->mDelayWhile > 0) port->mDelayWhile--;
78 | if (port->edgeDelayWhile > 0) port->edgeDelayWhile--;
79 | if (port->txCount > 0) port->txCount--;
80 | if (port->pseudoInfoHelloWhen > 0) port->pseudoInfoHelloWhen--;
81 |
82 | for (unsigned int treeIndex = 0; treeIndex < bridge->treeCount(); treeIndex++)
83 | {
84 | PORT_TREE* portTree = port->trees [treeIndex];
85 |
86 | if (portTree->tcWhile > 0) portTree->tcWhile--;
87 | if (portTree->fdWhile > 0) portTree->fdWhile--;
88 | if (portTree->rcvdInfoWhile > 0) portTree->rcvdInfoWhile--;
89 | if (portTree->rrWhile > 0) portTree->rrWhile--;
90 | if (portTree->tcDetected > 0) portTree->tcDetected--;
91 | if (portTree->rbWhile > 0) portTree->rbWhile--;
92 | }
93 | }
94 | }
95 |
96 | const StateMachine PortTimers::sm =
97 | {
98 | #if STP_USE_LOG
99 | "PortTimers",
100 | &GetStateName,
101 | #endif
102 | &CheckConditions,
103 | &InitState
104 | };
105 |
--------------------------------------------------------------------------------
/simulator/bridge_tree.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #pragma once
6 | #include "object.h"
7 | #include "win32/com_ptr.h"
8 |
9 | class bridge;
10 |
11 | using edge::object;
12 | using edge::uint32_p;
13 | using edge::temp_string_p;
14 | using edge::property_change_args;
15 | using edge::nvp;
16 | using edge::concrete_type;
17 |
18 | extern const nvp bridge_priority_nvps[];
19 | extern const char bridge_priority_type_name[];
20 | using bridge_priority_p = edge::enum_property;
21 |
22 | class bridge_tree : public object
23 | {
24 | using base = object;
25 |
26 | bridge* const _parent;
27 | size_t const _tree_index;
28 |
29 | SYSTEMTIME _last_topology_change;
30 | uint32_t _topology_change_count;
31 |
32 | friend class bridge;
33 |
34 | void on_topology_change (unsigned int timestamp);
35 | static void on_bridge_property_changing (void* arg, object* obj, const property_change_args& args);
36 | static void on_bridge_property_changed (void* arg, object* obj, const property_change_args& args);
37 |
38 | public:
39 | bridge_tree (bridge* parent, size_t tree_index);
40 |
41 | uint32_t bridge_priority() const;
42 | void set_bridge_priority (uint32_t priority);
43 |
44 | std::array root_priorty_vector() const;
45 | std::string root_bridge_id() const;
46 | uint32_t external_root_path_cost() const;
47 | std::string regional_root_id() const;
48 | uint32_t internal_root_path_cost() const;
49 | std::string designated_bridge_id() const;
50 | std::string designated_port_id() const;
51 | std::string receiving_port_id() const;
52 |
53 | uint32_t hello_time() const;
54 | uint32_t max_age() const;
55 | uint32_t bridge_forward_delay() const;
56 | uint32_t message_age() const;
57 | uint32_t remaining_hops() const;
58 |
59 | uint32_t topology_change_count() const { return _topology_change_count; }
60 |
61 | static const bridge_priority_p bridge_priority_property;
62 | static const temp_string_p root_id_property;
63 | static const uint32_p external_root_path_cost_property;
64 | static const temp_string_p regional_root_id_property;
65 | static const uint32_p internal_root_path_cost_property;
66 | static const temp_string_p designated_bridge_id_property;
67 | static const temp_string_p designated_port_id_property;
68 | static const temp_string_p receiving_port_id_property;
69 | static const uint32_p hello_time_property;
70 | static const uint32_p max_age_property;
71 | static const uint32_p forward_delay_property;
72 | static const uint32_p message_age_property;
73 | static const uint32_p remaining_hops_property;
74 | static const uint32_p topology_change_count_property;
75 | static const edge::property* const _properties[];
76 | static const edge::xtype _type;
77 | const concrete_type* type() const override final { return &_type; }
78 | };
79 |
80 |
--------------------------------------------------------------------------------
/simulator/edit_states/edit_state.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #pragma once
6 | #include "..\simulator.h"
7 | #include "win32\window.h"
8 |
9 | struct edit_state_deps
10 | {
11 | project_window_i* pw;
12 | edit_window_i* ew;
13 | project_i* project;
14 | selection_i* selection;
15 | };
16 |
17 | class edit_state abstract
18 | {
19 | protected:
20 | project_window_i* const _pw;
21 | edit_window_i* const _ew;
22 | project_i* const _project;
23 | selection_i* const _selection;
24 |
25 | public:
26 | edit_state (const edit_state_deps& deps)
27 | : _pw(deps.pw), _ew(deps.ew), _selection(deps.selection), _project(deps.project)
28 | { }
29 |
30 | virtual ~edit_state() { }
31 | virtual void process_mouse_button_down (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) { }
32 | virtual void process_mouse_button_up (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) { }
33 | virtual void process_mouse_move (const mouse_location& location) { }
34 | virtual std::optional process_key_or_syskey_down (UINT virtualKey, UINT modifierKeys) { return std::nullopt; }
35 | virtual std::optional process_key_or_syskey_up (UINT virtualKey, UINT modifierKeys) { return std::nullopt; }
36 | virtual void render (ID2D1DeviceContext* dc) { }
37 | virtual bool completed() const = 0;
38 | virtual HCURSOR cursor() const { return LoadCursor(nullptr, IDC_ARROW); }
39 | };
40 |
41 | std::unique_ptr create_state_move_bridges (const edit_state_deps& deps);
42 | std::unique_ptr create_state_move_port (const edit_state_deps& deps);
43 | std::unique_ptr create_state_create_bridge (const edit_state_deps& deps);
44 | std::unique_ptr create_state_create_wire (const edit_state_deps& deps);
45 | std::unique_ptr CreateStateMoveWirePoint (const edit_state_deps& deps, wire* wire, size_t pointIndex);
46 | std::unique_ptr CreateStateBeginningDrag (const edit_state_deps& deps,
47 | renderable_object* clickedObject,
48 | edge::mouse_button button,
49 | UINT modifierKeysDown,
50 | const mouse_location& location,
51 | HCURSOR cursor,
52 | std::unique_ptr&& stateMoveThreshold,
53 | std::unique_ptr&& stateButtonUp);
54 |
--------------------------------------------------------------------------------
/simulator/edit_states/move_bridges_es.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #include "pch.h"
6 | #include "edit_state.h"
7 | #include "bridge.h"
8 | #include "win32/utility_functions.h"
9 |
10 | class move_bridges_es : public edit_state
11 | {
12 | using base = edit_state;
13 |
14 | D2D1_POINT_2F _first_bridge_initial_location;
15 | D2D1_SIZE_F _offset_first_bridge;
16 |
17 | struct info
18 | {
19 | bridge* b;
20 | D2D1_SIZE_F offset_from_first;
21 | };
22 |
23 | std::vector _infos;
24 | bool _completed = false;
25 |
26 | public:
27 | using base::base;
28 |
29 | virtual void process_mouse_button_down (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) override final
30 | {
31 | auto firstBridge = static_cast(_selection->objects()[0]); assert (firstBridge != nullptr);
32 | _first_bridge_initial_location = firstBridge->location();
33 |
34 | for (auto o : _selection->objects())
35 | {
36 | auto b = dynamic_cast(o); assert (b != nullptr);
37 | _infos.push_back ({ b, b->location() - firstBridge->location() });
38 | }
39 |
40 | _offset_first_bridge = location.w - firstBridge->location();
41 | }
42 |
43 | virtual void process_mouse_move (const mouse_location& location) override final
44 | {
45 | auto firstBridgeLocation = location.w - _offset_first_bridge;
46 | _infos[0].b->set_location(firstBridgeLocation);
47 | for (size_t i = 1; i < _infos.size(); i++)
48 | _infos[i].b->set_location (firstBridgeLocation + _infos[i].offset_from_first);
49 | }
50 |
51 | virtual std::optional process_key_or_syskey_down (UINT virtualKey, UINT modifierKeys) override final
52 | {
53 | if (virtualKey == VK_ESCAPE)
54 | {
55 | _infos[0].b->set_location (_first_bridge_initial_location);
56 | for (size_t i = 1; i < _infos.size(); i++)
57 | _infos[i].b->set_location (_first_bridge_initial_location + _infos[i].offset_from_first);
58 |
59 | _completed = true;
60 | ::InvalidateRect (_ew->hwnd(), nullptr, FALSE);
61 | return 0;
62 | }
63 |
64 | return std::nullopt;
65 | }
66 |
67 | virtual void process_mouse_button_up (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) override final
68 | {
69 | _project->SetChangedFlag(true);
70 | _completed = true;
71 | }
72 |
73 | virtual bool completed() const override final { return _completed; }
74 | };
75 |
76 | std::unique_ptr create_state_move_bridges (const edit_state_deps& deps) { return std::make_unique(deps); }
77 |
--------------------------------------------------------------------------------
/simulator/edit_states/move_port_es.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #include "pch.h"
6 | #include "edit_state.h"
7 | #include "bridge.h"
8 | #include "port.h"
9 |
10 | class move_port_es : public edit_state
11 | {
12 | typedef edit_state base;
13 | port* _port;
14 | side _initialSide;
15 | float _initialOffset;
16 | bool _completed = false;
17 |
18 | public:
19 | using base::base;
20 |
21 | virtual void process_mouse_button_down (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) override final
22 | {
23 | assert (_selection->objects().size() == 1);
24 | _port = dynamic_cast(_selection->objects().front());
25 | assert (_port != nullptr);
26 | _initialSide = _port->side();
27 | _initialOffset = _port->offset();
28 | }
29 |
30 | virtual void process_mouse_move (const mouse_location& location) override final
31 | {
32 | _port->bridge()->SetCoordsForInteriorPort (_port, location.w);
33 | }
34 |
35 | virtual std::optional process_key_or_syskey_down (UINT virtualKey, UINT modifierKeys) override final
36 | {
37 | if (virtualKey == VK_ESCAPE)
38 | {
39 | _port->SetSideAndOffset (_initialSide, _initialOffset);
40 | _completed = true;
41 | return 0;
42 | }
43 |
44 | return std::nullopt;
45 | }
46 |
47 | virtual void process_mouse_button_up (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) override final
48 | {
49 | _project->SetChangedFlag(true);
50 | _completed = true;
51 | }
52 |
53 | virtual bool completed() const override final { return _completed; }
54 | };
55 |
56 | std::unique_ptr create_state_move_port (const edit_state_deps& deps) { return std::make_unique(deps); }
57 |
--------------------------------------------------------------------------------
/simulator/edit_states/move_wire_point_es.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #include "pch.h"
6 | #include "edit_state.h"
7 | #include "wire.h"
8 | #include "port.h"
9 |
10 | class MoveWirePointES : public edit_state
11 | {
12 | typedef edit_state base;
13 |
14 | wire* const _wire;
15 | size_t const _pointIndex;
16 | wire_end const _initialPoint;
17 | POINT _first_down_location;
18 |
19 | enum substate
20 | {
21 | waiting_first_down,
22 | waiting_first_up,
23 | waiting_second_down,
24 | waiting_second_up,
25 | down,
26 | };
27 |
28 | substate _substate = waiting_first_down;
29 |
30 | public:
31 | MoveWirePointES (const edit_state_deps& deps, wire* wire, size_t pointIndex)
32 | : base(deps), _wire(wire), _pointIndex(pointIndex), _initialPoint(wire->points()[pointIndex])
33 | { }
34 |
35 | virtual bool completed() const override final { return _substate == down; }
36 |
37 | virtual void process_mouse_button_down (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) override final
38 | {
39 | base::process_mouse_button_down (button, modifierKeysDown, location);
40 |
41 | if (button != edge::mouse_button::left)
42 | return;
43 |
44 | if (_substate == waiting_first_down)
45 | {
46 | _first_down_location = location.pt;
47 | _substate = waiting_first_up;
48 | }
49 | }
50 |
51 | virtual void process_mouse_move (const mouse_location& location) override
52 | {
53 | base::process_mouse_move(location);
54 |
55 | auto port = _ew->GetCPAt (location.d, SnapDistance);
56 | if (port != nullptr)
57 | {
58 | auto alreadyConnectedWire = _project->GetWireConnectedToPort(port);
59 | if (alreadyConnectedWire.first == nullptr)
60 | _wire->set_point(_pointIndex, port);
61 | }
62 | else
63 | _wire->set_point(_pointIndex, location.w);
64 |
65 | if (_substate == waiting_first_up)
66 | {
67 | RECT rc = { _first_down_location.x, _first_down_location.y, _first_down_location.x, _first_down_location.y };
68 | InflateRect (&rc, GetSystemMetrics(SM_CXDRAG), GetSystemMetrics(SM_CYDRAG));
69 | if (!PtInRect(&rc, location.pt))
70 | _substate = waiting_second_up;
71 | }
72 | }
73 |
74 | virtual void process_mouse_button_up (edge::mouse_button button, UINT modifierKeysDown, const mouse_location& location) override final
75 | {
76 | if (_substate == waiting_second_up)
77 | {
78 | _project->SetChangedFlag(true);
79 | _substate = down;
80 | }
81 | }
82 |
83 | virtual std::optional process_key_or_syskey_down (UINT virtualKey, UINT modifierKeys) override final
84 | {
85 | if (virtualKey == VK_ESCAPE)
86 | {
87 | _wire->set_point(_pointIndex, _initialPoint);
88 | _substate = down;
89 | return 0;
90 | }
91 |
92 | return std::nullopt;
93 | }
94 |
95 | virtual void render (ID2D1DeviceContext* rt) override final
96 | {
97 | auto& point = _wire->points()[_pointIndex];
98 | if (std::holds_alternative(point))
99 | _ew->RenderSnapRect (rt, std::get(point)->GetCPLocation());
100 | }
101 |
102 | virtual HCURSOR cursor() const override final { return LoadCursor(nullptr, IDC_CROSS); }
103 | };
104 |
105 | std::unique_ptr CreateStateMoveWirePoint (const edit_state_deps& deps, wire* wire, size_t pointIndex)
106 | {
107 | return std::unique_ptr(new MoveWirePointES(deps, wire, pointIndex));
108 | }
109 |
--------------------------------------------------------------------------------
/simulator/pch.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "pch.h"
3 |
4 |
--------------------------------------------------------------------------------
/simulator/pch.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #define NOMINMAX
5 | #define _USE_MATH_DEFINES
6 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
7 | #define _WIN7_PLATFORM_UPDATE // Needed by wincodec.h
8 |
9 | #include "targetver.h"
10 |
11 | // C/C++
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | // Windows
36 | #define _COM_NO_STANDARD_GUIDS_
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 | #include
49 | #include
50 | #undef DrawText
51 |
52 | #include "assert.h"
53 |
--------------------------------------------------------------------------------
/simulator/port_tree.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #pragma once
6 | #include "object.h"
7 | #include "win32/com_ptr.h"
8 | #include "stp.h"
9 |
10 | class bridge;
11 | class port;
12 |
13 | using edge::size_t_p;
14 | using edge::size_t_property_traits;
15 | using edge::uint32_p;
16 | using edge::bool_p;
17 | using edge::float_p;
18 | using edge::backed_string_p;
19 | using edge::temp_string_p;
20 | using edge::property;
21 | using edge::type;
22 | using edge::concrete_type;
23 | using edge::xtype;
24 | using edge::value_property;
25 | using edge::typed_object_collection_property;
26 | using edge::property_change_args;
27 | using edge::side;
28 | using edge::binary_reader;
29 | using edge::out_stream_i;
30 | using edge::nvp;
31 |
32 | extern const nvp port_priority_nvps[];
33 | extern const char port_priority_type_name[];
34 | using port_priority_p = edge::enum_property;
35 |
36 | extern const nvp port_role_nvps[];
37 | extern const char port_role_type_name[];
38 | using port_role_p = edge::enum_property;
39 |
40 | extern const char stp_disabled_text[];
41 |
42 | class port_tree : public edge::object
43 | {
44 | using base = edge::object;
45 |
46 | friend port;
47 |
48 | port* const _port;
49 | size_t const _tree_index;
50 | ULONGLONG _flush_tick_count = 0;
51 | bool _flush_text_visible = false;
52 |
53 | static UINT_PTR _flush_timer;
54 | static std::unordered_set _trees;
55 |
56 | static void on_bridge_property_changing (void* arg, object* obj, const property_change_args& args);
57 | static void on_bridge_property_changed (void* arg, object* obj, const property_change_args& args);
58 | static void CALLBACK flush_timer_proc (HWND hwnd, UINT, UINT_PTR, DWORD);
59 |
60 | public:
61 | port_tree (port* port, size_t tree_index);
62 | ~port_tree();
63 |
64 | uint32_t priority() const;
65 | void set_priority (uint32_t priority);
66 |
67 | uint32_t internal_port_path_cost() const;
68 | uint32_t admin_internal_port_path_cost() const;
69 | void set_admin_internal_port_path_cost (uint32_t value);
70 |
71 | bool learning() const;
72 | bool forwarding() const;
73 | STP_PORT_ROLE role() const;
74 |
75 | void flush_fdb (unsigned int timestamp);
76 |
77 | bool fdb_flush_text_visible() const { return _flush_text_visible; }
78 |
79 | size_t tree_index() const { return _tree_index; }
80 |
81 | static const size_t_p tree_index_property;
82 | static const port_priority_p priority_property;
83 | static const bool_p learning_property;
84 | static const bool_p forwarding_property;
85 | static const port_role_p role_property;
86 | static const uint32_p admin_internal_port_path_cost_property;
87 | static const uint32_p internal_port_path_cost_property;
88 | static const property* const _properties[];
89 | static const xtype _type;
90 | const concrete_type* type() const override final { return &_type; }
91 | };
92 |
--------------------------------------------------------------------------------
/simulator/renderable_object.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #pragma once
6 | #include "collection.h"
7 | #include "win32/com_ptr.h"
8 | #include "win32/zoomable_window.h"
9 |
10 | struct drawing_resources
11 | {
12 | edge::com_ptr _dWriteFactory;
13 | edge::com_ptr _poweredFillBrush;
14 | edge::com_ptr _unpoweredBrush;
15 | edge::com_ptr _brushWindowText;
16 | edge::com_ptr _brushWindow;
17 | edge::com_ptr _brushHighlight;
18 | edge::com_ptr _brushDiscardingPort;
19 | edge::com_ptr _brushLearningPort;
20 | edge::com_ptr _brushForwarding;
21 | edge::com_ptr _brushNoForwardingWire;
22 | edge::com_ptr _brushLoop;
23 | edge::com_ptr _brushTempWire;
24 | edge::com_ptr _strokeStyleForwardingWire;
25 | edge::com_ptr _strokeStyleNoForwardingWire;
26 | edge::com_ptr _regularTextFormat;
27 | edge::com_ptr _smallTextFormat;
28 | edge::com_ptr _smallBoldTextFormat;
29 | edge::com_ptr _strokeStyleSelectionRect;
30 | };
31 |
32 | class renderable_object : public edge::owned_object
33 | {
34 | public:
35 | struct ht_result
36 | {
37 | renderable_object* object;
38 | int code;
39 | bool operator==(const ht_result& other) const { return (this->object == other.object) && (this->code == other.code); }
40 | bool operator!=(const ht_result& other) const { return (this->object != other.object) || (this->code != other.code); }
41 | };
42 |
43 | struct invalidate_e : public edge::event { };
44 | invalidate_e::subscriber invalidated() { return invalidate_e::subscriber(this); }
45 |
46 | virtual void render_selection (const edge::zoomable_i* zoomable, ID2D1RenderTarget* rt, const drawing_resources& dos) const = 0;
47 | virtual ht_result hit_test (const edge::zoomable_i* zoomable, D2D1_POINT_2F dLocation, float tolerance) = 0;
48 | virtual D2D1_RECT_F extent() const = 0;
49 |
50 | protected:
51 | template
52 | void set_and_invalidate (const tpd_* pd, typename tpd_::value_t& field, typename tpd_::value_t value)
53 | {
54 | this->on_property_changing(pd);
55 | field = value;
56 | this->on_property_changed(pd);
57 | this->event_invoker()(this);
58 | }
59 | };
60 |
61 | struct project_i;
62 |
63 | class project_child : public renderable_object
64 | {
65 | friend class project;
66 |
67 | project_i* _project = nullptr;
68 |
69 | protected:
70 | virtual void on_added_to_project(project_i* project)
71 | {
72 | assert (_project == nullptr);
73 | _project = project;
74 | }
75 |
76 | virtual void on_removing_from_project(project_i* project)
77 | {
78 | assert (_project == project);
79 | _project = nullptr;
80 | }
81 |
82 | public:
83 | project_i* project() const { return _project; }
84 | };
85 |
--------------------------------------------------------------------------------
/simulator/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by simulator.rc
4 | //
5 | #define IDI_DESIGNER 107
6 | #define IDD_DIALOG_VLAN 108
7 | #define IDR_CONTEXT_MENU_EMPTY_SPACE 130
8 | #define IDR_CONTEXT_MENU_BRIDGE 131
9 | #define IDR_CONTEXT_MENU_PORT 132
10 | #define IDR_MAIN_MENU 133
11 | #define IDD_DIALOG_MST_CONFIG_ID 134
12 | #define IDR_ACCELERATOR1 135
13 | #define IDR_CONTEXT_MENU_LOG_WINDOW 136
14 | #define IDC_BUTTON_EDIT_MST_CONFIG_TABLE 1005
15 | #define IDC_COMBO_SELECTED_VLAN 1009
16 | #define IDC_EDIT_SELECTED_TREE 1010
17 | #define IDC_COMBO_NEW_WINDOW_VLAN 1011
18 | #define IDC_STATIC_CONFIG_TABLE 1012
19 | #define IDC_LIST_CONFIG_TABLE 1013
20 | #define IDC_BUTTON_USE_DEFAULT_CONFIG_TABLE 1014
21 | #define IDC_BUTTON_USE_TEST1_CONFIG_TABLE 1017
22 | #define IDC_STATIC_HINT_NOT_MSTP 1021
23 | #define IDC_STATIC_EXTENT 1025
24 | #define ID_NEW_BRIDGE 32772
25 | #define ID_PORT_AUTO_EDGE 32773
26 | #define ID_PORT_ADMIN_EDGE 32774
27 | #define ID_BRIDGE_ENABLE_STP 32775
28 | #define ID_BRIDGE_DISABLE_STP 32776
29 | #define ID_PASTE_BRIDGE 32777
30 | #define ID_FILE 32778
31 | #define ID_VIEW 32779
32 | #define ID_VIEW_PROPERTIES 32780
33 | #define ID_VIEW_STPLOG 32781
34 | #define ID_VIEW_VLANS 32782
35 | #define ID_FILE_NEW 32783
36 | #define ID_FILE_OPEN 32784
37 | #define ID_FILE_SAVEAS 32785
38 | #define ID_FILE_EXIT 32786
39 | #define ID_FILE_SAVE 32787
40 | #define ID_EDIT 32788
41 | #define ID_HELP 32791
42 | #define ID_HELP_ABOUT 32792
43 | #define ID_PAUSE_SIMULATION 32793
44 | #define ID_RESUME_SIMULATION 32794
45 | #define ID_FILE_RECENT 32795
46 | #define ID_RECENT_FILE_FIRST 32796
47 | #define ID_RECENT_FILE_LAST 32815
48 | #define ID_CLEAR_ALL_LOGS 32816
49 | #define IDC_STATIC -1
50 |
51 | // Next default values for new objects
52 | //
53 | #ifdef APSTUDIO_INVOKED
54 | #ifndef APSTUDIO_READONLY_SYMBOLS
55 | #define _APS_NO_MFC 1
56 | #define _APS_NEXT_RESOURCE_VALUE 137
57 | #define _APS_NEXT_COMMAND_VALUE 32817
58 | #define _APS_NEXT_CONTROL_VALUE 1026
59 | #define _APS_NEXT_SYMED_VALUE 110
60 | #endif
61 | #endif
62 |
--------------------------------------------------------------------------------
/simulator/simulator.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adigostin/mstp-lib/57089f9b7826a65fdd8d391a31d0598476c3488c/simulator/simulator.ico
--------------------------------------------------------------------------------
/simulator/simulator.natvis:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 0
6 | 1
7 | 2
8 | 3
9 | 4
10 | 5
11 | 6
12 | 7
13 | 8
14 | 9
15 | A
16 | B
17 | C
18 | D
19 | E
20 | F
21 |
22 |
23 |
24 | 0
25 | 1
26 | 2
27 | 3
28 | 4
29 | 5
30 | 6
31 | 7
32 | 8
33 | 9
34 | A
35 | B
36 | C
37 | D
38 | E
39 | F
40 |
41 |
42 |
43 | {*(natvis::hex_dummy_high*)(&vh)}{*(natvis::hex_dummy_low*)(&vh)}{*(natvis::hex_dummy_high*)(&vl)}{*(natvis::hex_dummy_low*)(&vl)}
44 |
45 |
46 | {*(uint16_nbo*)(&bytes[0])}{*(uint16_nbo*)(&bytes[2])}{*(uint16_nbo*)(&bytes[4])}
47 |
48 |
49 | {_priorityAndMstid}.{_address}
50 |
51 |
52 | {(vhh << 24) | (vhl << 16) | (vlh << 8) | vll}
53 |
54 |
55 | {*(uint16_nbo*)this}
56 |
57 |
58 | {RootId}-{ExternalRootPathCost}-{RegionalRootId}-{InternalRootPathCost}-{DesignatedBridgeId}-{DesignatedPortId}
59 |
60 |
--------------------------------------------------------------------------------
/simulator/simulator.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {44c75b95-8381-4205-bb9c-ff949707452e}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | edit_states
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | edit_states
32 |
33 |
34 | edit_states
35 |
36 |
37 |
38 | edit_states
39 |
40 |
41 | edit_states
42 |
43 |
44 |
45 |
46 | edit_states
47 |
48 |
49 | edit_states
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/simulator/targetver.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | // Including SDKDDKVer.h defines the highest available Windows platform.
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 | #include
8 | #define _WIN32_WINNT _WIN32_WINNT_WIN7
9 | #include
10 |
--------------------------------------------------------------------------------
/simulator/test.c:
--------------------------------------------------------------------------------
1 |
2 | #include "stp.h"
3 |
--------------------------------------------------------------------------------
/simulator/tests/bridge_tests.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #include "pch.h"
6 | #include "bridge.h"
7 | #include "test_helpers.h"
8 |
9 | using namespace Microsoft::VisualStudio::CppUnitTestFramework;
10 |
11 | TEST_CLASS(bridge_tests)
12 | {
13 | TEST_METHOD(create_bridge_test1)
14 | {
15 | uint32_t port_count = 4;
16 | uint32_t msti_count = 0;
17 | mac_address address = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 };
18 | auto b = std::make_unique(port_count, msti_count, address);
19 | }
20 |
21 | TEST_METHOD(disable_stp_test1)
22 | {
23 | uint32_t port_count = 4;
24 | uint32_t msti_count = 0;
25 | mac_address address = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 };
26 | auto b = std::make_unique(port_count, msti_count, address);
27 |
28 | auto get_root_bridge_id = [&b] { return b->trees()[0]->root_bridge_id(); };
29 |
30 | b->set_stp_enabled(true);
31 | get_root_bridge_id();
32 |
33 | b->set_stp_enabled(false);
34 | Assert::ExpectException(get_root_bridge_id);
35 |
36 | b->set_stp_enabled(true);
37 | get_root_bridge_id();
38 | }
39 |
40 | TEST_METHOD(undefined_role_test)
41 | {
42 | STP_PORT_ROLE role_from_callback = STP_PORT_ROLE_UNDEFINED;
43 | auto bridge = test_bridge(4, 0, 0, { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 });
44 | bridge.port_role_changed = [&role_from_callback](size_t portIndex, size_t treeIndex, enum STP_PORT_ROLE role)
45 | {
46 | role_from_callback = role;
47 | };
48 |
49 | Assert::AreEqual (STP_PORT_ROLE_UNDEFINED, role_from_callback);
50 |
51 | STP_StartBridge(bridge, 0);
52 |
53 | Assert::AreEqual (STP_PORT_ROLE_DISABLED, role_from_callback);
54 | }
55 |
56 | TEST_METHOD(receive_more_mstis_on_same_mst_config)
57 | {
58 | size_t port_count = 4;
59 | size_t msti_count = 5;
60 | test_bridge bridge0 (port_count, msti_count, 16, { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 });
61 | STP_SetStpVersion (bridge0, STP_VERSION_MSTP, 0);
62 | STP_SetMstConfigName (bridge0, "ABC", 0);
63 | STP_StartBridge (bridge0, 0);
64 | STP_OnPortEnabled (bridge0, 0, 100, true, 0);
65 |
66 | msti_count = 4;
67 | test_bridge bridge1 (port_count, msti_count, 16, { 0x10, 0x20, 0x30, 0x40, 0x50, 0x70 });
68 | STP_SetStpVersion (bridge1, STP_VERSION_MSTP, 0);
69 | STP_SetMstConfigName (bridge1, "ABC", 0);
70 | STP_StartBridge (bridge1, 0);
71 | STP_OnPortEnabled (bridge1, 0, 100, true, 0);
72 |
73 | exchange_bpdus (bridge0, 0, bridge1, 0); // shouldn't crash
74 | }
75 |
76 | TEST_METHOD(test_designated_bridge_priority_on_msti)
77 | {
78 | test_bridge bridge (4, 4, 16, { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 });
79 | STP_SetStpVersion (bridge, STP_VERSION_MSTP, 0);
80 | STP_SetBridgePriority (bridge, 1, 0x6000, 0);
81 | STP_StartBridge (bridge, 0);
82 |
83 | // First 8 bytes are RootId and for MSTIs must always be zero (see definition of PRIORITY_VECTOR in stp_base_types.h)
84 | unsigned char rpv[36];
85 | STP_GetRootPriorityVector(bridge, 1, rpv);
86 | uint64_t root_id;
87 | memcpy (&root_id, rpv, 8);
88 | Assert::AreEqual (0ull, root_id);
89 | }
90 | };
91 |
--------------------------------------------------------------------------------
/simulator/tests/pch.cpp:
--------------------------------------------------------------------------------
1 | // pch.cpp: source file corresponding to the pre-compiled header
2 |
3 | #include "pch.h"
4 |
5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
6 |
--------------------------------------------------------------------------------
/simulator/tests/pch.h:
--------------------------------------------------------------------------------
1 |
2 | #pragma once
3 |
4 | #define NOMINMAX
5 | #define _USE_MATH_DEFINES
6 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
7 | #define _WIN7_PLATFORM_UPDATE // Needed by wincodec.h
8 |
9 | #include "targetver.h"
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 |
--------------------------------------------------------------------------------
/simulator/tests/project_tests.cpp:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #include "pch.h"
6 | #include "bridge.h"
7 | #include "wire.h"
8 | #include "simulator.h"
9 | #include "test_helpers.h"
10 |
11 | using namespace Microsoft::VisualStudio::CppUnitTestFramework;
12 |
13 | extern const project_factory_t project_factory;
14 |
15 | TEST_CLASS(project_tests)
16 | {
17 | public:
18 | TEST_METHOD(TestMethod1)
19 | {
20 | uint32_t port_count = 4;
21 | uint32_t msti_count = 0;
22 | auto p = project_factory();
23 | p->insert_bridge(0, std::make_unique(port_count, msti_count, mac_address{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 }));
24 | p->insert_bridge(1, std::make_unique(port_count, msti_count, mac_address{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x70 }));
25 | p->insert_bridge(2, std::make_unique(port_count, msti_count, mac_address{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x80 }));
26 |
27 | auto w = std::make_unique();
28 | w->set_p0(p->bridges()[1]->ports()[2].get());
29 | w->set_p1(p->bridges()[2]->ports()[3].get());
30 | p->insert_wire(0, std::move(w));
31 |
32 | Assert::AreEqual (p->bridges()[1]->ports()[2].get(), std::get(p->wires()[0]->p0()));
33 | Assert::AreEqual (p->bridges()[2]->ports()[3].get(), std::get(p->wires()[0]->p1()));
34 |
35 | p->remove_bridge((size_t)0);
36 |
37 | Assert::AreEqual (p->bridges()[0]->ports()[2].get(), std::get(p->wires()[0]->p0()));
38 | Assert::AreEqual (p->bridges()[1]->ports()[3].get(), std::get(p->wires()[0]->p1()));
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/simulator/tests/test_helpers.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #pragma once
6 | #include "CppUnitTest.h"
7 | #include "stp.h"
8 | #include "port.h"
9 |
10 | using namespace Microsoft::VisualStudio::CppUnitTestFramework;
11 |
12 | namespace Microsoft::VisualStudio::CppUnitTestFramework
13 | {
14 | template<>
15 | static inline std::wstring ToString(port* p)
16 | {
17 | return L"port";
18 | }
19 |
20 | template<>
21 | static inline std::wstring ToString (const STP_PORT_ROLE& role)
22 | {
23 | std::string_view str = STP_GetPortRoleString(role);
24 | return std::wstring (str.begin(), str.end());
25 | }
26 | }
27 |
28 | class test_bridge
29 | {
30 | STP_BRIDGE* stp_bridge;
31 |
32 | static void* StpCallback_AllocAndZeroMemory (unsigned int size);
33 | static void StpCallback_FreeMemory (void* p);
34 | static void* StpCallback_TransmitGetBuffer (const STP_BRIDGE* bridge, unsigned int portIndex, unsigned int bpduSize, unsigned int timestamp);
35 | static void StpCallback_TransmitReleaseBuffer (const STP_BRIDGE* bridge, void* bufferReturnedByGetBuffer);
36 | static void StpCallback_OnPortRoleChanged (const STP_BRIDGE* bridge, unsigned int portIndex, unsigned int treeIndex, STP_PORT_ROLE role, unsigned int timestamp);
37 | static const STP_CALLBACKS callbacks;
38 |
39 | std::vector tx_buffer;
40 | size_t tx_buffer_port_index;
41 |
42 | public:
43 | test_bridge (size_t port_count, size_t msti_count, uint16_t max_vlan_number, const std::array& bridge_address);
44 | test_bridge (const test_bridge&) = delete;
45 | test_bridge& operator= (const test_bridge&) = delete;
46 | ~test_bridge();
47 |
48 | operator STP_BRIDGE* () const { return stp_bridge; }
49 |
50 | using tx_queue = std::queue>;
51 | std::unordered_map tx_queues;
52 | std::function port_role_changed;
53 | };
54 |
55 | bool exchange_bpdus (test_bridge& one, size_t one_port, test_bridge& other, size_t other_port);
56 |
--------------------------------------------------------------------------------
/simulator/tests/tests.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/simulator/wire.h:
--------------------------------------------------------------------------------
1 |
2 | // This file is part of the mstp-lib library, available at https://github.com/adigostin/mstp-lib
3 | // Copyright (c) 2011-2020 Adi Gostin, distributed under Apache License v2.0.
4 |
5 | #pragma once
6 | #include "renderable_object.h"
7 | #include "win32/utility_functions.h"
8 | #include "win32/xml_serializer.h"
9 |
10 | class port;
11 | struct project_i;
12 |
13 | using loose_wire_end = D2D1_POINT_2F;
14 | using connected_wire_end = port*;
15 | using serialized_connected_end = std::pair;
16 | using wire_end = std::variant;
17 |
18 | using edge::type;
19 | using edge::concrete_type;
20 | using edge::xtype;
21 | using edge::property;
22 | using edge::typed_property;
23 | using edge::uint32_p;
24 | using edge::ui_visible;
25 | using edge::object;
26 | using edge::out_stream_i;
27 | using edge::binary_reader;
28 | using edge::com_ptr;
29 |
30 | struct wire_end_property_traits
31 | {
32 | static constexpr char type_name[] = "wire_end";
33 | using value_t = wire_end;
34 | static void to_string (value_t from, std::string& to);
35 | static void from_string (std::string_view from, value_t& to);
36 | static void serialize (value_t from, out_stream_i* to) { assert(false); }
37 | static void deserialize (binary_reader& from, value_t& to) { assert(false); }
38 | };
39 | using wire_end_p = typed_property;
40 |
41 | class wire : public project_child, public edge::deserialize_i
42 | {
43 | using base = project_child;
44 |
45 | std::array _points;
46 |
47 | public:
48 | wire() = default;
49 | wire (wire_end firstEnd, wire_end secondEnd);
50 |
51 | // deserialize_i
52 | virtual void on_deserializing() override;
53 | virtual void on_deserialized() override;
54 |
55 | const std::array& points() const { return _points; }
56 | wire_end point (size_t i) const { return _points[i]; }
57 | void set_point (size_t i, wire_end point);
58 |
59 | wire_end p0() const { return _points[0]; }
60 | void set_p0 (wire_end p0) { set_point(0, p0); }
61 | void set_p0 (port* p0) { set_point(0, p0); }
62 | wire_end p1() const { return _points[1]; }
63 | void set_p1 (wire_end p1) { set_point(1, p1); }
64 | void set_p1 (port* p1) { set_point(1, p1); }
65 |
66 | D2D1_POINT_2F point_coords (size_t pointIndex) const;
67 |
68 | void render (ID2D1RenderTarget* rt, const drawing_resources& dos, bool forwarding, bool hasLoop) const;
69 |
70 | virtual void render_selection (const edge::zoomable_i* zoomable, ID2D1RenderTarget* rt, const drawing_resources& dos) const override final;
71 | virtual ht_result hit_test (const edge::zoomable_i* zoomable, D2D1_POINT_2F dLocation, float tolerance) override final;
72 | virtual D2D1_RECT_F extent() const override;
73 |
74 | static const wire_end_p p0_property;
75 | static const wire_end_p p1_property;
76 | static const property* const _properties[];
77 | static const xtype _type;
78 | virtual const concrete_type* type() const override { return &_type; }
79 | };
80 |
--------------------------------------------------------------------------------