diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000000000000000000000000000000000000..23a24c20bb1fcb4150b345d8012c67f989780b69 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,10 @@ +[target.thumbv7em-none-eabihf] +runner = 'arm-none-eabi-gdb' +rustflags = [ + "-C", "link-arg=-Tlink.x", + "-C", "linker=arm-none-eabi-ld", + "-Z", "linker-flavor=ld", +] + +[build] +target = "thumbv7em-none-eabihf" diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000000000000000000000000000000000000..90bca3d74a818810eb71148f4dde17a564b239fb --- /dev/null +++ b/.gdbinit @@ -0,0 +1,8 @@ +target remote :3333 + +monitor reset init +monitor arm semihosting enable +monitor tpiu config internal /tmp/itm.log uart off 84000000 +monitor itm port 0 on +load +monitor reset init diff --git a/.gitignore b/.gitignore index a7e04a7ccc1483d63845689895e2d858f84b7ee2..ed2510467fa18a3ec7a2e09b98ca3df290e926f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,18 @@ -*.log +**/*.rs.bk +.gdb_history +Cargo.lock +target/ + *.aux -*.bbl -*.blg +*.lof +*.log +*.lot +*.fls *.out -*.gz -*.pdf *.toc -*/target/* -/.vscode/* \ No newline at end of file +*.fmt +*.fot +*.cb +*.cb2 + +/Debug/ diff --git a/COURSE_GRADING.md b/COURSE_GRADING.md deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5b931df0918e7fe4f62ab9a23b2a507f1d846d51 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "d7018e_coap" +version = "0.1.0" +authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"] +categories = ["embedded", "hardware-support", "no-std"] +description = "CoAP on embedded rust" +readme = "README.md" +repository = "https://github.com/Shawnshank/D7018E_Project" +keywords = ["CoAP", "Embedded", "arm", "stm32"] +license = "MIT OR Apache-2.0" + + +[dependencies] +cortex-m-semihosting = "0.2.0" +static-ref = "0.2.0" +volatile-register = "0.2.0" +m = "0.1.1" +heapless = "0.2.1" +f4 = {git = "https://github.com/jsjolund/f4"} +xoap = { path = "../projects/xoap", version = "0.1.0", default-features = false, features = ["baremetal"] }#git = "https://github.com/Shawnshank/xoap", version = "0.1.0"} + +[dependencies.cast] +default-features = false +version = "0.2.2" + +[dependencies.cortex-m] +version = "0.3.1" + +[dependencies.either] +default-features = false +version = "1.3.0" + +[dependencies.embedded-hal] +git = "https://github.com/japaric/embedded-hal" +rev = "7d904f515d15fd5fe7ea34e18820ea83e2651fa2" + +[dependencies.nb] +git = "https://github.com/japaric/nb" + +[dependencies.cortex-m-rt] +features = ["abort-on-panic"] +version = "0.3.8" + +[dependencies.cortex-m-debug] +git = "https://gitlab.henriktjader.com/pln/cortex-m-debug.git" + +[dependencies.cortex-m-rtfm] +version = "0.2.0" + +[profile.release] +lto = true + +[profile.dev] +incremental = false +codegen-units = 1 \ No newline at end of file diff --git a/Client/Cargo.lock b/Client/Cargo.lock deleted file mode 100644 index 03c1e8a6b38945905abdd459215a129ce8bd5f45..0000000000000000000000000000000000000000 --- a/Client/Cargo.lock +++ /dev/null @@ -1,358 +0,0 @@ -[[package]] -name = "D7018E_Embedded_CoAp_client" -version = "0.1.0" -dependencies = [ - "coap 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bincode" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bytes" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cfg-if" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "coap" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bincode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "enum_primitive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libc" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "matches" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "mio" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "net2" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "nix" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-bigint" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-complex" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-iter" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-rational" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "num_cpus" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slab" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "threadpool" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "url" -version = "0.2.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "uuid" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum bincode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "951498c868b0683e1ba67afcdd6b1c3def08a713e66197aa17be8fad56cbaab5" -"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "29b2aa490a8f546381308d68fc79e6bd753cd3ad839f7a7172897f1feedfa175" -"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum coap 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "24c47dfbaf87a9a060aaa412b4af7852f512737f7bea3db50efcf035bb937e8f" -"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" -"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" -"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" -"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" -"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" -"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" -"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" -"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23" -"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c" -"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" -"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" -"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" -"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" -"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" -"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)" = "cbaa8377a162d88e7d15db0cf110c8523453edcbc5bc66d2b6fffccffa34a068" -"checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/Client/Cargo.toml b/Client/Cargo.toml deleted file mode 100644 index f5fd1251817423cd7f61c16e2803cdeee3e89b87..0000000000000000000000000000000000000000 --- a/Client/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "D7018E_Embedded_CoAp_client" -version = "0.1.0" -authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"] - -[dependencies] -coap = "0.5" \ No newline at end of file diff --git a/Client/src/main.rs b/Client/src/main.rs deleted file mode 100644 index 43720055fdcd5eb40c6b58a849d19f0b3eaec485..0000000000000000000000000000000000000000 --- a/Client/src/main.rs +++ /dev/null @@ -1,90 +0,0 @@ -// CoAP CLient -// D7018E - Embedded rust -// Joakim Lundberg <joakim@joakimlundberg.com> - -// Externally used crates -extern crate coap; - -use std::io::ErrorKind; -use coap::{CoAPClient, CoAPRequest, IsMessage, MessageType, CoAPOption}; - -fn main() { - println!("Request by GET:"); - let addr = "127.0.0.1:5683"; - let endpoint = "test"; - - let c = start_coap_client(addr); //CoAPClient::new(addr).unwrap(); - coap_get(c, addr, endpoint); - - println!("Request by POST:"); - coap_post(addr, endpoint); -} - -fn start_coap_client(address: &str) -> CoAPClient { - // Creates the CoAP client for the specific IP address - CoAPClient::new(address).unwrap() -} - - -fn coap_get(client: CoAPClient, address: &str, endpoint: &str) { - - // Creates a request to be - let mut request = CoAPRequest::new(); - - // Setup of the message header (4 bytes) - request.set_version(1); - request.set_type(MessageType::Confirmable); // MessageType (Confirmable, Non-confirmable, Acknowledgement, Reset) - request.set_code("0.01"); // Code -> Request code (1-10) or Response code (40-255) - request.set_message_id(1); // 16-bit identifier for matching responses - request.set_token(vec![0x51, 0x55, 0x77, 0xE8]); // optional response matching tokens - request.add_option(CoAPOption::UriPath, endpoint.to_string().into_bytes()); // additional options. eg URI - - // Sends the request - client.send(&request).unwrap(); - - println!("Client request: coap://{}/{}", address, endpoint); - - match client.receive() { - Ok(response) => { - println!("Server reply: {}", - String::from_utf8(response.message.payload).unwrap()); - } - Err(e) => { - match e.kind() { - ErrorKind::WouldBlock => println!("Request timeout"), // Unix - ErrorKind::TimedOut => println!("Request timeout"), // Windows - _ => println!("Request error: {:?}", e), - } - } - } -} - -fn coap_post(address: &str, endpoint: &str) { - - let client = CoAPClient::new(address).unwrap(); - let mut request = CoAPRequest::new(); - request.set_version(1); - request.set_type(MessageType::Confirmable); - request.set_code("0.02"); - request.set_message_id(1); - request.set_token(vec![0x51, 0x55, 0x77, 0xE8]); - request.add_option(CoAPOption::UriPath, endpoint.to_string().into_bytes()); - request.set_payload(b"data".to_vec()); - - client.send(&request).unwrap(); - println!("Client request: coap://{}/{}", address, endpoint); - - match client.receive() { - Ok(response) => { - println!("Server reply: {}", - String::from_utf8(response.message.payload).unwrap()); - } - Err(e) => { - match e.kind() { - ErrorKind::WouldBlock => println!("Request timeout"), // Unix - ErrorKind::TimedOut => println!("Request timeout"), // Windows - _ => println!("Request error: {:?}", e), - } - } - } -} \ No newline at end of file diff --git a/README.md b/README.md index 107157af0dfe1816102e4102ede17b61110ba84d..2f7fa8be0dd3a62b87131a8ae61a45e52bb840ce 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,16 @@ -# Embedded rust with CoAp -This project aims to make CoAP on ARM embedded systems coded with [Rust](https://www.rust-lang.org) a thing. +# Embedded rust with CoAP +This project aims to make [CoAP](https://tools.ietf.org/html/rfc7252) on ARM embedded systems coded with [Rust](https://www.rust-lang.org) a thing. This project is part of the course D7018E at [LuleƄ tekniska universitet](https://www.ltu.se) taught by [Per Lindgren](https://www.ltu.se/staff/p/pln-1.11258). ## Installation ## Crates used -- [coap](http://covertness.github.io/coap-rs/coap/index.html) \ No newline at end of file +- [coap](http://covertness.github.io/coap-rs/coap/index.html) +- [smoltcp](https://crates.io/crates/smoltcp) + + +## ESP8266 +As a WiFi bridge the ESP8266 is used and communicates with the CoAP server/client over USART using [SLIP](https://tools.ietf.org/html/rfc1055) +### Firmware +The firmware used for the esp8266 module is [esp-just-slip](https://github.com/krzychb/esp-just-slip) diff --git a/Server/Cargo.lock b/Server/Cargo.lock deleted file mode 100644 index a84a481e8dd3a379f0391e937380d382c1d1cfda..0000000000000000000000000000000000000000 --- a/Server/Cargo.lock +++ /dev/null @@ -1,358 +0,0 @@ -[[package]] -name = "D7018E_CoAp_server" -version = "0.1.0" -dependencies = [ - "coap 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bincode" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bytes" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cfg-if" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "coap" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bincode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "enum_primitive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libc" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "matches" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "mio" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "net2" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "nix" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-bigint" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-complex" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-iter" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-rational" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "num_cpus" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slab" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "threadpool" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "url" -version = "0.2.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "uuid" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum bincode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "951498c868b0683e1ba67afcdd6b1c3def08a713e66197aa17be8fad56cbaab5" -"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" -"checksum byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "29b2aa490a8f546381308d68fc79e6bd753cd3ad839f7a7172897f1feedfa175" -"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum coap 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "24c47dfbaf87a9a060aaa412b4af7852f512737f7bea3db50efcf035bb937e8f" -"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" -"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" -"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" -"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" -"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" -"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" -"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" -"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23" -"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c" -"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" -"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" -"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" -"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" -"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" -"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)" = "cbaa8377a162d88e7d15db0cf110c8523453edcbc5bc66d2b6fffccffa34a068" -"checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/Server/Cargo.toml b/Server/Cargo.toml deleted file mode 100644 index 3ce7582636973e4b231d173d24377d8a8c505978..0000000000000000000000000000000000000000 --- a/Server/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "xoap" -version = "0.1.0" -authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"] - -[dependencies] -coap = "0.5" \ No newline at end of file diff --git a/Server/src/main.rs b/Server/src/main.rs deleted file mode 100644 index 71be1b493d9135d2315003fbb679f5f147f56a97..0000000000000000000000000000000000000000 --- a/Server/src/main.rs +++ /dev/null @@ -1,48 +0,0 @@ -// CoAP Server -> Into the embedded system -// D7018E - Embedded rust -// Joakim Lundberg <joakim@joakimlundberg.com> - -// Externally used crates -extern crate coap; - -use std::io; -use coap::{CoAPServer, CoAPResponse, CoAPRequest, IsMessage}; - -fn request_handler(request: CoAPRequest) -> Option<CoAPResponse> { - let request_code = request.get_code(); - - match request_code.as_ref() { - "0.01" => { - println!("request by get"); - }, - "0.02" => { - println!("request by post"); - println!("request body: {}", String::from_utf8(request.message.payload).unwrap()); - }, - _ => { - println!("request by other method {}", request_code); - } - }; - - return match request.response { - Some(mut message) => { - message.set_payload(b"OK".to_vec()); - Some(message) - }, - _ => None - }; -} - -fn main() { - let addr = "127.0.0.1:5683"; - - let mut server = CoAPServer::new(addr).unwrap(); - server.handle(request_handler).unwrap(); - - println!("Server up on {}", addr); - println!("Press any key to stop..."); - - io::stdin().read_line(&mut String::new()).unwrap(); - - println!("Server shutdown"); -} \ No newline at end of file diff --git a/nucleo/app/Xargo.toml b/Xargo.toml similarity index 66% rename from nucleo/app/Xargo.toml rename to Xargo.toml index 89ad4cdcaeb6cce198c64fb0e03f570429243b42..8c5b2a9eeb915c85ebbed20619d678f2a9fe8674 100644 --- a/nucleo/app/Xargo.toml +++ b/Xargo.toml @@ -1,6 +1,7 @@ -[dependencies.core] -stage = 0 - -[dependencies.compiler_builtins] -features = ["mem"] -stage = 1 \ No newline at end of file +[dependencies.core] +stage = 0 + +[dependencies.compiler_builtins] +default-features = false +features = ["mem"] +stage = 1 diff --git a/nucleo/app/build.rs b/build.rs similarity index 96% rename from nucleo/app/build.rs rename to build.rs index 88f7fef81f872bd233dd7c6b13bfe04dccb5a276..34363d2dafe256086417aee9a6dae3148f3fe855 100644 --- a/nucleo/app/build.rs +++ b/build.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Write; use std::path::PathBuf; -fn main() { +pub fn main() { // Put the linker script somewhere the linker can find it let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); File::create(out.join("memory.x")) diff --git a/nucleo/app/memory.x b/memory.x similarity index 87% rename from nucleo/app/memory.x rename to memory.x index 6eced1e5e6f8f5a91bc4d8805040b3db5e9a4c4e..8462e02743c730756c84bbc9c0d8a54abb30c051 100644 --- a/nucleo/app/memory.x +++ b/memory.x @@ -1,22 +1,20 @@ -MEMORY -{ - /* NOTE K = KiBi = 1024 bytes */ - /* TODO Adjust these memory regions to match your device memory layout */ - /* Nucleo */ - FLASH : ORIGIN = 0x08000000, LENGTH = 512K - RAM : ORIGIN = 0x20000000, LENGTH = 96K - -} - -/* This is where the call stack will be allocated. */ -/* The stack is of the full descending type. */ -/* You may want to use this variable to locate the call stack and static - variables in different memory regions. Below is shown the default value */ -/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */ - -/* You can use this symbol to customize the location of the .text section */ -/* If omitted the .text section will be placed right after the .vector_table - section */ -/* This is required only on microcontrollers that store some configuration right - after the vector table */ -/* _stext = ORIGIN(FLASH) + 0x400; */ +MEMORY +{ + /* NOTE K = KiBi = 1024 bytes */ + /* TODO Adjust these memory regions to match your device memory layout */ + FLASH : ORIGIN = 0x08000000, LENGTH = 512K + RAM : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* You may want to use this variable to locate the call stack and static + variables in different memory regions. Below is shown the default value */ +/* _stack_start = ORIGIN(RAM) + LENGTH(RAM); */ + +/* You can use this symbol to customize the location of the .text section */ +/* If omitted the .text section will be placed right after the .vector_table + section */ +/* This is required only on microcontrollers that store some configuration right + after the vector table */ +/* _stext = ORIGIN(FLASH) + 0x400; */ \ No newline at end of file diff --git a/nucleo/Cargo.toml b/nucleo/Cargo.toml deleted file mode 100644 index bc7a8bf8ca378e06670989add9607685c9a4618c..0000000000000000000000000000000000000000 --- a/nucleo/Cargo.toml +++ /dev/null @@ -1,4 +0,0 @@ -[package] -name = "D7018E_Embedded_Nucleo" -version = "0.1.0" -authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"] diff --git a/nucleo/app/.cargo/config b/nucleo/app/.cargo/config deleted file mode 100644 index b0bb50be8496ec094ac0a3111c0b22dd66d2c2be..0000000000000000000000000000000000000000 --- a/nucleo/app/.cargo/config +++ /dev/null @@ -1,33 +0,0 @@ -[target.thumbv6m-none-eabi] -runner = 'arm-none-eabi-gdb' -rustflags = [ - "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", -] - -[target.thumbv7m-none-eabi] -runner = 'arm-none-eabi-gdb' -rustflags = [ - "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", -] - -[target.thumbv7em-none-eabi] -runner = 'arm-none-eabi-gdb' -rustflags = [ - "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", -] - -[target.thumbv7em-none-eabihf] -runner = 'arm-none-eabi-gdb' -rustflags = [ - "-C", "link-arg=-Tlink.x", - "-C", "linker=arm-none-eabi-ld", - "-Z", "linker-flavor=ld", -] -[build] -target = "thumbv7em-none-eabihf" diff --git a/nucleo/app/.gdbinit b/nucleo/app/.gdbinit deleted file mode 100644 index 098ff6f90cac5691f155e0dfba1ce4e87be3f7f3..0000000000000000000000000000000000000000 --- a/nucleo/app/.gdbinit +++ /dev/null @@ -1,18 +0,0 @@ -target remote :3333 - -monitor arm semihosting enable - -# # send captured ITM to the file itm.fifo -# # (the microcontroller SWO pin must be connected to the programmer SWO pin) -# # 8000000 must match the core clock frequency -# monitor tpiu config internal itm.fifo uart off 8000000 - -# # OR: make the microcontroller SWO pin output compatible with UART (8N1) -# # 2000000 is the frequency of the SWO pin -# monitor tpiu config external uart off 8000000 2000000 - -# # enable ITM port 0 -# monitor itm port 0 on - -load -step diff --git a/nucleo/app/.gitignore b/nucleo/app/.gitignore deleted file mode 100644 index 6cda3bd5bb2701b20eb0c9c4913206aa9cff99d4..0000000000000000000000000000000000000000 --- a/nucleo/app/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -**/*.rs.bk -.gdb_history -Cargo.lock -target/ diff --git a/nucleo/app/CHANGELOG.md b/nucleo/app/CHANGELOG.md deleted file mode 100644 index 2392beb8711eec22f165e293820f421c5a3e5435..0000000000000000000000000000000000000000 --- a/nucleo/app/CHANGELOG.md +++ /dev/null @@ -1,108 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] - -## [v0.2.1] - 2017-07-14 - -### Added - -- Troubleshooting documentation: how to fix the error of overwriting the - `.cargo/config` file when you meant to append text to it. - -### Changed - -- Xargo.toml: Changed the source of the `compiler-builtins` crate from git to - the `rust-src` component. - -- Expanded the `device` example to do some I/O. - -## [v0.2.0] - 2017-07-07 - -### Changed - -- [breaking-change] Bumped the cortex-m and cortex-m-rt versions to v0.3.0. - -## [v0.1.8] - 2017-05-30 - -### Changed - -- Bumped the cortex-m-rt dependency to v0.2.3, and documented the `_stext` - symbol (see memory.x). - -## [v0.1.7] - 2017-05-27 - -### Added - -- Documentation and an example about how to use the heap and a dynamic memory - allocator. - -### Changed - -- Bumped the `cortex-m-rt` dependency to v0.2.2 -- Bumped the `cortex-m` dependency to v0.2.7 - -## [v0.1.6] - 2017-05-26 - -### Added - -- Set the default runner in .cargo/config to `arm-none-eabi-gdb`. Now `xargo - run` will build the program and start a debug session. - -## [v0.1.5] - 2017-05-16 - -### Added - -- A warning about using CARGO_INCREMENTAL to the how to use and the - troubleshooting sections. - -## [v0.1.4] - 2017-05-13 - -### Added - -- A dependencies section to the documentation - -### Changed - -- Extend troubleshooting section - -## [v0.1.3] - 2017-05-13 - -### Added - -- A troubleshooting section to the documentation - -### Changed - -- Bumped the cortex-m crate version to v0.2.6 - -## [v0.1.2] - 2017-05-07 - -### Fixed - -- .gdbinit: jump to reset handler after loading the program. - -## [v0.1.1] - 2017-04-27 - -### Changed - -- Bumped the version of the `cortex-m-rt` dependency to v0.2.0. NOTE that the - instantiation steps have slightly changed, the `memory.x` file changed, - because of this. - -## v0.1.0 - 2017-04-25 - -- Initial release - -[Unreleased]: https://github.com/japaric/cortex-m-quickstart/compare/v0.2.0...HEAD -[v0.2.0]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.8...v0.2.0 -[v0.1.8]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.7...v0.1.8 -[v0.1.7]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.6...v0.1.7 -[v0.1.6]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.5...v0.1.6 -[v0.1.5]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.4...v0.1.5 -[v0.1.4]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.3...v0.1.4 -[v0.1.3]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.2...v0.1.3 -[v0.1.2]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.1...v0.1.2 -[v0.1.1]: https://github.com/japaric/cortex-m-quickstart/compare/v0.1.0...v0.1.1 diff --git a/nucleo/app/Cargo.toml b/nucleo/app/Cargo.toml deleted file mode 100644 index 0fd4818e4cecc5bc1bab95237e6d2f47bd6167a0..0000000000000000000000000000000000000000 --- a/nucleo/app/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "app" -version = "0.1.0" -authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"] -description = "A template for building applications for ARM Cortex-M microcontrollers" -keywords = ["arm", "cortex-m", "template"] -categories = ["embedded", "no-std"] -license = "MIT OR Apache-2.0" -[profile.release] -lto = true -debug = true -[dependencies.cortex-m-semihosting] -version = "0.2.0" - -[dependencies.cortex-m-rt] -version = "0.3.3" -features = ["abort-on-panic"] - -[dependencies.cortex-m] -version = "0.3.0" diff --git a/nucleo/app/Cargo.toml.orig b/nucleo/app/Cargo.toml.orig deleted file mode 100644 index 9c7018e1c3728d4350b3b04521b3cb62893b3439..0000000000000000000000000000000000000000 --- a/nucleo/app/Cargo.toml.orig +++ /dev/null @@ -1,33 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "cortex-m-quickstart" -version = "0.2.1" -authors = ["Jorge Aparicio <jorge@japaric.io>"] -description = "A template for building applications for ARM Cortex-M microcontrollers" -keywords = ["arm", "cortex-m", "template"] -categories = ["embedded", "no-std"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/japaric/cortex-m-quickstart" -[profile.release] -lto = true -debug = true -[dependencies.cortex-m-semihosting] -version = "0.2.0" - -[dependencies.cortex-m-rt] -version = "0.3.3" -features = ["abort-on-panic"] - -[dependencies.cortex-m] -version = "0.3.0" diff --git a/nucleo/app/LICENSE-APACHE b/nucleo/app/LICENSE-APACHE deleted file mode 100644 index 16fe87b06e802f094b3fbb0894b137bca2b16ef1..0000000000000000000000000000000000000000 --- a/nucleo/app/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/nucleo/app/LICENSE-MIT b/nucleo/app/LICENSE-MIT deleted file mode 100644 index 65a232326b2f0b4cfae3d1f2418cc6402e8766a5..0000000000000000000000000000000000000000 --- a/nucleo/app/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2017 {{toml-escape author}} - -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. diff --git a/nucleo/app/README.md b/nucleo/app/README.md deleted file mode 100644 index cb99f10f14a0aa90b7360988d7f5e89586d4ce11..0000000000000000000000000000000000000000 --- a/nucleo/app/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# `cortex-m-quickstart` - -> A template for building applications for ARM Cortex-M microcontrollers - -# [Documentation](https://docs.rs/cortex-m-quickstart) - -# License - -Licensed under either of - -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - -- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) - -at your option. - -## Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. diff --git a/nucleo/app/examples/allocator.rs b/nucleo/app/examples/allocator.rs deleted file mode 100644 index 7f61af14dcc56667c1b721615d00ea67082a7c4a..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/allocator.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! How to use the heap and a dynamic memory allocator -//! -//! To compile this example you'll need to build the collections crate as part -//! of the Xargo sysroot. To do that change the Xargo.toml file to look like -//! this: -//! -//! ``` text -//! [dependencies.core] -//! stage = 0 -//! -//! [dependencies.collections] # NEW -//! stage = 0 -//! -//! [dependencies.compiler_builtins] -//! stage = 1 -//! ``` -//! -//! This example depends on the alloc-cortex-m crate so you'll have to add it -//! to your Cargo.toml: -//! -//! ``` text -//! # or edit the Cargo.toml file manually -//! $ cargo add alloc-cortex-m -//! ``` -//! -//! --- - -#[allow(deprecated)] -#![feature(collections)] -#![feature(used)] -#![no_std] - -// This is the allocator crate; you can use a different one -extern crate alloc_cortex_m; -#[macro_use] -extern crate collections; -extern crate cortex_m; -extern crate cortex_m_rt; -extern crate cortex_m_semihosting; - -use core::fmt::Write; - -use cortex_m::asm; -use cortex_m_semihosting::hio; - -fn main() { - // Initialize the allocator - unsafe { - extern "C" { - // Start of the heap - static mut _sheap: usize; - } - - // Size of the heap in words (1 word = 4 bytes) - // NOTE The bigger the heap the greater the chance to run into a stack - // overflow (collision between the stack and the heap) - const SIZE: isize = 256; - - // End of the heap - let _eheap = (&mut _sheap as *mut _).offset(SIZE); - - alloc_cortex_m::init(&mut _sheap, _eheap); - } - - // Growable array allocated on the heap - let xs = vec![0, 1, 2]; - - let mut stdout = hio::hstdout().unwrap(); - writeln!(stdout, "{:?}", xs).unwrap(); -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/app/examples/crash.rs b/nucleo/app/examples/crash.rs deleted file mode 100644 index f0063234b6dcc62ed32df12f9a62e09634440efc..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/crash.rs +++ /dev/null @@ -1,85 +0,0 @@ -//! Debugging a crash (exception) -//! -//! The `cortex-m-rt` crate provides functionality for this through a default -//! exception handler. When an exception is hit, the default handler will -//! trigger a breakpoint and in this debugging context the stacked registers -//! are accessible. -//! -//! In you run the example below, you'll be able to inspect the state of your -//! program under the debugger using these commands: -//! -//! ``` text -//! (gdb) # Exception frame = program state during the crash -//! (gdb) print/x *ef -//! $1 = cortex_m::exception::ExceptionFrame { -//! r0 = 0x2fffffff, -//! r1 = 0x2fffffff, -//! r2 = 0x0, -//! r3 = 0x0, -//! r12 = 0x0, -//! lr = 0x8000481, -//! pc = 0x8000460, -//! xpsr = 0x61000000, -//! } -//! -//! (gdb) # Where did we come from? -//! (gdb) backtrace -//! #0 cortex_m_rt::default_handler (ef=0x20004f54) at (..) -//! #1 <signal handler called> -//! #2 0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..) -//! #3 0x08000480 in crash::main () at examples/crash.rs:68 -//! -//! (gdb) # Nail down the location of the crash -//! (gdb) disassemble/m ef.pc -//! Dump of assembler code for function core::ptr::read_volatile<u32>: -//! 408 pub unsafe fn read_volatile<T>(src: *const T) -> T { -//! 0x08000454 <+0>: sub sp, #20 -//! 0x08000456 <+2>: mov r1, r0 -//! 0x08000458 <+4>: str r0, [sp, #8] -//! 0x0800045a <+6>: ldr r0, [sp, #8] -//! 0x0800045c <+8>: str r0, [sp, #12] -//! -//! 409 intrinsics::volatile_load(src) -//! 0x0800045e <+10>: ldr r0, [sp, #12] -//! 0x08000460 <+12>: ldr r0, [r0, #0] -//! 0x08000462 <+14>: str r0, [sp, #16] -//! 0x08000464 <+16>: ldr r0, [sp, #16] -//! 0x08000466 <+18>: str r1, [sp, #4] -//! 0x08000468 <+20>: str r0, [sp, #0] -//! 0x0800046a <+22>: b.n 0x800046c <core::ptr::read_volatile<u32>+24> -//! -//! 410 } -//! 0x0800046c <+24>: ldr r0, [sp, #0] -//! 0x0800046e <+26>: add sp, #20 -//! 0x08000470 <+28>: bx lr -//! -//! End of assembler dump. -//! ``` -//! -//! --- - -#![feature(used)] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_rt; - -use core::ptr; - -use cortex_m::asm; - -fn main() { - // Read an invalid memory address - unsafe { - ptr::read_volatile(0x2FFF_FFFF as *const u32); - } -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/app/examples/device.rs b/nucleo/app/examples/device.rs deleted file mode 100644 index 0b28e19bde27a2c40994ac39f136004625d558fa..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/device.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! Using a device crate -//! -//! Crates generated using [`svd2rust`] are referred to as device crates. These -//! crates provides an API to access the peripherals of a device. When you -//! depend on one of these crates and the "rt" feature is enabled you don't need -//! link to the cortex-m-rt crate. -//! -//! [`svd2rust`]: https://crates.io/crates/svd2rust -//! -//! Device crates also provide an `interrupt!` macro to register interrupt -//! handlers. -//! -//! This example depends on the [`stm32f103xx`] crate so you'll have to add it -//! to your Cargo.toml. -//! -//! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx -//! -//! ``` -//! $ edit Cargo.toml && cat $_ -//! [dependencies.stm32f103xx] -//! features = ["rt"] -//! version = "0.7.0" -//! ``` -//! -//! --- - -#![deny(warnings)] -#![feature(const_fn)] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_semihosting; -#[macro_use(exception, interrupt)] -extern crate stm32f103xx; - -use core::cell::RefCell; -use core::fmt::Write; - -use cortex_m::interrupt::{self, Mutex}; -use cortex_m::peripheral::SystClkSource; -use cortex_m_semihosting::hio::{self, HStdout}; -use stm32f103xx::Interrupt; - -static HSTDOUT: Mutex<RefCell<Option<HStdout>>> = - Mutex::new(RefCell::new(None)); - -fn main() { - interrupt::free(|cs| { - let hstdout = HSTDOUT.borrow(cs); - if let Ok(fd) = hio::hstdout() { - *hstdout.borrow_mut() = Some(fd); - } - - let nvic = stm32f103xx::NVIC.borrow(cs); - nvic.enable(Interrupt::TIM2); - - let syst = stm32f103xx::SYST.borrow(cs); - syst.set_clock_source(SystClkSource::Core); - syst.set_reload(8_000_000); // 1s - syst.enable_counter(); - syst.enable_interrupt(); - }); -} - -exception!(SYS_TICK, tick); - -fn tick() { - interrupt::free(|cs| { - let hstdout = HSTDOUT.borrow(cs); - if let Some(hstdout) = hstdout.borrow_mut().as_mut() { - writeln!(*hstdout, "Tick").ok(); - } - - let nvic = stm32f103xx::NVIC.borrow(cs); - - nvic.set_pending(Interrupt::TIM2); - }); -} - -interrupt!(TIM2, tock, locals: { - tocks: u32 = 0; -}); - -fn tock(l: &mut TIM2::Locals) { - l.tocks += 1; - - interrupt::free(|cs| { - let hstdout = HSTDOUT.borrow(cs); - if let Some(hstdout) = hstdout.borrow_mut().as_mut() { - writeln!(*hstdout, "Tock ({})", l.tocks).ok(); - } - }); -} diff --git a/nucleo/app/examples/hello.rs b/nucleo/app/examples/hello.rs deleted file mode 100644 index a3f0eb4506e1f12e37abc632b4771c571a1761de..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/hello.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Prints "Hello, world!" on the OpenOCD console using semihosting -//! -//! --- - -#![feature(used)] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_rt; -extern crate cortex_m_semihosting; - -use core::fmt::Write; - -use cortex_m::asm; -use cortex_m_semihosting::hio; - -fn main() { - let mut stdout = hio::hstdout().unwrap(); - writeln!(stdout, "Hello, world!").unwrap(); -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/app/examples/itm.rs b/nucleo/app/examples/itm.rs deleted file mode 100644 index 4159c43c31bef75251ee5ea9ab236191ff4a6324..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/itm.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Sends "Hello, world!" through the ITM port 0 -//! -//! **IMPORTANT** Not all Cortex-M chips support ITM. You'll have to connect the -//! microcontroller's SWO pin to the SWD interface. Note that some development -//! boards don't provide this option. -//! -//! ITM is much faster than semihosting. Like 4 orders of magnitude or so. -//! -//! You'll need [`itmdump`] to receive the message on the host plus you'll need -//! to uncomment the `monitor` commands in the `.gdbinit` file. -//! -//! [`itmdump`]: https://docs.rs/itm/0.1.1/itm/ -//! -//! --- - -#![feature(used)] -#![no_std] - -#[macro_use] -extern crate cortex_m; -extern crate cortex_m_rt; - -use cortex_m::{asm, interrupt, peripheral}; - -fn main() { - interrupt::free(|cs| { - let itm = peripheral::ITM.borrow(&cs); - - iprintln!(&itm.stim[0], "Hello, world!"); - }); -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/app/examples/override-exception-handler.rs b/nucleo/app/examples/override-exception-handler.rs deleted file mode 100644 index 8785a2c62eccbcac5f381f011c6571d2001955fc..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/override-exception-handler.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! Overriding an exception handler -//! -//! You can override an exception handler using the [`exception!`][1] macro. -//! -//! [1]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.exception.html -//! -//! The default exception handler can be overridden using the -//! [`default_handler!`][2] macro -//! -//! [2]: https://docs.rs/cortex-m-rt/0.3.2/cortex_m_rt/macro.default_handler.html -//! -//! --- - -#![feature(used)] -#![no_std] - -extern crate cortex_m; -#[macro_use(exception)] -extern crate cortex_m_rt; - -use core::ptr; - -use cortex_m::asm; - -fn main() { - unsafe { - // Invalid memory access - ptr::read_volatile(0x2FFF_FFFF as *const u32); - } -} - -exception!(HARD_FAULT, handler); - -fn handler() { - // You'll hit this breakpoint rather than the one in cortex-m-rt - asm::bkpt() -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[allow(dead_code)] -#[used] -#[link_section = ".vector_table.interrupts"] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/app/examples/panic.rs b/nucleo/app/examples/panic.rs deleted file mode 100644 index a85f42579a46a30184fd5a5f875396204369313b..0000000000000000000000000000000000000000 --- a/nucleo/app/examples/panic.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Defining the panic handler -//! -//! The panic handler can be defined through the `panic_fmt` [language item][1]. -//! Make sure that the "abort-on-panic" feature of the cortex-m-rt crate is -//! disabled to avoid redefining the language item. -//! -//! [1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html -//! -//! --- - -#![feature(core_intrinsics)] -#![feature(lang_items)] -#![feature(used)] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_rt; -extern crate cortex_m_semihosting; - -use core::fmt::Write; -use core::intrinsics; - -use cortex_m::asm; -use cortex_m_semihosting::hio; - -fn main() { - panic!("Oops"); -} - -#[lang = "panic_fmt"] -#[no_mangle] -unsafe extern "C" fn rust_begin_unwind( - args: core::fmt::Arguments, - file: &'static str, - line: u32, - col: u32, -) -> ! { - if let Ok(mut stdout) = hio::hstdout() { - write!(stdout, "panicked at '") - .and_then(|_| { - stdout - .write_fmt(args) - .and_then(|_| writeln!(stdout, "', {}:{}", file, line)) - }) - .ok(); - } - - intrinsics::abort() -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/app/gen-examples.sh b/nucleo/app/gen-examples.sh deleted file mode 100644 index 660607b3227fb95ab543aa8d6275ff5c1cd921ae..0000000000000000000000000000000000000000 --- a/nucleo/app/gen-examples.sh +++ /dev/null @@ -1,55 +0,0 @@ -# Converts the examples in the `examples` directory into documentation in the -# `examples` module (`src/examples/*.rs`) - -set -ex - -main() { - local examples=( - hello - itm - panic - crash - override-exception-handler - device - allocator - ) - - rm -rf src/examples - - mkdir src/examples - - cat >src/examples/mod.rs <<'EOF' -//! Examples -// Auto-generated. Do not modify. -EOF - - local i=0 out= - for ex in ${examples[@]}; do - name=_${i}_${ex//-/_} - out=src/examples/${name}.rs - - echo "pub mod $name;" >> src/examples/mod.rs - - grep '//!' examples/$ex.rs > $out - echo '//!' >> $out - echo '//! ```' >> $out - grep -v '//!' examples/$ex.rs | ( - IFS='' - - while read line; do - echo "//! $line" >> $out; - done - ) - echo '//! ```' >> $out - echo '// Auto-generated. Do not modify.' >> $out - - - chmod -x $out - - i=$(( i + 1 )) - done - - chmod -x src/examples/mod.rs -} - -main diff --git a/nucleo/app/src/main.rs b/nucleo/app/src/main.rs deleted file mode 100644 index 5a051e2d75a84f23709e568353f66f162755556e..0000000000000000000000000000000000000000 --- a/nucleo/app/src/main.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Nucleo -// D7018E - Embedded rust -// Joakim Lundberg <joakim@joakimlundberg.com> - -#![feature(used)] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_rt; -extern crate cortex_m_semihosting; - -use core::fmt::Write; - -use cortex_m::asm; -use cortex_m_semihosting::hio; - -fn main() { - // get a handle to the *host* standard output - let mut stdout = hio::hstdout().unwrap(); - - for n in 1..101 { - if n % 15 == 0 { - writeln!(stdout,"fizzbuzz"); - } else if n % 3 == 0 { - writeln!(stdout,"fizz"); - } else if n % 5 == 0 { - writeln!(stdout,"buzz"); - } else { - writeln!(stdout,"{}", n); - } - } - - // write "Hello, world!" to it - writeln!(stdout, "Hello, world!").unwrap(); -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/nucleo/src/main.rs b/nucleo/src/main.rs deleted file mode 100644 index 12069c549a3de3a95d3866a6096be696f5ad47dd..0000000000000000000000000000000000000000 --- a/nucleo/src/main.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Nucleo -// D7018E - Embedded rust -// Joakim Lundberg <joakim@joakimlundberg.com> - -#![feature(used)] -#![no_std] - -extern crate cortex_m; -extern crate cortex_m_rt; -extern crate cortex_m_semihosting; - -use core::fmt::Write; - -use cortex_m::asm; -use cortex_m_semihosting::hio; - -fn main() { - // get a handle to the *host* standard output - let mut stdout = hio::hstdout().unwrap(); - - for n in 1..101 { - if n % 15 == 0 { - writeln!(stdout,"fizzbuzz"); - } else if n % 3 == 0 { - writeln!(stdout,"fizz"); - } else if n % 5 == 0 { - writeln!(stdout,"buzz"); - } else { - writeln!(stdout,"{}", n); - } - } - - // write "Hello, world!" to it - writeln!(stdout, "Hello, world!").unwrap(); -} - -// As we are not using interrupts, we just register a dummy catch all handler -#[link_section = ".vector_table.interrupts"] -#[used] -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; - -extern "C" fn default_handler() { - asm::bkpt(); -} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..1b3acf480694e15d50c8778a812b9c2fca9050bc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,178 @@ +//! Prints "Hello" and then "World" in the OpenOCD console +#![deny(unsafe_code)] +#![deny(warnings)] +#![feature(const_fn)] +#![feature(proc_macro)] +#![feature(lang_items)] +#![no_std] + +extern crate cortex_m_rtfm as rtfm; +//extern crate cortex_m_semihosting as semihosting; +#[macro_use] +extern crate f4; +extern crate heapless; +extern crate xoap; + +use core::fmt::Write; +use core::ops::Deref; +use f4::Serial; +use f4::U8Writer; +use f4::prelude::*; +use f4::dma::{Buffer, Dma1Stream5, Dma1Stream6}; +use f4::time::Hertz; +use f4::clock; +use heapless::Vec; +use rtfm::{app, Threshold}; +//use semihosting::hio::{self, HStdout}; + +// Max length of a command to be parsed. +const MAX_CMD_LEN: usize = 10; +// Max length of an output string that can be sent. +const MAX_TX_LEN: usize = 100; +// Max length of input buffer. Since we are parsing for commands, we need to check each received character. +const MAX_RX_LEN: usize = 100; + +const BAUD_RATE: Hertz = Hertz(115_200); + +enum CmdType { + Greeting, + Unknown, + None, +} + +app! { + device: f4::stm32f40x, + + resources: { + static CMD_BUFFER: Vec<u8, [u8; MAX_CMD_LEN]> = Vec::new(); + static RX_BUFFER: Buffer<[u8; MAX_RX_LEN], Dma1Stream5> = Buffer::new([0; MAX_RX_LEN]); + static TX_BUFFER: Buffer<[u8; MAX_TX_LEN], Dma1Stream6> = Buffer::new([0; MAX_TX_LEN]); + static CNT: u8 = 0; + }, + + tasks: { + DMA1_STREAM5: { + path: rx_done, + priority: 1, + resources: [CMD_BUFFER, RX_BUFFER, TX_BUFFER, DMA1, USART2, CNT], + }, + DMA1_STREAM6: { + path: tx_done, + priority: 2, + resources: [TX_BUFFER, DMA1], + }, + }, +} + +// Interrupt for serial receive DMA +fn rx_done(t: &mut Threshold, mut r: DMA1_STREAM5::Resources) { + use rtfm::Resource; + + let mut byte: u8 = 0; + let mut cmd_type: CmdType = CmdType::None; + + r.RX_BUFFER.claim(t, |rx, t| { + // We need to unlock the DMA to use it again in the future + r.DMA1.claim(t, |dma, _| rx.release(dma).unwrap()); + // Read the single character in the input buffer + byte = rx.deref().borrow()[0]; + // Echo the character back to the sender. + // We do not need to use DMA to transmit. + r.USART2.claim(t, |usart, t| { + let serial = Serial(&**usart); + if serial.write(byte).is_err() { + rtfm::bkpt(); + } + if byte == b'\r' { + // If we got carrige return, send new line as well + while serial.write(b'\n').is_err() { + // Since we just transmitted carrige return, + // we need to wait until tx line is free + } + } + // Get ready to receive again + r.DMA1 + .claim(t, |dma, _| serial.read_exact(dma, rx).unwrap()); + }); + }); + // Parse the user input + r.CMD_BUFFER.claim_mut(t, |cmd, _| { + if byte == b'\r' { + // End of command + cmd_type = match &***cmd { + b"hi" | b"Hi" => CmdType::Greeting, + _ => { + if cmd.len() == 0 { + CmdType::None // Empty string + } else { + CmdType::Unknown // Unknown string + } + } + }; + cmd.clear(); + } else { + // Append character to buffer + if cmd.push(byte).is_err() { + // Error: command buffer is full + cmd.clear(); + } + } + }); + // If user wrote 'hi' and pressed enter, respond appropriately + match cmd_type { + CmdType::Greeting => { + // Increment 'hi' counter + **r.CNT = (**r.CNT).wrapping_add(1); + let cnt: u8 = **r.CNT; + // Print a response using DMA + uprint!(t, r.USART2, r.DMA1, r.TX_BUFFER, "Hi counter {}!\r\n", cnt); + } + CmdType::Unknown => { + // Unknown command + uprint!(t, r.USART2, r.DMA1, r.TX_BUFFER, "That's no greeting.\r\n"); + } + _ => {} + } +} + +// Interrupt for serial transmit DMA +fn tx_done(t: &mut Threshold, r: DMA1_STREAM6::Resources) { + use rtfm::Resource; + // We need to unlock the DMA to use it again in the future + r.TX_BUFFER.claim(t, |tx, t| { + r.DMA1.claim(t, |dma, _| tx.release(dma).unwrap()); + }); + // Clear the transmit buffer so we do not retransmit old stuff + r.TX_BUFFER.claim_mut(t, |tx, _| { + let array = &**tx.deref(); + array.borrow_mut()[..MAX_TX_LEN].clone_from_slice(&[0; MAX_TX_LEN]); + }); +} + +fn init(_p: init::Peripherals, r: init::Resources) { + // Set clock to higher than default in order to test that it works + clock::set_84_mhz(&_p.RCC, &_p.FLASH); + + // Start the serial port + let serial = Serial(_p.USART2); + serial.init(BAUD_RATE.invert(), Some(_p.DMA1), _p.GPIOA, _p.RCC); + + // FIXME: We cannot use the uprint macro in the init since it needs Resources + // and Threshold... + // Send a welcome message by borrowing a slice of the transmit buffer and + // writing a formatted string into it. + write!( + U8Writer::new(&mut r.TX_BUFFER.borrow_mut()[..MAX_TX_LEN]), + "Hello, world! Say hi to me!\r\n", + ).unwrap(); + serial.write_all(_p.DMA1, r.TX_BUFFER).unwrap(); + + // Listen to serial input on the receive DMA + serial.read_exact(_p.DMA1, r.RX_BUFFER).unwrap(); +} + +fn idle() -> ! { + loop { + rtfm::wfi(); + } +} diff --git a/utils/xoap/Cargo.toml b/utils/xoap/Cargo.toml deleted file mode 100644 index 0f309543470661643ad4a33b5cc7d436a71276bf..0000000000000000000000000000000000000000 --- a/utils/xoap/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "xoap" -version = "0.1.0" -description = "A CoAP library for bare-metal applications" -readme = "README.md" -documentation = "" -repository = "" -license = "MIT OR Apache-2.0" -authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"] -keywords = ["CoAP", "xoap"] - -[dependencies] -#alloc-cortex-m = {} - -[dependencies.smoltcp] -version = "0.4" -default-features = false -features = ["alloc"] - -[dependencies.nb] -git = "https://github.com/japaric/nb" - -[dependencies.cast] -default-features = false -version = "0.2.2" - - diff --git a/utils/xoap/README.md b/utils/xoap/README.md deleted file mode 100644 index 718e8916f4cde983c0094c007b2ad3dd3a2b4563..0000000000000000000000000000000000000000 --- a/utils/xoap/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# xoap -[](./LICENSE) - -A fast and stable [Constrained Application Protocol(CoAP)](https://tools.ietf.org/html/rfc7252) library implemented in Rust. - -built from -[Documentation](http://covertness.github.io/coap-rs/coap/index.html) - -## Installation - -First add this to your `Cargo.toml`: - -```toml -[dependencies] -xoap = "0.5" -``` - -Then, add this to your crate root: - -```rust -extern crate xoap; -``` - -## Example - -### Server: -```rust -extern crate xoap; - -use std::io; -use xoap::{CoAPServer, CoAPResponse, CoAPRequest}; - -fn request_handler(req: CoAPRequest) -> Option<CoAPResponse> { - println!("Receive request: {:?}", req); - - // Return the auto-generated response - req.response -} - -fn main() { - let addr = "127.0.0.1:5683"; - - let mut server = CoAPServer::new(addr).unwrap(); - server.handle(request_handler).unwrap(); - - println!("Server up on {}", addr); - println!("Press any key to stop..."); - io::stdin().read_line(&mut String::new()).unwrap(); - - println!("Server shutdown"); -} -``` - -### Client: -```rust -extern crate coap; - -use coap::{CoAPClient, CoAPResponse}; - -fn main() { - let url = "coap://127.0.0.1:5683/Rust"; - println!("Client request: {}", url); - - let response: CoAPResponse = CoAPClient::request(url).unwrap(); - println!("Server reply: {}", String::from_utf8(response.message.payload).unwrap()); -} -``` - -## Benchmark -```bash -$ cargo run --example server -$ cargo bench -``` diff --git a/utils/xoap/Xargo.toml b/utils/xoap/Xargo.toml deleted file mode 100644 index fbb39993bdfef586458643adc31d07f583c3f0f3..0000000000000000000000000000000000000000 --- a/utils/xoap/Xargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[dependencies.core] -stage = 0 - -[dependencies.alloc] -stage = 0 - -[dependencies.compiler_builtins] -stage = 1 - diff --git a/utils/xoap/src/lib.rs b/utils/xoap/src/lib.rs deleted file mode 100644 index 483e4a021ab6736321c7af3331f9279290695f5f..0000000000000000000000000000000000000000 --- a/utils/xoap/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Implementation of the [CoAP Protocol][spec]. -//! -//! This library provides both a client interface (`CoAPClient`) -//! and a server interface (`CoAPServer`). -//! -//! [spec]: https://tools.ietf.org/html/rfc7252 -//! - -#![deny(missing_docs)] -#![deny(warnings)] -#[allow(deprecated)] -#![feature(collections)] -#![no_std] -#![allow(unused_mut)] - -//#[macro_use] -extern crate smoltcp; -extern crate nb; -extern crate cast; -extern crate alloc_cortex_m; -#[macro_use] -extern crate collections; - diff --git a/utils/xoap/src/message/header.rs b/utils/xoap/src/message/header.rs deleted file mode 100644 index 94825615649339c8a7eea66768f1799928770bff..0000000000000000000000000000000000000000 --- a/utils/xoap/src/message/header.rs +++ /dev/null @@ -1,251 +0,0 @@ -#[derive(Default, Debug, RustcEncodable, RustcDecodable)] -pub struct HeaderRaw { - ver_type_tkl: u8, - code: u8, - message_id: u16, -} - -#[derive(Debug)] -pub struct Header { - ver_type_tkl: u8, - pub code: MessageClass, - message_id: u16, -} - -#[derive(Debug, PartialEq)] -pub enum MessageClass { - Empty, - RequestType(Requests), - ResponseType(Responses), - Reserved, -} - -#[derive(Debug, PartialEq)] -pub enum Requests { - Get, - Post, - Put, - Delete, -} - -#[derive(Debug, PartialEq)] -pub enum Responses { - // 200 Codes - Created, - Deleted, - Valid, - Changed, - Content, - - // 400 Codes - BadRequest, - Unauthorized, - BadOption, - Forbidden, - NotFound, - MethodNotAllowed, - NotAcceptable, - PreconditionFailed, - RequestEntityTooLarge, - UnsupportedContentFormat, - - // 500 Codes - InternalServerError, - NotImplemented, - BadGateway, - ServiceUnavailable, - GatewayTimeout, - ProxyingNotSupported, -} - -#[derive(PartialEq, Eq, Debug)] -pub enum MessageType { - Confirmable, - NonConfirmable, - Acknowledgement, - Reset, - Invalid, -} - -impl Header { - pub fn new() -> Header { - return Header::from_raw(&HeaderRaw::default()); - } - - pub fn from_raw(raw: &HeaderRaw) -> Header { - return Header { - ver_type_tkl: raw.ver_type_tkl, - code: code_to_class(&raw.code), - message_id: raw.message_id, - }; - } - - pub fn to_raw(&self) -> HeaderRaw { - return HeaderRaw { - ver_type_tkl: self.ver_type_tkl, - code: class_to_code(&self.code), - message_id: self.message_id, - }; - } - - #[inline] - pub fn set_version(&mut self, v: u8) { - let type_tkl = 0x3F & self.ver_type_tkl; - self.ver_type_tkl = v << 6 | type_tkl; - } - - #[inline] - pub fn get_version(&self) -> u8 { - return self.ver_type_tkl >> 6; - } - - #[inline] - pub fn set_type(&mut self, t: MessageType) { - let tn = match t { - MessageType::Confirmable => 0, - MessageType::NonConfirmable => 1, - MessageType::Acknowledgement => 2, - MessageType::Reset => 3, - _ => unreachable!(), - }; - - let ver_tkl = 0xCF & self.ver_type_tkl; - self.ver_type_tkl = tn << 4 | ver_tkl; - } - - #[inline] - pub fn get_type(&self) -> MessageType { - let tn = (0x30 & self.ver_type_tkl) >> 4; - match tn { - 0 => MessageType::Confirmable, - 1 => MessageType::NonConfirmable, - 2 => MessageType::Acknowledgement, - 3 => MessageType::Reset, - _ => MessageType::Invalid, - } - } - - #[inline] - pub fn set_token_length(&mut self, tkl: u8) { - assert_eq!(0xF0 & tkl, 0); - - let ver_type = 0xF0 & self.ver_type_tkl; - self.ver_type_tkl = tkl | ver_type; - } - - #[inline] - pub fn get_token_length(&self) -> u8 { - return 0x0F & self.ver_type_tkl; - } - - pub fn set_code(&mut self, code: &str) { - let code_vec: Vec<&str> = code.split('.').collect(); - assert_eq!(code_vec.len(), 2); - - let class_code = code_vec[0].parse::<u8>().unwrap(); - let detail_code = code_vec[1].parse::<u8>().unwrap(); - assert_eq!(0xF8 & class_code, 0); - assert_eq!(0xE0 & detail_code, 0); - - self.code = code_to_class(&(class_code << 5 | detail_code)); - } - - pub fn get_code(&self) -> String { - class_to_str(&self.code) - } - - #[inline] - pub fn set_message_id(&mut self, message_id: u16) { - self.message_id = message_id; - } - - #[inline] - pub fn get_message_id(&self) -> u16 { - return self.message_id; - } -} - -pub fn class_to_code(class: &MessageClass) -> u8 { - return match *class { - MessageClass::Empty => 0x00, - - MessageClass::RequestType(Requests::Get) => 0x01, - MessageClass::RequestType(Requests::Post) => 0x02, - MessageClass::RequestType(Requests::Put) => 0x03, - MessageClass::RequestType(Requests::Delete) => 0x04, - - MessageClass::ResponseType(Responses::Created) => 0x41, - MessageClass::ResponseType(Responses::Deleted) => 0x42, - MessageClass::ResponseType(Responses::Valid) => 0x43, - MessageClass::ResponseType(Responses::Changed) => 0x44, - MessageClass::ResponseType(Responses::Content) => 0x45, - - MessageClass::ResponseType(Responses::BadRequest) => 0x80, - MessageClass::ResponseType(Responses::Unauthorized) => 0x81, - MessageClass::ResponseType(Responses::BadOption) => 0x82, - MessageClass::ResponseType(Responses::Forbidden) => 0x83, - MessageClass::ResponseType(Responses::NotFound) => 0x84, - MessageClass::ResponseType(Responses::MethodNotAllowed) => 0x85, - MessageClass::ResponseType(Responses::NotAcceptable) => 0x86, - MessageClass::ResponseType(Responses::PreconditionFailed) => 0x8C, - MessageClass::ResponseType(Responses::RequestEntityTooLarge) => 0x8D, - MessageClass::ResponseType(Responses::UnsupportedContentFormat) => 0x8F, - - MessageClass::ResponseType(Responses::InternalServerError) => 0x90, - MessageClass::ResponseType(Responses::NotImplemented) => 0x91, - MessageClass::ResponseType(Responses::BadGateway) => 0x92, - MessageClass::ResponseType(Responses::ServiceUnavailable) => 0x93, - MessageClass::ResponseType(Responses::GatewayTimeout) => 0x94, - MessageClass::ResponseType(Responses::ProxyingNotSupported) => 0x95, - - _ => 0xFF, - } as u8; -} - -pub fn code_to_class(code: &u8) -> MessageClass { - match *code { - 0x00 => MessageClass::Empty, - - 0x01 => MessageClass::RequestType(Requests::Get), - 0x02 => MessageClass::RequestType(Requests::Post), - 0x03 => MessageClass::RequestType(Requests::Put), - 0x04 => MessageClass::RequestType(Requests::Delete), - - 0x41 => MessageClass::ResponseType(Responses::Created), - 0x42 => MessageClass::ResponseType(Responses::Deleted), - 0x43 => MessageClass::ResponseType(Responses::Valid), - 0x44 => MessageClass::ResponseType(Responses::Changed), - 0x45 => MessageClass::ResponseType(Responses::Content), - - 0x80 => MessageClass::ResponseType(Responses::BadRequest), - 0x81 => MessageClass::ResponseType(Responses::Unauthorized), - 0x82 => MessageClass::ResponseType(Responses::BadOption), - 0x83 => MessageClass::ResponseType(Responses::Forbidden), - 0x84 => MessageClass::ResponseType(Responses::NotFound), - 0x85 => MessageClass::ResponseType(Responses::MethodNotAllowed), - 0x86 => MessageClass::ResponseType(Responses::NotAcceptable), - 0x8C => MessageClass::ResponseType(Responses::PreconditionFailed), - 0x8D => MessageClass::ResponseType(Responses::RequestEntityTooLarge), - 0x8F => MessageClass::ResponseType(Responses::UnsupportedContentFormat), - - 0x90 => MessageClass::ResponseType(Responses::InternalServerError), - 0x91 => MessageClass::ResponseType(Responses::NotImplemented), - 0x92 => MessageClass::ResponseType(Responses::BadGateway), - 0x93 => MessageClass::ResponseType(Responses::ServiceUnavailable), - 0x94 => MessageClass::ResponseType(Responses::GatewayTimeout), - 0x95 => MessageClass::ResponseType(Responses::ProxyingNotSupported), - - _ => MessageClass::Reserved, - } -} - -pub fn code_to_str(code: &u8) -> String { - let class_code = (0xE0 & code) >> 5; - let detail_code = 0x1F & code; - - return format!("{}.{:02}", class_code, detail_code); -} - -pub fn class_to_str(class: &MessageClass) -> String { - return code_to_str(&class_to_code(class)); -} diff --git a/utils/xoap/src/message/packet.rs b/utils/xoap/src/message/packet.rs deleted file mode 100644 index 9a25fbe012ec5f40a677554d20dd08fc4ae27b30..0000000000000000000000000000000000000000 --- a/utils/xoap/src/message/packet.rs +++ /dev/null @@ -1,608 +0,0 @@ -//use bincode; -use alloc::BTreeMap; -use alloc::LinkedList; - -//use num::FromPrimitive; - -use message::header; - -macro_rules! u8_to_unsigned_be { - ($src:ident, $start:expr, $end:expr, $t:ty) => ({ - (0 .. $end - $start + 1).rev().fold(0, |acc, i| acc | $src[$start+i] as $t << i * 8) - }) -} - -#[derive(PartialEq, Eq, Debug)] -pub enum CoAPOption { - IfMatch, - UriHost, - ETag, - IfNoneMatch, - Observe, - UriPort, - LocationPath, - UriPath, - ContentFormat, - MaxAge, - UriQuery, - Accept, - LocationQuery, - Block2, - Block1, - ProxyUri, - ProxyScheme, - Size1, -} - -enum_from_primitive! { -#[derive(PartialEq, Eq, Debug)] -pub enum ContentFormat { - TextPlain = 0, - ApplicationLinkFormat = 40, - ApplicationXML = 41, - ApplicationOctetStream = 42, - ApplicationEXI = 47, - ApplicationJSON = 50, -} -} - -#[derive(Debug)] -pub enum PackageError { - InvalidHeader, - InvalidPacketLength, -} - -#[derive(Debug)] -pub enum ParseError { - InvalidHeader, - InvalidTokenLength, - InvalidOptionDelta, - InvalidOptionLength, -} - -#[derive(Debug)] -pub struct Packet { - pub header: header::Header, - token: Vec<u8>, - options: BTreeMap<usize, LinkedList<Vec<u8>>>, - pub payload: Vec<u8>, -} - -impl Packet { - pub fn new() -> Packet { - Packet { - header: header::Header::new(), - token: Vec::new(), - options: BTreeMap::new(), - payload: Vec::new(), - } - } - - pub fn set_token(&mut self, token: Vec<u8>) { - self.header.set_token_length(token.len() as u8); - self.token = token; - } - - pub fn get_token(&self) -> &Vec<u8> { - return &self.token; - } - - pub fn set_option(&mut self, tp: CoAPOption, value: LinkedList<Vec<u8>>) { - let num = Self::get_option_number(tp); - self.options.insert(num, value); - } - - pub fn set_content_format(&mut self, cf: ContentFormat) { - let content_format = cf as u16; - let msb = (content_format >> 8) as u8; - let lsb = (content_format & 0xFF) as u8; - - let content_format: Vec<u8> = vec![msb, lsb]; - self.add_option(CoAPOption::ContentFormat, content_format); - } - - pub fn set_payload(&mut self, payload: Vec<u8>) { - self.payload = payload; - } - - pub fn add_option(&mut self, tp: CoAPOption, value: Vec<u8>) { - let num = Self::get_option_number(tp); - match self.options.get_mut(&num) { - Some(list) => { - list.push_back(value); - return; - } - None => (), - }; - - let mut list = LinkedList::new(); - list.push_back(value); - self.options.insert(num, list); - } - - pub fn get_option(&self, tp: CoAPOption) -> Option<LinkedList<Vec<u8>>> { - let num = Self::get_option_number(tp); - match self.options.get(&num) { - Some(options) => Some(options.clone()), - None => None, - } - } - - pub fn get_content_format(&self) -> Option<ContentFormat> { - if let Some(list) = self.get_option(CoAPOption::ContentFormat) { - if let Some(vector) = list.front() { - let msb = vector[0] as u16; - let lsb = vector[1] as u16; - let number = (msb << 8) + lsb; - - return ContentFormat::from_u16(number); - } - } - - None - } - - /// Decodes a byte slice and construct the equivalent Packet. - pub fn from_bytes(buf: &[u8]) -> Result<Packet, ParseError> { - let header_result: bincode::DecodingResult<header::HeaderRaw> = bincode::decode(buf); - match header_result { - Ok(raw_header) => { - let header = header::Header::from_raw(&raw_header); - let token_length = header.get_token_length(); - let options_start: usize = 4 + token_length as usize; - - if token_length > 8 { - return Err(ParseError::InvalidTokenLength); - } - - if options_start > buf.len() { - return Err(ParseError::InvalidTokenLength); - } - - let token = buf[4..options_start].to_vec(); - - let mut idx = options_start; - let mut options_number = 0; - let mut options: BTreeMap<usize, LinkedList<Vec<u8>>> = BTreeMap::new(); - while idx < buf.len() { - let byte = buf[idx]; - - if byte == 255 || idx > buf.len() { - break; - } - - let mut delta = (byte >> 4) as usize; - let mut length = (byte & 0xF) as usize; - - idx += 1; - - // Check for special delta characters - match delta { - 13 => { - if idx >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - delta = buf[idx] as usize + 13; - idx += 1; - } - 14 => { - if idx + 1 >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - - delta = (u16::from_be(u8_to_unsigned_be!(buf, idx, idx + 1, u16)) + 269) - as usize; - idx += 2; - } - 15 => { - return Err(ParseError::InvalidOptionDelta); - } - _ => {} - }; - - // Check for special length characters - match length { - 13 => { - if idx >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - - length = buf[idx] as usize + 13; - idx += 1; - } - 14 => { - if idx + 1 >= buf.len() { - return Err(ParseError::InvalidOptionLength); - } - - length = (u16::from_be(u8_to_unsigned_be!(buf, idx, idx + 1, u16)) - + 269) as usize; - idx += 2; - } - 15 => { - return Err(ParseError::InvalidOptionLength); - } - _ => {} - }; - - options_number += delta; - - let end = idx + length; - if end > buf.len() { - return Err(ParseError::InvalidOptionLength); - } - let options_value = buf[idx..end].to_vec(); - - if options.contains_key(&options_number) { - let mut options_list = options.get_mut(&options_number).unwrap(); - options_list.push_back(options_value); - } else { - let mut list = LinkedList::new(); - list.push_back(options_value); - options.insert(options_number, list); - } - - idx += length; - } - - let mut payload = Vec::new(); - if idx < buf.len() { - payload = buf[(idx + 1)..buf.len()].to_vec(); - } - - - Ok(Packet { - header: header, - token: token, - options: options, - payload: payload, - }) - } - Err(_) => Err(ParseError::InvalidHeader), - } - } - - /// Returns a vector of bytes representing the Packet. - pub fn to_bytes(&self) -> Result<Vec<u8>, PackageError> { - let mut options_delta_length = 0; - let mut options_bytes: Vec<u8> = Vec::new(); - for (number, value_list) in self.options.iter() { - for value in value_list.iter() { - let mut header: Vec<u8> = Vec::with_capacity(1 + 2 + 2); - let delta = number - options_delta_length; - - let mut byte: u8 = 0; - if delta <= 12 { - byte |= (delta << 4) as u8; - } else if delta < 269 { - byte |= 13 << 4; - } else { - byte |= 14 << 4; - } - if value.len() <= 12 { - byte |= value.len() as u8; - } else if value.len() < 269 { - byte |= 13; - } else { - byte |= 14; - } - header.push(byte); - - if delta > 12 && delta < 269 { - header.push((delta - 13) as u8); - } else if delta >= 269 { - let fix = (delta - 269) as u16; - header.push((fix >> 8) as u8); - header.push((fix & 0xFF) as u8); - } - - if value.len() > 12 && value.len() < 269 { - header.push((value.len() - 13) as u8); - } else if value.len() >= 269 { - let fix = (value.len() - 269) as u16; - header.push((fix >> 8) as u8); - header.push((fix & 0xFF) as u8); - } - - options_delta_length += delta; - - options_bytes.reserve(header.len() + value.len()); - unsafe { - use std::ptr; - let buf_len = options_bytes.len(); - ptr::copy( - header.as_ptr(), - options_bytes.as_mut_ptr().offset(buf_len as isize), - header.len(), - ); - ptr::copy( - value.as_ptr(), - options_bytes - .as_mut_ptr() - .offset((buf_len + header.len()) as isize), - value.len(), - ); - options_bytes.set_len(buf_len + header.len() + value.len()); - } - } - } - - let mut buf_length = 4 + self.payload.len() + self.token.len(); - if self.header.code != header::MessageClass::Empty && self.payload.len() != 0 { - buf_length += 1; - } - buf_length += options_bytes.len(); - - if buf_length > 1280 { - return Err(PackageError::InvalidPacketLength); - } - - let mut buf: Vec<u8> = Vec::with_capacity(buf_length); - let header_result: bincode::EncodingResult<()> = bincode::encode_into( - &self.header.to_raw(), - &mut buf, - bincode::SizeLimit::Infinite, - ); - match header_result { - Ok(_) => { - buf.reserve(self.token.len() + options_bytes.len()); - unsafe { - use std::ptr; - let buf_len = buf.len(); - ptr::copy( - self.token.as_ptr(), - buf.as_mut_ptr().offset(buf_len as isize), - self.token.len(), - ); - ptr::copy( - options_bytes.as_ptr(), - buf.as_mut_ptr() - .offset((buf_len + self.token.len()) as isize), - options_bytes.len(), - ); - buf.set_len(buf_len + self.token.len() + options_bytes.len()); - } - - if self.header.code != header::MessageClass::Empty && self.payload.len() != 0 { - buf.push(0xFF); - buf.reserve(self.payload.len()); - unsafe { - use std::ptr; - let buf_len = buf.len(); - ptr::copy( - self.payload.as_ptr(), - buf.as_mut_ptr().offset(buf.len() as isize), - self.payload.len(), - ); - buf.set_len(buf_len + self.payload.len()); - } - } - Ok(buf) - } - Err(_) => Err(PackageError::InvalidHeader), - } - } - - fn get_option_number(tp: CoAPOption) -> usize { - match tp { - CoAPOption::IfMatch => 1, - CoAPOption::UriHost => 3, - CoAPOption::ETag => 4, - CoAPOption::IfNoneMatch => 5, - CoAPOption::Observe => 6, - CoAPOption::UriPort => 7, - CoAPOption::LocationPath => 8, - CoAPOption::UriPath => 11, - CoAPOption::ContentFormat => 12, - CoAPOption::MaxAge => 14, - CoAPOption::UriQuery => 15, - CoAPOption::Accept => 17, - CoAPOption::LocationQuery => 20, - CoAPOption::Block2 => 23, - CoAPOption::Block1 => 27, - CoAPOption::ProxyUri => 35, - CoAPOption::ProxyScheme => 39, - CoAPOption::Size1 => 60, - } - } -} - -#[cfg(test)] -mod test { - use super::*; - use super::super::header; - use std::collections::LinkedList; - - #[test] - fn test_decode_packet_with_options() { - let buf = [ - 0x44, - 0x01, - 0x84, - 0x9e, - 0x51, - 0x55, - 0x77, - 0xe8, - 0xb2, - 0x48, - 0x69, - 0x04, - 0x54, - 0x65, - 0x73, - 0x74, - 0x43, - 0x61, - 0x3d, - 0x31, - ]; - let packet = Packet::from_bytes(&buf); - assert!(packet.is_ok()); - let packet = packet.unwrap(); - assert_eq!(packet.header.get_version(), 1); - assert_eq!(packet.header.get_type(), header::MessageType::Confirmable); - assert_eq!(packet.header.get_token_length(), 4); - assert_eq!( - packet.header.code, - header::MessageClass::RequestType(header::Requests::Get) - ); - assert_eq!(packet.header.get_message_id(), 33950); - assert_eq!(*packet.get_token(), vec![0x51, 0x55, 0x77, 0xE8]); - assert_eq!(packet.options.len(), 2); - - let uri_path = packet.get_option(CoAPOption::UriPath); - assert!(uri_path.is_some()); - let uri_path = uri_path.unwrap(); - let mut expected_uri_path = LinkedList::new(); - expected_uri_path.push_back("Hi".as_bytes().to_vec()); - expected_uri_path.push_back("Test".as_bytes().to_vec()); - assert_eq!(uri_path, expected_uri_path); - - let uri_query = packet.get_option(CoAPOption::UriQuery); - assert!(uri_query.is_some()); - let uri_query = uri_query.unwrap(); - let mut expected_uri_query = LinkedList::new(); - expected_uri_query.push_back("a=1".as_bytes().to_vec()); - assert_eq!(uri_query, expected_uri_query); - } - - #[test] - fn test_decode_packet_with_payload() { - let buf = [ - 0x64, - 0x45, - 0x13, - 0xFD, - 0xD0, - 0xE2, - 0x4D, - 0xAC, - 0xFF, - 0x48, - 0x65, - 0x6C, - 0x6C, - 0x6F, - ]; - let packet = Packet::from_bytes(&buf); - assert!(packet.is_ok()); - let packet = packet.unwrap(); - assert_eq!(packet.header.get_version(), 1); - assert_eq!( - packet.header.get_type(), - header::MessageType::Acknowledgement - ); - assert_eq!(packet.header.get_token_length(), 4); - assert_eq!( - packet.header.code, - header::MessageClass::ResponseType(header::Responses::Content) - ); - assert_eq!(packet.header.get_message_id(), 5117); - assert_eq!(*packet.get_token(), vec![0xD0, 0xE2, 0x4D, 0xAC]); - assert_eq!(packet.payload, "Hello".as_bytes().to_vec()); - } - - #[test] - fn test_encode_packet_with_options() { - let mut packet = Packet::new(); - packet.header.set_version(1); - packet.header.set_type(header::MessageType::Confirmable); - packet.header.code = header::MessageClass::RequestType(header::Requests::Get); - packet.header.set_message_id(33950); - packet.set_token(vec![0x51, 0x55, 0x77, 0xE8]); - packet.add_option(CoAPOption::UriPath, b"Hi".to_vec()); - packet.add_option(CoAPOption::UriPath, b"Test".to_vec()); - packet.add_option(CoAPOption::UriQuery, b"a=1".to_vec()); - assert_eq!( - packet.to_bytes().unwrap(), - vec![ - 0x44, - 0x01, - 0x84, - 0x9e, - 0x51, - 0x55, - 0x77, - 0xe8, - 0xb2, - 0x48, - 0x69, - 0x04, - 0x54, - 0x65, - 0x73, - 0x74, - 0x43, - 0x61, - 0x3d, - 0x31, - ] - ); - } - - #[test] - fn test_encode_packet_with_payload() { - let mut packet = Packet::new(); - packet.header.set_version(1); - packet.header.set_type(header::MessageType::Acknowledgement); - packet.header.code = header::MessageClass::ResponseType(header::Responses::Content); - packet.header.set_message_id(5117); - packet.set_token(vec![0xD0, 0xE2, 0x4D, 0xAC]); - packet.payload = "Hello".as_bytes().to_vec(); - assert_eq!( - packet.to_bytes().unwrap(), - vec![ - 0x64, - 0x45, - 0x13, - 0xFD, - 0xD0, - 0xE2, - 0x4D, - 0xAC, - 0xFF, - 0x48, - 0x65, - 0x6C, - 0x6C, - 0x6F, - ] - ); - } - - #[test] - fn test_encode_decode_content_format() { - let mut packet = Packet::new(); - packet.set_content_format(ContentFormat::ApplicationJSON); - assert_eq!( - ContentFormat::ApplicationJSON, - packet.get_content_format().unwrap() - ) - } - - #[test] - fn test_decode_empty_content_format() { - let packet = Packet::new(); - assert!(packet.get_content_format().is_none()); - } - - #[test] - fn test_malicious_packet() { - use rand; - use quickcheck::{QuickCheck, StdGen, TestResult}; - - fn run(x: Vec<u8>) -> TestResult { - match Packet::from_bytes(&x[..]) { - Ok(packet) => TestResult::from_bool( - packet.get_token().len() == packet.header.get_token_length() as usize, - ), - Err(_) => TestResult::passed(), - } - } - QuickCheck::new() - .tests(10000) - .gen(StdGen::new(rand::thread_rng(), 1500)) - .quickcheck(run as fn(Vec<u8>) -> TestResult) - } -} diff --git a/utils/xoap/src/message/request.rs b/utils/xoap/src/message/request.rs deleted file mode 100644 index 8ccff794996704d2cb8532c6c25467b58cf6e093..0000000000000000000000000000000000000000 --- a/utils/xoap/src/message/request.rs +++ /dev/null @@ -1,87 +0,0 @@ -use message::IsMessage; -use message::response::CoAPResponse; -use message::packet::Packet; -use message::header::Header; -//use std::net::SocketAddr; - -#[derive(Debug)] -pub struct CoAPRequest { - pub message: Packet, - pub response: Option<CoAPResponse>, - pub source: Option<SocketAddr>, -} - -impl CoAPRequest { - pub fn new() -> CoAPRequest { - CoAPRequest { - response: None, - message: Packet::new(), - source: None, - } - } - - pub fn from_packet(packet: Packet, source: &SocketAddr) -> CoAPRequest { - CoAPRequest { - response: CoAPResponse::new(&packet), - message: packet, - source: Some(source.clone()), - } - } -} - -impl IsMessage for CoAPRequest { - fn get_message(&self) -> &Packet { - &self.message - } - fn get_mut_message(&mut self) -> &mut Packet { - &mut self.message - } - fn get_header(&self) -> &Header { - &self.message.header - } - fn get_mut_header(&mut self) -> &mut Header { - &mut self.message.header - } -} - -#[cfg(test)] -mod test { - use super::*; - use message::packet::{Packet, CoAPOption}; - use message::header::MessageType; - use message::IsMessage; - use std::net::SocketAddr; - use std::str::FromStr; - - #[test] - fn test_request_create() { - - let mut packet = Packet::new(); - let mut request1 = CoAPRequest::new(); - - packet.set_token(vec![0x17, 0x38]); - request1.set_token(vec![0x17, 0x38]); - - packet.add_option(CoAPOption::UriPath, b"test-interface".to_vec()); - request1.add_option(CoAPOption::UriPath, b"test-interface".to_vec()); - - packet.header.set_message_id(42); - request1.set_message_id(42); - - packet.header.set_version(2); - request1.set_version(2); - - packet.header.set_type(MessageType::Confirmable); - request1.set_type(MessageType::Confirmable); - - packet.header.set_code("0.04"); - request1.set_code("0.04"); - - let request2 = CoAPRequest::from_packet(packet, - &SocketAddr::from_str("127.0.0.1:1234").unwrap()); - - assert_eq!(request1.message.to_bytes().unwrap(), - request2.message.to_bytes().unwrap()); - - } -} \ No newline at end of file