I appreciate this being worked on.

There is one scenario I am wondering whether it is handled.  I am not familiar 
enough with libsigrokdecode's code to know.  The question is when a lower-level 
PD has its decode_end() called and that PD flushes data with calls to put(), 
will the next higher-level PD have its decode() called before its own 
decode_end() is called?


Here is a lousy example.  Feel free to substitute alternative protocols to 
create a valid example.  Imagine the midi protocol which sits on top of the 
uart protocol.  The ideal execution flow would be:

1.  The uart PD has decoded 8 bits of data but has not received all the stop 
bits.

2.  The uart PD receives the decode_end() call.

3.  The uart PD call put() to output the last byte to the next protocol.

4.  The midi PD's decode() is called with this last byte of data and processes 
it.

5.  The midi PD's decode_end() is called.


-Chris

________________________________
From: Gerhard Sittig <gerhard.sit...@gmx.net>
Sent: Sunday, October 16, 2016 9:26 AM
To: sigrok-devel@lists.sourceforge.net
Subject: [sigrok-devel] [PATCH 9201/9201] decode session: add optional 
decode_end() PD method and send_eof() session call

Protocol decoders scan incoming samples in their decode() method, to
derive higher level "frames" or "transactions" or similar, and send them
to the output stream.  Typically sample data from multiple decode()
calls needs to get processed before sending a higher level annotation to
the output.  But protocol decoders cannot determine whether a decode()
call carries the last available input data, or whether more calls will
follow.

Add support for an optional decode_end() method with no parameters.
When the input stream for a decoder session was exhausted, this method
gets called for all decoders which implement it.  Execution order copes
with decoder stacks.

Add a new public srd_session_send_eof() call to the libsigrokdecode API.
When invoked, it will call the decode_end() method of all protocol
decoders which are involved in the specified session (when they
implement the method, absence of the method is non-fatal).

Strictly speaking a protocol decoder might question whether a "frame"
was completed when its terminating condition was not observed (e.g. the
deassertion of a select signal, or an idle line for a certain amount of
bit times).  In these cases, the decoder can flush the data which was
accumulated so far, yet emit a warning that the last frame should be
considered incomplete ("unterminated").

This change is related to, but does not resolve Bugs 292 and 749.

Signed-off-by: Gerhard Sittig <gerhard.sit...@gmx.net>
---
 instance.c                 | 43 +++++++++++++++++++++++++++++++++++++++++++
 libsigrokdecode-internal.h |  1 +
 libsigrokdecode.h          |  1 +
 session.c                  | 28 ++++++++++++++++++++++++++++
 4 files changed, 73 insertions(+)

diff --git a/instance.c b/instance.c
index b1bfd81ce0bf..911eabd4411d 100644
--- a/instance.c
+++ b/instance.c
@@ -602,6 +602,49 @@ SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst 
*di,
 }

 /** @private */
+SRD_PRIV int srd_inst_decode_end(struct srd_decoder_inst *di)
+{
+       const char *meth_name;
+       int has_meth;
+       PyObject *py_res;
+       GSList *l;
+       struct srd_decoder_inst *next_di;
+       int ret;
+
+       /*
+        * Invoke the optional decode_end() method.  Absence of the method
+        * is acceptable, failed execution of a present method is fatal.
+        */
+       meth_name = "decode_end";
+       has_meth = PyObject_HasAttrString(di->decoder->py_dec, meth_name);
+       if (has_meth) {
+               srd_dbg("Calling %s() method on protocol decoder instance %s.",
+                               meth_name, di->inst_id);
+               Py_IncRef(di->py_inst);
+               py_res = PyObject_CallMethod(di->py_inst, meth_name, NULL);
+               if (!py_res) {
+                       srd_exception_catch("Protocol decoder instance %s",
+                                       di->inst_id);
+                       return SRD_ERR_PYTHON;
+               }
+               Py_DecRef(py_res);
+       } else {
+               srd_dbg("Skipping %s() method on protocol decoder instance %s.",
+                               meth_name, di->inst_id);
+       }
+
+       /* Recurse for all the PDs stacked on top of this one. */
+       for (l = di->next_di; l; l = l->next) {
+               next_di = l->data;
+               ret = srd_inst_decode_end(next_di);
+               if (ret != SRD_OK)
+                       return ret;
+       }
+
+       return SRD_OK;
+}
+
+/** @private */
 SRD_PRIV void srd_inst_free(struct srd_decoder_inst *di)
 {
         GSList *l;
diff --git a/libsigrokdecode-internal.h b/libsigrokdecode-internal.h
index 8259b97935a9..8ee6fb47940e 100644
--- a/libsigrokdecode-internal.h
+++ b/libsigrokdecode-internal.h
@@ -65,6 +65,7 @@ SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di);
 SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst *di,
                 uint64_t start_samplenum, uint64_t end_samplenum,
                 const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize);
+SRD_PRIV int srd_inst_decode_end(struct srd_decoder_inst *di);
 SRD_PRIV void srd_inst_free(struct srd_decoder_inst *di);
 SRD_PRIV void srd_inst_free_all(struct srd_session *sess, GSList *stack);

diff --git a/libsigrokdecode.h b/libsigrokdecode.h
index 03a5de096b18..ce38941af263 100644
--- a/libsigrokdecode.h
+++ b/libsigrokdecode.h
@@ -278,6 +278,7 @@ SRD_API int srd_session_metadata_set(struct srd_session 
*sess, int key,
 SRD_API int srd_session_send(struct srd_session *sess,
                 uint64_t start_samplenum, uint64_t end_samplenum,
                 const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize);
+SRD_API int srd_session_send_eof(struct srd_session *sess);
 SRD_API int srd_session_destroy(struct srd_session *sess);
 SRD_API int srd_pd_output_callback_add(struct srd_session *sess,
                 int output_type, srd_pd_output_callback cb, void *cb_data);
diff --git a/session.c b/session.c
index e1bb4f9880d3..13f5c0cd14dd 100644
--- a/session.c
+++ b/session.c
@@ -257,6 +257,34 @@ SRD_API int srd_session_send(struct srd_session *sess,
 }

 /**
+ * Communicate "end of input" within the running decoder session.
+ *
+ * @param sess The session to use. Must not be NULL.
+ *
+ * @return SRD_OK upon success, a (negative) error code otherwise.
+ *
+ * @since 0.5.0
+ */
+SRD_API int srd_session_send_eof(struct srd_session *sess)
+{
+       GSList *d;
+       int ret;
+
+       if (session_is_valid(sess) != SRD_OK) {
+               srd_err("Invalid session.");
+               return SRD_ERR_ARG;
+       }
+
+       for (d = sess->di_list; d; d = d->next) {
+               ret = srd_inst_decode_end(d->data);
+               if (ret != SRD_OK)
+                       return ret;
+       }
+
+       return SRD_OK;
+}
+
+/**
  * Destroy a decoding session.
  *
  * All decoder instances and output callbacks are properly released.
--
1.9.1

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Slashdot: News for nerds, stuff that matters<http://sdm.link/slashdot>
sdm.link
Slashdot: News for nerds, stuff that matters. Timely news source for technology 
related news with a heavy slant towards Linux and Open Source issues.


_______________________________________________
sigrok-devel mailing list
sigrok-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sigrok-devel
sigrok-devel Info Page - 
SourceForge<https://lists.sourceforge.net/lists/listinfo/sigrok-devel>
lists.sourceforge.net
To see the collection of prior postings to the list, visit the sigrok-devel 
Archives. Using sigrok-devel: To post a message to all the list members ...


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
sigrok-devel mailing list
sigrok-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to