├── .editorconfig ├── .gitignore ├── Common.props ├── LICENSE.md ├── NuGet.config ├── README.md ├── README.zh_cn.md ├── Sandwych.SmartConfig.Demo.sln ├── Sandwych.SmartConfig.sln ├── appveyor.yml ├── assets ├── paypal_button.svg └── wechat_qrcode.png ├── demo ├── Sandwych.SmartConfig.AndroidDemoApp │ ├── Assets │ │ └── AboutAssets.txt │ ├── DeviceListViewAdapter.cs │ ├── DeviceListViewHolder.cs │ ├── MainActivity.cs │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── AboutResources.txt │ │ ├── Resource.designer.cs │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ ├── content_main.xml │ │ │ └── device_list_row.xml │ │ ├── menu │ │ │ └── menu_main.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── Sandwych.SmartConfig.AndroidDemoApp.csproj └── Sandwych.SmartConfig.CliDemoApp │ ├── Program.cs │ └── Sandwych.SmartConfig.CliDemoApp.csproj ├── src └── Sandwych.SmartConfig │ ├── AbstractSmartConfigProvider.cs │ ├── Airkiss │ ├── AirkissOptionNames.cs │ ├── AirkissSmartConfigProvider.cs │ ├── AirkissWellknownConstants.cs │ └── Protocol │ │ ├── AirkissDevicePacketInterpreter.cs │ │ ├── AirkissMagicCodeFrameEncoder.cs │ │ ├── AirkissPrefixCodeFrameEncoder.cs │ │ ├── AirkissProcedureEncoder.cs │ │ └── AirkissSeqEntryFrameEncoder.cs │ ├── Constants.cs │ ├── DeviceDiscoveredEventArgs.cs │ ├── Directory.Build.props │ ├── Esptouch │ ├── EspOptionNames.cs │ ├── EspSmartConfigProvider.cs │ ├── EspWellKnownConstants.cs │ └── Protocol │ │ ├── EspDatumFrameEncoder.cs │ │ ├── EspDevicePacketInterpreter.cs │ │ └── EspProcedureEncoder.cs │ ├── ISmartConfigContextFactory.cs │ ├── ISmartConfigDevice.cs │ ├── ISmartConfigJob.cs │ ├── ISmartConfigProvider.cs │ ├── Networking │ ├── DatagramBroadcaster.cs │ ├── DatagramReceiveResult.cs │ ├── DatagramReceiver.cs │ ├── DefaultDatagramClient.cs │ ├── IDatagramBroadcaster.cs │ ├── IDatagramClient.cs │ └── IDatagramReceiver.cs │ ├── Protocol │ ├── FrameDataConverter.cs │ ├── IDevicePacketInterpreter.cs │ ├── IProcedureEncoder.cs │ └── Segment.cs │ ├── Sandwych.SmartConfig.csproj │ ├── SmartConfigArguments.cs │ ├── SmartConfigContext.cs │ ├── SmartConfigDevice.cs │ ├── SmartConfigExtensions.cs │ ├── SmartConfigJob.cs │ ├── SmartConfigStarter.cs │ ├── SmartConfigTimerEventArgs.cs │ ├── SmartConfigTimerEventHandler.cs │ ├── StandardOptionNames.cs │ └── Util │ ├── AsyncExtensions.cs │ ├── BytesHelper.cs │ ├── Crc.cs │ ├── LinqExtensions.cs │ └── TaskExtensions.cs └── test └── Sandwych.SmartConfig.Test ├── Airkiss └── Protocol │ ├── AirkissDevicePacketInterpreterTests.cs │ ├── AirkissMagicCodeFrameEncoderTests.cs │ ├── AirkissPrefixCodeFrameEncoderTests.cs │ ├── AirkissProcedureEncoderTests.cs │ └── AirkissSeqEntryFrameEncoderTests.cs ├── Esptouch └── Protocol │ ├── EspDatumFrameEncoderTests.cs │ └── EspProcedureEncoderTests.cs ├── Sandwych.SmartConfig.Test.csproj └── Util ├── BytesHelperTests.cs ├── Crc8Tests.cs └── LinqExtensions.cs /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Don't use tabs for indentation. 7 | [*] 8 | indent_style = space 9 | # (Please don't specify an indent_size here; that has too many unintended consequences.) 10 | 11 | # Code files 12 | [*.{cs,csx,vb,vbx}] 13 | indent_size = 4 14 | insert_final_newline = true 15 | charset = utf-8-bom 16 | 17 | # XML project files 18 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] 19 | indent_size = 2 20 | 21 | # XML config files 22 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] 23 | indent_size = 2 24 | 25 | # JSON files 26 | [*.json] 27 | indent_size = 2 28 | 29 | # Powershell files 30 | [*.ps1] 31 | indent_size = 2 32 | 33 | # Shell script files 34 | [*.sh] 35 | end_of_line = lf 36 | indent_size = 2 37 | 38 | # Dotnet code style settings: 39 | [*.{cs,vb}] 40 | 41 | # Sort using and Import directives with System.* appearing first 42 | dotnet_sort_system_directives_first = true 43 | dotnet_separate_import_directive_groups = false 44 | # Avoid "this." and "Me." if not necessary 45 | dotnet_style_qualification_for_field = false:refactoring 46 | dotnet_style_qualification_for_property = false:refactoring 47 | dotnet_style_qualification_for_method = false:refactoring 48 | dotnet_style_qualification_for_event = false:refactoring 49 | 50 | # Use language keywords instead of framework type names for type references 51 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 52 | dotnet_style_predefined_type_for_member_access = true:suggestion 53 | 54 | # Suggest more modern language features when available 55 | dotnet_style_object_initializer = true:suggestion 56 | dotnet_style_collection_initializer = true:suggestion 57 | dotnet_style_coalesce_expression = true:suggestion 58 | dotnet_style_null_propagation = true:suggestion 59 | dotnet_style_explicit_tuple_names = true:suggestion 60 | 61 | # Whitespace options 62 | dotnet_style_allow_multiple_blank_lines_experimental = false 63 | 64 | # Non-private static fields are PascalCase 65 | dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion 66 | dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields 67 | dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style 68 | 69 | dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field 70 | dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected 71 | dotnet_naming_symbols.non_private_static_fields.required_modifiers = static 72 | 73 | dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case 74 | 75 | # Non-private readonly fields are PascalCase 76 | dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.severity = suggestion 77 | dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.symbols = non_private_readonly_fields 78 | dotnet_naming_rule.non_private_readonly_fields_should_be_pascal_case.style = non_private_readonly_field_style 79 | 80 | dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field 81 | dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected 82 | dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly 83 | 84 | dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_case 85 | 86 | # Constants are PascalCase 87 | dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion 88 | dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants 89 | dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style 90 | 91 | dotnet_naming_symbols.constants.applicable_kinds = field, local 92 | dotnet_naming_symbols.constants.required_modifiers = const 93 | 94 | dotnet_naming_style.constant_style.capitalization = pascal_case 95 | 96 | # Static fields are camelCase and start with s_ 97 | dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion 98 | dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields 99 | dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style 100 | 101 | dotnet_naming_symbols.static_fields.applicable_kinds = field 102 | dotnet_naming_symbols.static_fields.required_modifiers = static 103 | 104 | dotnet_naming_style.static_field_style.capitalization = camel_case 105 | dotnet_naming_style.static_field_style.required_prefix = s_ 106 | 107 | # Instance fields are camelCase and start with _ 108 | dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion 109 | dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields 110 | dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style 111 | 112 | dotnet_naming_symbols.instance_fields.applicable_kinds = field 113 | 114 | dotnet_naming_style.instance_field_style.capitalization = camel_case 115 | dotnet_naming_style.instance_field_style.required_prefix = _ 116 | 117 | # Locals and parameters are camelCase 118 | dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion 119 | dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters 120 | dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style 121 | 122 | dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local 123 | 124 | dotnet_naming_style.camel_case_style.capitalization = camel_case 125 | 126 | # Local functions are PascalCase 127 | dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion 128 | dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions 129 | dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style 130 | 131 | dotnet_naming_symbols.local_functions.applicable_kinds = local_function 132 | 133 | dotnet_naming_style.local_function_style.capitalization = pascal_case 134 | 135 | # By default, name items with PascalCase 136 | dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion 137 | dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members 138 | dotnet_naming_rule.members_should_be_pascal_case.style = pascal_case_style 139 | 140 | dotnet_naming_symbols.all_members.applicable_kinds = * 141 | 142 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case 143 | 144 | file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE file in the project root for more information. 145 | 146 | # RS0016: Only enable if API files are present 147 | dotnet_public_api_analyzer.require_api_files = true 148 | 149 | # CSharp code style settings: 150 | [*.cs] 151 | # Newline settings 152 | csharp_new_line_before_open_brace = all 153 | csharp_new_line_before_else = true 154 | csharp_new_line_before_catch = true 155 | csharp_new_line_before_finally = true 156 | csharp_new_line_before_members_in_object_initializers = true 157 | csharp_new_line_before_members_in_anonymous_types = true 158 | csharp_new_line_between_query_expression_clauses = true 159 | 160 | # Indentation preferences 161 | csharp_indent_block_contents = true 162 | csharp_indent_braces = false 163 | csharp_indent_case_contents = true 164 | csharp_indent_case_contents_when_block = true 165 | csharp_indent_switch_labels = true 166 | csharp_indent_labels = flush_left 167 | 168 | # Whitespace options 169 | csharp_style_allow_embedded_statements_on_same_line_experimental = false 170 | csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false 171 | csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false 172 | csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false 173 | csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false 174 | 175 | # Prefer "var" everywhere 176 | csharp_style_var_for_built_in_types = true:suggestion 177 | csharp_style_var_when_type_is_apparent = true:suggestion 178 | csharp_style_var_elsewhere = true:suggestion 179 | 180 | # Prefer method-like constructs to have a block body 181 | csharp_style_expression_bodied_methods = false:none 182 | csharp_style_expression_bodied_constructors = false:none 183 | csharp_style_expression_bodied_operators = false:none 184 | 185 | # Prefer property-like constructs to have an expression-body 186 | csharp_style_expression_bodied_properties = true:none 187 | csharp_style_expression_bodied_indexers = true:none 188 | csharp_style_expression_bodied_accessors = true:none 189 | 190 | # Suggest more modern language features when available 191 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 192 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 193 | csharp_style_inlined_variable_declaration = true:suggestion 194 | csharp_style_throw_expression = true:suggestion 195 | csharp_style_conditional_delegate_call = true:suggestion 196 | csharp_style_prefer_extended_property_pattern = true:suggestion 197 | 198 | # Space preferences 199 | csharp_space_after_cast = false 200 | csharp_space_after_colon_in_inheritance_clause = true 201 | csharp_space_after_comma = true 202 | csharp_space_after_dot = false 203 | csharp_space_after_keywords_in_control_flow_statements = true 204 | csharp_space_after_semicolon_in_for_statement = true 205 | csharp_space_around_binary_operators = before_and_after 206 | csharp_space_around_declaration_statements = do_not_ignore 207 | csharp_space_before_colon_in_inheritance_clause = true 208 | csharp_space_before_comma = false 209 | csharp_space_before_dot = false 210 | csharp_space_before_open_square_brackets = false 211 | csharp_space_before_semicolon_in_for_statement = false 212 | csharp_space_between_empty_square_brackets = false 213 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 214 | csharp_space_between_method_call_name_and_opening_parenthesis = false 215 | csharp_space_between_method_call_parameter_list_parentheses = false 216 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 217 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 218 | csharp_space_between_method_declaration_parameter_list_parentheses = false 219 | csharp_space_between_parentheses = false 220 | csharp_space_between_square_brackets = false 221 | 222 | # Blocks are allowed 223 | csharp_prefer_braces = true:silent 224 | csharp_preserve_single_line_blocks = true 225 | csharp_preserve_single_line_statements = true 226 | 227 | # IDE0060: Remove unused parameter 228 | dotnet_diagnostic.IDE0060.severity = warning 229 | 230 | [src/{Compilers,ExpressionEvaluator,Scripting}/**Test**/*.{cs,vb}] 231 | 232 | # IDE0060: Remove unused parameter 233 | dotnet_diagnostic.IDE0060.severity = none 234 | 235 | [src/{Analyzers,CodeStyle,Features,Workspaces,EditorFeatures,VisualStudio}/**/*.{cs,vb}] 236 | 237 | # IDE0011: Add braces 238 | csharp_prefer_braces = when_multiline:warning 239 | # NOTE: We need the below severity entry for Add Braces due to https://github.com/dotnet/roslyn/issues/44201 240 | dotnet_diagnostic.IDE0011.severity = warning 241 | 242 | # IDE0040: Add accessibility modifiers 243 | dotnet_diagnostic.IDE0040.severity = warning 244 | 245 | # IDE0052: Remove unread private member 246 | dotnet_diagnostic.IDE0052.severity = warning 247 | 248 | # IDE0059: Unnecessary assignment to a value 249 | dotnet_diagnostic.IDE0059.severity = warning 250 | 251 | # CA1012: Abstract types should not have public constructors 252 | dotnet_diagnostic.CA1012.severity = warning 253 | 254 | # CA1822: Make member static 255 | dotnet_diagnostic.CA1822.severity = warning 256 | 257 | # Prefer "var" everywhere 258 | dotnet_diagnostic.IDE0007.severity = warning 259 | csharp_style_var_for_built_in_types = true:warning 260 | csharp_style_var_when_type_is_apparent = true:warning 261 | csharp_style_var_elsewhere = true:warning 262 | 263 | # csharp_style_allow_embedded_statements_on_same_line_experimental 264 | dotnet_diagnostic.IDE2001.severity = warning 265 | 266 | # csharp_style_allow_blank_lines_between_consecutive_braces_experimental 267 | dotnet_diagnostic.IDE2002.severity = warning 268 | 269 | # csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental 270 | dotnet_diagnostic.IDE2004.severity = warning 271 | 272 | # csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental 273 | dotnet_diagnostic.IDE2005.severity = warning 274 | 275 | # csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental 276 | dotnet_diagnostic.IDE2006.severity = warning 277 | 278 | [src/{VisualStudio}/**/*.{cs,vb}] 279 | # CA1822: Make member static 280 | # There is a risk of accidentally breaking an internal API that partners rely on though IVT. 281 | dotnet_code_quality.CA1822.api_surface = private 282 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # Visual Studio (>=2015) project-specific, machine local files 5 | .vs/ 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.sln.docstates 11 | *.userprefs 12 | 13 | # ignore Xamarin.Android Resource.Designer.cs files 14 | **/*.Droid/**/[Rr]esource.[Dd]esigner.cs 15 | **/*.Android/**/[Rr]esource.[Dd]esigner.cs 16 | **/Android/**/[Rr]esource.[Dd]esigner.cs 17 | **/Droid/**/[Rr]esource.[Dd]esigner.cs 18 | 19 | # Xamarin Components 20 | Components/ 21 | 22 | # Build results 23 | [Dd]ebug/ 24 | [Dd]ebugPublic/ 25 | [Rr]elease/ 26 | x64/ 27 | build/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | #NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 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 addin-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 | _NCrunch_* 109 | .*crunch*.local.xml 110 | 111 | # MightyMoose 112 | *.mm.* 113 | AutoTest.Net/ 114 | 115 | # Web workbench (sass) 116 | .sass-cache/ 117 | 118 | # Installshield output folder 119 | [Ee]xpress/ 120 | 121 | # DocProject is a documentation generator add-in 122 | DocProject/buildhelp/ 123 | DocProject/Help/*.HxT 124 | DocProject/Help/*.HxC 125 | DocProject/Help/*.hhc 126 | DocProject/Help/*.hhk 127 | DocProject/Help/*.hhp 128 | DocProject/Help/Html2 129 | DocProject/Help/html 130 | 131 | # Click-Once directory 132 | publish/ 133 | 134 | # Publish Web Output 135 | *.[Pp]ublish.xml 136 | *.azurePubxml 137 | 138 | # NuGet Packages Directory 139 | packages/ 140 | *.nuget.targets 141 | *.lock.json 142 | *.nuget.props 143 | 144 | ## TODO: If the tool you use requires repositories.config uncomment the next line 145 | #!packages/repositories.config 146 | 147 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 148 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 149 | !packages/build/ 150 | 151 | # Windows Azure Build Output 152 | csx/ 153 | *.build.csdef 154 | 155 | # Windows Store app package directory 156 | AppPackages/ 157 | 158 | # Others 159 | sql/ 160 | *.Cache 161 | ClientBin/ 162 | [Ss]tyle[Cc]op.* 163 | ~$* 164 | *~ 165 | *.dbmdl 166 | *.dbproj.schemaview 167 | *.pfx 168 | *.publishsettings 169 | node_modules/ 170 | .DS_Store 171 | *.bak 172 | 173 | # RIA/Silverlight projects 174 | Generated_Code/ 175 | 176 | # Backup & report files from converting an old project file to a newer 177 | # Visual Studio version. Backup files are not needed, because we have git ;-) 178 | _UpgradeReport_Files/ 179 | Backup*/ 180 | UpgradeLog*.XML 181 | UpgradeLog*.htm 182 | 183 | # SQL Server files 184 | *.mdf 185 | *.ldf 186 | 187 | # Business Intelligence projects 188 | *.rdl.data 189 | *.bim.layout 190 | *.bim_*.settings 191 | 192 | # Microsoft Fakes 193 | FakesAssemblies/ 194 | 195 | .vscode/settings.json 196 | 197 | -------------------------------------------------------------------------------- /Common.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Li 'oldrev' Wei 5 | Li Wei 6 | true 7 | portable 8 | false 9 | false 10 | false 11 | false 12 | false 13 | false 14 | false 15 | true 16 | 0 17 | 1.1.1.$(BuildNumber) 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2014 Sandwych.SmartConfig contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status](https://ci.appveyor.com/api/projects/status/y4vy6qr9k0xj8e7y/branch/master?svg=true)](https://ci.appveyor.com/project/oldrev/sandwych-smartconfig/branch/master) 2 | [![NuGet](https://img.shields.io/nuget/v/Sandwych.SmartConfig.svg)](https://www.nuget.org/packages/Sandwych.SmartConfig) 3 | 4 | # Sandwych.SmartConfig 5 | 6 | Sandwych.SmartConfig is a pure C# implementation of various WiFi SmartConfig protocols that build from scratch. 7 | 8 | TD;LR: If you working on a Xamarin mobile app to deal with WiFi-capability IoT devices, you may need this library. 9 | 10 | English | [简体中文](README.zh_cn.md) 11 | 12 | ## Getting Started 13 | 14 | ## Features 15 | 16 | * A .NET Standard class library, works on both Xamarin and desktop. 17 | * No third-party library referenced. 18 | * Supported protocols: WeChat's AirKiss and Espressif's ESPTouch. 19 | * Clean architecture, easy to learn and add your own protocol. 20 | * IoC container friendly. 21 | 22 | ## Getting Started 23 | 24 | ### Prerequisites 25 | 26 | * Microsoft Visual Studio 2019 27 | * DocFX for API documents generation (Optional) 28 | 29 | ### Supported Platforms 30 | 31 | * .NET Standard 2.0+ 32 | 33 | ### Installation 34 | 35 | Install Sandwych.SmartConfig to your project by [NuGet](https://www.nuget.org/packages/Sandwych.SmartConfig) then you're good to go. 36 | 37 | ## Examples 38 | 39 | ### Usage 40 | 41 | ```csharp 42 | 43 | var provider = new EspSmartConfigProvider(); 44 | var ctx = provider.CreateContext(); 45 | 46 | ctx.DeviceDiscoveredEvent += (s, e) => { 47 | Console.WriteLine("Found device: IP={0} MAC={1}", e.Device.IPAddress, e.Device.MacAddress); 48 | }; 49 | 50 | var scArgs = new SmartConfigArguments() 51 | { 52 | Ssid = "YourWiFiSSID", 53 | Bssid = PhysicalAddress.Parse("10-10-10-10-10-10"), 54 | Password = "YourWiFiPassword", 55 | 56 | // Your local IP address of WiFi network. It's important for using multiple network interfaces 57 | // See CliDemoApp for details. 58 | LocalAddress = IPAddress.Parse("192.168.1.10") 59 | }; 60 | 61 | // Do the SmartConfig job 62 | using (var job = new SmartConfigJob(TimeSpan.FromSeconds(100))) // Set the timeout to 100 seconds 63 | { 64 | await job.ExecuteAsync(ctx, scArgs); 65 | } 66 | 67 | ``` 68 | 69 | Or much simpler if you perfer the callback style: 70 | 71 | ```csharp 72 | 73 | await SmartConfigStarter.StartAsync(args, 74 | onDeviceDiscovered: (s, e) => Console.WriteLine("Found device: IP={0} MAC={1}", e.Device.IPAddress, e.Device.MacAddress)); 75 | 76 | ``` 77 | 78 | ### The Demo Android App 79 | 80 | APK Download: WIP 81 | 82 | ## Donation 83 | 84 | If this project is useful to you, you can buy me a beer: 85 | 86 | [![Support via PayPal.me](https://github.com/oldrev/sandwych-smartconfig/blob/master/assets/paypal_button.svg)](https://www.paypal.me/oldrev) 87 | 88 | ## Contributiors 89 | 90 | * **Li "oldrev" Wei** - *Init work and the main maintainer* - [oldrev](https://github.com/oldrev) 91 | 92 | ## License 93 | 94 | Licensed under the MIT License. Copyright © Sandwych.SmartConfig Contributors. 95 | 96 | See [LICENSE.md](LICENSE.md) for details. 97 | 98 | ## Credits 99 | 100 | * Espressif EsptouchForAndroid: https://github.com/EspressifApp/EsptouchForAndroid 101 | -------------------------------------------------------------------------------- /README.zh_cn.md: -------------------------------------------------------------------------------- 1 | [![构建状态](https://ci.appveyor.com/api/projects/status/TODO?svg=true)](https://ci.appveyor.com/project/oldrev/sandwych-smartconfig) 2 | [![NuGet](https://img.shields.io/nuget/v/Sandwych.SmartConfig.svg)](https://www.nuget.org/packages/Sandwych.SmartConfig) 3 | 4 | # Sandwych.SmartConfig 5 | 6 | 一个从零开始实现的微信 AirKiss 和乐鑫 ESPTouch 的 WiFi SmartConfig 配网功能库。 7 | 8 | [English](README.md) | 简体中文 9 | 10 | 11 | ## 特性 12 | 13 | * 使用纯 C# 和 .NET BCL 的 `UDPClient` 类实现,不依赖设备厂家或其他的第三方包,可同时用于 Xamarin 手机 App 或桌面; 14 | * 目前支持的协议:AirKiss、ESPTouch; 15 | * 配网速度快,兼容性好; 16 | * 设计清晰可扩展,可自行增加其他协议,也可参考本项目编写其他语言的 AirKiss 和 ESPTouch 实现; 17 | * IoC 容器友好; 18 | * 纯异步设计 19 | 20 | 一般来说,如果你想用 .NET 的 Xamarin 开发涉及 WiFi 物联网设备的手机 App,那 Sandwych.SmartConfig 是你必须会用到的。 21 | 22 | ## 快速上手 23 | 24 | 25 | ### 前置需求 26 | 27 | * Microsoft Visual Studio 2019(免费社区版即可) 28 | * DocFX 用于生成 API 文档(可选) 29 | 30 | ### 支持平台 31 | 32 | * .NET Standard 2.0+ 33 | 34 | ### 安装 35 | 36 | 把 Sandwych.SmartConfig 通过 **[NuGet](https://www.nuget.org/packages/Sandwych.SmartConfig)** 安装到你的项目中即可使用。 37 | 38 | ## 例子 39 | 40 | ### 简单调用本库进行配网 41 | 42 | 以 ESPTouch 协议为例: 43 | 44 | ```csharp 45 | 46 | var provider = new EspSmartConfigProvider(); 47 | var ctx = provider.CreateContext(); 48 | 49 | // 设备通过 UDP 广播回报 IP 以后引发此事件,注意同一个设备 IP 只会触发一次 50 | ctx.DeviceDiscoveredEvent += (s, e) => { 51 | // 这里如果涉及更新 GUI 的话需要同步到主线程 52 | Console.WriteLine("Found device: IP={0} MAC={1}", e.Device.IPAddress, e.Device.MacAddress); 53 | }; 54 | 55 | // 设置配网参数 56 | var scArgs = new SmartConfigArguments() 57 | { 58 | Ssid = "YourWiFiSSID", // 路由器 SSID 59 | Bssid = PhysicalAddress.Parse("10-10-10-10-10-10"), // WiFi 路由器 BSSID,ESPTouch 协议需要,Airkiss 协议不需要 60 | Password = "YourWiFiPassword", // WiFi 路由器密码 61 | 62 | // 手机/PC 的本机 IP,如果有多个网卡,这里必须是 WiFi 网络的本机 IP 63 | // 获取本机 WiFi IP 可参见 CliDemoApp 演示程序 64 | LocalAddress = IPAddress.Parse("192.168.1.10") 65 | }; 66 | 67 | // 调用 SmartConfigJob 进行实际的配网 68 | using (var job = new SmartConfigJob(TimeSpan.FromSeconds(100))) // 设置最长配网时间 100秒 69 | { 70 | await job.ExecuteAsync(ctx, scArgs); 71 | } 72 | 73 | ``` 74 | 75 | 使用回调风格更加简单: 76 | 77 | ```csharp 78 | 79 | await SmartConfigStarter.StartAsync(args, 80 | onDeviceDiscovered: (s, e) => Console.WriteLine("Found device: IP={0} MAC={1}", e.Device.IPAddress, e.Device.MacAddress)); 81 | 82 | ``` 83 | 84 | ### 使用例子程序 85 | 86 | 本项目包括了一个通用的 Xamarin.Android 配网程序作为例子,可自行编译运行,也可直接下载编译好的 `.APK` 安装测试: 87 | 88 | APK 下载地址: TODO 89 | 90 | ## 支持本项目 91 | 92 | 假如本项目对你有用,可以考虑请我喝杯啤酒: 93 | 94 | 微信打赏二维码: 95 | 96 | ![微信](https://github.com/oldrev/sandwych-smartconfig/blob/master/assets/wechat_qrcode.png) 97 | 98 | 99 | * BTW 如果你需要在本项目贡献者处留名,打赏时请备注。 100 | 101 | 当然,也非常欢迎你测试提交 bug、贡献代码、帮其他用户解决问题、编写文档,这些都是金钱不能衡量的。 102 | 103 | ## 贡献者 104 | 105 | * **李维** - *初始开发及现维护者* - [oldrev](https://github.com/oldrev) 106 | 107 | ## 授权协议 108 | 109 | 版权所有 © Sandwych.SmartConfig 贡献者。 110 | 111 | 本项目使用 MIT 协议授权,详情见: [LICENSE.md](LICENSE.md)。 112 | 113 | ## 致谢 114 | 115 | * 乐鑫 EsptouchForAndroid: https://github.com/EspressifApp/EsptouchForAndroid 116 | -------------------------------------------------------------------------------- /Sandwych.SmartConfig.Demo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29926.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandwych.SmartConfig", "src\Sandwych.SmartConfig\Sandwych.SmartConfig.csproj", "{147CCAF3-F2DC-4D48-ACC5-7082D7DE7BF6}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandwych.SmartConfig.AndroidDemoApp", "demo\Sandwych.SmartConfig.AndroidDemoApp\Sandwych.SmartConfig.AndroidDemoApp.csproj", "{4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandwych.SmartConfig.CliDemoApp", "demo\Sandwych.SmartConfig.CliDemoApp\Sandwych.SmartConfig.CliDemoApp.csproj", "{5CBEA915-C15F-4074-8850-ACB0B9EB94F8}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {147CCAF3-F2DC-4D48-ACC5-7082D7DE7BF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {147CCAF3-F2DC-4D48-ACC5-7082D7DE7BF6}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {147CCAF3-F2DC-4D48-ACC5-7082D7DE7BF6}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {147CCAF3-F2DC-4D48-ACC5-7082D7DE7BF6}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 25 | {4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {4B7AA7C1-C490-4E29-A8B5-AF6E42F55F99}.Release|Any CPU.Deploy.0 = Release|Any CPU 28 | {5CBEA915-C15F-4074-8850-ACB0B9EB94F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {5CBEA915-C15F-4074-8850-ACB0B9EB94F8}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {5CBEA915-C15F-4074-8850-ACB0B9EB94F8}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {5CBEA915-C15F-4074-8850-ACB0B9EB94F8}.Release|Any CPU.Build.0 = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | GlobalSection(ExtensibilityGlobals) = postSolution 37 | SolutionGuid = {2DE497AB-6AEF-4839-B02E-F8ADECFE4027} 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /Sandwych.SmartConfig.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33213.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandwych.SmartConfig", "src\Sandwych.SmartConfig\Sandwych.SmartConfig.csproj", "{E851B517-D7A0-417E-BCB9-492081B26E6F}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandwych.SmartConfig.Test", "test\Sandwych.SmartConfig.Test\Sandwych.SmartConfig.Test.csproj", "{3022E137-2800-4BC5-962A-190E7DB47E3A}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3F6D0B71-67C9-4BA3-8C15-63DC63D36612}" 11 | ProjectSection(SolutionItems) = preProject 12 | .editorconfig = .editorconfig 13 | Common.props = Common.props 14 | LICENSE.md = LICENSE.md 15 | README.md = README.md 16 | README.zh_cn.md = README.zh_cn.md 17 | EndProjectSection 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Release|Any CPU = Release|Any CPU 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {E851B517-D7A0-417E-BCB9-492081B26E6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {E851B517-D7A0-417E-BCB9-492081B26E6F}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {E851B517-D7A0-417E-BCB9-492081B26E6F}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {E851B517-D7A0-417E-BCB9-492081B26E6F}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {3022E137-2800-4BC5-962A-190E7DB47E3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {3022E137-2800-4BC5-962A-190E7DB47E3A}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {3022E137-2800-4BC5-962A-190E7DB47E3A}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {3022E137-2800-4BC5-962A-190E7DB47E3A}.Release|Any CPU.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | GlobalSection(SolutionProperties) = preSolution 35 | HideSolutionNode = FALSE 36 | EndGlobalSection 37 | GlobalSection(ExtensibilityGlobals) = postSolution 38 | SolutionGuid = {C19C547C-046A-4F18-B697-8B4E43F6438B} 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2019 2 | 3 | # Do not build feature branch with open Pull Requests 4 | skip_branch_with_pr: true 5 | branches: 6 | only: 7 | - master 8 | - dev 9 | - release 10 | 11 | init: 12 | - git config --global core.autocrlf true 13 | install: 14 | - ps: $env:BuildNumber= $env:APPVEYOR_BUILD_NUMBER 15 | - ps: $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = true 16 | - ps: $env:NUGET_XMLDOC_MODE = "skip" 17 | - ps: $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 18 | - ps: $IsReleaseBranch = ($env:APPVEYOR_REPO_BRANCH -eq "master" -Or $env:APPVEYOR_REPO_BRANCH -eq "release") 19 | build_script: 20 | # Ensure we are not using the myget feed for dependencies 21 | - dotnet --version 22 | - dotnet pack Sandwych.SmartConfig.sln -c Release 23 | test_script: 24 | - dotnet test .\test\Sandwych.SmartConfig.Test\Sandwych.SmartConfig.Test.csproj -c Release 25 | artifacts: 26 | - path: 'src\**\*.nupkg' 27 | deploy: 28 | - provider: NuGet 29 | on: 30 | branch: release 31 | server: https://www.nuget.org/api/v2/package 32 | api_key: 33 | secure: 76dWrCJVCm1+cBO+WmjmZIvpAw7sf416N/UJWHMbshmC7BOBabuC4Mm6PP2MWdGk 34 | skip_symbols: true 35 | artifact: /.*\.nupkg/ 36 | - provider: NuGet 37 | on: 38 | branch: master 39 | server: https://www.nuget.org/api/v2/package 40 | api_key: 41 | secure: 76dWrCJVCm1+cBO+WmjmZIvpAw7sf416N/UJWHMbshmC7BOBabuC4Mm6PP2MWdGk 42 | skip_symbols: true 43 | artifact: /.*\.nupkg/ 44 | -------------------------------------------------------------------------------- /assets/paypal_button.svg: -------------------------------------------------------------------------------- 1 | Support via PayPal -------------------------------------------------------------------------------- /assets/wechat_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/assets/wechat_qrcode.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/DeviceListViewAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Android.App; 7 | using Android.Content; 8 | using Android.OS; 9 | using Android.Runtime; 10 | using Android.Views; 11 | using Android.Widget; 12 | 13 | namespace Sandwych.SmartConfig.AndroidDemoApp 14 | { 15 | public class DeviceListViewAdapter : BaseAdapter 16 | { 17 | private readonly IList _devices; 18 | 19 | public DeviceListViewAdapter(IList devices) 20 | { 21 | _devices = devices; 22 | } 23 | 24 | public override ISmartConfigDevice this[int position] => _devices[position]; 25 | 26 | public override int Count => throw new NotImplementedException(); 27 | 28 | public override long GetItemId(int position) => position; 29 | 30 | public override View GetView(int position, View convertView, ViewGroup parent) 31 | { 32 | var view = convertView; 33 | 34 | if (view == null) 35 | { 36 | view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.device_list_row, parent, false); 37 | 38 | /* 39 | var image = view.FindViewById(Resource.Id.photoImageView); 40 | var name = view.FindViewById(Resource.Id.ipad); 41 | var department = view.FindViewById(Resource.Id.departmentTextView); 42 | 43 | view.Tag = new DeviceListViewHolder() 44 | { 45 | Image = image, 46 | Name = name, 47 | Department = department 48 | }; 49 | var holder = (DeviceListViewHolder)view.Tag; 50 | holder.Photo.SetImageDrawable(ImageManager.Get(parent.Context, users[position].ImageUrl)); 51 | holder.Name.Text = users[position].Name; 52 | holder.Department.Text = users[position].Department; 53 | return view; 54 | */ 55 | } 56 | 57 | return view; 58 | } 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/DeviceListViewHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | using Android.App; 7 | using Android.Content; 8 | using Android.OS; 9 | using Android.Runtime; 10 | using Android.Views; 11 | using Android.Widget; 12 | 13 | namespace Sandwych.SmartConfig.AndroidDemoApp 14 | { 15 | public class DeviceListViewHolder 16 | { 17 | public ImageView Image { get; set; } 18 | public TextView IPAddressView { get; set; } 19 | public TextView MacAddressView { get; set; } 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Android.App; 4 | using Android.OS; 5 | using Android.Runtime; 6 | using Android.Support.Design.Widget; 7 | using Android.Support.V7.App; 8 | using Android.Views; 9 | using Android.Widget; 10 | 11 | namespace Sandwych.SmartConfig.AndroidDemoApp 12 | { 13 | [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)] 14 | public class MainActivity : AppCompatActivity 15 | { 16 | private readonly List _devices = new List(); 17 | private ListView _deviceListView; 18 | 19 | protected override void OnCreate(Bundle savedInstanceState) 20 | { 21 | base.OnCreate(savedInstanceState); 22 | Xamarin.Essentials.Platform.Init(this, savedInstanceState); 23 | SetContentView(Resource.Layout.activity_main); 24 | 25 | Android.Support.V7.Widget.Toolbar toolbar = FindViewById(Resource.Id.toolbar); 26 | SetSupportActionBar(toolbar); 27 | 28 | _deviceListView = this.FindViewById(Resource.Id.deviceListView); 29 | _deviceListView.Adapter = new DeviceListViewAdapter(_devices); 30 | 31 | FloatingActionButton fab = FindViewById(Resource.Id.fab); 32 | fab.Click += FabOnClick; 33 | } 34 | 35 | public override bool OnCreateOptionsMenu(IMenu menu) 36 | { 37 | MenuInflater.Inflate(Resource.Menu.menu_main, menu); 38 | return true; 39 | } 40 | 41 | public override bool OnOptionsItemSelected(IMenuItem item) 42 | { 43 | int id = item.ItemId; 44 | if (id == Resource.Id.action_settings) 45 | { 46 | return true; 47 | } 48 | 49 | return base.OnOptionsItemSelected(item); 50 | } 51 | 52 | private void FabOnClick(object sender, EventArgs eventArgs) 53 | { 54 | View view = (View) sender; 55 | Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong) 56 | .SetAction("Action", (Android.Views.View.IOnClickListener)null).Show(); 57 | } 58 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) 59 | { 60 | Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); 61 | 62 | base.OnRequestPermissionsResult(requestCode, permissions, grantResults); 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using Android.App; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("Sandwych.SmartConfig.AndroidDemoApp")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("Sandwych.SmartConfig.AndroidDemoApp")] 14 | [assembly: AssemblyCopyright("Copyright © 2018")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: ComVisible(false)] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | [assembly: AssemblyVersion("1.0.0.0")] 26 | [assembly: AssemblyFileVersion("1.0.0.0")] 27 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.xml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.xml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.xml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 18 | 24 | 29 | 34 | 39 | 40 | 41 | 42 | 45 | 51 | 58 | 59 | 60 | 63 | 69 | 76 | 77 | 78 | 81 | 89 | 90 | 91 | 92 | 93 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/layout/device_list_row.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oldrev/sandwych-smartconfig/c7cf59d4e21ef450f7b06abbebe137d40d1eb162/demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2c3e50 4 | #1B3147 5 | #3498db 6 | 7 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 16dp 3 | 4 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2C3E50 4 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | WiFi SmartConfig Demo App 3 | Settings 4 | 5 | -------------------------------------------------------------------------------- /demo/Sandwych.SmartConfig.AndroidDemoApp/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |