util.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. # Copyright (c) 2015, Nordic Semiconductor
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions are met:
  6. #
  7. # * Redistributions of source code must retain the above copyright notice, this
  8. # list of conditions and the following disclaimer.
  9. #
  10. # * Redistributions in binary form must reproduce the above copyright notice,
  11. # this list of conditions and the following disclaimer in the documentation
  12. # and/or other materials provided with the distribution.
  13. #
  14. # * Neither the name of Nordic Semiconductor ASA nor the names of its
  15. # contributors may be used to endorse or promote products derived from
  16. # this software without specific prior written permission.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  22. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  24. # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. import struct
  29. # Nordic libraries
  30. from nordicsemi.exceptions import NordicSemiException
  31. # TODO: Create query function that maps query-result strings with functions
  32. def query_func(question, default=False):
  33. """
  34. Ask a string question
  35. No input defaults to "no" which results in False
  36. """
  37. valid = {"yes": True, "y": True, "no": False, "n": False}
  38. if default is True:
  39. prompt = " [Y/n]"
  40. else:
  41. prompt = " [y/N]"
  42. while True:
  43. print "%s %s" % (question, prompt)
  44. choice = raw_input().lower()
  45. if choice == '':
  46. return default
  47. elif choice in valid:
  48. return valid[choice]
  49. else:
  50. print "Please respond with y/n"
  51. def convert_uint16_to_array(value):
  52. """
  53. Converts a int to an array of 2 bytes (little endian)
  54. :param int value: int value to convert to list
  55. :return list[int]: list with 2 bytes
  56. """
  57. byte0 = value & 0xFF
  58. byte1 = (value >> 8) & 0xFF
  59. return [byte0, byte1]
  60. def convert_uint32_to_array(value):
  61. """
  62. Converts a int to an array of 4 bytes (little endian)
  63. :param int value: int value to convert to list
  64. :return list[int]: list with 4 bytes
  65. """
  66. byte0 = value & 0xFF
  67. byte1 = (value >> 8) & 0xFF
  68. byte2 = (value >> 16) & 0xFF
  69. byte3 = (value >> 24) & 0xFF
  70. return [byte0, byte1, byte2, byte3]
  71. def slip_parts_to_four_bytes(seq, dip, rp, pkt_type, pkt_len):
  72. """
  73. Creates a SLIP header.
  74. For a description of the SLIP header go to:
  75. http://developer.nordicsemi.com/nRF51_SDK/doc/7.2.0/s110/html/a00093.html
  76. :param int seq: Packet sequence number
  77. :param int dip: Data integrity check
  78. :param int rp: Reliable packet
  79. :param pkt_type: Payload packet
  80. :param pkt_len: Packet length
  81. :return: str with SLIP header
  82. """
  83. ints = [0, 0, 0, 0]
  84. ints[0] = seq | (((seq + 1) % 8) << 3) | (dip << 6) | (rp << 7)
  85. ints[1] = pkt_type | ((pkt_len & 0x000F) << 4)
  86. ints[2] = (pkt_len & 0x0FF0) >> 4
  87. ints[3] = (~(sum(ints[0:3])) + 1) & 0xFF
  88. return ''.join(chr(b) for b in ints)
  89. def int32_to_bytes(value):
  90. """
  91. Converts a int to a str with 4 bytes
  92. :param value: int value to convert
  93. :return: str with 4 bytes
  94. """
  95. ints = [0, 0, 0, 0]
  96. ints[0] = (value & 0x000000FF)
  97. ints[1] = (value & 0x0000FF00) >> 8
  98. ints[2] = (value & 0x00FF0000) >> 16
  99. ints[3] = (value & 0xFF000000) >> 24
  100. return ''.join(chr(b) for b in ints)
  101. def int16_to_bytes(value):
  102. """
  103. Converts a int to a str with 2 bytes
  104. :param value: int value to convert
  105. :return: str with 2 bytes
  106. """
  107. ints = [0, 0]
  108. ints[0] = (value & 0x00FF)
  109. ints[1] = (value & 0xFF00) >> 8
  110. return ''.join(chr(b) for b in ints)
  111. def bytes_to_int32(value):
  112. if len(value) > 4:
  113. return None
  114. while len(value) < 4:
  115. value += '\x00'
  116. return struct.unpack("<L", value)[0]
  117. def slip_decode_esc_chars(data):
  118. """Decode esc characters in a SLIP package.
  119. Replaces 0xDBDC with 0xCO and 0xDBDD with 0xDB.
  120. :return: str decoded data
  121. :type str data: data to decode
  122. """
  123. result = []
  124. while len(data):
  125. char = data.pop(0)
  126. if char == 0xDB:
  127. char2 = data.pop(0)
  128. if char2 == 0xDC:
  129. result.append(0xC0)
  130. elif char2 == 0xDD:
  131. result.append(0xDB)
  132. else:
  133. raise NordicSemiException('Char 0xDB NOT followed by 0xDC or 0xDD')
  134. else:
  135. result.append(char)
  136. return result
  137. def slip_encode_esc_chars(data_in):
  138. """Encode esc characters in a SLIP package.
  139. Replace 0xCO with 0xDBDC and 0xDB with 0xDBDD.
  140. :type str data_in: str to encode
  141. :return: str with encoded packet
  142. """
  143. result = []
  144. data = []
  145. for i in data_in:
  146. data.append(ord(i))
  147. while len(data):
  148. char = data.pop(0)
  149. if char == 0xC0:
  150. result.extend([0xDB, 0xDC])
  151. elif char == 0xDB:
  152. result.extend([0xDB, 0xDD])
  153. else:
  154. result.append(char)
  155. return ''.join(chr(i) for i in result)