Fix "missing required field" error with submessage callback (#544).
diff --git a/pb_decode.c b/pb_decode.c
index 84b0f3e..41d895d 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -1601,6 +1601,7 @@
 static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field)
 {
     bool status = true;
+    bool submsg_consumed = false;
     pb_istream_t substream;
 
     if (!pb_make_string_substream(stream, &substream))
@@ -1632,11 +1633,16 @@
         if (callback->funcs.decode)
         {
             status = callback->funcs.decode(&substream, field, &callback->arg);
+
+            if (substream.bytes_left == 0)
+            {
+                submsg_consumed = true;
+            }
         }
     }
 
     /* Now decode the submessage contents */
-    if (status)
+    if (status && !submsg_consumed)
     {
         status = pb_decode_inner(&substream, field->submsg_desc, field->pData, 0);
     }
diff --git a/tests/regression/issue_544/SConscript b/tests/regression/issue_544/SConscript
new file mode 100644
index 0000000..4daf12c
--- /dev/null
+++ b/tests/regression/issue_544/SConscript
@@ -0,0 +1,8 @@
+# Regression test for #544:
+# Decoding whole submessage in submessage callback causes "missing required field"
+
+Import("env")
+env.NanopbProto("submsg_callback")
+
+test = env.Program(["submsg_callback.c", "submsg_callback.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
+env.RunTest(test)
diff --git a/tests/regression/issue_544/submsg_callback.c b/tests/regression/issue_544/submsg_callback.c
new file mode 100644
index 0000000..938ba6c
--- /dev/null
+++ b/tests/regression/issue_544/submsg_callback.c
@@ -0,0 +1,57 @@
+#include "submsg_callback.pb.h"
+#include <pb_encode.h>
+#include <pb_decode.h>
+#include "unittests.h"
+
+bool msg_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+    /* This tests decoding the submessage already in the message level callback. */
+
+    SubMessage *submsg = (SubMessage*)field->pData;
+
+    if (!pb_decode(stream, SubMessage_fields, submsg))
+        PB_RETURN_ERROR(stream, "submsg decode failed");
+    
+    if (submsg->foo != 1234)
+        PB_RETURN_ERROR(stream, "submsg.foo wrong value");
+    
+    return true;
+}
+
+int main()
+{
+    int status = 0;
+    pb_byte_t buf[64];
+    size_t msglen;
+
+    {
+        pb_ostream_t ostream = pb_ostream_from_buffer(buf, sizeof(buf));
+        MyMessage msg = MyMessage_init_zero;
+
+        msg.which_oneof = MyMessage_submsg_tag;
+        msg.oneof.submsg.foo = 1234;
+
+        if (!pb_encode(&ostream, MyMessage_fields, &msg))
+        {
+            fprintf(stderr, "pb_encode() failed: %s\n", PB_GET_ERROR(&ostream));
+            return 1;
+        }
+
+        msglen = ostream.bytes_written;
+        TEST(msglen > 0);
+    }
+
+    {
+        pb_istream_t istream = pb_istream_from_buffer(buf, msglen);
+        MyMessage msg = MyMessage_init_zero;
+        msg.cb_oneof.funcs.decode = msg_callback;
+
+        if (!pb_decode(&istream, MyMessage_fields, &msg))
+        {
+            fprintf(stderr, "pb_decode() failed: %s\n", PB_GET_ERROR(&istream));
+            return 1;
+        }
+    }
+
+    return status;
+}
\ No newline at end of file
diff --git a/tests/regression/issue_544/submsg_callback.proto b/tests/regression/issue_544/submsg_callback.proto
new file mode 100644
index 0000000..50485d2
--- /dev/null
+++ b/tests/regression/issue_544/submsg_callback.proto
@@ -0,0 +1,13 @@
+syntax = "proto2";
+
+import "nanopb.proto";
+
+message SubMessage {
+    required uint32 foo = 1;
+}
+
+message MyMessage {
+    oneof oneof {
+        SubMessage submsg = 1 [(nanopb).submsg_callback = true];
+    }
+}