Merge pull request #28 from DJ2LS/TNC-signalling

switching to signalling mode as default
This commit is contained in:
DJ2LS 2021-03-07 16:25:28 +01:00 committed by GitHub
commit 302cff8b23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 872 additions and 311 deletions

View file

@ -2,22 +2,18 @@
## FreeDV- Just Another TNC Experiment
My first attempt to learn more about FreeDV and how to create a TNC which gets data from a TCP/IP socket
## ToDo
- [x] ARQ: Stop-And-Wait
- [x] ARQ: Go-Back-N
- [x] ARQ: Selective repeating of lost arq frames
- [x] ARQ: Dynamic number of frames per burst
- [ ] ARQ: Set frames per burst automatically by channel quality
- [x] SOCKET: Run commands via TCP/IP socket
- [ ] TRX: Control radio via hamlib
- [ ] MODE: Beacon
- [ ] MODE: Broadcast
- [ ] MODE: ARQ AX25
- [ ] MODE: Gear shifting ARQ
- [ ] TNC: CLI GUI for basic settings
- [ ] TNC: Multicore support
- [ ] MODEM: Sample rate conversion
## Credits
David Rowe and the FreeDV team for developing the modem and libraries
FreeDV Codec 2 : https://github.com/drowe67/codec2
This software has been heavily inspired by https://github.com/xssfox/freedv-tnc/
## Setup
Install FreeDV-Socket-TNC directly to home folder and compile codec2 automatically
@ -30,73 +26,26 @@ chmod +x ~/install_socket_tnc.sh
## Usage main program
```
./main.py --port 3000 --tx 1 --rx 1 --mode 12
./main.py --port 3000 --tx 1 --rx 1
```
## Usage TCP/IP socket client
## Usage testclient
```
python3 readfromsocket.py --port 3000 --data "GET:RX_BUFFER:0
./socketclient.py --port 3000 --data "BC: hello"
```
## Socket Commands
#### SOCKETTEST
Message for testing purposes which repeats:
Send a simple broadcast
```
SOCKETTEST
BC:<DATA>
```
"WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC"
#### TRANSMIT ARQ MESSAGE 'HELLO!'
Send an ARQ like frame which will ask the receiver for acknowledgement
```
ARQ:HELLO!
ACK:<DATA>
```
#### SET NEW CALLSIGN
```
SET:MYCALLSIGN:AA1AA
```
#### GET CALLSIGN
```
GET:MYCALLSIGN
```
#### GET CALLSIGN CRC8
```
GET:MYCALLSIGN_CRC8
```
#### GET DX CALLSIGN
```
GET:DXCALLSIGN
```
#### GET ARQ STATE
```
GET:ARQ_STATE
```
#### GET RX BUFFER LENGTH / SIZE
```
GET:RX_BUFFER_LENGTH
```
#### GET RX BUFFER
```
GET:RX_BUFFER:POSITION
```
Position = 0 --> Latest Data
Position 1-N --> Buffer positions
#### DELETE RX BUFFER
```
DEL:RX_BUFFER
```
## Other stuff
@ -114,9 +63,3 @@ sudo modprobe snd-aloop index=1,2 enable=1,1 pcm_substreams=1,1 id=CHAT1,CHAT2
./main.py --port 3001 --tx 2 --rx 2
```
## Credits
David Rowe and the FreeDV team for developing the modem and libraries
FreeDV Codec 2 : https://github.com/drowe67/codec2
This software has been inspired by https://github.com/xssfox/freedv-tnc/

View file

@ -10,6 +10,8 @@ import logging
import threading
import time
from random import randrange
import asyncio
import trio
import static
import modem
@ -18,15 +20,20 @@ import helpers
def data_received(data_in):
static.TNC_STATE = b'BUSY'
#############################################################################################################
# ARQ DATA HANDLER
#############################################################################################################
def arq_data_received(data_in):
static.TNC_STATE = 'BUSY'
static.ARQ_N_FRAME = int.from_bytes(bytes(data_in[:1]), "big") - 10 #get number of burst frame
static.ARQ_N_RX_FRAMES_PER_BURSTS = int.from_bytes(bytes(data_in[1:2]), "big") #get number of bursts from received frame
static.ARQ_RX_N_CURRENT_ARQ_FRAME = int.from_bytes(bytes(data_in[2:4]), "big") #get current number of total frames
static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME = int.from_bytes(bytes(data_in[4:6]), "big") # get get total number of frames
static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME = int.from_bytes(bytes(data_in[4:6]), "big") # get get total number of frames
logging.debug("----------------------------------------------------------------")
logging.debug("ARQ_N_FRAME: " + str(static.ARQ_N_FRAME))
@ -35,14 +42,11 @@ def data_received(data_in):
logging.debug("ARQ_N_ARQ_FRAMES_PER_DATA_FRAME: " + str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME))
logging.debug("----------------------------------------------------------------")
arq_percent_burst = int((static.ARQ_N_FRAME / static.ARQ_N_RX_FRAMES_PER_BURSTS)*100)
arq_percent_frame = int(((static.ARQ_RX_N_CURRENT_ARQ_FRAME)/static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME)*100)
logging.log(24, "ARQ | RX | ARQ FRAME [" + str(static.ARQ_N_FRAME) + "/" + str(static.ARQ_N_RX_FRAMES_PER_BURSTS) + "] [" + str(arq_percent_burst).zfill(3) + "%] --- TOTAL [" + str(static.ARQ_RX_N_CURRENT_ARQ_FRAME) + "/" + str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME) + "] [" + str(arq_percent_frame).zfill(3) + "%]" )
logging.log(24, "ARQ | RX | " + str(static.ARQ_DATA_CHANNEL_MODE) + " | F:[" + str(static.ARQ_N_FRAME) + "/" + str(static.ARQ_N_RX_FRAMES_PER_BURSTS) + "] [" + str(arq_percent_burst).zfill(3) + "%] T:[" + str(static.ARQ_RX_N_CURRENT_ARQ_FRAME) + "/" + str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME) + "] [" + str(arq_percent_frame).zfill(3) + "%] [BER."+str(static.BER)+"]" )
#allocate ARQ_RX_FRAME_BUFFER as a list with "None" if not already done. This should be done only once per burst!
# here we will save the N frame of a data frame to N list position so we can explicit search for it
# delete frame buffer if first frame to make sure the buffer is cleared and no junks of a old frame is remaining
@ -73,19 +77,23 @@ def data_received(data_in):
static.ARQ_RX_BURST_BUFFER.insert(i,None)
static.ARQ_RX_BURST_BUFFER[static.ARQ_N_FRAME] = bytes(data_in)
# - ------------------------- ARQ BURST CHECKER
# run only if we recieved all ARQ FRAMES per ARQ BURST
if static.ARQ_RX_BURST_BUFFER.count(None) == 1: #count nones
logging.info("ARQ | TX | BURST ACK")
#BUILDING ACK FRAME FOR BURST -----------------------------------------------
ack_payload = b'BURST_ACK'
ack_payload = b'ACK'
ack_frame = b'<' + ack_payload # < = 60
#TRANSMIT ACK FRAME FOR BURST-----------------------------------------------
modem.transmit_arq_ack(ack_frame)
modem.transmit_signalling(ack_frame)
static.CHANNEL_STATE = 'RECEIVING_DATA'
#TRANSMIT_ARQ_ACK_THREAD = threading.Thread(target=modem.transmit_arq_ack, args=[ack_frame], name="TRANSMIT_ARQ_BURST")
#TRANSMIT_ARQ_ACK_THREAD.start()
#while static.ARQ_STATE == 'SENDING_ACK':
# pass
#clear burst buffer
static.ARQ_RX_BURST_BUFFER = []
@ -107,23 +115,22 @@ def data_received(data_in):
frame_number = frame_number.to_bytes(2, byteorder='big')
missing_frames += frame_number
logging.warning("ARQ | TX | RPT ARQ FRAMES [" + str(missing_frames) + "]")
logging.warning("ARQ | TX | RPT ARQ FRAMES [" + str(missing_frames) + "] [BER."+str(static.BER)+"]")
#BUILDING RPT FRAME FOR BURST -----------------------------------------------
rpt_payload = missing_frames
rpt_frame = b'>' + rpt_payload #> = 63
rpt_frame = b'>' + rpt_payload #> = 63 --> 62?!?!?!?!
#TRANSMIT RPT FRAME FOR BURST-----------------------------------------------
modem.transmit_arq_ack(rpt_frame)
modem.transmit_signalling(rpt_frame)
static.CHANNEL_STATE = 'RECEIVING_DATA'
# ---------------------------- FRAME MACHINE
# --------------- IF LIST NOT CONTAINS "None" stick everything together
complete_data_frame = bytearray()
#print("static.ARQ_RX_FRAME_BUFFER.count(None)" + str(static.ARQ_RX_FRAME_BUFFER.count(None)))
if static.ARQ_RX_FRAME_BUFFER.count(None) == 1: ## 1 because position 0 of list will alaways be None in our case
#print("DECODING FRAME!")
logging.debug("DECODING FRAME!")
for frame in range(1,len(static.ARQ_RX_FRAME_BUFFER)):
raw_arq_frame = static.ARQ_RX_FRAME_BUFFER[frame]
arq_frame_payload = raw_arq_frame[8:]
@ -135,18 +142,23 @@ def data_received(data_in):
arq_frame_payload = arq_frame_payload.split(static.FRAME_BOF)
arq_frame_payload = arq_frame_payload[1]
logging.debug("BOF")
# -------- DETECT IF WE RECEIVED A FRAME FOOTER THEN SAVE DATA TO GLOBALS
if arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF):
# we need to check for at least one xFF. Sometimes we have only one xFF, because the second one is in the next frame
if arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF) or arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF[:-1]):
static.ARQ_FRAME_EOF_RECEIVED = True
arq_frame_payload = arq_frame_payload.split(static.FRAME_EOF)
arq_frame_payload = arq_frame_payload[0]
if arq_frame_payload.rstrip(b'\x00').endswith(static.FRAME_EOF[:-1]):
arq_frame_payload = arq_frame_payload.split(static.FRAME_EOF[:-1])
arq_frame_payload = arq_frame_payload[0]
else:
arq_frame_payload = arq_frame_payload.split(static.FRAME_EOF)
arq_frame_payload = arq_frame_payload[0]
logging.debug("EOF")
# --------- AFTER WE SEPARATED BOF AND EOF, STICK EVERYTHING TOGETHER
complete_data_frame = complete_data_frame + arq_frame_payload
logging.debug(complete_data_frame)
#check if Begin of Frame BOF and End of Frame EOF are received, then start calculating CRC and sticking everything together
if static.ARQ_FRAME_BOF_RECEIVED == True and static.ARQ_FRAME_EOF_RECEIVED == True:
@ -155,8 +167,7 @@ def data_received(data_in):
#IF THE FRAME PAYLOAD CRC IS EQUAL TO THE FRAME CRC WHICH IS KNOWN FROM THE HEADER --> SUCCESS
if frame_payload_crc == static.FRAME_CRC:
#logging.info("ARQ | RX | DATA FRAME SUCESSFULLY RECEIVED! - TIME TO PARTY")
logging.log(25,"ARQ | RX | DATA FRAME SUCESSFULLY RECEIVED! :-)")
logging.log(25,"ARQ | RX | DATA FRAME SUCESSFULLY RECEIVED! :-) ")
#append received frame to RX_BUFFER
static.RX_BUFFER.append(complete_data_frame)
@ -167,33 +178,50 @@ def data_received(data_in):
#TRANSMIT ACK FRAME FOR BURST-----------------------------------------------
time.sleep(1) #0.5
logging.info("ARQ | TX | ARQ DATA FRAME ACK [" + str(static.FRAME_CRC.hex()) +"]")
logging.info("ARQ | TX | ARQ DATA FRAME ACK [" + str(static.FRAME_CRC.hex()) +"] [BER."+str(static.BER)+"]")
modem.transmit_arq_ack(ack_frame)
modem.transmit_signalling(ack_frame)
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
# clearing buffers and resetting counters
static.ARQ_RX_BURST_BUFFER = []
static.ARQ_RX_FRAME_BUFFER = []
static.ARQ_FRAME_BOF_RECEIVED = False
static.ARQ_FRAME_EOF_RECEIVED = False
static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME = 0
static.TNC_STATE = b'IDLE'
#print("----------------------------------------------------------------")
#print(static.RX_BUFFER[-1])
#print("----------------------------------------------------------------")
static.TNC_STATE = 'IDLE'
static.ARQ_SEND_KEEP_ALIVE = True
static.ARQ_READY_FOR_DATA = False
logging.info("DATA ["+ str(static.MYCALLSIGN, 'utf-8') + "]<< >>["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
else:
print("ARQ_FRAME_BOF_RECEIVED " + str(static.ARQ_FRAME_BOF_RECEIVED))
print("ARQ_FRAME_EOF_RECEIVED " + str(static.ARQ_FRAME_EOF_RECEIVED))
logging.error("ARQ | RX | DATA FRAME NOT SUCESSFULLY RECEIVED!")
static.TNC_STATE = b'IDLE'
static.ARQ_STATE = 'IDLE'
static.ARQ_SEND_KEEP_ALIVE = True
static.ARQ_READY_FOR_DATA = False
logging.info("DATA ["+ str(static.MYCALLSIGN, 'utf-8') + "]<< >>["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
async def arq_transmit(data_out):
# we need to set payload per frame manually at this point. maybe we can do this more dynmic.
if static.ARQ_DATA_CHANNEL_MODE == 10:
payload_per_frame = 512-2
elif static.ARQ_DATA_CHANNEL_MODE == 11:
payload_per_frame = 256-2
elif static.ARQ_DATA_CHANNEL_MODE == 12:
payload_per_frame = 128-2
elif static.ARQ_DATA_CHANNEL_MODE == 14:
payload_per_frame = 16-2
else:
payload_per_frame = 16-2
static.ARQ_PAYLOAD_PER_FRAME = payload_per_frame - 8
def transmit(data_out):
#print("static.ARQ_DATA_PAYLOAD_PER_FRAME " + str(static.FREEDV_DATA_PAYLOAD_PER_FRAME))
#print("static.ARQ_PAYLOAD_PER_FRAME " + str(static.ARQ_PAYLOAD_PER_FRAME))
static.ARQ_PAYLOAD_PER_FRAME = static.FREEDV_DATA_PAYLOAD_PER_FRAME - 8
frame_header_length = 6 #4
n_arq_frames_per_data_frame = (len(data_out)+frame_header_length) // static.ARQ_PAYLOAD_PER_FRAME + ((len(data_out)+frame_header_length) % static.ARQ_PAYLOAD_PER_FRAME > 0)
@ -208,10 +236,9 @@ def transmit(data_out):
static.TX_BUFFER = [data_out[i:i+static.ARQ_PAYLOAD_PER_FRAME] for i in range(0, len(data_out), static.ARQ_PAYLOAD_PER_FRAME)]
static.TX_BUFFER_SIZE = len(static.TX_BUFFER)
logging.info("ARQ | TX | DATA FRAME --- BYTES: " + str(len(data_out)) + " ARQ FRAMES: " + str(static.TX_BUFFER_SIZE))
logging.info("ARQ | TX | M:" + str(static.ARQ_DATA_CHANNEL_MODE) + " | DATA FRAME --- BYTES: " + str(len(data_out)) + " ARQ FRAMES: " + str(static.TX_BUFFER_SIZE))
# --------------------------------------------- THIS IS THE MAIN LOOP-----------------------------------------------------------------
static.ARQ_N_SENT_FRAMES = 0 # SET N SENT FRAMES TO 0 FOR A NEW SENDING CYCLE
while static.ARQ_N_SENT_FRAMES <= static.TX_BUFFER_SIZE:
@ -238,25 +265,37 @@ def transmit(data_out):
for static.TX_N_RETRIES in range(static.TX_N_MAX_RETRIES):
if static.ARQ_N_SENT_FRAMES + 1 <= static.TX_BUFFER_SIZE:
logging.log(24, "ARQ | TX | F:[" + str(static.ARQ_N_SENT_FRAMES+1) + "-" + str(static.ARQ_N_SENT_FRAMES + static.ARQ_TX_N_FRAMES_PER_BURST) + "] | T:[" + str(static.ARQ_N_SENT_FRAMES) + "/" + str(static.TX_BUFFER_SIZE) + "] [" + str(int(static.ARQ_N_SENT_FRAMES/(static.TX_BUFFER_SIZE)*100)).zfill(3) + "%] | A:[" + str(static.TX_N_RETRIES+1) + "/" + str(static.TX_N_MAX_RETRIES) + "]")
logging.log(24, "ARQ | TX | M:" + str(static.ARQ_DATA_CHANNEL_MODE) + " | F:[" + str(static.ARQ_N_SENT_FRAMES+1) + "-" + str(static.ARQ_N_SENT_FRAMES + static.ARQ_TX_N_FRAMES_PER_BURST) + "] | T:[" + str(static.ARQ_N_SENT_FRAMES) + "/" + str(static.TX_BUFFER_SIZE) + "] [" + str(int(static.ARQ_N_SENT_FRAMES/(static.TX_BUFFER_SIZE)*100)).zfill(3) + "%] | A:[" + str(static.TX_N_RETRIES+1) + "/" + str(static.TX_N_MAX_RETRIES) + "] [BER."+str(static.BER)+"]")
# lets start a thread to transmit nonblocking
TRANSMIT_ARQ_BURST_THREAD = threading.Thread(target=modem.transmit_arq_burst, name="TRANSMIT_ARQ_BURST")
TRANSMIT_ARQ_BURST_THREAD.start()
#TRANSMIT_ARQ_BURST_THREAD = threading.Thread(target=modem.transmit_arq_burst, name="TRANSMIT_ARQ_BURST")
#TRANSMIT_ARQ_BURST_THREAD.start()
#asyncio.run(modem.transmit_arq_burst())
await modem.transmit_arq_burst()
# lets wait during sending. After sending is finished we will continue
while static.ARQ_STATE == 'SENDING_DATA':
while static.CHANNEL_STATE == 'SENDING_DATA':
time.sleep(0.01)
# --------------------------- START TIMER FOR WAITING FOR ACK ---> IF TIMEOUT REACHED, ACK_TIMEOUT = 1
logging.debug("ARQ | RX | WAITING FOR BURST ACK")
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
helpers.arq_reset_timeout(False)
helpers.arq_reset_ack(False)
#print(static.ARQ_RX_ACK_TIMEOUT)
#print("timeout......?!?")
#asyncio.ensure_future(helpers.set_variable_after_timeout())
##################task = asyncio.create_task(helpers.set_after_timeout())
#async with trio.open_nursery() as nursery:
# nursery.start_soon(helpers.set_after_timeout())
#print("TIMEOUT glaube gestartet...")
#print(task)
#print(static.ARQ_RX_ACK_TIMEOUT)
acktimer = threading.Timer(static.ARQ_RX_ACK_TIMEOUT_SECONDS, helpers.arq_ack_timeout)
acktimer.start()
@ -278,15 +317,14 @@ def transmit(data_out):
logging.warning("ARQ | RX | REQUEST FOR REPEATING FRAMES: " + str(static.ARQ_RPT_FRAMES))
logging.warning("ARQ | TX | SENDING REQUESTED FRAMES: " + str(static.ARQ_RPT_FRAMES))
TRANSMIT_ARQ_BURST_THREAD = threading.Thread(target=modem.transmit_arq_burst, name="TRANSMIT_ARQ_BURST")
TRANSMIT_ARQ_BURST_THREAD.start()
#TRANSMIT_ARQ_BURST_THREAD = threading.Thread(target=modem.transmit_arq_burst, name="TRANSMIT_ARQ_BURST")
#TRANSMIT_ARQ_BURST_THREAD.start()
#asyncio.run(modem.transmit_arq_burst())
await modem.transmit_arq_burst()
# lets wait during sending. After sending is finished we will continue
while static.ARQ_STATE == 'SENDING_DATA':
time.sleep(0.01)
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
helpers.arq_reset_timeout(False)
helpers.arq_reset_ack(False)
@ -356,7 +394,7 @@ def transmit(data_out):
frametimer = threading.Timer(static.ARQ_RX_FRAME_TIMEOUT_SECONDS, helpers.arq_frame_timeout)
frametimer.start()
static.ARQ_STATE = 'RECEIVING_SIGNALLING'
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
# wait for frame ACK if we processed the last frame/burst
while static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_FRAME_TIMEOUT == False and static.ARQ_N_SENT_FRAMES == static.TX_BUFFER_SIZE:
@ -367,16 +405,21 @@ def transmit(data_out):
# ----------- if no ACK received and out of retries.....stop frame sending
if static.ARQ_ACK_RECEIVED == False and static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_ACK_TIMEOUT == True:
logging.error("ARQ | TX | NO BURST OR FRAME ACK RECEIVED | DATA SHOULD BE RESEND!")
logging.error("ARQ | TX | NO ACK RECEIVED | DATA SHOULD BE RESEND!")
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
logging.error("------------------------------------------------------")
break
#-------------------------BREAK TX BUFFER LOOP IF ALL PACKETS HAVE BEEN SENT AND WE GOT A FRAME ACK
elif static.ARQ_N_SENT_FRAMES == static.TX_BUFFER_SIZE and static.ARQ_FRAME_ACK_RECEIVED == True:
logging.log(25,"ARQ | RX | FRAME ACK RECEIVED - DATA TRANSMITTED! :-)")
logging.log(25,"------------------------------------------------------")
break
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
break
elif static.ARQ_FRAME_ACK_RECEIVED == False and static.ARQ_RX_FRAME_TIMEOUT == True:
logging.error("ARQ | TX | NO FRAME ACK RECEIVED")
static.CHANNEL_STATE = 'RECEIVING_DATA'
break
else:
logging.debug("NO MATCHING RULE AT THE END")
@ -396,13 +439,16 @@ def transmit(data_out):
logging.info("ARQ | TX | BUFFER EMPTY")
helpers.arq_reset_frame_machine()
await asyncio.sleep(2)
logging.info("DATA ["+ str(static.MYCALLSIGN, 'utf-8') + "]<< >>["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
arq_transmit_keep_alive()
# BURST MACHINE TO DEFINE N BURSTS PER FRAME ---> LATER WE CAN USE CHANNEL MESSUREMENT TO SET FRAMES PER BURST
def get_n_frames_per_burst():
#n_frames_per_burst = randrange(1,10)
n_frames_per_burst = 5
n_frames_per_burst = 1
return n_frames_per_burst
@ -427,4 +473,222 @@ def burst_rpt_received(data_in):
if not missing_area[i:i+2].endswith(b'\x00\x00'):
missing = missing_area[i:i+2]
static.ARQ_RPT_FRAMES.insert(0,missing)
#############################################################################################################
# ARQ CONNECT HANDLER
#############################################################################################################
async def arq_connect():
static.ARQ_STATE = 'CONNECTING'
logging.info("CONN ["+ str(static.MYCALLSIGN, 'utf-8') + "]-> <-["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
frame_type = bytes([220])
connection_frame = bytearray(14)
connection_frame[:1] = frame_type
connection_frame[1:2] = static.DXCALLSIGN_CRC8
connection_frame[2:3] = static.MYCALLSIGN_CRC8
connection_frame[3:9] = static.MYCALLSIGN # we need the full CALLSIGN, if we are doing a connect without ping and cq
#connection_frame[12:13] = bytes([static.ARQ_DATA_CHANNEL_MODE])
#connection_frame[13:14] = bytes([static.ARQ_READY_FOR_DATA])
#print(connection_frame)
modem.transmit_signalling(connection_frame)
def arq_received_connect(data_in):
static.ARQ_STATE = 'CONNECTING'
static.DXCALLSIGN = bytes(data_in[3:9]).rstrip(b'\x00')
static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN)
#static.FREEDV_DATA_MODE = int.from_bytes(bytes(data_in[12:13]), "big")
logging.info("CONN ["+ str(static.MYCALLSIGN, 'utf-8') + "]-> <-["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
frame_type = bytes([221])
connection_frame = bytearray(14)
connection_frame[:1] = frame_type
connection_frame[1:2] = static.DXCALLSIGN_CRC8
connection_frame[2:3] = static.MYCALLSIGN_CRC8
#connection_frame[12:13] = bytes([static.FREEDV_DATA_MODE])
#send ACK for connect
modem.transmit_signalling(connection_frame)
def arq_transmit_keep_alive():
frame_type = bytes([221])
connection_frame = bytearray(14)
connection_frame[:1] = frame_type
connection_frame[1:2] = static.DXCALLSIGN_CRC8
connection_frame[2:3] = static.MYCALLSIGN_CRC8
modem.transmit_signalling(connection_frame)
def arq_received_connect_keep_alive(data_in):
if static.ARQ_SEND_KEEP_ALIVE == True and (static.ARQ_STATE == 'CONNECTING' or static.ARQ_STATE == 'CONNECTED'):
logging.info("CONN ["+ str(static.MYCALLSIGN, 'utf-8') + "] >|< ["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
static.ARQ_STATE = 'CONNECTED'
frame_type = bytes([221])
connection_frame = bytearray(14)
connection_frame[:1] = frame_type
connection_frame[1:2] = static.DXCALLSIGN_CRC8
connection_frame[2:3] = static.MYCALLSIGN_CRC8
connection_frame[12:13] = bytes([static.ARQ_DATA_CHANNEL_MODE])
connection_frame[13:14] = bytes([0])
#lets wait a second before sending
acktimer = threading.Timer(1.0, modem.transmit_signalling, args=[connection_frame])
acktimer.start()
else:
pass
#print("keep alive = False")
#############################################################################################################
# ARQ DATA CHANNEL HANDLER
#############################################################################################################
async def arq_open_data_channel():
# we need to wait until the last keep alive has been sent.
logging.info("DATA ["+ str(static.MYCALLSIGN, 'utf-8') + "]>> <<["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
static.ARQ_SEND_KEEP_ALIVE = False
static.ARQ_DATA_CHANNEL_MODE = 12
while static.CHANNEL_STATE == 'SENDING_SIGNALLING':
time.sleep(0.01)
#print("wir warten 2 sekunden...")
await asyncio.sleep(2)
connection_frame = bytearray(14)
connection_frame[:1] = bytes([225])
connection_frame[1:2] = static.DXCALLSIGN_CRC8
connection_frame[2:3] = static.MYCALLSIGN_CRC8
connection_frame[12:13] = bytes([static.ARQ_DATA_CHANNEL_MODE])
#connection_frame[13:14] = bytes([225])
while static.CHANNEL_STATE == 'SENDING_SIGNALLING':
time.sleep(0.01)
modem.transmit_signalling(connection_frame)
def arq_received_data_channel_opener(data_in):
logging.info("DATA ["+ str(static.MYCALLSIGN, 'utf-8') + "]>> <<["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
static.ARQ_SEND_KEEP_ALIVE = False
static.ARQ_DATA_CHANNEL_MODE = int.from_bytes(bytes(data_in[12:13]), "big")
#static.ARQ_READY_FOR_DATA = int.from_bytes(bytes(data_in[13:14]), "big")
connection_frame = bytearray(14)
connection_frame[:1] = bytes([226])
connection_frame[1:2] = static.DXCALLSIGN_CRC8
connection_frame[2:3] = static.MYCALLSIGN_CRC8
connection_frame[12:13] = bytes([static.ARQ_DATA_CHANNEL_MODE])
#connection_frame[13:14] = bytes([226])
while static.CHANNEL_STATE == 'SENDING_SIGNALLING':
time.sleep(0.01)
modem.transmit_signalling(connection_frame)
#print("waiting for data....")
static.CHANNEL_STATE = 'RECEIVING_DATA'
# einen timeout benötigen wir auch noch....
# und ab hier geht es dann in den "RECEIVING_DATA" mode....
def arq_received_channel_is_open(data_in):
static.ARQ_SEND_KEEP_ALIVE == False
if static.ARQ_DATA_CHANNEL_MODE == int.from_bytes(bytes(data_in[12:13]), "big"):
logging.info("DATA ["+ str(static.MYCALLSIGN, 'utf-8') + "]>>|<<["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
time.sleep(1)
static.ARQ_READY_FOR_DATA = True
#static.CHANNEL_STATE = 'RECEIVING_DATA':
#############################################################################################################
# DISCONNECT HANDLER
#############################################################################################################
async def arq_disconnect():
# we need to create a "force ignore all" so we don't receive frames any more... Then we don't need a timer
static.ARQ_SEND_KEEP_ALIVE == False
static.ARQ_STATE = 'DISCONNECTING'
logging.info("DISC ["+ str(static.MYCALLSIGN, 'utf-8') + "] <-> ["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
frame_type = bytes([222])
disconnection_frame = frame_type + static.MYCALLSIGN
while static.CHANNEL_STATE == 'SENDING_SIGNALLING':
time.sleep(0.01)
await asyncio.sleep(5)
modem.transmit_signalling(disconnection_frame)
logging.info("DISC ["+ str(static.MYCALLSIGN, 'utf-8') + "]< X >["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
static.ARQ_STATE = 'IDLE'
static.DXCALLSIGN = b''
static.DXCALLSIGN_CRC8 = b''
def arq_disconnect_received(data_in):
static.ARQ_STATE = 'DISCONNECTED'
logging.info("DISC ["+ str(static.MYCALLSIGN, 'utf-8') + "]< X >["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
static.ARQ_STATE = 'DISCONNECTED'
static.TNC_STATE = 'IDLE'
static.DXCALLSIGN = b''
static.DXCALLSIGN_CRC8 = b''
#############################################################################################################
# PING HANDLER
#############################################################################################################
def transmit_ping(callsign):
static.DXCALLSIGN = bytes(callsign, 'utf-8')
logging.info("PING ["+ str(static.MYCALLSIGN, 'utf-8') + "] >>> [" + str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
frame_type = bytes([210])
ping_payload = b'PING'
ping_frame = frame_type + ping_payload
# wait while sending....
while static.CHANNEL_STATE == 'SENDING_SIGNALLING':
time.sleep(0.01)
modem.transmit_signalling(ping_frame)
def received_ping(data_in):
logging.info("PING ["+ str(static.MYCALLSIGN, 'utf-8') + "] <<< ["+ str(static.DXCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
frame_type = bytes([211])
ping_payload = b'PING_ACK'
ping_frame = frame_type + static.MYCALLSIGN + ping_payload
# wait while sending....
while static.CHANNEL_STATE == 'SENDING_SIGNALLING':
time.sleep(0.01)
modem.transmit_signalling(ping_frame)
def received_ping_ack(data_in):
dxcallsign = data_in[1:6]
static.DXCALLSIGN = bytes(dxcallsign)
static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN)
logging.info("PING [" + str(static.DXCALLSIGN, 'utf-8') + "] >|< [" + str(static.MYCALLSIGN, 'utf-8') + "] [BER."+str(static.BER)+"]")
static.TNC_STATE = 'IDLE'
#############################################################################################################
# BROADCAST HANDLER
#############################################################################################################
async def transmit_cq():
logging.info("CQ CQ CQ")
frame_type = bytes([200])
cq_frame = frame_type + static.MYCALLSIGN
modem.transmit_signalling(cq_frame)
async def transmit_beacon():
logging.info("BEACON")
frame_type = bytes([230])
print(frame_type)
beacon_frame = frame_type + static.MYCALLSIGN
while static.TNC_STATE == 'BEACON':
await asyncio.sleep(60)
modem.transmit_signalling(beacon_frame)

16
fec.py Normal file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import static
import modem
#modem = modem.RF()
import helpers
def transmit_cq():
cq_frame = b'CQCQCQ'
modem.RF.transmit_signalling(cq_frame)
pass

132
hamlib.py Normal file
View file

@ -0,0 +1,132 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
# Change this path to match your "make install" path
sys.path.append('/usr/local/lib/python3.8/site-packages')
## Uncomment to run this script from an in-tree build (or adjust to the
## build directory) without installing the bindings.
#sys.path.append ('.')
#sys.path.append ('.libs')
import Hamlib
def StartUp():
"""Simple script to test the Hamlib.py module with Python3."""
print("%s: Python %s; %s\n" \
% (sys.argv[0], sys.version.split()[0], Hamlib.cvar.hamlib_version))
Hamlib.rig_set_debug(Hamlib.RIG_DEBUG_NONE)
# Init RIG_MODEL_DUMMY
my_rig = Hamlib.Rig(Hamlib.RIG_MODEL_DUMMY)
my_rig.set_conf("rig_pathname", "/dev/Rig")
my_rig.set_conf("retry", "5")
my_rig.open ()
print("SET PTT------------------------------------------")
#Supported types are RIG (CAT command), DTR, RTS, PARALLEL, NONE, overriding PTT type defined in the rig's backend.
#Some side effects of this command are that when type is set to DTR, read PTT state comes from the Hamlib frontend, not read from the radio. When set to NONE, PTT state cannot be read or set even if rig backend supports reading/setting PTT status from the rig.
my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_DTR,1)
print(my_rig.get_ptt())
rpath = my_rig.get_conf("rig_pathname")
retry = my_rig.get_conf("retry")
print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status))
print("get_conf:\t\tpath = %s, retry = %s" \
% (rpath, retry))
my_rig.set_freq(Hamlib.RIG_VFO_B, 5700000000)
my_rig.set_vfo(Hamlib.RIG_VFO_B)
print("freq:\t\t\t%s" % my_rig.get_freq())
my_rig.set_freq(Hamlib.RIG_VFO_A, 145550000)
(mode, width) = my_rig.get_mode()
print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width))
my_rig.set_mode(Hamlib.RIG_MODE_CW)
(mode, width) = my_rig.get_mode()
print("mode:\t\t\t%s\nbandwidth:\t\t%s" % (Hamlib.rig_strrmode(mode), width))
print("Backend copyright:\t%s" % my_rig.caps.copyright)
print("Model:\t\t\t%s" % my_rig.caps.model_name)
print("Manufacturer:\t\t%s" % my_rig.caps.mfg_name)
print("Backend version:\t%s" % my_rig.caps.version)
print("Backend status:\t\t%s" % Hamlib.rig_strstatus(my_rig.caps.status))
print("Rig info:\t\t%s" % my_rig.get_info())
my_rig.set_level("VOXDELAY", 1)
print("VOX delay:\t\t%s" % my_rig.get_level_i("VOXDELAY"))
my_rig.set_level(Hamlib.RIG_LEVEL_VOXDELAY, 5)
print("VOX delay:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_VOXDELAY))
af = 12.34
print("Setting AF to %0.2f...." % (af))
my_rig.set_level("AF", af)
print("status:\t\t\t%s - %s" % (my_rig.error_status,
Hamlib.rigerror(my_rig.error_status)))
print("AF level:\t\t%0.2f" % my_rig.get_level_f(Hamlib.RIG_LEVEL_AF))
print("strength:\t\t%s" % my_rig.get_level_i(Hamlib.RIG_LEVEL_STRENGTH))
print("status:\t\t\t%s" % my_rig.error_status)
print("status(str):\t\t%s" % Hamlib.rigerror(my_rig.error_status))
chan = Hamlib.channel(Hamlib.RIG_VFO_B)
my_rig.get_channel(chan,1)
print("get_channel status:\t%s" % my_rig.error_status)
print("VFO:\t\t\t%s, %s" % (Hamlib.rig_strvfo(chan.vfo), chan.freq))
print("Attenuators:\t\t%s" % my_rig.caps.attenuator)
print("\nSending Morse, '73'")
my_rig.send_morse(Hamlib.RIG_VFO_A, "73")
my_rig.close()
print("\nSome static functions:")
err, lon1, lat1 = Hamlib.locator2longlat("IN98XC")
err, lon2, lat2 = Hamlib.locator2longlat("DM33DX")
err, loc1 = Hamlib.longlat2locator(lon1, lat1, 3)
err, loc2 = Hamlib.longlat2locator(lon2, lat2, 3)
print("Loc1:\t\tIN98XC -> %9.4f, %9.4f -> %s" % (lon1, lat1, loc1))
print("Loc2:\t\tDM33DX -> %9.4f, %9.4f -> %s" % (lon2, lat2, loc2))
err, dist, az = Hamlib.qrb(lon1, lat1, lon2, lat2)
longpath = Hamlib.distance_long_path(dist)
print("Distance:\t%.3f km, azimuth %.2f, long path:\t%.3f km" \
% (dist, az, longpath))
# dec2dms expects values from 180 to -180
# sw is 1 when deg is negative (west or south) as 0 cannot be signed
err, deg1, mins1, sec1, sw1 = Hamlib.dec2dms(lon1)
err, deg2, mins2, sec2, sw2 = Hamlib.dec2dms(lat1)
lon3 = Hamlib.dms2dec(deg1, mins1, sec1, sw1)
lat3 = Hamlib.dms2dec(deg2, mins2, sec2, sw2)
print('Longitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \
% (lon1, deg1, mins1, sec1, ('W' if sw1 else 'E'), lon3))
print('Latitude:\t%4.4f, %4d° %2d\' %2d" %1s\trecoded: %9.4f' \
% (lat1, deg2, mins2, sec2, ('S' if sw2 else 'N'), lat3))
if __name__ == '__main__':
StartUp()

View file

@ -11,6 +11,9 @@ import threading
import logging
import crcengine
import pyaudio
import asyncio
import data_handler
import static
@ -29,19 +32,36 @@ def get_crc_16(data):
crc_data = crc_algorithm(data)
crc_data = crc_data.to_bytes(2, byteorder='big')
return crc_data
async def set_after_timeout():
while True:
logging.info("HALLO?!?")
time.sleep(1)
print("HALLOIOIOIOIOIOI")
static.ARQ_RX_ACK_TIMEOUT = True
await asyncio.sleep(1.1)
#await asyncio.sleep(timeout)
#vars()[variable] = value
def arq_disconnect_timeout():
static.ARQ_WAIT_FOR_DISCONNECT = True
logging.debug("ARQ_WAIT_FOR_DISCONNECT")
def arq_ack_timeout():
if static.ARQ_STATE == 'RECEIVING_SIGNALLING':
if static.CHANNEL_STATE == 'RECEIVING_SIGNALLING':
static.ARQ_RX_ACK_TIMEOUT = True
logging.debug("ARQ_RX_ACK_TIMEOUT")
def arq_rpt_timeout():
if static.ARQ_STATE == 'RECEIVING_SIGNALLING':
if static.CHANNEL_STATE == 'RECEIVING_SIGNALLING':
static.ARQ_RX_RPT_TIMEOUT = True
logging.debug("ARQ_RX_RPT_TIMEOUT")
def arq_frame_timeout():
if static.ARQ_STATE == 'RECEIVING_SIGNALLING':
if static.CHANNEL_STATE == 'RECEIVING_SIGNALLING':
static.ARQ_RX_FRAME_TIMEOUT = True
logging.debug("ARQ_RX_FRAME_TIMEOUT")
@ -61,9 +81,16 @@ def arq_reset_frame_machine():
static.TX_N_RETRIES = 0
static.ARQ_N_SENT_FRAMES = 0
static.ARQ_TX_N_FRAMES_PER_BURST = 0
static.TNC_STATE = b'IDLE'
static.TNC_STATE = b'IDLE'
static.ARQ_SEND_KEEP_ALIVE = True
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
static.ARQ_READY_FOR_DATA = False
#start sending keep alive after some seconds
#acktimer = threading.Timer(3.0, data_handler.arq_connect)
#acktimer.start()
#await asyncio.sleep(2)
#modem.transmit_arq_connect()
def setup_logging():
logging.basicConfig(format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s', datefmt='%H:%M:%S', level=logging.INFO)
@ -86,13 +113,3 @@ def setup_logging():
#'ERROR' : 31, # red
#'CRITICAL': 41, # white on red bg
def list_audio_devices():
p = pyaudio.PyAudio()
devices = []
for x in range(0, p.get_device_count()):
devices.append(f"{x} - {p.get_device_info_by_index(x)['name']}")
for line in devices:
print(line)

17
main.py
View file

@ -12,25 +12,16 @@ import argparse
import logging
import threading
import static
import helpers
def client(ip, port, message):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((ip, port))
sock.sendall(bytes(message, 'ascii'))
response = str(sock.recv(1024), 'ascii')
print("Received: {}".format(response))
if __name__ == '__main__':
# config logging
helpers.setup_logging()
# list audio devices
helpers.list_audio_devices()
#--------------------------------------------GET PARAMETER INPUTS
@ -38,17 +29,17 @@ if __name__ == '__main__':
parser.add_argument('--rx', dest="audio_input_device", default=0, help="sound card for listening.", type=int)
parser.add_argument('--tx', dest="audio_output_device", default=0, help="sound card for transmitting.", type=int)
parser.add_argument('--port', dest="socket_port", default=3000, help="Set the port, the socket is listening on.", type=int)
parser.add_argument('--mode', dest="freedv_data_mode", default=12, help="Set the mode.", type=int)
#parser.add_argument('--mode', dest="freedv_data_mode", default=12, help="Set the mode.", type=int)
args = parser.parse_args()
static.FREEDV_DATA_MODE = args.freedv_data_mode
#static.FREEDV_DATA_MODE = args.freedv_data_mode
static.AUDIO_INPUT_DEVICE = args.audio_input_device
static.AUDIO_OUTPUT_DEVICE = args.audio_output_device
static.PORT = args.socket_port
#--------------------------------------------START CMD SERVER
import sock # we need to wait until we got all parameters from argparse
import sock # we need to wait until we got all parameters from argparse first before loading sock
cmd_server_thread = threading.Thread(target=sock.start_cmd_socket, name="cmd server")
cmd_server_thread.start()

268
modem.py
View file

@ -11,6 +11,7 @@ from ctypes import *
import pathlib
import pyaudio
import audioop
import asyncio
#import sys
import logging
import time
@ -18,17 +19,12 @@ import threading
import helpers
import static
import arq
import data_handler
import Hamlib
class RF():
def __init__(self):
@ -59,9 +55,17 @@ class RF():
output_device_index=static.AUDIO_OUTPUT_DEVICE, #static.AUDIO_OUTPUT_DEVICE
)
#--------------------------------------------START DECODER THREAD
FREEDV_DECODER_THREAD = threading.Thread(target=self.receive, args=[static.FREEDV_DATA_MODE,static.FREEDV_SIGNALLING_MODE], name="FREEDV_DECODER_THREAD")
FREEDV_DECODER_THREAD.start()
FREEDV_DECODER_THREAD_10 = threading.Thread(target=self.receive, args=[10], name="FREEDV_DECODER_THREAD")
FREEDV_DECODER_THREAD_10.start()
FREEDV_DECODER_THREAD_11 = threading.Thread(target=self.receive, args=[11], name="FREEDV_DECODER_THREAD")
FREEDV_DECODER_THREAD_11.start()
FREEDV_DECODER_THREAD_12 = threading.Thread(target=self.receive, args=[12], name="FREEDV_DECODER_THREAD")
FREEDV_DECODER_THREAD_12.start()
FREEDV_DECODER_THREAD_14 = threading.Thread(target=self.receive, args=[static.FREEDV_SIGNALLING_MODE], name="FREEDV_DECODER_THREAD")
FREEDV_DECODER_THREAD_14.start()
#--------------------------------------------CONFIGURE HAMLIB
@ -93,9 +97,13 @@ class RF():
self.my_rig.set_ptt(self.hamlib_ptt_type,0)
#--------------------------------------------------------------------------------------------------------
def transmit_arq_ack(self,ack_buffer):
def transmit_signalling(self,ack_buffer):
#print(ack_buffer)
static.ARQ_STATE = 'SENDING_ACK'
#static.ARQ_STATE = 'SENDING_ACK'
state_before_transmit = static.CHANNEL_STATE
static.CHANNEL_STATE = 'SENDING_SIGNALLING'
static.PTT_STATE = True
self.my_rig.set_ptt(self.hamlib_ptt_type,1)
@ -106,10 +114,11 @@ class RF():
payload_per_frame = bytes_per_frame -2
n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv)
n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv) #get n_tx_modem_samples which defines the size of the modulation object
n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(freedv)
mod_out = ctypes.c_short * n_tx_modem_samples
mod_out = mod_out()
mod_out_preamble = ctypes.c_short * (n_tx_modem_samples) #*2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_preamble = ctypes.c_short * n_tx_preamble_modem_samples #*2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_preamble = mod_out_preamble()
buffer = bytearray(payload_per_frame) # use this if CRC16 checksum is required ( DATA1-3)
@ -120,11 +129,7 @@ class RF():
buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer)
preamble_bytes = self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble)
#print(n_tx_modem_samples)
#print(preamble_bytes)
#print(len(mod_out_preamble))
self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble)
self.c_lib.freedv_rawdatatx(freedv,mod_out,data) # modulate DATA and safe it into mod_out pointer
txbuffer = bytearray()
txbuffer += bytes(mod_out_preamble)
@ -137,15 +142,18 @@ class RF():
self.my_rig.set_ptt(self.hamlib_ptt_type,0)
static.PTT_STATE = False
static.ARQ_STATE = 'RECEIVING_DATA'
static.CHANNEL_STATE = state_before_transmit
#static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
#static.ARQ_STATE = 'RECEIVING_DATA'
#--------------------------------------------------------------------------------------------------------
# GET ARQ BURST FRAME VOM BUFFER AND MODULATE IT
def transmit_arq_burst(self):
async def transmit_arq_burst(self):
self.my_rig.set_ptt(self.hamlib_ptt_type,1)
static.PTT_STATE = True
static.ARQ_STATE = 'SENDING_DATA'
state_before_transmit = static.CHANNEL_STATE
static.CHANNEL_STATE = 'SENDING_DATA'
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
freedv = self.c_lib.freedv_open(static.FREEDV_DATA_MODE)
@ -154,17 +162,15 @@ class RF():
n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv)
n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)#*2 #get n_tx_modem_samples which defines the size of the modulation object
n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(freedv)
mod_out = ctypes.c_short * n_tx_modem_samples
mod_out = mod_out()
mod_out_preamble = ctypes.c_short * (3520) #*2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_preamble = ctypes.c_short * n_tx_preamble_modem_samples #*2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_preamble = mod_out_preamble()
preamble = self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble);
#print(n_tx_modem_samples)
#print(preamble)
#print(len(mod_out_preamble))
self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble);
txbuffer = bytearray()
txbuffer += bytes(mod_out_preamble)
@ -246,155 +252,199 @@ class RF():
# -------------- transmit audio
self.stream_tx.write(bytes(txbuffer))
static.ARQ_STATE = 'IDLE'
#static.ARQ_STATE = 'RECEIVING_SIGNALLING'
#static.ARQ_STATE = 'IDLE'
#static.CHANNEL_STATE = state_before_transmit
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
static.PTT_STATE = False
self.my_rig.set_ptt(self.hamlib_ptt_type,0)
#--------------------------------------------------------------------------------------------------------
def receive(self,data_mode,signalling_mode):
def receive(self,mode):
force = True
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
freedv = self.c_lib.freedv_open(mode)
bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv)/8)
if mode == static.FREEDV_SIGNALLING_MODE:
static.FREEDV_SIGNALLING_BYTES_PER_FRAME = bytes_per_frame
static.FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = bytes_per_frame - 2
self.c_lib.freedv_set_frames_per_burst(freedv, 1);
freedv_data = self.c_lib.freedv_open(data_mode)
freedv_signalling = self.c_lib.freedv_open(signalling_mode)
elif mode == static.ARQ_DATA_CHANNEL_MODE:
static.FREEDV_DATA_BYTES_PER_FRAME = bytes_per_frame
static.FREEDV_DATA_PAYLOAD_PER_FRAME = bytes_per_frame - 2
self.c_lib.freedv_set_frames_per_burst(freedv, 0);
else:
pass
bytes_out = (ctypes.c_ubyte * bytes_per_frame)
bytes_out = bytes_out() #get pointer to bytes_out
static.FREEDV_DATA_BYTES_PER_FRAME = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv_data)/8)
static.FREEDV_DATA_PAYLOAD_PER_FRAME = static.FREEDV_DATA_BYTES_PER_FRAME -2
static.FREEDV_SIGNALLING_BYTES_PER_FRAME = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv_signalling)/8)
static.FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = static.FREEDV_SIGNALLING_BYTES_PER_FRAME -2
data_bytes_out = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME)
data_bytes_out = data_bytes_out() #get pointer to bytes_out
signalling_bytes_out = (ctypes.c_ubyte * static.FREEDV_SIGNALLING_BYTES_PER_FRAME)
signalling_bytes_out = signalling_bytes_out() #get pointer to bytes_out
self.c_lib.freedv_set_frames_per_burst(freedv_data, 0);
self.c_lib.freedv_set_frames_per_burst(freedv_signalling, 1);
# with this we can interrupt receiving
while static.FREEDV_RECEIVE == True:
time.sleep(0.01)
time.sleep(0.05)
# stuck in sync counter
stuck_in_sync_counter = 0
stuck_in_sync_10_counter = 0
#
while static.ARQ_STATE == 'RECEIVING_DATA':
# here we do a buffer cleanup before returning to demod loop
dummy_mod = bytes(self.c_lib.freedv_nin(freedv))
self.c_lib.freedv_rawdatarx(freedv, bytes_out, dummy_mod)
#demod loop
while (static.CHANNEL_STATE == 'RECEIVING_DATA' and static.ARQ_DATA_CHANNEL_MODE == mode) or (static.CHANNEL_STATE == 'RECEIVING_SIGNALLING' and static.FREEDV_SIGNALLING_MODE == mode):
time.sleep(0.01)
# refresh vars, so the correct parameters of the used mode are set
static.FREEDV_DATA_BYTES_PER_FRAME = bytes_per_frame
static.FREEDV_DATA_PAYLOAD_PER_FRAME = bytes_per_frame - 2
nin = self.c_lib.freedv_nin(freedv_data)
nin = self.c_lib.freedv_nin(freedv)
#nin = int(nin*(static.AUDIO_SAMPLE_RATE_RX/static.MODEM_SAMPLE_RATE))
data_in = self.stream_rx.read(nin, exception_on_overflow = False)
#print(audioop.rms(data_in, 2))
#self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), data_bytes_out, data_in] # check if really neccessary
nbytes = self.c_lib.freedv_rawdatarx(freedv_data, data_bytes_out, data_in) # demodulate audio
logging.debug(self.c_lib.freedv_get_rx_status(freedv_data))
nbytes = self.c_lib.freedv_rawdatarx(freedv, bytes_out, data_in) # demodulate audio
#logging.debug(self.c_lib.freedv_get_rx_status(freedv))
#print("listening-" + str(mode) + "-" + str(self.c_lib.freedv_get_rx_status(freedv)))
#-------------STUCK IN SYNC DETECTOR
stuck_in_sync_counter += 1
if self.c_lib.freedv_get_rx_status(freedv_data) == 10:
if self.c_lib.freedv_get_rx_status(freedv) == 10:
stuck_in_sync_10_counter += 1
if stuck_in_sync_counter == 33 and self.c_lib.freedv_get_rx_status(freedv_data) == 10:
if stuck_in_sync_counter == 33 and self.c_lib.freedv_get_rx_status(freedv) == 10:
logging.critical("stuck in sync #1")
self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC
self.c_lib.freedv_set_sync(freedv, 0) #FORCE UNSYNC
stuck_in_sync_counter = 0
stuck_in_sync_10_counter = 0
if stuck_in_sync_counter >= 66 and stuck_in_sync_10_counter >= 2:
logging.critical("stuck in sync #2")
self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC
self.c_lib.freedv_set_sync(freedv, 0) #FORCE UNSYNC
stuck_in_sync_counter = 0
stuck_in_sync_10_counter = 0
#-----------------------------------
if nbytes == static.FREEDV_DATA_BYTES_PER_FRAME:
rxstatus = self.c_lib.freedv_get_rx_status(freedv_data)
logging.debug("DATA-" + str(rxstatus))
if nbytes == bytes_per_frame:##########################################################FREEDV_DATA_BYTES_PER_FRAME
self.calculate_ber(freedv)
# counter reset for stuck in sync counter
stuck_in_sync_counter = 0
stuck_in_sync_10_counter = 0
#
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
frametype = int.from_bytes(bytes(data_bytes_out[:1]), "big")
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
frame = frametype - 10
n_frames_per_burst = int.from_bytes(bytes(data_bytes_out[1:2]), "big")
n_frames_per_burst = int.from_bytes(bytes(bytes_out[1:2]), "big")
#self.c_lib.freedv_set_frames_per_burst(freedv_data, n_frames_per_burst);
if 50 >= frametype >= 10:
if frame != 3 or force == True:
arq.data_received(bytes(data_bytes_out[:-2])) #send payload data to arq checker without CRC16
data_handler.arq_data_received(bytes(bytes_out[:-2])) #send payload data to arq checker without CRC16
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None)))
if static.ARQ_RX_BURST_BUFFER.count(None) <= 1:
logging.debug("FULL BURST BUFFER ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv_data, 0)
self.c_lib.freedv_set_sync(freedv, 0)
else:
logging.critical("---------------------------SIMULATED MISSING FRAME")
force = True
else:
logging.info("MODE: " + str(data_mode) + " DATA: " + str(bytes(data_bytes_out)))
# DO UNSYNC AFTER LAST BURST by checking the frame numbers agains the total frames per burst
if frame == n_frames_per_burst:
logging.debug("LAST FRAME ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv_data, 0) #FORCE UNSYNC
#while static.ARQ_STATE == 'IDLE' or static.ARQ_STATE == 'RECEIVING_SIGNALLING':
while static.ARQ_STATE == 'RECEIVING_SIGNALLING':
time.sleep(0.01)
nin = self.c_lib.freedv_nin(freedv_signalling)
#nin = int(nin*(static.AUDIO_SAMPLE_RATE_RX/static.MODEM_SAMPLE_RATE))
data_in = self.stream_rx.read(nin, exception_on_overflow = False)
#self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), signalling_bytes_out, data_in] # check if really neccessary
nbytes = self.c_lib.freedv_rawdatarx(freedv_signalling, signalling_bytes_out, data_in) # demodulate audio
# CHECK IF FRAME CONTAINS ACK------------------------
if nbytes == static.FREEDV_SIGNALLING_BYTES_PER_FRAME:
#self.c_lib.freedv_set_sync(freedv_signalling, 0)
frametype = int.from_bytes(bytes(signalling_bytes_out[:1]), "big")
# BURST ACK
if frametype == 60:
elif frametype == 60:
logging.debug("ACK RECEIVED....")
arq.burst_ack_received()
data_handler.burst_ack_received()
# FRAME ACK
elif frametype == 61:
logging.debug("FRAME ACK RECEIVED....")
arq.frame_ack_received()
data_handler.frame_ack_received()
# FRAME RPT
elif frametype == 62:
logging.debug("REPEAT REQUEST RECEIVED....")
arq.burst_rpt_received(signalling_bytes_out[:-2])
data_handler.burst_rpt_received(bytes_out[:-2])
# CQ FRAME
elif frametype == 200:
logging.info("CQ RECEIVED....")
# PING FRAME
elif frametype == 210:
logging.debug("PING RECEIVED....")
data_handler.received_ping(bytes_out[:-2])
# PING ACK
elif frametype == 211:
logging.debug("PING ACK RECEIVED....")
data_handler.received_ping_ack(bytes_out[:-2])
# ARQ CONNECT
elif frametype == 220:
logging.debug("ARQ CONNECT RECEIVED....")
data_handler.arq_received_connect(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 221:
logging.debug("ARQ CONNECT ACK RECEIVED / KEEP ALIVE....")
data_handler.arq_received_connect_keep_alive(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 222:
logging.debug("ARQ DISCONNECT RECEIVED")
data_handler.arq_disconnect_received(bytes_out[:-2])
# ARQ FILE TRANSFER RECEIVED!
elif frametype == 225:
logging.debug("ARQ arq_received_data_channel_opener RECEIVED")
data_handler.arq_received_data_channel_opener(bytes_out[:-2])
# ARQ CHANNEL IS OPENED
elif frametype == 226:
logging.debug("ARQ arq_received_channel_is_open RECEIVED")
data_handler.arq_received_channel_is_open(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 230:
logging.debug("BEACON RECEIVED")
else:
logging.debug("OTHER FRAME: " + str(signalling_bytes_out[:-2]))
logging.info("OTHER FRAME: " + str(bytes_out[:-2]))
print(frametype)
rxstatus = self.c_lib.freedv_get_rx_status(freedv_signalling)
logging.debug("ACK-" + str(rxstatus))
# DO UNSYNC AFTER LAST BURST by checking the frame nums agains the total frames per burst
if frame == n_frames_per_burst:
logging.debug("LAST FRAME ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv, 0) #FORCE UNSYNC
rxstatus = self.c_lib.freedv_get_rx_status(freedv)
#logging.info("DATA-" + str(mode) + " " +str(rxstatus))
if rxstatus == 10:
#self.c_lib.freedv_set_sync(freedv_signalling, 0) #FORCE UNSYNC
print("SIGNALLING -SYNC 10- Trigger")
#if nbytes == static.FREEDV_SIGNALLING_BYTES_PER_FRAME or rxstatus == 10:
# self.c_lib.freedv_set_sync(freedv_signalling, 0) #FORCE UNSYNC
self.c_lib.freedv_set_sync(freedv, 0) #FORCE UNSYNC
logging.warning("MODEM | SYNC 10 TRIGGER | M:" + str(mode))
self.calculate_ber(freedv)
def calculate_ber(self,freedv):
Tbits = self.c_lib.freedv_get_total_bits(freedv)
Terrs = self.c_lib.freedv_get_total_bit_errors(freedv)
if Tbits != 0:
ber = (Terrs/Tbits)*100
static.BER = int(ber)
self.c_lib.freedv_set_total_bit_errors(freedv,0)
self.c_lib.freedv_set_total_bits(freedv,0)

113
sock.py
View file

@ -12,45 +12,121 @@ import logging
import time
import static
import arq
import data_handler
import helpers
import fec
import asyncio
class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
encoding = 'utf-8'
data = str(self.request.recv(1024), 'utf-8')
#data = str(self.request.recv(1024), 'utf-8')
data = bytes()
while True:
chunk = self.request.recv(8192)#.strip()
data += chunk
if chunk.endswith(b'\n'):
break
data = data[:-1] # remove b'\n'
data = str(data, 'utf-8')
# SOCKETTEST
# SOCKETTEST ---------------------------------------------------
if data == 'SOCKETTEST':
cur_thread = threading.current_thread()
response = bytes("WELL DONE! YOU ARE ABLE TO COMMUNICATE WITH THE TNC", encoding)
self.request.sendall(response)
# TRANSMIT ARQ MESSAGE
if data.startswith('ARQ:') and static.TNC_STATE == b'IDLE':
logging.info("CMD | NEW ARQ DATA")
static.TNC_STATE = b'BUSY'
arqdata = data.split('ARQ:')
data_out = bytes(arqdata[1], 'utf-8')
# CQ CQ CQ -----------------------------------------------------
if data == 'CQCQCQ':
for i in range(0,3):
data_handler.transmit_cq()
self.request.sendall(bytes("CALLING CQ"))
while static.ARQ_STATE == 'SENDING_SIGNALLING':
time.sleep(0.1)
pass
TRANSMIT_ARQ = threading.Thread(target=arq.transmit, args=[data_out], name="TRANSMIT_ARQ")
TRANSMIT_ARQ.start()
# PING ----------------------------------------------------------
if data.startswith('PING:'):
#send ping frame and wait for ACK
pingcommand = data.split('PING:')
dxcallsign = pingcommand[1]
data_handler.transmit_ping(dxcallsign)
# ARQ CONNECT TO CALLSIGN ----------------------------------------
if data.startswith('ARQ:CONNECT:'):
arqconnectcommand = data.split('ARQ:CONNECT:')
dxcallsign = arqconnectcommand[1]
static.DXCALLSIGN = bytes(dxcallsign, 'utf-8')
static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN)
if static.ARQ_STATE == 'CONNECTED':
# here we could disconnect
pass
if static.TNC_STATE == 'IDLE':
# here we send an "CONNECT FRAME
#ARQ_CONNECT_THREAD = threading.Thread(target=data_handler.arq_connect, name="ARQ_CONNECT")
#ARQ_CONNECT_THREAD.start()
asyncio.run(data_handler.arq_connect())
self.request.sendall(bytes("CONNECTING", encoding))
#data_handler.arq_connect()
# ARQ DISCONNECT FROM CALLSIGN ----------------------------------------
if data == 'ARQ:DISCONNECT':
#ARQ_DISCONNECT_THREAD = threading.Thread(target=data_handler.arq_disconnect, name="ARQ_DISCONNECT")
#ARQ_DISCONNECT_THREAD.start()
asyncio.run(data_handler.arq_disconnect())
self.request.sendall(bytes("DISCONNECTING", encoding))
#data_handler.arq_disconnect()
# TRANSMIT ARQ MESSAGE ------------------------------------------
# wen need to change the TNC_STATE to "CONNECTE" and need to make sure we have a valid callsign and callsign crc8 of the DX station
#print(static.ARQ_STATE)
if data.startswith('ARQ:DATA') and static.ARQ_STATE == 'CONNECTED':
static.ARQ_READY_FOR_DATA = False
logging.info("CMD | NEW ARQ DATA")
self.request.sendall(b'SENDIN ARQ DATA')
asyncio.run(data_handler.arq_open_data_channel())
#data_handler.arq_open_data_channel()
#wait until we set the data mode
# here we need a timeout as well!!!
while static.ARQ_READY_FOR_DATA == False:
time.sleep(0.01)
if static.ARQ_READY_FOR_DATA == True:
#logging.info("CMD | SENDING ARQ DATA")
static.TNC_STATE = 'BUSY'
arqdata = data.split('ARQ:')
data_out = bytes(arqdata[1], 'utf-8')
asyncio.run(data_handler.arq_transmit(data_out))
#data_handler.arq_transmit(data_out)
#TRANSMIT_ARQ = threading.Thread(target=data_handler.transmit, args=[data_out], name="TRANSMIT_ARQ")
#TRANSMIT_ARQ.start()
# SETTINGS AND STATUS
# SETTINGS AND STATUS ---------------------------------------------
if data.startswith('SET:MYCALLSIGN:'):
data = data.split('SET:MYCALLSIGN:')
if bytes(data[1], encoding) == b'':
callsign = data.split('SET:MYCALLSIGN:')
if bytes(callsign[1], encoding) == b'':
self.request.sendall(b'INVALID CALLSIGN')
else:
static.MYCALLSIGN = bytes(data[1], encoding)
static.MYCALLSIGN = bytes(callsign[1], encoding)
static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN)
self.request.sendall(static.MYCALLSIGN)
logging.info("CMD | MYCALLSIGN: " + str(static.MYCALLSIGN))
if data == 'GET:MYCALLSIGN':
self.request.sendall(bytes(static.MYCALLSIGN, encoding))
@ -66,9 +142,6 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
if data == 'GET:PTT_STATE':
self.request.sendall(bytes(str(static.PTT_STATE), encoding))
# ARQ
if data == 'GET:ARQ_STATE':

View file

@ -16,9 +16,9 @@ DXCALLSIGN_CRC8 = b'A'
MYGRID = b''
TNC_STATE = b'IDLE'
PTT_STATE = False
#---------------------------------
@ -51,7 +51,7 @@ PORT = 3000
#PTT control through CM108 GPIO pin
HAMLIB_PTT_TYPE = 'RIG_PTT_NONE'
PTT_STATE = False
@ -62,13 +62,15 @@ HAMLIB_PTT_TYPE = 'RIG_PTT_NONE'
# FreeDV Defaults
FREEDV_RECEIVE = True
FREEDV_DATA_MODE = 10
FREEDV_DATA_MODE = 12
FREEDV_SIGNALLING_MODE = 14
FREEDV_DATA_BYTES_PER_FRAME = 0
FREEDV_DATA_PAYLOAD_PER_FRAME = 0
FREEDV_SIGNALLING_BYTES_PER_FRAME = 0
FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = 0
BER = 0
#---------------------------------
#Audio Defaults
@ -85,7 +87,7 @@ AUDIO_CHANNELS = 1
#---------------------------------
#ARQ DEFAULTS
TX_N_MAX_RETRIES = 10
TX_N_MAX_RETRIES = 5
TX_N_RETRIES = 0
ARQ_TX_N_FRAMES_PER_BURST = 0
@ -141,10 +143,34 @@ ARQ_N_SENT_FRAMES = 0 #counter for already sent frames
# RECEIVING_SIGNALLING
# SENDING_ACK
# ACK_RECEIVED
#
#
#
ARQ_STATE = 'RECEIVING_DATA'
# CONNECTED
# DISCONNECTED
# CONNECTING
# DISCONNECTING
ARQ_STATE = 'IDLE'
# RECEIVING_SIGNALLING
# RECEIVING_DATA_10
# RECEIVING_DATA_11
# RECEIVING_DATA_12
CHANNEL_STATE = 'RECEIVING_SIGNALLING'
# IDLE
# BUSY
TNC_STATE = 'IDLE'
# MODE FOR SENDING AN RECEIVING DATA DURING ARQ SESSION
# 0 = NOT WAITING FOR DATA
# 1 = TELL DX STATION WE WANT TO SEND DATA
# 2 = DX STATION IS READY FOR DATA
# 3 = DX STATION SAID, THEY ARE READY FOR DATA
ARQ_READY_FOR_DATA = False
ARQ_DATA_CHANNEL_MODE = 12
# SEND KEEP ALIVE ONLY IF WE WANT
ARQ_SEND_KEEP_ALIVE = True
#ARQ_WAIT_FOR_DISCONNECT = False
# ------- TX BUFFER
TX_BUFFER_SIZE = 0

23
tools/init_and_send.sh Normal file
View file

@ -0,0 +1,23 @@
for i in {1..5}
do
echo "Welcome $i times"
done
python3 readfromsocket.py --port 3002 --data "SET:MYCALLSIGN:DJ2LS"
python3 readfromsocket.py --port 3000 --data "SET:MYCALLSIGN:DH3WO"
sleep 3
#python3 readfromsocket.py --port 3002 --data "CQCQCQ"
#sleep 5
python3 readfromsocket.py --port 3002 --data "PING:DH3WO"
sleep 5
python3 readfromsocket.py --port 3002 --data "ARQ:CONNECT:DH3WO"
#sleep 1
python3 readfromsocket.py --port 3000 --data "GET:ARQ_STATE"
sleep 5
echo "ACHTUNG DATEI"
python3 socketclient.py --port 3002 --random 100
sleep 10
python3 readfromsocket.py --port 3000 --data "ARQ:DISCONNECT"
echo "ende..."

View file

@ -0,0 +1,24 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import pyaudio
def list_audio_devices():
p = pyaudio.PyAudio()
devices = []
print("--------------------------------------------------------------------")
for x in range(0, p.get_device_count()):
devices.append(f"{x} - {p.get_device_info_by_index(x)['name']}")
for line in devices:
print(line)
list_audio_devices()

View file

@ -24,12 +24,14 @@ args = parser.parse_args()
ip, port = "localhost", args.socket_port
message = args.data
print(len(b'\n'))
while True:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
print(ip)
print(port)
sock.connect((ip, port))
sock.sendall(bytes(message, 'utf-8'))
sock.sendall(bytes(message, 'utf-8') + b'\n')
response = str(sock.recv(1024), 'utf-8')
print("Received: {}".format(response))
print("CMD: {}".format(response))
False
break

View file

@ -43,7 +43,7 @@ args = parser.parse_args()
data = create_string(args.datalength)
data = bytes("ARQ:" + "" + data + "" + "\n", "utf-8")
data = bytes("ARQ:DATA:" + "" + data + "" + "\n", "utf-8")