diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt
new file mode 100644
index 0000000..0b83de3
--- /dev/null
+++ b/.github/.cSpellWords.txt
@@ -0,0 +1,1317 @@
+
+acceptmbox
+ACCEPTMBOX
+accomodate
+accoring
+acesses
+aclient
+additinal
+Additionaly
+Adleman
+Adpu
+adres
+Adrss
+aesni
+AESNI
+AHBCR
+ahbwritewaitinterval
+ahbwritewaitunit
+algorihtmic
+ALIGMENT
+Alligned
+alogortihm
+Alpar
+ALPAR
+alread
+alwasy
+AMBA
+Amira
+Ammendment
+Anack
+ANACK
+apdu
+Apdu
+APDU
+APDUCOMM
+apdus
+APDUs
+APDU's
+APDUV
+applicaiton
+approximative
+Arbtn
+argvp
+ARIBTARY
+armv
+assym
+Assym
+Assymmetric
+asym
+Asym
+asymetric
+asymm
+Asymm
+ASYMM
+asymmkey
+ATONEGOTIATION
+ATQA
+ATRFD
+Atrribute
+attestaion
+attribtes
+attst
+Attst
+ATTST
+authenticat
+autonego
+avialable
+avoidng
+awrseqindex
+awrseqnumber
+AXECCREFPEM
+BADOUTOFMEMORY
+baed
+Barreto
+BARRETO
+BBOOL
+B'EN'ETEAU
+Bhargavan
+biais
+bkpt
+BKPT
+Bleichenbacher's
+BMCR
+boundry
+bptr
+breif
+bufer
+BVIC
+byted
+bytestorecv
+caam
+CAAM
+Cachable
+cahced
+caluate
+calulating
+Catr
+CBCDR
+cbmc
+CBMC
+cbor
+Cbor
+CBOR
+CCGR
+ccid
+Ccid
+CCID
+ccide
+CCIDs
+CCLAN
+CCOSR
+CDEC
+CDMA
+cerdtials
+certficiates
+CERTIFCATES
+CESR
+cexpectednumberofparameters
+CFGDTCMSZ
+CHALLANGE
+charac
+CHCONSTL
+CHHLSE
+chkey
+chnage
+Chnl
+CKIL
+CLCOK
+cleard
+cliip
+CLKCFG
+CLKO
+CLKS
+CLKSOURCE
+CLRAHBRXBUF
+CLRAHBTXBUF
+cmac
+Cmac
+CMAC
+Cmdk
+cmse
+CMSE
+cmsis
+CMSIS
+CNST
+Cntx
+cofactor
+commmand
+commuication
+communicatation
+compilant
+Conditionaly
+CONDTIONS
+confg
+CONFICT
+configcmdseqs
+configurat
+conly
+Connnection
+convertdertopemformat
+convertpemtoder
+coreid
+coremqtt
+CORON
+correclty
+couter
+coutermeasueres
+coverity
+CPCL
+CPDU
+cplc
+Cplc
+CPLC
+cpsid
+cpsie
+Credentialnfo
+credtialstate
+critial
+crls
+Cryptombedtls
+Crypyto
+crytpo
+Crytpo
+Csession
+cspadsettingoverride
+csrs
+CSRS
+cssetuptime
+CUST
+customisation
+Customisation
+customlut
+cyphertext
+cyrptogrpahic
+Daemen
+DATAW
+DATSZ
+DBICR
+Dcap
+DCDC
+dcdx
+deactive
+DEBUGF
+Decription
+deinitializes
+Deinitializes
+delceration
+delimitor
+demostration
+demultiplexing
+Derviation
+descritpor
+desctription
+Deteceted
+devicemodetpe
+devleoper
+dgst
+dgug
+dhmlen
+DHMLEN
+differnt
+digestbyname
+Dindex
+DLMS
+DMBEDTLS
+Docuemntation
+doent
+doesnt
+dqspadsettingoverride
+drbg
+Drbg
+DRBG
+Dsmr
+DTCM
+DTCMSZ
+dtype
+DWNLD
+eccgfp
+ecdaa
+ECDAA
+ecdh
+Ecdh
+ECDH
+ecdhctx
+Ecdsakey
+ecdsasigner
+echci
+ecid
+ecjpake
+ECJPAKE
+Ecka
+ECKA
+Eckabit
+eckey
+ECKEY
+eckeypair
+ecount
+ecparameters
+ecparams
+ecpubkey
+ECPUBLICKEY
+ecrt
+Ecrt
+ecrypto
+EDDSA
+EDEV
+EEPROM
+egovaccelerators
+EGOVACCELERATORS
+ehci
+Ehci
+EHCI
+EMBSE
+emsa
+EMSA
+emvl
+EMVL
+EMVSIM
+Endiannes
+ENDOPOINT
+enets
+ENTEROPI
+ENTERQPI
+ephemral
+equivlant
+ERDF
+ERRIRQ
+esdsa
+esdsaigner
+ESEC
+Espressif
+ethernetif
+ETHERNETIF
+ethip
+Euicc
+evkb
+EVKB
+evkbmimxrt
+evkmimx
+evkmimxrt
+evnet
+exaple
+exceeed
+Exhange
+EXITQPI
+exmaple
+explictily
+Exponenciation
+exponentiaton
+Expresso
+Expsosed
+EXTCLK
+extented
+faild
+familiy
+fdata
+FDIS
+Feistel
+fetchup
+fileb
+Findex
+fira
+FIRALITE
+FLASHIAP
+flashm
+Flexio
+FLEXIO
+FLEXSPIA
+flexspirootclk
+fnet
+fout
+Fout
+frdm
+FRDM
+frdmk
+FROHF
+fromisr
+FRTOS
+fsanitize
+Fsci
+Fsdi
+fucntion
+Funciton
+gapplet
+gctx
+gdir
+GDIR
+gecc
+GECC
+geerator
+genertor
+genral
+GETCPLC
+gfile
+ghlse
+GMAC
+gmaster
+gmbedtls
+GNUCC
+gnxpese
+GPCNT
+GPCS
+gpdata
+gpio
+Gpio
+GPIO
+GPIOA
+grsa
+Gruss
+gsss
+gtimer
+gusleep
+gvar
+gxlen
+gylen
+halfclkfornonreadcmd
+Hanle
+happn
+hasle
+havege
+HAVEGE
+HCASN
+HEADR
+HEDABOU
+hkdf
+Hkdf
+HKDF
+HKDK
+HLCRYPT
+hlse
+Hlse
+HLSE
+HLSEAPI
+hlseret
+HSRUN
+hwaddr
+HWADDR
+hwcrypto
+hyst
+Hyst
+IACR
+iapfun
+iblock
+Iblock
+ICCPOWERON
+idendntifiers
+idntifier
+idobj
+ifindiscards
+ifinoctets
+ifoutdiscards
+ifouterrors
+ifoutoctets
+ifsc
+Ifsc
+IFSC
+IFSD
+IICIF
+impelementation
+implemetation
+implemntation
+implmentation
+IMXRT
+IMXRTXXX
+IMXRTYYYY
+increament
+inded
+indentifier
+indicaated
+initialzie
+Initilaize
+initilialized
+Initilising
+initilization
+inoffset
+Insufficinet
+INTEN
+Interm
+internaly
+Intialise
+Inversed
+INVQ
+IOCR
+iomuxc
+Iomuxc
+IOMUXC
+IOSB
+IOSSDATALAT
+ipcmd
+IPCMD
+ipcmdserialclkfreq
+IPCR
+ipinreceives
+ipoutrequests
+ipriority
+IPSR
+IPTXDAT
+iqmp
+iret
+IRQN
+IRQS
+isbufferable
+ISSI
+ISSN
+isuniformblocksize
+jcop
+Jcop
+JCOP
+jcopx
+jitp
+JITP
+jitr
+Jitr
+JITR
+jrcp
+JRCP
+jrcplib
+jrcpv
+jrif
+jsmn
+JSMN
+jsmntok
+jsoneq
+Kalycito
+Karthikeyan
+kboot
+KBOOT
+kbps
+kbyte
+kbytes
+Kbytes
+kconfig
+kestore
+khci
+Khci
+KHCI
+kinv
+klass
+koblitz
+Koblitz
+KOBLITZ
+KOCHER
+ksdk
+KSDK
+kvstore
+KVSTORE
+laready
+laso
+lasr
+lcdif
+Lcdif
+LCDIF
+LDRH
+lefover
+lengh
+Lengh
+lenght
+Lenght
+Lengthn
+lenth
+lhash
+licc
+Licc
+litte
+lnger
+lnumtries
+localip
+locl
+logicaly
+loopif
+lpathcount
+LPBYTE
+lpcip
+LPCIP
+lpcxpresso
+LPCXPRESSO
+lpspi
+Lpspi
+LPSPI
+lpthread
+Lpuart
+LPUART
+lset
+lutcustomseq
+lutcustomseqenable
+lvds
+LVDS
+lwipopts
+LWIPOPTS
+MANAG
+mannual
+MAXASYMKEYLENGTH
+maxfd
+maxium
+Maxium
+mbed
+Mbed
+MBED
+mbedcrypto
+MBEDCRYPTO
+mbedpkaltctx
+MBEDTLD
+MBEDTLSSL
+mbedts
+MCFGR
+MCIMX
+MCLK
+mctx
+mcuboot
+Mcuboot
+MCUBOOT
+MCU's
+mcux
+Mcux
+MCUX
+mcuxpresso
+MCUXPRESSO
+mdctx
+mdinfo
+mdio
+MDIO
+MDLM
+mebd
+mebdtls
+memeory
+memoy
+memp
+MEMP
+Menezes
+merkle
+Merkle
+MFDF
+Mfinish
+mflash
+MFLASH
+mifare
+Mifare
+MIFARE
+Mimick
+MIMXRT
+MINASYMKEYLENGTH
+miscelaneous
+misra
+MISRA
+mmcau
+MMCAU
+modn
+Modulde
+moduls
+MODX
+montogomery
+mosquitto
+Mosquitto
+MOVS
+mpis
+mqtt
+Mqtt
+MQTT
+mqttbadparameter
+mqttconnected
+mqttexample
+mqttnotconnected
+MQTT's
+mqttsuccess
+MRDR
+MSTCTL
+msticks
+MSTSTSTPERR
+msvcrt
+msvcrtd
+MTDR
+Mustapha
+mutliple
+mwlog
+myargv
+mynewt
+myrand
+NACKADR
+NACKDAT
+nacked
+Naehrig
+NAEHRIG
+neable
+necesarily
+NEEDCLK
+needexitnocmdmode
+needrestorenocmdmode
+negotation
+netif
+NETIF
+netifapi
+NFCA
+NISTK
+nistp
+NISTP
+NOASSERT
+NOCLOSE
+nohc
+Nohc
+nomalloc
+nonoadjacent
+noout
+normalised
+NSPE
+NVIC
+NXCONF
+NXEC
+NXENSURE
+nxpese
+NXPNCI
+nxpnfcrdlib
+NXPNFCRDLIB
+NXPRT
+NXSCP
+Oadjacent
+Obect
+OBEX
+occured
+octat
+Oftags
+oliveri
+Oliveri
+onego
+Oorschot
+OOSEQ
+OPTIM
+OPTSA
+ordern
+OSCNT
+ossl
+otaexample
+otamqttsuccess
+otapalsuccess
+OTFAD
+Outgoung
+outpubufferlength
+Outx
+overisght
+paased
+packetid
+pake
+PAKE
+palpnprotos
+papplet
+parame
+pareameters
+pauth
+pauthctx
+pbits
+pbkeylen
+pbuff
+pbuffer
+pbufs
+Pbufs
+PBUFS
+pcbs
+PCCA
+pccmdintprocesscommand
+pccommand
+pccommandinput
+pccommandstring
+pcdestination
+pcertificatepath
+pchannl
+pchelpstring
+pchip
+pcks
+PCKS
+pclabelname
+pclientcertlabel
+pclientidentifier
+pcmac
+pcname
+pcommandbuffer
+pcommandbufferindex
+pcommandcontext
+pcommandtorelease
+pcommandtosend
+pconsoleinput
+PCONTEXT
+pcoutputbuffer
+pcsc
+PCSC
+pcsclite
+pcservercertificate
+pctopic
+pctopicfilter
+pcurrpcb
+pcurve
+pcwritebuffer
+pdata
+pdecrypted
+pdek
+pderived
+pdev
+pdfalse
+pdpass
+PDRUNCFG
+pdyn
+penc
+pencrypted
+perclk
+Perclk
+PERCLK
+Perfom
+periph
+Periph
+PERIPH
+periphmux
+perso
+Perso
+PERSO
+pestablishedconnection
+pfilecontext
+phash
+phbal
+PHESECID
+PHESESTATUS
+PHESESTBLOWER
+PHESESTSHL
+PHESESTVAL
+PHESETYPES
+phhal
+PHHAL
+phkdf
+PHNXPESE
+PHNXPESEPROTO
+phost
+phostname
+phyksz
+PICC
+PINEL
+pirng
+pkha
+PKHA
+pkparse
+pkwrite
+plaform
+Plaform
+platf
+Platf
+PLATF
+platfscp
+PLATFSCP
+plls
+pmac
+pmeth
+pmethods
+pmore
+pmqttagentcontext
+pmsg
+pmsgctx
+pnetworkcontext
+pnetworkcredentials
+pnxpese
+pobj
+PODF
+portabilty
+PORTSZ
+poutnumestablishedconnections
+poutnumtcpopenports
+poutnumudpopenports
+pouttcpportsarray
+poutudpportsarray
+poweron
+ppassword
+pprivatekeylabel
+ppublishinfo
+ppuc
+ppvcontext
+ppxidletaskstackbuffer
+ppxtimertaskstackbuffer
+prandom
+preceivedcommand
+Precitec
+preperiph
+presponse
+prfx
+primality
+Primality
+PRIVDEFENA
+PRJECT
+procedue
+PROCTOCL
+prootca
+Proro
+protocl
+provisiong
+PRSWL
+PRTOL
+prvgeneraterandombytes
+prvgettimems
+prvincomingpublish
+prvkey
+PRVKEY
+prvupdatedeltacallback
+prvupdaterejectedcallback
+Psakey
+pshared
+Pskg
+psslcontext
+ptaskparam
+ptun
+pubuf
+pucdata
+puchash
+pucmsg
+pucpayload
+pucrandom
+pucreadbuffer
+pucreceivebuffer
+pucsig
+Purnank
+pval
+pvarg
+pvctx
+pvincomingpublishcallbackcontext
+pvmetricsreport
+pvparam
+pvparameters
+pvportcalloc
+pvportmalloc
+pvrng
+PWDN
+pwer
+pxbuffer
+pxcerthandle
+pxcertificate
+pxcertificatecontext
+pxcommand
+pxcommandcontext
+pxcommandinterpreter
+pxcommandtoregister
+pxctx
+pxmqttcontext
+pxnetworkcontext
+pxnetworkrecv
+pxnetworksend
+pxnext
+pxparams
+pxpublishcallback
+pxpublishinfo
+pxreturninfo
+pxsiglen
+pxsubscriptioncontext
+pxthread
+pxtlscontext
+Pxxx
+PYHSICAL
+qinv
+QINV
+Qxxx
+ransceive
+RAPDU
+RASR
+RBAR
+rcon
+RCON
+rcrt
+Rcrt
+reacheable
+READID
+readsampleclksrc
+reasing
+reasonnable
+receivetimeoutms
+recevied
+RECIEVE
+recieved
+Recieved
+reco
+RECO
+recvmbox
+RECVMBOX
+refernce
+referneced
+remoteip
+RENC
+renego
+RENEGO
+Reponse
+reponsed
+requets
+requiste
+Requistie
+resouces
+resoures
+Resynch
+RESYNCH
+resynchronished
+retieved
+Retreieve
+retruend
+retvak
+REVOCERY
+revovery
+Rfbo
+Rframe
+RFRAME
+RIHN
+Rijmen
+Rmac
+RMAC
+rnack
+RNACK
+RNAK
+RNGA
+rodata
+roolback
+rootca
+ROOTCA
+rootcasize
+RROUND
+rsaes
+RSAES
+rsassa
+RSASSA
+rsma
+RSSN
+RSTG
+RWDS
+RXBD
+RXBUFF
+RXEMPTY
+Rxframe
+rxlen
+RXREADY
+safly
+sbox
+SCARD
+SCARDCONTEXT
+SCARDHANDLE
+SCCOM
+SCCOMSERIAL
+SCCOMSOCKET
+Schwarz
+SCII
+SCIIC
+sclk
+SCLK
+sclkpadsettingoverride
+SCPO
+SCPP
+SCSPI
+scsv
+SCSV
+sdcard
+SDCARD
+sdpv
+SDRAMCR
+S'ebastien
+Sebd
+SECG
+SECK
+SECO
+secp
+Secp
+SECP
+segger
+Segger
+seggerrtt
+selectitvely
+semc
+Semc
+SEMC
+SENC
+sendtimeoutms
+seperate
+seperatly
+sepolicies
+SEPRATOR
+Seqs
+serialclkfreq
+servinfo
+sesion
+seucre
+sflash
+sflashpadtype
+sframe
+Sframe
+SFRAME
+shoudl
+signining
+signiture
+signiutre
+simulatenously
+simulateously
+simw
+SIMW
+Singature
+sligtly
+slotid
+slve
+SMAC
+smbus
+SMBUS
+smcom
+SMCOM
+SMCOMJRCP
+SMCOMPCSC
+SMCOMPN
+SMCOMSCI
+SMCOMT
+SNEP
+sobj
+sockapdu
+Soll
+spdif
+Spdif
+SPDIF
+spdy
+specifiedecdomain
+SRMAC
+SRST
+srtp
+SRTP
+sscp
+SSCP
+sscpprop
+SSLV
+sssapisdll
+sssapisw
+ssse
+sssftr
+SSSFTR
+stefano
+Stefano
+Storgae
+STRCH
+stringop
+stringz
+Structrues
+strucute
+strucutre
+submoduled
+subsciption
+subsrcibed
+succes
+SUCCES
+succesful
+succesfull
+succesfully
+Successed
+sucesseding
+summands
+symm
+Symm
+SYMM
+symmkey
+Synbolic
+SYSCLK
+SYSMPU
+systme
+sytem
+Sytem
+szbin
+tansient
+TCCKST
+TCCKTS
+tdes
+TDES
+tenenancy
+Tera
+Teraterm
+thare
+theoritical
+theortical
+timeoutinms
+timeoutms
+TLSC
+TOKDNEEN
+TOLERENCE
+totoal
+TPDU
+tpkey
+trainsient
+transceive
+Transceive
+TRANSCEIVE
+transcive
+Transcive
+transed
+trng
+TRNG
+truely
+TUNN
+TXAK
+TXBD
+TXBUFF
+TXCAL
+txrx
+TXRX
+Uboot
+uccount
+UCOSII
+UCOSIII
+ucqos
+ucrt
+UDBL
+udpated
+UICC
+UIDL
+uihashlen
+Uinquie
+ulbytesreceived
+ulbytessent
+ulclienttoken
+ulcurrentversion
+ulevk
+ulglobalentrytimems
+ullocalipaddr
+ulnextsubscribemessageid
+ulnotification
+ulnotificationvalue
+ulnumpubsubtasks
+ulpacketsreceived
+ulpacketssent
+ulrecievedtoken
+ulremoteipaddr
+ulservercertificatelength
+ulsize
+ulvaluelen
+unaccelerated
+Unallocate
+Unblind
+unblinded
+Unblinding
+unconf
+Unconfigure
+unefficiently
+Unhexify
+unitl
+UNLCOK
+unprotect
+UNPROTECT
+Unstall
+uplayer
+USART
+Usbfs
+Usbh
+Usbhs
+USBHS
+USBHSD
+USBHSH
+Usbhsl
+USBMPU
+Usdhc
+USDHC
+uslocalport
+usremoteport
+ustopicfilterlength
+UWBIOT
+uxpriority
+uxstacksize
+valdidation
+validiy
+valus
+vapplicationgetidletaskmemory
+vapplicationgettimertaskmemory
+varaibles
+varibale
+varifies
+Vbat
+VBAT
+vccorlib
+vccorlibd
+vcom
+Vcom
+VCOM
+VDIV
+verbsity
+Verfiication
+Verfying
+verif
+VLAUE
+vloggingprintf
+vportfree
+VREF
+vsel
+Vsel
+VSEL
+vsimplesubscribepublishtask
+VTOR
+WATSONP
+wcrt
+Wcrt
+wctx
+whan
+Whle
+WINRT
+Withmbed
+WITHOUTSEQN
+WITHSEQN
+WNCMD
+WSADATA
+wtls
+WTLS
+wuth
+Xbar
+xcleansession
+xcryptcbc
+xcryptecb
+xecparams
+xecpoint
+Xevent
+xhelpcommand
+xlength
+xmanageresubscription
+xmbedsslconfig
+xmbedsslctx
+xmdalg
+xmetricsreportlength
+xmodulus
+xnetworkrecv
+xnetworksend
+xored
+xotapalresetdevice
+xoutputbufferlen
+xparameternumber
+xpayloadlength
+Xpfd
+Xpresso
+xprop
+xpublicexponent
+xpublickeytype
+xqos
+xrandomlength
+xreadlength
+xreceivelength
+xresult
+xreturn
+xreturned
+xreturnstatus
+xsession
+xstatetowait
+xtal
+Xtal
+XTAL
+XTALOSC
+xtaskcreate
+xtasknotify
+xtea
+XTEA
+xtemplate
+xthingnamelength
+xtickstowait
+xtlschandshakesuccessful
+xtopicfilterlength
+xtopiclength
+xtra
+xtrue
+xwritebufferlen
+yotta
+YOTTA
+zeroize
+ZEROIZE
+zvyed
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fbab545..df81448 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,37 +10,18 @@ jobs:
spell-check:
runs-on: ubuntu-latest
steps:
- - name: Checkout Parent Repo
- uses: actions/checkout@v2
- with:
- ref: main
- repository: FreeRTOS/CI-CD-Github-Actions
- path: actions
- name: Clone This Repo
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
+ - name: Run spellings check
+ uses: FreeRTOS/CI-CD-Github-Actions/spellings@main
with:
- ref: ${{ github.event.pull_request.head.sha }}
- path: ./NXPRef
- - name: Install spell
- run: |
- sudo apt-get install spell
- sudo apt-get install util-linux
- - name: Check spelling
- run: |
- PATH=$PATH:actions/spellings/tools
- # Make sure that the portable directory is not included in the spellcheck.
- sed -i "s/-iname \\\\\*.\[ch\] -o/-not -path \\\*Middleware\\\\\/NXP\\\* -iname \\\\\*.\[ch\] -o/g" actions/spellings/tools/find-unknown-comment-words
- find-unknown-comment-words --directory NXPRef/ --lexicon NXPRef/lexicon.txt
- if [ "$?" = "0" ]; then
- exit 0
- else
- exit 1
- fi
+ path: ./
+
link-verifier:
runs-on: ubuntu-latest
steps:
- name: Clone This Repo
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Run link verifier
uses: FreeRTOS/CI-CD-Github-Actions/link-verifier@main
with:
@@ -51,7 +32,7 @@ jobs:
formatting:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Install Uncrustify
run: sudo apt-get install uncrustify
- name: Run Uncrustify
@@ -78,9 +59,9 @@ jobs:
git-secrets:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Checkout awslabs/git-secrets
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
with:
repository: awslabs/git-secrets
ref: master
@@ -91,3 +72,17 @@ jobs:
run: |
git-secrets --register-aws
git-secrets --scan
+
+ verify-manifest:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: true
+ fetch-depth: 0
+
+ - name: Run manifest verifier
+ uses: FreeRTOS/CI-CD-GitHub-Actions/manifest-verifier@main
+ with:
+ path: ./
+ fail-on-incorrect-version: true
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index 8ac0b83..ada8d8a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -25,9 +25,6 @@
[submodule "Middleware/FreeRTOS/pkcs11"]
path = Middleware/FreeRTOS/pkcs11
url = https://github.com/amazon-freertos/pkcs11.git
-[submodule "Middleware/AWS/ota"]
- path = Middleware/AWS/ota
- url = https://github.com/aws/ota-for-aws-iot-embedded-sdk
[submodule "Middleware/tinycbor"]
path = Middleware/tinycbor
url = https://github.com/intel/tinycbor.git
@@ -49,3 +46,9 @@
[submodule "Middleware/FreeRTOS/tests"]
path = Middleware/FreeRTOS/tests
url = https://github.com/FreeRTOS/FreeRTOS-Libraries-Integration-Tests.git
+[submodule "Middleware/AWS/mqtt-stream"]
+ path = Middleware/AWS/mqtt-stream
+ url = https://github.com/aws/aws-iot-core-mqtt-file-streams-embedded-c
+[submodule "Middleware/AWS/jobs"]
+ path = Middleware/AWS/jobs
+ url = https://github.com/aws/Jobs-for-AWS-IoT-embedded-sdk.git
diff --git a/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1060_dir_part.xml b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1060_dir_part.xml
new file mode 100644
index 0000000..b7735f3
--- /dev/null
+++ b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1060_dir_part.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1060_list.xml b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1060_list.xml
new file mode 100644
index 0000000..14ba535
--- /dev/null
+++ b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1060_list.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1062_internal.xml b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1062_internal.xml
new file mode 100644
index 0000000..53ad435
--- /dev/null
+++ b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/MIMXRT1062_internal.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+ MIMXRT1062xxxxB
+ MIMXRT1060
+ NXP
+
+
+
+
+
+
+
+
+ Cortex-M7
+ Cortex-M
+
+
+
diff --git a/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/crt_directory.dtd b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/crt_directory.dtd
new file mode 100644
index 0000000..1bf38a8
--- /dev/null
+++ b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/crt_directory.dtd
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/crt_infolist.dtd b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/crt_infolist.dtd
new file mode 100644
index 0000000..396f962
--- /dev/null
+++ b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/crt_infolist.dtd
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/info.properties b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/info.properties
new file mode 100644
index 0000000..97b0b28
--- /dev/null
+++ b/.mcuxpressoide_packages_support/MIMXRT1062xxxxB_support/info.properties
@@ -0,0 +1,7 @@
+#MCUXpresso IDE part support
+#Thu Feb 29 14:14:00 PST 2024
+sdk.id=SDK_2.x_MIMXRT1060-EVKB
+sdk.build=801 2024-01-15
+device.version=1.0.0
+sdk.version=2.15.000
+device.id=MIMXRT1062xxxxB
diff --git a/.mcuxpressoide_packages_support/crt_directory.dtd b/.mcuxpressoide_packages_support/crt_directory.dtd
new file mode 100644
index 0000000..1bf38a8
--- /dev/null
+++ b/.mcuxpressoide_packages_support/crt_directory.dtd
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/crt_directory.xml b/.mcuxpressoide_packages_support/crt_directory.xml
new file mode 100644
index 0000000..a0b9670
--- /dev/null
+++ b/.mcuxpressoide_packages_support/crt_directory.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/crt_infolist.dtd b/.mcuxpressoide_packages_support/crt_infolist.dtd
new file mode 100644
index 0000000..396f962
--- /dev/null
+++ b/.mcuxpressoide_packages_support/crt_infolist.dtd
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.mcuxpressoide_packages_support/info.properties b/.mcuxpressoide_packages_support/info.properties
new file mode 100644
index 0000000..55d7b8d
--- /dev/null
+++ b/.mcuxpressoide_packages_support/info.properties
@@ -0,0 +1,5 @@
+#MCUXpresso IDE
+#Thu Feb 29 14:14:00 PST 2024
+product.name=MCUXpresso IDE v11.9.0 [Build 2144] [2024-01-05]
+product.version=11.9.0
+product.build=2144
diff --git a/.mcuxpressoide_packages_support/readme.txt b/.mcuxpressoide_packages_support/readme.txt
new file mode 100644
index 0000000..00460b7
--- /dev/null
+++ b/.mcuxpressoide_packages_support/readme.txt
@@ -0,0 +1,2 @@
+This folder is automatically created and contains the SDK part support for the IDE
+*** DO NOT REMOVE OR MODIFY, YOUR CHANGES WILL BE OVERWRITTEN ON SDK REFRESH ***
\ No newline at end of file
diff --git a/GSG.md b/GSG.md
index ba101d4..8f5d509 100644
--- a/GSG.md
+++ b/GSG.md
@@ -88,7 +88,7 @@ Many of these steps are automated in production environments.
[Configuration basics](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)
to configure the basic settings (security credentials, the default AWS output format and the default AWS Region)
that AWS CLI uses to interact with AWS.
-* A serial terminal application, such as [Tera Term](https://ttssh2.osdn.jp/index.html.en).
+* A serial terminal application, such as [Tera Term](https://teratermproject.github.io/index-en.html).
## 2 Hardware and Software Setup
@@ -312,10 +312,9 @@ Follow the steps below to set up an AWS account and provision the device:

-1. Copy the PEM certificate from the terminal console and save to a file. Log into your AWS account, go to the AWS IoT Console, choose "Secure", choose
- "Certificates", and then choose "Create". Next to "Use my certificate" choose "Get started". On
- "Select a CA" choose "Next". On "Register existing device certificates", choose "Select certificates" and
- select the PEM file you just created. Select "Activate all" then choose "Register certificates".
+1. Copy the PEM certificate from the terminal console and save to a file. Log into your AWS account, go to the AWS IoT Console, choose "Security", choose
+ "Certificates", and then click on the drop down "Add Certificate" and choose "Register Certificate". Choose "CA is not registered with AWS IoT" and
+ select the PEM file you just created. Select "Activate" then choose "Register".
For more detailed instructions, see [Register a client certificate signed by an unregistered CA (console)](https://docs.aws.amazon.com/iot/latest/developerguide/manual-cert-registration.html#manual-cert-registration-console-noca).

@@ -480,7 +479,7 @@ perform OTA updates.
1. Import the code-signing certificate, private key, and certificate chain into the AWS
Certificate Manager.
```
- aws acm import-certificate --certificate fileb://ecdsasigner.crt --private-key fileb://ecdsasigner.key
+ aws acm import-certificate --certificate fileb://ecdsasigner.crt --private-key fileb://ecdsasigner.key --region=
```
1. Confirm the ARN for your certificate. You need this ARN when you create an OTA update job.
@@ -865,4 +864,4 @@ For more information, `.\devicetester_win_x86-64.exe help` will show all availab
When you run IDT, a `results/uuid` directory is generated that will contain all the logs and other information associated with your test run. This allows you to debug any failures.
-*Note: Please run qualification test without provision mode (set appmainPROVISIONING_MODE to 0 in [app_main.c](./examples/evkbmimxrt1060/test/app_main.c)).*
\ No newline at end of file
+*Note: Please run qualification test without provision mode (set appmainPROVISIONING_MODE to 0 in [app_main.c](./examples/evkbmimxrt1060/test/app_main.c)).*
diff --git a/Middleware/AWS/device-defender b/Middleware/AWS/device-defender
index 9896700..7059e19 160000
--- a/Middleware/AWS/device-defender
+++ b/Middleware/AWS/device-defender
@@ -1 +1 @@
-Subproject commit 989670043d46dc104477957cdc0ce263218dae0a
+Subproject commit 7059e199149a540471b484b710a51fc665636f22
diff --git a/Middleware/AWS/device-shadow b/Middleware/AWS/device-shadow
index 250821f..268a5a2 160000
--- a/Middleware/AWS/device-shadow
+++ b/Middleware/AWS/device-shadow
@@ -1 +1 @@
-Subproject commit 250821f043d2d080547270b43f01d53c7d52640a
+Subproject commit 268a5a276d3c3f451575b5a042b4e8ad53f134b6
diff --git a/Middleware/AWS/jobs b/Middleware/AWS/jobs
new file mode 160000
index 0000000..3ce91f5
--- /dev/null
+++ b/Middleware/AWS/jobs
@@ -0,0 +1 @@
+Subproject commit 3ce91f56427653705891a8668568cb247b97905f
diff --git a/Middleware/AWS/mqtt-stream b/Middleware/AWS/mqtt-stream
new file mode 160000
index 0000000..05ff5dc
--- /dev/null
+++ b/Middleware/AWS/mqtt-stream
@@ -0,0 +1 @@
+Subproject commit 05ff5dc55a8591360664557f78ae1d71d696d201
diff --git a/Middleware/AWS/ota b/Middleware/AWS/ota
deleted file mode 160000
index f976089..0000000
--- a/Middleware/AWS/ota
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f9760892ba152f2c9104d08192ea5ffbbf9fa8ea
diff --git a/Middleware/FreeRTOS/backoffAlgorithm b/Middleware/FreeRTOS/backoffAlgorithm
index 8818bed..3cc0bf8 160000
--- a/Middleware/FreeRTOS/backoffAlgorithm
+++ b/Middleware/FreeRTOS/backoffAlgorithm
@@ -1 +1 @@
-Subproject commit 8818bed40e57215fda8efa4b7fd33f7ae2c80d65
+Subproject commit 3cc0bf8c4d41d7cd7aa2f1ded5075c87bf6b2bbb
diff --git a/Middleware/FreeRTOS/coreJSON b/Middleware/FreeRTOS/coreJSON
index 5b31f4c..e3b7663 160000
--- a/Middleware/FreeRTOS/coreJSON
+++ b/Middleware/FreeRTOS/coreJSON
@@ -1 +1 @@
-Subproject commit 5b31f4c37a034911a4992fd415f8177a75014946
+Subproject commit e3b7663f6392d8c10e8db57506ec37e4801b145a
diff --git a/Middleware/FreeRTOS/coreMQTT b/Middleware/FreeRTOS/coreMQTT
index 6d5641b..3f4cedc 160000
--- a/Middleware/FreeRTOS/coreMQTT
+++ b/Middleware/FreeRTOS/coreMQTT
@@ -1 +1 @@
-Subproject commit 6d5641b8a2f410470134d9bfe8ee71e3d83a565e
+Subproject commit 3f4cedc1ad027d76b2f00c2f83481b212b7a8632
diff --git a/Middleware/FreeRTOS/corePKCS11 b/Middleware/FreeRTOS/corePKCS11
index 781f577..a923b21 160000
--- a/Middleware/FreeRTOS/corePKCS11
+++ b/Middleware/FreeRTOS/corePKCS11
@@ -1 +1 @@
-Subproject commit 781f5774948fa8e6427be544b1bf1ad512ae9e90
+Subproject commit a923b213d33c6538e92ba3c7971b2d859f881afb
diff --git a/Middleware/FreeRTOS/kernel b/Middleware/FreeRTOS/kernel
index def7d2d..dbf7055 160000
--- a/Middleware/FreeRTOS/kernel
+++ b/Middleware/FreeRTOS/kernel
@@ -1 +1 @@
-Subproject commit def7d2df2b0506d3d249334974f51e427c17a41c
+Subproject commit dbf70559b27d39c1fdb68dfb9a32140b6a6777a0
diff --git a/Middleware/FreeRTOS/lwip_osal/src/sys_arch.c b/Middleware/FreeRTOS/lwip_osal/src/sys_arch.c
index 0ad48d4..aabeb1e 100644
--- a/Middleware/FreeRTOS/lwip_osal/src/sys_arch.c
+++ b/Middleware/FreeRTOS/lwip_osal/src/sys_arch.c
@@ -62,7 +62,7 @@
#include "core_pkcs11.h"
#ifndef errno
-int errno = 0;
+volatile int errno = 0;
#endif
/*
diff --git a/Middleware/FreeRTOS/mqtt-agent-interface/freertos_command_pool.c b/Middleware/FreeRTOS/mqtt-agent-interface/freertos_command_pool.c
index 584b508..7e97cf3 100644
--- a/Middleware/FreeRTOS/mqtt-agent-interface/freertos_command_pool.c
+++ b/Middleware/FreeRTOS/mqtt-agent-interface/freertos_command_pool.c
@@ -37,6 +37,9 @@
#include "FreeRTOS.h"
#include "semphr.h"
+/* Demo Specific configs. */
+#include "core_mqtt_config.h"
+
/* Header include. */
#include "freertos_command_pool.h"
#include "freertos_agent_message.h"
diff --git a/Middleware/FreeRTOS/tests b/Middleware/FreeRTOS/tests
index 4ec8241..692d509 160000
--- a/Middleware/FreeRTOS/tests
+++ b/Middleware/FreeRTOS/tests
@@ -1 +1 @@
-Subproject commit 4ec8241acf2beede601d230f9bd51636df60e240
+Subproject commit 692d509221b7f71d42551ed6c7b8a524b039a44f
diff --git a/cspell.config.yaml b/cspell.config.yaml
new file mode 100644
index 0000000..d0b90eb
--- /dev/null
+++ b/cspell.config.yaml
@@ -0,0 +1,32 @@
+---
+$schema: https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
+version: '0.2'
+# Allows things like stringLength
+allowCompoundWords: true
+
+# Read files not to spell check from the git ignore
+useGitignore: true
+
+# Language settings for C
+languageSettings:
+ - caseSensitive: false
+ enabled: true
+ languageId: c
+ locale: "*"
+
+# Add a dictionary, and the path to the word list
+dictionaryDefinitions:
+ - name: freertos-words
+ path: '.github/.cSpellWords.txt'
+ addWords: true
+
+dictionaries:
+ - freertos-words
+
+# Paths and files to ignore
+ignorePaths:
+ - 'dependency'
+ - 'docs'
+ - 'ThirdParty'
+ - 'History.txt'
+ - './Middleware/NXP/hostLib/mbedtls'
diff --git a/examples/common/mqtt_agent/mqtt_agent_task.c b/examples/common/mqtt_agent/mqtt_agent_task.c
index 3729ec1..999c7e3 100644
--- a/examples/common/mqtt_agent/mqtt_agent_task.c
+++ b/examples/common/mqtt_agent/mqtt_agent_task.c
@@ -66,6 +66,8 @@
#include "core_pkcs11_config.h"
+#include "core_mqtt_config.h"
+
/* MQTT library includes. */
#include "core_mqtt.h"
@@ -88,6 +90,12 @@
/* Includes MQTT Agent Task management APIs. */
#include "mqtt_agent_task.h"
+/* Includes MQTT wrapper used in the OTA demo. */
+#include "mqtt_wrapper.h"
+
+/* Include required to pass unsolicited publishes to the OTA demo. */
+#include "ota_demo.h"
+
/**
* @brief Dimensions the buffer used to serialize and deserialize MQTT packets.
* @note Specified in bytes. Must be large enough to hold the maximum
@@ -108,26 +116,26 @@
* @brief Timeout for receiving CONNACK after sending an MQTT CONNECT packet.
* Defined in milliseconds.
*/
-#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 2000U )
+#define mqttexampleCONNACK_RECV_TIMEOUT_MS ( 2000U )
/**
* @brief The maximum number of retries for network operation with server.
* The configuration is set to retry forever. MQTT agent will retry in an infinite loop until
* its connected to broker.
*/
-#define RETRY_MAX_ATTEMPTS ( BACKOFF_ALGORITHM_RETRY_FOREVER )
+#define RETRY_MAX_ATTEMPTS ( BACKOFF_ALGORITHM_RETRY_FOREVER )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
-#define RETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
+#define RETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
-#define RETRY_BACKOFF_BASE_MS ( 500U )
+#define RETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief The maximum time interval in seconds which is allowed to elapse
@@ -138,12 +146,13 @@
* absence of sending any other Control Packets, the Client MUST send a
* PINGREQ Packet.
*//*_RB_ Move to be the responsibility of the agent. */
-#define mqttexampleKEEP_ALIVE_INTERVAL_SECONDS ( 60U )
+#define mqttexampleKEEP_ALIVE_INTERVAL_SECONDS ( 60U )
/**
* @brief Socket send and receive timeouts to use. Specified in milliseconds.
*/
-#define mqttexampleTRANSPORT_SEND_RECV_TIMEOUT_MS ( 750 )
+#define mqttexampleTRANSPORT_SEND_TIMEOUT_MS ( 750 )
+#define mqttexampleTRANSPORT_RECV_TIMEOUT_MS ( 0 )
/**
* @brief Configuration is used to turn on or off persistent sessions with MQTT broker.
@@ -152,19 +161,19 @@
* will be stored by the broker and resend to device, when it comes back online.
*
*/
-#define mqttexamplePERSISTENT_SESSION_REQUIRED ( 0 )
+#define mqttexamplePERSISTENT_SESSION_REQUIRED ( 0 )
/**
* @brief Used to convert times to/from ticks and milliseconds.
*/
-#define mqttexampleMILLISECONDS_PER_SECOND ( 1000U )
-#define mqttexampleMILLISECONDS_PER_TICK ( mqttexampleMILLISECONDS_PER_SECOND / configTICK_RATE_HZ )
+#define mqttexampleMILLISECONDS_PER_SECOND ( 1000U )
+#define mqttexampleMILLISECONDS_PER_TICK ( mqttexampleMILLISECONDS_PER_SECOND / configTICK_RATE_HZ )
/**
* @brief The MQTT agent manages the MQTT contexts. This set the handle to the
* context used by this demo.
*/
-#define mqttexampleMQTT_CONTEXT_HANDLE ( ( MQTTContextHandle_t ) 0 )
+#define mqttexampleMQTT_CONTEXT_HANDLE ( ( MQTTContextHandle_t ) 0 )
/**
* @brief Event Bit corresponding to an MQTT agent state.
@@ -180,6 +189,8 @@
*/
#define mqttexampleEVENT_BITS_ALL ( ( EventBits_t ) ( ( 1ULL << MQTT_AGENT_NUM_STATES ) - 1U ) )
+
+#define MQTT_AGENT_NOTIFY_IDX ( 3U )
/*-----------------------------------------------------------*/
/**
@@ -584,8 +595,8 @@ static BaseType_t prvCreateTLSConnection( NetworkContext_t * pxNetworkContext )
pcBrokerEndpoint,
ulBrokerPort,
&xNetworkCredentials,
- mqttexampleTRANSPORT_SEND_RECV_TIMEOUT_MS,
- mqttexampleTRANSPORT_SEND_RECV_TIMEOUT_MS );
+ mqttexampleTRANSPORT_RECV_TIMEOUT_MS,
+ mqttexampleTRANSPORT_SEND_TIMEOUT_MS );
if( xNetworkStatus == TLS_TRANSPORT_SUCCESS )
{
@@ -729,13 +740,21 @@ static void prvIncomingPublishCallback( MQTTAgentContext_t * pMqttAgentContext,
* handle it as an unsolicited publish. */
if( xPublishHandled != true )
{
- /* Ensure the topic string is terminated for printing. This will over-
- * write the message ID, which is restored afterwards. */
- pcLocation = ( char * ) &( pxPublishInfo->pTopicName[ pxPublishInfo->topicNameLength ] );
- cOriginalChar = *pcLocation;
- *pcLocation = 0x00;
- LogWarn( ( "WARN: Received an unsolicited publish from topic %s", pxPublishInfo->pTopicName ) );
- *pcLocation = cOriginalChar;
+ xPublishHandled = otaDemo_handleIncomingMQTTMessage( pxPublishInfo->pTopicName,
+ pxPublishInfo->topicNameLength,
+ pxPublishInfo->pPayload,
+ pxPublishInfo->payloadLength );
+
+ if( xPublishHandled != true )
+ {
+ /* Ensure the topic string is terminated for printing. This will over-
+ * write the message ID, which is restored afterwards. */
+ pcLocation = ( char * ) &( pxPublishInfo->pTopicName[ pxPublishInfo->topicNameLength ] );
+ cOriginalChar = *pcLocation;
+ *pcLocation = 0x00;
+ LogWarn( ( "WARN: Received an unsolicited publish from topic %s", pxPublishInfo->pTopicName ) );
+ *pcLocation = cOriginalChar;
+ }
}
}
@@ -760,6 +779,14 @@ static char * prvKVStoreGetString( KVStoreKey_t xKey )
return pcValue;
}
+
+/*-----------------------------------------------------------*/
+
+MQTTAgentContext_t * xGetMqttAgentHandle( void )
+{
+ return &xGlobalMqttAgentContext;
+}
+
/*-----------------------------------------------------------*/
void prvMQTTAgentTask( void * pvParameters )
@@ -842,6 +869,10 @@ void prvMQTTAgentTask( void * pvParameters )
* which could be a disconnect. If an error occurs the MQTT context on
* which the error happened is returned so there is an attempt to
* clean up and reconnect. */
+
+ /* Set the MQTT context to be used by the MQTT wrapper. */
+ mqttWrapper_setCoreMqttContext( &( xGlobalMqttAgentContext.mqttContext ) );
+
prvSetMQTTAgentState( MQTT_AGENT_STATE_CONNECTED );
xMQTTStatus = MQTTAgent_CommandLoop( &xGlobalMqttAgentContext );
@@ -1033,6 +1064,31 @@ static void prvSetMQTTAgentState( MQTTAgentState_t xAgentState )
/*-----------------------------------------------------------*/
+static void prvSubscribeRqCallback( MQTTAgentCommandContext_t * pxCommandContext,
+ MQTTAgentReturnInfo_t * pxReturnInfo )
+{
+ TaskHandle_t xTaskHandle = ( struct tskTaskControlBlock * ) pxCommandContext;
+
+ configASSERT( pxReturnInfo );
+
+ if( xTaskHandle != NULL )
+ {
+ uint32_t ulNotifyValue = ( pxReturnInfo->returnCode & 0xFFFFFF );
+
+ if( pxReturnInfo->pSubackCodes )
+ {
+ ulNotifyValue += ( pxReturnInfo->pSubackCodes[ 0 ] << 24 );
+ }
+
+ ( void ) xTaskNotifyIndexed( xTaskHandle,
+ MQTT_AGENT_NOTIFY_IDX,
+ ulNotifyValue,
+ eSetValueWithOverwrite );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
BaseType_t xMQTTAgentInit( configSTACK_DEPTH_TYPE uxStackSize,
UBaseType_t uxPriority )
{
@@ -1177,3 +1233,69 @@ void vRemoveMQTTTopicFilterCallback( const char * pcTopicFilter,
}
xSemaphoreGive( xSubscriptionsMutex );
}
+
+MQTTStatus_t MqttAgent_SubscribeSync( const char * pcTopicFilter,
+ uint16_t uxTopicFilterLength,
+ MQTTQoS_t xRequestedQoS,
+ IncomingPubCallback_t pxCallback,
+ void * pvCallbackCtx )
+{
+ BaseType_t xMQTTCallbackAdded;
+ MQTTStatus_t xResult;
+
+ xMQTTCallbackAdded = xAddMQTTTopicFilterCallback( pcTopicFilter,
+ uxTopicFilterLength,
+ pxCallback,
+ pvCallbackCtx,
+ pdFALSE );
+
+ if( xMQTTCallbackAdded == pdTRUE )
+ {
+ MQTTSubscribeInfo_t xSubInfo =
+ {
+ .qos = xRequestedQoS,
+ .pTopicFilter = pcTopicFilter,
+ .topicFilterLength = uxTopicFilterLength
+ };
+
+ MQTTAgentSubscribeArgs_t xSubArgs =
+ {
+ .pSubscribeInfo = &xSubInfo,
+ .numSubscriptions = 1
+ };
+
+ /* The block time can be 0 as the command loop is not running at this point. */
+ MQTTAgentCommandInfo_t xCommandParams =
+ {
+ .blockTimeMs = portMAX_DELAY,
+ .cmdCompleteCallback = prvSubscribeRqCallback,
+ .pCmdCompleteCallbackContext = ( void * ) ( xTaskGetCurrentTaskHandle() )
+ };
+
+ ( void ) xTaskNotifyStateClearIndexed( NULL, MQTT_AGENT_NOTIFY_IDX );
+
+ /* Enqueue subscribe to the command queue. These commands will be processed only
+ * when command loop starts. */
+ xResult = MQTTAgent_Subscribe( &xGlobalMqttAgentContext, &xSubArgs, &xCommandParams );
+
+ if( xResult == MQTTSuccess )
+ {
+ uint32_t ulNotifyValue = 0;
+
+ if( xTaskNotifyWaitIndexed( MQTT_AGENT_NOTIFY_IDX,
+ 0x0,
+ 0xFFFFFFFF,
+ &ulNotifyValue,
+ portMAX_DELAY ) )
+ {
+ xResult = ( ulNotifyValue & 0x00FFFFFF );
+ }
+ else
+ {
+ xResult = MQTTKeepAliveTimeout;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/examples/common/mqtt_agent/mqtt_agent_task.h b/examples/common/mqtt_agent/mqtt_agent_task.h
index 0530388..160638e 100644
--- a/examples/common/mqtt_agent/mqtt_agent_task.h
+++ b/examples/common/mqtt_agent/mqtt_agent_task.h
@@ -127,4 +127,12 @@ void vRemoveMQTTTopicFilterCallback( const char * pcTopicFilter,
uint16_t usTopicFilterLength );
+MQTTAgentContext_t * xGetMqttAgentHandle( void );
+
+MQTTStatus_t MqttAgent_SubscribeSync( const char * pcTopicFilter,
+ uint16_t uxTopicFilterLength,
+ MQTTQoS_t xRequestedQoS,
+ IncomingPubCallback_t pxCallback,
+ void * pvCallbackCtx );
+
#endif /* ifndef _MQTT_AGENT_TASK_H_ */
diff --git a/examples/common/mqtt_wrapper/mqtt_wrapper.c b/examples/common/mqtt_wrapper/mqtt_wrapper.c
new file mode 100644
index 0000000..ae78fef
--- /dev/null
+++ b/examples/common/mqtt_wrapper/mqtt_wrapper.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include
+#include
+
+#include "mqtt_wrapper.h"
+#include "ota_demo.h"
+
+#define MQTT_AGENT_NOTIFY_IDX ( 2 )
+
+static MQTTContext_t * globalCoreMqttContext = NULL;
+
+#define MAX_THING_NAME_SIZE 128U
+static char globalThingName[ MAX_THING_NAME_SIZE + 1 ];
+static size_t globalThingNameLength = 0U;
+
+/**
+ * @brief Defines the structure to use as the command callback context in this
+ * demo.
+ */
+struct MQTTAgentCommandContext
+{
+ MQTTStatus_t xReturnStatus;
+ TaskHandle_t xTaskToNotify;
+};
+
+static void handleIncomingMQTTMessage( char * topic,
+ size_t topicLength,
+ uint8_t * message,
+ size_t messageLength )
+
+{
+ bool messageHandled = otaDemo_handleIncomingMQTTMessage( topic,
+ topicLength,
+ message,
+ messageLength );
+
+ if( !messageHandled )
+ {
+ printf( "Unhandled incoming PUBLISH received on topic, message: "
+ "%.*s\n%.*s\n",
+ ( unsigned int ) topicLength,
+ topic,
+ ( unsigned int ) messageLength,
+ ( char * ) message );
+ }
+}
+
+void mqttWrapper_setCoreMqttContext( MQTTContext_t * mqttContext )
+{
+ globalCoreMqttContext = mqttContext;
+}
+
+MQTTContext_t * mqttWrapper_getCoreMqttContext( void )
+{
+ assert( globalCoreMqttContext != NULL );
+ return globalCoreMqttContext;
+}
+
+void mqttWrapper_setThingName( char * thingName,
+ size_t thingNameLength )
+{
+ assert( thingNameLength <= MAX_THING_NAME_SIZE );
+ strncpy( globalThingName, thingName, MAX_THING_NAME_SIZE );
+ globalThingNameLength = thingNameLength;
+}
+
+void mqttWrapper_getThingName( char * thingNameBuffer,
+ size_t * thingNameLength )
+{
+ assert( globalThingName[ 0 ] != 0 );
+
+ memcpy( thingNameBuffer, globalThingName, globalThingNameLength );
+ thingNameBuffer[ globalThingNameLength ] = '\0';
+ *thingNameLength = globalThingNameLength;
+}
+
+bool mqttWrapper_connect( char * thingName,
+ size_t thingNameLength )
+{
+ MQTTConnectInfo_t connectInfo = { 0 };
+ MQTTStatus_t mqttStatus = MQTTSuccess;
+ bool sessionPresent = false;
+
+ assert( globalCoreMqttContext != NULL );
+
+ connectInfo.pClientIdentifier = thingName;
+ connectInfo.clientIdentifierLength = thingNameLength;
+ connectInfo.pUserName = NULL;
+ connectInfo.userNameLength = 0U;
+ connectInfo.pPassword = NULL;
+ connectInfo.passwordLength = 0U;
+ connectInfo.keepAliveSeconds = 60U;
+ connectInfo.cleanSession = true;
+ mqttStatus = MQTT_Connect( globalCoreMqttContext,
+ &connectInfo,
+ NULL,
+ 5000U,
+ &sessionPresent );
+ return mqttStatus == MQTTSuccess;
+}
+
+bool mqttWrapper_isConnected( void )
+{
+ bool isConnected = false;
+
+ assert( globalCoreMqttContext != NULL );
+ isConnected = globalCoreMqttContext->connectStatus == MQTTConnected;
+ return isConnected;
+}
+
+static void prvPublishCommandCallback( MQTTAgentCommandContext_t * pCmdCallbackContext,
+ MQTTAgentReturnInfo_t * pReturnInfo )
+{
+ TaskHandle_t xTaskHandle = ( struct tskTaskControlBlock * ) pCmdCallbackContext->xTaskToNotify;
+
+
+ if( xTaskHandle != NULL )
+ {
+ uint32_t ulNotifyValue = MQTTSuccess; /* ( pxReturnInfo->returnCode & 0xFFFFFF ); */
+/* */
+/* if( pxReturnInfo->pSubackCodes ) */
+/* { */
+/* ulNotifyValue += ( pxReturnInfo->pSubackCodes[ 0 ] << 24 ); */
+/* } */
+
+ ( void ) xTaskNotifyIndexed( xTaskHandle,
+ MQTT_AGENT_NOTIFY_IDX,
+ ulNotifyValue,
+ eSetValueWithOverwrite );
+ }
+}
+
+bool mqttWrapper_publish( char * topic,
+ size_t topicLength,
+ uint8_t * message,
+ size_t messageLength )
+{
+ bool success = false;
+
+ assert( globalCoreMqttContext != NULL );
+
+ success = mqttWrapper_isConnected();
+
+ if( success )
+ {
+ MQTTStatus_t mqttStatus = MQTTSuccess;
+ /* TODO: This should be static or should we wait? */
+ static MQTTPublishInfo_t pubInfo = { 0 };
+ MQTTAgentContext_t * xAgentHandle = xGetMqttAgentHandle();
+ pubInfo.qos = 0;
+ pubInfo.retain = false;
+ pubInfo.dup = false;
+ pubInfo.pTopicName = topic;
+ pubInfo.topicNameLength = topicLength;
+ pubInfo.pPayload = message;
+ pubInfo.payloadLength = messageLength;
+
+ MQTTAgentCommandContext_t xCommandContext =
+ {
+ .xTaskToNotify = xTaskGetCurrentTaskHandle(),
+ .xReturnStatus = MQTTIllegalState,
+ };
+
+ MQTTAgentCommandInfo_t xCommandParams =
+ {
+ .blockTimeMs = 1000,
+ .cmdCompleteCallback = prvPublishCommandCallback,
+ .pCmdCompleteCallbackContext = &xCommandContext,
+ };
+
+ ( void ) xTaskNotifyStateClearIndexed( NULL, MQTT_AGENT_NOTIFY_IDX );
+
+ mqttStatus = MQTTAgent_Publish( xAgentHandle,
+ &pubInfo,
+ &xCommandParams );
+
+ if( mqttStatus == MQTTSuccess )
+ {
+ uint32_t ulNotifyValue = 0;
+
+ if( xTaskNotifyWaitIndexed( MQTT_AGENT_NOTIFY_IDX,
+ 0x0,
+ 0xFFFFFFFF,
+ &ulNotifyValue,
+ portMAX_DELAY ) )
+ {
+ mqttStatus = ( ulNotifyValue & 0x00FFFFFF );
+ }
+ else
+ {
+ mqttStatus = MQTTKeepAliveTimeout;
+ }
+ }
+
+ success = mqttStatus == MQTTSuccess;
+ }
+
+ return success;
+}
+
+void handleIncomingPublish( void * pvIncomingPublishCallbackContext,
+ MQTTPublishInfo_t * pxPublishInfo )
+{
+ char * topic = NULL;
+ size_t topicLength = 0U;
+ uint8_t * message = NULL;
+ size_t messageLength = 0U;
+
+ topic = ( char * ) pxPublishInfo->pTopicName;
+ topicLength = pxPublishInfo->topicNameLength;
+ message = ( uint8_t * ) pxPublishInfo->pPayload;
+ messageLength = pxPublishInfo->payloadLength;
+ handleIncomingMQTTMessage( topic, topicLength, message, messageLength );
+}
+
+bool mqttWrapper_subscribe( char * topic,
+ size_t topicLength )
+{
+ bool success = false;
+
+ assert( globalCoreMqttContext != NULL );
+
+ success = mqttWrapper_isConnected();
+
+ if( success )
+ {
+ MQTTStatus_t mqttStatus = MQTTSuccess;
+
+ mqttStatus = MqttAgent_SubscribeSync( topic,
+ topicLength,
+ 0,
+ handleIncomingPublish,
+ NULL );
+
+ configASSERT( mqttStatus == MQTTSuccess );
+
+ success = mqttStatus == MQTTSuccess;
+ }
+
+ return success;
+}
diff --git a/examples/common/mqtt_wrapper/mqtt_wrapper.h b/examples/common/mqtt_wrapper/mqtt_wrapper.h
new file mode 100644
index 0000000..8d0ed33
--- /dev/null
+++ b/examples/common/mqtt_wrapper/mqtt_wrapper.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#ifndef MQTT_WRAPPER_H
+#define MQTT_WRAPPER_H
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "core_mqtt.h"
+#include "core_mqtt_agent.h"
+#include "mqtt_agent_task.h"
+
+void mqttWrapper_setCoreMqttContext( MQTTContext_t * mqttContext );
+
+MQTTContext_t * mqttWrapper_getCoreMqttContext( void );
+
+void mqttWrapper_setThingName( char * thingName,
+ size_t thingNameLength );
+
+void mqttWrapper_getThingName( char * thingNameBuffer,
+ size_t * thingNameLength );
+
+bool mqttWrapper_connect( char * thingName,
+ size_t thingNameLength );
+
+bool mqttWrapper_isConnected( void );
+
+bool mqttWrapper_publish( char * topic,
+ size_t topicLength,
+ uint8_t * message,
+ size_t messageLength );
+
+bool mqttWrapper_subscribe( char * topic,
+ size_t topicLength );
+
+#endif /* ifndef MQTT_WRAPPER_H */
diff --git a/examples/common/ota/ota_demo.h b/examples/common/ota/ota_demo.h
new file mode 100644
index 0000000..80f8438
--- /dev/null
+++ b/examples/common/ota/ota_demo.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#ifndef OTA_DEMO_H
+#define OTA_DEMO_H
+
+#include
+#include
+
+#include "MQTTFileDownloader.h"
+#include "MQTTFileDownloader_defaults.h"
+
+#define OTA_DATA_BLOCK_SIZE mqttFileDownloader_CONFIG_BLOCK_SIZE
+#define JOB_DOC_SIZE 2048U
+
+typedef enum OtaEvent
+{
+ OtaAgentEventStart = 0, /*!< @brief Start the OTA state machine */
+ OtaAgentEventRequestJobDocument, /*!< @brief Event for requesting job document. */
+ OtaAgentEventReceivedJobDocument, /*!< @brief Event when job document is received. */
+ OtaAgentEventCreateFile, /*!< @brief Event to create a file. */
+ OtaAgentEventRequestFileBlock, /*!< @brief Event to request file blocks. */
+ OtaAgentEventReceivedFileBlock, /*!< @brief Event to trigger when file block is received. */
+ OtaAgentEventCloseFile, /*!< @brief Event to trigger closing file. */
+ OtaAgentEventActivateImage, /*!< @brief Event to activate the new image. */
+ OtaAgentEventSuspend, /*!< @brief Event to suspend ota task */
+ OtaAgentEventResume, /*!< @brief Event to resume suspended task */
+ OtaAgentEventUserAbort, /*!< @brief Event triggered by user to stop agent. */
+ OtaAgentEventShutdown, /*!< @brief Event to trigger ota shutdown */
+ OtaAgentEventMax /*!< @brief Last event specifier */
+} OtaEvent_t;
+
+/**
+ * @brief OTA Agent states.
+ *
+ * The current state of the OTA Task (OTA Agent).
+ */
+typedef enum OtaState
+{
+ OtaAgentStateNoTransition = -1,
+ OtaAgentStateInit = 0,
+ OtaAgentStateReady,
+ OtaAgentStateRequestingJob,
+ OtaAgentStateWaitingForJob,
+ OtaAgentStateCreatingFile,
+ OtaAgentStateRequestingFileBlock,
+ OtaAgentStateWaitingForFileBlock,
+ OtaAgentStateClosingFile,
+ OtaAgentStateSuspended,
+ OtaAgentStateShuttingDown,
+ OtaAgentStateStopped,
+ OtaAgentStateAll
+} OtaState_t;
+
+/**
+ * @brief The OTA Agent event and data structures.
+ */
+
+typedef struct OtaDataEvent
+{
+ uint8_t data[ OTA_DATA_BLOCK_SIZE * 2 ]; /*!< Buffer for storing event information. */
+ size_t dataLength; /*!< Total space required for the event. */
+ bool bufferUsed; /*!< Flag set when buffer is used otherwise cleared. */
+} OtaDataEvent_t;
+
+typedef struct OtaJobEventData
+{
+ uint8_t jobData[ JOB_DOC_SIZE ];
+ size_t jobDataLength;
+} OtaJobEventData_t;
+
+/**
+ * @brief Application version structure.
+ *
+ */
+typedef struct
+{
+ /* MISRA Ref 19.2.1 [Unions] */
+ /* More details at: https://github.com/aws/ota-for-aws-iot-embedded-sdk/blob/main/MISRA.md#rule-192 */
+ /* coverity[misra_c_2012_rule_19_2_violation] */
+ union
+ {
+#if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN )
+ struct version
+ {
+ uint16_t build; /*!< @brief Build of the firmware (Z in firmware version Z.Y.X). */
+ uint8_t minor; /*!< @brief Minor version number of the firmware (Y in firmware version Z.Y.X). */
+
+ uint8_t major; /*!< @brief Major version number of the firmware (X in firmware version Z.Y.X). */
+ } x; /*!< @brief Version number of the firmware. */
+#elif ( defined( __BYTE_ORDER__ ) && defined( __ORDER_BIG_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) || ( __big_endian__ == 1 ) || ( __BYTE_ORDER == __BIG_ENDIAN )
+ struct version
+ {
+ uint8_t major; /*!< @brief Major version number of the firmware (X in firmware version X.Y.Z). */
+ uint8_t minor; /*!< @brief Minor version number of the firmware (Y in firmware version X.Y.Z). */
+
+ uint16_t build; /*!< @brief Build of the firmware (Z in firmware version X.Y.Z). */
+ } x; /*!< @brief Version number of the firmware. */
+#else /* if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) */
+#error "Unable to determine byte order!"
+#endif /* if ( defined( __BYTE_ORDER__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) || ( __little_endian__ == 1 ) || WIN32 || ( __BYTE_ORDER == __LITTLE_ENDIAN ) */
+ uint32_t unsignedVersion32;
+ int32_t signedVersion32;
+ } u; /*!< @brief Version based on configuration in big endian or little endian. */
+} AppVersion32_t;
+
+/**
+ * @brief Stores information about the event message.
+ *
+ */
+typedef struct OtaEventMsg
+{
+ OtaDataEvent_t * dataEvent; /*!< Data Event message. */
+ OtaJobEventData_t * jobEvent; /*!< Job Event message. */
+ OtaEvent_t eventId; /*!< Identifier for the event. */
+} OtaEventMsg_t;
+
+
+void otaDemo_start( void );
+
+bool otaDemo_handleIncomingMQTTMessage( char * topic,
+ size_t topicLength,
+ uint8_t * message,
+ size_t messageLength );
+
+OtaState_t getOtaAgentState();
+#endif /* ifndef OTA_DEMO_H */
diff --git a/examples/common/ota/ota_os/ota_os_freertos.c b/examples/common/ota/ota_os/ota_os_freertos.c
new file mode 100644
index 0000000..75fe9c4
--- /dev/null
+++ b/examples/common/ota/ota_os/ota_os_freertos.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @file ota_os_freertos.c
+ * @brief Example implementation of the OTA OS Functional Interface for
+ * FreeRTOS.
+ */
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "timers.h"
+
+/* OTA OS POSIX Interface Includes.*/
+
+#include "ota_demo.h"
+#include "ota_os_freertos.h"
+
+/* OTA Event queue attributes.*/
+#define MAX_MESSAGES 20
+#define MAX_MSG_SIZE sizeof( OtaEventMsg_t )
+
+/* Array containing pointer to the OTA event structures used to send events to
+ * the OTA task. */
+static OtaEventMsg_t queueData[ MAX_MESSAGES * MAX_MSG_SIZE ];
+
+/* The queue control structure. .*/
+static StaticQueue_t staticQueue;
+
+/* The queue control handle. .*/
+static QueueHandle_t otaEventQueue;
+
+OtaOsStatus_t OtaInitEvent_FreeRTOS()
+{
+ OtaOsStatus_t otaOsStatus = OtaOsSuccess;
+
+ otaEventQueue = xQueueCreateStatic( ( UBaseType_t ) MAX_MESSAGES,
+ ( UBaseType_t ) MAX_MSG_SIZE,
+ ( uint8_t * ) queueData,
+ &staticQueue );
+
+ if( otaEventQueue == NULL )
+ {
+ otaOsStatus = OtaOsEventQueueCreateFailed;
+
+/* printf( "Failed to create OTA Event Queue: " */
+/* "xQueueCreateStatic returned error: " */
+/* "OtaOsStatus_t=%d \n", */
+/* ( int ) otaOsStatus ); */
+ }
+ else
+ {
+/* printf( "OTA Event Queue created.\n" ); */
+ }
+
+ return otaOsStatus;
+}
+
+OtaOsStatus_t OtaSendEvent_FreeRTOS( const void * pEventMsg )
+{
+ OtaOsStatus_t otaOsStatus = OtaOsSuccess;
+ BaseType_t retVal = pdFALSE;
+
+ /* Send the event to OTA event queue.*/
+ retVal = xQueueSendToBack( otaEventQueue, pEventMsg, ( TickType_t ) 0 );
+
+ if( retVal == pdTRUE )
+ {
+/* printf( "OTA Event Sent.\n" ); */
+ }
+ else
+ {
+ otaOsStatus = OtaOsEventQueueSendFailed;
+
+/* printf( "Failed to send event to OTA Event Queue: " */
+/* "xQueueSendToBack returned error: " */
+/* "OtaOsStatus_t=%d \n", */
+/* ( int ) otaOsStatus ); */
+ }
+
+ return otaOsStatus;
+}
+
+OtaOsStatus_t OtaReceiveEvent_FreeRTOS( void * pEventMsg )
+{
+ OtaOsStatus_t otaOsStatus = OtaOsSuccess;
+ BaseType_t retVal = pdFALSE;
+
+ retVal = xQueueReceive( otaEventQueue, ( OtaEventMsg_t * ) pEventMsg, pdMS_TO_TICKS( 3000U ) );
+
+ if( retVal == pdTRUE )
+ {
+/* printf( "OTA Event received \n" ); */
+ }
+ else
+ {
+ otaOsStatus = OtaOsEventQueueReceiveFailed;
+
+ /* printf( "Failed to receive event or timeout from OTA Event Queue: " */
+/* "xQueueReceive returned error: " */
+/* "OtaOsStatus_t=%d \n", */
+/* ( int ) otaOsStatus ); */
+ }
+
+ return otaOsStatus;
+}
+
+void OtaDeinitEvent_FreeRTOS()
+{
+ vQueueDelete( otaEventQueue );
+
+/* printf( "OTA Event Queue Deleted. \n" ); */
+}
diff --git a/examples/common/ota/ota_os/ota_os_freertos.h b/examples/common/ota/ota_os/ota_os_freertos.h
new file mode 100644
index 0000000..6ecfe23
--- /dev/null
+++ b/examples/common/ota/ota_os/ota_os_freertos.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @file ota_os_freertos.h
+ * @brief Function declarations for the example OTA OS Functional interface for
+ * FreeRTOS.
+ */
+
+#ifndef _OTA_OS_FREERTOS_H_
+#define _OTA_OS_FREERTOS_H_
+
+/* Standard library include. */
+#include
+#include
+#include
+#include
+
+/**
+ * @ingroup ota_enum_types
+ * @brief The OTA OS interface return status.
+ */
+typedef enum OtaOsStatus
+{
+ OtaOsSuccess = 0, /*!< @brief OTA OS interface success. */
+ OtaOsEventQueueCreateFailed = 0x80U, /*!< @brief Failed to create the event
+ * queue. */
+ OtaOsEventQueueSendFailed, /*!< @brief Posting event message to the event
+ * queue failed. */
+ OtaOsEventQueueReceiveFailed, /*!< @brief Failed to receive from the event
+ * queue. */
+ OtaOsEventQueueDeleteFailed, /*!< @brief Failed to delete the event queue.
+ */
+} OtaOsStatus_t;
+
+/**
+ * @brief Initialize the OTA events.
+ *
+ * This function initializes the OTA events mechanism for freeRTOS platforms.
+ *
+ * @param[pEventCtx] Pointer to the OTA event context.
+ *
+ * @return OtaOsStatus_t, OtaOsSuccess if success , other error
+ * code on failure.
+ */
+OtaOsStatus_t OtaInitEvent_FreeRTOS();
+
+/**
+ * @brief Sends an OTA event.
+ *
+ * This function sends an event to OTA library event handler on FreeRTOS
+ * platforms.
+ *
+ * @param[pEventCtx] Pointer to the OTA event context.
+ *
+ * @param[pEventMsg] Event to be sent to the OTA handler.
+ *
+ * @param[timeout] The maximum amount of time (msec) the task should
+ * block.
+ *
+ * @return OtaOsStatus_t, OtaOsSuccess if success , other error
+ * code on failure.
+ */
+OtaOsStatus_t OtaSendEvent_FreeRTOS( const void * pEventMsg );
+
+/**
+ * @brief Receive an OTA event.
+ *
+ * This function receives next event from the pending OTA events on FreeRTOS
+ * platforms.
+ *
+ * @param[pEventCtx] Pointer to the OTA event context.
+ *
+ * @param[pEventMsg] Pointer to store message.
+ *
+ * @param[timeout] The maximum amount of time the task should block.
+ *
+ * @return OtaOsStatus_t, OtaOsSuccess if success , other error
+ * code on failure.
+ */
+OtaOsStatus_t OtaReceiveEvent_FreeRTOS( void * pEventMsg );
+
+/**
+ * @brief Deinitialize the OTA Events mechanism.
+ *
+ * This function deinitialize the OTA events mechanism and frees any resources
+ * used on FreeRTOS platforms.
+ *
+ * @param[pEventCtx] Pointer to the OTA event context.
+ *
+ * @return OtaOsStatus_t, OtaOsSuccess if success , other error
+ * code on failure.
+ */
+void OtaDeinitEvent_FreeRTOS();
+
+#endif /* ifndef _OTA_OS_FREERTOS_H_ */
diff --git a/examples/common/ota/ota_pal.c b/examples/common/ota/ota_pal.c
index 9400f51..1abb2e7 100644
--- a/examples/common/ota/ota_pal.c
+++ b/examples/common/ota/ota_pal.c
@@ -37,13 +37,10 @@
#include "mcuboot_app_support.h"
-/* Specify the OTA signature algorithm we support on this platform. */
-const char OTA_JsonFileSignatureKey[ OTA_FILE_SIG_KEY_STR_MAX_LENGTH ] = "sig-sha256-ecdsa";
-
/* PAL file context structure */
typedef struct
{
- const OtaFileContext_t * FileXRef;
+ const AfrOtaJobDocumentFields_t * FileXRef;
uint32_t partition_log_addr;
uint32_t partition_phys_addr;
uint32_t partition_size;
@@ -54,44 +51,57 @@ typedef struct
static PAL_FileContext_t prvPAL_CurrentFileContext;
-static PAL_FileContext_t * prvPAL_GetPALFileContext( OtaFileContext_t * const C )
-{
- PAL_FileContext_t * PalFileContext;
+OtaPalStatus_t xFlashPalValidateSignature( uint8_t * pMappedAddress,
+ size_t mappedLength,
+ char * pCertificatePath,
+ size_t certlength,
+ uint8_t * pSignature,
+ size_t signatureLength );
- if( ( C == NULL ) || ( C->pFile == NULL ) )
+
+static PAL_FileContext_t * prvPAL_GetPALFileContext( AfrOtaJobDocumentFields_t * const pFileContext )
+{
+ if( pFileContext == NULL )
{
return NULL;
}
-
- PalFileContext = ( PAL_FileContext_t * ) C->pFile;
-
- if( ( PalFileContext == NULL ) || ( PalFileContext->FileXRef != C ) )
+ else if( prvPAL_CurrentFileContext.FileXRef != pFileContext )
{
return NULL;
}
-
- return PalFileContext;
+ else
+ {
+ return &prvPAL_CurrentFileContext;
+ }
}
-OtaPalStatus_t xOtaPalAbort( OtaFileContext_t * const C )
+OtaPalStatus_t otaPal_Abort( AfrOtaJobDocumentFields_t * const pFileContext )
{
OtaPalStatus_t result = OtaPalSuccess;
LogInfo( ( "[OTA-NXP] Abort" ) );
- C->pFile = NULL;
+ pFileContext->fileId = 0;
+ pFileContext->filepath = NULL;
return result;
}
-OtaPalStatus_t xOtaPalCreateFileForRx( OtaFileContext_t * const C )
+OtaPalJobDocProcessingResult_t otaPal_CreateFileForRx( AfrOtaJobDocumentFields_t * const pFileContext )
{
partition_t update_partition;
PAL_FileContext_t * PalFileContext = &prvPAL_CurrentFileContext;
LogDebug( ( "[OTA-NXP] CreateFileForRx" ) );
+ if( otaPal_SetPlatformImageState( pFileContext, OtaImageStateAccepted ) == OtaPalSuccess )
+ {
+ /* TODO: Check here if anything is to be verified before sending the
+ * success message to IoT core. */
+ return OtaPalNewImageBooted;
+ }
+
if( bl_get_update_partition_info( &update_partition ) != kStatus_Success )
{
LogError( ( "[OTA-NXP] Could not get update partition information" ) );
@@ -108,21 +118,21 @@ OtaPalStatus_t xOtaPalCreateFileForRx( OtaFileContext_t * const C )
if( PalFileContext->partition_phys_addr == MFLASH_INVALID_ADDRESS )
{
LogError( ( "[OTA-NXP] Could not get update partition FLASH address" ) );
- return OTA_PAL_COMBINE_ERR( OtaPalRxFileCreateFailed, 0U );
+ return OtaPalRxFileCreateFailed;
}
/* Check partition alignment */
if( !mflash_drv_is_sector_aligned( PalFileContext->partition_phys_addr ) || !mflash_drv_is_sector_aligned( PalFileContext->partition_size ) )
{
LogError( ( "[OTA-NXP] Invalid update partition" ) );
- return OTA_PAL_COMBINE_ERR( OtaPalRxFileCreateFailed, 0U );
+ return OtaPalRxFileCreateFailed;
}
/* Check whether the file fits at all */
- if( C->fileSize > update_partition.size )
+ if( pFileContext->fileSize > update_partition.size )
{
LogError( ( "[OTA-NXP] File too large" ) );
- return OTA_PAL_COMBINE_ERR( OtaPalRxFileTooLarge, 0U );
+ return OtaPalRxFileTooLarge;
}
/* Actual size of the file according to data received */
@@ -134,14 +144,15 @@ OtaPalStatus_t xOtaPalCreateFileForRx( OtaFileContext_t * const C )
/* Pre-set address of area not erased so far */
PalFileContext->next_erase_addr = PalFileContext->partition_phys_addr;
- PalFileContext->FileXRef = C; /* pointer cross reference for integrity check */
- C->pFile = ( uint8_t * ) PalFileContext;
+ PalFileContext->FileXRef = pFileContext; /* pointer cross reference for integrity check */
+
+ /*C->pFile = ( uint8_t * ) PalFileContext; */
return OtaPalSuccess;
}
-OtaPalStatus_t xOtaPalCloseFile( OtaFileContext_t * const C )
+OtaPalStatus_t otaPal_CloseFile( AfrOtaJobDocumentFields_t * const pFileContext )
{
OtaPalStatus_t result = OtaPalSuccess;
PAL_FileContext_t * PalFileContext;
@@ -149,14 +160,14 @@ OtaPalStatus_t xOtaPalCloseFile( OtaFileContext_t * const C )
LogDebug( ( "[OTA-NXP] CloseFile" ) );
- PalFileContext = prvPAL_GetPALFileContext( C );
+ PalFileContext = prvPAL_GetPALFileContext( pFileContext );
if( PalFileContext == NULL )
{
- return OTA_PAL_COMBINE_ERR( OtaPalFileClose, 0U );
+ return OtaPalFileClose;
}
- if( PalFileContext->file_size != C->fileSize )
+ if( PalFileContext->file_size != pFileContext->fileSize )
{
LogWarn( ( "[OTA-NXP] Actual file size is not as expected" ) );
}
@@ -165,14 +176,15 @@ OtaPalStatus_t xOtaPalCloseFile( OtaFileContext_t * const C )
if( file_data == NULL )
{
- return OTA_PAL_COMBINE_ERR( OtaPalSignatureCheckFailed, 0U );
+ return OtaPalSignatureCheckFailed;
}
result = xFlashPalValidateSignature( ( void * ) file_data,
PalFileContext->file_size,
- ( char * ) C->pCertFilepath,
- C->pSignature->data,
- C->pSignature->size );
+ ( char * ) pFileContext->certfile,
+ pFileContext->certfileLen,
+ pFileContext->signature,
+ pFileContext->signatureLen );
if( result != OtaPalSuccess )
{
@@ -198,12 +210,12 @@ OtaPalStatus_t xOtaPalCloseFile( OtaFileContext_t * const C )
}
#endif /* ifndef DISABLE_OTA_CLOSE_FILE_HEADER_CHECK */
- C->pFile = NULL;
- return OTA_PAL_COMBINE_ERR( result, 0U );
+ pFileContext->fileId = 0;
+ return result;
}
-int16_t xOtaPalWriteBlock( OtaFileContext_t * const C,
+int16_t otaPal_WriteBlock( AfrOtaJobDocumentFields_t * const pFileContext,
uint32_t ulOffset,
uint8_t * const pcData,
uint32_t ulBlockSize )
@@ -219,7 +231,7 @@ int16_t xOtaPalWriteBlock( OtaFileContext_t * const C,
LogDebug( ( "[OTA-NXP] WriteBlock 0x%x : 0x%x", ulOffset, ulBlockSize ) );
- PalFileContext = prvPAL_GetPALFileContext( C );
+ PalFileContext = prvPAL_GetPALFileContext( pFileContext );
if( PalFileContext == NULL )
{
@@ -315,31 +327,23 @@ int16_t xOtaPalWriteBlock( OtaFileContext_t * const C,
}
-OtaPalStatus_t xOtaPalActivateNewImage( OtaFileContext_t * const C )
+OtaPalStatus_t otaPal_ActivateNewImage( AfrOtaJobDocumentFields_t * const pFileContext )
{
LogInfo( ( "[OTA-NXP] ActivateNewImage" ) );
- xOtaPalResetDevice( C ); /* go for reboot */
+ otaPal_ResetDevice( pFileContext ); /* go for reboot */
return OtaPalSuccess;
}
-OtaPalStatus_t xOtaPalResetDevice( OtaFileContext_t * const C )
-{
- LogInfo( ( "[OTA-NXP] SystemReset" ) );
- vTaskDelay( 100 / portTICK_PERIOD_MS );
- NVIC_SystemReset(); /* this should never return */
-}
-
-
-OtaPalStatus_t xOtaPalSetPlatformImageState( OtaFileContext_t * const C,
+OtaPalStatus_t otaPal_SetPlatformImageState( AfrOtaJobDocumentFields_t * const pFileContext,
OtaImageState_t eState )
{
OtaPalStatus_t result = OtaPalSuccess;
LogDebug( ( "[OTA-NXP] SetPlatformImageState %d", eState ) );
- if( xOtaPalGetPlatformImageState( C ) == OtaPalImageStatePendingCommit )
+ if( otaPal_GetPlatformImageState( pFileContext ) == OtaPalImageStatePendingCommit )
{
/* Device in test mode */
switch( eState )
@@ -414,11 +418,11 @@ OtaPalStatus_t xOtaPalSetPlatformImageState( OtaFileContext_t * const C,
}
}
- return OTA_PAL_COMBINE_ERR( result, 0U );
+ return result;
}
-OtaPalImageState_t xOtaPalGetPlatformImageState( OtaFileContext_t * const C )
+OtaPalImageState_t otaPal_GetPlatformImageState( AfrOtaJobDocumentFields_t * const pFileContext )
{
uint32_t state;
@@ -442,3 +446,11 @@ OtaPalImageState_t xOtaPalGetPlatformImageState( OtaFileContext_t * const C )
return OtaPalImageStateInvalid;
}
+
+
+OtaPalStatus_t otaPal_ResetDevice( AfrOtaJobDocumentFields_t * const pFileContext )
+{
+ LogInfo( ( "[OTA-NXP] SystemReset" ) );
+ vTaskDelay( 100 / portTICK_PERIOD_MS );
+ NVIC_SystemReset(); /* this should never return */
+}
diff --git a/examples/common/ota/ota_pal.h b/examples/common/ota/ota_pal.h
index bcf5266..6c2f8ef 100644
--- a/examples/common/ota/ota_pal.h
+++ b/examples/common/ota/ota_pal.h
@@ -31,131 +31,276 @@
#ifndef OTA_PAL_H
#define OTA_PAL_H
-#include "ota.h"
+
+#include "jobs.h"
+#include "job_parser.h"
/**
- * @brief Retrieve the current firmware image state from flash.
+ * @ingroup ota_enum_types
+ * @brief OTA Image states.
+ *
+ * After an OTA update image is received and authenticated, it is logically moved to
+ * the Self Test state by the OTA agent pending final acceptance. After the image is
+ * activated and tested by your user code, you should put it into either the Accepted
+ * or Rejected state by calling @ref OTA_SetImageState ( OtaImageStateAccepted ) or
+ * @ref OTA_SetImageState ( OtaImageStateRejected ). If the image is accepted, it becomes
+ * the main firmware image to be booted from then on. If it is rejected, the image is
+ * no longer valid and shall not be used, reverting to the last known good image.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return Appropriate state of the firmware image.
+ * If you want to abort an active OTA transfer, you may do so by calling the API
+ * @ref OTA_SetImageState ( OtaImageStateAborted ).
*/
-OtaPalImageState_t xOtaPalGetPlatformImageState( OtaFileContext_t * const pFileContext );
-
-#define otaPal_GetPlatformImageState xOtaPalGetPlatformImageState
+typedef enum OtaImageState
+{
+ OtaImageStateUnknown = 0, /*!< @brief The initial state of the OTA MCU Image. */
+ OtaImageStateTesting = 1, /*!< @brief The state of the OTA MCU Image post successful download and reboot. */
+ OtaImageStateAccepted = 2, /*!< @brief The state of the OTA MCU Image post successful download and successful self_test. */
+ OtaImageStateRejected = 3, /*!< @brief The state of the OTA MCU Image when the job has been rejected. */
+ OtaImageStateAborted = 4, /*!< @brief The state of the OTA MCU Image after a timeout publish to the stream request fails.
+ * Also if the OTA MCU image is aborted in the middle of a stream. */
+ OtaLastImageState = OtaImageStateAborted
+} OtaImageState_t;
/**
- * @brief Set the current firmware image state in flash.
+ * @ingroup ota_enum_types
+ * @brief OTA Platform Image State.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @param[in] eState State to be set for the firmware image.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * The image state set by platform implementation.
*/
-OtaPalStatus_t xOtaPalSetPlatformImageState( OtaFileContext_t * const pFileContext,
- OtaImageState_t eState );
-
-#define otaPal_SetPlatformImageState xOtaPalSetPlatformImageState
+typedef enum OtaPalImageState
+{
+ OtaPalImageStateUnknown = 0, /*!< @brief The initial state of the OTA PAL Image. */
+ OtaPalImageStatePendingCommit, /*!< @brief OTA PAL Image awaiting update. */
+ OtaPalImageStateValid, /*!< @brief OTA PAL Image is valid. */
+ OtaPalImageStateInvalid /*!< @brief OTA PAL Image is invalid. */
+} OtaPalImageState_t;
/**
- * @brief Resets the device with the current firmware image.
- * The API can be invoked when aborting the current OTA update to fall back to old image or while activating
- * new image after a successful update.
+ * @ingroup ota_enum_types
+ * @brief OTA Platform Image State.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * The image state set by platform implementation.
*/
-OtaPalStatus_t xOtaPalResetDevice( OtaFileContext_t * const pFileContext );
+typedef enum OtaPalJobDocProcessingResult
+{
+ OtaPalJobDocFileCreated = 0,
+ OtaPalJobDocFileCreateFailed,
+ OtaPalNewImageBooted,
+ OtaPalNewImageBootFailed,
+ OtaPalJobDocProcessingStateInvalid
+} OtaPalJobDocProcessingResult_t;
-#define otaPal_ResetDevice xOtaPalResetDevice
+typedef enum OtaPalStatus
+{
+ OtaPalSuccess = 0,
+ OtaPalUninitialized,
+ OtaPalOutOfMemory,
+ OtaPalNullFileContext,
+ OtaPalSignatureCheckFailed,
+ OtaPalRxFileCreateFailed,
+ OtaPalRxFileTooLarge,
+ OtaPalBootInfoCreateFailed,
+ OtaPalBadSignerCert,
+ OtaPalBadImageState,
+ OtaPalAbortFailed,
+ OtaPalRejectFailed,
+ OtaPalCommitFailed,
+ OtaPalActivateFailed,
+ OtaPalFileAbort,
+ OtaPalFileClose
+} OtaPalStatus_t;
/**
- * @brief Activates the device with the new firmware image.
- * The API should prepare the new image to be booted up and reset the device to boot up with the new image.
+ * @brief Abort an OTA transfer.
+ *
+ * Aborts access to an existing open file represented by the OTA file context pFileContext. This is
+ * only valid for jobs that started successfully.
+ *
+ * @note The input OtaFileContext_t pFileContext is checked for NULL by the OTA agent before this
+ * function is called.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * This function may be called before the file is opened, so the file pointer pFileContext->fileHandle
+ * may be NULL when this function is called.
+ *
+ * @param[in] pFileContext OTA file context information.
+ *
+ * @return The OtaPalStatus_t error code is a combination of the main OTA PAL interface error and
+ * the MCU specific sub error code. See ota_platform_interface.h for the OtaPalMainStatus_t
+ * error codes and your specific PAL implementation for the sub error code.
+ *
+ * Major error codes returned are:
+ *
+ * OtaPalSuccess: Aborting access to the open file was successful.
+ * OtaPalFileAbort: Aborting access to the open file context was unsuccessful.
*/
-OtaPalStatus_t xOtaPalActivateNewImage( OtaFileContext_t * const pFileContext );
-
-#define otaPal_ActivateNewImage xOtaPalActivateNewImage
+OtaPalStatus_t otaPal_Abort( AfrOtaJobDocumentFields_t * const pFileContext );
/**
- * @brief Writes a block of the firmware image to flash.
+ * @brief Create a new receive file.
+ *
+ * @note Opens the file indicated in the OTA file context in the MCU file system.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @param[in] offset Offset in bytes of the block with in the whole firmware image
- * @param[in] pData Pointer to buffer containing the block.
- * @param[in] blockSize Size of the block
- * @return Number of bytes of block written or < 0 if there is an error.
+ * @note The previous image may be present in the designated image download partition or file, so the
+ * partition or file must be completely erased or overwritten in this routine.
+ *
+ * @note The input OtaFileContext_t pFileContext is checked for NULL by the OTA agent before this
+ * function is called.
+ * The device file path is a required field in the OTA job document, so pFileContext->pFilePath is
+ * checked for NULL by the OTA agent before this function is called.
+ *
+ * @param[in] pFileContext OTA file context information.
+ *
+ * @return The OtaPalStatus_t error code is a combination of the main OTA PAL interface error and
+ * the MCU specific sub error code. See ota_platform_interface.h for the OtaPalMainStatus_t
+ * error codes and your specific PAL implementation for the sub error code.
+ *
+ * Major error codes returned are:
+ *
+ * OtaPalSuccess: File creation was successful.
+ * OtaPalRxFileTooLarge: The OTA receive file is too big for the platform to support.
+ * OtaPalBootInfoCreateFailed: The bootloader information file creation failed.
+ * OtaPalRxFileCreateFailed: Returned for other errors creating the file in the device's
+ * non-volatile memory. If this error is returned, then the sub error
+ * should be set to the appropriate platform specific value.
*/
-int16_t xOtaPalWriteBlock( OtaFileContext_t * const pFileContext,
- uint32_t offset,
- uint8_t * const pData,
- uint32_t blockSize );
-
-#define otaPal_WriteBlock xOtaPalWriteBlock
+OtaPalJobDocProcessingResult_t otaPal_CreateFileForRx( AfrOtaJobDocumentFields_t * const pFileContext );
/**
- * @brief Closes the firmware image after reading or writing.
+ * @brief Authenticate and close the underlying receive file in the specified OTA context.
+ *
+ * @note The input OtaFileContext_t pFileContext is checked for NULL by the OTA agent before this
+ * function is called. This function is called only at the end of block ingestion.
+ * otaPAL_CreateFileForRx() must succeed before this function is reached, so
+ * pFileContext->fileHandle(or pFileContext->pFile) is never NULL.
+ * The file signature key is required job document field in the OTA Agent, so pFileContext->pSignature will
+ * never be NULL.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * If the signature verification fails, file close should still be attempted.
+ *
+ * @param[in] pFileContext OTA file context information.
+ *
+ * @return The OtaPalStatus_t error code is a combination of the main OTA PAL interface error and
+ * the MCU specific sub error code. See ota_platform_interface.h for the OtaPalMainStatus_t
+ * error codes and your specific PAL implementation for the sub error code.
+ *
+ * Major error codes returned are:
+ *
+ * OtaPalSuccess on success.
+ * OtaPalSignatureCheckFailed: The signature check failed for the specified file.
+ * OtaPalBadSignerCert: The signer certificate was not readable or zero length.
+ * OtaPalFileClose: Error in low level file close.
*/
-OtaPalStatus_t xOtaPalCloseFile( OtaFileContext_t * const pFileContext );
-
-#define otaPal_CloseFile xOtaPalCloseFile
+OtaPalStatus_t otaPal_CloseFile( AfrOtaJobDocumentFields_t * const pFileContext );
/**
- * @brief Prepares a new firmware image to be written.
+ * @brief Write a block of data to the specified file at the given offset.
+ *
+ * @note The input OtaFileContext_t pFileContext is checked for NULL by the OTA agent before this
+ * function is called.
+ * The file pointer/handle pFileContext->pFile, is checked for NULL by the OTA agent before this
+ * function is called.
+ * pData is checked for NULL by the OTA agent before this function is called.
+ * blockSize is validated for range by the OTA agent before this function is called.
+ * offset is validated by the OTA agent before this function is called.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * @param[in] pFileContext OTA file context information.
+ * @param[in] ulOffset Byte offset to write to from the beginning of the file.
+ * @param[in] pData Pointer to the byte array of data to write.
+ * @param[in] ulBlockSize The number of bytes to write.
+ *
+ * @return The number of bytes written successfully, or a negative error code from the platform
+ * abstraction layer.
*/
-OtaPalStatus_t xOtaPalCreateFileForRx( OtaFileContext_t * const pFileContext );
-
-#define otaPal_CreateFileForRx xOtaPalCreateFileForRx
+int16_t otaPal_WriteBlock( AfrOtaJobDocumentFields_t * const pFileContext,
+ uint32_t ulOffset,
+ uint8_t * const pcData,
+ uint32_t ulBlockSize );
/**
- * @brief Aborts the current firmware image being written.
+ * @brief Activate the newest MCU image received via OTA.
+ *
+ * This function shall take necessary actions to activate the newest MCU
+ * firmware received via OTA. It is typically just a reset of the device.
+ *
+ * @note This function SHOULD NOT return. If it does, the platform does not support
+ * an automatic reset or an error occurred.
+ *
+ * @param[in] pFileContext OTA file context information.
+ *
+ * @return The OtaPalStatus_t error code is a combination of the main OTA PAL interface error and
+ * the MCU specific sub error code. See ota_platform_interface.h for the OtaPalMainStatus_t
+ * error codes and your specific PAL implementation for the sub error code.
+ *
+ * Major error codes returned are:
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * OtaPalSuccess on success.
+ * OtaPalActivateFailed: The activation of the new OTA image failed.
*/
-OtaPalStatus_t xOtaPalAbort( OtaFileContext_t * const pFileContext );
-
-#define otaPal_Abort xOtaPalAbort
-
+OtaPalStatus_t otaPal_ActivateNewImage( AfrOtaJobDocumentFields_t * const pFileContext );
/**
- * @brief Opens the firmware image for reading
- * The API is used to verify the image signature after it has been written.
+ * @brief Attempt to set the state of the OTA update image.
+ *
+ * Take required actions on the platform to Accept/Reject the OTA update image (or bundle).
+ * Refer to the PAL implementation to determine what happens on your platform.
+ *
+ * @param[in] pFileContext File context of type OtaFileContext_t.
+ * @param[in] eState The desired state of the OTA update image.
+ *
+ * @return The OtaPalStatus_t error code is a combination of the main OTA PAL interface error and
+ * the MCU specific sub error code. See ota_platform_interface.h for the OtaPalMainStatus_t
+ * error codes and your specific PAL implementation for the sub error code.
+ *
+ * Major error codes returned are:
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @return OtaPalSuccess if successful, else OTA error code along with detailed PAL error code.
+ * OtaPalSuccess on success.
+ * OtaPalBadImageState: if you specify an invalid OtaImageState_t. No sub error code.
+ * OtaPalAbortFailed: failed to roll back the update image as requested by OtaImageStateAborted.
+ * OtaPalRejectFailed: failed to roll back the update image as requested by OtaImageStateRejected.
+ * OtaPalCommitFailed: failed to make the update image permanent as requested by OtaImageStateAccepted.
*/
-OtaPalStatus_t xOtaPalOpenFileForRead( OtaFileContext_t * const pContext );
-
-#define otaPal_OpenFileForRead xOtaPalOpenFileForRead
+OtaPalStatus_t otaPal_SetPlatformImageState( AfrOtaJobDocumentFields_t * const pFileContext,
+ OtaImageState_t eState );
/**
- * @brief Reads a block of firmware image from flash
+ * @brief Get the state of the OTA update image.
+ *
+ * We read this at OTA_Init time and when the latest OTA job reports itself in self
+ * test. If the update image is in the "pending commit" state, we start a self test
+ * timer to assure that we can successfully connect to the OTA services and accept
+ * the OTA update image within a reasonable amount of time (user configurable). If
+ * we don't satisfy that requirement, we assume there is something wrong with the
+ * firmware and automatically reset the device, causing it to roll back to the
+ * previously known working code.
+ *
+ * If the update image state is not in "pending commit," the self test timer is
+ * not started.
*
- * @param[in] pFileContext Pointer to a context containing firmware image details.
- * @param[in] offset Offset in bytes of the block with in the whole firmware image
- * @param[in] pData Pointer to buffer where block is read to.
- * @param[in] blockSize Size of the buffer
- * @return Number of bytes of block read or < 0 if there is an error.
+ * @param[in] pFileContext File context of type OtaFileContext_t.
+ *
+ * @return An OtaPalImageState_t. One of the following:
+ * OtaPalImageStatePendingCommit (the new firmware image is in the self test phase)
+ * OtaPalImageStateValid (the new firmware image is already committed)
+ * OtaPalImageStateInvalid (the new firmware image is invalid or non-existent)
+ *
+ * NOTE: OtaPalImageStateUnknown should NEVER be returned and indicates an implementation error.
*/
-int32_t xOtaPalReadBlock( OtaFileContext_t * const pContext,
- uint32_t offset,
- uint8_t * pData,
- uint16_t blockSize );
-
-#define otaPal_ReadBlock xOtaPalReadBlock
+OtaPalImageState_t otaPal_GetPlatformImageState( AfrOtaJobDocumentFields_t * const pFileContext );
-OtaPalStatus_t xFlashPalValidateSignature( uint8_t * pMappedAddress,
- size_t mappedLength,
- char * pCertificatePath,
- uint8_t * pSignature,
- size_t signatureLength );
+/**
+ * @brief Reset the device.
+ *
+ * This function shall reset the MCU and cause a reboot of the system.
+ *
+ * @note This function SHOULD NOT return. If it does, the platform does not support
+ * an automatic reset or an error occurred.
+ *
+ * @param[in] pFileContext OTA file context information.
+ *
+ * @return The OtaPalStatus_t error code is a combination of the main OTA PAL interface error and
+ * the MCU specific sub error code. See ota_platform_interface.h for the OtaPalMainStatus_t
+ * error codes and your specific PAL implementation for the sub error code.
+ */
+OtaPalStatus_t otaPal_ResetDevice( AfrOtaJobDocumentFields_t * const pFileContext );
-#endif /* OTA_PAL_H */
+#endif /* ifndef OTA_PAL_H_ */
diff --git a/examples/common/ota/ota_signature_validation.c b/examples/common/ota/ota_signature_validation.c
index 88cac9c..016cdaa 100644
--- a/examples/common/ota/ota_signature_validation.c
+++ b/examples/common/ota/ota_signature_validation.c
@@ -246,6 +246,7 @@ CK_RV xVerifyImageSignatureUsingPKCS11( CK_SESSION_HANDLE session,
OtaPalStatus_t xFlashPalValidateSignature( uint8_t * pMappedAddress,
size_t mappedLength,
char * pCertificatePath,
+ size_t certlength,
uint8_t * pSignature,
size_t signatureLength )
{
@@ -254,6 +255,10 @@ OtaPalStatus_t xFlashPalValidateSignature( uint8_t * pMappedAddress,
CK_RV xPKCS11Status = CKR_OK;
CK_OBJECT_HANDLE certHandle;
uint8_t pkcs11Signature[ pkcs11ECDSA_P256_SIGNATURE_LENGTH ] = { 0 };
+ /* TODO: Fix the label length. */
+ char certfile[ 30 + 1 ] = { '\0' };
+
+ memcpy( certfile, pCertificatePath, certlength );
if( PKI_mbedTLSSignatureToPkcs11Signature( pkcs11Signature, pSignature ) != 0 )
{
diff --git a/examples/common/ota/ota_update.c b/examples/common/ota/ota_update.c
index 434e95a..1a5b73d 100644
--- a/examples/common/ota/ota_update.c
+++ b/examples/common/ota/ota_update.c
@@ -52,15 +52,24 @@
/* MQTT library includes. */
#include "core_mqtt_agent.h"
-/* OTA Library include. */
-#include "ota.h"
+/* MQTT streams Library include. */
+#include "MQTTFileDownloader.h"
+#include "MQTTFileDownloader_base64.h"
-/* OTA Library Interface include. */
-#include "ota_os_freertos.h"
-#include "ota_mqtt_interface.h"
+/* jobs Library include. */
+#include "jobs.h"
+
+/* OTA job parser include. */
+#include "job_parser.h"
+#include "ota_job_processor.h"
/* Include firmware version struct definition. */
-#include "ota_appversion32.h"
+/*#include "ota_appversion32.h" */
+
+#include "ota_demo.h"
+#include "ota_os_freertos.h"
+
+#include "mqtt_wrapper.h"
/* Include platform abstraction header. */
#include "ota_pal.h"
@@ -168,7 +177,19 @@
/**
* @brief Maximum stack size of OTA agent task.
*/
-#define otaexampleAGENT_TASK_STACK_SIZE ( 4096 )
+#define otaexampleAGENT_TASK_STACK_SIZE ( 4096 * 2 )
+
+
+#define CONFIG_MAX_FILE_SIZE 200 /* TODO:!! */
+#define NUM_OF_BLOCKS_REQUESTED 1U
+#define START_JOB_MSG_LENGTH 147U
+#define MAX_THING_NAME_SIZE 128U
+#define MAX_JOB_ID_LENGTH 64U
+#define UPDATE_JOB_MSG_LENGTH 48U
+#define MAX_NUM_OF_OTA_DATA_BUFFERS 2U
+
+/* Max bytes supported for a file signature (3072 bit RSA is 384 bytes). */
+#define OTA_MAX_SIGNATURE_SIZE ( 384U )
/**
* @brief Defines the structure to use as the command callback context in this
@@ -180,114 +201,22 @@ struct MQTTAgentCommandContext
void * pArgs;
};
-/**
- * @brief Function used by OTA agent to publish control messages to the MQTT broker.
- *
- * The implementation uses MQTT agent to queue a publish request. It then waits
- * for the request complete notification from the agent. The notification along with result of the
- * operation is sent back to the caller task using xTaskNotify API. For publishes involving QOS 1 and
- * QOS2 the operation is complete once an acknowledgment (PUBACK) is received. OTA agent uses this function
- * to fetch new job, provide status update and send other control related messages to the MQTT broker.
- *
- * @param[in] pacTopic Topic to publish the control packet to.
- * @param[in] topicLen Length of the topic string.
- * @param[in] pMsg Message to publish.
- * @param[in] msgSize Size of the message to publish.
- * @param[in] qos Qos for the publish.
- * @return OtaMqttSuccess if successful. Appropriate error code otherwise.
- */
-static OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic,
- uint16_t topicLen,
- const char * pMsg,
- uint32_t msgSize,
- uint8_t qos );
-
-
-/**
- * @brief The callback invoked by the MQTT agent on a successful subscription of a topic filter
- * with broker.
- * The implementation adds a local subscription for the topic filter with the MQTT agent.
- *
- * @param pCommandContext Pointer to the command context passed from the caller.
- * @param pxReturnInfo Pointer to the return status of the subscribe command.
- */
-static void prvSubscribeCommandCallback( MQTTAgentCommandContext_t * pxCommandContext,
- MQTTAgentReturnInfo_t * pxReturnInfo );
-
-/**
- * @brief The callback invoked by the MQTT agent on unsubscribing a topic filter
- * with broker.
- * The implementation removes the local subscription for the topic filter with the MQTT agent.
- *
- * @param pCommandContext Pointer to the command context passed from the caller.
- * @param pxReturnInfo Pointer to the return status of the unsubscribe command.
- */
-static void prvUnSubscribeCommandCallback( MQTTAgentCommandContext_t * pxCommandContext,
- MQTTAgentReturnInfo_t * pxReturnInfo );
-
-/**
- * @brief Function used by OTA agent to subscribe for a control or data packet from the MQTT broker.
- *
- * The implementation queues a SUBSCRIBE request for the topic filter with the MQTT agent. It then waits for
- * a notification of the request completion. Notification will be sent back to caller task,
- * using xTaskNotify APIs. MQTT agent also stores a callback provided by this function with
- * the associated topic filter. The callback will be used to
- * route any data received on the matching topic to the OTA agent. OTA agent uses this function
- * to subscribe to all topic filters necessary for receiving job related control messages as
- * well as firmware image chunks from MQTT broker.
- *
- * @param[in] pTopicFilter The topic filter used to subscribe for packets.
- * @param[in] topicFilterLength Length of the topic filter string.
- * @param[in] ucQoS Intended qos value for the messages received on this topic.
- * @return OtaMqttSuccess if successful. Appropriate error code otherwise.
- */
-static OtaMqttStatus_t prvMQTTSubscribe( const char * pTopicFilter,
- uint16_t topicFilterLength,
- uint8_t ucQoS );
+static MqttFileDownloaderContext_t mqttFileDownloaderContext = { 0 };
+static uint32_t numOfBlocksRemaining = 0;
+static uint32_t currentBlockOffset = 0;
+static uint8_t currentFileId = 0;
+static uint32_t totalBytesReceived = 0;
+char globalJobId[ MAX_JOB_ID_LENGTH ] = { 0 };
-/**
- * @brief Function is used by OTA agent to unsubscribe a topicfilter from MQTT broker.
- *
- * The implementation queues an UNSUBSCRIBE request for the topic filter with the MQTT agent. It then waits
- * for a successful completion of the request from the agent. Notification along with results of
- * operation is sent using xTaskNotify API to the caller task. MQTT agent also removes the topic filter
- * subscription from its memory so any future
- * packets on this topic will not be routed to the OTA agent.
- *
- * @param[in] pTopicFilter Topic filter to be unsubscribed.
- * @param[in] topicFilterLength Length of the topic filter.
- * @param[in] ucQos Qos value for the topic.
- * @return OtaMqttSuccess if successful. Appropriate error code otherwise.
- *
- */
-static OtaMqttStatus_t prvMQTTUnsubscribe( const char * pTopicFilter,
- uint16_t topicFilterLength,
- uint8_t ucQoS );
+static SemaphoreHandle_t bufferSemaphore;
-/**
- * @brief Fetch an unused OTA event buffer from the pool.
- *
- * Demo uses a simple statically allocated array of fixed size event buffers. The
- * number of event buffers is configured by the param otaconfigMAX_NUM_OTA_DATA_BUFFERS
- * within ota_config.h. This function is used to fetch a free buffer from the pool for processing
- * by the OTA agent task. It uses a mutex for thread safe access to the pool.
- *
- * @return A pointer to an unused buffer. NULL if there are no buffers available.
- */
-static OtaEventData_t * prvOTAEventBufferGet( void );
+static OtaDataEvent_t dataBuffers[ MAX_NUM_OF_OTA_DATA_BUFFERS ] = { 0 };
+static OtaJobEventData_t jobDocBuffer = { 0 };
+static AfrOtaJobDocumentFields_t jobFields = { 0 };
+static uint8_t OtaImageSingatureDecoded[ OTA_MAX_SIGNATURE_SIZE ] = { 0 };
+static SemaphoreHandle_t bufferSemaphore;
-/**
- * @brief Free an event buffer back to pool
- *
- * OTA demo uses a statically allocated array of fixed size event buffers . The
- * number of event buffers is configured by the param otaconfigMAX_NUM_OTA_DATA_BUFFERS
- * within ota_config.h. The function is used by the OTA application callback to free a buffer,
- * after OTA agent has completed processing with the event. The access to the pool is made thread safe
- * using a mutex.
- *
- * @param[in] pxBuffer Pointer to the buffer to be freed.
- */
-static void prvOTAEventBufferFree( OtaEventData_t * const pxBuffer );
+static OtaState_t otaAgentState = OtaAgentStateInit;
/**
* @brief The function which runs the OTA agent task.
@@ -314,101 +243,79 @@ static void prvOTAAgentTask( void * pvParam );
void vOTAUpdateTask( void * pvParam );
/**
- * @brief Callback to receive either data or control messages on OTA topics.
- *
- * Function can get invoked for a job notification message or a data message from MQTT broker.
- * Function matches the topic of the message with list of topic filters and routes the message to
- * either control message or data message processing functions.
- *
- * @param[in] pxSubscriptionContext Context which is passed unmodified from the MQTT agent.
- * @param[in] pPublishInfo Pointer to the structure containing the details of the MQTT packet.
+ * @brief This is in essence the OTA agent implementation.
*/
-static void prvProcessIncomingMessage( void * pxSubscriptionContext,
- MQTTPublishInfo_t * pxPublishInfo );
+static void processOTAEvents( void );
/**
- * @brief Callback invoked for data messages received from MQTT broker.
- *
- * Function gets invoked for the firmware image blocks received on OTA data stream topic.
- * The function is registered with MQTT agent's subscription manger along with the
- * topic filter for data stream. For each packet received, the
- * function fetches a free event buffer from the pool and queues the firmware image chunk for
- * OTA agent task processing.
- *
- * @param[in] pxSubscriptionContext Context which is passed unmodified from the MQTT agent.
- * @param[in] pPublishInfo Pointer to the structure containing the details of the MQTT packet.
+ * @brief
*/
-static void prvProcessIncomingData( void * pxSubscriptionContext,
- MQTTPublishInfo_t * pPublishInfo );
+static bool imageActivationHandler( void );
/**
- * @brief Callback invoked for job control messages from MQTT broker.
- *
- * Callback gets invoked for any OTA job related control messages from the MQTT broker.
- * The function is registered with MQTT agent's subscription manger along with the topic filter for
- * job stream. The function fetches a free event buffer from the pool and queues the appropriate event type
- * based on the control message received.
- *
- * @param[in] pxSubscriptionContext Context which is passed unmodified from the MQTT agent.
- * @param[in] pPublishInfo Pointer to the structure containing the details of MQTT packet.
+ * @brief
*/
-static void prvProcessIncomingJobMessage( void * pxSubscriptionContext,
- MQTTPublishInfo_t * pPublishInfo );
+static bool closeFileHandler( void );
/**
- * @brief Matches a client identifier within an OTA topic.
- * This function is used to validate that topic is valid and intended for this device thing name.
- *
- * @param[in] pTopic Pointer to the topic
- * @param[in] topicNameLength length of the topic
- * @param[in] pClientIdentifier Client identifier, should be null terminated.
- * @param[in] clientIdentifierLength Length of the client identifier.
- * @return pdTRUE if client identifier is found within the topic at the right index.
+ * @brief
+ */
+static OtaPalJobDocProcessingResult_t receivedJobDocumentHandler( OtaJobEventData_t * jobDoc );
+
+/**
+ * @brief
+ */
+static uint16_t getFreeOTABuffers( void );
+
+/**
+ * @brief
+ */
+static void freeOtaDataEventBuffer( OtaDataEvent_t * const pxBuffer );
+
+/**
+ * @brief
*/
-static BaseType_t prvMatchClientIdentifierInTopic( const char * pTopic,
- size_t topicNameLength,
- const char * pClientIdentifier,
- size_t clientIdentifierLength );
+static OtaDataEvent_t * getOtaDataEventBuffer( void );
+/**
+ * @brief
+ */
+static void requestDataBlock( void );
/**
- * @brief Buffer used to store the firmware image file path.
- * Buffer is passed to the OTA agent during initialization.
+ * @brief
*/
-static uint8_t updateFilePath[ otaexampleMAX_FILE_PATH_SIZE ];
+static int16_t handleMqttStreamsBlockArrived( uint8_t * data,
+ size_t dataLength );
/**
- * @brief Buffer used to store the code signing certificate file path.
- * Buffer is passed to the OTA agent during initialization.
+ * @brief
*/
-static uint8_t certFilePath[ otaexampleMAX_FILE_PATH_SIZE ];
+static bool convertSignatureToDER( AfrOtaJobDocumentFields_t * jobFields );
/**
- * @brief Buffer used to store the name of the data stream.
- * Buffer is passed to the OTA agent during initialization.
+ * @brief
*/
-static uint8_t streamName[ otaexampleMAX_STREAM_NAME_SIZE ];
+static void initMqttDownloader( AfrOtaJobDocumentFields_t * jobFields );
/**
- * @brief Buffer used decode the CBOR message from the MQTT payload.
- * Buffer is passed to the OTA agent during initialization.
+ * @brief
*/
-static uint8_t decodeMem[ ( 1U << otaconfigLOG2_FILE_BLOCK_SIZE ) ];
+static void requestJobDocumentHandler( void );
/**
- * @brief Application buffer used to store the bitmap for requesting firmware image
- * chunks from MQTT broker. Buffer is passed to the OTA agent during initialization.
+ * @brief
*/
-static uint8_t bitmap[ OTA_MAX_BLOCK_BITMAP_SIZE ];
+static bool jobDocumentParser( char * message,
+ size_t messageLength,
+ AfrOtaJobDocumentFields_t * jobFields );
+
/**
- * @brief A statically allocated array of event buffers used by the OTA agent.
- * Maximum number of buffers are determined by how many chunks are requested
- * by OTA agent at a time along with an extra buffer to handle control message.
- * The size of each buffer is determined by the maximum size of firmware image
- * chunk, and other metadata send along with the chunk.
+ * @brief
*/
-static OtaEventData_t eventBuffer[ otaconfigMAX_NUM_OTA_DATA_BUFFERS ] = { 0 };
+static bool sendSuccessMessage( void );
+
/*
* @brief Mutex used to manage thread safe access of OTA event buffers.
@@ -420,23 +327,6 @@ static SemaphoreHandle_t xBufferSemaphore;
*/
extern MQTTAgentContext_t xGlobalMqttAgentContext;
-/**
- * @brief Structure containing all application allocated buffers used by the OTA agent.
- * Structure is passed to the OTA agent during initialization.
- */
-static OtaAppBuffer_t otaBuffer =
-{
- .pUpdateFilePath = updateFilePath,
- .updateFilePathsize = otaexampleMAX_FILE_PATH_SIZE,
- .pCertFilePath = certFilePath,
- .certFilePathSize = otaexampleMAX_FILE_PATH_SIZE,
- .pStreamName = streamName,
- .streamNameSize = otaexampleMAX_STREAM_NAME_SIZE,
- .pDecodeMemory = decodeMem,
- .decodeMemorySize = ( 1U << otaconfigLOG2_FILE_BLOCK_SIZE ),
- .pFileBitmap = bitmap,
- .fileBitmapSize = OTA_MAX_BLOCK_BITMAP_SIZE
-};
/**
* @brief Structure used for encoding firmware version.
@@ -455,717 +345,759 @@ const AppVersion32_t appFirmwareVersion =
static char * pcThingName = NULL;
static size_t xThingNameLength = 0U;
-
-/*---------------------------------------------------------*/
-
-static void prvOTAEventBufferFree( OtaEventData_t * const pxBuffer )
-{
- if( xSemaphoreTake( xBufferSemaphore, portMAX_DELAY ) == pdTRUE )
- {
- pxBuffer->bufferUsed = false;
- ( void ) xSemaphoreGive( xBufferSemaphore );
- }
- else
- {
- LogError( ( "Failed to get buffer semaphore." ) );
- }
-}
-
/*-----------------------------------------------------------*/
-static OtaEventData_t * prvOTAEventBufferGet( void )
+static void prvOTAAgentTask( void * pvParam )
{
- uint32_t ulIndex = 0;
- OtaEventData_t * pFreeBuffer = NULL;
+ BaseType_t xResult;
+ size_t xValueLength = 0U;
+ char * pcValue = NULL;
+
+ LogError( "Running OTA Agent task. Waiting..." );
- if( xSemaphoreTake( xBufferSemaphore, portMAX_DELAY ) == pdTRUE )
+ while( 1 )
{
- for( ulIndex = 0; ulIndex < otaconfigMAX_NUM_OTA_DATA_BUFFERS; ulIndex++ )
+ xResult = xWaitForMQTTAgentState( MQTT_AGENT_STATE_CONNECTED,
+ portMAX_DELAY );
+
+ if( xResult == pdTRUE )
{
- if( eventBuffer[ ulIndex ].bufferUsed == false )
- {
- eventBuffer[ ulIndex ].bufferUsed = true;
- pFreeBuffer = &eventBuffer[ ulIndex ];
- break;
- }
+ break;
}
-
- ( void ) xSemaphoreGive( xBufferSemaphore );
}
- else
+
+ /* Load broker thing name from the key store. */
+ xValueLength = KVStore_getValueLength( KVS_CORE_THING_NAME );
+
+ if( xValueLength > 0 )
{
- LogError( ( "Failed to get buffer semaphore." ) );
+ pcValue = pvPortMalloc( xValueLength + 1 );
+
+ if( pcValue != NULL )
+ {
+ ( void ) KVStore_getString( KVS_CORE_THING_NAME, pcValue, ( xValueLength + 1 ) );
+ }
}
- return pFreeBuffer;
-}
+ mqttWrapper_setThingName( pcValue, xValueLength );
+
+ vPortFree( pcValue );
+
+ otaDemo_start();
-/*-----------------------------------------------------------*/
-static void prvOTAAgentTask( void * pvParam )
-{
- OTA_EventProcessingTask( pvParam );
vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
-/**
- * @brief The OTA agent has completed the update job or it is in
- * self test mode. If it was accepted, we want to activate the new image.
- * This typically means we should reset the device to run the new firmware.
- * If now is not a good time to reset the device, it may be activated later
- * by your user code. If the update was rejected, just return without doing
- * anything and we will wait for another job. If it reported that we should
- * start test mode, normally we would perform some kind of system checks to
- * make sure our new firmware does the basic things we think it should do
- * but we will just go ahead and set the image as accepted for demo purposes.
- * The accept function varies depending on your platform. Refer to the OTA
- * PAL implementation for your platform in aws_ota_pal.c to see what it
- * does for you.
- *
- * @param[in] event Specify if this demo is running with the AWS IoT
- * MQTT server. Set this to `false` if using another MQTT server.
- * @param[in] pData Data associated with the event.
- * @return None.
- */
-static void otaAppCallback( OtaJobEvent_t event,
- void * pData )
+void otaDemo_start( void )
{
- OtaErr_t err = OtaErrUninitialized;
+ OtaEventMsg_t initEvent = { 0 };
- switch( event )
+ if( !mqttWrapper_isConnected() )
{
- case OtaJobEventActivate:
- LogInfo( ( "Received OtaJobEventActivate callback from OTA Agent." ) );
-
- /**
- * Activate the new firmware image immediately. Applications can choose to postpone
- * the activation to a later stage if needed.
- */
- err = OTA_ActivateNewImage();
-
- /**
- * Activation of the new image failed. This indicates an error that requires a follow
- * up through manual activation by resetting the device. The demo reports the error
- * and shuts down the OTA agent.
- */
- LogError( ( "New image activation failed." ) );
+ LogInfo( "MQTT not connected, exiting!" );
+ return;
+ }
- /* Shutdown OTA Agent, if it is required that the unsubscribe operations are not
- * performed while shutting down please set the second parameter to 0 instead of 1. */
- OTA_Shutdown( 0, 1 );
+ bufferSemaphore = xSemaphoreCreateMutex();
+ if( bufferSemaphore != NULL )
+ {
+ memset( dataBuffers, 0x00, sizeof( dataBuffers ) );
+ }
- break;
+ LogError( "Starting OTA thread." );
- case OtaJobEventFail:
+ OtaInitEvent_FreeRTOS();
- /**
- * No user action is needed here. OTA agent handles the job failure event.
- */
- LogInfo( ( "Received an OtaJobEventFail notification from OTA Agent." ) );
+ initEvent.eventId = OtaAgentEventRequestJobDocument;
+ OtaSendEvent_FreeRTOS( &initEvent );
- break;
+ while( otaAgentState != OtaAgentStateStopped )
+ {
+ processOTAEvents();
+ }
+}
- case OtaJobEventStartTest:
+/*-----------------------------------------------------------*/
- /* This demo just accepts the image since it was a good OTA update and networking
- * and services are all working (or we would not have made it this far). If this
- * were some custom device that wants to test other things before validating new
- * image, this would be the place to kick off those tests before calling
- * OTA_SetImageState() with the final result of either accepted or rejected. */
+static void requestJobDocumentHandler( void )
+{
+ char thingName[ MAX_THING_NAME_SIZE + 1 ] = { 0 };
+ size_t thingNameLength = 0U;
+ char topicBuffer[ TOPIC_BUFFER_SIZE + 1 ] = { 0 };
+ char messageBuffer[ START_JOB_MSG_LENGTH ] = { 0 };
+ size_t topicLength = 0U;
- LogInfo( ( "Received OtaJobEventStartTest callback from OTA Agent." ) );
+ mqttWrapper_getThingName( thingName, &thingNameLength );
- err = OTA_SetImageState( OtaImageStateAccepted );
+ /*
+ * AWS IoT Jobs library:
+ * Creates the topic string for a StartNextPendingJobExecution request.
+ * It used to check if any pending jobs are available.
+ */
+ Jobs_StartNext( topicBuffer,
+ TOPIC_BUFFER_SIZE,
+ thingName,
+ ( uint16_t ) thingNameLength,
+ &topicLength );
- if( err == OtaErrNone )
- {
- LogInfo( ( "New image validation succeeded in self test mode." ) );
- }
- else
- {
- LogError( ( "Failed to set image state as accepted with error %d.", err ) );
- }
+ /*
+ * AWS IoT Jobs library:
+ * Creates the message string for a StartNextPendingJobExecution request.
+ * It will be sent on the topic created in the previous step.
+ */
+ size_t messageLength = Jobs_StartNextMsg( "test",
+ 4U,
+ messageBuffer,
+ START_JOB_MSG_LENGTH );
+
+ mqttWrapper_publish( topicBuffer,
+ topicLength,
+ ( uint8_t * ) messageBuffer,
+ messageLength );
+}
- break;
+/*-----------------------------------------------------------*/
- case OtaJobEventProcessed:
+static void initMqttDownloader( AfrOtaJobDocumentFields_t * jobFields )
+{
+ char thingName[ MAX_THING_NAME_SIZE + 1 ] = { 0 };
+ size_t thingNameLength = 0U;
- LogDebug( ( "OTA Event processing completed. Freeing the event buffer to pool." ) );
- configASSERT( pData != NULL );
- prvOTAEventBufferFree( ( OtaEventData_t * ) pData );
+ numOfBlocksRemaining = jobFields->fileSize /
+ mqttFileDownloader_CONFIG_BLOCK_SIZE;
+ numOfBlocksRemaining += ( jobFields->fileSize %
+ mqttFileDownloader_CONFIG_BLOCK_SIZE > 0 ) ? 1 : 0;
+ currentFileId = ( uint8_t ) jobFields->fileId;
+ currentBlockOffset = 0;
+ totalBytesReceived = 0;
- break;
+ mqttWrapper_getThingName( thingName, &thingNameLength );
- case OtaJobEventSelfTestFailed:
- LogDebug( ( "Received OtaJobEventSelfTestFailed callback from OTA Agent." ) );
+ /*
+ * MQTT streams Library:
+ * Initializing the MQTT streams downloader. Passing the
+ * parameters extracted from the AWS IoT OTA jobs document
+ * using OTA jobs parser.
+ */
+ mqttDownloader_init( &mqttFileDownloaderContext,
+ jobFields->imageRef,
+ jobFields->imageRefLen,
+ thingName,
+ thingNameLength,
+ DATA_TYPE_JSON );
+
+ mqttWrapper_subscribe( mqttFileDownloaderContext.topicStreamData,
+ mqttFileDownloaderContext.topicStreamDataLength );
+}
- /* Requires manual activation of previous image as self-test for
- * new image downloaded failed.*/
- LogError( ( "OTA Self-test failed for new image. shutting down OTA Agent." ) );
+/*-----------------------------------------------------------*/
- /* Shutdown OTA Agent, if it is required that the unsubscribe operations are not
- * performed while shutting down please set the second parameter to 0 instead of 1. */
- OTA_Shutdown( 0, 1 );
+static bool convertSignatureToDER( AfrOtaJobDocumentFields_t * jobFields )
+{
+ bool returnVal = true;
+ size_t decodedSignatureLength = 0;
- break;
- default:
- LogWarn( ( "Received an unhandled callback event from OTA Agent, event = %d", event ) );
+ Base64Status_t xResult = base64_Decode( OtaImageSingatureDecoded,
+ sizeof( OtaImageSingatureDecoded ),
+ &decodedSignatureLength,
+ jobFields->signature,
+ jobFields->signatureLen );
- break;
+ if( xResult == Base64Success )
+ {
+ jobFields->signature = OtaImageSingatureDecoded;
+ jobFields->signatureLen = decodedSignatureLength;
+ }
+ else
+ {
+ returnVal = false;
}
+
+ return returnVal;
}
/*-----------------------------------------------------------*/
-static void prvProcessIncomingMessage( void * pxSubscriptionContext,
- MQTTPublishInfo_t * pxPublishInfo )
+static int16_t handleMqttStreamsBlockArrived( uint8_t * data,
+ size_t dataLength )
{
- bool isMatched = false;
+ int16_t writeblockRes = -1;
- {
- ( void ) MQTT_MatchTopic( pxPublishInfo->pTopicName,
- pxPublishInfo->topicNameLength,
- OTA_JOB_NOTIFY_TOPIC_FILTER,
- OTA_JOB_NOTIFY_TOPIC_FILTER_LENGTH,
- &isMatched );
+ LogInfo( "Downloaded block %u of %u. \n", currentBlockOffset, ( currentBlockOffset + numOfBlocksRemaining ) );
- if( isMatched == true )
- {
- prvProcessIncomingJobMessage( pxSubscriptionContext, pxPublishInfo );
- }
- }
+ writeblockRes = otaPal_WriteBlock( &jobFields,
+ totalBytesReceived,
+ data,
+ dataLength );
- if( isMatched == false )
+ if( writeblockRes > 0 )
{
- ( void ) MQTT_MatchTopic( pxPublishInfo->pTopicName,
- pxPublishInfo->topicNameLength,
- OTA_DATA_STREAM_TOPIC_FILTER,
- OTA_DATA_STREAM_TOPIC_FILTER_LENGTH,
- &isMatched );
-
- if( isMatched == true )
- {
- prvProcessIncomingData( pxSubscriptionContext, pxPublishInfo );
- }
+ totalBytesReceived += writeblockRes;
}
+
+ return writeblockRes;
}
/*-----------------------------------------------------------*/
-static void prvProcessIncomingData( void * pxSubscriptionContext,
- MQTTPublishInfo_t * pPublishInfo )
+static void requestDataBlock( void )
{
- BaseType_t isMatch = pdFALSE;
- OtaEventData_t * pData;
- OtaEventMsg_t eventMsg = { 0 };
-
+ char getStreamRequest[ GET_STREAM_REQUEST_BUFFER_SIZE ];
+ size_t getStreamRequestLength = 0U;
- configASSERT( pPublishInfo != NULL );
- ( void ) pxSubscriptionContext;
+ /*
+ * MQTT streams Library:
+ * Creating the Get data block request. MQTT streams library only
+ * creates the get block request. To publish the request, MQTT libraries
+ * like coreMQTT are required.
+ */
+ getStreamRequestLength = mqttDownloader_createGetDataBlockRequest( mqttFileDownloaderContext.dataType,
+ currentFileId,
+ mqttFileDownloader_CONFIG_BLOCK_SIZE,
+ ( uint16_t ) currentBlockOffset,
+ NUM_OF_BLOCKS_REQUESTED,
+ getStreamRequest,
+ GET_STREAM_REQUEST_BUFFER_SIZE );
+
+ mqttWrapper_publish( mqttFileDownloaderContext.topicGetStream,
+ mqttFileDownloaderContext.topicGetStreamLength,
+ ( uint8_t * ) getStreamRequest,
+ getStreamRequestLength );
+}
- isMatch = prvMatchClientIdentifierInTopic( pPublishInfo->pTopicName,
- pPublishInfo->topicNameLength,
- pcThingName,
- xThingNameLength );
+/*-----------------------------------------------------------*/
- if( isMatch == pdTRUE )
- {
- if( pPublishInfo->payloadLength <= OTA_DATA_BLOCK_SIZE )
- {
- pData = prvOTAEventBufferGet();
+static bool closeFileHandler( void )
+{
+ return( OtaPalSuccess == otaPal_CloseFile( &jobFields ) );
+}
- if( pData != NULL )
- {
- memcpy( pData->data, pPublishInfo->pPayload, pPublishInfo->payloadLength );
- pData->dataLength = pPublishInfo->payloadLength;
- eventMsg.eventId = OtaAgentEventReceivedFileBlock;
- eventMsg.pEventData = pData;
+/*-----------------------------------------------------------*/
- /* Send job document received event. */
- OTA_SignalEvent( &eventMsg );
- }
- else
- {
- LogError( ( "Error: No OTA data buffers available.\r\n" ) );
- }
- }
- else
- {
- LogError( ( "Received OTA data block of size (%d) larger than maximum size(%d) defined. ",
- pPublishInfo->payloadLength,
- OTA_DATA_BLOCK_SIZE ) );
- }
- }
- else
- {
- LogWarn( ( "Received data block on an unsolicited topic, thing name does not match. topic: %.*s ",
- pPublishInfo->topicNameLength,
- pPublishInfo->pTopicName ) );
- }
+static bool imageActivationHandler( void )
+{
+ return( OtaPalSuccess == otaPal_ActivateNewImage( &jobFields ) );
}
/*-----------------------------------------------------------*/
-static void prvProcessIncomingJobMessage( void * pxSubscriptionContext,
- MQTTPublishInfo_t * pPublishInfo )
+static OtaPalJobDocProcessingResult_t receivedJobDocumentHandler( OtaJobEventData_t * jobDoc )
{
- OtaEventData_t * pData;
- OtaEventMsg_t eventMsg = { 0 };
- BaseType_t isMatch = pdFALSE;
+ bool parseJobDocument = false;
+ bool handled = false;
+ char * jobId;
+ const char ** jobIdptr = &jobId;
+ size_t jobIdLength = 0U;
+ OtaPalJobDocProcessingResult_t xResult = OtaPalJobDocFileCreateFailed;
+
+ memset( &jobFields, 0, sizeof( jobFields ) );
- ( void ) pxSubscriptionContext;
- configASSERT( pPublishInfo != NULL );
+ /*
+ * AWS IoT Jobs library:
+ * Extracting the job ID from the received OTA job document.
+ */
+ jobIdLength = Jobs_GetJobId( ( char * ) jobDoc->jobData, jobDoc->jobDataLength, jobIdptr );
- isMatch = prvMatchClientIdentifierInTopic( pPublishInfo->pTopicName,
- pPublishInfo->topicNameLength,
- pcThingName,
- xThingNameLength );
+ if( jobIdLength )
+ {
+ if( strncmp( globalJobId, jobId, jobIdLength ) )
+ {
+ parseJobDocument = true;
+ strncpy( globalJobId, jobId, jobIdLength );
+ }
+ else
+ {
+ xResult = OtaPalJobDocFileCreated;
+ }
+ }
- if( isMatch == pdTRUE )
+ if( parseJobDocument )
{
- if( pPublishInfo->payloadLength <= OTA_DATA_BLOCK_SIZE )
+ handled = jobDocumentParser( ( char * ) jobDoc->jobData, jobDoc->jobDataLength, &jobFields );
+
+ if( handled )
{
- LogInfo( ( "Received OTA job message, size: %d.\n\n", pPublishInfo->payloadLength ) );
- pData = prvOTAEventBufferGet();
+ initMqttDownloader( &jobFields );
- if( pData != NULL )
- {
- memcpy( pData->data, pPublishInfo->pPayload, pPublishInfo->payloadLength );
- pData->dataLength = pPublishInfo->payloadLength;
- eventMsg.eventId = OtaAgentEventReceivedJobDocument;
- eventMsg.pEventData = pData;
+ /* AWS IoT core returns the signature in a PEM format. We need to
+ * convert it to DER format for image signature verification. */
+
+ handled = convertSignatureToDER( &jobFields );
- /* Send job document received event. */
- OTA_SignalEvent( &eventMsg );
+ if( handled )
+ {
+ xResult = otaPal_CreateFileForRx( &jobFields );
}
else
{
- LogError( ( "Error: No OTA data buffers available.\r\n" ) );
+ LogError( "Failed to decode the image signature to DER format." );
}
}
- else
- {
- LogError( ( "Received OTA job message size (%d) is larger than the OTA maximum size (%d) defined.\n\n", pPublishInfo->payloadLength, OTA_DATA_BLOCK_SIZE ) );
- }
- }
- else
- {
- LogWarn( ( "Received a job message on an unsolicited topic, thing name does not match. topic: %.*s ",
- pPublishInfo->topicNameLength,
- pPublishInfo->pTopicName ) );
}
-}
+ return xResult;
+}
/*-----------------------------------------------------------*/
-static BaseType_t prvMatchClientIdentifierInTopic( const char * pTopic,
- size_t topicNameLength,
- const char * pClientIdentifier,
- size_t clientIdentifierLength )
+static uint16_t getFreeOTABuffers( void )
{
- BaseType_t isMatch = pdFALSE;
- size_t idx;
- size_t matchIdx = 0;
+ uint32_t ulIndex = 0;
+ uint16_t freeBuffers = 0;
- for( idx = OTA_TOPIC_CLIENT_IDENTIFIER_START_IDX; idx < topicNameLength; idx++ )
+ if( xSemaphoreTake( bufferSemaphore, portMAX_DELAY ) == pdTRUE )
{
- if( matchIdx == clientIdentifierLength )
- {
- if( pTopic[ idx ] == '/' )
- {
- isMatch = pdTRUE;
- }
-
- break;
- }
- else
+ for( ulIndex = 0; ulIndex < MAX_NUM_OF_OTA_DATA_BUFFERS; ulIndex++ )
{
- if( pClientIdentifier[ matchIdx ] != pTopic[ idx ] )
+ if( dataBuffers[ ulIndex ].bufferUsed == false )
{
- break;
+ freeBuffers++;
}
}
- matchIdx++;
+ ( void ) xSemaphoreGive( bufferSemaphore );
+ }
+ else
+ {
+ LogInfo( "Failed to get buffer semaphore. \n" );
}
- return isMatch;
+ return freeBuffers;
}
/*-----------------------------------------------------------*/
-static void prvCommandCallback( MQTTAgentCommandContext_t * pCommandContext,
- MQTTAgentReturnInfo_t * pxReturnInfo )
+static void freeOtaDataEventBuffer( OtaDataEvent_t * const pxBuffer )
{
- if( pCommandContext->xTaskToNotify != NULL )
+ if( xSemaphoreTake( bufferSemaphore, portMAX_DELAY ) == pdTRUE )
+ {
+ pxBuffer->bufferUsed = false;
+ ( void ) xSemaphoreGive( bufferSemaphore );
+ }
+ else
{
- xTaskNotify( pCommandContext->xTaskToNotify, ( uint32_t ) ( pxReturnInfo->returnCode ), eSetValueWithOverwrite );
+ LogInfo( "Failed to get buffer semaphore.\n" );
}
}
-
/*-----------------------------------------------------------*/
-static void prvSubscribeCommandCallback( MQTTAgentCommandContext_t * pxCommandContext,
- MQTTAgentReturnInfo_t * pxReturnInfo )
+/* Implemented for use by the MQTT library */
+bool otaDemo_handleIncomingMQTTMessage( char * topic,
+ size_t topicLength,
+ uint8_t * message,
+ size_t messageLength )
{
- MQTTAgentSubscribeArgs_t * pxSubscribeArgs = ( MQTTAgentSubscribeArgs_t * ) pxCommandContext->pArgs;
- BaseType_t xResult;
+ OtaEventMsg_t nextEvent = { 0 };
+ char thingName[ MAX_THING_NAME_SIZE + 1 ] = { 0 };
+ size_t thingNameLength = 0U;
+
+ /*
+ * MQTT streams Library:
+ * Checks if the incoming message contains the requested data block. It is performed by
+ * comparing the incoming MQTT message topic with MQTT streams topics.
+ */
+ bool handled = mqttDownloader_isDataBlockReceived( &mqttFileDownloaderContext, topic, topicLength );
- if( pxReturnInfo->returnCode == MQTTSuccess )
+ if( handled )
{
- xResult = xAddMQTTTopicFilterCallback( pxSubscribeArgs->pSubscribeInfo[ 0 ].pTopicFilter,
- pxSubscribeArgs->pSubscribeInfo[ 0 ].topicFilterLength,
- prvProcessIncomingMessage,
- NULL,
- pdFALSE );
- configASSERT( xResult == pdTRUE );
+ nextEvent.eventId = OtaAgentEventReceivedFileBlock;
+ OtaDataEvent_t * dataBuf = getOtaDataEventBuffer();
+ memcpy( dataBuf->data, message, messageLength );
+ nextEvent.dataEvent = dataBuf;
+ dataBuf->dataLength = messageLength;
+ OtaSendEvent_FreeRTOS( &nextEvent );
}
-
- if( pxCommandContext->xTaskToNotify != NULL )
+ else
{
- xTaskNotify( pxCommandContext->xTaskToNotify, ( uint32_t ) ( pxReturnInfo->returnCode ), eSetValueWithOverwrite );
+ mqttWrapper_getThingName( thingName, &thingNameLength );
+
+ /*
+ * AWS IoT Jobs library:
+ * Checks if a message comes from the start-next/accepted reserved topic.
+ */
+ handled = Jobs_IsStartNextAccepted( topic,
+ topicLength,
+ thingName,
+ thingNameLength );
+
+ if( handled )
+ {
+ memcpy( jobDocBuffer.jobData, message, messageLength );
+ nextEvent.jobEvent = &jobDocBuffer;
+ jobDocBuffer.jobDataLength = messageLength;
+ nextEvent.eventId = OtaAgentEventReceivedJobDocument;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ }
}
+
+ return handled;
}
/*-----------------------------------------------------------*/
-static void prvUnSubscribeCommandCallback( MQTTAgentCommandContext_t * pxCommandContext,
- MQTTAgentReturnInfo_t * pxReturnInfo )
+static bool sendSuccessMessage( void )
{
- MQTTAgentSubscribeArgs_t * pxSubscribeArgs = ( MQTTAgentSubscribeArgs_t * ) pxCommandContext->pArgs;
+ char thingName[ MAX_THING_NAME_SIZE + 1 ] = { 0 };
+ size_t thingNameLength = 0U;
+ char topicBuffer[ TOPIC_BUFFER_SIZE + 1 ] = { 0 };
+ size_t topicBufferLength = 0U;
+ char messageBuffer[ UPDATE_JOB_MSG_LENGTH ] = { 0 };
+ bool result = true;
+ JobsStatus_t jobStatusResult;
- if( pxReturnInfo->returnCode == MQTTSuccess )
+ mqttWrapper_getThingName( thingName, &thingNameLength );
+
+ /*
+ * AWS IoT Jobs library:
+ * Creating the MQTT topic to update the status of OTA job.
+ */
+ jobStatusResult = Jobs_Update( topicBuffer,
+ TOPIC_BUFFER_SIZE,
+ thingName,
+ ( uint16_t ) thingNameLength,
+ globalJobId,
+ ( uint16_t ) strnlen( globalJobId, 1000U ),
+ &topicBufferLength );
+
+ if( jobStatusResult == JobsSuccess )
{
- vRemoveMQTTTopicFilterCallback( pxSubscribeArgs->pSubscribeInfo[ 0 ].pTopicFilter,
- pxSubscribeArgs->pSubscribeInfo[ 0 ].topicFilterLength );
+ /*
+ * AWS IoT Jobs library:
+ * Creating the message which contains the status of OTA job.
+ * It will be published on the topic created in the previous step.
+ */
+ size_t messageBufferLength = Jobs_UpdateMsg( Succeeded,
+ "2",
+ 1U,
+ messageBuffer,
+ UPDATE_JOB_MSG_LENGTH );
+
+ result = mqttWrapper_publish( topicBuffer,
+ topicBufferLength,
+ ( uint8_t * ) messageBuffer,
+ messageBufferLength );
+
+ LogInfo( "\033[1;32mOTA Completed successfully!\033[0m\n" );
+ globalJobId[ 0 ] = 0U;
+
+ /* Clean up the job doc buffer so that it is ready for when we
+ * receive new job doc. */
+ memset( &jobDocBuffer, 0, sizeof( jobDocBuffer ) );
}
-
- if( pxCommandContext->xTaskToNotify != NULL )
+ else
{
- xTaskNotify( pxCommandContext->xTaskToNotify, ( uint32_t ) ( pxReturnInfo->returnCode ), eSetValueWithOverwrite );
+ result = false;
}
+
+ return result;
}
/*-----------------------------------------------------------*/
-
-static OtaMqttStatus_t prvMQTTSubscribe( const char * pTopicFilter,
- uint16_t topicFilterLength,
- uint8_t ucQoS )
+static bool jobDocumentParser( char * message,
+ size_t messageLength,
+ AfrOtaJobDocumentFields_t * jobFields )
{
- MQTTStatus_t mqttStatus;
- uint32_t ulNotifiedValue;
- MQTTAgentSubscribeArgs_t xSubscribeArgs = { 0 };
- MQTTSubscribeInfo_t xSubscribeInfo = { 0 };
- BaseType_t result;
- MQTTAgentCommandInfo_t xCommandParams = { 0 };
- MQTTAgentCommandContext_t xCommandContext = { 0 };
- OtaMqttStatus_t otaRet = OtaMqttSuccess;
-
- configASSERT( pTopicFilter != NULL );
- configASSERT( topicFilterLength > 0 );
-
- xSubscribeInfo.pTopicFilter = pTopicFilter;
- xSubscribeInfo.topicFilterLength = topicFilterLength;
- xSubscribeInfo.qos = ucQoS;
- xSubscribeArgs.pSubscribeInfo = &xSubscribeInfo;
- xSubscribeArgs.numSubscriptions = 1;
-
- xCommandContext.pArgs = ( void * ) ( &xSubscribeArgs );
- xCommandContext.xTaskToNotify = xTaskGetCurrentTaskHandle();
-
- xCommandParams.blockTimeMs = otaexampleMQTT_TIMEOUT_MS;
- xCommandParams.cmdCompleteCallback = prvSubscribeCommandCallback;
- xCommandParams.pCmdCompleteCallbackContext = ( void * ) &xCommandContext;
+ const char * jobDoc;
+ size_t jobDocLength = 0U;
+ int8_t fileIndex = 0;
/*
- * Wait for Agent to be connected before sending a subscribe message.
+ * AWS IoT Jobs library:
+ * Extracting the OTA job document from the jobs message recevied from AWS IoT core.
*/
- if( xGetMQTTAgentState() != MQTT_AGENT_STATE_CONNECTED )
+ jobDocLength = Jobs_GetJobDocument( message, messageLength, &jobDoc );
+
+ if( jobDocLength != 0U )
{
- ( void ) xWaitForMQTTAgentState( MQTT_AGENT_STATE_CONNECTED, portMAX_DELAY );
+ do
+ {
+ /*
+ * AWS IoT Jobs library:
+ * Parsing the OTA job document to extract all of the parameters needed to download
+ * the new firmware.
+ */
+ fileIndex = otaParser_parseJobDocFile( jobDoc,
+ jobDocLength,
+ fileIndex,
+ jobFields );
+ } while( fileIndex > 0 );
}
- xTaskNotifyStateClear( NULL );
+ /* File index will be -1 if an error occured, and 0 if all files were
+ * processed. */
+ return fileIndex == 0;
+}
- mqttStatus = MQTTAgent_Subscribe( &xGlobalMqttAgentContext,
- &xSubscribeArgs,
- &xCommandParams );
+/*-----------------------------------------------------------*/
- /* Block for command to complete so MQTTSubscribeInfo_t remains in scope for the
- * duration of the command. */
- if( mqttStatus == MQTTSuccess )
- {
- result = xTaskNotifyWait( 0, otaexampleMAX_UINT32, &ulNotifiedValue, portMAX_DELAY );
+static OtaDataEvent_t * getOtaDataEventBuffer( void )
+{
+ uint32_t ulIndex = 0;
+ OtaDataEvent_t * freeBuffer = NULL;
- if( result == pdTRUE )
- {
- mqttStatus = ( MQTTStatus_t ) ( ulNotifiedValue );
- }
- else
+ if( xSemaphoreTake( bufferSemaphore, portMAX_DELAY ) == pdTRUE )
+ {
+ for( ulIndex = 0; ulIndex < MAX_NUM_OF_OTA_DATA_BUFFERS; ulIndex++ )
{
- mqttStatus = MQTTRecvFailed;
+ if( dataBuffers[ ulIndex ].bufferUsed == false )
+ {
+ dataBuffers[ ulIndex ].bufferUsed = true;
+ freeBuffer = &dataBuffers[ ulIndex ];
+ break;
+ }
}
- }
-
- if( mqttStatus != MQTTSuccess )
- {
- LogError( ( "Failed to SUBSCRIBE to topic with error = %u.",
- mqttStatus ) );
- otaRet = OtaMqttSubscribeFailed;
+ ( void ) xSemaphoreGive( bufferSemaphore );
}
else
{
- LogInfo( ( "Subscribed to topic %.*s.\n\n",
- topicFilterLength,
- pTopicFilter ) );
-
- otaRet = OtaMqttSuccess;
+ LogInfo( "Failed to get buffer semaphore. \n" );
}
- return otaRet;
+ return freeBuffer;
}
-static OtaMqttStatus_t prvMQTTPublish( const char * const pacTopic,
- uint16_t topicLen,
- const char * pMsg,
- uint32_t msgSize,
- uint8_t qos )
-{
- OtaMqttStatus_t otaRet = OtaMqttSuccess;
- BaseType_t result;
- MQTTStatus_t mqttStatus = MQTTBadParameter;
- MQTTPublishInfo_t publishInfo = { MQTTQoS0 };
- MQTTAgentCommandInfo_t xCommandParams = { 0 };
- MQTTAgentCommandContext_t xCommandContext = { 0 };
- uint32_t ulNotifiedValue;
-
- configASSERT( qos <= MQTTQoS2 );
-
- publishInfo.pTopicName = pacTopic;
- publishInfo.topicNameLength = topicLen;
- publishInfo.qos = ( MQTTQoS_t ) qos;
- publishInfo.pPayload = pMsg;
- publishInfo.payloadLength = msgSize;
+/*-----------------------------------------------------------*/
- xCommandContext.xTaskToNotify = xTaskGetCurrentTaskHandle();
+static void processOTAEvents( void )
+{
+ OtaEventMsg_t recvEvent = { 0 };
+ OtaEvent_t recvEventId = 0;
+ static OtaEvent_t lastRecvEventId = OtaAgentEventStart;
+ OtaEventMsg_t nextEvent = { 0 };
- xCommandParams.blockTimeMs = otaexampleMQTT_TIMEOUT_MS;
- xCommandParams.cmdCompleteCallback = prvCommandCallback;
- xCommandParams.pCmdCompleteCallbackContext = ( void * ) &xCommandContext;
+ OtaReceiveEvent_FreeRTOS( &recvEvent );
+ recvEventId = recvEvent.eventId;
- /*
- * Wait for Agent to be connected before sending a publish message.
- */
- if( xGetMQTTAgentState() != MQTT_AGENT_STATE_CONNECTED )
+ if( recvEventId != OtaAgentEventStart )
{
- ( void ) xWaitForMQTTAgentState( MQTT_AGENT_STATE_CONNECTED, portMAX_DELAY );
+ lastRecvEventId = recvEventId;
}
-
- xTaskNotifyStateClear( NULL );
-
- mqttStatus = MQTTAgent_Publish( &xGlobalMqttAgentContext,
- &publishInfo,
- &xCommandParams );
-
- /* Block for command to complete so MQTTPublishInfo_t remains in scope for the
- * duration of the command. */
- if( mqttStatus == MQTTSuccess )
+ else
{
- result = xTaskNotifyWait( 0, otaexampleMAX_UINT32, &ulNotifiedValue, portMAX_DELAY );
-
- if( result != pdTRUE )
- {
- mqttStatus = MQTTSendFailed;
- }
- else
+ if( lastRecvEventId == OtaAgentEventRequestFileBlock )
{
- mqttStatus = ( MQTTStatus_t ) ( ulNotifiedValue );
+ /* No current event and we have not received the new block
+ * since last timeout, try sending the request for block again. */
+ recvEventId = lastRecvEventId;
+
+ /* It is likely that the network was disconnected and reconnected,
+ * we should wait for the MQTT connection to go up. */
+ while( !mqttWrapper_isConnected() )
+ {
+ vTaskDelay( pdMS_TO_TICKS( 100 ) );
+ }
}
}
- if( mqttStatus != MQTTSuccess )
- {
- LogError( ( "Failed to send PUBLISH packet to broker with error = %u.", mqttStatus ) );
- otaRet = OtaMqttPublishFailed;
- }
- else
+ switch( recvEventId )
{
- LogInfo( ( "Sent PUBLISH packet to broker %.*s to broker.\n\n",
- topicLen,
- pacTopic ) );
+ case OtaAgentEventRequestJobDocument:
+ LogInfo( "Request Job Document event Received \n" );
+ LogInfo( "-------------------------------------\n" );
+ requestJobDocumentHandler();
+ otaAgentState = OtaAgentStateRequestingJob;
+ break;
- otaRet = OtaMqttSuccess;
- }
+ case OtaAgentEventReceivedJobDocument:
+ LogInfo( "Received Job Document event Received \n" );
+ LogInfo( "-------------------------------------\n" );
- return otaRet;
-}
+ if( otaAgentState == OtaAgentStateSuspended )
+ {
+ LogInfo( "OTA-Agent is in Suspend State. Hence dropping Job Document. \n" );
+ break;
+ }
-static OtaMqttStatus_t prvMQTTUnsubscribe( const char * pTopicFilter,
- uint16_t topicFilterLength,
- uint8_t ucQoS )
-{
- MQTTStatus_t mqttStatus;
- uint32_t ulNotifiedValue;
- MQTTAgentSubscribeArgs_t xSubscribeArgs = { 0 };
- MQTTSubscribeInfo_t xSubscribeInfo = { MQTTQoS0 };
- BaseType_t result;
- MQTTAgentCommandInfo_t xCommandParams = { 0 };
- MQTTAgentCommandContext_t xCommandContext = { 0 };
- OtaMqttStatus_t otaRet = OtaMqttSuccess;
+ switch( receivedJobDocumentHandler( recvEvent.jobEvent ) )
+ {
+ case OtaPalJobDocFileCreated:
+ LogInfo( "Received OTA Job. \n" );
+ nextEvent.eventId = OtaAgentEventRequestFileBlock;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ otaAgentState = OtaAgentStateCreatingFile;
+ break;
+
+ case OtaPalJobDocFileCreateFailed:
+ case OtaPalNewImageBootFailed:
+ case OtaPalJobDocProcessingStateInvalid:
+ LogInfo( "This is not an OTA job \n" );
+ break;
+
+ case OtaPalNewImageBooted:
+ ( void ) sendSuccessMessage();
+
+ /* Short delay before restarting the loop. This allows IoT core
+ * to update the status of the job. */
+ vTaskDelay( pdMS_TO_TICKS( 5000 ) );
+
+ /* Get ready for new OTA job. */
+ nextEvent.eventId = OtaAgentEventRequestJobDocument;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ break;
+ }
+
+ break;
- configASSERT( pTopicFilter != NULL );
- configASSERT( topicFilterLength > 0 );
- configASSERT( ucQoS <= MQTTQoS2 );
+ case OtaAgentEventRequestFileBlock:
+ otaAgentState = OtaAgentStateRequestingFileBlock;
+ LogInfo( "Request File Block event Received \n" );
+ LogInfo( "-----------------------------------\n" );
+
+ if( currentBlockOffset == 0 )
+ {
+ LogInfo( "Starting The Download. \n" );
+ }
- xSubscribeInfo.pTopicFilter = pTopicFilter;
- xSubscribeInfo.topicFilterLength = topicFilterLength;
- xSubscribeInfo.qos = ( MQTTQoS_t ) ucQoS;
- xSubscribeArgs.pSubscribeInfo = &xSubscribeInfo;
- xSubscribeArgs.numSubscriptions = 1;
+ requestDataBlock();
+ LogInfo( "ReqSent----------------------------\n" );
+ break;
+ case OtaAgentEventReceivedFileBlock:
+ LogInfo( "Received File Block event Received \n" );
+ LogInfo( "---------------------------------------\n" );
- xCommandContext.xTaskToNotify = xTaskGetCurrentTaskHandle();
- xCommandContext.pArgs = ( void * ) ( &xSubscribeArgs );
+ if( otaAgentState == OtaAgentStateSuspended )
+ {
+ LogInfo( "OTA-Agent is in Suspend State. Hence dropping File Block. \n" );
+ freeOtaDataEventBuffer( recvEvent.dataEvent );
+ break;
+ }
- xCommandParams.blockTimeMs = otaexampleMQTT_TIMEOUT_MS;
- xCommandParams.cmdCompleteCallback = prvUnSubscribeCommandCallback;
- xCommandParams.pCmdCompleteCallbackContext = ( void * ) &xCommandContext;
+ uint8_t decodedData[ mqttFileDownloader_CONFIG_BLOCK_SIZE ];
+ size_t decodedDataLength = 0;
+ MQTTFileDownloaderStatus_t xReturnStatus;
+ int16_t result = -1;
+ int32_t fileId;
+ int32_t blockId;
+ int32_t blockSize;
+ static int32_t lastReceivedblockId = -1;
+
+ /*
+ * MQTT streams Library:
+ * Extracting and decoding the received data block from the incoming MQTT message.
+ */
+ xReturnStatus = mqttDownloader_processReceivedDataBlock(
+ &mqttFileDownloaderContext,
+ recvEvent.dataEvent->data,
+ recvEvent.dataEvent->dataLength,
+ &fileId,
+ &blockId,
+ &blockSize,
+ decodedData,
+ &decodedDataLength );
+
+ if( xReturnStatus != MQTTFileDownloaderSuccess )
+ {
+ /* There was some failure in trying to decode the block. */
+ }
+ else if( fileId != jobFields.fileId )
+ {
+ /* Error - the file ID doesn't match with the one we received in the job document. */
+ }
+ else if( blockSize > mqttFileDownloader_CONFIG_BLOCK_SIZE )
+ {
+ /* Error - the block size doesn't match with what we requested. It can be smaller as
+ * the last block may or may not be of exact size. */
+ }
+ else if( blockId <= lastReceivedblockId )
+ {
+ /* Ignore this block. */
+ }
+ else
+ {
+ result = handleMqttStreamsBlockArrived( decodedData, decodedDataLength );
+ lastReceivedblockId = blockId;
+ }
- LogInfo( ( " Unsubscribing to topic filter: %s", pTopicFilter ) );
- xTaskNotifyStateClear( NULL );
+ freeOtaDataEventBuffer( recvEvent.dataEvent );
+ if( result > 0 )
+ {
+ numOfBlocksRemaining--;
+ currentBlockOffset++;
+ }
- mqttStatus = MQTTAgent_Unsubscribe( &xGlobalMqttAgentContext,
- &xSubscribeArgs,
- &xCommandParams );
+ if( ( numOfBlocksRemaining % 10 ) == 0 )
+ {
+ LogInfo( "Free OTA buffers %u", getFreeOTABuffers() );
+ }
- /* Block for command to complete so MQTTSubscribeInfo_t remains in scope for the
- * duration of the command. */
- if( mqttStatus == MQTTSuccess )
- {
- result = xTaskNotifyWait( 0, otaexampleMAX_UINT32, &ulNotifiedValue, portMAX_DELAY );
+ if( numOfBlocksRemaining == 0 )
+ {
+ nextEvent.eventId = OtaAgentEventCloseFile;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ }
+ else
+ {
+ if( currentBlockOffset % NUM_OF_BLOCKS_REQUESTED == 0 )
+ {
+ nextEvent.eventId = OtaAgentEventRequestFileBlock;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ }
+ }
- if( result == pdTRUE )
- {
- mqttStatus = ( MQTTStatus_t ) ( ulNotifiedValue );
- }
- else
- {
- mqttStatus = MQTTRecvFailed;
- }
- }
+ break;
- if( mqttStatus != MQTTSuccess )
- {
- LogError( ( "Failed to UNSUBSCRIBE from topic %.*s with error = %u.",
- topicFilterLength,
- pTopicFilter,
- mqttStatus ) );
+ case OtaAgentEventCloseFile:
+ LogInfo( "Close file event Received \n" );
+ LogInfo( "-----------------------\n" );
- otaRet = OtaMqttUnsubscribeFailed;
- }
- else
- {
- LogInfo( ( "UNSUBSCRIBED from topic %.*s.\n\n",
- topicFilterLength,
- pTopicFilter ) );
+ if( closeFileHandler() == true )
+ {
+ nextEvent.eventId = OtaAgentEventActivateImage;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ }
- otaRet = OtaMqttSuccess;
- }
+ break;
- return otaRet;
-}
+ case OtaAgentEventActivateImage:
+ LogInfo( "Activate Image event Received \n" );
+ LogInfo( "-----------------------\n" );
-/*-----------------------------------------------------------*/
+ if( imageActivationHandler() == true )
+ {
+ nextEvent.eventId = OtaAgentEventActivateImage;
+ OtaSendEvent_FreeRTOS( &nextEvent );
+ }
-static void setOtaInterfaces( OtaInterfaces_t * pOtaInterfaces )
-{
- configASSERT( pOtaInterfaces != NULL );
-
- /* Initialize OTA library OS Interface. */
- pOtaInterfaces->os.event.init = OtaInitEvent_FreeRTOS;
- pOtaInterfaces->os.event.send = OtaSendEvent_FreeRTOS;
- pOtaInterfaces->os.event.recv = OtaReceiveEvent_FreeRTOS;
- pOtaInterfaces->os.event.deinit = OtaDeinitEvent_FreeRTOS;
- pOtaInterfaces->os.timer.start = OtaStartTimer_FreeRTOS;
- pOtaInterfaces->os.timer.stop = OtaStopTimer_FreeRTOS;
- pOtaInterfaces->os.timer.delete = OtaDeleteTimer_FreeRTOS;
- pOtaInterfaces->os.mem.malloc = Malloc_FreeRTOS;
- pOtaInterfaces->os.mem.free = Free_FreeRTOS;
-
- /* Initialize the OTA library MQTT Interface.*/
- pOtaInterfaces->mqtt.subscribe = prvMQTTSubscribe;
- pOtaInterfaces->mqtt.publish = prvMQTTPublish;
- pOtaInterfaces->mqtt.unsubscribe = prvMQTTUnsubscribe;
-
- /* Initialize the OTA library PAL Interface.*/
- pOtaInterfaces->pal.getPlatformImageState = xOtaPalGetPlatformImageState;
- pOtaInterfaces->pal.setPlatformImageState = xOtaPalSetPlatformImageState;
- pOtaInterfaces->pal.writeBlock = xOtaPalWriteBlock;
- pOtaInterfaces->pal.activate = xOtaPalActivateNewImage;
- pOtaInterfaces->pal.closeFile = xOtaPalCloseFile;
- pOtaInterfaces->pal.reset = xOtaPalResetDevice;
- pOtaInterfaces->pal.abort = xOtaPalAbort;
- pOtaInterfaces->pal.createFile = xOtaPalCreateFileForRx;
-}
+ otaAgentState = OtaAgentStateStopped;
+ break;
-static void prvSuspendOTAUpdate( void )
-{
- if( ( OTA_GetState() != OtaAgentStateSuspended ) && ( OTA_GetState() != OtaAgentStateStopped ) )
- {
- OTA_Suspend();
- while( ( OTA_GetState() != OtaAgentStateSuspended ) &&
- ( OTA_GetState() != OtaAgentStateStopped ) )
- {
- vTaskDelay( pdMS_TO_TICKS( otaexampleTASK_DELAY_MS ) );
- }
- }
-}
+ case OtaAgentEventSuspend:
+ LogInfo( "Suspend Event Received \n" );
+ LogInfo( "-----------------------\n" );
+ otaAgentState = OtaAgentStateSuspended;
+ break;
-static void prvResumeOTAUpdate( void )
-{
- if( OTA_GetState() == OtaAgentStateSuspended )
- {
- OTA_Resume();
+ case OtaAgentEventResume:
+ LogInfo( "Resume Event Received \n" );
+ LogInfo( "---------------------\n" );
+ otaAgentState = OtaAgentStateRequestingJob;
+ nextEvent.eventId = OtaAgentEventRequestJobDocument;
+ OtaSendEvent_FreeRTOS( &nextEvent );
- while( OTA_GetState() == OtaAgentStateSuspended )
- {
- vTaskDelay( pdMS_TO_TICKS( otaexampleTASK_DELAY_MS ) );
- }
+ default:
+ break;
}
}
+/*-----------------------------------------------------------*/
+
void vOTAUpdateTask( void * pvParam )
{
/* FreeRTOS APIs return status. */
BaseType_t xResult = pdPASS;
- /* OTA library return status. */
- OtaErr_t otaRet = OtaErrNone;
-
- /* OTA event message used for sending event to OTA Agent.*/
- OtaEventMsg_t eventMsg = { 0 };
-
- /* OTA interface context required for library interface functions.*/
- OtaInterfaces_t otaInterfaces;
-
- /* OTA library packet statistics per job.*/
- OtaAgentStatistics_t otaStatistics = { 0 };
-
-
( void ) pvParam;
- /* Set OTA Library interfaces.*/
- setOtaInterfaces( &otaInterfaces );
-
LogInfo( ( "OTA over MQTT demo, Application version %u.%u.%u",
appFirmwareVersion.u.x.major,
appFirmwareVersion.u.x.minor,
@@ -1204,36 +1136,6 @@ void vOTAUpdateTask( void * pvParam )
}
}
- if( xResult == pdPASS )
- {
- /*
- * Topic is an unsolicited topic, ie a subscription is not required with the MQTT broker.
- * Messages on this topic is directly sent to client. Hence this topic filter is added as
- * a static entry in the MQTT agent topic filter store. Last parameter indicates MQTT agent
- * should not subscribe to topic on a reconnection.
- */
- xResult = xAddMQTTTopicFilterCallback( OTA_JOB_ACCEPTED_RESPONSE_TOPIC_FILTER,
- OTA_JOB_ACCEPTED_RESPONSE_TOPIC_FILTER_LENGTH,
- prvProcessIncomingJobMessage,
- NULL,
- pdFALSE );
- }
-
- if( xResult == pdPASS )
- {
- memset( eventBuffer, 0x00, sizeof( eventBuffer ) );
-
- if( ( otaRet = OTA_Init( &otaBuffer,
- &otaInterfaces,
- ( const uint8_t * ) ( pcThingName ),
- otaAppCallback ) ) != OtaErrNone )
- {
- LogError( ( "Failed to initialize OTA Agent, exiting = %u.",
- otaRet ) );
- xResult = pdFAIL;
- }
- }
-
if( xResult == pdPASS )
{
if( ( xResult = xTaskCreate( prvOTAAgentTask,
@@ -1249,45 +1151,10 @@ void vOTAUpdateTask( void * pvParam )
}
}
- /***************************Start OTA demo loop. ******************************/
-
- if( xResult == pdPASS )
- {
- /* Start the OTA Agent.*/
- eventMsg.eventId = OtaAgentEventStart;
- OTA_SignalEvent( &eventMsg );
-
- while( OTA_GetState() != OtaAgentStateStopped )
- {
- /* Get OTA statistics for currently executing job. */
- OTA_GetStatistics( &otaStatistics );
- LogInfo( ( " Received: %u Queued: %u Processed: %u Dropped: %u",
- otaStatistics.otaPacketsReceived,
- otaStatistics.otaPacketsQueued,
- otaStatistics.otaPacketsProcessed,
- otaStatistics.otaPacketsDropped ) );
-
- if( xWaitForMQTTAgentState( MQTT_AGENT_STATE_DISCONNECTED,
- pdMS_TO_TICKS( otaexampleTASK_DELAY_MS ) ) == pdTRUE )
- {
- /* Suspend ongoing OTA job if any until MQTT agent is reconnected. */
- prvSuspendOTAUpdate();
-
- ( void ) xWaitForMQTTAgentState( MQTT_AGENT_STATE_CONNECTED, portMAX_DELAY );
-
- /* Resume OTA Update so that agent checks for any new jobs during a lost connection. */
- prvResumeOTAUpdate();
- }
- }
- }
+ vTaskDelay( portMAX_DELAY );
LogInfo( ( "OTA agent task stopped. Exiting OTA demo." ) );
-
- /* Unconditionally remove the static subscription. */
- vRemoveMQTTTopicFilterCallback( OTA_JOB_ACCEPTED_RESPONSE_TOPIC_FILTER,
- OTA_JOB_ACCEPTED_RESPONSE_TOPIC_FILTER_LENGTH );
-
if( pcThingName != NULL )
{
vPortFree( pcThingName );
diff --git a/examples/evkbmimxrt1060/bootloader/signing_pub_key.c b/examples/evkbmimxrt1060/bootloader/signing_pub_key.c
deleted file mode 100644
index dc0943f..0000000
--- a/examples/evkbmimxrt1060/bootloader/signing_pub_key.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#include "mcuboot_config.h"
-
-#if defined( MCUBOOT_SIGN_RSA )
-
-#error Please use MCUBoot imgtool.py to generate an RSA signing key \
- and replace this file with the output of the tool.
-
-const unsigned char rsa_pub_key[] = { 0x00 };
-const unsigned int rsa_pub_key_len = 0;
-
-#elif defined( MCUBOOT_SIGN_EC256 )
-
-#error Please use MCUBoot imgtool.py to generate an EC signing key \
- and replace this file with the output of the tool.
-
-const unsigned char ecdsa_pub_key[] = { 0x00 };
-const unsigned int ecdsa_pub_key_len = 0;
-
-#endif /* if defined( MCUBOOT_SIGN_RSA ) */
diff --git a/examples/evkbmimxrt1060/defender/include/FreeRTOSConfig.h b/examples/evkbmimxrt1060/defender/include/FreeRTOSConfig.h
index 2629dd3..1fee882 100644
--- a/examples/evkbmimxrt1060/defender/include/FreeRTOSConfig.h
+++ b/examples/evkbmimxrt1060/defender/include/FreeRTOSConfig.h
@@ -76,6 +76,9 @@ extern void vLoggingPrintf( const char * pcFormat,
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
#define configRECORD_STACK_HIGH_ADDRESS 1
+/* Task notification settings. */
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES ( 4 )
+
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
diff --git a/examples/evkbmimxrt1060/defender/include/MQTTFileDownloader_config.h b/examples/evkbmimxrt1060/defender/include/MQTTFileDownloader_config.h
new file mode 100644
index 0000000..6d7a256
--- /dev/null
+++ b/examples/evkbmimxrt1060/defender/include/MQTTFileDownloader_config.h
@@ -0,0 +1,27 @@
+/*
+ * AWS IoT Core MQTT File Streams Embedded C v1.1.0
+ * Copyright (C) 2023 Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @file MQTTFileDownloader_config.h
+ * @brief Configs for MQTT stream.
+ */
+
+#ifndef MQTT_FILE_DOWNLOADER_CONFIG_H
+#define MQTT_FILE_DOWNLOADER_CONFIG_H
+
+/**
+ * Configure the Maximum size of the data payload. The smallest value is 256 bytes,
+ * maximum is 128KB.
+ */
+#ifndef mqttFileDownloader_CONFIG_BLOCK_SIZE
+#define mqttFileDownloader_CONFIG_BLOCK_SIZE 512U
+#endif
+
+#endif /* #ifndef MQTT_FILE_DOWNLOADER_DEFAULT_H */
diff --git a/examples/evkbmimxrt1060/pubsub/app_main.c b/examples/evkbmimxrt1060/pubsub/app_main.c
index 107558d..a6a2467 100644
--- a/examples/evkbmimxrt1060/pubsub/app_main.c
+++ b/examples/evkbmimxrt1060/pubsub/app_main.c
@@ -47,7 +47,7 @@
* information for the device to connect to broker and perform OTA updates. Disabling the flag results
* in disabling the CLI task and execution of the demo tasks in normal device operation mode.
*/
-#define appmainPROVISIONING_MODE ( 1 )
+#define appmainPROVISIONING_MODE ( 0 )
/**
* @brief Subscribe Publish demo tasks configuration.
@@ -55,7 +55,7 @@
* to a topic, publishing messages to a topic and reporting the incoming messages on subscribed topic.
* Number of subscribe publish demo tasks to be spawned is configurable.
*/
-#define appmainMQTT_NUM_PUBSUB_TASKS ( 2 )
+#define appmainMQTT_NUM_PUBSUB_TASKS ( 0 )
#define appmainMQTT_PUBSUB_TASK_STACK_SIZE ( 2048 )
#define appmainMQTT_PUBSUB_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
@@ -97,6 +97,8 @@ int app_main( void )
xResult = KVStore_init();
+ configPRINTF( ( "Version 0.1.0" ) );
+
if( xResult == pdFAIL )
{
configPRINTF( ( "Failed to initialize key value configuration store.\r\n" ) );
diff --git a/examples/evkbmimxrt1060/pubsub/include/FreeRTOSConfig.h b/examples/evkbmimxrt1060/pubsub/include/FreeRTOSConfig.h
index 2629dd3..1fee882 100644
--- a/examples/evkbmimxrt1060/pubsub/include/FreeRTOSConfig.h
+++ b/examples/evkbmimxrt1060/pubsub/include/FreeRTOSConfig.h
@@ -76,6 +76,9 @@ extern void vLoggingPrintf( const char * pcFormat,
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
#define configRECORD_STACK_HIGH_ADDRESS 1
+/* Task notification settings. */
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES ( 4 )
+
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
diff --git a/examples/evkbmimxrt1060/pubsub/include/MQTTFileDownloader_config.h b/examples/evkbmimxrt1060/pubsub/include/MQTTFileDownloader_config.h
new file mode 100644
index 0000000..6d7a256
--- /dev/null
+++ b/examples/evkbmimxrt1060/pubsub/include/MQTTFileDownloader_config.h
@@ -0,0 +1,27 @@
+/*
+ * AWS IoT Core MQTT File Streams Embedded C v1.1.0
+ * Copyright (C) 2023 Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @file MQTTFileDownloader_config.h
+ * @brief Configs for MQTT stream.
+ */
+
+#ifndef MQTT_FILE_DOWNLOADER_CONFIG_H
+#define MQTT_FILE_DOWNLOADER_CONFIG_H
+
+/**
+ * Configure the Maximum size of the data payload. The smallest value is 256 bytes,
+ * maximum is 128KB.
+ */
+#ifndef mqttFileDownloader_CONFIG_BLOCK_SIZE
+#define mqttFileDownloader_CONFIG_BLOCK_SIZE 512U
+#endif
+
+#endif /* #ifndef MQTT_FILE_DOWNLOADER_DEFAULT_H */
diff --git a/examples/evkbmimxrt1060/pubsub/main.c b/examples/evkbmimxrt1060/pubsub/main.c
index eabd49f..5ef34b1 100644
--- a/examples/evkbmimxrt1060/pubsub/main.c
+++ b/examples/evkbmimxrt1060/pubsub/main.c
@@ -325,6 +325,7 @@ int main( void )
}
}
+
void vApplicationDaemonTaskStartupHook( void )
{
/* Initialize file system. */
diff --git a/examples/evkbmimxrt1060/shadow/include/FreeRTOSConfig.h b/examples/evkbmimxrt1060/shadow/include/FreeRTOSConfig.h
index 2629dd3..1fee882 100644
--- a/examples/evkbmimxrt1060/shadow/include/FreeRTOSConfig.h
+++ b/examples/evkbmimxrt1060/shadow/include/FreeRTOSConfig.h
@@ -76,6 +76,9 @@ extern void vLoggingPrintf( const char * pcFormat,
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
#define configRECORD_STACK_HIGH_ADDRESS 1
+/* Task notification settings. */
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES ( 4 )
+
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
diff --git a/examples/evkbmimxrt1060/shadow/include/MQTTFileDownloader_config.h b/examples/evkbmimxrt1060/shadow/include/MQTTFileDownloader_config.h
new file mode 100644
index 0000000..6d7a256
--- /dev/null
+++ b/examples/evkbmimxrt1060/shadow/include/MQTTFileDownloader_config.h
@@ -0,0 +1,27 @@
+/*
+ * AWS IoT Core MQTT File Streams Embedded C v1.1.0
+ * Copyright (C) 2023 Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @file MQTTFileDownloader_config.h
+ * @brief Configs for MQTT stream.
+ */
+
+#ifndef MQTT_FILE_DOWNLOADER_CONFIG_H
+#define MQTT_FILE_DOWNLOADER_CONFIG_H
+
+/**
+ * Configure the Maximum size of the data payload. The smallest value is 256 bytes,
+ * maximum is 128KB.
+ */
+#ifndef mqttFileDownloader_CONFIG_BLOCK_SIZE
+#define mqttFileDownloader_CONFIG_BLOCK_SIZE 512U
+#endif
+
+#endif /* #ifndef MQTT_FILE_DOWNLOADER_DEFAULT_H */
diff --git a/examples/evkbmimxrt1060/test/include/FreeRTOSConfig.h b/examples/evkbmimxrt1060/test/include/FreeRTOSConfig.h
index 2629dd3..1fee882 100644
--- a/examples/evkbmimxrt1060/test/include/FreeRTOSConfig.h
+++ b/examples/evkbmimxrt1060/test/include/FreeRTOSConfig.h
@@ -76,6 +76,9 @@ extern void vLoggingPrintf( const char * pcFormat,
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
#define configRECORD_STACK_HIGH_ADDRESS 1
+/* Task notification settings. */
+#define configTASK_NOTIFICATION_ARRAY_ENTRIES ( 4 )
+
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
diff --git a/examples/evkbmimxrt1060/test/include/MQTTFileDownloader_config.h b/examples/evkbmimxrt1060/test/include/MQTTFileDownloader_config.h
new file mode 100644
index 0000000..6d7a256
--- /dev/null
+++ b/examples/evkbmimxrt1060/test/include/MQTTFileDownloader_config.h
@@ -0,0 +1,27 @@
+/*
+ * AWS IoT Core MQTT File Streams Embedded C v1.1.0
+ * Copyright (C) 2023 Amazon.com, Inc. and its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: MIT
+ *
+ * Licensed under the MIT License. See the LICENSE accompanying this file
+ * for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @file MQTTFileDownloader_config.h
+ * @brief Configs for MQTT stream.
+ */
+
+#ifndef MQTT_FILE_DOWNLOADER_CONFIG_H
+#define MQTT_FILE_DOWNLOADER_CONFIG_H
+
+/**
+ * Configure the Maximum size of the data payload. The smallest value is 256 bytes,
+ * maximum is 128KB.
+ */
+#ifndef mqttFileDownloader_CONFIG_BLOCK_SIZE
+#define mqttFileDownloader_CONFIG_BLOCK_SIZE 512U
+#endif
+
+#endif /* #ifndef MQTT_FILE_DOWNLOADER_DEFAULT_H */
diff --git a/manifest.yml b/manifest.yml
index 4566d28..958f3eb 100644
--- a/manifest.yml
+++ b/manifest.yml
@@ -4,100 +4,112 @@ description: |-
"Reference IoT integration project using NXP i.MX RT1060 with EdgeLock® SE050 secure element and FreeRTOS LTS libraries"
dependencies:
- name: "FreeRTOS-Kernel"
- version: "V10.5.1"
+ version: "V11.1.0"
repository:
type: "git"
url: "https://github.com/FreeRTOS/FreeRTOS-Kernel.git"
- path: "/Middleware/FreeRTOS/kernel"
+ path: "Middleware/FreeRTOS/kernel"
- name: "coreJSON"
- version: "v3.2.0"
+ version: "v3.3.0"
repository:
type: "git"
url: "https://github.com/FreeRTOS/coreJSON.git"
- path: "/Middleware/FreeRTOS/coreJSON"
+ path: "Middleware/FreeRTOS/coreJSON"
- name: "coreMQTT"
- version: "v2.1.1"
+ version: "v2.3.0"
repository:
type: "git"
url: "https://github.com/FreeRTOS/coreMQTT.git"
- path: "/Middleware/FreeRTOS/coreMQTT"
+ path: "Middleware/FreeRTOS/coreMQTT"
- name: "corePKCS11"
- version: "v3.5.0"
+ version: "v3.6.1"
repository:
type: "git"
url: "https://github.com/FreeRTOS/corePKCS11.git"
- path: "/Middleware/FreeRTOS/corePKCS11"
+ path: "Middleware/FreeRTOS/corePKCS11"
- name: "backoffAlgorithm"
- version: "v1.3.0"
+ version: "v1.4.1"
repository:
type: "git"
url: "https://github.com/FreeRTOS/backoffAlgorithm"
- path: "/Middleware/FreeRTOS/backoffAlgorithm"
+ path: "Middleware/FreeRTOS/backoffAlgorithm"
- name: "coreMQTT-Agent"
version: "v1.2.0"
repository:
type: "git"
url: "https://github.com/FreeRTOS/coreMQTT-Agent.git"
- path: "/Middleware/FreeRTOS/coreMQTT-Agent"
+ path: "Middleware/FreeRTOS/coreMQTT-Agent"
- name: "device-defender"
- version: "v1.3.0"
+ version: "v1.4.0"
repository:
type: "git"
url: "https://github.com/aws/Device-Defender-for-AWS-IoT-embedded-sdk.git"
- path: "/Middleware/AWS/device-defender"
- - name: "ota"
- version: "v3.4.0"
- repository:
- type: "git"
- url: "https://github.com/aws/ota-for-AWS-IoT-embedded-sdk.git"
- path: "/Middleware/AWS/ota"
+ path: "Middleware/AWS/device-defender"
- name: "device-shadow"
- version: "v1.3.0"
+ version: "v1.4.1"
repository:
type: "git"
url: "https://github.com/aws/Device-Shadow-for-AWS-IoT-embedded-sdk.git"
- path: "/Middleware/AWS/device-shadow"
+ path: "Middleware/AWS/device-shadow"
- name: "mcux-sdk"
version: "MCUX_2.10.0"
repository:
type: "git"
url: "https://github.com/NXPmicro/mcux-sdk.git"
- path: "/core"
+ path: "core"
- name: "lwip"
version: "STABLE-2_1_2_RELEASE"
repository:
type: "git"
url: "https://github.com/lwip-tcpip/lwip.git"
- path: "/Middleware/lwip"
+ path: "Middleware/lwip"
- name: "mbedtls"
version: "v2.26.0"
repository:
type: "git"
url: "https://github.com/Mbed-TLS/mbedtls.git"
- path: "/Middleware/mbedtls"
+ path: "Middleware/mbedtls"
- name: "mcuboot"
version: "v1.7.2"
repository:
type: "git"
url: "https://github.com/mcu-tools/mcuboot.git"
- path: "/Middleware/mcuboot"
+ path: "Middleware/mcuboot"
- name: "tinycbor"
version: "v0.6.0"
repository:
type: "git"
url: "https://github.com/intel/tinycbor.git"
- path: "/Middleware/tinycbor"
+ path: "Middleware/tinycbor"
- name: "unity"
version: "db878ccaedaea3d07b3c5443a00d131ecacd30b3"
repository:
type: "git"
url: "https://github.com/ThrowTheSwitch/Unity.git"
- path: "/Middleware/unity"
+ path: "Middleware/unity"
- name: "FreeRTOS-Libraries-Integration-Tests"
- version: "202210.01"
+ version: "692d509"
repository:
type: "git"
url: "https://github.com/FreeRTOS/FreeRTOS-Libraries-Integration-Tests"
- path: "/Middleware/FreeRTOS/tests"
+ path: "Middleware/FreeRTOS/tests"
+ - name: "aws-iot-core-mqtt-file-streams-embedded-c"
+ version: "v1.1.0"
+ repository:
+ type: "git"
+ url: "https://github.com/aws/aws-iot-core-mqtt-file-streams-embedded-c"
+ path: "Middleware/AWS/mqtt-stream"
+ - name: "pkcs11"
+ version: "v2.40_errata01"
+ repository:
+ type: "git"
+ url: "https://github.com/amazon-freertos/pkcs11.git"
+ path: "Middleware/FreeRTOS/pkcs11"
+ - name: "Jobs-for-AWS-IoT-embedded-sdk"
+ version: "v1.5.1"
+ repository:
+ type: "git"
+ url: "https://github.com/aws/Jobs-for-AWS-IoT-embedded-sdk.git"
+ path: "Middleware/AWS/jobs"
license: "MIT"
diff --git a/projects/evkmimxrt1060/bootloader/.cproject b/projects/evkmimxrt1060/bootloader/.cproject
index 549607e..f2609e3 100644
--- a/projects/evkmimxrt1060/bootloader/.cproject
+++ b/projects/evkmimxrt1060/bootloader/.cproject
@@ -35,7 +35,7 @@
-
+
@@ -104,6 +104,8 @@
+
+
@@ -141,7 +143,6 @@
-
@@ -149,7 +150,7 @@
-
+
@@ -272,7 +273,7 @@
-
+
@@ -375,7 +376,7 @@
-
+
@@ -452,6 +453,8 @@
+
+
-
+
@@ -590,7 +593,7 @@
-
+
@@ -684,40 +687,31 @@
-
- SDK_2.x_MIMXRT1060-EVKB
- 2.10.1
- middleware.baremetal.MIMXRT1062;platform.drivers.clock.MIMXRT1062;platform.drivers.xip_device.MIMXRT1062;platform.drivers.lpuart.MIMXRT1062;platform.drivers.igpio.MIMXRT1062;platform.drivers.nic301.MIMXRT1062;platform.drivers.common.MIMXRT1062;platform.drivers.iomuxc.MIMXRT1062;component.serial_manager_uart.MIMXRT1062;component.serial_manager.MIMXRT1062;component.lpuart_adapter.MIMXRT1062;utility.debug_console.MIMXRT1062;platform.drivers.xip_board.evkmimxrt1060.MIMXRT1062;component.lists.MIMXRT1062;device.MIMXRT1062_startup.MIMXRT1062;CMSIS_Include_core_cm.MIMXRT1062;device.MIMXRT1062_CMSIS.MIMXRT1062;device.MIMXRT1062_system.MIMXRT1062;project_template.evkmimxrt1060.MIMXRT1062;
- evkmimxrt1060
- MIMXRT1062DVL6A
- cm7
- core0_MIMXRT1062xxxxA
-
- <?xml version="1.0" encoding="UTF-8"?>
-<TargetConfig>
-<Properties property_3="NXP" property_4="MIMXRT1062xxxxA" property_count="5" version="100300"/>
-<infoList vendor="NXP">
-<info chip="MIMXRT1062xxxxA" name="MIMXRT1062xxxxA">
-<chip>
-<name>MIMXRT1062xxxxA</name>
-<family>MIMXRT1060</family>
-<vendor>NXP</vendor>
-<memory can_program="true" id="Flash" is_ro="true" size="0" type="Flash"/>
-<memory id="RAM" size="1024" type="RAM"/>
-<memoryInstance derived_from="Flash" driver="MIMXRT1060_SFDP_QSPI.cfx" edited="true" id="BOARD_FLASH" location="0x60000000" size="0x800000"/>
-<memoryInstance derived_from="RAM" edited="true" id="SRAM_DTC" location="0x20000000" size="0x20000"/>
-<memoryInstance derived_from="RAM" edited="true" id="SRAM_ITC" location="0x0" size="0x20000"/>
-<memoryInstance derived_from="RAM" edited="true" id="SRAM_OC" location="0x20200000" size="0xc0000"/>
-<memoryInstance derived_from="RAM" edited="true" id="BOARD_SDRAM" location="0x80000000" size="0x1e00000"/>
-<memoryInstance derived_from="RAM" edited="true" id="NCACHE_REGION" location="0x81e00000" size="0x200000"/>
-</chip>
-<processor>
-<name gcc_name="cortex-m7">Cortex-M7</name>
-<family>Cortex-M</family>
-</processor>
-</info>
-</infoList>
+ <?xml version="1.0" encoding="UTF-8"?>
+<TargetConfig>
+<Properties property_3="NXP" property_4="MIMXRT1062xxxxB" property_count="5" version="100300"/>
+<infoList vendor="NXP">
+<info chip="MIMXRT1062xxxxB" name="MIMXRT1062xxxxB">
+<chip>
+<name>MIMXRT1062xxxxB</name>
+<family>MIMXRT1060</family>
+<vendor>NXP</vendor>
+<memory can_program="true" id="Flash" is_ro="true" size="0" type="Flash"/>
+<memory id="RAM" size="1024" type="RAM"/>
+<memoryInstance derived_from="Flash" driver="MIMXRT1060_SFDP_QSPI.cfx" edited="true" id="BOARD_FLASH" location="0x60000000" size="0x800000"/>
+<memoryInstance derived_from="RAM" edited="true" id="SRAM_DTC" location="0x20000000" size="0x20000"/>
+<memoryInstance derived_from="RAM" edited="true" id="SRAM_ITC" location="0x0" size="0x20000"/>
+<memoryInstance derived_from="RAM" edited="true" id="SRAM_OC" location="0x20200000" size="0xc0000"/>
+<memoryInstance derived_from="RAM" edited="true" id="BOARD_SDRAM" location="0x80000000" size="0x1e00000"/>
+<memoryInstance derived_from="RAM" edited="true" id="NCACHE_REGION" location="0x81e00000" size="0x200000"/>
+</chip>
+<processor>
+<name gcc_name="cortex-m7">Cortex-M7</name>
+<family>Cortex-M</family>
+</processor>
+</info>
+</infoList>
</TargetConfig>
@@ -729,4 +723,13 @@
-
+
+
+ SDK_2.x_MIMXRT1060-EVKB
+ 2.15.000
+ evkbmimxrt1060
+ MIMXRT1062DVL6B
+ cm7
+ core0_MIMXRT1062xxxxB
+
+
\ No newline at end of file
diff --git a/projects/evkmimxrt1060/bootloader/.settings/language.settings.xml b/projects/evkmimxrt1060/bootloader/.settings/language.settings.xml
new file mode 100644
index 0000000..08c4e0d
--- /dev/null
+++ b/projects/evkmimxrt1060/bootloader/.settings/language.settings.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/evkmimxrt1060/bootloader/.settings/org.eclipse.cdt.core.prefs b/projects/evkmimxrt1060/bootloader/.settings/org.eclipse.cdt.core.prefs
new file mode 100644
index 0000000..c8ec5df
--- /dev/null
+++ b/projects/evkmimxrt1060/bootloader/.settings/org.eclipse.cdt.core.prefs
@@ -0,0 +1,6 @@
+doxygen/doxygen_new_line_after_brief=true
+doxygen/doxygen_use_brief_tag=false
+doxygen/doxygen_use_javadoc_tags=true
+doxygen/doxygen_use_pre_tag=false
+doxygen/doxygen_use_structural_commands=false
+eclipse.preferences.version=1
diff --git a/projects/evkmimxrt1060/bootloader/.settings/org.eclipse.core.resources.prefs b/projects/evkmimxrt1060/bootloader/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/projects/evkmimxrt1060/bootloader/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/projects/evkmimxrt1060/bootloader/bootloader LinkServer Debug.launch b/projects/evkmimxrt1060/bootloader/bootloader LinkServer Debug.launch
new file mode 100644
index 0000000..12f979a
--- /dev/null
+++ b/projects/evkmimxrt1060/bootloader/bootloader LinkServer Debug.launch
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/evkmimxrt1060/defender/.cproject b/projects/evkmimxrt1060/defender/.cproject
index 9f24d96..e2bfb4c 100644
--- a/projects/evkmimxrt1060/defender/.cproject
+++ b/projects/evkmimxrt1060/defender/.cproject
@@ -58,6 +58,8 @@
+
+
@@ -131,13 +133,19 @@
-
+
+
+
+
+
+
+
@@ -157,7 +165,7 @@
-
+
-
+
+
@@ -262,10 +271,15 @@
-
+
+
+
+
+
+
@@ -279,7 +293,7 @@
-
+
@@ -312,6 +326,8 @@
+
+
@@ -328,14 +344,14 @@
-
+
-
+
@@ -121,8 +123,6 @@
-
-
@@ -134,9 +134,15 @@
+
+
+
+
+
+
@@ -156,7 +162,7 @@
-
+
-
+
+
@@ -189,7 +196,7 @@
-
+
@@ -222,9 +229,14 @@
+
+
+
@@ -238,14 +250,14 @@
-
+
-
+
@@ -121,9 +123,7 @@
-
-
@@ -135,9 +135,15 @@
+
+
+
+
+
+
@@ -157,7 +163,7 @@
-
+
-
+
+
@@ -252,9 +259,7 @@
-
-
@@ -266,6 +271,11 @@
+
+
+
+
+
@@ -279,7 +289,7 @@
-
+
@@ -312,6 +322,8 @@
+
+
@@ -328,14 +340,14 @@
-
+
-
+
@@ -145,9 +147,15 @@
+
+
+
+
+
+
@@ -191,6 +199,7 @@
+
@@ -200,7 +209,7 @@
-
+
@@ -233,6 +242,8 @@
+
+
@@ -256,7 +267,7 @@
-
+