Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON-output #332

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ set(SOURCE_FILES ${SOURCE_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/device_registry.h
${CMAKE_CURRENT_SOURCE_DIR}/hid_utility.c
${CMAKE_CURRENT_SOURCE_DIR}/hid_utility.h
${CMAKE_CURRENT_SOURCE_DIR}/output.c
${CMAKE_CURRENT_SOURCE_DIR}/output.h
${CMAKE_CURRENT_SOURCE_DIR}/utility.c
${CMAKE_CURRENT_SOURCE_DIR}/utility.h
PARENT_SCOPE)
135 changes: 117 additions & 18 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "device.h"
#include "device_registry.h"
#include "hid_utility.h"
#include "output.h"
#include "utility.h"

#include <hidapi.h>
Expand All @@ -35,13 +36,15 @@

int hsc_device_timeout = 5000;

// 0=false; 1=true
static int short_output = 0;
// 0=text; 1=short; 2=json
static int output = 0;

static t_output json_output;

/// printf only when short output not specified
#define PRINT_INFO(...) \
{ \
if (!short_output) { \
if (output == 0) { \
printf(__VA_ARGS__); \
} \
}
Expand All @@ -63,6 +66,14 @@ static int find_device(struct device* device_found)

if (found == 0) {
PRINT_INFO("Found %s!\n", device_found->device_name);
if (output == 2) {
char* device_name = malloc(strlen(device_found->device_name) + 2);
strcpy(device_name, "\"");
strcat(device_name, device_found->device_name);
strcat(device_name, "\"");
output_add(&json_output, new_entry("device", device_name));
free(device_name);
}
break;
}

Expand Down Expand Up @@ -185,14 +196,52 @@ static int handle_feature(struct device* device_found, hid_device** device_handl
case CAP_BATTERY_STATUS:
ret = device_found->request_battery(*device_handle);

if (ret < 0)
if (ret < 0) {
break;
else if (ret == BATTERY_CHARGING)
short_output ? printf("-1") : printf("Battery: Charging\n");
else if (ret == BATTERY_UNAVAILABLE)
short_output ? printf("-2") : printf("Battery: Unavailable\n");
else
short_output ? printf("%d", ret) : printf("Battery: %d%%\n", ret);
}

else if (ret == BATTERY_CHARGING) {
switch (output) {
case 0:
printf("Battery: Charging\n");
break;
case 1:
printf("-1");
break;
case 2:
output_add(&json_output, new_entry("battery", "charging"));
break;
}
} else if (ret == BATTERY_UNAVAILABLE) {
switch (output) {
case 0:
printf("Battery: Unavailable\n");
break;
case 1:
printf("-2");
break;
case 2:
output_add(&json_output, new_entry("battery", "unavailable"));
break;
}
} else {
switch (output) {
case 0: {
printf("Battery: %d%%\n", ret);
break;
}
case 1: {
printf("%d", ret);
break;
}
case 2: {
char buffer[16];
sprintf(buffer, "%d", ret);
output_add(&json_output, new_entry("battery", buffer));
break;
}
}
}

break;

Expand All @@ -216,10 +265,26 @@ static int handle_feature(struct device* device_found, hid_device** device_handl
case CAP_CHATMIX_STATUS:
ret = device_found->request_chatmix(*device_handle);

if (ret < 0)
if (ret < 0) {
break;
}

short_output ? printf("%d", ret) : printf("Chat-Mix: %d\n", ret);
switch (output) {
case 0: {
printf("Chat-Mix: %d\n", ret);
break;
}
case 1: {
printf("%d", ret);
break;
}
case 2: {
char buffer[16];
sprintf(buffer, "%d", ret);
output_add(&json_output, new_entry("chatmix", buffer));
break;
}
}
break;

case CAP_VOICE_PROMPTS:
Expand Down Expand Up @@ -325,6 +390,7 @@ int main(int argc, char* argv[])
{ "microphone-mute-led-brightness", required_argument, NULL, 0 },
{ "microphone-volume", required_argument, NULL, 0 },
{ "inactive-time", required_argument, NULL, 'i' },
{ "json-output", no_argument, NULL, 'j' },
{ "light", required_argument, NULL, 'l' },
{ "follow", optional_argument, NULL, 'f' },
{ "notificate", required_argument, NULL, 'n' },
Expand All @@ -344,15 +410,15 @@ int main(int argc, char* argv[])
// describes the headsetcontrol device, when a headset was found
static struct device device_found;

while ((c = getopt_long(argc, argv, "bchi:l:f::mn:r:s:uv:p:e:?", opts, &option_index)) != -1) {
while ((c = getopt_long(argc, argv, "bchi:jl:f::mn:r:s:uv:p:e:?", opts, &option_index)) != -1) {
char* endptr = NULL; // for strtol

switch (c) {
case 'b':
request_battery = 1;
break;
case 'c':
short_output = 1;
output = 1;
break;
case 'e': {
int size = get_float_data_from_parameter(optarg, read_buffer, BUFFERLENGTH);
Expand Down Expand Up @@ -392,6 +458,9 @@ int main(int argc, char* argv[])
return 1;
}
break;
case 'j':
output = 2;
break;
case 'l':
lights = strtol(optarg, &endptr, 10);
if (*endptr != '\0' || endptr == optarg || lights < 0 || lights > 1) {
Expand Down Expand Up @@ -455,6 +524,7 @@ int main(int argc, char* argv[])
printf(" -n, --notificate soundid\tMakes the headset play a notifiation\n");
printf(" -l, --light 0|1\t\tSwitch lights (0 = off, 1 = on)\n");
printf(" -c, --short-output\t\tUse more machine-friendly output \n");
printf(" -j, --json-output\t\tUse json-format output \n");
printf(" -i, --inactive-time time\tSets inactive time in minutes, time must be between 0 and 90, 0 disables the feature.\n");
printf(" -m, --chatmix\t\t\tRetrieves the current chat-mix-dial level setting between 0 and 128. Below 64 is the game side and above is the chat side.\n");
printf(" -v, --voice-prompt 0|1\tTurn voice prompts on or off (0 = off, 1 = on)\n");
Expand Down Expand Up @@ -502,7 +572,8 @@ int main(int argc, char* argv[])
}
break;
} else if (strcmp(opts[option_index].name, "connected") == 0) {
short_output = 1;
if (output == 0)
output = 1;
if (find_device(&device_found) != 0) {
return 1;
}
Expand All @@ -526,6 +597,10 @@ int main(int argc, char* argv[])
fprintf(stderr, "Non-option argument %s\n", argv[index]);
}

if (output == 2) {
json_output = new_output();
}

// Look for a supported device
int headset_available = find_device(&device_found);
if (headset_available != 0) {
Expand Down Expand Up @@ -607,17 +682,41 @@ int main(int argc, char* argv[])
if (print_capabilities != -1) {
PRINT_INFO("Supported capabilities:\n\n");

char json_string[256];
strcpy(json_string, "[");

// go through all enum capabilities
for (int i = 0; i < NUM_CAPABILITIES; i++) {
// When the capability i is included in .capabilities
if ((device_found.capabilities & B(i)) == B(i)) {
if (short_output) {
printf("%c", capabilities_str_short[i]);
} else {
switch (output) {
case 0: {
printf("* %s\n", capabilities_str[i]);
break;
}
case 1: {
printf("%c", capabilities_str_short[i]);
break;
}
case 2: {
char buffer[64];
sprintf(buffer, "\"%s\",", capabilities_str[i]);
strcat(json_string, buffer);
break;
}
}
}
}
if (output == 2) {
json_string[strlen(json_string) - 1] = ']';
output_add(&json_output, new_entry("capabilities", json_string));
}
}

if (output == 2) {
char* json = gen_output(&json_output);
printf("%s\n", json);
output_free(&json_output);
}

if (request_connected) {
Expand Down
63 changes: 63 additions & 0 deletions src/output.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include "output.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

t_entry* new_entry(char* key, char* value)
{
t_entry* entry = malloc(sizeof(t_entry));
entry->key = strdup(key);
entry->value = strdup(value);
return entry;
}

t_output new_output()
{
t_output output;
output.entries = malloc(0);
output.length = 0;
return output;
}

void output_add(t_output* output, t_entry* entry)
{
output->length++;
output->entries = realloc(output->entries, output->length * sizeof(t_entry));
output->entries[output->length - 1] = *entry;
}

void output_free(t_output* output)
{
free(output->entries);
output->length = 0;
}

char* gen_output(t_output* output)
{
if (output->length == 0) {
return strdup("{}");
}

size_t max_length = 2; // For '{' and '}'
for (size_t i = 0; i < output->length; i++) {
max_length += strlen(output->entries[i].key) + strlen(output->entries[i].value) + 5; // 5 for quotes, colon, and comma
}

char* result = (char*)malloc(max_length + 1); // Allocate memory for the result string
if (result == NULL) {
// Handle memory allocation failure
return NULL;
}

strcpy(result, "{");
for (size_t i = 0; i < output->length; i++) {
char entry[64];
sprintf(entry, "\"%s\":%s,", output->entries[i].key, output->entries[i].value);
strcat(result, entry);
}

result[strlen(result) - 1] = '}'; // Replace the last comma with '}'
char* dup_result = strdup(result);
free(result);
return dup_result;
}
21 changes: 21 additions & 0 deletions src/output.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

typedef struct {
char* key;
char* value;
} t_entry;

t_entry* new_entry(char* key, char* value);

typedef struct {
t_entry* entries;
int length;
} t_output;

t_output new_output();

void output_add(t_output* output, t_entry* entry);

void output_free(t_output* output);

char* gen_output(t_output* output);
Loading