diff --git a/src/06-mini-project/cli/.clangd b/src/06-mini-project/cli/.clangd new file mode 100644 index 0000000..2322919 --- /dev/null +++ b/src/06-mini-project/cli/.clangd @@ -0,0 +1,7 @@ +CompileFlags: + Add: + # Architecture and cross-compilation + - "--target=aarch64-linux-gnu" + + # Setup sysroot for buildroot + - "--sysroot=/buildroot/output/host/aarch64-buildroot-linux-gnu/sysroot" diff --git a/src/06-mini-project/cli/Makefile b/src/06-mini-project/cli/Makefile new file mode 100644 index 0000000..5b9051f --- /dev/null +++ b/src/06-mini-project/cli/Makefile @@ -0,0 +1,7 @@ +EXE=mp +SRCS=$(shell find . -name "*.c") +LDFLAGS+=-lpthread +EXTRA_CFLAGS+=-I. + +# Include the standard application Makefile for the CSEL1 labs +include ../../appl.mk diff --git a/src/06-mini-project/cli/justfile b/src/06-mini-project/cli/justfile new file mode 100644 index 0000000..137ab76 --- /dev/null +++ b/src/06-mini-project/cli/justfile @@ -0,0 +1,14 @@ +@default: + just --list + +@build: + make + +@install: build + install -d /rootfs/usr/bin + install -m 0755 mp /rootfs/usr/bin/mp + echo "temp_cli installed successfully in /rootfs/usr/bin/" + +@clean: + make clean + rm -f -- mp diff --git a/src/06-mini-project/cli/main.c b/src/06-mini-project/cli/main.c new file mode 100644 index 0000000..27f70db --- /dev/null +++ b/src/06-mini-project/cli/main.c @@ -0,0 +1,96 @@ +// workspace/src/06-mini-project/cli/main.c +#include +#include +#include +#include +#include +#include + +/* Relative path to your common IPC definitions */ +#include "../common/common_ipc.h" + +/** + * print_usage() - Display the help menu for the CLI tool. + */ +static void print_usage(const char *prog_name) { + printf("Temperature Regulator CLI\n"); + printf("Usage:\n"); + printf(" %s mode <0|1> : Set mode (0 = Manual, 1 = Auto)\n", prog_name); + printf(" %s freq : Set frequency in Hz (only works in Manual mode)\n", prog_name); + printf(" %s inc : Increase frequency (only works in Manual mode)\n", prog_name); + printf(" %s dec : Decrease frequency (only works in Manual mode)\n", prog_name); + printf("\nExamples:\n"); + printf(" %s mode 1 (Switch to automatic mode)\n", prog_name); + printf(" %s freq 50 (Set frequency to 50 Hz)\n", prog_name); +} + +int main(int argc, char *argv[]) { + int client_fd; + struct sockaddr_un server_addr; + ipc_msg_t msg = {0}; + + /* 1. Parse command line arguments */ + if (argc < 2) { + print_usage(argv[0]); + return EXIT_FAILURE; + } + + if (strcmp(argv[1], "mode") == 0 && argc == 3) { + msg.command = CMD_SET_MODE; + msg.value = atoi(argv[2]); + if (msg.value != 0 && msg.value != 1) { + printf("Error: Mode must be 0 (Manual) or 1 (Auto).\n"); + return EXIT_FAILURE; + } + } + else if (strcmp(argv[1], "freq") == 0 && argc == 3) { + msg.command = CMD_SET_FREQ; + msg.value = atoi(argv[2]); + if (msg.value <= 0) { + printf("Error: Frequency must be a positive integer.\n"); + return EXIT_FAILURE; + } + } + else if (strcmp(argv[1], "inc") == 0 && argc == 2) { + msg.command = CMD_INC_FREQ; + msg.value = 0; /* Ignored by daemon */ + } + else if (strcmp(argv[1], "dec") == 0 && argc == 2) { + msg.command = CMD_DEC_FREQ; + msg.value = 0; /* Ignored by daemon */ + } + else { + printf("Error: Invalid arguments.\n\n"); + print_usage(argv[0]); + return EXIT_FAILURE; + } + + /* 2. Create local Unix Domain Socket (Datagram) */ + client_fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (client_fd < 0) { + perror("Error: Socket creation failed"); + return EXIT_FAILURE; + } + + /* 3. Prepare the destination address (the Daemon's socket) */ + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sun_family = AF_UNIX; + strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1); + + /* 4. Send the binary structure to the Daemon */ + ssize_t sent_bytes = sendto(client_fd, &msg, sizeof(msg), 0, + (struct sockaddr *)&server_addr, sizeof(server_addr)); + + if (sent_bytes < 0) { + perror("Error: Failed to send message"); + printf("Hint: Is the background daemon running and listening on '%s'?\n", SOCKET_PATH); + close(client_fd); + return EXIT_FAILURE; + } + + /* 5. Cleanup */ + printf("Success: Command sent to the daemon.\n"); + close(client_fd); + + return EXIT_SUCCESS; +}