Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions gs/backend/obc_utils/command_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
CmdCallbackId,
CmdMsg,
CmdResponseErrorCode,
create_cmd_arm,
create_cmd_downlink_logs_next_pass,
create_cmd_downlink_telem,
create_cmd_download_data,
create_cmd_end_of_frame,
create_cmd_erase_app,
create_cmd_exec_obc_reset,
create_cmd_execute,
create_cmd_i2c_probe,
create_cmd_mirco_sd_format,
create_cmd_ping,
Expand Down Expand Up @@ -257,6 +259,8 @@ def generate_command(args: str) -> tuple[CmdMsg | None, bool]:
create_cmd_download_data,
create_cmd_verify_crc,
create_cmd_i2c_probe,
create_cmd_arm,
create_cmd_execute,
]

# Loop through each of the specific parses and see if we get a valid parse on any of them
Expand Down
59 changes: 58 additions & 1 deletion interfaces/obc_gs_interface/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ class SetProgrammingSessionCmdData(Structure):
_fields_ = [("programmingSession", c_uint)]


class CmdArmCmdData(Structure):
"""
The python equivalent class for the cmd_arm_cmd_data_t structure in the C implementation
"""

_fields_ = [("cmdArm", c_uint)]
_fields_ = [("armId", c_uint32)]


class CmdExecuteCmdData(Structure):
"""
The python equivalent class for the cmd_execute_cmd_data_t structure in the C implementation
"""

_fields_ = [("cmdExecute", c_uint)]
_fields_ = [("execId", c_uint32)]


# NOTE: When adding commands only add their data to the following union type as shown with RtcSyncCmdData and
# DownlinkLogsNextPassCmdData
class _U(Union):
Expand All @@ -66,6 +84,8 @@ class _U(Union):
("downlinkLogsNextPass", DownlinkLogsNextPassCmdData),
("downloadData", DownloadDataCmdData),
("setProgrammingSession", SetProgrammingSessionCmdData),
("cmdArm", CmdArmCmdData),
("cmdExecute", CmdExecuteCmdData),
]


Expand Down Expand Up @@ -159,7 +179,9 @@ class CmdCallbackId(IntEnum):
CMD_DOWNLOAD_DATA = 10
CMD_VERIFY_CRC = 11
CMD_I2C_PROBE = 12
NUM_CMD_CALLBACKS = 13
CMD_ARM = 13
CMD_EXECUTE = 14
NUM_CMD_CALLBACKS = 15


# Path to File: interfaces/obc_gs_interface/commands/obc_gs_commands_response.h
Expand Down Expand Up @@ -393,6 +415,41 @@ def create_cmd_i2c_probe(unixtime_of_execution: int | None = None) -> CmdMsg:
return cmd_msg


def create_cmd_arm(cmd_arm: c_uint, arm_id: c_uint32, unixtime_of_execution: int | None = None) -> CmdMsg:
"""
Function to create a CmdMsg structure for CMD_ARM

:param cmdArm: The ARM command callback struct ID
:param armId: The ID value associated to an arm command sent by an operator
:param unixtime_of_execution: A time of when to execute a certain event,
by default, it is set to None (i.e. a specific
time is not needed)
:return: CmdMsg structure for CMD_ARM
"""
cmd_msg = CmdMsg(unixtime_of_execution)
cmd_msg.id = CmdCallbackId.CMD_ARM
cmd_msg.cmdArm.cmd_arm = c_uint(cmd_arm.vlaue)
cmd_msg.cmdArm.arm_id = c_uint32(arm_id.value)
return cmd_msg


def create_cmd_execute(cmd_execute: c_uint, exec_id: c_uint32, unixtime_of_execution: int | None = None) -> CmdMsg:
"""
Function to create a CmdMsg structure for CMD_EXECUTE
:param cmdExecute: The EXECUTE command callback struct ID
:param execId: The ID value associated to an execute command sent by an operator
:param unixtime_of_execution: A time of when to execute a certain event,
by default, it is set to None (i.e. a specific
time is not needed)
:return: CmdMsg structure for CMD_EXECUTE
"""
cmd_msg = CmdMsg(unixtime_of_execution)
cmd_msg.id = CmdCallbackId.CMD_EXECUTE
cmd_msg.cmdExecute.cmd_execute = c_uint(cmd_execute.value)
cmd_msg.execId.exec_id = c_uint32(exec_id.value)
return cmd_msg


# ######################################################################
# || ||
# || Command Pack and Unpack Implementations ||
Expand Down
30 changes: 30 additions & 0 deletions interfaces/obc_gs_interface/commands/command_response_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from interfaces.obc_gs_interface.commands import CmdCallbackId, unpack_command_response
from interfaces.obc_gs_interface.commands.command_response_classes import (
CmdCmdArmRes,
CmdCmdExecuteRes,
CmdI2CProbeRes,
CmdRes,
CmdRtcSyncRes,
Expand Down Expand Up @@ -73,12 +75,40 @@ def parse_cmd_i2c_probe(cmd_response: CmdRes, data: bytes) -> CmdI2CProbeRes:
return CmdI2CProbeRes(cmd_response.cmd_id, cmd_response.error_code, cmd_response.response_length, valid_addresses)


def parse_cmd_arm(cmd_response: CmdRes, data: bytes) -> CmdCmdArmRes:
"""
A function to parse the raw data from the response of CMD_ARM
:param cmd_response: Basic command response
:param data: The raw bytes containing the data that needs to be parsed
:return: CmdCmdNameRes (i.e. A command response with no data for CMD_NAME)
"""
if cmd_response.cmd_id != CmdCallbackId.CMD_ARM:
raise ValueError("Wrong command id for parsing the name command")

return CmdCmdArmRes(cmd_response.cmd_id, cmd_response.error_code, cmd_response.response_length)


def parse_cmd_execute(cmd_response: CmdRes, data: bytes) -> CmdCmdExecuteRes:
"""
A function to parse the raw data from the response of CMD_EXECUTE
:param cmd_response: Basic command response
:param data: The raw bytes containing the data that needs to be parsed
:return: CmdCmdNameRes (i.e. A command response with no data for CMD_NAME)
"""
if cmd_response.cmd_id != CmdCallbackId.CMD_NAME:
raise ValueError("Wrong command id for parsing the name command")

return CmdCmdExecuteRes(cmd_response.cmd_id, cmd_response.error_code, cmd_response.response_length)


# Function array where each index corresponds to the command enum value + 1

parse_func_dict: dict[CmdCallbackId, Callable[..., CmdRes]] = defaultdict(lambda: parse_cmd_with_no_data)
parse_func_dict[CmdCallbackId.CMD_VERIFY_CRC] = parse_cmd_verify_crc
parse_func_dict[CmdCallbackId.CMD_RTC_SYNC] = parse_cmd_rtc_sync
parse_func_dict[CmdCallbackId.CMD_I2C_PROBE] = parse_cmd_i2c_probe
parse_func_dict[CmdCallbackId.CMD_ARM] = parse_cmd_arm
parse_func_dict[CmdCallbackId.CMD_EXECUTE] = parse_cmd_execute


def parse_command_response(data: bytes) -> CmdRes:
Expand Down
34 changes: 34 additions & 0 deletions interfaces/obc_gs_interface/commands/command_response_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,40 @@ def __str__(self) -> str:
return formatted_string


@dataclass
class CmdCmdArmRes(CmdRes):
"""
Class for storing the response to CMD_ARM
"""

cmd_arm: int
arm_id: int

def __str__(self) -> str:
"""
Overriding the str method for a better representation of what's happening
"""
formatted_string = super().__str__()
return formatted_string


@dataclass
class CmdCmdExecuteRes(CmdRes):
"""
Class for storing the response to CMD_EXECUTE
"""

cmd_execute: int
exec_id: int

def __str__(self) -> str:
"""
Overriding the str method for a better representation of what's happening
"""
formatted_string = super().__str__()
return formatted_string


if __name__ == "__main__":
cmd = CmdVerifyCrcRes(CmdCallbackId.CMD_VERIFY_CRC, CmdResponseErrorCode.CMD_RESPONSE_ERROR, 4, 0x12345678)
print(cmd)
14 changes: 14 additions & 0 deletions interfaces/obc_gs_interface/commands/obc_gs_command_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ typedef struct {
uint8_t logLevel;
} downlink_logs_next_pass_cmd_data_t;

// CMD_ARM
typedef struct {
cmd_callback_id_t cmdArm;
uint32_t armId;
} cmd_arm_cmd_data_t;

// CMD_EXECUTE
typedef struct {
cmd_callback_id_t cmdExecute;
uint32_t execId;
} cmd_execute_cmd_data_t;

/* -------------------------- */
/* BL Command Data Structures */
/* -------------------------- */
Expand Down Expand Up @@ -47,6 +59,8 @@ typedef struct {
downlink_logs_next_pass_cmd_data_t downlinkLogsNextPass;
download_data_cmd_data_t downloadData;
set_programming_session_cmd_data_t setProgrammingSession;
cmd_arm_cmd_data_t cmdArm;
cmd_execute_cmd_data_t cmdExecute;
};

uint32_t timestamp; // Unix timestamp in seconds
Expand Down
2 changes: 2 additions & 0 deletions interfaces/obc_gs_interface/commands/obc_gs_command_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,7 @@ typedef enum {
CMD_DOWNLOAD_DATA,
CMD_VERIFY_CRC,
CMD_I2C_PROBE,
CMD_ARM,
CMD_EXECUTE,
NUM_CMD_CALLBACKS
} cmd_callback_id_t;
20 changes: 20 additions & 0 deletions interfaces/obc_gs_interface/commands/obc_gs_command_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ static void packVerifyCrcCmdData(uint8_t* buffer, uint32_t* offset, const cmd_ms
// CMD_I2C_PROBE
static void packI2CProbeCmdData(uint8_t* buffer, uint32_t* offset, const cmd_msg_t* msg);

// CMD_ARM
static void packCmdArmCmdData(uint8_t* buffer, uint32_t* offset, const cmd_msg_t* msg);

// CMD_EXECUTE
static void packCmdExecuteCmdData(uint8_t* buffer, uint32_t* offset, const cmd_msg_t* msg);

typedef void (*pack_func_t)(uint8_t*, uint32_t*, const cmd_msg_t*);

static const pack_func_t packFns[] = {
Expand All @@ -61,6 +67,8 @@ static const pack_func_t packFns[] = {
[CMD_ERASE_APP] = packEraseAppCmdData,
[CMD_VERIFY_CRC] = packVerifyCrcCmdData,
[CMD_I2C_PROBE] = packI2CProbeCmdData,
[CMD_ARM] = packCmdArmCmdData,
[CMD_EXECUTE] = packCmdExecuteCmdData,
// Add more functions for other commands as needed
};

Expand Down Expand Up @@ -153,3 +161,15 @@ static void packVerifyCrcCmdData(uint8_t* buffer, uint32_t* offset, const cmd_ms
static void packI2CProbeCmdData(uint8_t* buffer, uint32_t* offset, const cmd_msg_t* msg) {
// No data to pack
}

// CMD_ARM
static void packCmdArmCmdData(uint8_t* buffer, uint32_t* offset, const cmd_msg_t* cmdMsg) {
packUint32(cmdMsg->cmdArm.cmdArm, buffer, offset);
packUint32(cmdMsg->cmdArm.armId, buffer, offset);
}

// CMD_EXECUTE
static void packCmdExecuteCmdData(uint8_t* buffer, uint32_t* offset, const cmd_msg_t* cmdMsg) {
packUint32(cmdMsg->cmdExecute.cmdExecute, buffer, offset);
packUint32(cmdMsg->cmdExecute.execId, buffer, offset);
}
20 changes: 20 additions & 0 deletions interfaces/obc_gs_interface/commands/obc_gs_command_unpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ static void unpackVerifyCrcCmdData(const uint8_t* buffer, uint32_t* offset, cmd_
// CMD_I2C_PROBE
static void unpackI2CProbeCmdData(const uint8_t* buffer, uint32_t* offset, cmd_msg_t* msg);

// CMD_ARM
static void unpackCmdArmCmdData(const uint8_t* buffer, uint32_t* offset, cmd_msg_t* msg);

// CMD_EXECUTE
static void unpackCmdExecuteCmdData(const uint8_t* buffer, uint32_t* offset, cmd_msg_t* msg);

typedef void (*unpack_func_t)(const uint8_t*, uint32_t*, cmd_msg_t*);

static const unpack_func_t unpackFns[] = {
Expand All @@ -64,6 +70,8 @@ static const unpack_func_t unpackFns[] = {
[CMD_ERASE_APP] = unpackEraseAppCmdData,
[CMD_VERIFY_CRC] = unpackVerifyCrcCmdData,
[CMD_I2C_PROBE] = unpackI2CProbeCmdData,
[CMD_ARM] = unpackCmdArmCmdData,
[CMD_EXECUTE] = unpackCmdExecuteCmdData,
// Add more functions for other commands as needed
};

Expand Down Expand Up @@ -165,3 +173,15 @@ static void unpackVerifyCrcCmdData(const uint8_t* buffer, uint32_t* offset, cmd_
static void unpackI2CProbeCmdData(const uint8_t* buffer, uint32_t* offset, cmd_msg_t* cmdMsg) {
// No data to unpack
}

// CMD_ARM
static void unpackCmdArmCmdData(const uint8_t* buffer, uint32_t* offset, cmd_msg_t* cmdMsg) {
cmdMsg->cmdArm.cmdArm = unpackUint32(buffer, offset);
cmdMsg->cmdArm.armId = unpackUint32(buffer, offset);
}

// CMD_EXECUTE
static void unpackCmdExecuteCmdData(const uint8_t* buffer, uint32_t* offset, cmd_msg_t* cmdMsg) {
cmdMsg->cmdExecute.cmdExecute = unpackUint32(buffer, offset);
cmdMsg->cmdExecute.execId = unpackUint32(buffer, offset);
}
18 changes: 18 additions & 0 deletions obc/app/modules/command_mgr/command_callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ static obc_error_code_t I2CProbeCmdCallback(cmd_msg_t *cmd, uint8_t *responseDat
return OBC_ERR_CODE_SUCCESS;
}

static obc_error_code_t cmdArmCmdCallback(cmd_msg_t *cmd, uint8_t *responseData, uint8_t *responseDataLen) {
if (cmd == NULL || responseData == NULL || responseDataLen == NULL) {
return OBC_ERR_CODE_INVALID_ARG;
}

return OBC_ERR_CODE_SUCCESS;
}

static obc_error_code_t cmdExecuteCmdCallback(cmd_msg_t *cmd, uint8_t *responseData, uint8_t *responseDataLen) {
if (cmd == NULL || responseData == NULL || responseDataLen == NULL) {
return OBC_ERR_CODE_INVALID_ARG;
}

return OBC_ERR_CODE_SUCCESS;
}

const cmd_info_t cmdsConfig[] = {
[CMD_END_OF_FRAME] = {NULL, CMD_POLICY_PROD, CMD_TYPE_NORMAL},
// TODO: Change this to critial once critical commands are implemented
Expand All @@ -126,6 +142,8 @@ const cmd_info_t cmdsConfig[] = {
[CMD_PING] = {pingCmdCallback, CMD_POLICY_PROD, CMD_TYPE_NORMAL},
[CMD_DOWNLINK_TELEM] = {downlinkTelemCmdCallback, CMD_POLICY_PROD, CMD_TYPE_NORMAL},
[CMD_I2C_PROBE] = {I2CProbeCmdCallback, CMD_POLICY_PROD, CMD_TYPE_NORMAL},
[CMD_ARM] = {cmdArmCmdCallback, CMD_POLICY_PROD, CMD_TYPE_NORMAL},
[CMD_EXECUTE] = {cmdExecuteCmdCallback, CMD_POLICY_PROD, CMD_TYPE_NORMAL},
};

// This function is purely to trick the compiler into thinking we are using the cmdsConfig variable so we avoid the
Expand Down
Loading