Commit 4911d2db authored by Arnim Läuger's avatar Arnim Läuger
Browse files

Merge pull request #1336 from nodemcu/dev

1.5.1 master drop
parents c8037568 2e109686
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.cross.base.992255352">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.cross.base.992255352" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.cross.base.992255352" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.cross.base.992255352.1209976491" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.base.1901907892" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base">
<option id="cdt.managedbuild.option.gnu.cross.prefix.1771691886" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix"/>
<option id="cdt.managedbuild.option.gnu.cross.path.1831805518" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.2055058514" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder enableAutoBuild="false" enabledIncrementalBuild="true" id="cdt.managedbuild.builder.gnu.cross.415628675" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="false" superClass="cdt.managedbuild.builder.gnu.cross">
<outputEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
</outputEntries>
</builder>
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.972920545" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1985687892" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.36308842" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1696212951" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1453974065" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2057246668" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.2049169207" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.2111505538" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.353143895" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1235194497" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
<folderInfo id="cdt.managedbuild.toolchain.gnu.cross.base.992255352.588851457" name="/" resourcePath="bin">
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.base.255773949" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.base" unusedChildren="">
<option id="cdt.managedbuild.option.gnu.cross.prefix.1771691886.1324829965" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix.1771691886"/>
<option id="cdt.managedbuild.option.gnu.cross.path.1831805518.1198903031" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path.1831805518"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1642402045" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler.972920545">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.584005709" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1648531134" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler.36308842">
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.598540090" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.910780357" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker.1453974065"/>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.586323152" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker.2057246668"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.1467668351" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver.2111505538"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.36312719" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler.353143895">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1895164072" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="nodemcu-firmware.null.292794708" name="nodemcu-firmware"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/nodemcu-firmware"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.992255352;cdt.managedbuild.toolchain.gnu.cross.base.992255352.1209976491;cdt.managedbuild.tool.gnu.cross.c.compiler.972920545;cdt.managedbuild.tool.gnu.c.compiler.input.1985687892">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.cross.base.992255352;cdt.managedbuild.toolchain.gnu.cross.base.992255352.1209976491;cdt.managedbuild.tool.gnu.cross.cpp.compiler.36308842;cdt.managedbuild.tool.gnu.cpp.compiler.input.1696212951">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="flash" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>flash</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>
Make sure you read and understand http://nodemcu.readthedocs.io/en/dev/en/support/.
Use one of the two templates below and delete the rest.
8<------------------------ BUG REPORT -----------------------------------------
### Expected behavior
### Actual behavior
### Test code
Provide a minimal and isolated test which will reproduce the problem.
```Lua
-- add code here
```
### NodeMCU version
Which branch are you on? If you know the Git revision then add it here as well.
### Hardware
Describe which ESP8266 device you use and document any special hardware setup
required to reproduce the problem.
8<------------------------ END BUG REPORT -------------------------------------
8<------------------------ FEATURE REQUEST ------------------------------------
### Missing feature
### Justification
Tell us why you would like to see this feature added.
### Workarounds
Are there any workarounds you currently have in place because the feature is missing?
8<------------------------ END FEATURE REQUEST --------------------------------
Fixes #\<GitHub-issue-number\>.
Make sure all boxes are checked (add x inside the brackets) when you submit your contribution, remove this sentence before doing so.
- [ ] This PR is compliant with the [contributing guidelines](https://github.com/nodemcu/nodemcu-firmware/blob/dev/CONTRIBUTING.md) (if not, please describe why).
- [ ] I have thoroughly tested my contribution.
- [ ] The code changes are reflected in the documentation at `docs/en/*`.
\<Description of and rational behind this PR\>
Committers supporting this PR: leave blank
\ No newline at end of file
sdk/
cache/
user_config.h
server-ca.crt
#ignore Eclipse project files
.cproject
.project
.settings/
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>nodemcu-firmware</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.toolchain.gnu.cross.base.992255352" name="Default">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
</extension>
</configuration>
</project>
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},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}}
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},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}}
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}}
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}}
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}}
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},no_break_comment\=>"no break",last_case_param\=>false,empty_case_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},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}}
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},skip\=>true}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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},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}}
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}}
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}}
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}}
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}}
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}}
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},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},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},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}}
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},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},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},macro\=>true,exceptions\=>("@(\#)","$Id")}
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}}
eclipse.preferences.version=1
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/delimiter=;
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/operation=append
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/value=C\:\\Espressif\\xtensa-lx106-elf\\bin;C\:\\MinGW\\bin;C\:\\MinGW\\msys\\1.0\\bin;C\:\\Python27
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/append=true
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/appendContributed=true
......@@ -5,6 +5,9 @@ addons:
packages:
- python-serial
- srecord
cache:
directories:
- cache
install:
- tar -zxvf tools/esp-open-sdk.tar.gz
- export PATH=$PATH:$PWD/esp-open-sdk/xtensa-lx106-elf/bin
......@@ -22,14 +25,3 @@ script:
- srec_cat -output ${file_name_integer} -binary 0x00000.bin -binary -fill 0xff 0x00000 0x10000 0x10000.bin -binary -offset 0x10000
# http://docs.travis-ci.com/user/environment-variables/#Convenience-Variables
- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash "$TRAVIS_BUILD_DIR"/tools/pr-build.sh; fi
deploy:
provider: releases
api_key:
secure: Swecz5lWvsuSbchSbVQ1rmCPN9nQIN5p/HlZNIEdEgAgnoLcJxRV4P8poVTB37jiA8Pck+8x2nWXpg74Rqik0i3KlPNvDfg5o4rIazWLNs4bc1Tbcpt44XAzFKKLYnDnWQUGcqjk7BcAXuNAF2X/fPBCVhFbHVg3Z7cDb32RsNw=
file:
- "$TRAVIS_BUILD_DIR/bin/${file_name_float}"
- "$TRAVIS_BUILD_DIR/bin/${file_name_integer}"
skip_cleanup: true
on:
tags: true
repo: nodemcu/nodemcu-firmware
......@@ -9,6 +9,7 @@ It is appreciated but optional if you raise an issue _before_ you start changing
### Table Of Contents
* [Development environment setup](#development-environment-setup)
* [Writing Documentation](#writing-documentation)
* [Working with Git and GitHub](#working-with-git-and-github)
* [General flow](#general-flow)
* [Keeping your fork in sync](#keeping-your-fork-in-sync)
......@@ -19,6 +20,22 @@ Use the platform and tools you feel most comfortable with. There are no constra
- [Full-fledged Linux enviroment](http://www.esp8266.com/wiki/doku.php?id=toolchain#how_to_setup_a_vm_to_host_your_toolchain), either physical or virtual.
- [Docker image](https://hub.docker.com/r/marcelstoer/nodemcu-build/) which allows to run the build inside the container as if you were running a build script on your local machine.
## Writing Documentation
The NodeMCU documentation is maintained within the same repository as the code. The primary reason is to keep the two in sync more easily. It's thus trivial for the NodeMCU team to verify that a PR includes the necessary documentation. Furthermore, the documentation is merged automatically with the code if it moves from branch X to Y.
The documentation consists of a collection of Markdown files (see note on Markdown syntax at end of chapter) stored in the [`/docs`](docs) directory. With every commit a human readable and browsable version is automatically built with [Read the Docs](https://readthedocs.io/) (RTD). The public NodeMCU documentation can be found at [nodemcu.readthedocs.io](http://nodemcu.readthedocs.io/).
There are essentially only two things to keep in mind if you're contributing a PR:
- If you add functions to or change functions of an *existing module* you should modify the module's `.md` file in [`/docs/en/modules`](docs/en/modules). Adhere to the existing documentation structure and keep functions in alphabetical order.
- If you add a *new module* you should, in addition to the above, also add a reference for the new `.md` file to [`mkdocs.yml`](./mkdocs.yml) (lines 32+). Note that modules are ordered alphabetically here as well.
If you also want to verify that all is well with your Markdown files you can install Python-based [MkDocs](http://www.mkdocs.org/), which is used by RTD to build the static HTML files, and run `mkdocs serve` in the root of your NodeMCU firmware directory.
A note on Markdown *syntax*. As Mkdocs is Python-based it's no surprise it uses a [Python Markdown implementation](https://pythonhosted.org/Markdown/). The good news is that it sticks pretty closely to John Gruber's Markdown and also [supports tables and fenced code blocks](http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions) just like GitHub does.
If you're interested in some NodeMCU history you're welcome to read [issue #774](https://github.com/nodemcu/nodemcu-firmware/issues/774)
## Working with Git and GitHub
*Pull requests for new features and major fixes should be opened against the `dev` branch.*
......@@ -33,7 +50,7 @@ Avoid intermediate merge commits. [Rebase](https://www.atlassian.com/git/tutoria
1. `git checkout <branch-name>`
1. Make changes to the code base and commit them using e.g. `git commit -a -m 'Look ma, I did it'`
1. When you're done:
1. [Squash your commits](http://stackoverflow.com/a/5201642/131929) into one. There are several ways of doing this.
1. [Squash your commits](http://www.andrewconnell.com/blog/squash-multiple-git-commits-into-one) into one. There are [several ways](http://stackoverflow.com/a/5201642/131929) of doing this.
1. Bring your fork up-to-date with the NodeMCU upstream repo ([see below](#keeping-your-fork-in-sync)). Then rebase your branch on `dev` running `git rebase dev`.
1. `git push`
1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/) (PR) on GitHub.
......
# copyright (c) 2010 Espressif System
#
.NOTPARALLEL:
ifndef PDIR
endif
# SDK version NodeMCU is locked to
SDK_VER:=1.4.0
SDK_VER:=1.5.1
SDK_FILE_VER:=$(SDK_VER)_16_01_08
SDK_FILE_ID:=1046
SDK_FILE_SHA1:=374f689a5f9e47690d7b4cd2fc1a1094f3fd5a4f
# Ensure we search "our" SDK before the tool-chain's SDK (if any)
TOP_DIR:=$(dir $(lastword $(MAKEFILE_LIST)))
SDK_DIR:=$(TOP_DIR)sdk/esp_iot_sdk_v$(SDK_VER)
CCFLAGS:= -I$(TOP_DIR)sdk-overrides/include -I$(SDK_DIR)/include
TOP_DIR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST))))
SDK_DIR:=$(TOP_DIR)/sdk/esp_iot_sdk_v$(SDK_VER)
CCFLAGS:= -I$(TOP_DIR)/sdk-overrides/include -I$(SDK_DIR)/include
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld $(LDFLAGS)
#############################################################
......@@ -131,8 +131,8 @@ CCFLAGS += \
-mtext-section-literals
# -Wall
CFLAGS = $(CCFLAGS) $(DEFINES) $(EXTRA_CCFLAGS) $(INCLUDES)
DFLAGS = $(CCFLAGS) $(DDEFINES) $(EXTRA_CCFLAGS) $(INCLUDES)
CFLAGS = $(CCFLAGS) $(DEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
DFLAGS = $(CCFLAGS) $(DDEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
#############################################################
......@@ -171,11 +171,27 @@ $(BINODIR)/%.bin: $(IMAGEODIR)/%.out
# Should be done in top-level makefile only
#
all: .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
all: sdk_extracted pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
.PHONY: sdk_extracted
sdk_extracted: $(TOP_DIR)/sdk/.extracted-$(SDK_VER)
$(TOP_DIR)/sdk/.extracted-$(SDK_VER): $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip
mkdir -p "$(dir $@)"
(cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) && unzip $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_VER)*.zip esp_iot_sdk_v$(SDK_VER)/lib/* esp_iot_sdk_v$(SDK_VER)/ld/eagle.rom.addr.v6.ld esp_iot_sdk_v$(SDK_VER)/include/* )
rm -f $(SDK_DIR)/lib/liblwip.a
touch $@
$(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip:
mkdir -p "$(dir $@)"
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused http://bbs.espressif.com/download/file.php?id=$(SDK_FILE_ID) -O $@ || { rm -f "$@"; exit 1; }
(echo "$(SDK_FILE_SHA1) $@" | sha1sum -c -) || { rm -f "$@"; exit 1; }
clean:
$(foreach d, $(SUBDIRS), $(MAKE) -C $(d) clean;)
$(RM) -r $(ODIR)/$(TARGET)/$(FLAVOR)
$(RM) -r "$(TOP_DIR)/sdk"
clobber: $(SPECIAL_CLOBBER)
$(foreach d, $(SUBDIRS), $(MAKE) -C $(d) clobber;)
......@@ -202,6 +218,18 @@ endif
endif
endif
.PHONY: pre_build
ifneq ($(wildcard $(TOP_DIR)/server-ca.crt),)
pre_build:
python $(TOP_DIR)/tools/make_server_cert.py $(TOP_DIR)/server-ca.crt > $(TOP_DIR)/app/modules/server-ca.crt.h
DEFINES += -DHAVE_SSL_SERVER_CRT=\"server-ca.crt.h\"
else
pre_build:
@-rm -f $(TOP_DIR)/app/modules/server-ca.crt.h
endif
$(OBJODIR)/%.o: %.c
@mkdir -p $(OBJODIR);
$(CC) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $<
......
# **NodeMCU 1.4.0** #
# **NodeMCU 1.5.1** #
[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware)
[![Documentation Status](https://readthedocs.com/projects/nodemcu/badge/?version=dev)](http://nodemcu.readthedocs.io/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/nodemcu/nodemcu-firmware/blob/master/LICENSE)
###A lua based firmware for wifi-soc esp8266
- Build on [ESP8266 NONOS SDK 1.4.0](http://bbs.espressif.com/viewtopic.php?f=46&t=1124)
- Lua core based on [eLua project](http://www.eluaproject.net/)
- cjson based on [lua-cjson](https://github.com/mpx/lua-cjson)
- File system based on [spiffs](https://github.com/pellepl/spiffs)
- Open source development kit for NodeMCU [nodemcu-devkit-v0.9](https://github.com/nodemcu/nodemcu-devkit) [nodemcu-devkit-v1.0](https://github.com/nodemcu/nodemcu-devkit-v1.0)
### A Lua based firmware for ESP8266 WiFi SOC
# Summary
- Easy to program wireless node and/or Access Point
- Based on Lua 5.1.4 (without *debug, os* module.)
- Event-driven programming model preferred
- Built-in modules: node, json, file, timer, pwm, i2c, spi, onewire, net, mqtt, coap, gpio, wifi, adc, uart, bit, u8g, ucg, ws2801, ws2812, crypto, dht, rtc, sntp, bmp085, tls2561, hx711 and system api.
- Both Integer (less memory usage) and Float version firmware provided.
## Useful links
| Resource | Location |
| -------------- | -------------- |
| Developer Wiki | https://github.com/nodemcu/nodemcu-firmware/wiki |
| API docs | [NodeMCU api](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en) |
| Home | [nodemcu.com](http://www.nodemcu.com) |
| BBS | [Chinese BBS](http://bbs.nodemcu.com) |
| Docs | [NodeMCU docs](http://www.nodemcu.com/docs/) |
| Tencent QQ group | 309957875 |
| Windows flash tool | [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) |
| Linux flash tool | [Esptool](https://github.com/themadinventor/esptool) |
| ESPlorer GUI | https://github.com/4refr0nt/ESPlorer |
| NodeMCU Studio GUI | https://github.com/nodemcu/nodemcu-studio-csharp |
# Programming Examples
NodeMCU is an [eLua](http://www.eluaproject.net/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/). The firmware is based on the [Espressif NON-OS SDK 1.5.1](http://bbs.espressif.com/viewtopic.php?f=46&p=5315) and uses a file system based on [spiffs](https://github.com/pellepl/spiffs). The code repository consists of 98.1% C-code that glues the thin Lua veneer to the SDK.
Because Lua is a high level language and several modules are built into the firmware, you can very easily program your ESP8266. Here are some examples!
## Connect to your AP
```lua
ip = wifi.sta.getip()
print(ip)
--nil
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID", "password")
ip = wifi.sta.getip()
print(ip)
--192.168.18.110
```
The NodeMCU *firmware* is a companion project to the popular [NodeMCU dev kits](https://github.com/nodemcu/nodemcu-devkit-v1.0), ready-made open source development boards with ESP8266-12E chips.
## Manipulate hardware like an Arduino
```lua
pin = 1
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)
print(gpio.read(pin))
```
# Summary
## Write a network application in Node.js style
- Easy to program wireless node and/or access point
- Based on Lua 5.1.4 (without *debug, os* modules)
- Asynchronous event-driven programming model
- 40+ built-in modules
- Firmware available with or without floating point support (integer-only uses less memory)
- Up-to-date documentation at [https://nodemcu.readthedocs.io](https://nodemcu.readthedocs.io)
```lua
-- A simple http client
conn=net.createConnection(net.TCP, 0)
conn:on("receive", function(conn, payload) print(payload) end)
conn:connect(80, "115.239.210.27")
conn:send("GET / HTTP/1.1\r\nHost: www.baidu.com\r\n"
.. "Connection: keep-alive\r\nAccept: */*\r\n\r\n")
```
# Programming Model
## Or a simple HTTP server
The NodeMCU programming model is similar to that of [Node.js](https://en.wikipedia.org/wiki/Node.js), only in Lua. It is asynchronous and event-driven. Many functions, therefore, have parameters for callback functions. To give you an idea what a NodeMCU program looks like study the short snippets below. For more extensive examples have a look at the [`/lua_examples`](lua_examples) folder in the repository on GitHub.
```lua
-- A simple http server
srv=net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on("receive", function(conn,payload)
print(payload)
conn:send("<h1> Hello, NodeMCU.</h1>")
end)
conn:on("sent", function(conn) conn:close() end)
end)
```
## Connect to MQTT broker
```lua
-- init mqtt client with keepalive timer 120sec
m = mqtt.Client("clientid", 120, "user", "password")
-- setup Last Will and Testament (optional)
-- Broker will publish a message with qos = 0, retain = 0, data = "offline"
-- to topic "/lwt" if client doesn't send keepalive packet
m:lwt("/lwt", "offline", 0, 0)
m:on("connect", function(con) print("connected") end)
m:on("offline", function(con) print("offline") end)
-- on publish message receive event
m:on("message", function(conn, topic, data)
print(topic .. ":")
if data ~= nil then
print(data)
end
-- a simple HTTP server
srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on("receive", function(conn, payload)
print(payload)
conn:send("<h1> Hello, NodeMCU.</h1>")
end)
conn:on("sent", function(conn) conn:close() end)
end)
-- m:connect(host, port, secure, auto_reconnect, function(client) end)
-- for secure: m:connect("192.168.11.118", 1880, 1, 0)
-- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1)
m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end)
-- subscribe to topic with qos = 0
m:subscribe("/topic", 0, function(conn) print("subscribe success") end)
-- or subscribe multiple topics (topic/0, qos = 0; topic/1, qos = 1; topic2, qos = 2)
-- m:subscribe({["topic/0"]=0,["topic/1"]=1,topic2=2}, function(conn) print("subscribe success") end)
-- publish a message with data = hello, QoS = 0, retain = 0
m:publish("/topic", "hello", 0, 0, function(conn) print("sent") end)
m:close(); -- if auto-reconnect == 1, it will disable auto-reconnect and then disconnect from host.
-- you can call m:connect again
```
## UDP client and server
```lua
-- a udp server
s=net.createServer(net.UDP)
s:on("receive", function(s, c) print(c) end)
s:listen(5683)
-- a udp client
cu=net.createConnection(net.UDP)
cu:on("receive", function(cu, c) print(c) end)
cu:connect(5683, "192.168.18.101")
cu:send("hello")
```
## Do something shiny with an RGB LED
```lua
function led(r, g, b)
pwm.setduty(1, r)
pwm.setduty(2, g)
pwm.setduty(3, b)
end
pwm.setup(1, 500, 512)
pwm.setup(2, 500, 512)
pwm.setup(3, 500, 512)
pwm.start(1)
pwm.start(2)
pwm.start(3)
led(512, 0, 0) -- red
led(0, 0, 512) -- blue
```
## And blink it
```lua
lighton=0
tmr.alarm(1, 1000, 1, function()
if lighton==0 then
lighton=1
led(512, 512, 512)
else
lighton=0
led(0, 0, 0)
end
end)
```
## If you want to run something when the system boots
```lua
--init.lua will be executed
file.open("init.lua", "w")
file.writeline([[print("Hello, do this at the beginning.")]])
file.close()
node.restart() -- this will restart the module.
-- connect to WiFi access point
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID", "password")
```
## Add a simple telnet server to the Lua interpreter
# Documentation
```lua
-- a simple telnet server
s=net.createServer(net.TCP, 180)
s:listen(2323, function(c)
function s_output(str)
if(c~=nil)
then c:send(str)
end
end
node.output(s_output, 0) -- re-direct output to function s_ouput.
c:on("receive", function(c, l)
node.input(l) -- works like pcall(loadstring(l)) but support multiples separate lines
end)
c:on("disconnection", function(c)
node.output(nil) -- un-register the redirect output function, output goes to serial
end)
print("Welcome to NodeMCU world.")
end)
```
# Building the firmware
The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained right in this repository at [/docs](docs). The fact that the API documentation is mainted in the same repository as the code that *provides* the API ensures consistency between the two. With every commit the documentation is rebuilt by Read the Docs and thus transformed from terse Markdown into a nicely browsable HTML site at [https://nodemcu.readthedocs.io](https://nodemcu.readthedocs.io).
There are several options for building the NodeMCU firmware.
- How to [build the firmware](https://nodemcu.readthedocs.io/en/dev/en/build/)
- How to [flash the firmware](https://nodemcu.readthedocs.io/en/dev/en/flash/)
- How to [upload code and NodeMCU IDEs](https://nodemcu.readthedocs.io/en/dev/en/upload/)
- API documentation for every module
## Online firmware custom build
# Releases
Please try Marcel's [NodeMCU custom build](http://nodemcu-build.com) cloud service and you can choose only the modules you need, and download the firmware once built.
Due to the ever-growing number of modules available within NodeMCU, pre-built binaries are no longer made available. Use the automated [custom firmware build service](http://nodemcu-build.com/) to get the specific firmware configuration you need, or consult the [documentation](http://nodemcu.readthedocs.io/en/dev/en/build/) for other options to build your own firmware.
NodeMCU custom builds can build from all active branches (with the latest fixes).
This projects uses two main branches, `master` and `dev`. `dev` is actively worked on and it's also where PRs should be created against. `master` thus can be considered "stable" even though there are no automated regression tests. The goal is to merge back to `master` roughly every 2 months. Depending on the current "heat" (issues, PRs) we accept changes to `dev` for 5-6 weeks and then hold back for 2-3 weeks before the next snap is completed.
## Docker containerised build
A new tag is created every time `dev` is merged back to `master`. They are listed in the [releases section here on GitHub](https://github.com/nodemcu/nodemcu-firmware/releases). Tag names follow the \<SDK-version\>-master_yyyymmdd pattern.
See [https://hub.docker.com/r/marcelstoer/nodemcu-build/](https://hub.docker.com/r/marcelstoer/nodemcu-build/)
# Support
This Docker image includes the build toolchain and SDK. You just run the Docker image with your checked-out NodeMCU firmware repository (this one).
See [https://nodemcu.readthedocs.io/en/dev/en/support/](https://nodemcu.readthedocs.io/en/dev/en/support/).
You will need to see BUILD OPTIONS below, to configure the firmware before building.
# License
## Build it yourself
[MIT](https://github.com/nodemcu/nodemcu-firmware/blob/master/LICENSE) © [zeroday](https://github.com/NodeMCU)/[nodemcu.com](http://nodemcu.com/index_en.html)
See BUILD OPTIONS below, to configure the firmware before building.
# Build Options
### Minimum requirements:
The following sections explain some of the options you have if you want to [build your own NodeMCU firmware](http://nodemcu.readthedocs.io/en/dev/en/build/).
- unrar
- GNU autoconf, automake, libtool
- GNU gcc, g++, make
- GNU flex, bison, gawk, sed
- python, python-serial, libexpat-dev
- srecord
- The esp-open-sdk from https://github.com/pfalcon/esp-open-sdk
### Select Modules
### Build instructions:
Disable modules you won't be using to reduce firmware size and free up some RAM. The ESP8266 is quite limited in available RAM and running out of memory can cause a system panic. The default configuration is designed to run on all ESP modules including the 512 KB modules like ESP-01 and only includes general purpose interface modules which require at most two GPIO pins.
Assuming NodeMCU firmware is checked-out to `/opt/nodemcu-firmware`:
```sh
git clone --recursive https://github.com/pfalcon/esp-open-sdk.git /opt/esp-open-sdk
cd /opt/esp-open-sdk
make STANDALONE=y
PATH=/opt/esp-open-sdk/xtensa-lx106-elf/bin:$PATH
cd /opt/nodemcu-firmware
make
```
# BUILD OPTIONS
Disable modules you won't be using, to reduce firmware size on flash and
free more RAM. The ESP8266 is quite limited in available RAM, and running
out can cause a system panic.
## Edit `app/include/user_modules.h`
Comment-out the #define statement for unused modules. Example:
Edit `app/include/user_modules.h` and comment-out the `#define` statement for modules you don't need. Example:
```c
#ifdef LUA_USE_MODULES
#define LUA_USE_MODULES_NODE
#define LUA_USE_MODULES_FILE
#define LUA_USE_MODULES_GPIO
#define LUA_USE_MODULES_WIFI
#define LUA_USE_MODULES_NET
#define LUA_USE_MODULES_PWM
#define LUA_USE_MODULES_I2C
#define LUA_USE_MODULES_SPI
#define LUA_USE_MODULES_TMR
#define LUA_USE_MODULES_ADC
#define LUA_USE_MODULES_UART
#define LUA_USE_MODULES_OW
#define LUA_USE_MODULES_BIT
...
#define LUA_USE_MODULES_MQTT
// #define LUA_USE_MODULES_COAP
// #define LUA_USE_MODULES_U8G
// #define LUA_USE_MODULES_WS2801
// #define LUA_USE_MODULES_WS2812
// #define LUA_USE_MODULES_CJSON
#define LUA_USE_MODULES_CRYPTO
#define LUA_USE_MODULES_RC
#define LUA_USE_MODULES_DHT
#define LUA_USE_MODULES_RTCMEM
#define LUA_USE_MODULES_RTCTIME
#define LUA_USE_MODULES_RTCFIFO
#define LUA_USE_MODULES_SNTP
// #define LUA_USE_MODULES_BMP085
#define LUA_USE_MODULES_TSL2561
// #define LUA_USE_MODULES_HX711
#endif /* LUA_USE_MODULES */
...
```
## Tagging your build
### Tag Your Build
Identify your firmware builds by editing `app/include/user_version.h`
```c
#define NODE_VERSION "NodeMCU 1.4.0+myname"
#define NODE_VERSION "NodeMCU 1.5.1+myname"
#ifndef BUILD_DATE
#define BUILD_DATE "YYYYMMDD"
#define BUILD_DATE "YYYYMMDD"
#endif
```
## Setting the boot time serial interface rate
### Set UART Bit Rate
The initial baud rate at boot time is 9600 bps, but you can change this by
editing `app/include/user_config.h` and change BIT_RATE_DEFAULT, e.g.:
The initial baud rate at boot time is 115200bps. You can change this by
editing `BIT_RATE_DEFAULT` in `app/include/user_config.h`:
```c
#define BIT_RATE_DEFAULT BIT_RATE_115200
```
## Debugging
To enable runtime debug messages to serial console, edit `app/include/user_config.h`
```c
#define DEVELOP_VERSION
```
`DEVELOP_VERSION` changes the startup baud rate to 74880.
# Flash the firmware
## Flash tools for Windows
You can use the [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) to burn the firmware.
## Flash tools for Linux
Esptool is a python utility which can read and write the flash in an ESP8266 device. See https://github.com/themadinventor/esptool
## Preparing the hardware for firmware upgrade
To enable ESP8266 firmware flashing, the GPIO0 pin must be pulled low before
the device is reset. Conversely, for a normal boot, GPIO0 must be pulled high
or floating.
If you have a [NodeMCU Development Kit](http://www.nodemcu.com/index_en.html) then
you don't need to do anything, as the USB connection can pull GPIO0
low by asserting DTR, and reset your board by asserting RTS.
If you have an ESP-01 or other device without inbuilt USB, you will need to
enable flashing yourself by pulling GPIO0 low or pressing a "flash" switch.
## Files to burn to the flash
If you got your firmware from [NodeMCU custom builds](http://frightanic.com/nodemcu-custom-build) then you can flash that file directly to address 0x00000.
Otherwise, if you built your own firmware from source code:
- bin/0x00000.bin to 0x00000
- bin/0x10000.bin to 0x10000
Also, in some special circumstances, you may need to flash `blank.bin` or `esp_init_data_default.bin` to various addresses on the flash (depending on flash size and type).
If upgrading from `spiffs` version 0.3.2 to 0.3.3 or later, or after flashing any new firmware (particularly one with a much different size), you may need to run `file.format()` to re-format your flash filesystem.
You will know if you need to do this because your flash files disappeared, or they exist but seem empty, or data cannot be written to new files.
Note that, by default, the firmware runs an auto-baudrate detection algorithm so that typing a few characters at boot time will cause
the firmware to lock onto that baud rate (between 1200 and 230400).
# Connecting to your NodeMCU device
### Debugging
NodeMCU serial interface uses 9600 baud at boot time. To increase the speed after booting, issue `uart.setup(0,115200,8,0,1,1)` (ESPlorer will do this automatically when changing the speed in the dropdown list).
To enable runtime debug messages to serial console edit `app/include/user_config.h`
If the device panics and resets at any time, errors will be written to the serial interface at 115200 bps.
# User Interface tools
## Esplorer
Victor Brutskiy's [ESPlorer](https://github.com/4refr0nt/ESPlorer) is written in Java, is open source and runs on most platforms such as Linux, Windows, Mac OS, etc.
#### Features
- Edit Lua scripts and run on the ESP8266 and save to its flash
- Serial console log
- Also supports original AT firmware (reading and setting WiFi modes, etc)
## NodeMCU Studio
[NodeMCU Studio](https://github.com/nodemcu/nodemcu-studio-csharp) is written in C# and supports Windows. This software is open source and can write lua files to filesystem.
# OPTIONAL MODULES
####Use DS18B20 module extends your esp8266
```lua
-- read temperature with DS18B20
node.compile("ds18b20.lua") -- run this only once to compile and save to "ds18b20.lc"
t=require("ds18b20")
t.setup(9)
addrs=t.addrs()
-- Total DS18B20 numbers, assume it is 2
print(table.getn(addrs))
-- The first DS18B20
print(t.read(addrs[1],t.C))
print(t.read(addrs[1],t.F))
print(t.read(addrs[1],t.K))
-- The second DS18B20
print(t.read(addrs[2],t.C))
print(t.read(addrs[2],t.F))
print(t.read(addrs[2],t.K))
-- Just read
print(t.read())
-- Just read as centigrade
print(t.read(nil,t.C))
-- Don't forget to release it after use
t = nil
ds18b20 = nil
package.loaded["ds18b20"]=nil
```
####Operate a display with u8glib
u8glib is a graphics library with support for many different displays. The nodemcu firmware supports a subset of these.
Both I2C and SPI:
* sh1106_128x64
* ssd1306 - 128x64 and 64x48 variants
* ssd1309_128x64
* ssd1327_96x96_gr
* uc1611 - dogm240 and dogxl240 variants
SPI only:
* ld7032_60x32
* pcd8544_84x48
* pcf8812_96x65
* ssd1322_nhd31oled - bw and gr variants
* ssd1325_nhd27oled - bw and gr variants
* ssd1351_128x128 - gh and hicolor variants
* st7565_64128n - variants 64128n, dogm128/132, lm6059/lm6063, c12832/c12864
* uc1601_c128032
* uc1608 - 240x128 and 240x64 variants
* uc1610_dogxl160 - bw and gr variants
* uc1611 - dogm240 and dogxl240 variants
* uc1701 - dogs102 and mini12864 variants
U8glib v1.18.1
#####I2C connection
Hook up SDA and SCL to any free GPIOs. Eg. [u8g_graphics_test.lua](lua_examples/u8glib/u8g_graphics_test.lua) expects SDA=5 (GPIO14) and SCL=6 (GPIO12). They are used to set up nodemcu's I2C driver before accessing the display:
```lua
sda = 5
scl = 6
i2c.setup(0, sda, scl, i2c.SLOW)
```
#####SPI connection
The HSPI module is used, so certain pins are fixed:
* HSPI CLK = GPIO14
* HSPI MOSI = GPIO13
* HSPI MISO = GPIO12 (not used)
All other pins can be assigned to any available GPIO:
* CS
* D/C
* RES (optional for some displays)
Also refer to the initialization sequence eg in [u8g_graphics_test.lua](lua_examples/u8glib/u8g_graphics_test.lua):
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
```
#####Library usage
The Lua bindings for this library closely follow u8glib's object oriented C++ API. Based on the u8g class, you create an object for your display type.
SSD1306 via I2C:
```lua
sla = 0x3c
disp = u8g.ssd1306_128x64_i2c(sla)
```
SSD1306 via SPI:
```lua
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = u8g.ssd1306_128x64_hw_spi(cs, dc, res)
```
This object provides all of u8glib's methods to control the display.
Again, refer to [u8g_graphics_test.lua](lua_examples/u8glib/u8g_graphics_test.lua) to get an impression how this is achieved with Lua code. Visit the [u8glib homepage](https://github.com/olikraus/u8glib) for technical details.
#####Displays
I2C and HW SPI based displays with support in u8glib can be enabled. To get access to the respective constructors, add the desired entries to the I2C or SPI display tables in [app/include/u8g_config.h](app/include/u8g_config.h):
```c
#define U8G_DISPLAY_TABLE_I2C \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c) \
#define U8G_DISPLAY_TABLE_SPI \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcd8544_84x48_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcf8812_96x65_hw_spi) \
```
An exhaustive list of available displays can be found in the [u8g module wiki entry](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#u8g-module).
#####Fonts
u8glib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in [app/include/u8g_config.h](app/include/u8g_config.h) and recompile. Simply add the desired fonts to the font table:
```c
#define U8G_FONT_TABLE \
U8G_FONT_TABLE_ENTRY(font_6x10) \
U8G_FONT_TABLE_ENTRY(font_chikita)
```
They'll be available as `u8g.<font_name>` in Lua.
#####Bitmaps
Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This off-loads all data handling from the u8g module to generic methods for binary files. See [u8g_bitmaps.lua](lua_examples/u8glib/u8g_bitmaps.lua).
In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with [Online-Utility's Image Converter](http://www.online-utility.org/image_converter.jsp): Convert from XBM to MONO format and upload the binary result with [nodemcu-uploader.py](https://github.com/kmpm/nodemcu-uploader).
#####Unimplemented functions
- [ ] Cursor handling
- [ ] disableCursor()
- [ ] enableCursor()
- [ ] setCursorColor()
- [ ] setCursorFont()
- [ ] setCursorPos()
- [ ] setCursorStyle()
- [ ] General functions
- [ ] setContrast()
- [ ] setPrintPos()
- [ ] setHardwareBackup()
- [ ] setRGB()
- [ ] setDefaultMidColor()
####Operate a display with ucglib
Ucglib is a graphics library with support for color TFT displays.
Ucglib v1.3.3
#####SPI connection
The HSPI module is used, so certain pins are fixed:
* HSPI CLK = GPIO14
* HSPI MOSI = GPIO13
* HSPI MISO = GPIO12 (not used)
All other pins can be assigned to any available GPIO:
* CS
* D/C
* RES (optional for some displays)
Also refer to the initialization sequence eg in [GraphicsTest.lua](lua_examples/ucglib/GraphicsRest.lua):
```lua
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
```
#####Library usage
The Lua bindings for this library closely follow ucglib's object oriented C++ API. Based on the ucg class, you create an object for your display type.
ILI9341 via SPI:
```lua
cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2
res = 0 -- GPIO16, RES is optional YMMV
disp = ucg.ili9341_18x240x320_hw_spi(cs, dc, res)
```
This object provides all of ucglib's methods to control the display.
Again, refer to [GraphicsTest.lua](lua_examples/ucglib/GraphicsTest.lua) to get an impression how this is achieved with Lua code. Visit the [ucglib homepage](https://github.com/olikraus/ucglib) for technical details.
#####Displays
To get access to the display constructors, add the desired entries to the display table in [app/include/ucg_config.h](app/include/ucg_config.h):
```c
#define UCG_DISPLAY_TABLE \
UCG_DISPLAY_TABLE_ENTRY(ili9341_18x240x320_hw_spi, ucg_dev_ili9341_18x240x320, ucg_ext_ili9341_18) \
UCG_DISPLAY_TABLE_ENTRY(st7735_18x128x160_hw_spi, ucg_dev_st7735_18x128x160, ucg_ext_st7735_18) \
```
#####Fonts
ucglib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in [app/include/ucg_config.h](app/include/ucg_config.h) and recompile. Simply add the desired fonts to the font table:
```c
#define UCG_FONT_TABLE \
UCG_FONT_TABLE_ENTRY(font_7x13B_tr) \
UCG_FONT_TABLE_ENTRY(font_helvB12_hr) \
UCG_FONT_TABLE_ENTRY(font_helvB18_hr) \
UCG_FONT_TABLE_ENTRY(font_ncenR12_tr) \
UCG_FONT_TABLE_ENTRY(font_ncenR14_hr)
```
They'll be available as `ucg.<font_name>` in Lua.
####Control a WS2812 based light strip
```lua
-- set the color of one LED on GPIO2 to red
ws2812.writergb(4, string.char(255, 0, 0))
-- set the color of 10 LEDs on GPIO0 to blue
ws2812.writergb(3, string.char(0, 0, 255):rep(10))
-- first LED green, second LED white
ws2812.writergb(4, string.char(0, 255, 0, 255, 255, 255))
```
####coap client and server
```lua
-- use copper addon for firefox
cs=coap.Server()
cs:listen(5683)
myvar=1
cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1
all='[1,2,3]'
cs:var("all", coap.JSON) -- sets content type to json
-- function should tack one string, return one string.
function myfun(payload)
print("myfun called")
respond = "hello"
return respond
end
cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun
cc = coap.Client()
cc:get(coap.CON, "coap://192.168.18.100:5683/.well-known/core")
cc:post(coap.NON, "coap://192.168.18.100:5683/", "Hello")
```
####cjson
```lua
-- Note that when cjson deal with large content, it may fails a memory allocation, and leaks a bit of memory.
-- so it's better to detect that and schedule a restart.
--
-- Translate Lua value to/from JSON
-- text = cjson.encode(value)
-- value = cjson.decode(text)
json_text = '[ true, { "foo": "bar" } ]'
value = cjson.decode(json_text)
-- Returns: { true, { foo = "bar" } }
value = { true, { foo = "bar" } }
json_text = cjson.encode(value)
-- Returns: '[true,{"foo":"bar"}]'
```
####Read an HX711 load cell ADC.
Note: currently only chanel A with gain 128 is supported.
The HX711 is an inexpensive 24bit ADC with programmable 128x, 64x, and 32x gain.
```lua
-- Initialize the hx711 with clk on pin 5 and data on pin 6
hx711.init(5,6)
-- Read ch A with 128 gain.
raw_data = hx711.read(0)
```
####Universal DHT Sensor support
Support DHT11, DHT21, DHT22, DHT33, DHT44, etc.
Use all-in-one function to read DHT sensor.
```lua
pin = 5
status,temp,humi,temp_decimial,humi_decimial = dht.readxx(pin)
if( status == dht.OK ) then
-- Integer firmware using this example
print(
string.format(
"DHT Temperature:%d.%03d;Humidity:%d.%03d\r\n",
math.floor(temp),
temp_decimial,
math.floor(humi),
humi_decimial
)
)
-- Float firmware using this example
print("DHT Temperature:"..temp..";".."Humidity:"..humi)
elseif( status == dht.ERROR_CHECKSUM ) then
print( "DHT Checksum error." );
elseif( status == dht.ERROR_TIMEOUT ) then
print( "DHT Time out." );
end
#define DEVELOP_VERSION
```
......@@ -24,24 +24,24 @@ SPECIAL_MKTARGETS=$(APP_MKTARGETS)
SUBDIRS= \
user \
driver \
json \
upgrade \
platform \
libc \
lua \
lwip \
coap \
mqtt \
task \
u8glib \
ucglib \
smart \
wofs \
modules \
spiffs \
cjson \
crypto \
dhtlib \
tsl2561
tsl2561 \
net \
http
endif # } PDIR
......@@ -69,9 +69,8 @@ LD_FILE = $(LDDIR)/nodemcu.ld
COMPONENTS_eagle.app.v6 = \
user/libuser.a \
driver/libdriver.a \
json/libjson.a \
upgrade/libupgrade.a \
platform/libplatform.a \
task/libtask.a \
libc/liblibc.a \
lua/liblua.a \
lwip/liblwip.a \
......@@ -80,12 +79,13 @@ COMPONENTS_eagle.app.v6 = \
u8glib/u8glib.a \
ucglib/ucglib.a \
smart/smart.a \
wofs/wofs.a \
spiffs/spiffs.a \
cjson/libcjson.a \
crypto/libcrypto.a \
dhtlib/libdhtlib.a \
tsl2561/tsl2561lib.a \
http/libhttp.a \
net/libnodemcu_net.a \
modules/libmodules.a \
# Inspect the modules library and work out which modules need to be linked.
......@@ -112,10 +112,11 @@ LINKFLAGS_eagle.app.v6 = \
-lpp \
-lnet80211 \
-lwpa \
-lwpa2 \
-lmain \
-ljson \
-lsmartconfig \
-lssl \
-lcrypto \
$(DEP_LIBS_eagle.app.v6) \
-Wl,--end-group \
-lm
......
......@@ -192,6 +192,11 @@ void coap_setup(void);
void endpoint_setup(void);
int coap_buildOptionHeader(uint32_t optDelta, size_t length, uint8_t *buf, size_t buflen);
int check_token(coap_packet_t *pkt);
#include "uri.h"
int coap_make_request(coap_rw_buffer_t *scratch, coap_packet_t *pkt, coap_msgtype_t t, coap_method_t m, coap_uri_t *uri, const uint8_t *payload, size_t payload_len);
#ifdef __cplusplus
}
......
......@@ -15,6 +15,8 @@ ifndef PDIR
GEN_LIBS = libcrypto.a
endif
STD_CFLAGS=-std=gnu11 -Wimplicit
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
......
......@@ -122,6 +122,39 @@ int ICACHE_FLASH_ATTR crypto_hash (const digest_mech_info_t *mi,
}
int ICACHE_FLASH_ATTR crypto_fhash (const digest_mech_info_t *mi,
read_fn read, int readarg,
uint8_t *digest)
{
if (!mi)
return EINVAL;
// Initialise
void *ctx = (void *)os_malloc (mi->ctx_size);
if (!ctx)
return ENOMEM;
mi->create (ctx);
// Hash bytes from file in blocks
uint8_t* buffer = (uint8_t*)os_malloc (mi->block_size);
if (!buffer)
return ENOMEM;
int read_len = 0;
do {
read_len = read(readarg, buffer, mi->block_size);
mi->update (ctx, buffer, read_len);
} while (read_len == mi->block_size);
// Finish up
mi->finalize (digest, ctx);
os_free (buffer);
os_free (ctx);
return 0;
}
int ICACHE_FLASH_ATTR crypto_hmac (const digest_mech_info_t *mi,
const char *data, size_t data_len,
const char *key, size_t key_len,
......
......@@ -6,6 +6,7 @@
typedef void (*create_ctx_fn)(void *ctx);
typedef void (*update_ctx_fn)(void *ctx, const uint8_t *msg, int len);
typedef void (*finalize_ctx_fn)(uint8_t *digest, void *ctx);
typedef size_t ( *read_fn )(int fd, void *ptr, size_t len);
/**
* Description of a message digest mechanism.
......@@ -53,6 +54,16 @@ const digest_mech_info_t *crypto_digest_mech (const char *mech);
*/
int crypto_hash (const digest_mech_info_t *mi, const char *data, size_t data_len, uint8_t *digest);
/**
* Wrapper function for performing a one-in-all hashing operation of a file.
* @param mi A mech from @c crypto_digest_mech(). A null pointer @c mi
* is harmless, but will of course result in an error return.
* @param read Pointer to the read function (e.g. fs_read)
* @param readarg Argument to pass to the read function (e.g. file descriptor)
* @param digest Output buffer, must be at least @c mi->digest_size in size.
* @return 0 on success, non-zero on error.
*/
int crypto_fhash (const digest_mech_info_t *mi, read_fn read, int readarg, uint8_t *digest);
/**
* Generate a HMAC signature.
......
/*
* Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the copyright holders nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Johny Mattsson <jmattsson@dius.com.au>
*/
#include "mech.h"
#include "sdk-aes.h"
#include "c_string.h"
/* ----- AES ---------------------------------------------------------- */
static const struct aes_funcs
{
void *(*init) (const char *key, size_t keylen);
void (*crypt) (void *ctx, const char *in, char *out);
void (*deinit) (void *ctx);
} aes_funcs[] =
{
{ aes_encrypt_init, aes_encrypt, aes_encrypt_deinit },
{ aes_decrypt_init, aes_decrypt, aes_decrypt_deinit }
};
static bool do_aes (crypto_op_t *co, bool with_cbc)
{
const struct aes_funcs *funcs = &aes_funcs[co->op];
void *ctx = funcs->init (co->key, co->keylen);
if (!ctx)
return false;
char iv[AES_BLOCKSIZE] = { 0 };
if (with_cbc && co->ivlen)
c_memcpy (iv, co->iv, co->ivlen < AES_BLOCKSIZE ? co->ivlen : AES_BLOCKSIZE);
const char *src = co->data;
char *dst = co->out;
size_t left = co->datalen;
while (left)
{
char block[AES_BLOCKSIZE] = { 0 };
size_t n = left > AES_BLOCKSIZE ? AES_BLOCKSIZE : left;
c_memcpy (block, src, n);
if (with_cbc && co->op == OP_ENCRYPT)
{
const char *xor = (src == co->data) ? iv : dst - AES_BLOCKSIZE;
int i;
for (i = 0; i < AES_BLOCKSIZE; ++i)
block[i] ^= xor[i];
}
funcs->crypt (ctx, block, dst);
if (with_cbc && co->op == OP_DECRYPT)
{
const char *xor = (src == co->data) ? iv : src - AES_BLOCKSIZE;
int i;
for (i = 0; i < AES_BLOCKSIZE; ++i)
dst[i] ^= xor[i];
}
left -= n;
src += n;
dst += n;
}
funcs->deinit (ctx);
return true;
}
static bool do_aes_ecb (crypto_op_t *co)
{
return do_aes (co, false);
}
static bool do_aes_cbc (crypto_op_t *co)
{
return do_aes (co, true);
}
/* ----- mechs -------------------------------------------------------- */
static const crypto_mech_t mechs[] =
{
{ "AES-ECB", do_aes_ecb, AES_BLOCKSIZE },
{ "AES-CBC", do_aes_cbc, AES_BLOCKSIZE }
};
const crypto_mech_t *crypto_encryption_mech (const char *name)
{
size_t i;
for (i = 0; i < sizeof (mechs) / sizeof (mechs[0]); ++i)
{
const crypto_mech_t *mech = mechs + i;
if (strcasecmp (name, mech->name) == 0)
return mech;
}
return 0;
}
#ifndef _MECH_H_
#define _MECH_H_
#include "c_types.h"
typedef struct
{
const char *key;
size_t keylen;
const char *iv;
size_t ivlen;
const char *data;
size_t datalen;
char *out;
size_t outlen;
enum { OP_ENCRYPT, OP_DECRYPT } op;
} crypto_op_t;
typedef struct
{
const char *name;
bool (*run) (crypto_op_t *op);
uint16_t block_size;
} crypto_mech_t;
const crypto_mech_t *crypto_encryption_mech (const char *name);
#endif
#ifndef _SDK_AES_H_
#define _SDK_AES_H_
#define AES_BLOCKSIZE 16
void *aes_encrypt_init (const char *key, size_t len);
void aes_encrypt (void *ctx, const char *plain, char *crypt);
void aes_encrypt_deinit (void *ctx);
void *aes_decrypt_init (const char *key, size_t len);
void aes_decrypt (void *ctx, const char *crypt, char *plain);
void aes_decrypt_deinit (void *ctx);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment