<root>
<document scada='0' projtype='1' schema='103' license='1,82702381,95CJQR' title='' description='' fcversion='720899' target='PIC.16F.16F1937' >
	<config data='!0,fe2!10,1633%0,2%3,0%5,1%6,1%7,1%8,1%9,3%b,1%c,0%d,0%10,3%14,3%18,0%19,1%1a,1%1c,1%1d,0' clkspd='19660800' simspd='1' usewdt='0' constif='0' Use3V3='0' />
	<plugins >
		<dll_models enabled='1' />
	</plugins>
	<supplement use='0' head='' body='' />
	<debug />
	<traces />
	<ghost >
		<FK2 >
			<data name='FK2D0' port='4294967295' pin='4294967295' />
			<data name='FK2D1' port='4294967295' pin='4294967295' />
			<data name='FK2D2' port='4294967295' pin='4294967295' />
			<data name='FK2D3' port='4294967295' pin='4294967295' />
			<data name='FK2D4' port='4294967295' pin='4294967295' />
			<data name='FK2D5' port='4294967295' pin='4294967295' />
			<data name='FK2D6' port='4294967295' pin='4294967295' />
			<data name='FK2D7' port='4294967295' pin='4294967295' />
			<data name='FK2D8' port='4294967295' pin='4294967295' />
			<data name='FK2D9' port='4294967295' pin='4294967295' />
			<data name='FK2D10' port='4294967295' pin='4294967295' />
			<data name='FK2D11' port='4294967295' pin='4294967295' />
			<data name='FK2D12' port='4294967295' pin='4294967295' />
			<data name='FK2D13' port='4294967295' pin='4294967295' />
			<data name='FK2D14' port='4294967295' pin='4294967295' />
			<data name='FK2D15' port='4294967295' pin='4294967295' />
			<data name='FK2A0' port='4294967295' pin='4294967295' />
			<data name='FK2A1' port='4294967295' pin='4294967295' />
			<data name='FK2A2' port='4294967295' pin='4294967295' />
			<data name='FK2A3' port='4294967295' pin='4294967295' />
			<data name='FK2A4' port='4294967295' pin='4294967295' />
			<data name='FK2A5' port='4294967295' pin='4294967295' />
		</FK2>
		<ICD >
			<data name='AnalogPrescaleValue' value='19' />
			<data name='DigitalSampleRate' value='100000' />
			<data name='BreakpointCount' value='8' />
			<data name='CallStackDepthCount' value='8' />
			<data name='ClockPort' value='1' />
			<data name='ClockPin' value='6' />
			<data name='DataPort' value='1' />
			<data name='DataPin' value='7' />
			<data name='UseDefaultPins' value='1' />
			<data name='WrapEnabled' value='1' />
			<data name='CommsDelayOverridden' value='0' />
			<data name='CommsDelay' value='9' />
			<data name='CalculatedCommsDelay' value='9' />
			<data name='AnalogEB2PrescaleValue' value='2' />
			<data name='DigitalEB2SampleRate' value='100000' />
		</ICD>
		<pins >
			<digital A='0' B='0' C='0' D='0' E='0' F='0' G='0' H='0' I='0' J='0' K='0' L='0' M='0' N='0' O='0' P='0' Q='0' R='0' S='0' T='0' U='0' V='0' W='0' X='0' Y='0' Z='0' />
			<analog A='0' B='0' C='0' D='0' E='0' F='0' G='0' H='0' I='0' J='0' K='0' L='0' M='0' N='0' O='0' P='0' Q='0' R='0' S='0' T='0' U='0' V='0' W='0' X='0' Y='0' Z='0' />
		</pins>
	</ghost>
	<components >
		<settings autoimg='0' center='1' unitscale='0' fixedscale='0' fixedx='1' fixedy='1' fixedz='1' headcode='0' />
		<definition guid='5d9e3c56-f5f8-4183-8580-387ac0e83693' vstate='40' vmin='0' vmaj='1' srcleaf='WebSocket.fcfx' visiblename='WebSocket (GENERIC)' description='WebSocket server and client component designed to work with the Network Comms abstraction layer.

Server mode: use CreateServerSocket to listen, then poll CheckSocketActivity to accept a browser or client connection (RFC 6455 HTTP upgrade handshake) and receive frames.

Client mode: use Connect to open a link to a remote WebSocket server, then poll CheckSocketActivity to receive frames.

SendText / SendBinary and the GetRx macros work identically in both modes. 
Frames are masked automatically in client mode.

Ping, pong and close control frames are handled automatically.' category='Comms: Networking' category2='' category3='' bIs2dOnly='1' bIs3dOnly='0' bIsWysiwyg='0' catenable='1' author='Matrix Ltd.' manuname='' manucode='' sysinfo='1052939' keywords='websocket|ws|socket|realtime' dynamic='1' scadaCompatible='1' embeddedCompatible='1' showmacros='1' iconpath='..\..\Icons\Components\Web Server.png' />
		<component class_type='root' codename='WebSocket' panelId='-1' x='0' y='0' z='0' xsz='1' ysz='1' zsz='1' xang='0' yang='0' zang='0' xquat='0' yquat='0' zquat='0' wquat='1' visible='1' scadavisible='1' interactive='1' solid='1' layer='0' poslock='0' ancTop='0' ancBottom='0' ancLeft='0' ancRight='0' ancMinX='0' ancMinY='0' angle2d='0' comp2dType='0' >
			<resources />
			<properties >
				<property name='Max Frame Size (B)' target='MaxFrame' typeid='21' hidden='0' locked='0' info='Number of bytes reserved for the payload of a received WebSocket frame. Larger frames are truncated.' />
				<property name='Timeout (ms)' target='Timeout' typeid='21' hidden='0' locked='0' info='Number of milliseconds to wait for data when performing the CheckSocketActivity macro.' />
				<property name='Keepalive Ping (calls)' target='PingIdle' typeid='21' hidden='0' locked='0' info='Send a ping after this many consecutive CheckSocketActivity calls with nothing received, and use the same interval between retries. 
Browsers reply to pings automatically but never send their own. 
0 disables the keepalive entirely, so a client that vanishes without a close frame will hold the server forever. 
When the link is idle each call takes about Timeout ms, so 100 calls at the default 120 ms is roughly 12 seconds.' />
				<property name='Keepalive Retries' target='PingRetries' typeid='21' hidden='0' locked='0' info='How many extra pings to send when the first goes unanswered before declaring the link dead and freeing the server to accept a new client. 
0 means give up after the first unanswered ping.
The link is dropped after Keepalive Ping x (Retries + 2) idle calls.' />
				<property name='Network Comms Component' target='Component' typeid='17' hidden='1' locked='0' info='Redirects communications via the selected component allowing different TCP/IP modules with different macros to work.' filter='91049bf5-2436-42dc-947a-c30c86463d98' />
				<property name='LinkTo' target='LibraryComponent1::OutputIcon::LinkTo' typeid='16' hidden='0' locked='0' info='' filter='000' />
			</properties>
			<values >
				<value target='MaxFrame' data='128' />
				<value target='Timeout' data='120' />
				<value target='PingIdle' data='100' />
				<value target='PingRetries' data='2' />
				<value target='Component' data='0' />
				<value target='LibraryComponent1::OutputIcon::LinkTo' data='0' />
			</values>
			<events >
				<event class='Compile' event='GetVarSize' target='Ev_GetVarSize' />
				<event class='System' event='LoadComplete' target='Ev_LoadComplete' />
				<event class='Components' event='Initialise' target='Ev_Initialise' />
				<event class='Components' event='Property' target='Ev_Property' />
				<event class='Components' event='Renamed' target='Ev_Renamed' />
			</events>
			<apis >
				<api name='GetRxByte' alt='GetRxByte' type='1' proto='1' />
				<api name='Connect' alt='Connect' type='1' proto='1' />
				<api name='GetRxOpcode' alt='GetRxOpcode' type='1' proto='1' />
				<api name='Disconnect' alt='Disconnect' type='1' proto='1' />
				<api name='Ping' alt='Ping' type='1' proto='1' />
				<api name='IsConnected' alt='IsConnected' type='1' proto='1' />
				<api name='IsClientMode' alt='IsClientMode' type='1' proto='1' />
				<api name='GetRxCount' alt='GetRxCount' type='1' proto='1' />
				<api name='GetRxString' alt='GetRxString' type='1' proto='1' />
				<api name='CreateServerSocket' alt='CreateServerSocket' type='1' proto='1' />
				<api name='CheckSocketActivity' alt='CheckSocketActivity' type='1' proto='1' />
				<api name='SendText' alt='SendText' type='1' proto='1' />
				<api name='Initialise' alt='Initialise' type='1' proto='1' />
				<api name='SendBinary' alt='SendBinary' type='1' proto='1' />
			</apis>
			<variables >
				<variable public='0' >
					<def class_type='variable' name='Seed' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
				<variable public='0' >
					<def class_type='variable' name='RxCount' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
				<variable public='0' >
					<def class_type='variable' name='RxOpcode' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
				<variable public='0' >
					<def class_type='variable' name='RxData' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
						<array size='128' />
					</def>
				</variable>
				<variable public='0' >
					<def class_type='variable' name='PingsSent' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
				<variable public='0' >
					<def class_type='variable' name='IsClient' type='b1' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
				<variable public='0' >
					<def class_type='variable' name='Connected' type='b1' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
				<variable public='0' >
					<def class_type='variable' name='IdleCount' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
				</variable>
			</variables>
			<macros >
				<macro >
					<flowline name='GetRxByte' description='Returns a single byte from the last received data frame payload.' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Index' type='u16' description='Byte index 0 to GetRxCount - 1' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = 0' />
						</command>
						<command class_type='decision' title='In range?' exp='.Index &lt; RxCount' swap='0' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Return = RxData[.Index]' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Connect' description='Client mode: connects to a remote WebSocket server and performs the HTTP upgrade handshake.
Once connected use CheckSocketActivity to receive frames and SendText / SendBinary to transmit, exactly as in server mode.
Returns: 1 = Connected / 0 = TCP connect failed / 2 = WebSocket handshake rejected' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Address' type='T8*' description='IP address or host name of the server (used for the Host header too)' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</param>
						<param name='Port' type='u16' description='Server port, usually 80' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Path' type='T8*' description='Resource path e.g. &quot;/&quot; or &quot;/ws&quot;' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</param>
						<local name='ok' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Nonce' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='16' />
						</local>
						<local name='Key' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='36' />
						</local>
						<local name='Accept' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='32' />
						</local>
						<local name='Expected' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='32' />
						</local>
						<local name='Line' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='128' />
						</local>
						<local name='RxTempBuff' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<local name='n' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='idx' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='i' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Char' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Up' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='T101' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='6' />
						</local>
						<local name='Target' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='22' />
						</local>
						<local name='st101' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='m1' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='state' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='m' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='ai' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='eoh' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='tries' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='got' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Client mode' >
							<exp exp='.Return = 0' />
							<exp exp='IsClient = 1' />
							<exp exp='Connected = 0' />
							<exp exp='Seed = Seed + 7919' />
						</command>
						<command class_type='call' title='Attempt to open socket' component='NetworkComms1' macro='SocketOpen' >
							<return exp='.ok' />
						</command>
						<command class_type='decision' title='Socket open OK?' exp='.ok' swap='0' >
							<flowline >
								<command class_type='call' title='Connect to server' component='NetworkComms1' macro='Connect' >
									<return exp='.ok' />
									<argument exp='.Address' />
									<argument exp='.Port' />
								</command>
							</flowline>
							<flowline >
								<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
									<argument exp='&quot;Socket Open Error&quot;' />
								</command>
							</flowline>
						</command>
						<command class_type='decision' title='TCP connected?' exp='.ok' swap='0' >
							<flowline >
								<command class_type='comment' title='' comment='Generate a random 16 byte nonce and Base64 encode it to give the 24 char Sec-WebSocket-Key' textarea='12,0,12,0' />
								<command class_type='calculation' title='Reset' >
									<exp exp='.i = 0' />
								</command>
								<command class_type='loop' title='16 random bytes' type='0' exp='.i &lt; 16' for1='' for3='' >
									<flowline >
										<command class_type='call' title='Random byte' macro='Prv_RandomByte' >
											<return exp='.Nonce[.i]' />
										</command>
										<command class_type='calculation' title='Next' >
											<exp exp='.i = .i + 1' />
										</command>
									</flowline>
								</command>
								<command class_type='call' title='Encode key' macro='Prv_Base64' >
									<return exp='.Key' />
									<argument exp='.Nonce' />
									<argument exp='16' />
								</command>
								<command class_type='comment' title='' comment='Send the HTTP upgrade request' textarea='12,0,12,0' />
								<command class_type='calculation' title='Request line' >
									<exp exp='.Line = &quot;GET &quot; + .Path + &quot; HTTP/1.1\r\n&quot;' />
									<exp exp='.n = Length$ (.Line)' />
								</command>
								<command class_type='call' title='Send request line' component='NetworkComms1' macro='Send' >
									<argument exp='.Line' />
									<argument exp='.n' />
								</command>
								<command class_type='calculation' title='Host header' >
									<exp exp='.Line = &quot;Host: &quot; + .Address + &quot;\r\n&quot;' />
									<exp exp='.n = Length$ (.Line)' />
								</command>
								<command class_type='call' title='Send Host header' component='NetworkComms1' macro='Send' >
									<argument exp='.Line' />
									<argument exp='.n' />
								</command>
								<command class_type='call' title='Send Upgrade header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Upgrade: websocket\r\n&quot;' />
									<argument exp='20' />
								</command>
								<command class_type='call' title='Send Connection header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Connection: Upgrade\r\n&quot;' />
									<argument exp='21' />
								</command>
								<command class_type='call' title='Send Key header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Sec-WebSocket-Key: &quot;' />
									<argument exp='19' />
								</command>
								<command class_type='call' title='Send Key value' component='NetworkComms1' macro='Send' >
									<argument exp='.Key' />
									<argument exp='24' />
								</command>
								<command class_type='call' title='Send Version + end of header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;\r\nSec-WebSocket-Version: 13\r\n\r\n&quot;' />
									<argument exp='31' />
								</command>
								<command class_type='sim' title='Flash TX icon' component='LibraryComponent1' macro='FlashTx' />
								<command class_type='comment' title='' comment='Parse the response as it streams in from the socket - nothing is buffered so a server reply of any length is handled. state: 0 = hunting for the Sec-WebSocket-Accept header, 1 = skipping spaces after the colon, 2 = collecting the 28 character accept value, 3 = value complete. In parallel st101 records whether the status line said 101, and eoh tracks the CR LF CR LF that ends the headers.' textarea='12,0,12,0' />
								<command class_type='calculation' title='Reset the parser' >
									<exp exp='.T101 = &quot; 101 &quot;' />
									<exp exp='.Target = &quot;SEC-WEBSOCKET-ACCEPT:&quot;' />
									<exp exp='.st101 = 0' />
									<exp exp='.m1 = 0' />
									<exp exp='.state = 0' />
									<exp exp='.m = 0' />
									<exp exp='.ai = 0' />
									<exp exp='.eoh = 0' />
									<exp exp='.tries = 0' />
									<exp exp='.got = 0' />
								</command>
								<command class_type='comment' title='' comment='Read the response ONE byte at a time. A chunked read would over-run the blank line that ends the headers and swallow the first bytes of the server&apos;s first frame - most servers send one the instant the link opens - desynchronising the frame stream. The handshake happens once per connection so the extra calls cost nothing in steady state.' textarea='12,0,12,0' />
								<command class_type='loop' title='Until end of headers' type='0' exp='(.eoh &lt; 4) &amp;&amp; (.tries &lt; 25)' for1='' for3='' >
									<flowline >
										<command class_type='call' title='Read one byte' component='NetworkComms1' macro='Receive' >
											<return exp='.n' />
											<argument exp='.RxTempBuff' />
											<argument exp='1' />
											<argument exp='Timeout' />
										</command>
										<command class_type='decision' title='Byte received?' exp='.n &gt; 0' swap='0' >
											<flowline >
												<command class_type='calculation' title='Take the byte' >
													<exp exp='.tries = 0' />
													<exp exp='.Char = .RxTempBuff[0]' />
													<exp exp='.Up = .Char' />
												</command>
												<command class_type='decision' title='First byte?' exp='.got = 0' swap='0' >
													<flowline >
														<command class_type='calculation' title='Calculation' >
															<exp exp='.got = 1' />
														</command>
														<command class_type='sim' title='Flash RX icon' component='LibraryComponent1' macro='FlashRx' />
													</flowline>
													<flowline />
												</command>
												<command class_type='decision' title='Lower case letter?' exp='(.Char &gt;= &apos;a&apos;) &amp;&amp; (.Char &lt;= &apos;z&apos;)' swap='0' >
													<flowline >
														<command class_type='calculation' title='Fold to upper case' >
															<exp exp='.Up = .Char - 32' />
														</command>
													</flowline>
													<flowline />
												</command>
												<command class_type='decision' title='Still looking for the 101 status?' exp='.st101 = 0' swap='0' >
													<flowline >
														<command class_type='decision' title='Matches next status char?' exp='.Char = .T101[.m1]' swap='0' >
															<flowline >
																<command class_type='calculation' title='Advance the match' >
																	<exp exp='.m1 = .m1 + 1' />
																</command>
																<command class_type='decision' title='Whole status matched?' exp='.m1 = 5' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Server is upgrading' >
																			<exp exp='.st101 = 1' />
																			<exp exp='.m1 = 0' />
																		</command>
																	</flowline>
																	<flowline />
																</command>
															</flowline>
															<flowline >
																<command class_type='calculation' title='Restart the match' >
																	<exp exp='.m1 = 0' />
																</command>
																<command class_type='decision' title='Could this be a new start?' exp='.Char = .T101[0]' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Calculation' >
																			<exp exp='.m1 = 1' />
																		</command>
																	</flowline>
																	<flowline />
																</command>
															</flowline>
														</command>
													</flowline>
													<flowline />
												</command>
												<command class_type='decision' title='Hunting for the accept header?' exp='.state = 0' swap='0' >
													<flowline >
														<command class_type='decision' title='Matches next header char?' exp='.Up = .Target[.m]' swap='0' >
															<flowline >
																<command class_type='calculation' title='Advance the match' >
																	<exp exp='.m = .m + 1' />
																</command>
																<command class_type='decision' title='Whole header matched?' exp='.m = 21' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Now skip spaces' >
																			<exp exp='.state = 1' />
																			<exp exp='.m = 0' />
																		</command>
																	</flowline>
																	<flowline />
																</command>
															</flowline>
															<flowline >
																<command class_type='calculation' title='Restart the match' >
																	<exp exp='.m = 0' />
																</command>
																<command class_type='decision' title='Could this be a new start?' exp='.Up = .Target[0]' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Calculation' >
																			<exp exp='.m = 1' />
																		</command>
																	</flowline>
																	<flowline />
																</command>
															</flowline>
														</command>
													</flowline>
													<flowline >
														<command class_type='decision' title='Skipping spaces?' exp='.state = 1' swap='0' >
															<flowline >
																<command class_type='decision' title='First value character?' exp='.Char != &apos; &apos;' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Start collecting' >
																			<exp exp='.Accept[0] = .Char' />
																			<exp exp='.ai = 1' />
																			<exp exp='.state = 2' />
																		</command>
																	</flowline>
																	<flowline />
																</command>
															</flowline>
															<flowline >
																<command class_type='decision' title='Collecting the value?' exp='.state = 2' swap='0' >
																	<flowline >
																		<command class_type='decision' title='End of the value?' exp='(.Char = &apos;\r&apos;) || (.ai &gt;= 28)' swap='0' >
																			<flowline >
																				<command class_type='calculation' title='Value complete' >
																					<exp exp='.state = 3' />
																				</command>
																			</flowline>
																			<flowline >
																				<command class_type='calculation' title='Store' >
																					<exp exp='.Accept[.ai] = .Char' />
																					<exp exp='.ai = .ai + 1' />
																				</command>
																			</flowline>
																		</command>
																	</flowline>
																	<flowline />
																</command>
															</flowline>
														</command>
													</flowline>
												</command>
												<command class_type='comment' title='' comment='Track the blank line that ends the headers - match CR LF CR LF' textarea='12,0,12,0' />
												<command class_type='decision' title='Expecting a CR?' exp='(.eoh &amp; 1) = 0' swap='0' >
													<flowline >
														<command class_type='decision' title='Got CR?' exp='.Char = 13' swap='0' >
															<flowline >
																<command class_type='calculation' title='Calculation' >
																	<exp exp='.eoh = .eoh + 1' />
																</command>
															</flowline>
															<flowline >
																<command class_type='calculation' title='Calculation' >
																	<exp exp='.eoh = 0' />
																</command>
															</flowline>
														</command>
													</flowline>
													<flowline >
														<command class_type='decision' title='Got LF?' exp='.Char = 10' swap='0' >
															<flowline >
																<command class_type='calculation' title='Calculation' >
																	<exp exp='.eoh = .eoh + 1' />
																</command>
															</flowline>
															<flowline >
																<command class_type='decision' title='Restarting on a CR?' exp='.Char = 13' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Calculation' >
																			<exp exp='.eoh = 1' />
																		</command>
																	</flowline>
																	<flowline >
																		<command class_type='calculation' title='Calculation' >
																			<exp exp='.eoh = 0' />
																		</command>
																	</flowline>
																</command>
															</flowline>
														</command>
													</flowline>
												</command>
											</flowline>
											<flowline >
												<command class_type='calculation' title='Nothing yet - retry' >
													<exp exp='.tries = .tries + 1' />
												</command>
											</flowline>
										</command>
									</flowline>
								</command>
								<command class_type='calculation' title='Terminate the accept value' >
									<exp exp='.Accept[.ai] = 0' />
								</command>
								<command class_type='decision' title='101 Switching Protocols?' exp='.st101' swap='0' >
									<flowline >
										<command class_type='decision' title='Accept header found?' exp='.ai = 28' swap='0' >
											<flowline >
												<command class_type='call' title='Expected accept value' macro='Prv_ComputeAccept' >
													<return exp='.Expected' />
													<argument exp='.Key' />
												</command>
												<command class_type='decision' title='Accept value matches?' exp='Compare$ (.Accept,.Expected,0) == 0' swap='0' >
													<flowline >
														<command class_type='calculation' title='Connected' >
															<exp exp='Connected = 1' />
															<exp exp='IdleCount = 0' />
															<exp exp='PingsSent = 0' />
															<exp exp='.Return = 1' />
														</command>
														<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
															<argument exp='&quot;WebSocket connected to server&quot;' />
														</command>
													</flowline>
													<flowline >
														<command class_type='calculation' title='Bad accept' >
															<exp exp='.Return = 2' />
														</command>
													</flowline>
												</command>
											</flowline>
											<flowline >
												<command class_type='calculation' title='No accept header' >
													<exp exp='.Return = 2' />
												</command>
											</flowline>
										</command>
									</flowline>
									<flowline >
										<command class_type='calculation' title='Not upgraded' >
											<exp exp='.Return = 2' />
										</command>
									</flowline>
								</command>
								<command class_type='decision' title='Handshake failed?' exp='.Return != 1' swap='0' >
									<flowline >
										<command class_type='call' title='Close the socket' component='NetworkComms1' macro='SocketClose' />
										<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
											<argument exp='&quot;WebSocket client handshake failed&quot;' />
										</command>
									</flowline>
									<flowline />
								</command>
							</flowline>
							<flowline >
								<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
									<argument exp='&quot;Connect Error&quot;' />
								</command>
							</flowline>
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Ev_Initialise' description='Initialisation routine for the component once the component is linked to its parent' statediag='0' >
						<return name='Return' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='ver' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='sim' title='Built-in Function' macro='System.TimerStart' >
							<argument exp='0' />
							<argument exp='200' />
						</command>
						<command class_type='sim' title='Built-in Function' macro='System.GetFCVersion' >
							<return exp='.ver' />
						</command>
						<command class_type='decision' title='Decision' exp='.ver &lt; 0x0A0003' swap='0' >
							<flowline >
								<command class_type='call' title='User Macro' macro='Ev_Property' />
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_CloseLink' description='Closes the underlying TCP connection. Client mode closes the socket, server mode closes the accepted client thread.' statediag='0' >
						<return name='Return' type='v0' description='' isconst='0' isHidden='0' isinit='0' usrinit='' setinit='' />
						<command class_type='decision' title='Client mode?' exp='IsClient' swap='0' >
							<flowline >
								<command class_type='call' title='Close the socket' component='NetworkComms1' macro='SocketClose' />
							</flowline>
							<flowline >
								<command class_type='call' title='Close the accepted connection' component='NetworkComms1' macro='AcceptClose' />
							</flowline>
						</command>
						<command class_type='calculation' title='Disconnected' >
							<exp exp='Connected = 0' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_SendFrame' description='Sends a single WebSocket frame with the given opcode and payload. Frames are masked automatically when in client mode.
Returns the number of payload bytes sent.' statediag='0' >
						<return name='Return' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Opcode' type='u8' description='1=Text, 2=Binary, 8=Close, 9=Ping, 10=Pong' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Data' type='T8*' description='Payload data' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</param>
						<param name='Count' type='u16' description='Number of payload bytes' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Hdr' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='4' />
						</local>
						<local name='Mask' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='4' />
						</local>
						<local name='Tmp' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<local name='n' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='idx' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='chunk' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='i' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Frame header - FIN + opcode' >
							<exp exp='.Hdr[0] = 0x80 | (.Opcode &amp; 0x0F)' />
							<exp exp='.Return = 0' />
						</command>
						<command class_type='decision' title='Short payload?' exp='.Count &lt; 126' swap='0' >
							<flowline >
								<command class_type='calculation' title='7-bit length' >
									<exp exp='.Hdr[1] = .Count' />
								</command>
							</flowline>
							<flowline >
								<command class_type='calculation' title='16-bit length' >
									<exp exp='.Hdr[1] = 126' />
									<exp exp='.Hdr[2] = (.Count &gt;&gt; 8) &amp; 0xFF' />
									<exp exp='.Hdr[3] = .Count &amp; 0xFF' />
								</command>
							</flowline>
						</command>
						<command class_type='comment' title='' comment='Client to server frames must be masked (RFC 6455 5.3). Server to client frames are never masked.
Payload is sent in chunks of 20 bytes as some modules (ESP8266) are slow with single bytes.' textarea='12,0,12,0' />
						<command class_type='decision' title='Client mode?' exp='IsClient' swap='0' >
							<flowline >
								<command class_type='calculation' title='Set mask bit' >
									<exp exp='.Hdr[1] = .Hdr[1] | 0x80' />
								</command>
							</flowline>
							<flowline >
								<command class_type='calculation' title='No mask' >
									<exp exp='.Mask[0] = 0' />
									<exp exp='.Mask[1] = 0' />
									<exp exp='.Mask[2] = 0' />
									<exp exp='.Mask[3] = 0' />
								</command>
							</flowline>
						</command>
						<command class_type='decision' title='Short payload?' exp='.Count &lt; 126' swap='0' >
							<flowline >
								<command class_type='call' title='Send 2 byte header' component='NetworkComms1' macro='Send' >
									<return exp='.n' />
									<argument exp='.Hdr' />
									<argument exp='2' />
								</command>
							</flowline>
							<flowline >
								<command class_type='call' title='Send 4 byte header' component='NetworkComms1' macro='Send' >
									<return exp='.n' />
									<argument exp='.Hdr' />
									<argument exp='4' />
								</command>
							</flowline>
						</command>
						<command class_type='decision' title='Client mode?' exp='IsClient' swap='0' >
							<flowline >
								<command class_type='call' title='Mask byte 0' macro='Prv_RandomByte' >
									<return exp='.Mask[0]' />
								</command>
								<command class_type='call' title='Mask byte 1' macro='Prv_RandomByte' >
									<return exp='.Mask[1]' />
								</command>
								<command class_type='call' title='Mask byte 2' macro='Prv_RandomByte' >
									<return exp='.Mask[2]' />
								</command>
								<command class_type='call' title='Mask byte 3' macro='Prv_RandomByte' >
									<return exp='.Mask[3]' />
								</command>
								<command class_type='call' title='Send 4 byte mask key' component='NetworkComms1' macro='Send' >
									<return exp='.n' />
									<argument exp='.Mask' />
									<argument exp='4' />
								</command>
							</flowline>
							<flowline />
						</command>
						<command class_type='calculation' title='Reset' >
							<exp exp='.idx = 0' />
						</command>
						<command class_type='loop' title='Send payload' type='0' exp='.idx &lt; .Count' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Chunk size' >
									<exp exp='.chunk = .Count - .idx' />
								</command>
								<command class_type='decision' title='Limit to 20' exp='.chunk &gt; 20' swap='0' >
									<flowline >
										<command class_type='calculation' title='Calculation' >
											<exp exp='.chunk = 20' />
										</command>
									</flowline>
									<flowline />
								</command>
								<command class_type='calculation' title='Reset' >
									<exp exp='.i = 0' />
								</command>
								<command class_type='loop' title='Copy and mask chunk' type='0' exp='.i &lt; .chunk' for1='' for3='' >
									<flowline >
										<command class_type='calculation' title='Calculation' >
											<exp exp='.Tmp[.i] = .Data[.idx + .i] ^ .Mask[(.idx + .i) &amp; 3]' />
											<exp exp='.i = .i + 1' />
										</command>
									</flowline>
								</command>
								<command class_type='call' title='Send chunk' component='NetworkComms1' macro='Send' >
									<return exp='.n' />
									<argument exp='.Tmp' />
									<argument exp='.chunk' />
								</command>
								<command class_type='calculation' title='Advance' >
									<exp exp='.Return = .Return + .n' />
									<exp exp='.idx = .idx + .chunk' />
								</command>
							</flowline>
						</command>
						<command class_type='sim' title='Flash TX icon' component='LibraryComponent1' macro='FlashTx' />
					</flowline>
				</macro>
				<macro >
					<flowline name='GetRxOpcode' description='Returns the opcode of the last received frame: 0 = Continuation, 1 = Text, 2 = Binary, 8 = Close, 9 = Ping, 10 = Pong' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = RxOpcode' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Disconnect' description='Sends a close frame to the remote end and closes the connection. Works in both server and client mode.' statediag='0' >
						<return name='Return' type='v0' description='' isconst='0' isHidden='0' isinit='0' usrinit='' setinit='' />
						<command class_type='decision' title='Connected?' exp='Connected' swap='0' >
							<flowline >
								<command class_type='call' title='Send close frame' macro='Prv_SendFrame' >
									<argument exp='8' />
									<argument exp='&quot;&quot;' />
									<argument exp='0' />
								</command>
								<command class_type='call' title='Close the connection' macro='Prv_CloseLink' />
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_Base64' description='Base64 encodes up to 24 bytes of data. Returns the encoded string.' statediag='0' >
						<return name='Return' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='2000' />
						</return>
						<param name='Data' type='T8*' description='Bytes to encode' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='24' />
						</param>
						<param name='Count' type='u8' description='Number of bytes (max 24)' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='T' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='i' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='o' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='rem' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Reset' >
							<exp exp='.i = 0' />
							<exp exp='.o = 0' />
						</command>
						<command class_type='loop' title='Full 3 byte groups' type='0' exp='(.i + 3) &lt;= .Count' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='24-bit group' >
									<exp exp='.T = .Data[.i] &amp; 0xFF' />
									<exp exp='.T = (.T &lt;&lt; 8) | (.Data[.i + 1] &amp; 0xFF)' />
									<exp exp='.T = (.T &lt;&lt; 8) | (.Data[.i + 2] &amp; 0xFF)' />
									<exp exp='.i = .i + 3' />
								</command>
								<command class_type='call' title='Char 1' macro='Prv_B64Char' >
									<return exp='.Return[.o]' />
									<argument exp='(.T &gt;&gt; 18) &amp; 63' />
								</command>
								<command class_type='call' title='Char 2' macro='Prv_B64Char' >
									<return exp='.Return[.o + 1]' />
									<argument exp='(.T &gt;&gt; 12) &amp; 63' />
								</command>
								<command class_type='call' title='Char 3' macro='Prv_B64Char' >
									<return exp='.Return[.o + 2]' />
									<argument exp='(.T &gt;&gt; 6) &amp; 63' />
								</command>
								<command class_type='call' title='Char 4' macro='Prv_B64Char' >
									<return exp='.Return[.o + 3]' />
									<argument exp='.T &amp; 63' />
								</command>
								<command class_type='calculation' title='Next' >
									<exp exp='.o = .o + 4' />
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Remaining bytes' >
							<exp exp='.rem = .Count - .i' />
						</command>
						<command class_type='decision' title='2 bytes left?' exp='.rem = 2' swap='0' >
							<flowline >
								<command class_type='calculation' title='Group' >
									<exp exp='.T = .Data[.i] &amp; 0xFF' />
									<exp exp='.T = (.T &lt;&lt; 8) | (.Data[.i + 1] &amp; 0xFF)' />
									<exp exp='.T = .T &lt;&lt; 8' />
								</command>
								<command class_type='call' title='Char 1' macro='Prv_B64Char' >
									<return exp='.Return[.o]' />
									<argument exp='(.T &gt;&gt; 18) &amp; 63' />
								</command>
								<command class_type='call' title='Char 2' macro='Prv_B64Char' >
									<return exp='.Return[.o + 1]' />
									<argument exp='(.T &gt;&gt; 12) &amp; 63' />
								</command>
								<command class_type='call' title='Char 3' macro='Prv_B64Char' >
									<return exp='.Return[.o + 2]' />
									<argument exp='(.T &gt;&gt; 6) &amp; 63' />
								</command>
								<command class_type='calculation' title='Pad' >
									<exp exp='.Return[.o + 3] = &apos;=&apos;' />
									<exp exp='.o = .o + 4' />
								</command>
							</flowline>
							<flowline >
								<command class_type='decision' title='1 byte left?' exp='.rem = 1' swap='0' >
									<flowline >
										<command class_type='calculation' title='Group' >
											<exp exp='.T = .Data[.i] &amp; 0xFF' />
											<exp exp='.T = .T &lt;&lt; 16' />
										</command>
										<command class_type='call' title='Char 1' macro='Prv_B64Char' >
											<return exp='.Return[.o]' />
											<argument exp='(.T &gt;&gt; 18) &amp; 63' />
										</command>
										<command class_type='call' title='Char 2' macro='Prv_B64Char' >
											<return exp='.Return[.o + 1]' />
											<argument exp='(.T &gt;&gt; 12) &amp; 63' />
										</command>
										<command class_type='calculation' title='Pad' >
											<exp exp='.Return[.o + 2] = &apos;=&apos;' />
											<exp exp='.Return[.o + 3] = &apos;=&apos;' />
											<exp exp='.o = .o + 4' />
										</command>
									</flowline>
									<flowline />
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Terminate' >
							<exp exp='.Return[.o] = 0' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Ev_LoadComplete' description='Broadcast after a project has finished loading' statediag='0' >
						<return name='Return' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='decision' title='Decision' exp='Component' swap='0' >
							<flowline >
								<command class_type='sim' title='Component Macro' component='LibraryComponent1' macro='SetLinkHandle' >
									<argument exp='1' />
									<argument exp='Component' />
								</command>
								<command class_type='sim' title='Built-in Function' macro='Component.Property.SetValue' >
									<argument exp='this' />
									<argument exp='&quot;Component&quot;' />
									<argument exp='0' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Ev_Property' description='Sent when a property has been changed by the User' statediag='0' >
						<return name='Return' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='tempstr' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<local name='NCHandle' type='h32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='sim' title='Component Macro' component='LibraryComponent1' macro='GetLinkHandle' >
							<return exp='.NCHandle' />
							<argument exp='1' />
						</command>
						<command class_type='decision' title='Decision' exp='.NCHandle &gt; 0' swap='0' >
							<flowline >
								<command class_type='sim' title='Simulation' macro='System.RedirectMacros' >
									<argument exp='NetworkComms1' />
									<argument exp='.NCHandle' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Ping' description='Sends a ping frame to the connected client. The client should reply with a pong which is consumed by CheckSocketActivity.
Returns 1 if sent, 0 = not connected.' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = 0' />
						</command>
						<command class_type='decision' title='Connected?' exp='Connected' swap='0' >
							<flowline >
								<command class_type='call' title='Send ping frame' macro='Prv_SendFrame' >
									<argument exp='9' />
									<argument exp='&quot;ping&quot;' />
									<argument exp='4' />
								</command>
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Return = 1' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='IsConnected' description='Returns 1 if a WebSocket link is currently open (client connected to us in server mode, or we are connected to a server in client mode), else 0.' statediag='0' >
						<return name='Return' type='b1' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = Connected' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='IsClientMode' description='Returns 1 if the component is operating as a WebSocket client (after Connect), 0 if operating as a server.' statediag='0' >
						<return name='Return' type='b1' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = IsClient' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Ev_Renamed' description='' statediag='0' >
						<return name='Return' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Name' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<command class_type='sim' title='' macro='Tree.GetName' >
							<return exp='.Name' />
							<argument exp='this' />
						</command>
						<command class_type='sim' title='' macro='Component.Property.SetValue' >
							<argument exp='LibraryComponent1' />
							<argument exp='&quot;Name&quot;' />
							<argument exp='.Name' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_RandomByte' description='Returns a pseudo random byte using a 32-bit linear congruential generator.' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='LCG step' >
							<exp exp='Seed = (Seed * 1103515245) + 12345' />
							<exp exp='.Return = (Seed &gt;&gt; 16) &amp; 0xFF' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_Handshake' description='Reads the HTTP upgrade request from a newly accepted client and replies with the 101 Switching Protocols response.
The request is parsed as it streams in from the socket so no RAM is needed to buffer it - requests of any length are handled.
Returns 1 if the WebSocket connection is now open, 0 if the request was rejected.' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='RxTempBuff' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<local name='Target' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='19' />
						</local>
						<local name='Key' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='25' />
						</local>
						<local name='Accept' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='32' />
						</local>
						<local name='n' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Char' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Up' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='state' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='m' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='ki' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='eoh' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='tries' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='got' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='OptTarget' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;OPTIONS &quot;' setinit='' >
							<array size='9' />
						</local>
						<local name='om' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='IsOptions' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Handled' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='comment' title='' comment='Streaming parser - the request is never buffered, each byte is fed through a small state machine as it arrives. state: 0 = hunting for the Sec-WebSocket-Key header, 1 = skipping spaces after the colon, 2 = collecting the 24 character key, 3 = key complete. In parallel the first 8 bytes of the request line are matched against &quot;OPTIONS &quot; to detect a Chrome Private Network Access preflight, which carries no Sec-WebSocket-Key and must be answered separately.' textarea='12,0,12,0' />
						<command class_type='calculation' title='Reset the parser' >
							<exp exp='.Return = 0' />
							<exp exp='.Target = &quot;SEC-WEBSOCKET-KEY:&quot;' />
							<exp exp='.OptTarget[0] = 0' />
							<exp exp='.RxTempBuff[0] = 0' />
							<exp exp='.state = 0' />
							<exp exp='.m = 0' />
							<exp exp='.ki = 0' />
							<exp exp='.eoh = 0' />
							<exp exp='.tries = 0' />
							<exp exp='.got = 0' />
							<exp exp='.om = 0' />
							<exp exp='.IsOptions = 1' />
							<exp exp='.Handled = 0' />
						</command>
						<command class_type='comment' title='' comment='Read the request ONE byte at a time. A chunked read would over-run the blank line that ends the headers and swallow the first bytes of the client&apos;s first frame, desynchronising the frame stream. The handshake happens once per connection so the extra calls cost nothing in steady state.' textarea='12,0,12,0' />
						<command class_type='loop' title='Until end of headers' type='0' exp='(.eoh &lt; 4) &amp;&amp; (.tries &lt; 25)' for1='' for3='' >
							<flowline >
								<command class_type='call' title='Read one byte' component='NetworkComms1' macro='Receive' >
									<return exp='.n' />
									<argument exp='.RxTempBuff' />
									<argument exp='1' />
									<argument exp='Timeout' />
								</command>
								<command class_type='decision' title='Byte received?' exp='.n &gt; 0' swap='0' >
									<flowline >
										<command class_type='calculation' title='Take the byte' >
											<exp exp='.tries = 0' />
											<exp exp='.Char = .RxTempBuff[0]' />
											<exp exp='.Up = .Char' />
										</command>
										<command class_type='decision' title='First byte?' exp='.got = 0' swap='0' >
											<flowline >
												<command class_type='calculation' title='Calculation' >
													<exp exp='.got = 1' />
												</command>
												<command class_type='sim' title='Flash RX icon' component='LibraryComponent1' macro='FlashRx' />
											</flowline>
											<flowline />
										</command>
										<command class_type='decision' title='Lower case letter?' exp='(.Char &gt;= &apos;a&apos;) &amp;&amp; (.Char &lt;= &apos;z&apos;)' swap='0' >
											<flowline >
												<command class_type='calculation' title='Fold to upper case' >
													<exp exp='.Up = .Char - 32' />
												</command>
											</flowline>
											<flowline />
										</command>
										<command class_type='decision' title='Still checking method?' exp='.om &lt; 8' swap='0' >
											<flowline >
												<command class_type='decision' title='Matches OPTIONS char?' exp='.Up = .OptTarget[.om]' swap='0' >
													<flowline >
														<command class_type='calculation' title='Advance method match' >
															<exp exp='.om = .om + 1' />
														</command>
													</flowline>
													<flowline >
														<command class_type='calculation' title='Not an OPTIONS request' >
															<exp exp='.IsOptions = 0' />
															<exp exp='.om = 8' />
														</command>
													</flowline>
												</command>
											</flowline>
											<flowline />
										</command>
										<command class_type='decision' title='Hunting for the key header?' exp='.state = 0' swap='0' >
											<flowline >
												<command class_type='decision' title='Matches next header char?' exp='.Up = .Target[.m]' swap='0' >
													<flowline >
														<command class_type='calculation' title='Advance the match' >
															<exp exp='.m = .m + 1' />
														</command>
														<command class_type='decision' title='Whole header matched?' exp='.m = 18' swap='0' >
															<flowline >
																<command class_type='calculation' title='Now skip spaces' >
																	<exp exp='.state = 1' />
																	<exp exp='.m = 0' />
																</command>
															</flowline>
															<flowline />
														</command>
													</flowline>
													<flowline >
														<command class_type='calculation' title='Restart the match' >
															<exp exp='.m = 0' />
														</command>
														<command class_type='decision' title='Could this be a new start?' exp='.Up = .Target[0]' swap='0' >
															<flowline >
																<command class_type='calculation' title='Calculation' >
																	<exp exp='.m = 1' />
																</command>
															</flowline>
															<flowline />
														</command>
													</flowline>
												</command>
											</flowline>
											<flowline >
												<command class_type='decision' title='Skipping spaces?' exp='.state = 1' swap='0' >
													<flowline >
														<command class_type='decision' title='First key character?' exp='.Char != &apos; &apos;' swap='0' >
															<flowline >
																<command class_type='calculation' title='Start collecting' >
																	<exp exp='.Key[0] = .Char' />
																	<exp exp='.ki = 1' />
																	<exp exp='.state = 2' />
																</command>
															</flowline>
															<flowline />
														</command>
													</flowline>
													<flowline >
														<command class_type='decision' title='Collecting the key?' exp='.state = 2' swap='0' >
															<flowline >
																<command class_type='decision' title='End of the key?' exp='(.Char = &apos;\r&apos;) || (.ki &gt;= 24)' swap='0' >
																	<flowline >
																		<command class_type='calculation' title='Key complete' >
																			<exp exp='.state = 3' />
																		</command>
																	</flowline>
																	<flowline >
																		<command class_type='calculation' title='Store' >
																			<exp exp='.Key[.ki] = .Char' />
																			<exp exp='.ki = .ki + 1' />
																		</command>
																	</flowline>
																</command>
															</flowline>
															<flowline />
														</command>
													</flowline>
												</command>
											</flowline>
										</command>
										<command class_type='comment' title='' comment='Track the blank line that ends the headers - match CR LF CR LF' textarea='12,0,12,0' />
										<command class_type='decision' title='Expecting a CR?' exp='(.eoh &amp; 1) = 0' swap='0' >
											<flowline >
												<command class_type='decision' title='Got CR?' exp='.Char = 13' swap='0' >
													<flowline >
														<command class_type='calculation' title='Calculation' >
															<exp exp='.eoh = .eoh + 1' />
														</command>
													</flowline>
													<flowline >
														<command class_type='calculation' title='Calculation' >
															<exp exp='.eoh = 0' />
														</command>
													</flowline>
												</command>
											</flowline>
											<flowline >
												<command class_type='decision' title='Got LF?' exp='.Char = 10' swap='0' >
													<flowline >
														<command class_type='calculation' title='Calculation' >
															<exp exp='.eoh = .eoh + 1' />
														</command>
													</flowline>
													<flowline >
														<command class_type='decision' title='Restarting on a CR?' exp='.Char = 13' swap='0' >
															<flowline >
																<command class_type='calculation' title='Calculation' >
																	<exp exp='.eoh = 1' />
																</command>
															</flowline>
															<flowline >
																<command class_type='calculation' title='Calculation' >
																	<exp exp='.eoh = 0' />
																</command>
															</flowline>
														</command>
													</flowline>
												</command>
											</flowline>
										</command>
									</flowline>
									<flowline >
										<command class_type='calculation' title='Nothing yet - retry' >
											<exp exp='.tries = .tries + 1' />
										</command>
									</flowline>
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Terminate the key' >
							<exp exp='.Key[.ki] = 0' />
						</command>
						<command class_type='decision' title='OPTIONS preflight request?' exp='.IsOptions = 1' swap='0' >
							<flowline >
								<command class_type='comment' title='' comment='Chrome sends this before the WebSocket GET when the page origin (eg. file:// or a public origin) is less trusted than the local/private target IP. It must see 200/204 with Access-Control-Allow-Private-Network: true or it cancels the connection before the real handshake is even attempted.' textarea='12,0,12,0' />
								<command class_type='call' title='Send 204 response' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;HTTP/1.1 204 No Content\r\n&quot;' />
									<argument exp='25' />
								</command>
								<command class_type='call' title='Send CORS origin header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Access-Control-Allow-Origin: *\r\n&quot;' />
									<argument exp='32' />
								</command>
								<command class_type='call' title='Send Private Network header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Access-Control-Allow-Private-Network: true\r\n&quot;' />
									<argument exp='44' />
								</command>
								<command class_type='call' title='Send allowed methods header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Access-Control-Allow-Methods: GET, OPTIONS\r\n&quot;' />
									<argument exp='44' />
								</command>
								<command class_type='call' title='Send allowed headers header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;Access-Control-Allow-Headers: *\r\n&quot;' />
									<argument exp='33' />
								</command>
								<command class_type='call' title='End of header' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;\r\n&quot;' />
									<argument exp='2' />
								</command>
								<command class_type='sim' title='Flash TX icon' component='LibraryComponent1' macro='FlashTx' />
								<command class_type='call' title='Close the accepted connection' component='NetworkComms1' macro='AcceptClose' />
								<command class_type='calculation' title='Preflight handled' >
									<exp exp='.Handled = 1' />
								</command>
								<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
									<argument exp='&quot;WebSocket CORS/PNA preflight answered&quot;' />
								</command>
							</flowline>
							<flowline >
								<command class_type='decision' title='Valid key length?' exp='.ki = 24' swap='0' >
									<flowline >
										<command class_type='call' title='Compute accept value' macro='Prv_ComputeAccept' >
											<return exp='.Accept' />
											<argument exp='.Key' />
										</command>
										<command class_type='call' title='Send 101 response' component='NetworkComms1' macro='Send' >
											<argument exp='&quot;HTTP/1.1 101 Switching Protocols\r\n&quot;' />
											<argument exp='34' />
										</command>
										<command class_type='call' title='Send Upgrade header' component='NetworkComms1' macro='Send' >
											<argument exp='&quot;Upgrade: websocket\r\n&quot;' />
											<argument exp='20' />
										</command>
										<command class_type='call' title='Send Connection header' component='NetworkComms1' macro='Send' >
											<argument exp='&quot;Connection: Upgrade\r\n&quot;' />
											<argument exp='21' />
										</command>
										<command class_type='call' title='Send Accept header' component='NetworkComms1' macro='Send' >
											<argument exp='&quot;Sec-WebSocket-Accept: &quot;' />
											<argument exp='22' />
										</command>
										<command class_type='call' title='Send Accept value' component='NetworkComms1' macro='Send' >
											<argument exp='.Accept' />
											<argument exp='28' />
										</command>
										<command class_type='call' title='End of header' component='NetworkComms1' macro='Send' >
											<argument exp='&quot;\r\n\r\n&quot;' />
											<argument exp='4' />
										</command>
										<command class_type='sim' title='Flash TX icon' component='LibraryComponent1' macro='FlashTx' />
										<command class_type='calculation' title='Connected' >
											<exp exp='Connected = 1' />
											<exp exp='IdleCount = 0' />
											<exp exp='PingsSent = 0' />
											<exp exp='.Return = 1' />
										</command>
										<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
											<argument exp='&quot;WebSocket client connected&quot;' />
										</command>
									</flowline>
									<flowline >
										<command class_type='calculation' title='Not a WebSocket request' >
											<exp exp='.Return = 0' />
										</command>
									</flowline>
								</command>
							</flowline>
						</command>
						<command class_type='decision' title='Handshake failed?' exp='(.Return = 0) &amp;&amp; (.Handled = 0)' swap='0' >
							<flowline >
								<command class_type='call' title='Send 400 response' component='NetworkComms1' macro='Send' >
									<argument exp='&quot;HTTP/1.1 400 Bad Request\r\n\r\n&quot;' />
									<argument exp='28' />
								</command>
								<command class_type='call' title='Close the accepted connection' component='NetworkComms1' macro='AcceptClose' />
								<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
									<argument exp='&quot;WebSocket handshake failed&quot;' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='GetRxCount' description='Returns the number of payload bytes received in the last data frame (limited to Max Frame Size - 1).' statediag='0' >
						<return name='Return' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = RxCount' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_B64Char' description='Converts a 6-bit value (0-63) into its Base64 character.' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Value' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='decision' title='&lt; 26' exp='.Value &lt; 26' swap='0' >
							<flowline >
								<command class_type='calculation' title='A-Z' >
									<exp exp='.Return = &apos;A&apos; + .Value' />
								</command>
							</flowline>
							<flowline >
								<command class_type='decision' title='&lt; 52' exp='.Value &lt; 52' swap='0' >
									<flowline >
										<command class_type='calculation' title='a-z' >
											<exp exp='.Return = &apos;a&apos; + (.Value - 26)' />
										</command>
									</flowline>
									<flowline >
										<command class_type='decision' title='&lt; 62' exp='.Value &lt; 62' swap='0' >
											<flowline >
												<command class_type='calculation' title='0-9' >
													<exp exp='.Return = &apos;0&apos; + (.Value - 52)' />
												</command>
											</flowline>
											<flowline >
												<command class_type='decision' title='= 62' exp='.Value = 62' swap='0' >
													<flowline >
														<command class_type='calculation' title='+' >
															<exp exp='.Return = &apos;+&apos;' />
														</command>
													</flowline>
													<flowline >
														<command class_type='calculation' title='/' >
															<exp exp='.Return = &apos;/&apos;' />
														</command>
													</flowline>
												</command>
											</flowline>
										</command>
									</flowline>
								</command>
							</flowline>
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_ReceiveFrame' description='Checks for an incoming WebSocket frame from the connected client, unmasks the payload into RxData and handles control frames.
Returns 0 = nothing, 2 = data frame received, 3 = client closed, 4 = ping received (pong sent automatically).' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Hdr' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='2' />
						</local>
						<local name='Tmp' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<local name='Mask' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='4' />
						</local>
						<local name='n' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Len' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='pos' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='chunk' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='i' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Masked' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='Char' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Defaults' >
							<exp exp='.Return = 0' />
							<exp exp='RxCount = 0' />
							<exp exp='.Hdr[0] = 0' />
							<exp exp='.Mask[0] = 0' />
							<exp exp='.Tmp[0] = 0' />
						</command>
						<command class_type='call' title='Read 2 byte frame header' component='NetworkComms1' macro='Receive' >
							<return exp='.n' />
							<argument exp='.Hdr' />
							<argument exp='2' />
							<argument exp='Timeout' />
						</command>
						<command class_type='decision' title='Frame available?' exp='.n &gt; 0' swap='0' >
							<flowline >
								<command class_type='calculation' title='Link is alive' >
									<exp exp='IdleCount = 0' />
									<exp exp='PingsSent = 0' />
								</command>
								<command class_type='decision' title='Only 1 byte so far?' exp='.n = 1' swap='0' >
									<flowline >
										<command class_type='call' title='Read 2nd header byte' component='NetworkComms1' macro='Receive' >
											<return exp='.n' />
											<argument exp='.Tmp' />
											<argument exp='1' />
											<argument exp='Timeout' />
										</command>
										<command class_type='calculation' title='Calculation' >
											<exp exp='.Hdr[1] = .Tmp[0] &amp; 0xFF' />
										</command>
									</flowline>
									<flowline />
								</command>
								<command class_type='sim' title='Flash RX icon' component='LibraryComponent1' macro='FlashRx' />
								<command class_type='calculation' title='Decode header' >
									<exp exp='RxOpcode = .Hdr[0] &amp; 0x0F' />
									<exp exp='.Masked = .Hdr[1] &amp; 0x80' />
									<exp exp='.Len = .Hdr[1] &amp; 0x7F' />
								</command>
								<command class_type='decision' title='16-bit length?' exp='.Len = 126' swap='0' >
									<flowline >
										<command class_type='call' title='Read 2 length bytes' component='NetworkComms1' macro='Receive' >
											<return exp='.n' />
											<argument exp='.Tmp' />
											<argument exp='2' />
											<argument exp='Timeout' />
										</command>
										<command class_type='calculation' title='Calculation' >
											<exp exp='.Len = .Tmp[0] &amp; 0xFF' />
											<exp exp='.Len = (.Len &lt;&lt; 8) | (.Tmp[1] &amp; 0xFF)' />
										</command>
									</flowline>
									<flowline >
										<command class_type='decision' title='64-bit length?' exp='.Len = 127' swap='0' >
											<flowline >
												<command class_type='comment' title='' comment='Frames over 65535 bytes are not supported - only the low 16 bits are used' textarea='12,0,12,0' />
												<command class_type='call' title='Read 8 length bytes' component='NetworkComms1' macro='Receive' >
													<return exp='.n' />
													<argument exp='.Tmp' />
													<argument exp='8' />
													<argument exp='Timeout' />
												</command>
												<command class_type='calculation' title='Calculation' >
													<exp exp='.Len = .Tmp[6] &amp; 0xFF' />
													<exp exp='.Len = (.Len &lt;&lt; 8) | (.Tmp[7] &amp; 0xFF)' />
												</command>
											</flowline>
											<flowline />
										</command>
									</flowline>
								</command>
								<command class_type='decision' title='Masked?' exp='.Masked' swap='0' >
									<flowline >
										<command class_type='call' title='Read 4 byte mask key' component='NetworkComms1' macro='Receive' >
											<return exp='.n' />
											<argument exp='.Mask' />
											<argument exp='4' />
											<argument exp='Timeout' />
										</command>
									</flowline>
									<flowline >
										<command class_type='calculation' title='No mask' >
											<exp exp='.Mask[0] = 0' />
											<exp exp='.Mask[1] = 0' />
											<exp exp='.Mask[2] = 0' />
											<exp exp='.Mask[3] = 0' />
										</command>
									</flowline>
								</command>
								<command class_type='calculation' title='Reset' >
									<exp exp='.pos = 0' />
								</command>
								<command class_type='loop' title='Read payload' type='0' exp='.pos &lt; .Len' for1='' for3='' >
									<flowline >
										<command class_type='calculation' title='Chunk size' >
											<exp exp='.chunk = .Len - .pos' />
										</command>
										<command class_type='decision' title='Limit to 20' exp='.chunk &gt; 20' swap='0' >
											<flowline >
												<command class_type='calculation' title='Calculation' >
													<exp exp='.chunk = 20' />
												</command>
											</flowline>
											<flowline />
										</command>
										<command class_type='call' title='Read payload chunk' component='NetworkComms1' macro='Receive' >
											<return exp='.n' />
											<argument exp='.Tmp' />
											<argument exp='.chunk' />
											<argument exp='Timeout' />
										</command>
										<command class_type='decision' title='Timed out?' exp='.n = 0' swap='0' >
											<flowline >
												<command class_type='calculation' title='Abort - treat as end of data' >
													<exp exp='.pos = .Len' />
												</command>
											</flowline>
											<flowline >
												<command class_type='calculation' title='Reset' >
													<exp exp='.i = 0' />
												</command>
												<command class_type='loop' title='Unmask and store' type='0' exp='.i &lt; .n' for1='' for3='' >
													<flowline >
														<command class_type='calculation' title='Unmask byte' >
															<exp exp='.Char = .Tmp[.i] ^ .Mask[.pos &amp; 3]' />
														</command>
														<command class_type='decision' title='Room in buffer?' exp='RxCount &lt; (MaxFrame - 1)' swap='0' >
															<flowline >
																<command class_type='calculation' title='Store' >
																	<exp exp='RxData[RxCount] = .Char' />
																	<exp exp='RxCount = RxCount + 1' />
																</command>
															</flowline>
															<flowline />
														</command>
														<command class_type='calculation' title='Next' >
															<exp exp='.pos = .pos + 1' />
															<exp exp='.i = .i + 1' />
														</command>
													</flowline>
												</command>
											</flowline>
										</command>
									</flowline>
								</command>
								<command class_type='calculation' title='Terminate as string' >
									<exp exp='RxData[RxCount] = 0' />
								</command>
								<command class_type='decision' title='Close frame?' exp='RxOpcode = 8' swap='0' >
									<flowline >
										<command class_type='call' title='Echo close frame' macro='Prv_SendFrame' >
											<argument exp='8' />
											<argument exp='&quot;&quot;' />
											<argument exp='0' />
										</command>
										<command class_type='call' title='Close the connection' macro='Prv_CloseLink' />
										<command class_type='calculation' title='Disconnected' >
											<exp exp='.Return = 3' />
										</command>
										<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
											<argument exp='&quot;WebSocket client disconnected&quot;' />
										</command>
									</flowline>
									<flowline >
										<command class_type='decision' title='Ping?' exp='RxOpcode = 9' swap='0' >
											<flowline >
												<command class_type='call' title='Reply with pong' macro='Prv_SendFrame' >
													<argument exp='10' />
													<argument exp='RxData' />
													<argument exp='RxCount' />
												</command>
												<command class_type='calculation' title='Ping' >
													<exp exp='.Return = 4' />
												</command>
											</flowline>
											<flowline >
												<command class_type='decision' title='Pong?' exp='RxOpcode = 10' swap='0' >
													<flowline >
														<command class_type='calculation' title='Ignore pong' >
															<exp exp='.Return = 0' />
														</command>
													</flowline>
													<flowline >
														<command class_type='calculation' title='Text / Binary / Continuation data' >
															<exp exp='.Return = 2' />
														</command>
													</flowline>
												</command>
											</flowline>
										</command>
									</flowline>
								</command>
							</flowline>
							<flowline >
								<command class_type='calculation' title='Nothing received' >
									<exp exp='IdleCount = IdleCount + 1' />
								</command>
							</flowline>
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='GetRxString' description='Returns the payload of the last received data frame as a string (up to 255 characters, use GetRxByte for larger frames or binary data).' statediag='0' >
						<return name='Return' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='2000' />
						</return>
						<local name='i' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Reset' >
							<exp exp='.i = 0' />
						</command>
						<command class_type='loop' title='Copy' type='0' exp='(.i &lt; RxCount) &amp;&amp; (.i &lt; 255)' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Return[.i] = RxData[.i]' />
									<exp exp='.i = .i + 1' />
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Terminate' >
							<exp exp='.Return[.i] = 0' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Ev_GetVarSize' description='Sent to a component to amend the size of the expected array' statediag='0' >
						<return name='Return' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='VarName' type='T8' description='The original Flowcode variable' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</param>
						<param name='Elements' type='u32*' description='The number of elements in the array' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = 1' />
						</command>
						<command class_type='decision' title='RxData?' exp='Compare$ (.VarName,&quot;RxData&quot;,1) == 0' swap='0' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Elements = MaxFrame' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='CreateServerSocket' description='Creates a listening socket on the selected port ready to accept incoming WebSocket connections.
Returns: 1 = OK / 0 = Listen Err / 255 = Socket Open Err' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Port' type='u16' description='Default HTTP port = 80' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Server mode' >
							<exp exp='IsClient = 0' />
							<exp exp='Connected = 0' />
						</command>
						<command class_type='call' title='Attempt to open socket' component='NetworkComms1' macro='SocketOpen' >
							<return exp='.Return' />
						</command>
						<command class_type='decision' title='Decision' exp='.Return' swap='0' >
							<flowline >
								<command class_type='call' title='Start Listening for incoming connections on socket' component='NetworkComms1' macro='Listen' >
									<return exp='.Return' />
									<argument exp='.Port' />
								</command>
								<command class_type='decision' title='Decision' exp='.Return = 0' swap='0' >
									<flowline >
										<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
											<argument exp='&quot;Listen Error&quot;' />
										</command>
									</flowline>
									<flowline >
										<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
											<argument exp='&quot;Open and Listen OK&quot;' />
										</command>
									</flowline>
								</command>
							</flowline>
							<flowline >
								<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
									<argument exp='&quot;Socket Open Error&quot;' />
								</command>
								<command class_type='calculation' title='Socket Open Err' >
									<exp exp='.Return = 255' />
								</command>
							</flowline>
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='CheckSocketActivity' description='Checks for activity on the WebSocket link. In server mode this accepts and upgrades new clients. In both modes it receives frames from the remote end.
Also runs the keepalive: after Keepalive Ping idle calls it sends a ping, and after Dead Link idle calls with no reply it closes the link so a new client can be accepted. Any inbound frame resets the idle count.
Returns: 0 = No activity, 1 = Client connected (server mode), 2 = Data frame received (see GetRxCount / GetRxString / GetRxByte), 3 = Remote end disconnected, 4 = Ping received (pong sent automatically)' statediag='0' >
						<return name='Return' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='test' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = 0' />
						</command>
						<command class_type='decision' title='Already connected?' exp='Connected' swap='0' >
							<flowline >
								<command class_type='call' title='Check for a frame from the remote end' macro='Prv_ReceiveFrame' >
									<return exp='.Return' />
								</command>
								<command class_type='comment' title='' comment='Keepalive. We send the ping - browsers answer pings automatically but never send their own, so waiting to receive one would drop every idle browser. Any inbound frame, pong included, clears IdleCount and PingsSent. After PingRetries unanswered retries the link is assumed dead and closed so a new client can be accepted.' textarea='12,0,12,0' />
								<command class_type='decision' title='Keepalive due?' exp='(PingIdle &gt; 0) &amp;&amp; (IdleCount &gt;= PingIdle)' swap='0' >
									<flowline >
										<command class_type='decision' title='Out of retries?' exp='PingsSent &gt; PingRetries' swap='0' >
											<flowline >
												<command class_type='call' title='Assume the peer has gone' macro='Prv_CloseLink' />
												<command class_type='calculation' title='Ready for a new client' >
													<exp exp='IdleCount = 0' />
													<exp exp='PingsSent = 0' />
													<exp exp='.Return = 3' />
												</command>
												<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
													<argument exp='&quot;WebSocket keepalive timeout - closing the link&quot;' />
												</command>
											</flowline>
											<flowline >
												<command class_type='call' title='Send keepalive ping' macro='Prv_SendFrame' >
													<argument exp='9' />
													<argument exp='&quot;&quot;' />
													<argument exp='0' />
												</command>
												<command class_type='calculation' title='Restart the interval' >
													<exp exp='PingsSent = PingsSent + 1' />
													<exp exp='IdleCount = 0' />
												</command>
											</flowline>
										</command>
									</flowline>
									<flowline />
								</command>
							</flowline>
							<flowline >
								<command class_type='decision' title='Server mode?' exp='IsClient = 0' swap='0' >
									<flowline >
										<command class_type='call' title='Check for comms from client' component='NetworkComms1' macro='AcceptOpen' >
											<return exp='.test' />
										</command>
										<command class_type='decision' title='New connection?' exp='.test' swap='0' >
											<flowline >
												<command class_type='call' title='Perform the HTTP upgrade handshake' macro='Prv_Handshake' >
													<return exp='.Return' />
												</command>
											</flowline>
											<flowline />
										</command>
									</flowline>
									<flowline >
										<command class_type='comment' title='' comment='Client mode and not connected - call Connect to establish a link' textarea='12,0,12,0' />
									</flowline>
								</command>
							</flowline>
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='SendText' description='Sends a text frame to the connected client.
Returns the number of bytes sent, 0 = not connected or failed.' statediag='0' >
						<return name='Return' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Data' type='T8*' description='String to send' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</param>
						<local name='Len' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = 0' />
						</command>
						<command class_type='decision' title='Connected?' exp='Connected' swap='0' >
							<flowline >
								<command class_type='calculation' title='Length' >
									<exp exp='.Len = Length$ (.Data)' />
								</command>
								<command class_type='call' title='Send text frame' macro='Prv_SendFrame' >
									<return exp='.Return' />
									<argument exp='1' />
									<argument exp='.Data' />
									<argument exp='.Len' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Main' description='' statediag='0' >
						<return name='Return' type='v0' description='' isconst='0' isHidden='0' isinit='0' usrinit='' setinit='' />
						<local name='s' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='256' />
						</local>
						<local name='ev' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='call' title='Call Macro' macro='Initialise' />
						<command class_type='call' title='Call Macro' macro='CreateServerSocket' >
							<argument exp='80' />
						</command>
						<command class_type='loop' title='Loop' type='0' exp='1' for1='' for3='' >
							<flowline >
								<command class_type='call' title='Call Macro' macro='CheckSocketActivity' >
									<return exp='.ev' />
								</command>
								<command class_type='decision' title='Data received?' exp='.ev = 2' swap='0' >
									<flowline >
										<command class_type='call' title='Get text' macro='GetRxString' >
											<return exp='.s' />
										</command>
										<command class_type='sim' title='Simulation' macro='Debug.PrintLn' >
											<argument exp='&quot;RX: &quot; + .s' />
										</command>
										<command class_type='calculation' title='Calculation' >
											<exp exp='.s = &quot;Echo: &quot; + .s' />
										</command>
										<command class_type='call' title='Echo back' macro='SendText' >
											<argument exp='.s' />
										</command>
									</flowline>
									<flowline />
								</command>
								<command class_type='delay' title='Delay' exp='10' type='1' />
							</flowline>
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Prv_ComputeAccept' description='Calculates the Sec-WebSocket-Accept value for a handshake: Base64( SHA-1( Key + &quot;258EAFA5-E914-47DA-95CA-C5AB0DC85B11&quot; ) )
Implemented using Flowcode icons so it works in simulation and on any target.' statediag='0' >
						<return name='Return' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='2000' />
						</return>
						<param name='Key' type='T8*' description='24 character Sec-WebSocket-Key from the client request' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='25' />
						</param>
						<local name='Guid' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='40' />
						</local>
						<local name='Msg' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='128' />
						</local>
						<local name='W' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' >
							<array size='16' />
						</local>
						<local name='H' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' >
							<array size='5' />
						</local>
						<local name='Dig' type='T8' description='' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</local>
						<local name='A' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='B' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='C' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='D' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='E' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='F' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='K' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='T' type='u32' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='rnd' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='i' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<local name='blk' type='u8' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='comment' title='' comment='Build the 128 byte padded SHA-1 message: 24 char key + 36 char WebSocket GUID + 0x80 + zeros + 64-bit bit length (480 = 0x01E0)' textarea='12,0,12,0' />
						<command class_type='calculation' title='WebSocket GUID' >
							<exp exp='.Guid = &quot;258EAFA5-E914-47DA-95CA-C5AB0DC85B11&quot;' />
						</command>
						<command class_type='calculation' title='Clear message' >
							<exp exp='.i = 0' />
						</command>
						<command class_type='loop' title='Zero 128 bytes' type='0' exp='.i &lt; 128' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Msg[.i] = 0' />
									<exp exp='.i = .i + 1' />
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Reset index' >
							<exp exp='.i = 0' />
						</command>
						<command class_type='loop' title='Copy key' type='0' exp='.i &lt; 24' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Msg[.i] = .Key[.i]' />
									<exp exp='.i = .i + 1' />
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Reset index' >
							<exp exp='.i = 0' />
						</command>
						<command class_type='loop' title='Copy GUID' type='0' exp='.i &lt; 36' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Msg[24 + .i] = .Guid[.i]' />
									<exp exp='.i = .i + 1' />
								</command>
							</flowline>
						</command>
						<command class_type='calculation' title='Padding + bit length' >
							<exp exp='.Msg[60] = 0x80' />
							<exp exp='.Msg[126] = 0x01' />
							<exp exp='.Msg[127] = 0xE0' />
						</command>
						<command class_type='calculation' title='Initial hash' >
							<exp exp='.H[0] = 0x67452301' />
							<exp exp='.H[1] = 0xEFCDAB89' />
							<exp exp='.H[2] = 0x98BADCFE' />
							<exp exp='.H[3] = 0x10325476' />
							<exp exp='.H[4] = 0xC3D2E1F0' />
						</command>
						<command class_type='calculation' title='Block index' >
							<exp exp='.blk = 0' />
						</command>
						<command class_type='loop' title='2 x 64 byte blocks' type='0' exp='.blk &lt; 2' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Load 16 words big-endian' >
									<exp exp='.rnd = 0' />
								</command>
								<command class_type='loop' title='Load W' type='0' exp='.rnd &lt; 16' for1='' for3='' >
									<flowline >
										<command class_type='calculation' title='Calculation' >
											<exp exp='.i = (.blk * 64) + (.rnd * 4)' />
											<exp exp='.W[.rnd] = .Msg[.i]' />
											<exp exp='.W[.rnd] = (.W[.rnd] &lt;&lt; 8) | .Msg[.i + 1]' />
											<exp exp='.W[.rnd] = (.W[.rnd] &lt;&lt; 8) | .Msg[.i + 2]' />
											<exp exp='.W[.rnd] = (.W[.rnd] &lt;&lt; 8) | .Msg[.i + 3]' />
											<exp exp='.rnd = .rnd + 1' />
										</command>
									</flowline>
								</command>
								<command class_type='calculation' title='Init working vars' >
									<exp exp='.A = .H[0]' />
									<exp exp='.B = .H[1]' />
									<exp exp='.C = .H[2]' />
									<exp exp='.D = .H[3]' />
									<exp exp='.E = .H[4]' />
									<exp exp='.rnd = 0' />
								</command>
								<command class_type='loop' title='80 rounds' type='0' exp='.rnd &lt; 80' for1='' for3='' >
									<flowline >
										<command class_type='decision' title='Extend schedule?' exp='.rnd &gt;= 16' swap='0' >
											<flowline >
												<command class_type='calculation' title='W[t] = rotl1(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])' >
													<exp exp='.T = .W[(.rnd + 13) &amp; 15] ^ .W[(.rnd + 8) &amp; 15] ^ .W[(.rnd + 2) &amp; 15] ^ .W[.rnd &amp; 15]' />
													<exp exp='.W[.rnd &amp; 15] = (.T &lt;&lt; 1) | (.T &gt;&gt; 31)' />
												</command>
											</flowline>
											<flowline />
										</command>
										<command class_type='decision' title='t &lt; 20' exp='.rnd &lt; 20' swap='0' >
											<flowline >
												<command class_type='calculation' title='Ch' >
													<exp exp='.F = (.B &amp; .C) | ((.B ^ 0xFFFFFFFF) &amp; .D)' />
													<exp exp='.K = 0x5A827999' />
												</command>
											</flowline>
											<flowline >
												<command class_type='decision' title='t &lt; 40' exp='.rnd &lt; 40' swap='0' >
													<flowline >
														<command class_type='calculation' title='Parity' >
															<exp exp='.F = .B ^ .C ^ .D' />
															<exp exp='.K = 0x6ED9EBA1' />
														</command>
													</flowline>
													<flowline >
														<command class_type='decision' title='t &lt; 60' exp='.rnd &lt; 60' swap='0' >
															<flowline >
																<command class_type='calculation' title='Maj' >
																	<exp exp='.F = (.B &amp; .C) | (.B &amp; .D) | (.C &amp; .D)' />
																	<exp exp='.K = 0x8F1BBCDC' />
																</command>
															</flowline>
															<flowline >
																<command class_type='calculation' title='Parity' >
																	<exp exp='.F = .B ^ .C ^ .D' />
																	<exp exp='.K = 0xCA62C1D6' />
																</command>
															</flowline>
														</command>
													</flowline>
												</command>
											</flowline>
										</command>
										<command class_type='calculation' title='Round' >
											<exp exp='.T = ((.A &lt;&lt; 5) | (.A &gt;&gt; 27)) + .F + .E + .K + .W[.rnd &amp; 15]' />
											<exp exp='.E = .D' />
											<exp exp='.D = .C' />
											<exp exp='.C = (.B &lt;&lt; 30) | (.B &gt;&gt; 2)' />
											<exp exp='.B = .A' />
											<exp exp='.A = .T' />
											<exp exp='.rnd = .rnd + 1' />
										</command>
									</flowline>
								</command>
								<command class_type='calculation' title='Add to hash' >
									<exp exp='.H[0] = .H[0] + .A' />
									<exp exp='.H[1] = .H[1] + .B' />
									<exp exp='.H[2] = .H[2] + .C' />
									<exp exp='.H[3] = .H[3] + .D' />
									<exp exp='.H[4] = .H[4] + .E' />
									<exp exp='.blk = .blk + 1' />
								</command>
							</flowline>
						</command>
						<command class_type='comment' title='' comment='Digest = 20 bytes big-endian' textarea='12,0,12,0' />
						<command class_type='calculation' title='Reset' >
							<exp exp='.i = 0' />
						</command>
						<command class_type='loop' title='Extract digest' type='0' exp='.i &lt; 5' for1='' for3='' >
							<flowline >
								<command class_type='calculation' title='Calculation' >
									<exp exp='.Dig[.i * 4] = (.H[.i] &gt;&gt; 24) &amp; 0xFF' />
									<exp exp='.Dig[(.i * 4) + 1] = (.H[.i] &gt;&gt; 16) &amp; 0xFF' />
									<exp exp='.Dig[(.i * 4) + 2] = (.H[.i] &gt;&gt; 8) &amp; 0xFF' />
									<exp exp='.Dig[(.i * 4) + 3] = .H[.i] &amp; 0xFF' />
									<exp exp='.i = .i + 1' />
								</command>
							</flowline>
						</command>
						<command class_type='call' title='Base64 encode the 20 byte digest' macro='Prv_Base64' >
							<return exp='.Return' />
							<argument exp='.Dig' />
							<argument exp='20' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='Initialise' description='Resets and initialises the WebSocket component. Defaults to server mode; calling Connect switches to client mode, CreateServerSocket switches back.' statediag='0' >
						<return name='Return' type='v0' description='' isconst='0' isHidden='0' isinit='0' usrinit='' setinit='' />
						<command class_type='calculation' title='Reset state' >
							<exp exp='Connected = 0' />
							<exp exp='IsClient = 0' />
							<exp exp='RxCount = 0' />
							<exp exp='RxOpcode = 0' />
							<exp exp='RxData[0] = 0' />
							<exp exp='IdleCount = 0' />
							<exp exp='PingsSent = 0' />
							<exp exp='Seed = 0x2545F491' />
						</command>
					</flowline>
				</macro>
				<macro >
					<flowline name='SendBinary' description='Sends a binary frame to the connected client.
Returns the number of bytes sent, 0 = not connected or failed.' statediag='0' >
						<return name='Return' type='u16' description='' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<param name='Data' type='T8*' description='Data array to send' isconst='0' isHidden='0' isinit='0' usrinit='&quot;&quot;' setinit='' >
							<array size='20' />
						</param>
						<param name='Count' type='u16' description='Number of bytes to send' isconst='0' isHidden='0' isinit='0' usrinit='0' setinit='' />
						<command class_type='calculation' title='Calculation' >
							<exp exp='.Return = 0' />
						</command>
						<command class_type='decision' title='Connected?' exp='Connected' swap='0' >
							<flowline >
								<command class_type='call' title='Send binary frame' macro='Prv_SendFrame' >
									<return exp='.Return' />
									<argument exp='2' />
									<argument exp='.Data' />
									<argument exp='.Count' />
								</command>
							</flowline>
							<flowline />
						</command>
					</flowline>
				</macro>
			</macros>
			<component class_type='ref' guid='58be670e-18fb-477e-ab09-61fde14b23ec' vmin='0' vmaj='1' codename='LibraryComponent1' panelId='-1' x='0' y='0' z='0' xsz='100' ysz='100' zsz='100' xang='0' yang='0' zang='0' xquat='0' yquat='0' zquat='0' wquat='1' visible='1' scadavisible='1' interactive='1' solid='1' layer='1' poslock='1' ancTop='0' ancBottom='0' ancLeft='0' ancRight='0' ancMinX='0' ancMinY='0' angle2d='0' comp2dType='0' >
				<resources />
				<properties />
				<values >
					<value target='Text::sText' data='Web
Socket' />
					<value target='Name' data='' />
					<value target='Peripheral::sText' data='' />
					<value target='Text::nVerticalAlignment' data='002' />
					<value target='ShowComms' data='1' />
					<value target='InputIcon::CommsType' data='255' />
					<value target='InputIcon::LinkTo' data='0' />
					<value target='IconsOnRight' data='1' />
					<value target='OutputIcon::CommsType' data='000' />
					<value target='OutputIcon::LinkTo' data='0' />
					<value target='InputIcon1::CommsType' data='255' />
					<value target='ConsoleHandle' data='0' />
					<value target='Upgraded' data='0' />
				</values>
				<events />
				<apis />
				<variables />
				<macros />
			</component>
			<component class_type='ref' guid='6112d87f-f9c8-4670-a5d1-dfcf313d935c' vmin='1' vmaj='1' codename='NetworkComms1' panelId='-1' x='0' y='0' z='0' xsz='0.2' ysz='0.2' zsz='0.2' xang='0' yang='0' zang='0' xquat='0' yquat='0' zquat='0' wquat='1' visible='0' scadavisible='1' interactive='0' solid='0' layer='1' poslock='0' ancTop='0' ancBottom='0' ancLeft='0' ancRight='0' ancMinX='0' ancMinY='0' angle2d='0' comp2dType='0' >
				<resources />
				<properties />
				<values >
					<value target='Component' data='' />
					<value target='RemapIndex' data='0' />
					<value target='Status' data='Simulation Only' />
				</values>
				<events />
				<apis />
				<variables />
				<macros />
			</component>
		</component>
	</components>
	<scadaresourcelookup />
	<keymap />
	<panel2d shadows='0' lighting='0' brightness='0' >
		<background rgb='9737364' img='' style='0' />
		<camera xe='9.13654' ye='15.2223' ze='341.112' xt='9.13654' yt='15.2223' zt='0' xquat='0' yquat='0' zquat='0' wquat='1' />
		<viewport dx='397' dy='774' zoom='140.825' fix_topleft='0' />
		<page x='1000' y='1000' show='0' rgb='0' />
		<winpos ID='7005' RectRecentFloat='260,504,910,954' RectRecentDocked='1064,141,1481,1005' RecentFrameAlignment='16384' RecentRowIndex='0' IsFloating='0' MRUWidth='32767' PinState='0' IsMaximized='0' IsVisible='1' />
	</panel2d>
	<panel3d shadows='0' lighting='2' brightness='0' perspective='1' >
		<background rgb='8409120' img='' style='0' />
		<table rgb='7360576' img='' style='0' size='25' />
		<camera xe='-26.9029' ye='11.7267' ze='618.51' xt='-26.9029' yt='11.7267' zt='0' xquat='0' yquat='0' zquat='0' wquat='1' />
		<camerakey0 xe='0' ye='0' ze='300' xt='0' yt='0' zt='0' xquat='0' yquat='0' zquat='0' wquat='1' />
		<camerakey1 xe='-3.67394e-14' ye='0' ze='-300' xt='0' yt='0' zt='0' xquat='0' yquat='1' zquat='0' wquat='6.12323e-17' />
		<camerakey2 xe='0' ye='-300' ze='6.66134e-14' xt='0' yt='0' zt='0' xquat='-0.707107' yquat='0' zquat='0' wquat='0.707107' />
		<camerakey3 xe='-3.67394e-14' ye='300' ze='6.66134e-14' xt='0' yt='0' zt='0' xquat='-4.32978e-17' yquat='0.707107' zquat='0.707107' wquat='4.32978e-17' />
		<camerakey4 xe='-300' ye='-6.66134e-14' ze='6.66134e-14' xt='0' yt='0' zt='0' xquat='-0.5' yquat='0.5' zquat='0.5' wquat='0.5' />
		<camerakey5 xe='300' ye='-6.66134e-14' ze='6.66134e-14' xt='0' yt='0' zt='0' xquat='-0.5' yquat='-0.5' zquat='-0.5' wquat='0.5' />
		<camerakey6 xe='-173.205' ye='-173.205' ze='173.205' xt='0' yt='0' zt='0' xquat='-0.424708' yquat='0.17592' zquat='0.339851' wquat='0.820473' />
		<winpos ID='7004' RectRecentFloat='0,425,654,1002' RectRecentDocked='0,0,210,864' RecentFrameAlignment='16384' RecentRowIndex='0' IsFloating='0' MRUWidth='32767' PinState='0' IsMaximized='0' IsVisible='0' />
	</panel3d>
	<panels2d count='1' >
		<panel2d_0 id='0' name='NewPanel' type='0' >
			<winpos ID='1171' RectRecentFloat='0,360,650,810' RectRecentDocked='1064,141,1481,1005' RecentFrameAlignment='16384' RecentRowIndex='0' IsFloating='1' MRUWidth='32767' PinState='0' IsMaximized='0' IsVisible='0' />
			<background fill='288230376151053813' showgrid='1' gridstyle='0' gridsize='5' gridbrush='71776119075691740' snaptogrid='0' fitcomp='0' disp_x='300' disp_y='400' scale='100' disp_col='16777215' />
		</panel2d_0>
	</panels2d>
	<layout >
		<view type='0' name='CheckSocketActivity' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Connect' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Prv_Handshake' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Prv_ReceiveFrame' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Prv_SendFrame' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Prv_ComputeAccept' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Main' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Prv_B64Char' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Ev_Property' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Ev_GetVarSize' mode='0' placement='LAAAAAAAAAABAAAA---------------------wUAAAAYAAAAlgEAAFsDAAA' zoom='100' scrollx='0' scrolly='0' flags='0' />
	</layout>
</document>
</root>
