Initial commit
This commit is contained in:
20
azeron-cli/CMakeLists.txt
Normal file
20
azeron-cli/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# azeron-cli - Command-line tool for Azeron configuration
|
||||
|
||||
set(AZERON_CLI_SOURCES
|
||||
main.c
|
||||
commands.c
|
||||
utils.c
|
||||
)
|
||||
|
||||
add_executable(azeron-cli ${AZERON_CLI_SOURCES})
|
||||
|
||||
# Link libraries
|
||||
target_link_libraries(azeron-cli azeron ${LIBUSB_LIBRARIES} ${JSON_LIBRARIES})
|
||||
|
||||
# Include directories
|
||||
target_include_directories(azeron-cli PRIVATE ${CMAKE_SOURCE_DIR}/libazeron)
|
||||
|
||||
# Install executable
|
||||
install(TARGETS azeron-cli
|
||||
RUNTIME DESTINATION bin
|
||||
)
|
||||
19
azeron-cli/commands.c
Normal file
19
azeron-cli/commands.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Azeron CLI - Command implementations
|
||||
* Copyright (C) 2024 Azeron Linux Project
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "azeron.h"
|
||||
|
||||
/* Command implementations will go here as they are developed */
|
||||
/* For now, this file contains placeholder functions */
|
||||
|
||||
void commands_init(void)
|
||||
{
|
||||
/* Initialize command system */
|
||||
}
|
||||
376
azeron-cli/main.c
Normal file
376
azeron-cli/main.c
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Azeron CLI - Command-line tool for Azeron device configuration
|
||||
* Copyright (C) 2024 Azeron Linux Project
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include "azeron.h"
|
||||
|
||||
#define AZERON_CLI_VERSION "1.0.0"
|
||||
|
||||
/* Command function prototypes */
|
||||
int cmd_list(int argc, char *argv[]);
|
||||
int cmd_info(int argc, char *argv[]);
|
||||
int cmd_map_button(int argc, char *argv[]);
|
||||
int cmd_show_mappings(int argc, char *argv[]);
|
||||
int cmd_set_profile(int argc, char *argv[]);
|
||||
int cmd_save_profile(int argc, char *argv[]);
|
||||
int cmd_load_profile(int argc, char *argv[]);
|
||||
int cmd_export_config(int argc, char *argv[]);
|
||||
int cmd_import_config(int argc, char *argv[]);
|
||||
|
||||
/* Command structure */
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *description;
|
||||
int (*func)(int argc, char *argv[]);
|
||||
};
|
||||
|
||||
static struct command commands[] = {
|
||||
{"list", "List connected Azeron devices", cmd_list},
|
||||
{"info", "Show device information", cmd_info},
|
||||
{"map-button", "Map a button to a key or action", cmd_map_button},
|
||||
{"show-mappings", "Show current button mappings", cmd_show_mappings},
|
||||
{"set-profile", "Set active profile", cmd_set_profile},
|
||||
{"save-profile", "Save current configuration to profile", cmd_save_profile},
|
||||
{"load-profile", "Load configuration from profile", cmd_load_profile},
|
||||
{"export-config", "Export configuration to file", cmd_export_config},
|
||||
{"import-config", "Import configuration from file", cmd_import_config},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/* Print usage information */
|
||||
static void print_usage(const char *program_name)
|
||||
{
|
||||
printf("Azeron CLI - Configuration tool for Azeron devices\n");
|
||||
printf("Version: %s\n\n", AZERON_CLI_VERSION);
|
||||
printf("Usage: %s <command> [options]\n\n", program_name);
|
||||
printf("Commands:\n");
|
||||
|
||||
for (int i = 0; commands[i].name != NULL; i++) {
|
||||
printf(" %-15s %s\n", commands[i].name, commands[i].description);
|
||||
}
|
||||
|
||||
printf("\nExamples:\n");
|
||||
printf(" %s list\n", program_name);
|
||||
printf(" %s info\n", program_name);
|
||||
printf(" %s map-button 5 KEY_W\n", program_name);
|
||||
printf(" %s set-profile 1\n", program_name);
|
||||
printf("\nFor help with a specific command:\n");
|
||||
printf(" %s <command> --help\n", program_name);
|
||||
}
|
||||
|
||||
/* List connected devices */
|
||||
int cmd_list(int argc, char *argv[])
|
||||
{
|
||||
struct azeron_device_info *devices;
|
||||
size_t count;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
ret = azeron_init();
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize library: %s\n", azeron_error_string(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = azeron_device_list(&devices, &count);
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to list devices: %s\n", azeron_error_string(ret));
|
||||
azeron_exit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
printf("No Azeron devices found.\n");
|
||||
printf("Make sure your device is connected and you have proper permissions.\n");
|
||||
} else {
|
||||
printf("Found %zu Azeron device(s):\n\n", count);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
printf("Device %d:\n", i);
|
||||
printf(" Product: %s\n", devices[i].product);
|
||||
printf(" Manufacturer: %s\n", devices[i].manufacturer);
|
||||
printf(" Serial: %s\n", devices[i].serial_number);
|
||||
printf(" USB ID: %04x:%04x\n", devices[i].vendor_id, devices[i].product_id);
|
||||
printf(" Firmware: %d.%d\n",
|
||||
devices[i].firmware_version >> 8,
|
||||
devices[i].firmware_version & 0xFF);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
azeron_device_list_free(devices, count);
|
||||
azeron_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Show device information */
|
||||
int cmd_info(int argc, char *argv[])
|
||||
{
|
||||
struct azeron_device *device;
|
||||
struct azeron_device_info info;
|
||||
int ret;
|
||||
int device_index = 0;
|
||||
|
||||
/* Parse options */
|
||||
static struct option long_options[] = {
|
||||
{"device", required_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, "d:h", long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
device_index = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
printf("Usage: %s info [options]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" -d, --device <index> Select device by index (default: 0)\n");
|
||||
printf(" -h, --help Show this help message\n");
|
||||
return 0;
|
||||
default:
|
||||
fprintf(stderr, "Unknown option. Use --help for usage.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = azeron_init();
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize library: %s\n", azeron_error_string(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = azeron_device_open_index(&device, device_index);
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to open device %d: %s\n", device_index, azeron_error_string(ret));
|
||||
azeron_exit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = azeron_device_get_info(device, &info);
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to get device info: %s\n", azeron_error_string(ret));
|
||||
azeron_device_close(device);
|
||||
azeron_exit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Device Information:\n");
|
||||
printf("===================\n\n");
|
||||
printf("Product: %s\n", info.product);
|
||||
printf("Manufacturer: %s\n", info.manufacturer);
|
||||
printf("Serial Number: %s\n", info.serial_number);
|
||||
printf("USB ID: %04x:%04x\n", info.vendor_id, info.product_id);
|
||||
printf("Firmware: %d.%d\n", info.firmware_version >> 8, info.firmware_version & 0xFF);
|
||||
printf("Profiles: %d\n", info.num_profiles);
|
||||
printf("Active Profile: %d\n", info.active_profile);
|
||||
|
||||
azeron_device_close(device);
|
||||
azeron_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Show current button mappings */
|
||||
int cmd_show_mappings(int argc, char *argv[])
|
||||
{
|
||||
struct azeron_device *device;
|
||||
int ret;
|
||||
int device_index = 0;
|
||||
int i;
|
||||
|
||||
/* Parse options */
|
||||
static struct option long_options[] = {
|
||||
{"device", required_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
while ((opt = getopt_long(argc, argv, "d:h", long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
device_index = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
printf("Usage: %s show-mappings [options]\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" -d, --device <index> Select device by index (default: 0)\n");
|
||||
printf(" -h, --help Show this help message\n");
|
||||
return 0;
|
||||
default:
|
||||
fprintf(stderr, "Unknown option. Use --help for usage.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = azeron_init();
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to initialize library: %s\n", azeron_error_string(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = azeron_device_open_index(&device, device_index);
|
||||
if (ret != AZERON_SUCCESS) {
|
||||
fprintf(stderr, "Failed to open device %d: %s\n", device_index, azeron_error_string(ret));
|
||||
azeron_exit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Button Mappings:\n");
|
||||
printf("================\n\n");
|
||||
printf("%-10s %-15s %s\n", "Button", "Type", "Mapping");
|
||||
printf("%-10s %-15s %s\n", "------", "----", "-------");
|
||||
|
||||
/* For now, show placeholder since protocol isn't implemented yet */
|
||||
for (i = 1; i <= 24; i++) {
|
||||
printf("%-10d %-15s %s\n", i, "keyboard", "<not implemented yet>");
|
||||
}
|
||||
|
||||
printf("\nNote: Button mapping functionality requires protocol reverse engineering.\n");
|
||||
printf("This is a placeholder implementation.\n");
|
||||
|
||||
azeron_device_close(device);
|
||||
azeron_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Map button (placeholder) */
|
||||
int cmd_map_button(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s map-button <button-id> <key>\n", argv[0]);
|
||||
fprintf(stderr, "Example: %s map-button 5 KEY_W\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Button mapping is not yet implemented.\n");
|
||||
fprintf(stderr, "Protocol reverse engineering is required for this feature.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set active profile (placeholder) */
|
||||
int cmd_set_profile(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s set-profile <profile-id>\n", argv[0]);
|
||||
fprintf(stderr, "Example: %s set-profile 1\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Profile switching is not yet implemented.\n");
|
||||
fprintf(stderr, "Protocol reverse engineering is required for this feature.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Save profile (placeholder) */
|
||||
int cmd_save_profile(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s save-profile <profile-name>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Profile saving is not yet implemented.\n");
|
||||
fprintf(stderr, "Protocol reverse engineering is required for this feature.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load profile (placeholder) */
|
||||
int cmd_load_profile(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s load-profile <profile-name>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Profile loading is not yet implemented.\n");
|
||||
fprintf(stderr, "Protocol reverse engineering is required for this feature.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Export config (placeholder) */
|
||||
int cmd_export_config(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s export-config <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Config export is not yet implemented.\n");
|
||||
fprintf(stderr, "Protocol reverse engineering is required for this feature.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Import config (placeholder) */
|
||||
int cmd_import_config(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s import-config <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Config import is not yet implemented.\n");
|
||||
fprintf(stderr, "Protocol reverse engineering is required for this feature.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Main function */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *command;
|
||||
int i;
|
||||
|
||||
if (argc < 2) {
|
||||
print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
command = argv[1];
|
||||
|
||||
/* Help command */
|
||||
if (strcmp(command, "help") == 0 || strcmp(command, "--help") == 0 || strcmp(command, "-h") == 0) {
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Version command */
|
||||
if (strcmp(command, "version") == 0 || strcmp(command, "--version") == 0 || strcmp(command, "-v") == 0) {
|
||||
printf("azeron-cli version %s\n", AZERON_CLI_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find and execute command */
|
||||
for (i = 0; commands[i].name != NULL; i++) {
|
||||
if (strcmp(command, commands[i].name) == 0) {
|
||||
return commands[i].func(argc - 1, argv + 1);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown command: %s\n", command);
|
||||
fprintf(stderr, "Use '%s help' for usage information.\n", argv[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
17
azeron-cli/utils.c
Normal file
17
azeron-cli/utils.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Azeron CLI - Utility functions
|
||||
* Copyright (C) 2024 Azeron Linux Project
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* CLI utility functions will be implemented here */
|
||||
|
||||
void cli_utils_init(void)
|
||||
{
|
||||
/* Initialize CLI utilities */
|
||||
}
|
||||
Reference in New Issue
Block a user