Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.63 KB | None | 0 0
  1. import os
  2. import time
  3. import struct
  4. import socket
  5. import pyodbc
  6. import logging
  7. import datetime
  8.  
  9. UDP_IP = '192.168.10.2'
  10. UDP_PORT = 4007
  11.  
  12.  
  13. def rawbytes(s):
  14. """
  15. Convert a string to raw bytes without encoding
  16. Used to convert the encoded string message for the radio into a byte array
  17. """
  18. outlist = []
  19. for cp in s:
  20. num = ord(cp)
  21. if num < 255:
  22. outlist.append(struct.pack('B', num))
  23. elif num < 65535:
  24. outlist.append(struct.pack('>H', num))
  25. else:
  26. b = (num & 0xFF0000) >> 16
  27. H = num & 0xFFFF
  28. outlist.append(struct.pack('>bH', b, H))
  29. return b''.join(outlist)
  30.  
  31.  
  32. def decode_message(message):
  33. """
  34. decode the string message coming from the radio
  35. """
  36. # header = message[:message.index(b'\n')]
  37. header = message[:6]
  38. ret = message[6:].replace(b'\x00', b'')
  39. return header, ret.decode(errors='ignore').strip()
  40.  
  41.  
  42. def recv_message(cursor, conn, udp_ip=UDP_IP, udp_port=UDP_PORT):
  43. """
  44. listen for messages then generate ack and send it
  45. """
  46. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  47. sock.bind((udp_ip, udp_port))
  48. while True:
  49. data, addr = sock.recvfrom(1024)
  50. header, decoded_message = decode_message(data)
  51. if len(header) == 6:
  52. print('Recieved {} from {}:{}'.format(
  53. decoded_message, addr[0], addr[1]))
  54. # time.sleep(1)
  55. send_ack(generate_ack(header), sock, addr[0], addr[1])
  56. push_to_db(cursor, conn, decoded_message, addr[0])
  57.  
  58.  
  59. def push_to_db(cursor, conn, decoded_message, radio_id):
  60. cursor.execute('insert into messages (radio_id, message_type, message_text, timestamp) values(?, ?, ?, ?)',
  61. 205, 'Text', decoded_message, datetime.datetime.now())
  62. conn.commit()
  63.  
  64.  
  65. def generate_ack(header):
  66. """
  67. generate ack for message
  68. """
  69. msg_header_2 = bin(header[5])[2:]
  70. extension = 0
  71.  
  72. if msg_header_2[1:3] != '00':
  73. extension = 1
  74. seq_extension = msg_header_2[1:3]
  75. ack_header_3 = '0{}00000'.format(seq_extension)
  76. ack_message_size = '0000000000000100'
  77. else:
  78. ack_header_3 = ''
  79. ack_message_size = '0000000000000011'
  80.  
  81. seq_num = bin(header[4])[2:][3:]
  82. ack_header_1 = '10011111'
  83. ack_header_2 = '{}00{}'.format(extension, seq_num)
  84. address_size = '00000000'
  85. print(ack_message_size[:8], ack_message_size[8:], ack_header_1,
  86. address_size, ack_header_2, ack_header_3)
  87. s = ack_message_size + ack_header_1 + address_size + ack_header_2 + ack_header_3
  88. return bytes(int(s[i:i+8], 2) for i in range(0, len(s), 8))
  89.  
  90.  
  91. def send_ack(ack, sock, udp_ip, udp_port):
  92. """
  93. send ack
  94. """
  95. print('Sending {} to {}:{}'.format(ack, udp_ip, udp_port))
  96. sock.sendto(ack, (udp_ip, udp_port))
  97.  
  98.  
  99. def init_db():
  100. conn = pyodbc.connect('Driver={MariaDB};'
  101. 'Server=localhost;'
  102. 'Database=motoroladb;'
  103. 'UID=engineer;'
  104. 'PWD=motorolastore')
  105. cursor = conn.cursor()
  106. return conn, cursor
  107.  
  108.  
  109. if __name__ == '__main__':
  110. conn, cursor = init_db()
  111. recv_message(cursor, conn)
  112.  
  113. # 00000000 00000011 10011111 00000000 000[10111]
  114. # [MESSAGE SIZE] [HEADER 1] [ADDRESS SIZE] [HEADER 2]
  115. # 00000000 00000011 10011111 00000000 000[01101]
  116.  
  117. # 00000010 00110100 11100000 00000000 100[10111] 0[00]00100
  118.  
  119. # If extension is indicated in message header, add extra header to ack and copy two extra seq num bits
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement