Skip to content

Commit

Permalink
WIP: Enhancement nasa#103 - updates to miniCmdUtil and other files
Browse files Browse the repository at this point in the history
  • Loading branch information
lbleier-GSFC committed Jun 25, 2020
1 parent 6d3f7ed commit 9d233eb
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 112 deletions.
9 changes: 5 additions & 4 deletions GroundSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox

import common.shareddata as shared
from shareddata import tlmOffset, cmdOffsetPri, cmdOffsetSec
from RoutingService import RoutingService
from Ui_MainWindow import Ui_MainWindow

Expand Down Expand Up @@ -146,9 +146,10 @@ def setCmdOffsets(self):
self.sbCmdOffsetSec.setValue(self.HDR_VER_1_OFFSET)

def saveOffsets(self):
shared.tlmOffset = self.sbTlmOffset.value()
shared.cmdOffsetPri = self.sbCmdOffsetPri.value()
shared.cmdOffsetSec = self.sbCmdOffsetSec.value()
tlmOffset = self.sbTlmOffset.value()
cmdOffsetPri = self.sbCmdOffsetPri.value()
cmdOffsetSec = self.sbCmdOffsetSec.value()
print(tlmOffset, cmdOffsetPri, cmdOffsetSec)

# Update the combo box list in gui
def updateIpList(self, ip, name):
Expand Down
19 changes: 12 additions & 7 deletions Subsystems/cmdGui/CommandSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from PyQt5.QtWidgets import (QApplication, QDialog, QHeaderView, QPushButton,
QTableWidgetItem)

from MiniCmdUtil import MiniCmdUtil
from Ui_CommandSystemDialog import Ui_CommandSystemDialog

## ../cFS/tools/cFS-GroundSystem/Subsystems/cmdGui/
Expand Down Expand Up @@ -92,15 +93,19 @@ def ProcessQuickButton(self, idx):
f'--port={quickPort[qIdx]} '
f'--pktid={pktId} --endian={quickEndian[qIdx]} '
f'--cmdcode={quickCode[qIdx]} --file={quickParam[qIdx]}')
cmd_args = shlex.split(launch_string)
subprocess.Popen(cmd_args)
# if doesn't require parameters
else:
launch_string = (
f'{ROOTDIR.parent}/cmdUtil/cmdUtil '
f'--host=\"{address}\" --port={quickPort[qIdx]} '
f'--pktid={pktId} --endian={quickEndian[qIdx]} '
f'--cmdcode={quickCode[qIdx]}')
cmd_args = shlex.split(launch_string)
subprocess.Popen(cmd_args)
mcu = MiniCmdUtil(address, quickPort[qIdx], quickEndian[qIdx],
pktId, quickCode[qIdx])
sendSuccess = mcu.sendPacket()
print("Command sent successfully:", sendSuccess)
# launch_string = (
# f'{ROOTDIR.parent}/cmdUtil/cmdUtil '
# f'--host=\"{address}\" --port={quickPort[qIdx]} '
# f'--pktid={pktId} --endian={quickEndian[qIdx]} '
# f'--cmdcode={quickCode[qIdx]}')


#
Expand Down
130 changes: 83 additions & 47 deletions Subsystems/cmdGui/MiniCmdUtil.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,19 @@
## This file is a Python implementation of a subset of functions in cmdUtil
## to support the GroundSystem GUI

import socket
import sys
from pathlib import Path
from collections import namedtuple

ROOTDIR = Path().resolve().parent
sys.path.append(ROOTDIR.parent.parent)
ROOTDIR = Path(sys.argv[0]).resolve().parent
sys.path.append(str(ROOTDIR.parent.parent))
## The two preceding lines must be above
## the next import or the import will fail
import common.shareddata as shared
from shareddata import cmdOffsetPri, cmdOffsetSec, sock


class MiniCmdUtil:
ccsdsExt = bytearray(4)
checksum = 0xFF
cfsCmdSecHdr = bytearray(2)
TypeSignature = namedtuple("TypeSignature", 'byteLen, signed, endian')
dataTypes = {
Expand All @@ -56,53 +55,90 @@ class MiniCmdUtil:

def __init__(self,
host="127.0.0.1",
port="1234",
port=1234,
endian="BE",
hdrVer=1,
pktID=None,
cmdCode=None,
payload=None):
pktID=0,
cmdCode=0,
parameters=None):

self.host = host
self.port = port
self.port = int(port)
self.endian = "big" if endian == "BE" else "little"
self.pktID = pktID
self.cmdCode = cmdCode
self.hdrVer = hdrVer
self.payload = payload
self.pktID = int(pktID, 16)
self.cmdCode = int(cmdCode)
self.parameters = parameters
self.payload = bytearray()
self.packet = bytearray()

self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def assemblePriHeader(self):
ccsdsPri = bytearray(6)
ccsdsPri[:2] = self.pktID.to_bytes(2, byteorder='big')
ccsdsPri[2:4] = (0xC000).to_bytes(2, byteorder='big')
totalPacketLen = len(ccsdsPri) + len(self.cfsCmdSecHdr)
self.assemblePayload()
totalPacketLen += len(self.payload)
totalPacketLen += cmdOffsetPri + cmdOffsetSec
ccsdsPri[4:] = (totalPacketLen - 7).to_bytes(2, byteorder="big")
return ccsdsPri

def assemblePayload(self):
if self.parameters:
paramList = self.parameters.split(" ")
for param in paramList:
items = param.split("=") ## e.g. ["--uint16", "2"]
if "--string" not in param: ## non-string param
dataType = items[0].strip("-") ## Remove "--" prefix
dataVal = int(items[1])
for key in self.dataTypes: ## Loop thru dictionary keys
if dataType in key: ## Check if e.g. "uint16" in key tuple
## Get the TypeSignature tuple
typeSig = self.dataTypes[key]
break ## Stop checking dictionary
## If TypeSignature endian is None, get the
## user-provided/default endian. Otherwise get
## the TypeSignature endian
endian = typeSig.endian or self.endian
## Convert to bytes of correct length, endianess, and sign
dataValB = dataVal.to_bytes(typeSig.byteLen,
byteorder=endian,
signed=typeSig.signed)
## Add data to payload bytearray
self.payload.extend(dataValB)
else:
stringParams = items[1].strip("\"").split(
":") ## e.g. ["16", "ES_APP"]
## Zero init'd bytearray of length e.g. 16
fixedLenStr = bytearray(int(stringParams[0]))
stringB = stringParams[1].encode(
) ## Param string to bytes
## Insert param bytes into front of bytearray
fixedLenStr[:len(stringB)] = stringB
## Add data to payload bytearray
self.payload.extend(fixedLenStr)

def assemblePriHeader(self):
ccsdsPri = bytearray(6)
ccsdsPri[0:2] = self.pktID.to_bytes(2, byteorder='big')
ccsdsPri[2:4] = (0xC000).to_bytes(2, byteorder='big')
totalPacketLen = len(ccsdsPri) + len(self.cfsCmdSecHdr)
if self.hdrVer == 2:
totalPacketLen += len(self.ccsdsExt)
def assemblePacket(self):
pri = self.assemblePriHeader()
self.packet.extend(pri)
priOffset = bytearray(cmdOffsetPri)
self.packet.extend(priOffset)
self.cfsCmdSecHdr[0] = self.cmdCode
secOffset = bytearray(cmdOffsetSec)
for b in b''.join(
(pri, priOffset, self.cfsCmdSecHdr, secOffset, self.payload)):
self.checksum ^= b
self.cfsCmdSecHdr[1] = self.checksum
self.packet.extend(self.cfsCmdSecHdr)
self.packet.extend(secOffset)
self.packet.extend(self.payload)
self.checksum = 0xFF


def assemblePayload(self):
completePayload = bytearray(0)
paramList = self.payload.split(" ")
for param in paramList:
if "--string" not in param: ## non-string param
items = param.split("=") ## e.g. ["--uint16", "2"]
dataType = items[0].strip("-") ## Remove "--" prefix
dataVal = int(items[1]) ## "2" --> 2
for key in self.dataTypes: ## Loop thru dictionary
if dataType in key: ## Check if "uint16" in key tuple
## Get the TypeSignature tuple
typeSig = self.dataTypes[key]
break ## Stop checking dictionary
## If TypeSignature endian is None, get the user-provided endian
## Otherwise get the TypeSignature endian
endian = typeSig.endian or self.endian
## Convert to bytes of correct length, endianess, and sign
dataValb = dataVal.to_bytes(typeSig.byteLen,
byteorder=endian,
signed=typeSig.signed)
completePayload.extend(dataValb) ## Add data to bytearray
else:
pass
def sendPacket(self):
self.assemblePacket()
print("Data to send:")
for i, v in enumerate(self.packet):
print(f"0x{format(v, '02X')}", end=" ")
if (i + 1) % 8 == 0:
print()
print()
bytesSent = sock.sendto(self.packet, (self.host, self.port))
return bytesSent > 0
21 changes: 14 additions & 7 deletions Subsystems/cmdGui/Parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
QTableWidgetItem)

from HTMLDocsParser import HTMLDocsParser
from MiniCmdUtil import MiniCmdUtil
from Ui_ParameterDialog import Ui_Dialog

ROOTDIR = Path(sys.argv[0]).resolve().parent
Expand Down Expand Up @@ -63,13 +64,19 @@ def ProcessSendButton(self):
else:
param_list.append(f'{dataType}={inpt}') # --byte=4
param_string = ' '.join(param_list)
launch_string = (
f'{ROOTDIR.parent}/cmdUtil/cmdUtil --host={pageAddress} '
f'--port={pagePort} --pktid={pagePktId} --endian={pageEndian} '
f'--cmdcode={cmdCode} {param_string.strip()}')
cmd_args = shlex.split(launch_string)
subprocess.Popen(cmd_args)
self.status_box.setText('Command sent!')
mcu = MiniCmdUtil(pageAddress, pagePort, pageEndian, pagePktId,
cmdCode, param_string.strip())
sendSuccess = mcu.sendPacket()
# launch_string = (
# f'{ROOTDIR.parent}/cmdUtil/cmdUtil --host={pageAddress} '
# f'--port={pagePort} --pktid={pagePktId} --endian={pageEndian} '
# f'--cmdcode={cmdCode} {param_string.strip()}')result
# cmd_args = shlex.split(launch_string)
# subprocess.Popen(cmd_args)
if sendSuccess:
self.status_box.setText('Command sent!')
else:
self.status_box.setText('Error occured')


#
Expand Down
20 changes: 12 additions & 8 deletions Subsystems/cmdGui/UdpCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@
from PyQt5.QtWidgets import (QApplication, QDialog, QHeaderView, QPushButton,
QTableWidgetItem)

from MiniCmdUtil import MiniCmdUtil
from Ui_GenericCommandDialog import Ui_GenericCommandDialog

## ../cFS/tools/cFS-GroundSystem/Subsystems/cmdGui/
ROOTDIR = Path(sys.argv[0]).resolve().parent


class SubsystemCommands(QDialog, Ui_GenericCommandDialog):
#
# Init the class
Expand Down Expand Up @@ -90,16 +92,18 @@ def ProcessSendButtonGeneric(self, idx):
f'--host=\"{address}\" --port={pagePort} '
f'--pktid={pagePktId} --endian={pageEndian} '
f'--cmdcode={cmdCodes[idx]} --file={param_files[idx]}')

cmd_args = shlex.split(launch_string)
subprocess.Popen(cmd_args)
# If parameters not required, directly calls cmdUtil to send command
else:
launch_string = (
f'{ROOTDIR.parent}/cmdUtil/cmdUtil --host=\"{address}\" '
f'--port={pagePort} --pktid={pagePktId} '
f'--endian={pageEndian} --cmdcode={cmdCodes[idx]}')

cmd_args = shlex.split(launch_string)
subprocess.Popen(cmd_args)
mcu = MiniCmdUtil(address, pagePort, pageEndian, pagePktId,
cmdCodes[idx])
sendSuccess = mcu.sendPacket()
print("Command sent successfully:", sendSuccess)
# launch_string = (
# f'{ROOTDIR.parent}/cmdUtil/cmdUtil --host=\"{address}\" '
# f'--port={pagePort} --pktid={pagePktId} '
# f'--endian={pageEndian} --cmdcode={cmdCodes[idx]}')


#
Expand Down
69 changes: 33 additions & 36 deletions Subsystems/tlmGUI/EventMessage.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,30 @@
# The EVS Event Message has the following format
#
#
# ES HK format:
#
# Packet Header
# uint16 StreamId; 0
# uint16 Sequence; 2
# uint16 Length; 4

# Tlm Secondary Header
# uint32 seconds 6
# uint16 subseconds 10
# Packet Header Start Byte
# uint16 StreamId; 0
# uint16 Sequence; 2
# uint16 Length; 4

# Packet data
#
# Event format:
#
# Packet Header
# uint16 StreamId;
# uint16 Sequence;
# uint16 Length;
# Start byte values after primary header depend
# on header version.
# Add 4 to ALL the values below if header version 2

# Tlm Secondary Header
# uint32 seconds
# uint16 subseconds
# Tlm Secondary Header Start Byte
# uint32 seconds 6
# uint16 subseconds 10

# Packet ID
# char AppName[20]
# uint16 EventID;
# uint16 EventType;
# uint32 SpacecraftID;
# uint32 ProcessorID;
# char AppName[20] 12
# uint16 EventID; 32
# uint16 EventType; 34
# uint32 SpacecraftID; 36
# uint32 ProcessorID; 40

# Message
# char Message[122];
# uint8 Spare1;
# uint8 Spare2;
# char Message[122]; 44
# uint8 Spare1; 166
# uint8 Spare2; 167

import getopt
import sys
Expand All @@ -72,6 +61,10 @@
from Ui_EventMessageDialog import Ui_EventMessageDialog

ROOTDIR = Path(sys.argv[0]).resolve().parent
sys.path.append(str(ROOTDIR.parent.parent))
## The two preceding lines must be above
## the next import or the import will fail
from shareddata import tlmOffset


class EventMessageTelemetry(QDialog, Ui_EventMessageDialog):
Expand Down Expand Up @@ -107,13 +100,17 @@ def processPendingDatagrams(self, datagram):
#
# Get App Name, Event ID, Type and Event Text!
#
appName = datagram[16:36].decode('utf-8', 'ignore')
eventID = int.from_bytes(datagram[36:38], byteorder='little')
eventType = int.from_bytes(datagram[38:40], byteorder='little')
eventText = datagram[48:].decode('utf-8', 'ignore')
print(tlmOffset)
startByte = 12 + tlmOffset
appName = datagram[startByte:startByte + 20].decode('utf-8', 'ignore')
eventID = int.from_bytes(datagram[startByte + 20:startByte + 22],
byteorder='little')
eventType = int.from_bytes(datagram[startByte + 22:startByte + 24],
byteorder='little')
eventText = datagram[startByte + 32:].decode('utf-8', 'ignore')
appName = appName.split("\0")[0]
eventText = eventText.split("\0")[0]
eventTypeStr = self.eventTypes.get(eventType, "Invalid Event Type")
eventTypeStr = self.eventTypes.get(eventType, "INVALID EVENT TYPE")

eventString = f"EVENT --> {appName}-{eventTypeStr} Event ID: {eventID} : {eventText}"
self.eventOutput.appendPlainText(eventString)
Expand Down Expand Up @@ -188,11 +185,11 @@ def usage():
usage()
sys.exit()
if opt in ("-p", "--port"):
_ = arg
pass
elif opt in ("-t", "--title"):
pageTitle = arg
elif opt in ("-f", "--file"):
_ = arg
pass
elif opt in ("-a", "--appid"):
appId = arg
elif opt in ("-e", "--endian"):
Expand Down
Loading

0 comments on commit 9d233eb

Please sign in to comment.