<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12500">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add initial DFU class request handling<br><br>downloading is not supported yet, but the rest works<br><br>Change-Id: I4896d73602bb1b1001c1ce3af9b98e5173b45edf<br>---<br>M usb/class/dfu/device/dfudf.c<br>1 file changed, 49 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/usb/class/dfu/device/dfudf.c b/usb/class/dfu/device/dfudf.c</span><br><span>index faf12c1..f3286a1 100644</span><br><span>--- a/usb/class/dfu/device/dfudf.c</span><br><span>+++ b/usb/class/dfu/device/dfudf.c</span><br><span>@@ -34,6 +34,9 @@</span><br><span> static struct usbdf_driver _dfudf;</span><br><span> static struct dfudf_func_data _dfudf_funcd;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static enum usb_dfu_state dfu_state = USB_DFU_STATE_DFU_IDLE; /**< current DFU state */</span><br><span style="color: hsl(120, 100%, 40%);">+static enum usb_dfu_status dfu_status = USB_DFU_STATUS_OK; /**< current DFU status */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /**</span><br><span>  * \brief Enable DFU Function</span><br><span>  * \param[in] drv Pointer to USB device function driver</span><br><span>@@ -137,15 +140,55 @@</span><br><span>  if (0x01 != ((req->bmRequestType >> 5) & 0x03)) { // class request</span><br><span>              return ERR_NOT_FOUND;</span><br><span>        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   int32_t to_return = ERR_NONE;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t response[6]; // buffer for the response to this request</span><br><span>      if ((req->wIndex == _dfudf_funcd.func_iface)) {</span><br><span>           // we don't verify the bmRequestType</span><br><span>             switch (req->bRequest) {</span><br><span style="color: hsl(0, 100%, 40%);">-             default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        return ERR_UNSUPPORTED_OP;</span><br><span style="color: hsl(120, 100%, 40%);">+            case USB_DFU_GETSTATUS: // get status</span><br><span style="color: hsl(120, 100%, 40%);">+                 response[0] = dfu_status; // set status</span><br><span style="color: hsl(120, 100%, 40%);">+                       response[1] = 100; // set poll timeout (24 bits, in milliseconds) to small value for periodical poll</span><br><span style="color: hsl(120, 100%, 40%);">+                  response[2] = 0; // set poll timeout (24 bits, in milliseconds) to small value for periodical poll</span><br><span style="color: hsl(120, 100%, 40%);">+                    response[3] = 0; // set poll timeout (24 bits, in milliseconds) to small value for periodical poll</span><br><span style="color: hsl(120, 100%, 40%);">+                    response[4] = dfu_state; // set state</span><br><span style="color: hsl(120, 100%, 40%);">+                 response[5] = 0; // string not used</span><br><span style="color: hsl(120, 100%, 40%);">+                   to_return = usbdc_xfer(ep, response, 6, false); // send back status</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (USB_DFU_STATE_DFU_DNLOAD_SYNC == dfu_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             dfu_state = USB_DFU_STATE_DFU_DNBUSY; // switch to busy state</span><br><span style="color: hsl(120, 100%, 40%);">+                 } else if (USB_DFU_STATE_DFU_MANIFEST_SYNC == dfu_state) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            dfu_state = USB_DFU_STATE_DFU_MANIFEST; // go to manifest mode</span><br><span style="color: hsl(120, 100%, 40%);">+                                dfu_state = USB_DFU_STATE_APP_DETACH;</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case USB_DFU_CLRSTATUS: // clear status</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (USB_DFU_STATE_DFU_ERROR == dfu_state || USB_DFU_STATUS_OK != dfu_status) { // only clear in case there is an error</span><br><span style="color: hsl(120, 100%, 40%);">+                                dfu_status = USB_DFU_STATUS_OK; // clear error status</span><br><span style="color: hsl(120, 100%, 40%);">+                         dfu_state = USB_DFU_STATE_DFU_IDLE; // put back in idle state</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                     to_return = usbdc_xfer(ep, NULL, 0, true); // send ACK</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case USB_DFU_GETSTATE: // get state</span><br><span style="color: hsl(120, 100%, 40%);">+                   response[0] = dfu_state; // return state</span><br><span style="color: hsl(120, 100%, 40%);">+                      to_return = usbdc_xfer(ep, response, 1, false); // send back state</span><br><span style="color: hsl(120, 100%, 40%);">+                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case USB_DFU_ABORT: // abort current operation</span><br><span style="color: hsl(120, 100%, 40%);">+                        dfu_state = USB_DFU_STATE_DFU_IDLE; // put back in idle state (nothing else to do)</span><br><span style="color: hsl(120, 100%, 40%);">+                    to_return = usbdc_xfer(ep, NULL, 0, true); // send ACK</span><br><span style="color: hsl(120, 100%, 40%);">+                        //flash_pointer = (uint32_t)&__application_beginning; // reset download location</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case USB_DFU_DETACH: // detach makes only sense in DFU run-time/application mode</span><br><span style="color: hsl(120, 100%, 40%);">+              case USB_DFU_UPLOAD: // upload firmware from flash not supported</span><br><span style="color: hsl(120, 100%, 40%);">+              case USB_DFU_DNLOAD: // download firmware on flash TODO implement</span><br><span style="color: hsl(120, 100%, 40%);">+             default: // all other DFU class request</span><br><span style="color: hsl(120, 100%, 40%);">+                       dfu_state = USB_DFU_STATE_DFU_ERROR; // unknown or unsupported class request</span><br><span style="color: hsl(120, 100%, 40%);">+                  to_return = ERR_UNSUPPORTED_OP; // stall control pipe (don't reply to the request)</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span>               }</span><br><span>    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                return ERR_NOT_FOUND;</span><br><span style="color: hsl(120, 100%, 40%);">+         to_return = ERR_NOT_FOUND;</span><br><span>   }</span><br><span style="color: hsl(120, 100%, 40%);">+     return to_return;</span><br><span> }</span><br><span> </span><br><span> /** USB Device DFU Handler Struct */</span><br><span>@@ -165,11 +208,13 @@</span><br><span> </span><br><span>       usbdc_register_function(&_dfudf);</span><br><span>        usbdc_register_handler(USBDC_HDL_REQ, &dfudf_req_h);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    // TODO check if firmware is corrupted and set dfuERROR state if it is</span><br><span>       return ERR_NONE;</span><br><span> }</span><br><span> </span><br><span> /**</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Deinitialize the USB DFU Function Driver</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief De-initialize the USB DFU Function Driver</span><br><span>  */</span><br><span> void dfudf_deinit(void)</span><br><span> {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12500">change 12500</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12500"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-asf4-dfu </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I4896d73602bb1b1001c1ce3af9b98e5173b45edf </div>
<div style="display:none"> Gerrit-Change-Number: 12500 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Kévin Redon <kredon@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>