Advertisement
Guest User

Untitled

a guest
Oct 19th, 2016
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.13 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib
  3. import matplotlib.patches as mpatches
  4. import matplotlib.pyplot as plt
  5. import matplotlib.animation as animation
  6. import matplotlib.ticker as plticker
  7.  
  8. USERNAME = 'ubnt'
  9. PASSWORD = 'ubnt1'
  10. HOST = "192.168.1.220"
  11. PORT = 18888
  12. TIMEOUT = 10
  13. FRAME_SPEED = 1
  14.  
  15. LOGIN_URI = 'http://' + HOST + ':80/login.cgi'
  16. #LOGIN_URI = 'https://' + HOST + ':443/login.cgi'
  17.  
  18. def usage():
  19. print ("Usage:+ sys.argv[0] + <live|replay FILENAME>")
  20. print ("")
  21. print ("Options:")
  22. print ("tlive t=tProcess live data from device ") + HOST
  23. print ("treplay FILENAME t=tReplay FILENAME")
  24. print ("trecord FILENAME t=tMake movie of FILENAME")
  25. exit(128)
  26.  
  27. if len(sys.argv) == 2 and sys.argv[1] == 'live':
  28. ACTION='live'
  29. FILENAME = None
  30. elif len(sys.argv) == 3 and sys.argv[1] == 'replay':
  31. ACTION='replay'
  32.  
  33. ocessing
  34. FRAME_SPEED = 50
  35. elif len(sys.argv) == 3 and sys.argv[1] == 'record':
  36. ACTION='record'
  37. FILENAME = sys.argv[2] # Stored data processing
  38. FRAME_SPEED = 50
  39. else:
  40. usage()
  41.  
  42.  
  43.  
  44. def parse_get_frame_resp(line):
  45. _,vals_raw = line.split(':')
  46. vals = map(int, vals_raw.split(','))
  47. frame_nr = vals.pop(0)
  48. return(frame_nr, vals)
  49.  
  50. #TODO: Make me dynamic parse from 'SCAN RANGE' response
  51. scan_range_begin = 2402000000
  52. scan_range_end = 2497000000
  53.  
  54. if not FILENAME:
  55. print ("Enabling Ubiquiti airView at %s:%s@%s...") %(USERNAME, PASSWORD, HOST)
  56. s = requests.session()
  57. s.get(LOGIN_URI, verify=False)
  58. r = s.post(LOGIN_URI,
  59. {"username": USERNAME, "password": PASSWORD, "uri": "airview.cgi? start=1"},
  60. verify=False)
  61. if 'Invalid credentials.' in r.text:
  62. print ("# CRIT: Username/password invalid!")
  63. sys.exit(1)
  64. print ("Waiting for device to enter airView modus...")
  65. # Allow device a few moments to settle
  66. time.sleep(TIMEOUT)
  67.  
  68. print ("Start scanning...")
  69. tn = telnetlib.Telnet(HOST, PORT, timeout=TIMEOUT)
  70. #tn.set_debuglevel(99)
  71.  
  72. # Storage on unique files
  73. outfile = 'output-%s.dat' % int(time.time())
  74. print ("Storing output at '%s'") % outfile
  75. fh = open(outfile, 'a')
  76. def writeline(cmd):
  77. """ Write line to device"""
  78. ts = time.time()
  79. tn.write(cmd)
  80. print (cmd)
  81. fh.write("%s01%s" % (ts, cmd))
  82. return ts
  83.  
  84.  
  85. def getline():
  86. """Read line from device"""
  87. line = tn.read_until("n")
  88. print (line)
  89. fh.write("%s01%s" % (time.time(), line))
  90. return line
  91.  
  92. # Commands needs to have a trailing space if no arguments specified
  93. writeline("CONNECT: n")
  94. getline()
  95.  
  96. #writeline("REQUEST RANGE: 2402000000,2407000000n") # 5 MHz
  97. #writeline("REQUEST RANGE: 2402000000,2412000000n") # 10 MHz
  98. #writeline("REQUEST RANGE: 2402000000,2417000000n") # 15 MHz
  99. #writeline("REQUEST RANGE: 2402000000,2422000000n") # 20 Mhz
  100. #writeline("REQUEST RANGE: 2402000000,2477000000n") # (ch 1-11 - US allocation)
  101. #writeline("REQUEST RANGE: 2402000000,2487000000n") # (ch 1-13 - UK allocation)
  102. writeline("REQUEST RANGE: 2402000000,2497000000n") # (ch 1-14)
  103. getline()
  104.  
  105. writeline("START SCAN: n")
  106. getline()
  107. print ("Waiting for scan to start...")
  108. time.sleep(2)
  109.  
  110. def get_frame(frame):
  111. """ Get frame from device airView """
  112. # TODO: Receiving frames in order, sometimes yield of empty responses. Already flush out maybe?
  113. #writeline("GET FRAME: %sn" % frame)
  114. ts = writeline("GET FRAME: n")
  115. line = getline()
  116. return((ts,) + parse_get_frame_resp(line))
  117. else:
  118. # No need for logic since we are processing stored data
  119. sh = open(FILENAME, 'r')
  120. def get_frame(frame):
  121. """ Perform replay data processing """
  122. while True:
  123. line = sh.readline()
  124. if not line:
  125. return(None, None, None)
  126. ts_raw, a = line.split('01', 1)
  127. ts = float(ts_raw)
  128. cmd, ret = a.split(':', 1)
  129. if cmd == 'FRAME':
  130. return((ts,) + parse_get_frame_resp(a))
  131.  
  132.  
  133. # Get innitial frame number and bins sizes
  134. _, frame_nr, vals = get_frame(None)
  135. bin_size = len(vals)
  136. bin_sample_khz = float(scan_range_end - scan_range_begin) / 1000 / bin_size
  137. print ("Bin size: %s") % bin_size
  138.  
  139.  
  140. # Start making picture
  141. fig, ax = plt.subplots(figsize=(20,11))
  142. fig.canvas.set_window_title('UBNT airView Client')
  143. ax.set_ylabel('100ms units elapsed')
  144. ax.set_xlabel('Frequency (sampled with bins of %s kHz)' % bin_sample_khz)
  145.  
  146. # Channel center frequencies
  147. a = [2402,2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462,2467,2472,2484,2497]
  148. channels = (np.array(a,dtype='float32') - 2402) / (bin_sample_khz / 1000)
  149. ax.get_xaxis().set_ticks(channels)
  150. plt.xticks(rotation=90)
  151.  
  152. # Plot channel description
  153. for i in range(1,15):
  154. width_20mhz = 20000.0 / bin_sample_khz
  155. if i in [1,6,11,14]:
  156. pac = mpatches.Arc([channels[i], 0], width_20mhz, 300,
  157. theta2=180, linestyle='solid', linewidth=2, color='black')
  158. else:
  159. pac = mpatches.Arc([channels[i], 0], width_20mhz, 300,
  160. theta2=180, linestyle='dashed', linewidth=2, color='black')
  161. ax.add_patch(pac)
  162.  
  163.  
  164. ax.get_xaxis().set_major_formatter(
  165. plticker.FuncFormatter(lambda x, p: format(int((x * bin_sample_khz / 1000) + 2402), ',')))
  166.  
  167. plt.grid(linewidth=2,linestyle='solid',color='black')
  168. plt.tight_layout()
  169.  
  170. bbox = fig.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
  171. width, height = bbox.width*fig.dpi, bbox.height*fig.dpi
  172. print (width), (height)
  173.  
  174. # Initial data and history of amount of pixels of the screen, since it is
  175. # important that all lines are draw on the screen.
  176. bbox = fig.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
  177. width, height = bbox.width*fig.dpi, bbox.height*fig.dpi
  178.  
  179. matrix = np.empty([int(height),bin_size]) * np.nan
  180. pcm = ax.pcolorfast(matrix, vmin=-122, vmax=-30)
  181.  
  182. if ACTION == 'record':
  183. # Set up formatting for the movie files
  184. Writer = animation.writers['ffmpeg']
  185. writer = Writer(fps=15, metadata=dict(artist='AnyWi UBNT airViewer'), bitrate=1800)
  186.  
  187. #
  188. # Matplotlib Animation
  189. #
  190. def update(data):
  191. global frame_nr, matrix
  192.  
  193. # Fast forwarding in time
  194. for i in range(FRAME_SPEED):
  195.  
  196. frame_nr_next = -1
  197.  
  198. # The same frame (duplicated), we are too fast
  199. while frame_nr_next <= frame_nr:
  200. ts, frame_nr_next, row = get_frame(frame_nr + 1)
  201.  
  202. frame_nr = frame_nr_next
  203.  
  204. # We are on the end of the file
  205. if not ts and not frame_nr and not row:
  206. return
  207.  
  208. #matrix = np.vstack([row, pcm.get_array()[:-1]])
  209. matrix = np.vstack([row, matrix[:-1]])
  210.  
  211. pcm.set_array(matrix)
  212. ax.set_title('Frame %s at %s' % (frame_nr,time.asctime(time.localtime(ts))))
  213. #fig.canvas.draw()
  214.  
  215.  
  216. ani = animation.FuncAnimation(fig, update, interval=100)
  217.  
  218. # Dual display and recording data does not seems to work, use a screencast
  219. # program like gtk-recordmydesktop for that matter
  220. if ACTION == 'record':
  221. ani.save('live.mp4' if not FILENAME else FILENAME.rsplit('.',1)[0] + '.mp4', writer=writer)
  222. else:
  223. plt.show()
  224.  
  225. #
  226. # Takes some time (10 seconds) for device to return to an active state
  227. #
  228.  
  229.  
  230. error output
  231. Usage:+ sys.argv[0] + <live|replay FILENAME>
  232.  
  233. Options:
  234. live = Process live data from device
  235. Traceback (most recent call last):
  236. File "C:UsersABDULHUSSEINDesktoppy-ubnt-airviewer-masterairviewer.py", line 76, in <module>
  237. usage()
  238. File "C:UsersABDULHUSSEINDesktoppy-ubnt-airviewer-masterairviewer.py", line 58, in usage
  239. print ("tlive t=tProcess live data from device ") + HOST
  240. TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement