Retabbed anything else in python
This commit is contained in:
parent
2b11e0f94a
commit
9e8f8e986d
@ -3,9 +3,9 @@
|
|||||||
"""
|
"""
|
||||||
config_webrx: configuration options for OpenWebRX
|
config_webrx: configuration options for OpenWebRX
|
||||||
|
|
||||||
This file is part of OpenWebRX,
|
This file is part of OpenWebRX,
|
||||||
an open-source SDR receiver software with a web UI.
|
an open-source SDR receiver software with a web UI.
|
||||||
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as
|
||||||
@ -20,15 +20,15 @@ config_webrx: configuration options for OpenWebRX
|
|||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
In addition, as a special exception, the copyright holders
|
In addition, as a special exception, the copyright holders
|
||||||
state that config_rtl.py and config_webrx.py are not part of the
|
state that config_rtl.py and config_webrx.py are not part of the
|
||||||
Corresponding Source defined in GNU AGPL version 3 section 1.
|
Corresponding Source defined in GNU AGPL version 3 section 1.
|
||||||
|
|
||||||
(It means that you do not have to redistribute config_rtl.py and
|
(It means that you do not have to redistribute config_rtl.py and
|
||||||
config_webrx.py if you make any changes to these two configuration files,
|
config_webrx.py if you make any changes to these two configuration files,
|
||||||
and use them for running your web service with OpenWebRX.)
|
and use them for running your web service with OpenWebRX.)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# NOTE: you can find additional information about configuring OpenWebRX in the Wiki:
|
# NOTE: you can find additional information about configuring OpenWebRX in the Wiki:
|
||||||
@ -181,8 +181,8 @@ waterfall_auto_level_margin = (5, 40)
|
|||||||
##For the old colors, you might also want to set [fft_voverlap_factor] to 0.
|
##For the old colors, you might also want to set [fft_voverlap_factor] to 0.
|
||||||
|
|
||||||
#Note: When the auto waterfall level button is clicked, the following happens:
|
#Note: When the auto waterfall level button is clicked, the following happens:
|
||||||
# [waterfall_min_level] = [current_min_power_level] - [waterfall_auto_level_margin[0]]
|
# [waterfall_min_level] = [current_min_power_level] - [waterfall_auto_level_margin[0]]
|
||||||
# [waterfall_max_level] = [current_max_power_level] + [waterfall_auto_level_margin[1]]
|
# [waterfall_max_level] = [current_max_power_level] + [waterfall_auto_level_margin[1]]
|
||||||
#
|
#
|
||||||
# ___|____________________________________|____________________________________|____________________________________|___> signal power
|
# ___|____________________________________|____________________________________|____________________________________|___> signal power
|
||||||
# \_waterfall_auto_level_margin[0]_/ |__ current_min_power_level | \_waterfall_auto_level_margin[1]_/
|
# \_waterfall_auto_level_margin[0]_/ |__ current_min_power_level | \_waterfall_auto_level_margin[1]_/
|
||||||
|
1068
openwebrx.py
1068
openwebrx.py
File diff suppressed because it is too large
Load Diff
236
rxws.py
236
rxws.py
@ -1,9 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
rxws: WebSocket methods implemented for OpenWebRX
|
rxws: WebSocket methods implemented for OpenWebRX
|
||||||
|
|
||||||
This file is part of OpenWebRX,
|
This file is part of OpenWebRX,
|
||||||
an open-source SDR receiver software with a web UI.
|
an open-source SDR receiver software with a web UI.
|
||||||
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as
|
||||||
@ -26,146 +26,146 @@ import select
|
|||||||
import code
|
import code
|
||||||
|
|
||||||
class WebSocketException(Exception):
|
class WebSocketException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def handshake(myself):
|
def handshake(myself):
|
||||||
my_client_id=myself.path[4:]
|
my_client_id=myself.path[4:]
|
||||||
my_headers=myself.headers.items()
|
my_headers=myself.headers.items()
|
||||||
my_header_keys=map(lambda x:x[0],my_headers)
|
my_header_keys=map(lambda x:x[0],my_headers)
|
||||||
h_key_exists=lambda x:my_header_keys.count(x)
|
h_key_exists=lambda x:my_header_keys.count(x)
|
||||||
h_value=lambda x:my_headers[my_header_keys.index(x)][1]
|
h_value=lambda x:my_headers[my_header_keys.index(x)][1]
|
||||||
#print "The Lambdas(tm)"
|
#print "The Lambdas(tm)"
|
||||||
#print h_key_exists("upgrade")
|
#print h_key_exists("upgrade")
|
||||||
#print h_value("upgrade")
|
#print h_value("upgrade")
|
||||||
#print h_key_exists("sec-websocket-key")
|
#print h_key_exists("sec-websocket-key")
|
||||||
if (not h_key_exists("upgrade")) or not (h_value("upgrade")=="websocket") or (not h_key_exists("sec-websocket-key")):
|
if (not h_key_exists("upgrade")) or not (h_value("upgrade")=="websocket") or (not h_key_exists("sec-websocket-key")):
|
||||||
raise WebSocketException
|
raise WebSocketException
|
||||||
ws_key=h_value("sec-websocket-key")
|
ws_key=h_value("sec-websocket-key")
|
||||||
ws_key_toreturn=base64.b64encode(sha.new(ws_key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest())
|
ws_key_toreturn=base64.b64encode(sha.new(ws_key+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest())
|
||||||
#A sample list of keys we get: [('origin', 'http://localhost:8073'), ('upgrade', 'websocket'), ('sec-websocket-extensions', 'x-webkit-deflate-frame'), ('sec-websocket-version', '13'), ('host', 'localhost:8073'), ('sec-websocket-key', 't9J1rgy4fc9fg2Hshhnkmg=='), ('connection', 'Upgrade'), ('pragma', 'no-cache'), ('cache-control', 'no-cache')]
|
#A sample list of keys we get: [('origin', 'http://localhost:8073'), ('upgrade', 'websocket'), ('sec-websocket-extensions', 'x-webkit-deflate-frame'), ('sec-websocket-version', '13'), ('host', 'localhost:8073'), ('sec-websocket-key', 't9J1rgy4fc9fg2Hshhnkmg=='), ('connection', 'Upgrade'), ('pragma', 'no-cache'), ('cache-control', 'no-cache')]
|
||||||
myself.wfile.write("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+ws_key_toreturn+"\r\nCQ-CQ-de: HA5KFU\r\n\r\n")
|
myself.wfile.write("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+ws_key_toreturn+"\r\nCQ-CQ-de: HA5KFU\r\n\r\n")
|
||||||
|
|
||||||
def get_header(size):
|
def get_header(size):
|
||||||
#this does something similar: https://github.com/lemmingzshadow/php-websocket/blob/master/server/lib/WebSocket/Connection.php
|
#this does something similar: https://github.com/lemmingzshadow/php-websocket/blob/master/server/lib/WebSocket/Connection.php
|
||||||
ws_first_byte=0b10000010 # FIN=1, OP=2
|
ws_first_byte=0b10000010 # FIN=1, OP=2
|
||||||
if(size>125):
|
if(size>125):
|
||||||
ws_second_byte=126 # The following two bytes will indicate frame size
|
ws_second_byte=126 # The following two bytes will indicate frame size
|
||||||
extended_size=chr((size>>8)&0xff)+chr(size&0xff) #Okay, it uses reverse byte order (little-endian) compared to anything else sent on TCP
|
extended_size=chr((size>>8)&0xff)+chr(size&0xff) #Okay, it uses reverse byte order (little-endian) compared to anything else sent on TCP
|
||||||
else:
|
else:
|
||||||
ws_second_byte=size
|
ws_second_byte=size
|
||||||
#256 bytes binary message in a single unmasked frame | 0x82 0x7E 0x0100 [256 bytes of binary data]
|
#256 bytes binary message in a single unmasked frame | 0x82 0x7E 0x0100 [256 bytes of binary data]
|
||||||
extended_size=""
|
extended_size=""
|
||||||
return chr(ws_first_byte)+chr(ws_second_byte)+extended_size
|
return chr(ws_first_byte)+chr(ws_second_byte)+extended_size
|
||||||
|
|
||||||
def code_payload(data, masking_key=""):
|
def code_payload(data, masking_key=""):
|
||||||
# both encode or decode
|
# both encode or decode
|
||||||
if masking_key=="":
|
if masking_key=="":
|
||||||
key = (61, 84, 35, 6)
|
key = (61, 84, 35, 6)
|
||||||
else:
|
else:
|
||||||
key = [ord(i) for i in masking_key]
|
key = [ord(i) for i in masking_key]
|
||||||
encoded=""
|
encoded=""
|
||||||
for i in range(0,len(data)):
|
for i in range(0,len(data)):
|
||||||
encoded+=chr(ord(data[i])^key[i%4])
|
encoded+=chr(ord(data[i])^key[i%4])
|
||||||
return encoded
|
return encoded
|
||||||
|
|
||||||
def xxdg(data):
|
def xxdg(data):
|
||||||
output=""
|
output=""
|
||||||
for i in range(0,len(data)/8):
|
for i in range(0,len(data)/8):
|
||||||
output+=xxd(data[i:i+8])
|
output+=xxd(data[i:i+8])
|
||||||
if i%2: output+="\n"
|
if i%2: output+="\n"
|
||||||
else: output+=" "
|
else: output+=" "
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def xxd(data):
|
def xxd(data):
|
||||||
#diagnostic purposes only
|
#diagnostic purposes only
|
||||||
output=""
|
output=""
|
||||||
for d in data:
|
for d in data:
|
||||||
output+=hex(ord(d))[2:].zfill(2)+" "
|
output+=hex(ord(d))[2:].zfill(2)+" "
|
||||||
return output
|
return output
|
||||||
|
|
||||||
#for R/W the WebSocket, use recv/send
|
#for R/W the WebSocket, use recv/send
|
||||||
#for reading the TCP socket, use readsock
|
#for reading the TCP socket, use readsock
|
||||||
#for writing the TCP socket, use myself.wfile.write and flush
|
#for writing the TCP socket, use myself.wfile.write and flush
|
||||||
|
|
||||||
def readsock(myself,size,blocking):
|
def readsock(myself,size,blocking):
|
||||||
#http://thenestofheliopolis.blogspot.hu/2011/01/how-to-implement-non-blocking-two-way.html
|
#http://thenestofheliopolis.blogspot.hu/2011/01/how-to-implement-non-blocking-two-way.html
|
||||||
if blocking:
|
if blocking:
|
||||||
return myself.rfile.read(size)
|
return myself.rfile.read(size)
|
||||||
else:
|
else:
|
||||||
poll = select.poll()
|
poll = select.poll()
|
||||||
poll.register(myself.rfile.fileno(), select.POLLIN or select.POLLPRI)
|
poll.register(myself.rfile.fileno(), select.POLLIN or select.POLLPRI)
|
||||||
fd = poll.poll(0) #timeout is 0
|
fd = poll.poll(0) #timeout is 0
|
||||||
if len(fd):
|
if len(fd):
|
||||||
f = fd[0]
|
f = fd[0]
|
||||||
if f[1] > 0:
|
if f[1] > 0:
|
||||||
return myself.rfile.read(size)
|
return myself.rfile.read(size)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def recv(myself, blocking=False, debug=False):
|
def recv(myself, blocking=False, debug=False):
|
||||||
bufsize=70000
|
bufsize=70000
|
||||||
#myself.connection.setblocking(blocking) #umm... we cannot do that with rfile
|
#myself.connection.setblocking(blocking) #umm... we cannot do that with rfile
|
||||||
if debug: print "ws_recv begin"
|
if debug: print "ws_recv begin"
|
||||||
try:
|
try:
|
||||||
data=readsock(myself,6,blocking)
|
data=readsock(myself,6,blocking)
|
||||||
#print "rxws.recv bytes:",xxd(data)
|
#print "rxws.recv bytes:",xxd(data)
|
||||||
except:
|
except:
|
||||||
if debug: print "ws_recv error"
|
if debug: print "ws_recv error"
|
||||||
return ""
|
return ""
|
||||||
if debug: print "ws_recv recved"
|
if debug: print "ws_recv recved"
|
||||||
if(len(data)==0): return ""
|
if(len(data)==0): return ""
|
||||||
fin=ord(data[0])&128!=0
|
fin=ord(data[0])&128!=0
|
||||||
is_text_frame=ord(data[0])&15==1
|
is_text_frame=ord(data[0])&15==1
|
||||||
length=ord(data[1])&0x7f
|
length=ord(data[1])&0x7f
|
||||||
data+=readsock(myself,length,blocking)
|
data+=readsock(myself,length,blocking)
|
||||||
#print "rxws.recv length is ",length," (multiple packets together?) len(data) =",len(data)
|
#print "rxws.recv length is ",length," (multiple packets together?) len(data) =",len(data)
|
||||||
has_one_byte_length=length<125
|
has_one_byte_length=length<125
|
||||||
masked=ord(data[1])&0x80!=0
|
masked=ord(data[1])&0x80!=0
|
||||||
#print "len=", length, len(data)-2
|
#print "len=", length, len(data)-2
|
||||||
#print "fin, is_text_frame, has_one_byte_length, masked = ", (fin, is_text_frame, has_one_byte_length, masked)
|
#print "fin, is_text_frame, has_one_byte_length, masked = ", (fin, is_text_frame, has_one_byte_length, masked)
|
||||||
#print xxd(data)
|
#print xxd(data)
|
||||||
if fin and is_text_frame and has_one_byte_length:
|
if fin and is_text_frame and has_one_byte_length:
|
||||||
if masked:
|
if masked:
|
||||||
return code_payload(data[6:], data[2:6])
|
return code_payload(data[6:], data[2:6])
|
||||||
else:
|
else:
|
||||||
return data[2:]
|
return data[2:]
|
||||||
|
|
||||||
#Useful links for ideas on WebSockets:
|
#Useful links for ideas on WebSockets:
|
||||||
# http://stackoverflow.com/questions/8125507/how-can-i-send-and-receive-websocket-messages-on-the-server-side
|
# http://stackoverflow.com/questions/8125507/how-can-i-send-and-receive-websocket-messages-on-the-server-side
|
||||||
# https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_server
|
# https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_server
|
||||||
# http://tools.ietf.org/html/rfc6455#section-5.2
|
# http://tools.ietf.org/html/rfc6455#section-5.2
|
||||||
|
|
||||||
|
|
||||||
def flush(myself):
|
def flush(myself):
|
||||||
myself.wfile.flush()
|
myself.wfile.flush()
|
||||||
#or the socket, not the rfile:
|
#or the socket, not the rfile:
|
||||||
#lR,lW,lX = select.select([],[myself.connection,],[],60)
|
#lR,lW,lX = select.select([],[myself.connection,],[],60)
|
||||||
|
|
||||||
|
|
||||||
def send(myself, data, begin_id="", debug=0):
|
def send(myself, data, begin_id="", debug=0):
|
||||||
base_frame_size=35000 #could guess by MTU?
|
base_frame_size=35000 #could guess by MTU?
|
||||||
debug=0
|
debug=0
|
||||||
#try:
|
#try:
|
||||||
while True:
|
while True:
|
||||||
counter=0
|
counter=0
|
||||||
from_end=len(data)-counter
|
from_end=len(data)-counter
|
||||||
if from_end+len(begin_id)>base_frame_size:
|
if from_end+len(begin_id)>base_frame_size:
|
||||||
data_to_send=begin_id+data[counter:counter+base_frame_size-len(begin_id)]
|
data_to_send=begin_id+data[counter:counter+base_frame_size-len(begin_id)]
|
||||||
header=get_header(len(data_to_send))
|
header=get_header(len(data_to_send))
|
||||||
flush(myself)
|
flush(myself)
|
||||||
myself.wfile.write(header+data_to_send)
|
myself.wfile.write(header+data_to_send)
|
||||||
flush(myself)
|
flush(myself)
|
||||||
if debug: print "rxws.send ==================== #1 if branch :: from={0} to={1} dlen={2} hlen={3}".format(counter,counter+base_frame_size-len(begin_id),len(data_to_send),len(header))
|
if debug: print "rxws.send ==================== #1 if branch :: from={0} to={1} dlen={2} hlen={3}".format(counter,counter+base_frame_size-len(begin_id),len(data_to_send),len(header))
|
||||||
else:
|
else:
|
||||||
data_to_send=begin_id+data[counter:]
|
data_to_send=begin_id+data[counter:]
|
||||||
header=get_header(len(data_to_send))
|
header=get_header(len(data_to_send))
|
||||||
flush(myself)
|
flush(myself)
|
||||||
myself.wfile.write(header+data_to_send)
|
myself.wfile.write(header+data_to_send)
|
||||||
flush(myself)
|
flush(myself)
|
||||||
if debug: print "rxws.send :: #2 else branch :: dlen={0} hlen={1}".format(len(data_to_send),len(header))
|
if debug: print "rxws.send :: #2 else branch :: dlen={0} hlen={1}".format(len(data_to_send),len(header))
|
||||||
#if debug: print "header:\n"+xxdg(header)+"\n\nws data:\n"+xxdg(data_to_send)
|
#if debug: print "header:\n"+xxdg(header)+"\n\nws data:\n"+xxdg(data_to_send)
|
||||||
break
|
break
|
||||||
counter+=base_frame_size-len(begin_id)
|
counter+=base_frame_size-len(begin_id)
|
||||||
#except:
|
#except:
|
||||||
# pass
|
# pass
|
||||||
|
51
sdrhu.py
51
sdrhu.py
@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/python2
|
#!/usr/bin/python2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
This file is part of OpenWebRX,
|
This file is part of OpenWebRX,
|
||||||
an open-source SDR receiver software with a web UI.
|
an open-source SDR receiver software with a web UI.
|
||||||
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
Copyright (c) 2013-2015 by Andras Retzler <randras@sdr.hu>
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as
|
it under the terms of the GNU Affero General Public License as
|
||||||
@ -23,29 +23,28 @@
|
|||||||
import config_webrx as cfg, time, subprocess
|
import config_webrx as cfg, time, subprocess
|
||||||
|
|
||||||
def run(continuously=True):
|
def run(continuously=True):
|
||||||
if not cfg.sdrhu_key: return
|
if not cfg.sdrhu_key: return
|
||||||
firsttime="(Your receiver is soon getting listed on sdr.hu!)"
|
firsttime="(Your receiver is soon getting listed on sdr.hu!)"
|
||||||
while True:
|
while True:
|
||||||
cmd = "wget --timeout=15 -qO- http://sdr.hu/update --post-data \"url=http://"+cfg.server_hostname+":"+str(cfg.web_port)+"&apikey="+cfg.sdrhu_key+"\" 2>&1"
|
cmd = "wget --timeout=15 -qO- http://sdr.hu/update --post-data \"url=http://"+cfg.server_hostname+":"+str(cfg.web_port)+"&apikey="+cfg.sdrhu_key+"\" 2>&1"
|
||||||
#print "[openwebrx-sdrhu]", cmd
|
#print "[openwebrx-sdrhu]", cmd
|
||||||
returned=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()
|
returned=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()
|
||||||
returned=returned[0]
|
returned=returned[0]
|
||||||
#print returned
|
#print returned
|
||||||
if "UPDATE:" in returned:
|
if "UPDATE:" in returned:
|
||||||
retrytime_mins = 20
|
retrytime_mins = 20
|
||||||
value=returned.split("UPDATE:")[1].split("\n",1)[0]
|
value=returned.split("UPDATE:")[1].split("\n",1)[0]
|
||||||
if value.startswith("SUCCESS"):
|
if value.startswith("SUCCESS"):
|
||||||
print "[openwebrx-sdrhu] Update succeeded! "+firsttime
|
print "[openwebrx-sdrhu] Update succeeded! "+firsttime
|
||||||
firsttime=""
|
firsttime=""
|
||||||
else:
|
else:
|
||||||
print "[openwebrx-sdrhu] Update failed, your receiver cannot be listed on sdr.hu! Reason:", value
|
print "[openwebrx-sdrhu] Update failed, your receiver cannot be listed on sdr.hu! Reason:", value
|
||||||
else:
|
else:
|
||||||
retrytime_mins = 2
|
retrytime_mins = 2
|
||||||
print "[openwebrx-sdrhu] wget failed while updating, your receiver cannot be listed on sdr.hu!"
|
print "[openwebrx-sdrhu] wget failed while updating, your receiver cannot be listed on sdr.hu!"
|
||||||
if not continuously: break
|
if not continuously: break
|
||||||
time.sleep(60*retrytime_mins)
|
time.sleep(60*retrytime_mins)
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
run(False)
|
run(False)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user