├── .gitattributes ├── .gitignore ├── CottonwoodRfidReader ├── Cottonwood.cs ├── CottonwoodRfidReader.csproj ├── Properties │ ├── AssemblyInfo.cs │ └── CottonwoodRfidReader.rd.xml └── project.json ├── RfidScanner.sln └── RfidScanner ├── Assets ├── LockScreenLogo.scale-200.png ├── SplashScreen.scale-200.png ├── Square150x150Logo.scale-200.png ├── Square44x44Logo.scale-200.png ├── Square44x44Logo.targetsize-24_altform-unplated.png ├── StoreLogo.png └── Wide310x150Logo.scale-200.png ├── Package.appxmanifest ├── Properties ├── AssemblyInfo.cs └── Default.rd.xml ├── RfidScanner.csproj ├── StartupTask.cs └── project.json /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /CottonwoodRfidReader/Cottonwood.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Windows.Devices.SerialCommunication; 7 | using Windows.Storage.Streams; 8 | 9 | namespace CottonwoodRfidReader 10 | { 11 | /// 12 | /// The Cottonwood board is communicated with Serially through a 13 | /// byte arrays that represent specific commands. The board also 14 | /// responds in byte arrays. We only use a few commands here. 15 | /// For a full list of available commands and expected byte array 16 | /// responses, please download the following PDF here: 17 | /// https://s3.amazonaws.com/linksprite/cuttonwood/datasheet.pdf 18 | /// 19 | public class Cottonwood 20 | { 21 | private SerialDevice _rfidReader = null; 22 | 23 | //Cottonwood Command Arrays used in this Proof of Concept 24 | private byte[] CMD_TURN_ON_ANTENNA = new byte[] { 0x18, 0x03, 0xFF }; 25 | private byte[] CMD_TURN_OFF_ANTENNA = new byte[] { 0x18, 0x03, 0x00 }; 26 | private byte[] CMD_SET_US_FREQUENCY = new byte[] { 0x41, 0x08, 0x08,0x12,0x26, 0x0e, 0xd8, 0x01 }; 27 | private byte[] CMD_INVENTORY_SCAN = new byte[] { 0x43, 0x03, 0x01 }; 28 | 29 | /// 30 | /// Constructor configures the Serial settings for interfacing 31 | /// with the Cottonwood board 32 | /// 33 | /// Serial device object representing 34 | /// the Cottonwood board 35 | public Cottonwood(SerialDevice device) 36 | { 37 | //configures the serial settings for interfacing with 38 | //the Cottonwood board 39 | _rfidReader = device; 40 | _rfidReader.WriteTimeout = TimeSpan.FromMilliseconds(1000); 41 | _rfidReader.ReadTimeout = TimeSpan.FromMilliseconds(1000); 42 | _rfidReader.BaudRate = 9600; 43 | _rfidReader.Parity = SerialParity.None; 44 | _rfidReader.StopBits = SerialStopBitCount.One; 45 | _rfidReader.DataBits = 8; 46 | } 47 | 48 | /// 49 | /// Turns on antenna 50 | /// 51 | /// Is Successful? 52 | public async Task TurnOnAntenna() 53 | { 54 | return await AntennaPower(CMD_TURN_ON_ANTENNA); 55 | } 56 | 57 | /// 58 | /// Turns off antenna 59 | /// 60 | /// Is Successful? 61 | public async Task TurnOffAntenna() 62 | { 63 | return await AntennaPower(CMD_TURN_OFF_ANTENNA); 64 | } 65 | 66 | /// 67 | /// Turns off hop mode - scans only us frequencies 68 | /// 69 | /// Is Successful? 70 | public async Task ConfigureUnitedStatesFrequency() 71 | { 72 | bool retvalue = false; 73 | byte[] result = await SendCommand(CMD_SET_US_FREQUENCY); 74 | if (result != null) 75 | { 76 | //check for the expected result 77 | if (result.Length > 3 78 | && result[0] == 0x42 79 | && result[1] == 0x40 80 | && result[2] == 0xFE 81 | && result[3] == 0xFF) 82 | { 83 | retvalue = true; 84 | } 85 | } 86 | return retvalue; 87 | } 88 | 89 | /// 90 | /// Performs an inventory scan 91 | /// 92 | /// list of Tag Ids 93 | public async Task> PerformInventoryScan() 94 | { 95 | List retvalue = new List(); 96 | byte[] result = await SendCommand(CMD_INVENTORY_SCAN); 97 | //check for the expected result 98 | if (result != null) 99 | { 100 | if (result.Length > 3 101 | && result[0] == 0x44 102 | ) 103 | { 104 | //determine the number of tags read 105 | int numTags = result[2]; 106 | if (numTags > 0) 107 | { 108 | //collect the id's of the tags read 109 | int arrayIdx = 0; 110 | for (int i = 0; i < numTags; i++) 111 | { 112 | //10 skip bytes (header of the frame) 113 | arrayIdx += 10; 114 | 115 | //12 byte Tag Id 116 | byte[] tagid = new byte[12]; 117 | for (int j = 0; j < 12; j++) 118 | { 119 | tagid[j] = result[arrayIdx]; 120 | arrayIdx += 1; 121 | } 122 | retvalue.Add(tagid); 123 | } 124 | } 125 | } 126 | 127 | } 128 | return retvalue; 129 | } 130 | 131 | /// 132 | /// A method that sends antenna commands and parses the 133 | /// expected response from the Cottonwood 134 | /// 135 | /// command array sent to the Cottonwood 136 | /// Is Successful? 137 | private async Task AntennaPower(byte[] command) 138 | { 139 | bool retvalue = false; 140 | byte[] result = await SendCommand(command); 141 | if (result != null) 142 | { 143 | if (result.Length == 3 144 | && result[0] == 0x19 145 | && result[1] == 0x03 146 | && result[2] == 0x00) 147 | { 148 | retvalue = true; 149 | } 150 | } 151 | return retvalue; 152 | } 153 | 154 | /// 155 | /// Serially writes a command byte array to the Cottonwood board 156 | /// 157 | /// command byte array 158 | /// byte array response from the command obtained from 159 | /// the Cottonwood board 160 | /// 161 | private async Task SendCommand(byte[] command) 162 | { 163 | byte[] retvalue = null; 164 | //send command to the Cottonwood 165 | var writeResult = await Write(command); 166 | if (writeResult.IsSuccessful) 167 | { 168 | //get response from the Cottonwood 169 | var readResult = await Read(); 170 | if (readResult.IsSuccessful) 171 | { 172 | retvalue = readResult.Result; 173 | } 174 | else 175 | { 176 | throw new Exception("Reader did not respond"); 177 | } 178 | } 179 | else 180 | { 181 | throw new Exception("Could not write to the reader"); 182 | } 183 | return retvalue; 184 | } 185 | 186 | /// 187 | /// internal encapsulation of the response read from the Cottonwood 188 | /// after issuing a command 189 | /// 190 | internal class RfidReaderResult 191 | { 192 | public bool IsSuccessful { get; set; } 193 | public byte[] Result { get; set; } 194 | 195 | } 196 | 197 | /// 198 | /// Serial read from the Cottonwood 199 | /// 200 | /// bytes read 201 | private async Task Read() 202 | { 203 | RfidReaderResult retvalue = new RfidReaderResult(); 204 | var dataReader = new DataReader(_rfidReader.InputStream); 205 | try 206 | { 207 | //Awaiting Data from RFID Reader 208 | var numBytesRecvd = await dataReader.LoadAsync(1024); 209 | retvalue.Result = new byte[numBytesRecvd]; 210 | if (numBytesRecvd > 0) 211 | { 212 | //Data successfully read from RFID Reader" 213 | dataReader.ReadBytes(retvalue.Result); 214 | retvalue.IsSuccessful = true; 215 | } 216 | } 217 | catch (Exception ex) 218 | { 219 | retvalue.IsSuccessful = false; 220 | throw ex; 221 | } 222 | finally 223 | { 224 | if (dataReader != null) 225 | { 226 | dataReader.DetachStream(); 227 | dataReader = null; 228 | } 229 | } 230 | return retvalue; 231 | } 232 | 233 | /// 234 | /// Serial write function to the Cottonwood 235 | /// 236 | /// byte array sent to the Cottonwood 237 | /// bytes written and success indicator 238 | private async Task Write(byte[] writeBytes) 239 | { 240 | var dataWriter = new DataWriter(_rfidReader.OutputStream); 241 | RfidReaderResult retvalue = new RfidReaderResult(); 242 | try 243 | { 244 | //send the message 245 | //Writing command to RFID Reader 246 | dataWriter.WriteBytes(writeBytes); 247 | await dataWriter.StoreAsync(); 248 | retvalue.IsSuccessful = true; 249 | retvalue.Result = writeBytes; 250 | //Writing of command has been successful 251 | } 252 | catch (Exception ex) 253 | { 254 | throw ex; 255 | } 256 | finally 257 | { 258 | if (dataWriter != null) 259 | { 260 | dataWriter.DetachStream(); 261 | dataWriter = null; 262 | } 263 | } 264 | return retvalue; 265 | } 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /CottonwoodRfidReader/CottonwoodRfidReader.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A} 8 | Library 9 | Properties 10 | CottonwoodRfidReader 11 | CottonwoodRfidReader 12 | en-US 13 | UAP 14 | 10.0.10240.0 15 | 10.0.10240.0 16 | 14 17 | 512 18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 19 | 20 | 21 | AnyCPU 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 27 | prompt 28 | 4 29 | 30 | 31 | AnyCPU 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE;NETFX_CORE;WINDOWS_UWP 36 | prompt 37 | 4 38 | 39 | 40 | ARM 41 | true 42 | bin\ARM\Debug\ 43 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 44 | ;2008 45 | full 46 | ARM 47 | false 48 | prompt 49 | true 50 | 51 | 52 | ARM 53 | bin\ARM\Release\ 54 | TRACE;NETFX_CORE;WINDOWS_UWP 55 | true 56 | ;2008 57 | pdbonly 58 | ARM 59 | false 60 | prompt 61 | true 62 | 63 | 64 | x64 65 | true 66 | bin\x64\Debug\ 67 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 68 | ;2008 69 | full 70 | x64 71 | false 72 | prompt 73 | true 74 | 75 | 76 | x64 77 | bin\x64\Release\ 78 | TRACE;NETFX_CORE;WINDOWS_UWP 79 | true 80 | ;2008 81 | pdbonly 82 | x64 83 | false 84 | prompt 85 | true 86 | 87 | 88 | x86 89 | true 90 | bin\x86\Debug\ 91 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 92 | ;2008 93 | full 94 | x86 95 | false 96 | prompt 97 | true 98 | 99 | 100 | x86 101 | bin\x86\Release\ 102 | TRACE;NETFX_CORE;WINDOWS_UWP 103 | true 104 | ;2008 105 | pdbonly 106 | x86 107 | false 108 | prompt 109 | true 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | Windows IoT Extensions for the UWP 123 | 124 | 125 | 126 | 14.0 127 | 128 | 129 | 136 | -------------------------------------------------------------------------------- /CottonwoodRfidReader/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("CottonwoodRfidReader")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CottonwoodRfidReader")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /CottonwoodRfidReader/Properties/CottonwoodRfidReader.rd.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /CottonwoodRfidReader/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0" 4 | }, 5 | "frameworks": { 6 | "uap10.0": {} 7 | }, 8 | "runtimes": { 9 | "win10-arm": {}, 10 | "win10-arm-aot": {}, 11 | "win10-x86": {}, 12 | "win10-x86-aot": {}, 13 | "win10-x64": {}, 14 | "win10-x64-aot": {} 15 | } 16 | } -------------------------------------------------------------------------------- /RfidScanner.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RfidScanner", "RfidScanner\RfidScanner.csproj", "{6D83B468-9231-48AC-8EA2-2CF730DE64AD}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CottonwoodRfidReader", "CottonwoodRfidReader\CottonwoodRfidReader.csproj", "{EE1C2577-2317-4E21-8DFF-565C24D6CD5A}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|ARM = Debug|ARM 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|Any CPU = Release|Any CPU 17 | Release|ARM = Release|ARM 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|Any CPU.ActiveCfg = Debug|x86 23 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|ARM.ActiveCfg = Debug|ARM 24 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|ARM.Build.0 = Debug|ARM 25 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|ARM.Deploy.0 = Debug|ARM 26 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|x64.ActiveCfg = Debug|x64 27 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|x64.Build.0 = Debug|x64 28 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|x64.Deploy.0 = Debug|x64 29 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|x86.ActiveCfg = Debug|x86 30 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|x86.Build.0 = Debug|x86 31 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Debug|x86.Deploy.0 = Debug|x86 32 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|Any CPU.ActiveCfg = Release|x86 33 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|ARM.ActiveCfg = Release|ARM 34 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|ARM.Build.0 = Release|ARM 35 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|ARM.Deploy.0 = Release|ARM 36 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|x64.ActiveCfg = Release|x64 37 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|x64.Build.0 = Release|x64 38 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|x64.Deploy.0 = Release|x64 39 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|x86.ActiveCfg = Release|x86 40 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|x86.Build.0 = Release|x86 41 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD}.Release|x86.Deploy.0 = Release|x86 42 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|ARM.ActiveCfg = Debug|ARM 45 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|ARM.Build.0 = Debug|ARM 46 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|x64.ActiveCfg = Debug|x64 47 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|x64.Build.0 = Debug|x64 48 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|x86.ActiveCfg = Debug|x86 49 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Debug|x86.Build.0 = Debug|x86 50 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|ARM.ActiveCfg = Release|ARM 53 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|ARM.Build.0 = Release|ARM 54 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|x64.ActiveCfg = Release|x64 55 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|x64.Build.0 = Release|x64 56 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|x86.ActiveCfg = Release|x86 57 | {EE1C2577-2317-4E21-8DFF-565C24D6CD5A}.Release|x86.Build.0 = Release|x86 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | EndGlobal 63 | -------------------------------------------------------------------------------- /RfidScanner/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /RfidScanner/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /RfidScanner/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /RfidScanner/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /RfidScanner/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /RfidScanner/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/StoreLogo.png -------------------------------------------------------------------------------- /RfidScanner/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codingbandit/RfidScanner/90bad51bda5b123164f73d87174e1937bd4b4b0d/RfidScanner/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /RfidScanner/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | RfidScanner 19 | Carey 20 | Assets\StoreLogo.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /RfidScanner/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RfidScanner")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RfidScanner")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.0.0.0")] 28 | [assembly: AssemblyFileVersion("1.0.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /RfidScanner/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /RfidScanner/RfidScanner.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x86 7 | {6D83B468-9231-48AC-8EA2-2CF730DE64AD} 8 | winmdobj 9 | Properties 10 | RfidScanner 11 | RfidScanner 12 | en-US 13 | UAP 14 | 10.0.10240.0 15 | 10.0.10240.0 16 | 14 17 | true 18 | 512 19 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 20 | false 21 | RfidScanner_TemporaryKey.pfx 22 | true 23 | true 24 | 25 | 26 | true 27 | bin\ARM\Debug\ 28 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 29 | ;2008 30 | full 31 | ARM 32 | false 33 | prompt 34 | true 35 | 36 | 37 | bin\ARM\Release\ 38 | TRACE;NETFX_CORE;WINDOWS_UWP 39 | true 40 | ;2008 41 | pdbonly 42 | ARM 43 | false 44 | prompt 45 | true 46 | true 47 | 48 | 49 | true 50 | bin\x64\Debug\ 51 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 52 | ;2008 53 | full 54 | x64 55 | false 56 | prompt 57 | true 58 | 59 | 60 | bin\x64\Release\ 61 | TRACE;NETFX_CORE;WINDOWS_UWP 62 | true 63 | ;2008 64 | pdbonly 65 | x64 66 | false 67 | prompt 68 | true 69 | true 70 | 71 | 72 | true 73 | bin\x86\Debug\ 74 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 75 | ;2008 76 | full 77 | x86 78 | false 79 | prompt 80 | true 81 | 82 | 83 | bin\x86\Release\ 84 | TRACE;NETFX_CORE;WINDOWS_UWP 85 | true 86 | ;2008 87 | pdbonly 88 | x86 89 | false 90 | prompt 91 | true 92 | true 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | Designer 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | {ee1c2577-2317-4e21-8dff-565c24d6cd5a} 121 | CottonwoodRfidReader 122 | 123 | 124 | 125 | 14.0 126 | 127 | 128 | 135 | -------------------------------------------------------------------------------- /RfidScanner/StartupTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Net.Http; 6 | using Windows.ApplicationModel.Background; 7 | using Windows.System.Threading; 8 | using CottonwoodRfidReader; 9 | using Windows.Devices.SerialCommunication; 10 | using Windows.Devices.Enumeration; 11 | using Windows.Networking.Connectivity; 12 | using System.Threading.Tasks; 13 | using System.Net.Http.Headers; 14 | 15 | // The Background Application template is documented at http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409 16 | 17 | namespace RfidScanner 18 | { 19 | public sealed class StartupTask : IBackgroundTask 20 | { 21 | private BackgroundTaskDeferral _deferral; 22 | private ThreadPoolTimer _timer; 23 | private string _uartBridgeName = "CP2102 USB to UART Bridge Controller"; 24 | private Cottonwood _reader = null; 25 | private string _ipAddress = null; 26 | 27 | public async void Run(IBackgroundTaskInstance taskInstance) 28 | { 29 | //keeps this process alive in the OS 30 | _deferral = taskInstance.GetDeferral(); 31 | 32 | if (SetDeviceIpv4Address()) 33 | { 34 | bool isStartedUp = await ConfigureCottonwood(); 35 | if (isStartedUp) 36 | { 37 | //only kick off timer if everything gets configured properly 38 | //reads will occur every 10 seconds 39 | _timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, TimeSpan.FromMilliseconds(10000)); 40 | } 41 | } 42 | } 43 | 44 | private async void Timer_Tick(ThreadPoolTimer timer) 45 | { 46 | try 47 | { 48 | //perform inventory scan and read available RFID tags 49 | var tagInventory = await _reader.PerformInventoryScan(); 50 | if(tagInventory.Count() > 0) 51 | { 52 | //assemble readings in the expected structure 53 | List readings = new List(); 54 | foreach(var tag in tagInventory) 55 | { 56 | TrackerReadingModel reading = new TrackerReadingModel(); 57 | reading.IpAddress = _ipAddress; 58 | reading.TagId = BitConverter.ToString(tag); 59 | reading.Reading = DateTime.Now; 60 | readings.Add(reading); 61 | } 62 | 63 | //send reading data to the cloud service 64 | using (var client = new HttpClient()) 65 | { 66 | client.BaseAddress = new Uri("http://YOURBASEURL.COM/"); 67 | client.DefaultRequestHeaders.Accept.Clear(); 68 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 69 | var response = await client.PostAsJsonAsync("api/reading/add-multi-readings", readings); 70 | } 71 | } 72 | } 73 | catch (Exception ex) 74 | { 75 | //TODO: Logging of exception 76 | } 77 | } 78 | 79 | /// 80 | /// internal encapsulation class of a reading 81 | /// this is the structure that the ASP.NET Web API 82 | /// service is expecting 83 | /// 84 | internal class TrackerReadingModel 85 | { 86 | public string IpAddress { get; set; } 87 | public string TagId { get; set; } 88 | public DateTime Reading { get; set; } 89 | } 90 | 91 | /// 92 | /// Obtains the IP address of the Raspberry Pi 93 | /// The IP is used to identify the Pi. 94 | /// 95 | /// Is Successful? 96 | private bool SetDeviceIpv4Address() 97 | { 98 | var hostInfo = NetworkInformation.GetHostNames().Where(x => x.Type == Windows.Networking.HostNameType.Ipv4).FirstOrDefault(); 99 | if (hostInfo != null) 100 | { 101 | _ipAddress = hostInfo.RawName; 102 | return true; 103 | } 104 | return false; 105 | } 106 | 107 | /// 108 | /// Retrieves the serial device, instantiates and configures 109 | /// the Cottonwood board. Also turns on the antenna so that 110 | /// the device is ready to perform inventory scans 111 | /// 112 | /// 113 | private async Task ConfigureCottonwood() 114 | { 115 | //Retrieve serial device representing the Cottonwood board 116 | string deviceQuery = SerialDevice.GetDeviceSelector(); 117 | var discovered = await DeviceInformation.FindAllAsync(deviceQuery); 118 | var readerInfo = discovered.Where(x => x.Name == _uartBridgeName).FirstOrDefault(); 119 | if (readerInfo != null) 120 | { 121 | var bridgeDevice = await SerialDevice.FromIdAsync(readerInfo.Id); 122 | if (bridgeDevice != null) 123 | { 124 | //instantiate the Cottonwood with the serial device 125 | _reader = new Cottonwood(bridgeDevice); 126 | bool isAntennaOn = await _reader.TurnOnAntenna(); 127 | if (isAntennaOn) 128 | { 129 | //set us frequency 130 | var isUsFrequency = await _reader.ConfigureUnitedStatesFrequency(); 131 | if (isUsFrequency) 132 | { 133 | return true; 134 | } 135 | } 136 | }//end bridge device retrieved 137 | } //end serial device found 138 | return false; 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /RfidScanner/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.AspNet.WebApi.Client": "5.2.3", 4 | "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0" 5 | }, 6 | "frameworks": { 7 | "uap10.0": {} 8 | }, 9 | "runtimes": { 10 | "win10-arm": {}, 11 | "win10-arm-aot": {}, 12 | "win10-x86": {}, 13 | "win10-x86-aot": {}, 14 | "win10-x64": {}, 15 | "win10-x64-aot": {} 16 | } 17 | } --------------------------------------------------------------------------------