Difference between revisions of "Protocol decoder:Ook"

From sigrok
Jump to navigation Jump to search
 
(13 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{Infobox protocol decoder
{{Infobox protocol decoder
| id              = ook
| id              = ook
| name            = On Off Keying
| name            = On-off keying
| description    = Decodes On Off Keying waveforms which are frequently used for remote control protocols
| description    = On-off keying protocol
| status          = possible candidate
| status          = supported
| license        = GPLv2+
| license        = GPLv2+
| source_code_dir = ook
| source_code_dir = ook
Line 9: Line 9:
| input          = logic
| input          = logic
| output          = ook
| output          = ook
| probes          = none
| probes          = data
| optional_probes = —
| optional_probes = —
| options        = invert, decodeas, preamble, preamlen, diffmanvar
| options        = invert, decodeas, preamble, preamlen, diffmanvar
}}
}}


The '''ook''' protocol decoder takes a logic level input and decodes NRZ, Manchester and Differential Manchester encoding.
The '''ook''' protocol decoder takes a logic level input and decodes '''NRZ''', '''Manchester''' and '''Differential Manchester''' encoding.


It decodes based on sample lengths rather than on sampling rate or inter pulse delays, so should be capable of decoding a variety of signals.
This PD can decode e.g. OOK based remote control protocols. It is aimed at 433MHz but should also work with other common RC frequencies.


== Getting a signal to Analyse ==
It decodes based on numbers of samples rather than on sampling rate or specific inter pulse delays, so should be capable of decoding a variety of signals.
 
== Getting a signal to analyse ==


There are two main ways of getting a signal to decode. Opening up the device and attaching the probes from a logic analyser directly to the logic level signal (if you can find and safely connect to it) or using a receiver to demodulate the Radio Frequency (RF) signal to recover the logic level signal.  
There are two main ways of getting a signal to decode. Opening up the device and attaching the probes from a logic analyser directly to the logic level signal (if you can find and safely connect to it) or using a receiver to demodulate the Radio Frequency (RF) signal to recover the logic level signal.  
Line 26: Line 28:
Using a demodulator is much lower risk but comes with its own challenges which mainly resolve around the extra noise and other signals that the RF receiver picks up that are nothing to do with the signal that you are interested in. If another device transmits at the same time as the wanted signal then the two will interfere with each other and add up to a mangled mess. Similarly if something creates noise at the same time as the wanted signal then there are going to be some holes in it. One coping strategy is to take a decent number of samples and hopefully get one that is clean.
Using a demodulator is much lower risk but comes with its own challenges which mainly resolve around the extra noise and other signals that the RF receiver picks up that are nothing to do with the signal that you are interested in. If another device transmits at the same time as the wanted signal then the two will interfere with each other and add up to a mangled mess. Similarly if something creates noise at the same time as the wanted signal then there are going to be some holes in it. One coping strategy is to take a decent number of samples and hopefully get one that is clean.


Sigrok has a very useful feature that allows the cursors in PulseView to be used to highlight part of the waveform and "Save Selected Range As" to manually cut out a useful signal from the noise and other signals around it. '''Important''' when using this feature make sure that you leave at least five times the preamble period on the end of the signal or the stacked decoders will not get triggered.
sigrok has a very useful feature that allows the cursors in PulseView to be used to highlight part of the waveform and '''Save Selected Range As''' to manually cut out a useful signal from the noise and other signals around it. '''Important''': When using this feature make sure that you leave at least five times the preamble period on the end of the signal or the stacked decoders will not get triggered.


In an ideal world the decoder would be able to do the manual identification for you and chop the garbage out too. There are a couple of extra things that have been built into this decoder that will try and improve your chances of getting a good result from a less than ideal waveform. Good electrical design and layout of the receiver are major factors too.
In an ideal world the decoder would be able to do the manual identification for you and chop the garbage out too. There are a couple of extra things that have been built into this decoder that will try and improve your chances of getting a good result from a less than ideal waveform. Good electrical design and layout of the receiver are major factors too.
Line 32: Line 34:
== How it works ==
== How it works ==


The '''ook''' decoder assumes that the signal that it needs to decode will have a square wave preamble which can be analysed to work out the original clock period (in samples) which it needs to recover the sending clock and decode the signal. '''Note''' that it does not look for specific inter pulse times which would limit what it could decode.
The '''ook''' decoder assumes that the signal that it needs to decode will have a square wave preamble which can be analysed to work out the original clock period (in samples) which it needs to recover the sending clock and decode the signal. '''Note''': It does not look for specific inter-pulse times which would limit what it could decode.


It is important to make sure that the preamble is correctly identified and that the decoder doesn't try and use random noise or other garbage as the preamble.
It is important to make sure that the preamble is correctly identified and that the decoder doesn't try and use random noise or other garbage as the preamble.


To give the demodulator option a better chance of working from the output of an RF receiver, this decoder contains some garbage removal code. The code requires 7 pulses (adjustable from 3 to 10) in a row that have lengths within a factor of 5 of each other before it will start decoding. This is designed to reject random background noise and noise which is created by the way that RF receivers work.  
To give the demodulator option a better chance of working from the output of an RF receiver, this decoder contains some garbage removal code. The code requires 7 pulses (adjustable from 3 to 10) in a row that have lengths within a factor of 5 of each other before it will start decoding. This is designed to reject random background noise and noise which is created by the way that RF receivers work.


If garbage removal and Advanced clock recovery (see below) are not needed then these features can be totally disabled by selecting a preamlen of '0'. Don't disable this feature unless you are opening up the device and attaching the probes from a logic analyser directly to the logic level signal.
If garbage removal and advanced clock recovery (see below) are not needed then these features can be totally disabled by selecting a '''preamlen''' of '0'. Don't disable this feature unless you are opening up the device and attaching the probes from a logic analyser directly to the logic level signal.


A genuine preamble will pass intact through the garbage filter.
A genuine preamble will pass intact through the garbage filter.
Line 46: Line 48:
At the end of receiving a good signal the super regenerative RF receivers go low for a few hundred milliseconds. This is a useful marker to spot when looking at captured waveforms. Find the blanks and go backwards to the signal and its preamble.
At the end of receiving a good signal the super regenerative RF receivers go low for a few hundred milliseconds. This is a useful marker to spot when looking at captured waveforms. Find the blanks and go backwards to the signal and its preamble.


The decoder imitates this behaviour to detects the end of each set of pulses by looking for a low for five times the preamble period. Once the decode has timed out the resulting OOK pattern is sent up the stack to the higher level decoders and the decoder is reset ready for the next set of pulses which may be from a completely different device.
The decoder imitates this behaviour to detect the end of each set of pulses by looking for a low for five times the preamble period. Once the decode has timed out the resulting OOK pattern is sent up the stack to the higher level decoders and the decoder is reset ready for the next set of pulses which may be from a completely different device.


== Advanced Clock Recovery ==
== Advanced clock recovery ==


The example waveforms in the articles in the Resources section below all use a clock that is a pure square wave (50:50 mark/space) which have equal high and low times. It makes it much easier to understand what is going on and also makes it easier to decode at the other end.
The example waveforms in the articles in the [[Protocol decoder:Ook#Resources|Resources]] section below all use a clock that is a pure square wave (50:50 mark/space) which have equal high and low times. It makes it much easier to understand what is going on and also makes it easier to decode at the other end.


Decoding is based upon spotting long and short pulses, so its essential to recover the clock accurately to work out what is a long and short pulse.
Decoding is based upon spotting long and short pulses, so it's essential to recover the clock accurately to work out what is a long and short pulse.


In real life the ideal square wave preamble doesn't always happen and the signal can frequently end up skewed with significantly longer on than off periods or vice versa. This makes some devices much harder to see and decode than others. The RF decoder chosen will have a significant effect too.
In real life the ideal square wave preamble doesn't always happen and the signal can frequently end up skewed with significantly longer on than off periods or vice versa. This makes some devices much harder to see and decode than others. The RF decoder chosen will have a significant effect too.
Line 60: Line 62:
== Decoder ==
== Decoder ==


The '''ook''' decoder has the following options and defaults
The '''ook''' decoder has the following options and defaults:
    invert - Yes/No - default No
 
    decodeas - Manchester/Differential Manchester/NRZ - Decode As - default Manchester
* '''invert''' - Yes/No - Invert data - default No
    preamble - '1010 ...'/'1111 ...' - Preamble pattern - default '1111 ...'  
* '''decodeas''' - Manchester/Differential Manchester/NRZ - Decode type - default Manchester
    preamlen - 0/3/4/5/6/7/8/9/10 - Preamble filter length - default 7 - 0 turns it off
* '''preamble''' - auto/1010/1111 - Preamble - default auto
    diffmanver - 1/0 Differential Manchester - transition at start is a - default 1  
* '''preamlen''' - 0/3/4/5/6/7/8/9/10 - Filter length - default 7 - 0 turns it off
* '''diffmanvar''' - 1/0 Differential Manchester - Transition at start - default 1  


'''Manchester encoding'''
'''Manchester encoding'''


This can send a 50:50 mark/space square wave to transmit a signal that is '1111 ...' or '1010 ...'. In one case the pulse samples represent the clock period in the other only half. Which one was intended cannot be easily detected by the receiver, so there is an option for the user to make the choice. Making the right choice should remove most of the decoding errors.
Devices can send a 50:50 mark/space square wave to transmit a signal that represents '1111' or '1010'. In one case the pulse samples represent the clock period, in the other only half. The default '''preamble''' option is '''auto''' which tries both variants at the same time and selects the result with least errors when all of the packet has been seen. This can be very useful when there are Oregon v2 and v3 devices in the same capture. The user can also force the preamble to be 1111 or 1010.


There are also two variants, as per G.E Thomas and IEEE 802.3 These are the opposite way up to each other. The default here is IEEE 802.3 but the option is there to '''invert''' the result and comply with G.E Thomas.
There are two variants, G.E Thomas and IEEE 802.3. These are the opposite way up to each other. The default here is IEEE 802.3 but the option is there to '''invert''' the result and follow G.E Thomas.
The '''diffmanver''' option will be ignored as it only applies to Differential Manchester decoding.
The '''diffmanver''' option will be ignored as it only applies to Differential Manchester decoding.


Line 77: Line 80:


Again there are two options, to treat a transition at the start of the clock cycle as a 1 or 0 and no transition as a 0 or 1. The default is to treat a transition as a 1 and no transition as a 0.
Again there are two options, to treat a transition at the start of the clock cycle as a 1 or 0 and no transition as a 0 or 1. The default is to treat a transition as a 1 and no transition as a 0.
Note. Inverting a Differential Manchester signals does nothing, so although the '''invert''' option does work here, it won't effect the result. The '''preamble''' pattern only applies to Manchester encoding and is ignored inside this decoder.
'''Note:''' Inverting a Differential Manchester signal does nothing, so although the '''invert''' option does work here, it won't effect the result. The '''preamble''' pattern only applies to Manchester encoding and is ignored inside this decoder.


'''NRZ'''
'''NRZ'''


Or '''Binary Encoding''' as it is called in Computer Networks 2nd Edition - Andrew S. Tannenbaum only has one option which is '''invert'''
Or '''Binary Encoding''' as it is called in ''Computer Networks 2nd Edition - Andrew S. Tannenbaum'' only has one option which is '''invert'''.
The '''decodeas''', '''preamble''' and '''diffmanver''' options are ignored.
The '''decodeas''', '''preamble''' and '''diffmanvar''' options are ignored.


== Output ==
== Output ==


The results of decoding each bit can be
The results of decoding each bit can be
'0'   zero or low
 
'1'   one or high
* '0': zero (low)
'E'   Error or invalid. This can be caused by missing transitions or the wrong pulse lengths according to the rules for the particular encoding. In some cases this is intentional (Oregon v1 preamble) and is part of the sync pattern. In other cases the signal could simply be broken.
* '1': one (high)
* 'E': Error (invalid)
 
Error bits can be caused by missing transitions or the wrong pulse lengths according to the rules for the particular encoding. In some cases this is intentional (Oregon v1 preamble) and is part of the sync pattern. In other cases the signal could simply be broken.


If you get large numbers of 'E's then you are probably using the wrong decoder, using the wrong options with the right decoder, there is simply too much noise or more rarely the sample rate is too low for the decoder to work properly. The ideal sample rate is 50 to 100 times higher than the preamble clock and becomes more of an issue with badly skewed signals.
If you get large numbers of 'E's then you are probably using the wrong decoder, using the wrong options with the right decoder, there is simply too much noise or more rarely the sample rate is too low for the decoder to work properly. The ideal sample rate is 50 to 100 times higher than the preamble clock and becomes more of an issue with badly skewed signals.
   
== sigrok-cli examples ==


You can show the available options with the --show command:
You can show the available options with the --show command:


<pre>
$ '''sigrok-cli -P ook --show'''
$ sigrok-cli -P ook --show
 
</pre>
To use '''ook''' to decode a Manchester (default) encoded trace with auto preamble (default):
   
 
== sigrok-cli examples ==
$ '''sigrok-cli -P ook:data=D0 -i oregon_pcr800.sr'''


usage with sigrok-cli is:
To decode a Manchester (default) encoded trace with a preamble starting 1010 (Oregon v2):


To use '''ook''' to decode a Manchester (default) encoded  trace with a preamble starting 1010.
$ '''sigrok-cli -P ook:data=D1:preamble='1010' -i oregon_bthr968.sr'''
<pre>
sigrok-cli -P ook:data=D1:preamble='1010 ...' -i thgr228n.sr
</pre>


To decode a Manchester (default) encoded trace with a preamble starting 1111 (default)
The ook output from the ook decoder can also be stacked with another decoder that accepts ook input such as the [http://store.oregonscientific.com/us/weather-stations.html Oregon Scientific] decoder.
<pre>
sigrok-cli -P ook:data=D0 -i oregon_pcr800.sr
</pre>


The ook output from the ook decoder can also be stacked with another decoder that accepts ook input such as the [http://store.oregonscientific.com/us/weather-stations.html Oregon Scientific] decoder
To decode a Manchester (default) encoded trace and then pass the result to the oregon decoder and only display the oregon output:
To decode a Manchester (default) encoded trace with a preamble starting 1010 (Oregon V2.1 sensor) and then pass the result to the oregon decoder and only display the oregon output
<pre>
sigrok-cli -P ook:data=D1:preamble='1010 ...',oregon -i thgr228n.sr -A oregon
</pre>


The ook decoder can optionally display the pulse lengths in micro seconds by using the Binary output switch with an option called "pulse-lengths"
$ '''sigrok-cli -P ook:data=D0,ook_oregon -i oregon_bthr968.sr -A ook_oregon'''
<pre>
sigrok-cli -P ook:data=D0,ook_oregon -B ook=pulse-lengths -i oregon_pcr800.sr
</pre>


== Resources ==
The ook decoder can output the pulse lengths in micro seconds by using the binary output switch ('''-B''') with an option called "pulse-lengths":
* [https://en.wikipedia.org/wiki/On-off_keying On Off Keying wiki]
* [https://en.wikipedia.org/wiki/Unipolar_encoding Unipolar Encoding includes NRZ]
* Computer Networks 2nd Edition - Andrew S. Tannenbaum P60 Fig 2.3 "Three different encoding techniques" has an excellent picture of logic level waveforms that were used to create the Manchester and Differential Manchester decoders
* [https://en.wikipedia.org/wiki/Manchester_code Wikipedia: Manchester code] Pictures are analog waveforms not logic
* [https://en.wikipedia.org/wiki/Differential_Manchester_encoding Wikipedia: Differential Manchester code] Pictures are analog waveforms not logic


* [https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Differential_Manchester_encoding.html  Differential Manchester encoding]
$ '''sigrok-cli -P ook:data=D0,ook_oregon -B ook=pulse-lengths -i oregon_pcr800.sr'''


Other interesting articles
== Resources ==


* [https://en.wikipedia.org/wiki/On-off_keying Wikipedia: On-off keying]
* [https://en.wikipedia.org/wiki/Unipolar_encoding Wikipedia: Unipolar encoding] (includes NRZ)
* Computer Networks 2nd Edition - Andrew S. Tannenbaum P60 Fig 2.3 "Three different encoding techniques" has an excellent picture of logic level waveforms that were used to create the Manchester and Differential Manchester decoders
* [https://en.wikipedia.org/wiki/Manchester_code Wikipedia: Manchester code] (pictures are analog waveforms not logic)
* [https://en.wikipedia.org/wiki/Differential_Manchester_encoding Wikipedia: Differential Manchester code] (pictures are analog waveforms not logic)
* [https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Differential_Manchester_encoding.html Distributed Wikipedia Mirror: Differential Manchester encoding]
* [http://www.nesweb.ch/downloads/doc9164.pdf Atmel (Arduino) Manchester coding basics]
* [http://www.nesweb.ch/downloads/doc9164.pdf Atmel (Arduino) Manchester coding basics]
* [http://www.pcbheaven.com/wikipages/manchester_coding/ Manchester and Diff Manchester encoding] good unipolar pictures plus some good flow charts for decoding with a microcontroller.
* [http://www.pcbheaven.com/wikipages/manchester_coding/ PCBHeaven: Manchester and Diff Manchester encoding] u(nipolar pictures plus some good flow charts for decoding with a microcontroller)


__FORCETOC__
__FORCETOC__


[[Category:Protocol decoder]]
[[Category:Protocol decoder]]

Latest revision as of 13:23, 13 October 2018

ook
Ook.png
Name On-off keying
Description On-off keying protocol
Status supported
License GPLv2+
Source code decoders/ook
Input logic
Output ook
Probes data
Optional probes
Options invert, decodeas, preamble, preamlen, diffmanvar

The ook protocol decoder takes a logic level input and decodes NRZ, Manchester and Differential Manchester encoding.

This PD can decode e.g. OOK based remote control protocols. It is aimed at 433MHz but should also work with other common RC frequencies.

It decodes based on numbers of samples rather than on sampling rate or specific inter pulse delays, so should be capable of decoding a variety of signals.

Getting a signal to analyse

There are two main ways of getting a signal to decode. Opening up the device and attaching the probes from a logic analyser directly to the logic level signal (if you can find and safely connect to it) or using a receiver to demodulate the Radio Frequency (RF) signal to recover the logic level signal.

Opening up the device is going to get you the cleanest signal but carries the risk of breaking the device and any warranty.

Using a demodulator is much lower risk but comes with its own challenges which mainly resolve around the extra noise and other signals that the RF receiver picks up that are nothing to do with the signal that you are interested in. If another device transmits at the same time as the wanted signal then the two will interfere with each other and add up to a mangled mess. Similarly if something creates noise at the same time as the wanted signal then there are going to be some holes in it. One coping strategy is to take a decent number of samples and hopefully get one that is clean.

sigrok has a very useful feature that allows the cursors in PulseView to be used to highlight part of the waveform and Save Selected Range As to manually cut out a useful signal from the noise and other signals around it. Important: When using this feature make sure that you leave at least five times the preamble period on the end of the signal or the stacked decoders will not get triggered.

In an ideal world the decoder would be able to do the manual identification for you and chop the garbage out too. There are a couple of extra things that have been built into this decoder that will try and improve your chances of getting a good result from a less than ideal waveform. Good electrical design and layout of the receiver are major factors too.

How it works

The ook decoder assumes that the signal that it needs to decode will have a square wave preamble which can be analysed to work out the original clock period (in samples) which it needs to recover the sending clock and decode the signal. Note: It does not look for specific inter-pulse times which would limit what it could decode.

It is important to make sure that the preamble is correctly identified and that the decoder doesn't try and use random noise or other garbage as the preamble.

To give the demodulator option a better chance of working from the output of an RF receiver, this decoder contains some garbage removal code. The code requires 7 pulses (adjustable from 3 to 10) in a row that have lengths within a factor of 5 of each other before it will start decoding. This is designed to reject random background noise and noise which is created by the way that RF receivers work.

If garbage removal and advanced clock recovery (see below) are not needed then these features can be totally disabled by selecting a preamlen of '0'. Don't disable this feature unless you are opening up the device and attaching the probes from a logic analyser directly to the logic level signal.

A genuine preamble will pass intact through the garbage filter.

Only decoding from a genuine preamble does several good things, it reduces the work that the higher levels have to do and it frames the wanted signals.

At the end of receiving a good signal the super regenerative RF receivers go low for a few hundred milliseconds. This is a useful marker to spot when looking at captured waveforms. Find the blanks and go backwards to the signal and its preamble.

The decoder imitates this behaviour to detect the end of each set of pulses by looking for a low for five times the preamble period. Once the decode has timed out the resulting OOK pattern is sent up the stack to the higher level decoders and the decoder is reset ready for the next set of pulses which may be from a completely different device.

Advanced clock recovery

The example waveforms in the articles in the Resources section below all use a clock that is a pure square wave (50:50 mark/space) which have equal high and low times. It makes it much easier to understand what is going on and also makes it easier to decode at the other end.

Decoding is based upon spotting long and short pulses, so it's essential to recover the clock accurately to work out what is a long and short pulse.

In real life the ideal square wave preamble doesn't always happen and the signal can frequently end up skewed with significantly longer on than off periods or vice versa. This makes some devices much harder to see and decode than others. The RF decoder chosen will have a significant effect too.

This decoder copes with the problem by treating the clock high and low reference lengths independently. It looks at the preamble and if the preamble is skewed then it assumes that the signal will be too and compensates by comparing high pulses with the high reference and low pulses with the low reference.

Decoder

The ook decoder has the following options and defaults:

  • invert - Yes/No - Invert data - default No
  • decodeas - Manchester/Differential Manchester/NRZ - Decode type - default Manchester
  • preamble - auto/1010/1111 - Preamble - default auto
  • preamlen - 0/3/4/5/6/7/8/9/10 - Filter length - default 7 - 0 turns it off
  • diffmanvar - 1/0 Differential Manchester - Transition at start - default 1

Manchester encoding

Devices can send a 50:50 mark/space square wave to transmit a signal that represents '1111' or '1010'. In one case the pulse samples represent the clock period, in the other only half. The default preamble option is auto which tries both variants at the same time and selects the result with least errors when all of the packet has been seen. This can be very useful when there are Oregon v2 and v3 devices in the same capture. The user can also force the preamble to be 1111 or 1010.

There are two variants, G.E Thomas and IEEE 802.3. These are the opposite way up to each other. The default here is IEEE 802.3 but the option is there to invert the result and follow G.E Thomas. The diffmanver option will be ignored as it only applies to Differential Manchester decoding.

Differential Manchester encoding

Again there are two options, to treat a transition at the start of the clock cycle as a 1 or 0 and no transition as a 0 or 1. The default is to treat a transition as a 1 and no transition as a 0. Note: Inverting a Differential Manchester signal does nothing, so although the invert option does work here, it won't effect the result. The preamble pattern only applies to Manchester encoding and is ignored inside this decoder.

NRZ

Or Binary Encoding as it is called in Computer Networks 2nd Edition - Andrew S. Tannenbaum only has one option which is invert. The decodeas, preamble and diffmanvar options are ignored.

Output

The results of decoding each bit can be

  • '0': zero (low)
  • '1': one (high)
  • 'E': Error (invalid)

Error bits can be caused by missing transitions or the wrong pulse lengths according to the rules for the particular encoding. In some cases this is intentional (Oregon v1 preamble) and is part of the sync pattern. In other cases the signal could simply be broken.

If you get large numbers of 'E's then you are probably using the wrong decoder, using the wrong options with the right decoder, there is simply too much noise or more rarely the sample rate is too low for the decoder to work properly. The ideal sample rate is 50 to 100 times higher than the preamble clock and becomes more of an issue with badly skewed signals.

sigrok-cli examples

You can show the available options with the --show command:

$ sigrok-cli -P ook --show

To use ook to decode a Manchester (default) encoded trace with auto preamble (default):

$ sigrok-cli -P ook:data=D0 -i oregon_pcr800.sr

To decode a Manchester (default) encoded trace with a preamble starting 1010 (Oregon v2):

$ sigrok-cli -P ook:data=D1:preamble='1010' -i oregon_bthr968.sr

The ook output from the ook decoder can also be stacked with another decoder that accepts ook input such as the Oregon Scientific decoder.

To decode a Manchester (default) encoded trace and then pass the result to the oregon decoder and only display the oregon output:

$ sigrok-cli -P ook:data=D0,ook_oregon -i oregon_bthr968.sr -A ook_oregon

The ook decoder can output the pulse lengths in micro seconds by using the binary output switch (-B) with an option called "pulse-lengths":

$ sigrok-cli -P ook:data=D0,ook_oregon -B ook=pulse-lengths -i oregon_pcr800.sr

Resources