Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

217 lines
6.0 KiB

  1. import codecs
  2. import construct
  3. import importlib
  4. import sys
  5. from usb_protocol.types.descriptors.standard import ConfigurationDescriptor, DescriptorFormat, EndpointDescriptor, InterfaceDescriptor, StandardDescriptorNumbers
  6. from string import Template
  7. # Note this file is under the following copyright:
  8. copyright = '''/*-
  9. * Copyright 2022 John-Mark Gurney.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * 3. If you are STMicroelectronics N.V., one of it's subsidiaries, a
  20. * subsidiary of an owner of STMicroelectronics N.V., or an employee,
  21. * contractor, or agent of any of the preceeding entities, you are not
  22. * allowed to use this code, in either source or binary forms.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  25. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34. * SUCH DAMAGE.
  35. *
  36. */
  37. '''
  38. UniDesc = DescriptorFormat(
  39. "bLength" / construct.Int8ul,
  40. "bDescriptorType" / construct.Int8ul,
  41. )
  42. descparsers = {
  43. StandardDescriptorNumbers.INTERFACE: InterfaceDescriptor.parse,
  44. StandardDescriptorNumbers.ENDPOINT: EndpointDescriptor.parse,
  45. }
  46. def getepdescs(confdesc):
  47. ret = []
  48. lastdesc = ConfigurationDescriptor.parse(confdesc)
  49. pos = lastdesc.bLength
  50. while pos < len(confdesc):
  51. descparser = descparsers.get(confdesc[pos + 1], UniDesc.parse)
  52. desc = descparser(confdesc[pos:])
  53. if confdesc[pos + 1] == StandardDescriptorNumbers.ENDPOINT:
  54. ret.append(desc)
  55. lastdesc = desc
  56. pos += lastdesc.bLength
  57. return ret
  58. if __name__ == '__main__':
  59. usbname = sys.argv[1]
  60. mod = importlib.import_module(usbname)
  61. collection = mod.collection
  62. sorteddesc = sorted(collection)
  63. descs = { (x, y): z for x, y, z in collection }
  64. for value, index, raw in sorteddesc:
  65. print(int(value), repr(index), codecs.encode(raw, 'hex'))
  66. p = lambda *args, **kwargs: print(*args, **kwargs, file=fp)
  67. with open('%s_base.h' % usbname, 'w') as fp:
  68. p(Template('''${copyright}
  69. #include <usbd_core.h>
  70. extern USBD_ClassTypeDef ${usbname}_def;
  71. void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
  72. void ${usbname}_init(void);
  73. void ${usbname}_epopen(USBD_HandleTypeDef *pdev);
  74. void ${usbname}_epclose(USBD_HandleTypeDef *pdev);
  75. ''').substitute(locals()))
  76. with open('%s_base.c' % usbname, 'w') as fp:
  77. descstrings = '\n'.join('const uint8_t desc_%d_%d[] = { %s };' % (x, y, ', '.join(hex(w) for w in z)) for x, y, z in sorteddesc)
  78. descstructs = '\n'.join('\t{ .type = %d, .subnumb = %d, .datalen = %d, .data = desc_%d_%d },' % (x, y, len(z), x, y) for x, y, z in sorteddesc)
  79. epdescs = getepdescs(descs[(2, 0)])
  80. print(repr(epdescs))
  81. epopencode = '\n\t'.join(sum(([
  82. 'USBD_LL_OpenEP(pdev, %#x, %d, %d);' % (ep.bEndpointAddress, ep.bmAttributes & 0x3, ep.wMaxPacketSize),
  83. 'pdev->%s[%#x & 0xFU].is_used = 1;' % ('ep_in' if ep.bEndpointAddress & 0x80 else 'ep_out', ep.bEndpointAddress)
  84. ] for ep in epdescs), []))
  85. epclosecode = '\n\t'.join(sum(([
  86. 'USBD_LL_CloseEP(pdev, %#x);' % (ep.bEndpointAddress),
  87. 'pdev->%s[%#x & 0xFU].is_used = 0;' % ('ep_in' if ep.bEndpointAddress & 0x80 else 'ep_out', ep.bEndpointAddress)
  88. ] for ep in epdescs), []))
  89. print(repr(epopencode))
  90. p(Template('''${copyright}
  91. #include "${usbname}_base.h"
  92. #include <sysinit.h>
  93. #include <usbd_core.h>
  94. /* #include <usbd_desc.h> */
  95. /* #include <usbd_conf.h> */
  96. static USBD_HandleTypeDef usbd_inst;
  97. void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
  98. ${descstrings}
  99. static const struct {
  100. uint8_t type;
  101. uint8_t subnumb;
  102. uint8_t datalen;
  103. const uint8_t *data;
  104. } descriptors[] = {
  105. ${descstructs}
  106. };
  107. void
  108. USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
  109. {
  110. uint8_t const *buf;
  111. uint8_t buflen;
  112. uint8_t type, subnumb;
  113. int i;
  114. type = req->wValue >> 8;
  115. subnumb = req->wValue & 0xff;
  116. for (i = 0; i < sizeof descriptors / sizeof *descriptors; i++) {
  117. if (descriptors[i].type == type && descriptors[i].subnumb == subnumb) {
  118. buf = descriptors[i].data;
  119. buflen = descriptors[i].datalen;
  120. if ((buflen != 0U) && (req->wLength != 0U)) {
  121. buflen = MIN(buflen, req->wLength);
  122. USBD_CtlSendData(pdev, (uint8_t *)(uintptr_t)buf, buflen);
  123. }
  124. if(req->wLength == 0U) {
  125. USBD_CtlSendStatus(pdev);
  126. }
  127. return;
  128. }
  129. }
  130. USBD_CtlError(pdev , req);
  131. }
  132. void
  133. ${usbname}_init(void)
  134. {
  135. if (USBD_Init(&usbd_inst, NULL/*Desc, not used*/, DEVICE_FS) != USBD_OK)
  136. Error_Handler();
  137. if (USBD_RegisterClass(&usbd_inst, &${usbname}_def) != USBD_OK)
  138. Error_Handler();
  139. if (USBD_Start(&usbd_inst) != USBD_OK)
  140. Error_Handler();
  141. }
  142. SYSINIT_VF(${usbname}_init, SI_SUB_USB, SI_ORDER_MIDDLE, ${usbname}_init);
  143. void
  144. ${usbname}_epopen(USBD_HandleTypeDef *pdev)
  145. {
  146. ${epopencode}
  147. }
  148. void
  149. ${usbname}_epclose(USBD_HandleTypeDef *pdev)
  150. {
  151. ${epclosecode}
  152. }
  153. extern PCD_HandleTypeDef hpcd_USB_FS;
  154. void
  155. USB_LP_IRQHandler(void)
  156. {
  157. HAL_PCD_IRQHandler(&hpcd_USB_FS);
  158. }
  159. static volatile uint32_t holding;
  160. void
  161. Error_Handler(void)
  162. {
  163. #if 0
  164. debug_printf("error_handler\\n");
  165. #endif
  166. for (;;) holding++;
  167. }''').substitute(locals()))
  168. print('enda')