Add the state machine.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
This commit is contained in:
		
							parent
							
								
									bb1f18d87b
								
							
						
					
					
						commit
						f5ef4a3d3d
					
				
							
								
								
									
										301
									
								
								fsm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								fsm.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,301 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file fsm.c
 | 
				
			||||||
 | 
					 * @note Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include "fsm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum port_state next = state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EV_INITIALIZE == event || EV_POWERUP == event)
 | 
				
			||||||
 | 
							return PS_INITIALIZING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (state) {
 | 
				
			||||||
 | 
						case PS_INITIALIZING:
 | 
				
			||||||
 | 
							next = PS_LISTENING;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_FAULTY:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_CLEARED:
 | 
				
			||||||
 | 
								next = PS_INITIALIZING;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_DISABLED:
 | 
				
			||||||
 | 
							if (EV_DESIGNATED_ENABLED == event)
 | 
				
			||||||
 | 
								next = PS_INITIALIZING;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_LISTENING:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
								next = PS_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
								next = PS_PRE_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_PASSIVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_PRE_MASTER:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_QUALIFICATION_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
								next = PS_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_PASSIVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_MASTER:
 | 
				
			||||||
 | 
						case PS_GRAND_MASTER:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_PASSIVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_PASSIVE:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
								next = PS_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
								next = PS_PRE_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_UNCALIBRATED:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
								next = PS_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_MASTER_CLOCK_SELECTED:
 | 
				
			||||||
 | 
								next = PS_SLAVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
								next = PS_PRE_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_PASSIVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_SLAVE:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
								next = PS_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_SYNCHRONIZATION_FAULT:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
								next = PS_PRE_MASTER;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_PASSIVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return next;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						enum port_state next = state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (EV_INITIALIZE == event || EV_POWERUP == event)
 | 
				
			||||||
 | 
							return PS_INITIALIZING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (state) {
 | 
				
			||||||
 | 
						case PS_INITIALIZING:
 | 
				
			||||||
 | 
							next = PS_LISTENING;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_FAULTY:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_CLEARED:
 | 
				
			||||||
 | 
								next = PS_INITIALIZING;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_DISABLED:
 | 
				
			||||||
 | 
							if (EV_DESIGNATED_ENABLED == event)
 | 
				
			||||||
 | 
								next = PS_INITIALIZING;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_LISTENING:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_LISTENING;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_UNCALIBRATED:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_LISTENING;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_MASTER_CLOCK_SELECTED:
 | 
				
			||||||
 | 
								next = PS_SLAVE;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case PS_SLAVE:
 | 
				
			||||||
 | 
							switch (event) {
 | 
				
			||||||
 | 
							case EV_DESIGNATED_DISABLED:
 | 
				
			||||||
 | 
								next = PS_DISABLED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_FAULT_DETECTED:
 | 
				
			||||||
 | 
								next = PS_FAULTY;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES:
 | 
				
			||||||
 | 
							case EV_RS_MASTER:
 | 
				
			||||||
 | 
							case EV_RS_PASSIVE:
 | 
				
			||||||
 | 
								next = PS_LISTENING;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_SYNCHRONIZATION_FAULT:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case EV_RS_SLAVE:
 | 
				
			||||||
 | 
								next = PS_UNCALIBRATED;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return next;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								fsm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								fsm.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @file fsm.h
 | 
				
			||||||
 | 
					 * @brief The finite state machine for ports on boundary and ordinary clocks.
 | 
				
			||||||
 | 
					 * @note Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					 * with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef HAVE_FSM_H
 | 
				
			||||||
 | 
					#define HAVE_FSM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Defines the state of a port. */
 | 
				
			||||||
 | 
					enum port_state {
 | 
				
			||||||
 | 
						PS_INITIALIZING = 1,
 | 
				
			||||||
 | 
						PS_FAULTY,
 | 
				
			||||||
 | 
						PS_DISABLED,
 | 
				
			||||||
 | 
						PS_LISTENING,
 | 
				
			||||||
 | 
						PS_PRE_MASTER,
 | 
				
			||||||
 | 
						PS_MASTER,
 | 
				
			||||||
 | 
						PS_GRAND_MASTER,
 | 
				
			||||||
 | 
						PS_PASSIVE,
 | 
				
			||||||
 | 
						PS_UNCALIBRATED,
 | 
				
			||||||
 | 
						PS_SLAVE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Defines the events for the port state machine. */
 | 
				
			||||||
 | 
					enum fsm_event {
 | 
				
			||||||
 | 
						EV_NONE,
 | 
				
			||||||
 | 
						EV_POWERUP,
 | 
				
			||||||
 | 
						EV_INITIALIZE,
 | 
				
			||||||
 | 
						EV_DESIGNATED_ENABLED,
 | 
				
			||||||
 | 
						EV_DESIGNATED_DISABLED,
 | 
				
			||||||
 | 
						EV_FAULT_CLEARED,
 | 
				
			||||||
 | 
						EV_FAULT_DETECTED,
 | 
				
			||||||
 | 
						EV_STATE_DECISION_EVENT,
 | 
				
			||||||
 | 
						EV_QUALIFICATION_TIMEOUT_EXPIRES,
 | 
				
			||||||
 | 
						EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES,
 | 
				
			||||||
 | 
						EV_SYNCHRONIZATION_FAULT,
 | 
				
			||||||
 | 
						EV_MASTER_CLOCK_SELECTED,
 | 
				
			||||||
 | 
						EV_RS_MASTER,
 | 
				
			||||||
 | 
						EV_RS_SLAVE,
 | 
				
			||||||
 | 
						EV_RS_PASSIVE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Run the state machine for a BC or OC port.
 | 
				
			||||||
 | 
					 * @param state  The current state of the port.
 | 
				
			||||||
 | 
					 * @param event  The event to be processed.
 | 
				
			||||||
 | 
					 * @return       The new state for the port.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum port_state ptp_fsm(enum port_state state, enum fsm_event event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Run the state machine for a slave only clock.
 | 
				
			||||||
 | 
					 * @param state  The current state of the port.
 | 
				
			||||||
 | 
					 * @param event  The event to be processed.
 | 
				
			||||||
 | 
					 * @return       The new state for the port.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user