diff --git a/.gitmodules b/.gitmodules
index 9bb87d3574..e2a90fbd3b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -227,6 +227,10 @@
path = Sming/Libraries/MultipartParser/multipart-parser
url = https://github.com/iafonov/multipart-parser-c.git
ignore = dirty
+[submodule "Libraries.nanopb"]
+ path = Sming/Libraries/nanopb/nanopb
+ url = https://github.com/nanopb/nanopb.git
+ ignore = dirty
[submodule "Libraries.RapidXML"]
path = Sming/Libraries/RapidXML
url = https://github.com/mikee47/Sming-RapidXML
diff --git a/Sming/Libraries/nanopb/README.rst b/Sming/Libraries/nanopb/README.rst
new file mode 100644
index 0000000000..5a70236598
--- /dev/null
+++ b/Sming/Libraries/nanopb/README.rst
@@ -0,0 +1,56 @@
+Nano Protocol-Buffer
+====================
+
+Introduction
+------------
+
+This component adds support for `Nano Protocol-Buffer `_ implementation.
+
+ Nanopb is a small code-size `Protocol Buffers `_ implementation in ansi C. It is especially suitable for use in microcontrollers, but fits any memory restricted system.
+
+
+C file generation from Proto files
+----------------------------------
+
+Once this component is installed you can use it to add Nano Protocol-Buffer support to your project and generate C and header files from Proto files.
+One possible way to call the generator is to go to the directory where the proto file is located and run the generator. As shown below::
+
+ make -C $SMING_HOME fetch nano-pb
+ cd
+ python $SMING_HOME/Libraries/nanopb/nanopb/generator/nanopb_generator.py .proto
+
+After the generator tool is run you will have newly generated C and header files that can be used in your Sming application.
+
+Using
+-----
+
+1. Add ``COMPONENT_DEPENDS += nanopb`` to your application componenent.mk file.
+2. Add these lines to your application::
+
+ #include
+ // The line below should be replaced with the generated header file
+ #include "cast_channel.pb.h"
+
+3. Example::
+
+ #include
+ #include "cast_channel.pb.h"
+
+ void doSomething(const uint8_t* data, size_t length)
+ {
+ // ...
+
+ extensions_api_cast_channel_CastMessage message = extensions_api_cast_channel_CastMessage_init_default;
+
+ message.protocol_version = extensions_api_cast_channel_CastMessage_ProtocolVersion_CASTV2_1_0;
+ message.source_id.funcs.encode = &pbEncodeData;
+ message.source_id.arg = new PbData(sourceId);
+ message.destination_id.funcs.encode = &pbEncodeData;
+ message.destination_id.arg = new PbData(destinationId);
+ message.nameSpace.funcs.encode = &pbEncodeData;
+ message.nameSpace.arg = new PbData(ns);
+ message.payload_type = extensions_api_cast_channel_CastMessage_PayloadType_STRING;
+ message.payload_utf8.funcs.encode = &pbEncodeData;
+ message.payload_utf8.arg = new PbData((uint8_t*)data, length);
+ // ...
+ }
\ No newline at end of file
diff --git a/Sming/Libraries/nanopb/component.mk b/Sming/Libraries/nanopb/component.mk
new file mode 100644
index 0000000000..7145d462d4
--- /dev/null
+++ b/Sming/Libraries/nanopb/component.mk
@@ -0,0 +1,4 @@
+COMPONENT_SRCDIRS := nanopb src
+COMPONENT_INCDIRS := $(COMPONENT_SRCDIRS)
+
+COMPONENT_SUBMODULES += nanopb
\ No newline at end of file
diff --git a/Sming/Libraries/nanopb/nanopb b/Sming/Libraries/nanopb/nanopb
new file mode 160000
index 0000000000..049485ff55
--- /dev/null
+++ b/Sming/Libraries/nanopb/nanopb
@@ -0,0 +1 @@
+Subproject commit 049485ff557178f646d573eca3bd647f543b760b
diff --git a/Sming/Libraries/nanopb/src/PbUtils.cpp b/Sming/Libraries/nanopb/src/PbUtils.cpp
new file mode 100644
index 0000000000..2ba2047d1b
--- /dev/null
+++ b/Sming/Libraries/nanopb/src/PbUtils.cpp
@@ -0,0 +1,41 @@
+#include "PbUtils.h"
+
+// See: https://iam777.tistory.com/538
+
+bool pbEncodeData(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
+{
+ PbData *data = (PbData*) *arg;
+ if(data == nullptr) {
+ return false;
+ }
+
+ if (!pb_encode_tag_for_field(stream, field)) {
+ return false;
+ }
+
+ return pb_encode_string(stream, (uint8_t*)data->value, data->length);
+}
+
+bool pbDecodeData(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+ uint8_t buffer[1024] = {0};
+
+ /* We could read block-by-block to avoid the large buffer... */
+ if (stream->bytes_left > sizeof(buffer) - 1) {
+ return false;
+ }
+
+ size_t available = stream->bytes_left;
+ if (!pb_read(stream, buffer, stream->bytes_left)) {
+ return false;
+ }
+
+
+ MemoryDataStream* data = (MemoryDataStream*) *arg;
+ if(data == nullptr) {
+ data = new MemoryDataStream();
+ *arg = (void*)data;
+ }
+ data->write(buffer, available);
+ return true;
+}
diff --git a/Sming/Libraries/nanopb/src/PbUtils.h b/Sming/Libraries/nanopb/src/PbUtils.h
new file mode 100644
index 0000000000..78c221e659
--- /dev/null
+++ b/Sming/Libraries/nanopb/src/PbUtils.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+class PbData
+{
+public:
+ uint8_t* value = nullptr;
+ size_t length = 0;
+
+ PbData(const String& text)
+ {
+ PbData((uint8_t *)text.c_str(), text.length());
+ }
+
+ PbData(uint8_t* data, size_t length)
+ {
+ value = data;
+ this->length = length;
+ }
+};
+
+bool pbEncodeData(pb_ostream_t *stream, const pb_field_t *field, void * const *arg);
+bool pbDecodeData(pb_istream_t *stream, const pb_field_t *field, void **arg);