浏览代码

added ability to upload new firmware from the browser.

Sebastien 5 年之前
父节点
当前提交
8c3a52d40c

+ 1 - 7
.cproject

@@ -199,12 +199,6 @@
             			
             <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291" moduleId="org.eclipse.cdt.core.settings" name="recovery_windows">
                 				
-                <macros>
-                    					
-                    <stringMacro name="RECOVERY_APPLICATION" type="VALUE_TEXT" value="1"/>
-                    				
-                </macros>
-                				
                 <externalSettings/>
                 				
                 <extensions>
@@ -239,7 +233,7 @@
                             							
                             <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1831977109" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
                             							
-                            <builder arguments="&quot;c:/msys32/opt/esp-idf/tools/windows/eclipse_make.py&quot;  EXTRA_CPPFLAGS='-DRECOVERY_APPLICATION=${RECOVERY_APPLICATION}'" buildPath="${workspace_loc:/squeezelite-esp32}" command="python" id="cdt.managedbuild.builder.gnu.cross.1069921467" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
+                            <builder arguments="&quot;c:/msys32/opt/esp-idf/tools/windows/eclipse_make.py&quot;" buildPath="${workspace_loc:/squeezelite-esp32}" command="python" enabledIncrementalBuild="true" id="cdt.managedbuild.builder.gnu.cross.1069921467" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" stopOnErr="false" superClass="cdt.managedbuild.builder.gnu.cross"/>
                             							
                             <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1302011176" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
                                 								

+ 4 - 4
.settings/language.settings.xml

@@ -5,7 +5,7 @@
         		
         <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
             			
-            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+            <provider class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" name="CDT User Setting Entries" prefer-non-shared="true"/>
             			
             <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
             			
@@ -29,7 +29,7 @@
         		
         <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
             			
-            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+            <provider class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" name="CDT User Setting Entries" prefer-non-shared="true"/>
             			
             <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
             			
@@ -53,7 +53,7 @@
         		
         <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
             			
-            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+            <provider class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" name="CDT User Setting Entries" prefer-non-shared="true"/>
             			
             <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
             			
@@ -77,7 +77,7 @@
         		
         <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
             			
-            <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+            <provider class="org.eclipse.cdt.core.language.settings.providers.LanguageSettingsGenericProvider" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider" name="CDT User Setting Entries" prefer-non-shared="true"/>
             			
             <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
             			

+ 89 - 0
.settings/org.eclipse.cdt.codan.core.prefs

@@ -0,0 +1,89 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
+org.eclipse.cdt.codan.internal.checkers.CStyleCastProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.CStyleCastProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"C-Style cast instead of C++ cast\\")"}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.CopyrightProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.CopyrightProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Lack of copyright information\\")",regex\=>".*Copyright.*"}
+org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
+org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.GotoStatementProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.GotoStatementProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Goto statement used\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.MissCaseProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MissCaseProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing cases in switch\\")"}
+org.eclipse.cdt.codan.internal.checkers.MissDefaultProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.MissDefaultProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Missing default in switch\\")",defaultWithAllEnums\=>false}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.UsingInHeaderProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.UsingInHeaderProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Using directive in header\\")"}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.VirtualMethodCallProblem=-Error
+org.eclipse.cdt.codan.internal.checkers.VirtualMethodCallProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Virtual method call in constructor/destructor\\")"}
+org.eclipse.cdt.qt.core.qtproblem=Warning
+org.eclipse.cdt.qt.core.qtproblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_ON_FILE_OPEN\=>true,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>null}

+ 12 - 0
.settings/org.eclipse.cdt.core.prefs

@@ -27,6 +27,9 @@ environment/project/cdt.managedbuild.toolchain.gnu.cross.base.1476804786/appendC
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/BATCH_BUILD/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/BATCH_BUILD/operation=append
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/BATCH_BUILD/value=1
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/EXTRA_CPPFLAGS/delimiter=;
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/EXTRA_CPPFLAGS/operation=append
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/EXTRA_CPPFLAGS/value=-DRECOVERY_APPLICATION\=0
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/IDF_PATH/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/IDF_PATH/operation=replace
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291.395881736/IDF_PATH/value=C\:/msys32/opt/esp-idf
@@ -44,6 +47,9 @@ environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.16039962
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/BATCH_BUILD/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/BATCH_BUILD/operation=append
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/BATCH_BUILD/value=1
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/EXTRA_CPPFLAGS/delimiter=;
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/EXTRA_CPPFLAGS/operation=replace
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/EXTRA_CPPFLAGS/value=-DRECOVERY_APPLICATION\=1
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/IDF_PATH/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/IDF_PATH/operation=replace
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.1603996291/IDF_PATH/value=C\:/msys32/opt/esp-idf
@@ -61,6 +67,9 @@ environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.16039962
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/BATCH_BUILD/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/BATCH_BUILD/operation=append
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/BATCH_BUILD/value=1
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/EXTRA_CPPFLAGS/delimiter=;
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/EXTRA_CPPFLAGS/operation=append
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/EXTRA_CPPFLAGS/value=-DRECOVERY_APPLICATION\=1
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/IDF_PATH/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/IDF_PATH/operation=append
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.839256934/IDF_PATH/value=/var/opt/esp-idf/
@@ -78,6 +87,9 @@ environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348.83925693
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/BATCH_BUILD/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/BATCH_BUILD/operation=append
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/BATCH_BUILD/value=1
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/EXTRA_CPPFLAGS/delimiter=;
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/EXTRA_CPPFLAGS/operation=append
+environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/EXTRA_CPPFLAGS/value=-DRECOVERY_APPLICATION\=0
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/IDF_PATH/delimiter=\:
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/IDF_PATH/operation=append
 environment/project/cdt.managedbuild.toolchain.gnu.cross.base.293933348/IDF_PATH/value=/var/opt/esp-idf/

+ 3 - 1
components/config/config.h

@@ -12,7 +12,9 @@ extern "C" {
 #endif
 #define DECLARE_SET_DEFAULT(t) void config_set_default_## t (const char *key, t  value);
 #define DECLARE_GET_NUM(t) esp_err_t config_get_## t (const char *key, t *  value);
-
+#ifndef FREE_RESET
+#define FREE_RESET(p) if(p!=NULL) { free(p); p=NULL; }
+#endif
 
 DECLARE_SET_DEFAULT(uint8_t);
 DECLARE_SET_DEFAULT(uint16_t);

+ 3 - 2
components/squeezelite-ota/cmd_ota.c

@@ -17,6 +17,7 @@
 #include "esp_system.h"
 #include "esp_sleep.h"
 #include "esp_spi_flash.h"
+#include "squeezelite-ota.h"
 #include "driver/rtc_io.h"
 #include "driver/uart.h"
 #include "argtable3/argtable3.h"
@@ -27,7 +28,7 @@
 #include "sdkconfig.h"
 
 static const char * TAG = "ota";
-extern esp_err_t start_ota(const char * bin_url);
+
 static struct {
     struct arg_str *url;
     struct arg_end *end;
@@ -45,7 +46,7 @@ static int perform_ota_update(int argc, char **argv)
 
     esp_err_t err=ESP_OK;
     ESP_LOGI(TAG, "Starting ota: %s", url);
-    start_ota(url);
+    start_ota(url, NULL, 0);
 
     if (err != ESP_OK) {
         ESP_LOGE(TAG, "%s", esp_err_to_name(err));

+ 150 - 93
components/squeezelite-ota/squeezelite-ota.c

@@ -32,20 +32,38 @@
 #include "esp_ota_ops.h"
 extern const char * get_certificate();
 
+#ifdef CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1
+#define OTA_CORE 0
+#else
+#define OTA_CORE 1
+#endif
+
 static const char *TAG = "squeezelite-ota";
 char * ota_write_data = NULL;
 esp_http_client_handle_t ota_http_client = NULL;
 #define IMAGE_HEADER_SIZE sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t) + 1
 #define BUFFSIZE 4096
 #define HASH_LEN 32 /* SHA-256 digest length */
-
-
+typedef struct  {
+	char * url;
+	char * bin;
+	uint32_t length;
+} ota_thread_parms_t ;
+static ota_thread_parms_t ota_thread_parms;
+typedef enum  {
+	OTA_TYPE_HTTP,
+	OTA_TYPE_BUFFER,
+	OTA_TYPE_INVALID
+} ota_type_t;
 static struct {
 	char status_text[81];
-	uint32_t ota_actual_len;
-	uint32_t ota_total_len;
+	uint32_t actual_image_len;
+	uint32_t total_image_len;
+	uint32_t remain_image_len;
 	char * redirected_url;
 	char * current_url;
+	ota_type_t ota_type;
+	char * bin;
 	bool bOTAStarted;
 	bool bInitialized;
 	uint8_t lastpct;
@@ -92,8 +110,8 @@ const char *  ota_get_status(){
 	return ota_status.status_text;
 }
 uint8_t  ota_get_pct_complete(){
-	return ota_status.ota_total_len==0?0:
-			(uint8_t)((float)ota_status.ota_actual_len/(float)ota_status.ota_total_len*100.0f);
+	return ota_status.total_image_len==0?0:
+			(uint8_t)((float)ota_status.actual_image_len/(float)ota_status.total_image_len*100.0f);
 }
 
 static void __attribute__((noreturn)) task_fatal_error(void)
@@ -105,7 +123,7 @@ static void __attribute__((noreturn)) task_fatal_error(void)
         ;
     }
 }
-#define FREE_RESET(p) if(p!=NULL) { free(p); p=NULL; }
+
 esp_err_t _http_event_handler(esp_http_client_event_t *evt)
 {
 // --------------
@@ -134,9 +152,10 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
         ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
 
         if(ota_status.bOTAStarted) triggerStatusJsonRefresh(true,"Installing...");
-        ota_status.ota_total_len=0;
-		ota_status.ota_actual_len=0;
+        ota_status.total_image_len=0;
+		ota_status.actual_image_len=0;
 		ota_status.lastpct=0;
+		ota_status.remain_image_len=0;
 		ota_status.newpct=0;
 		gettimeofday(&ota_status.OTA_start, NULL);
 
@@ -152,8 +171,8 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
         	ESP_LOGW(TAG,"OTA will redirect to url: %s",ota_status.redirected_url);
         }
         if (strcasecmp(evt->header_key, "content-length") == 0) {
-        	ota_status.ota_total_len = atol(evt->header_value);
-        	 ESP_LOGW(TAG, "Content length found: %s, parsed to %d", evt->header_value, ota_status.ota_total_len);
+        	ota_status.total_image_len = atol(evt->header_value);
+        	 ESP_LOGW(TAG, "Content length found: %s, parsed to %d", evt->header_value, ota_status.total_image_len);
         }
         break;
     case HTTP_EVENT_ON_DATA:
@@ -171,29 +190,51 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
     return ESP_OK;
 }
 
-esp_err_t init_config(char * url){
+esp_err_t init_config(ota_thread_parms_t * p_ota_thread_parms){
 	memset(&ota_config, 0x00, sizeof(ota_config));
 	ota_status.bInitialized = true;
 	triggerStatusJsonRefresh(true,"Initializing...");
-	if(url==NULL || strlen(url)==0){
-		ESP_LOGE(TAG,"HTTP OTA called without a url");
-		return ESP_FAIL;
+	ota_status.ota_type= OTA_TYPE_INVALID;
+	if(p_ota_thread_parms->url !=NULL && strlen(p_ota_thread_parms->url)>0 ){
+		ota_status.ota_type= OTA_TYPE_HTTP;
 	}
-	ota_status.current_url= url;
-	ota_config.cert_pem =get_certificate();
-	ota_config.event_handler = _http_event_handler;
-	ota_config.buffer_size = BUFFSIZE;
-	//ota_config.disable_auto_redirect=true;
-	ota_config.disable_auto_redirect=false;
-	ota_config.skip_cert_common_name_check = false;
-	ota_config.url = strdup(url);
-	ota_config.max_redirection_count = 3;
-	ota_write_data = heap_caps_malloc(ota_config.buffer_size+1 , MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
-	//ota_write_data = malloc(ota_config.buffer_size+1);
-	if(ota_write_data== NULL){
-		ESP_LOGE(TAG,"Error allocating the ota buffer");
-		return ESP_ERR_NO_MEM;
+	else if(p_ota_thread_parms->bin!=NULL && p_ota_thread_parms->length > 0) {
+		ota_status.ota_type= OTA_TYPE_BUFFER;
+	}
+
+	if(  ota_status.ota_type== OTA_TYPE_INVALID ){
+		ESP_LOGE(TAG,"HTTP OTA called without a url or a binary buffer");
+		return ESP_ERR_INVALID_ARG;
+	}
+
+	switch (ota_status.ota_type) {
+	case OTA_TYPE_HTTP:
+		ota_status.current_url= p_ota_thread_parms->url;
+		ota_config.cert_pem =get_certificate();
+		ota_config.event_handler = _http_event_handler;
+		ota_config.buffer_size = BUFFSIZE;
+		ota_config.disable_auto_redirect=false;
+		ota_config.skip_cert_common_name_check = false;
+		ota_config.url = strdup(ota_status.current_url);
+		ota_config.max_redirection_count = 3;
+		ota_write_data = heap_caps_malloc(ota_config.buffer_size+1 , MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+		//ota_write_data = malloc(ota_config.buffer_size+1);
+		if(ota_write_data== NULL){
+			ESP_LOGE(TAG,"Error allocating the ota buffer");
+			return ESP_ERR_NO_MEM;
+		}
+
+		break;
+	case OTA_TYPE_BUFFER:
+		ota_status.bin = p_ota_thread_parms->bin;
+		ota_status.total_image_len = p_ota_thread_parms->length;
+
+		break;
+	default:
+		return ESP_FAIL;
+		break;
 	}
+
 	return ESP_OK;
 }
 esp_partition_t * _get_ota_partition(esp_partition_subtype_t subtype){
@@ -252,7 +293,6 @@ esp_err_t _erase_last_boot_app_partition(esp_partition_t *ota_partition)
 		ESP_LOGD(TAG,"Pass %d of %d, with chunks of %d bytes, from %d to %d", i+1, num_passes,single_pass_size,i*single_pass_size,i*single_pass_size+single_pass_size);
 		err=esp_partition_erase_range(ota_partition, i*single_pass_size, single_pass_size);
 		if(err!=ESP_OK) return err;
-//		triggerStatusJsonRefresh(i%10==0?true:false,"Erasing flash (%u/%u)",i,num_passes);
 		if(i%2) {
 			triggerStatusJsonRefresh(false,"Erasing flash (%u/%u)",i,num_passes);
 		}
@@ -352,15 +392,16 @@ static esp_err_t _http_connect(esp_http_client_handle_t http_client)
 void ota_task_cleanup(const char * message, ...){
 	ota_status.bOTAThreadStarted=false;
 	if(message!=NULL){
-
 	    va_list args;
 	    va_start(args, message);
 		triggerStatusJsonRefresh(true,message, args);
 	    va_end(args);
 	    ESP_LOGE(TAG, "%s",ota_status.status_text);
 	}
+
 	FREE_RESET(ota_status.redirected_url);
 	FREE_RESET(ota_status.current_url);
+	FREE_RESET(ota_status.bin);
 	FREE_RESET(ota_write_data);
 	if(ota_http_client!=NULL) {
 		esp_http_client_cleanup(ota_http_client);
@@ -404,6 +445,12 @@ void ota_task(void *pvParameter)
         ota_task_cleanup("Error: OTA application partition not found. (%s)",esp_err_to_name(err));
         return;
 	}
+	if(ota_status.ota_type == OTA_TYPE_BUFFER){
+		if(ota_status.total_image_len > ota_partition->size){
+			ota_task_cleanup("Error: Image size too large to fit in partition.");
+			return;
+		}
+	}
 	_printMemStats();
 	err=_erase_last_boot_app_partition(ota_partition);
 	if(err!=ESP_OK){
@@ -414,28 +461,44 @@ void ota_task(void *pvParameter)
 	_printMemStats();
 	ota_status.bOTAStarted = true;
 	triggerStatusJsonRefresh(true,"Starting OTA...");
-    ota_http_client = esp_http_client_init(&ota_config);
-    if (ota_http_client == NULL) {
-        ota_task_cleanup("Error: Failed to initialize HTTP connection.");
-        return;
-    }
-    _printMemStats();
-    // Open the http connection and follow any redirection
-    err = _http_connect(ota_http_client);
-    if (err != ESP_OK) {
-       ota_task_cleanup("Error: HTTP Start read failed. (%s)",esp_err_to_name(err));
-       return;
-    }
-
-    _printMemStats();
+	if (ota_status.ota_type == OTA_TYPE_HTTP){
+	    ota_http_client = esp_http_client_init(&ota_config);
+	    if (ota_http_client == NULL) {
+	        ota_task_cleanup("Error: Failed to initialize HTTP connection.");
+	        return;
+	    }
+	    _printMemStats();
+	    // Open the http connection and follow any redirection
+	    err = _http_connect(ota_http_client);
+	    if (err != ESP_OK) {
+	       ota_task_cleanup("Error: HTTP Start read failed. (%s)",esp_err_to_name(err));
+	       return;
+	    }
+	}
+	else {
+		ota_write_data = ota_status.bin;
+		gettimeofday(&ota_status.OTA_start, NULL);
+	}
+	_printMemStats();
 
     esp_ota_handle_t update_handle = 0 ;
-    int binary_file_length = 0;
-
     /*deal with all receive packet*/
     bool image_header_was_checked = false;
+    int data_read = 0;
+
     while (1) {
-        int data_read = esp_http_client_read(ota_http_client, ota_write_data, buffer_size);
+    	ota_status.remain_image_len =ota_status.total_image_len -ota_status.actual_image_len;
+
+        if (ota_status.ota_type == OTA_TYPE_HTTP){
+        	data_read = esp_http_client_read(ota_http_client, ota_write_data, buffer_size);
+        }
+        else {
+        	if(ota_status.remain_image_len >buffer_size){
+        		data_read = buffer_size;
+        	} else {
+        		data_read = ota_status.remain_image_len;
+        	}
+        }
         if (data_read < 0) {
             ota_task_cleanup("Error: Data read error");
             return;
@@ -458,22 +521,11 @@ void ota_task(void *pvParameter)
                         ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version);
                     }
 
-                    // check current version with last invalid partition
-//                    if (last_invalid_app != NULL) {
-//                        if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) {
-//                            ESP_LOGW(TAG, "New version is the same as invalid version.");
-//                            ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);
-//                            ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
-//                    		  ota_task_cleanup("esp_ota_begin failed (%s)", esp_err_to_name(err));
-//                        }
-//                    }
-
                     if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {
                         ESP_LOGW(TAG, "Current running version is the same as a new.");
                     }
 
                     image_header_was_checked = true;
-
                     // Call OTA Begin with a small partition size - this drives the erase operation which was already done;
                     err = esp_ota_begin(ota_partition, 512, &update_handle);
                     if (err != ESP_OK) {
@@ -491,27 +543,30 @@ void ota_task(void *pvParameter)
                 ota_task_cleanup("Error: OTA Partition write failure. (%s)",esp_err_to_name(err));
                 return;
             }
-            binary_file_length += data_read;
-            ESP_LOGD(TAG, "Written image length %d", binary_file_length);
-			ota_status.ota_actual_len=binary_file_length;
+            ota_status.actual_image_len += data_read;
+            if(ota_status.ota_type == OTA_TYPE_BUFFER){
+            	// position the ota buffer in the next buffer chunk
+            	ota_write_data+= data_read;
+            }
+            ESP_LOGD(TAG, "Written image length %d", ota_status.actual_image_len);
 			if(ota_get_pct_complete()%5 == 0) ota_status.newpct = ota_get_pct_complete();
 			if(ota_status.lastpct!=ota_status.newpct ) {
 				gettimeofday(&tv, NULL);
 				uint32_t elapsed_ms= (tv.tv_sec-ota_status.OTA_start.tv_sec )*1000+(tv.tv_usec-ota_status.OTA_start.tv_usec)/1000;
-				ESP_LOGI(TAG,"OTA progress : %d/%d (%d pct), %d KB/s", ota_status.ota_actual_len, ota_status.ota_total_len, ota_status.newpct, elapsed_ms>0?ota_status.ota_actual_len*1000/elapsed_ms/1024:0);
-				triggerStatusJsonRefresh(true,"Downloading & writing update.");
+				ESP_LOGI(TAG,"OTA progress : %d/%d (%d pct), %d KB/s", ota_status.actual_image_len, ota_status.total_image_len, ota_status.newpct, elapsed_ms>0?ota_status.actual_image_len*1000/elapsed_ms/1024:0);
+				triggerStatusJsonRefresh(true,ota_status.ota_type == OTA_TYPE_HTTP?"Downloading & writing update.":"Writing binary file.");
 				ota_status.lastpct=ota_status.newpct;
 			}
 			taskYIELD();
 
         } else if (data_read == 0) {
-            ESP_LOGI(TAG, "Connection closed");
+            ESP_LOGI(TAG, "End of OTA data stream");
             break;
         }
     }
 
-    ESP_LOGI(TAG, "Total Write binary data length: %d", binary_file_length);
-    if (ota_status.ota_total_len != binary_file_length) {
+    ESP_LOGI(TAG, "Total Write binary data length: %d", ota_status.actual_image_len);
+    if (ota_status.total_image_len != ota_status.actual_image_len) {
         ota_task_cleanup("Error: Error in receiving complete file");
         return;
     }
@@ -537,7 +592,7 @@ void ota_task(void *pvParameter)
     return;
 }
 
-esp_err_t process_recovery_ota(const char * bin_url){
+esp_err_t process_recovery_ota(const char * bin_url, char * bin_buffer, uint32_t length){
 	int ret = 0;
 	uint16_t stack_size, task_priority;
     if(ota_status.bOTAThreadStarted){
@@ -546,18 +601,17 @@ esp_err_t process_recovery_ota(const char * bin_url){
 	}
 	memset(&ota_status, 0x00, sizeof(ota_status));
 	ota_status.bOTAThreadStarted=true;
-    char * urlPtr=strdup(bin_url);
-	// the first thing we need to do here is to erase the firmware url
-	// to avoid a boot loop
 
-#ifdef CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1
-#define OTA_CORE 0
-#warning "OTA will run on core 0"
-#else
-#pragma message "OTA will run on core 1"
-#define OTA_CORE 1
-#endif
-    ESP_LOGI(TAG, "Starting ota on core %u for : %s", OTA_CORE,urlPtr);
+	if(bin_url){
+		ota_thread_parms.url =strdup(bin_url);
+		ESP_LOGI(TAG, "Starting ota on core %u for : %s", OTA_CORE,bin_url);
+	}
+	else {
+		ota_thread_parms.bin = bin_buffer;
+		ota_thread_parms.length = length;
+		ESP_LOGI(TAG, "Starting ota on core %u for file upload", OTA_CORE);
+	}
+
     char * num_buffer=config_alloc_get(NVS_TYPE_STR, "ota_stack");
   	if(num_buffer!=NULL) {
   		stack_size= atol(num_buffer);
@@ -578,9 +632,9 @@ esp_err_t process_recovery_ota(const char * bin_url){
 		ESP_LOGW(TAG,"OTA task priority not found");
 		task_priority= OTA_TASK_PRIOTITY;
   	}
+
   	ESP_LOGD(TAG,"OTA task stack size %d, priority %d (%d %s ESP_TASK_MAIN_PRIO)",stack_size , task_priority, abs(task_priority-ESP_TASK_MAIN_PRIO), task_priority-ESP_TASK_MAIN_PRIO>0?"above":"below");
-    ret=xTaskCreatePinnedToCore(&ota_task, "ota_task", stack_size , (void *)urlPtr, task_priority, NULL, OTA_CORE);
-    //ret=xTaskCreate(&ota_task, "ota_task", 1024*20, (void *)urlPtr, ESP_TASK_MAIN_PRIO+2, NULL);
+    ret=xTaskCreatePinnedToCore(&ota_task, "ota_task", stack_size , (void *)&ota_thread_parms, task_priority, NULL, OTA_CORE);
     if (ret != pdPASS)  {
             ESP_LOGI(TAG, "create thread %s failed", "ota_task");
             return ESP_FAIL;
@@ -588,23 +642,26 @@ esp_err_t process_recovery_ota(const char * bin_url){
     return ESP_OK;
 }
 
-esp_err_t start_ota(const char * bin_url)
+esp_err_t start_ota(const char * bin_url, char * bin_buffer, uint32_t length)
 {
-//	uint8_t * config_alloc_get_default(NVS_TYPE_BLOB, "certs", server_cert_pem_start , server_cert_pem_end-server_cert_pem_start);
 #if RECOVERY_APPLICATION
-	return process_recovery_ota(bin_url);
+	return process_recovery_ota(bin_url,bin_buffer,length);
 #else
-		ESP_LOGW(TAG, "Called to update the firmware from url: %s",bin_url);
-		if(config_set_value(NVS_TYPE_STR, "fwurl", bin_url) != ESP_OK){
-			ESP_LOGE(TAG,"Failed to save the OTA url into nvs cache");
-			return ESP_FAIL;
-		}
+	if(!bin_url){
+		ESP_LOGE(TAG,"missing URL parameter. Unable to start OTA");
+		return ESP_ERR_INVALID_ARG;
+	}
+	ESP_LOGW(TAG, "Called to update the firmware from url: %s",bin_url);
+	if(config_set_value(NVS_TYPE_STR, "fwurl", bin_url) != ESP_OK){
+		ESP_LOGE(TAG,"Failed to save the OTA url into nvs cache");
+		return ESP_FAIL;
+	}
 
-		if(!wait_for_commit()){
-			ESP_LOGW(TAG,"Unable to commit configuration. ");
-		}
+	if(!wait_for_commit()){
+		ESP_LOGW(TAG,"Unable to commit configuration. ");
+	}
 
-		ESP_LOGW(TAG, "Rebooting to recovery to complete the installation");
+	ESP_LOGW(TAG, "Rebooting to recovery to complete the installation");
 	return guided_factory();
 	return ESP_OK;
 #endif

+ 2 - 1
components/squeezelite-ota/squeezelite-ota.h

@@ -9,6 +9,7 @@
 #include "esp_attr.h"
 #include "esp_image_format.h"
 #include "esp_ota_ops.h"
+#include "sys/param.h"
 
 #if RECOVERY_APPLICATION
 #define CODE_RAM_LOCATION
@@ -35,7 +36,7 @@
 // tasks
 #define OTA_TASK_PRIOTITY 6
 
-esp_err_t start_ota(const char * bin_url);
+esp_err_t start_ota(const char * bin_url, char * bin_buffer, uint32_t length);
 const char * ota_get_status();
 uint8_t ota_get_pct_complete();
 

+ 30 - 1
components/wifi-manager/code.js

@@ -367,7 +367,31 @@ $(document).ready(function(){
         console.log('sent config JSON with headers:', JSON.stringify(headers));
         console.log('sent config JSON with data:', JSON.stringify(data));
     });
-
+    $("#fwUpload").on("click", function() {
+    	
+        var upload_path = "/flash.json";
+        var fileInput = document.getElementById("flashfilename").files;
+        if (fileInput.length == 0) {
+            alert("No file selected!");
+        } else {
+            var file = fileInput[0];
+            var xhttp = new XMLHttpRequest();
+            xhttp.onreadystatechange = function() {
+                if (xhttp.readyState == 4) {
+                    if (xhttp.status == 200) {
+                    	showMessage(xhttp.responseText, 'INFO')
+                    } else if (xhttp.status == 0) {
+                    	showMessage("Upload connection was closed abruptly!", 'ERROR');
+                    } else {
+                    	showMessage(xhttp.status + " Error!\n" + xhttp.responseText, 'ERROR');
+                    }
+                }
+            };
+            xhttp.open("POST", upload_path, true);
+            xhttp.send(file);    	
+        }
+    	enableStatusTimer = true;
+    });
     $("#flash").on("click", function() {
         var data = { 'timestamp': Date.now() };
         if (blockFlashButton) return;
@@ -732,6 +756,8 @@ function checkStatus(){
                 $("footer.footer").addClass('sl');
                 $("#boot-button").html('Recovery');
                 $("#boot-form").attr('action', '/recovery.json');
+                $('#uploaddiv"]').hide();
+                
                 enableStatusTimer = false;
             }
         }
@@ -874,3 +900,6 @@ function showMessage(message, severity) {
 function inRange(x, min, max) {
     return ((x-min)*(x-max) <= 0);
 }
+
+    
+    

+ 116 - 9
components/wifi-manager/http_server_handlers.c

@@ -41,6 +41,7 @@ function to process requests, decode URLs, serve files, etc. etc.
 #include <stdio.h>
 #include <stdlib.h>
 #include "cJSON.h"
+#include "config.h"
 #include "esp_system.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
@@ -323,7 +324,10 @@ static const char* get_path_from_uri(char *dest, const char *uri, size_t destsiz
 /* Set HTTP response content type according to file extension */
 static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename)
 {
-    if (IS_FILE_EXT(filename, ".pdf")) {
+    if(strlen(filename) ==0){
+    	// for root page, etc.
+    	return httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
+    } else if (IS_FILE_EXT(filename, ".pdf")) {
         return httpd_resp_set_type(req, "application/pdf");
     } else if (IS_FILE_EXT(filename, ".html")) {
         return httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
@@ -340,6 +344,7 @@ static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filena
     } else if (IS_FILE_EXT(filename, ".json")) {
         return httpd_resp_set_type(req, HTTPD_TYPE_JSON);
     }
+
     /* This is a limited set only */
     /* For any other type always set as plain text */
     return httpd_resp_set_type(req, "text/plain");
@@ -360,6 +365,7 @@ static esp_err_t set_content_type_from_req(httpd_req_t *req)
 	   httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Browsing files forbidden.");
 	   return ESP_FAIL;
    }
+   set_content_type_from_file(req, filename);
    return ESP_OK;
 }
 
@@ -548,6 +554,11 @@ esp_err_t config_post_handler(httpd_req_t *req){
     	// todo:  redirect to login page
     	// return ESP_OK;
     }
+	err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
+
     char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch;
     cJSON *root = cJSON_Parse(buf);
     if(root == NULL){
@@ -637,7 +648,6 @@ esp_err_t config_post_handler(httpd_req_t *req){
 
 
 	if(err==ESP_OK){
-		set_content_type_from_req(req);
 		httpd_resp_sendstr(req, "{ \"result\" : \"OK\" }");
 	}
     cJSON_Delete(root);
@@ -660,11 +670,16 @@ esp_err_t connect_post_handler(httpd_req_t *req){
     char * ssid=NULL;
     char * password=NULL;
     char * host_name=NULL;
-	set_content_type_from_req(req);
+
 	esp_err_t err = post_handler_buff_receive(req);
 	if(err!=ESP_OK){
 		return err;
 	}
+	err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
+
 	char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch;
     if(!is_user_authenticated(req)){
     	// todo:  redirect to login page
@@ -724,7 +739,10 @@ esp_err_t connect_delete_handler(httpd_req_t *req){
     	// todo:  redirect to login page
     	// return ESP_OK;
     }
-	set_content_type_from_req(req);
+	esp_err_t err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
 	httpd_resp_send(req, (const char *)success, strlen(success));
 	wifi_manager_disconnect_async();
 
@@ -737,7 +755,11 @@ esp_err_t reboot_ota_post_handler(httpd_req_t *req){
     	// todo:  redirect to login page
     	// return ESP_OK;
     }
-	set_content_type_from_req(req);
+    esp_err_t err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
+
 	httpd_resp_send(req, (const char *)success, strlen(success));
 	wifi_manager_reboot(OTA);
     return ESP_OK;
@@ -749,7 +771,10 @@ esp_err_t reboot_post_handler(httpd_req_t *req){
     	// todo:  redirect to login page
     	// return ESP_OK;
     }
-	set_content_type_from_req(req);
+    esp_err_t err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
 	httpd_resp_send(req, (const char *)success, strlen(success));
 	wifi_manager_reboot(RESTART);
 	return ESP_OK;
@@ -761,12 +786,91 @@ esp_err_t recovery_post_handler(httpd_req_t *req){
     	// todo:  redirect to login page
     	// return ESP_OK;
     }
-	set_content_type_from_req(req);
+    esp_err_t err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
 	httpd_resp_send(req, (const char *)success, strlen(success));
 	wifi_manager_reboot(RECOVERY);
 	return ESP_OK;
 }
 
+#if RECOVERY_APPLICATION
+esp_err_t flash_post_handler(httpd_req_t *req){
+    ESP_LOGD_LOC(TAG, "serving [%s]", req->uri);
+    char success[]="File uploaded. Flashing started.";
+    if(!is_user_authenticated(req)){
+    	// todo:  redirect to login page
+    	// return ESP_OK;
+    }
+    esp_err_t err = httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
+	if(err != ESP_OK){
+		return err;
+	}
+	char * binary_buffer = malloc(req->content_len);
+	if(binary_buffer == NULL){
+        ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
+        /* Respond with 400 Bad Request */
+        httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST,
+                            "Binary file too large. Unable to allocate memory!");
+        return ESP_FAIL;
+	}
+	ESP_LOGI(TAG, "Receiving ota binary file");
+	/* Retrieve the pointer to scratch buffer for temporary storage */
+	char *buf = ((rest_server_context_t *)(req->user_ctx))->scratch;
+
+	char *head=binary_buffer;
+	int received;
+
+	/* Content length of the request gives
+	 * the size of the file being uploaded */
+	int remaining = req->content_len;
+
+	while (remaining > 0) {
+
+		ESP_LOGI(TAG, "Remaining size : %d", remaining);
+		/* Receive the file part by part into a buffer */
+		if ((received = httpd_req_recv(req, buf, MIN(remaining, SCRATCH_BUFSIZE))) <= 0) {
+			if (received == HTTPD_SOCK_ERR_TIMEOUT) {
+				/* Retry if timeout occurred */
+				continue;
+			}
+			FREE_RESET(binary_buffer);
+			ESP_LOGE(TAG, "File reception failed!");
+			/* Respond with 500 Internal Server Error */
+			httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file");
+			err = ESP_FAIL;
+			goto bail_out;
+		}
+
+		/* Write buffer content to file on storage */
+		if (received ) {
+			memcpy(head,buf,received );
+			head+=received;
+		}
+
+		/* Keep track of remaining size of
+		 * the file left to be uploaded */
+		remaining -= received;
+	}
+
+	/* Close file upon upload completion */
+	ESP_LOGI(TAG, "File reception complete. Invoking OTA process.");
+	err = start_ota(NULL, binary_buffer, req->content_len);
+	if(err!=ESP_OK){
+		httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "OTA processing failed");
+		goto bail_out;
+	}
+
+	//todo:  handle this in ajax.  For now, just send the root page
+	httpd_resp_send(req, (const char *)success, strlen(success));
+
+bail_out:
+
+	return err;
+}
+
+#endif
 char * get_ap_ip_address(){
 	static char ap_ip_address[IP4ADDR_STRLEN_MAX]={};
 
@@ -869,7 +973,7 @@ esp_err_t redirect_processor(httpd_req_t *req, httpd_err_code_t error){
     char *req_host = alloc_get_http_header(req, "Host");
 
     user_agent = alloc_get_http_header(req,"User-Agent");
-    if((useragentiscaptivenetwork = strcasestr(user_agent,"CaptiveNetworkSupport"))==true){
+    if((useragentiscaptivenetwork = (user_agent!=NULL  && strcasestr(user_agent,"CaptiveNetworkSupport"))==true)){
     	ESP_LOGW_LOC(TAG,"Found user agent that supports captive networks! [%s]",user_agent);
     }
 
@@ -941,7 +1045,10 @@ esp_err_t status_get_handler(httpd_req_t *req){
     	// todo:  redirect to login page
     	// return ESP_OK;
     }
-	set_content_type_from_req(req);
+    esp_err_t err = set_content_type_from_req(req);
+	if(err != ESP_OK){
+		return err;
+	}
 
 	if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
 		char *buff = wifi_manager_alloc_get_ip_info_json();

+ 3 - 0
components/wifi-manager/http_server_handlers.h

@@ -88,6 +88,9 @@ esp_err_t connect_delete_handler(httpd_req_t *req);
 esp_err_t reboot_ota_post_handler(httpd_req_t *req);
 esp_err_t reboot_post_handler(httpd_req_t *req);
 esp_err_t recovery_post_handler(httpd_req_t *req);
+#if RECOVERY_APPLICATION
+esp_err_t flash_post_handler(httpd_req_t *req);
+#endif
 esp_err_t status_get_handler(httpd_req_t *req);
 esp_err_t ap_scan_handler(httpd_req_t *req);
 esp_err_t redirect_ev_handler(httpd_req_t *req);

+ 8 - 9
components/wifi-manager/index.html

@@ -345,21 +345,20 @@
                     </table>
                     <h2>Firmware URL:</h2>
                     <textarea id="fwurl" maxlength="350"></textarea>
-                   <!-- 
-                    <br />OR<br />
-                    <div class="input-group mb-3" id="upload">
+                    <div class="buttons">
+                    	<input type="button" id="flash" class="btn btn-danger" value="Flash!" /><span id="flash-status"></span>
+                    </div>
+                     <br />OR<br />
+                    <div class="input-group mb-3" id="uploaddiv">
                         <div class="custom-file">
-                            <input type="file" class="custom-file-input" id="inputGroupFile01">
-                            <label class="custom-file-label" for="inputGroupFile01"></label>
+                            <input type="file" class="custom-file-input" id="flashfilename">
+                            <label class="custom-file-label" for="flashfilename"></label>
                         </div>
                         <div class="input-group-append">
                             <span class="input-group-text" id="fwUpload">Upload</span>
                         </div>
                     </div>
-                   -->
-                    <div class="buttons">
-                    	<input type="button" id="flash" class="btn btn-danger" value="Flash!" /><span id="flash-status"></span>
-                    </div>
+                    
                     <div id="otadiv">
                         <div class="progress" id="progress">
                             <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" style="width:0%">

+ 2 - 1
components/wifi-manager/wifi_manager.c

@@ -66,6 +66,7 @@ Contains the freeRTOS task and all necessary support
 #include "globdefs.h"
 
 #ifndef RECOVERY_APPLICATION
+#pragma warning "Defaulting to squeezelite build"
 #define RECOVERY_APPLICATION 0
 #endif
 
@@ -1470,7 +1471,7 @@ void wifi_manager( void * pvParameters ){
 				break;
 			case  ORDER_RESTART_OTA_URL:
 				ESP_LOGD(TAG,   "Calling start_ota.");
-				start_ota(msg.param);
+				start_ota(msg.param, NULL, 0);
 				free(msg.param);
 				break;
 

+ 0 - 1
components/wifi-manager/wifi_manager.h

@@ -48,7 +48,6 @@ extern "C" {
 
 #if RECOVERY_APPLICATION==1
 #elif RECOVERY_APPLICATION==0
-#pragma message "compiling for squeezelite."
 #else
 #error "unknown configuration"
 #endif

+ 8 - 221
components/wifi-manager/wifi_manager_http_server.c

@@ -19,7 +19,7 @@
  *
  */
 
-#include  "http_server_handlers.h"
+#include "http_server_handlers.h"
 #include "esp_log.h"
 #include "esp_http_server.h"
 #include <inttypes.h>
@@ -70,6 +70,12 @@ void register_regular_handlers(httpd_handle_t server){
 	httpd_uri_t connect_delete = { .uri = "/connect.json", .method = HTTP_DELETE, .handler = connect_delete_handler, .user_ctx = rest_context };
 	httpd_register_uri_handler(server, &connect_delete);
 
+#if RECOVERY_APPLICATION
+
+	httpd_uri_t flash_post = { .uri = "/flash.json", .method = HTTP_POST, .handler = flash_post_handler, .user_ctx = rest_context };
+	httpd_register_uri_handler(server, &flash_post);
+#endif
+
 
 	// from https://github.com/tripflex/wifi-captive-portal/blob/master/src/mgos_wifi_captive_portal.c
 	// https://unix.stackexchange.com/questions/432190/why-isnt-androids-captive-portal-detection-triggering-a-browser-window
@@ -97,6 +103,7 @@ void register_regular_handlers(httpd_handle_t server){
 	httpd_register_uri_handler(server, &connect_redirect_8);
 
 
+
 	ESP_LOGD(TAG,"Registering default error handler for 404");
 	httpd_register_err_handler(server, HTTPD_404_NOT_FOUND,&err_handler);
 
@@ -150,223 +157,3 @@ void stop_webserver(httpd_handle_t server)
 
 
 
-
-
-#if 0
-
-if(strstr(line, "GET / ")) {
-	netconn_write(conn, http_html_hdr, sizeof(http_html_hdr) - 1, NETCONN_NOCOPY);
-	netconn_write(conn, index_html_start, index_html_end- index_html_start, NETCONN_NOCOPY);
-}
-else if(strstr(line, "GET /code.js ")) {
-	netconn_write(conn, http_js_hdr, sizeof(http_js_hdr) - 1, NETCONN_NOCOPY);
-	netconn_write(conn, code_js_start, code_js_end - code_js_start, NETCONN_NOCOPY);
-}
-else if(strstr(line, "GET /style.css ")) {
-	netconn_write(conn, http_css_hdr, sizeof(http_css_hdr) - 1, NETCONN_NOCOPY);
-	netconn_write(conn, style_css_start, style_css_end - style_css_start, NETCONN_NOCOPY);
-}
-else if(strstr(line, "GET /jquery.js ")) {
-	http_server_send_resource_file(conn,jquery_gz_start, jquery_gz_end, "text/javascript", "gzip" );
-}
-else if(strstr(line, "GET /popper.js ")) {
-	http_server_send_resource_file(conn,popper_gz_start, popper_gz_end, "text/javascript", "gzip" );
-}
-else if(strstr(line, "GET /bootstrap.js ")) {
-	http_server_send_resource_file(conn,bootstrap_js_gz_start, bootstrap_js_gz_end, "text/javascript", "gzip" );
-}
-else if(strstr(line, "GET /bootstrap.css ")) {
-	http_server_send_resource_file(conn,bootstrap_css_gz_start, bootstrap_css_gz_end, "text/css", "gzip" );
-}
-
-//dynamic stuff
-else if(strstr(line, "GET /scan.json ")) {
-	ESP_LOGI(TAG,  "Starting wifi scan");
-	wifi_manager_scan_async();
-}
-else if(strstr(line, "GET /ap.json ")) {
-	/* if we can get the mutex, write the last version of the AP list */
-	ESP_LOGI(TAG,  "Processing ap.json request");
-	if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
-		netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
-		char *buff = wifi_manager_alloc_get_ap_list_json();
-		wifi_manager_unlock_json_buffer();
-		if(buff!=NULL){
-			netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
-			free(buff);
-		}
-		else {
-			ESP_LOGD(TAG,  "Error retrieving ap list json string. ");
-			netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
-		}
-	}
-	else {
-		netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
-		ESP_LOGE(TAG,   "http_server_netconn_serve: GET /ap.json failed to obtain mutex");
-	}
-	/* request a wifi scan */
-	ESP_LOGI(TAG,  "Starting wifi scan");
-	wifi_manager_scan_async();
-	ESP_LOGI(TAG,  "Done serving ap.json");
-}
-else if(strstr(line, "GET /config.json ")) {
-	ESP_LOGI(TAG,  "Serving config.json");
-	ESP_LOGI(TAG,   "About to get config from flash");
-	http_server_send_config_json(conn);
-	ESP_LOGD(TAG,  "Done serving config.json");
-}
-else if(strstr(line, "POST /config.json ")) {
-	ESP_LOGI(TAG,  "Serving POST config.json");
-	int lenA=0;
-	char * last_parm=save_ptr;
-	char * next_parm=save_ptr;
-	char  * last_parm_name=NULL;
-	bool bErrorFound=false;
-	bool bOTA=false;
-	char * otaURL=NULL;
-	// todo:  implement json body parsing
-	//http_server_process_config(conn,save_ptr);
-
-	while(last_parm!=NULL) {
-		// Search will return
-		ESP_LOGD(TAG,   "Getting parameters from X-Custom headers");
-		last_parm = http_server_search_header(next_parm, "X-Custom-", &lenA, &last_parm_name,&next_parm,buf+buflen);
-		if(last_parm!=NULL && last_parm_name!=NULL) {
-			ESP_LOGI(TAG,   "http_server_netconn_serve: POST config.json, config %s=%s", last_parm_name, last_parm);
-			if(strcmp(last_parm_name, "fwurl")==0) {
-				// we're getting a request to do an OTA from that URL
-				ESP_LOGW(TAG,   "Found OTA request!");
-				otaURL=strdup(last_parm);
-				bOTA=true;
-			}
-			else {
-				ESP_LOGV(TAG,   "http_server_netconn_serve: POST config.json Storing parameter");
-				if(config_set_value(NVS_TYPE_STR, last_parm_name , last_parm) != ESP_OK){
-					ESP_LOGE(TAG,  "Unable to save nvs value.");
-				}
-			}
-		}
-		if(last_parm_name!=NULL) {
-			free(last_parm_name);
-			last_parm_name=NULL;
-		}
-	}
-	if(bErrorFound) {
-		netconn_write(conn, http_400_hdr, sizeof(http_400_hdr) - 1, NETCONN_NOCOPY); //400 invalid request
-	}
-	else {
-		netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); //200ok
-		if(bOTA) {
-
-#if RECOVERY_APPLICATION
-			ESP_LOGW(TAG,   "Starting process OTA for url %s",otaURL);
-#else
-			ESP_LOGW(TAG,   "Restarting system to process OTA for url %s",otaURL);
-#endif
-			wifi_manager_reboot_ota(otaURL);
-			free(otaURL);
-		}
-	}
-	ESP_LOGI(TAG,  "Done Serving POST config.json");
-}
-else if(strstr(line, "POST /connect.json ")) {
-	ESP_LOGI(TAG,   "http_server_netconn_serve: POST /connect.json");
-	bool found = false;
-	int lenS = 0, lenP = 0, lenN = 0;
-	char *ssid = NULL, *password = NULL;
-	ssid = http_server_get_header(save_ptr, "X-Custom-ssid: ", &lenS);
-	password = http_server_get_header(save_ptr, "X-Custom-pwd: ", &lenP);
-	char * new_host_name_b = http_server_get_header(save_ptr, "X-Custom-host_name: ", &lenN);
-	if(lenN > 0){
-		lenN++;
-		char * new_host_name = malloc(lenN);
-		strlcpy(new_host_name, new_host_name_b, lenN);
-		if(config_set_value(NVS_TYPE_STR, "host_name", new_host_name) != ESP_OK){
-			ESP_LOGE(TAG,  "Unable to save host name configuration");
-		}
-		free(new_host_name);
-	}
-
-	if(ssid && lenS <= MAX_SSID_SIZE && password && lenP <= MAX_PASSWORD_SIZE) {
-		wifi_config_t* config = wifi_manager_get_wifi_sta_config();
-		memset(config, 0x00, sizeof(wifi_config_t));
-		memcpy(config->sta.ssid, ssid, lenS);
-		memcpy(config->sta.password, password, lenP);
-		ESP_LOGD(TAG,   "http_server_netconn_serve: wifi_manager_connect_async() call, with ssid: %s, password: %s", config->sta.ssid, config->sta.password);
-		wifi_manager_connect_async();
-		netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); //200ok
-		found = true;
-	}
-	else{
-		ESP_LOGE(TAG,  "SSID or Password invalid");
-	}
-
-
-	if(!found) {
-		/* bad request the authentification header is not complete/not the correct format */
-		netconn_write(conn, http_400_hdr, sizeof(http_400_hdr) - 1, NETCONN_NOCOPY);
-		ESP_LOGE(TAG,   "bad request the authentification header is not complete/not the correct format");
-	}
-
-	ESP_LOGI(TAG,   "http_server_netconn_serve: done serving connect.json");
-}
-else if(strstr(line, "DELETE /connect.json ")) {
-	ESP_LOGI(TAG,   "http_server_netconn_serve: DELETE /connect.json");
-	/* request a disconnection from wifi and forget about it */
-	wifi_manager_disconnect_async();
-	netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
-	ESP_LOGI(TAG,   "http_server_netconn_serve: done serving DELETE /connect.json");
-}
-else if(strstr(line, "POST /reboot_ota.json ")) {
-	ESP_LOGI(TAG,   "http_server_netconn_serve: POST reboot_ota.json");
-	netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
-	wifi_manager_reboot(OTA);
-	ESP_LOGI(TAG,   "http_server_netconn_serve: done serving POST reboot_ota.json");
-}
-else if(strstr(line, "POST /reboot.json ")) {
-	ESP_LOGI(TAG,   "http_server_netconn_serve: POST reboot.json");
-	netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
-	wifi_manager_reboot(RESTART);
-	ESP_LOGI(TAG,   "http_server_netconn_serve: done serving POST reboot.json");
-}
-else if(strstr(line, "POST /recovery.json ")) {
-	ESP_LOGI(TAG,   "http_server_netconn_serve: POST recovery.json");
-	netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY); /* 200 ok */
-	wifi_manager_reboot(RECOVERY);
-	ESP_LOGI(TAG,   "http_server_netconn_serve: done serving POST recovery.json");
-}
-else if(strstr(line, "GET /status.json ")) {
-	ESP_LOGI(TAG,  "Serving status.json");
-	if(wifi_manager_lock_json_buffer(( TickType_t ) 10)) {
-		char *buff = wifi_manager_alloc_get_ip_info_json();
-		wifi_manager_unlock_json_buffer();
-		if(buff) {
-			netconn_write(conn, http_ok_json_no_cache_hdr, sizeof(http_ok_json_no_cache_hdr) - 1, NETCONN_NOCOPY);
-			netconn_write(conn, buff, strlen(buff), NETCONN_NOCOPY);
-			free(buff);
-		}
-		else {
-			netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
-		}
-
-	}
-	else {
-		netconn_write(conn, http_503_hdr, sizeof(http_503_hdr) - 1, NETCONN_NOCOPY);
-		ESP_LOGE(TAG,   "http_server_netconn_serve: GET /status failed to obtain mutex");
-	}
-	ESP_LOGI(TAG,  "Done Serving status.json");
-}
-else {
-	netconn_write(conn, http_400_hdr, sizeof(http_400_hdr) - 1, NETCONN_NOCOPY);
-	ESP_LOGE(TAG,   "bad request from host: %s, request %s",remote_address, line);
-}
-}
-}
-else {
-ESP_LOGE(TAG,   "URL not found processing for remote host : %s",remote_address);
-netconn_write(conn, http_404_hdr, sizeof(http_404_hdr) - 1, NETCONN_NOCOPY);
-}
-free(host);
-
-}
-#endif

+ 1 - 1
main/esp_app_main.c

@@ -421,7 +421,7 @@ void app_main()
 			taskYIELD();
 		}
 		ESP_LOGI(TAG,"Updating firmware from link: %s",fwurl);
-		start_ota(fwurl);
+		start_ota(fwurl, NULL, 0);
 #else
 		ESP_LOGE(TAG,"Restarted to application partition. We're not going to perform OTA!");
 #endif