|
|
|
@ -630,6 +630,195 @@ static char *escape_string(char *str, bool isjson)
@@ -630,6 +630,195 @@ static char *escape_string(char *str, bool isjson)
|
|
|
|
|
return buf; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_data_type type, void *data, bool copy_data) |
|
|
|
|
{ |
|
|
|
|
struct api_data *api_data; |
|
|
|
|
|
|
|
|
|
api_data = (struct api_data *)malloc(sizeof(struct api_data)); |
|
|
|
|
|
|
|
|
|
api_data->type = type; |
|
|
|
|
api_data->name = name; |
|
|
|
|
|
|
|
|
|
if (root == NULL) { |
|
|
|
|
root = api_data; |
|
|
|
|
root->prev = root; |
|
|
|
|
root->next = root; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
api_data->prev = root->prev; |
|
|
|
|
root->prev = api_data; |
|
|
|
|
api_data->next = root; |
|
|
|
|
api_data->prev->next = api_data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
api_data->data_was_malloc = copy_data; |
|
|
|
|
|
|
|
|
|
if (!copy_data) |
|
|
|
|
api_data->data = data; |
|
|
|
|
else |
|
|
|
|
switch(type) { |
|
|
|
|
case API_ESCAPE: |
|
|
|
|
case API_STRING: |
|
|
|
|
api_data->data = (void *)malloc(strlen((char *)data) + 1); |
|
|
|
|
strcpy((char*)(api_data->data), (char *)data); |
|
|
|
|
break; |
|
|
|
|
case API_INT: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(int)); |
|
|
|
|
*((int *)(api_data->data)) = *((int *)data); |
|
|
|
|
break; |
|
|
|
|
case API_UINT: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(unsigned int)); |
|
|
|
|
*((unsigned int *)(api_data->data)) = *((unsigned int *)data); |
|
|
|
|
break; |
|
|
|
|
case API_UINT64: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(uint64_t)); |
|
|
|
|
*((uint64_t *)(api_data->data)) = *((uint64_t *)data); |
|
|
|
|
break; |
|
|
|
|
case API_ULONG: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(unsigned long)); |
|
|
|
|
*((unsigned long *)(api_data->data)) = *((unsigned long *)data); |
|
|
|
|
break; |
|
|
|
|
case API_DOUBLE: |
|
|
|
|
case API_MHS: |
|
|
|
|
case API_MHTOTAL: |
|
|
|
|
case API_UTILITY: |
|
|
|
|
case API_VOLTS: |
|
|
|
|
case API_HS: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(double)); |
|
|
|
|
*((double *)(api_data->data)) = *((double *)data); |
|
|
|
|
break; |
|
|
|
|
case API_BOOL: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(bool)); |
|
|
|
|
*((bool *)(api_data->data)) = *((bool *)data); |
|
|
|
|
break; |
|
|
|
|
case API_TIMEVAL: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(struct timeval)); |
|
|
|
|
memcpy(api_data->data, data, sizeof(struct timeval)); |
|
|
|
|
break; |
|
|
|
|
case API_TIME: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(time_t)); |
|
|
|
|
*(time_t *)(api_data->data) = *((time_t *)data); |
|
|
|
|
break; |
|
|
|
|
case API_TEMP: |
|
|
|
|
api_data->data = (void *)malloc(sizeof(float)); |
|
|
|
|
*((float *)(api_data->data)) = *((float *)data); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
applog(LOG_ERR, "API: unknown1 data type %d ignored", type); |
|
|
|
|
api_data->type = API_STRING; |
|
|
|
|
api_data->data_was_malloc = false; |
|
|
|
|
api_data->data = (void *)UNKNOWN; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return root; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static struct api_data *print_data(struct api_data *root, char *buf, bool isjson) |
|
|
|
|
{ |
|
|
|
|
struct api_data *tmp; |
|
|
|
|
bool first = true; |
|
|
|
|
char *quote; |
|
|
|
|
|
|
|
|
|
if (isjson) { |
|
|
|
|
strcpy(buf, JSON0); |
|
|
|
|
quote = JSON1; |
|
|
|
|
} else { |
|
|
|
|
strcpy(buf, COMMA); |
|
|
|
|
quote = (char *)BLANK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buf = strchr(buf, '\0'); |
|
|
|
|
|
|
|
|
|
while (root) { |
|
|
|
|
if (!first) |
|
|
|
|
*(buf++) = *COMMA; |
|
|
|
|
else |
|
|
|
|
first = false; |
|
|
|
|
|
|
|
|
|
sprintf(buf, "%s%s%s%s", quote, root->name, quote, isjson ? ":" : "="); |
|
|
|
|
|
|
|
|
|
buf = strchr(buf, '\0'); |
|
|
|
|
|
|
|
|
|
switch(root->type) { |
|
|
|
|
case API_STRING: |
|
|
|
|
sprintf(buf, "%s%s%s", quote, (char *)(root->data), quote); |
|
|
|
|
break; |
|
|
|
|
case API_ESCAPE: |
|
|
|
|
sprintf(buf, "%s%s%s", |
|
|
|
|
quote, |
|
|
|
|
escape_string((char *)(root->data), isjson), |
|
|
|
|
quote); |
|
|
|
|
break; |
|
|
|
|
case API_INT: |
|
|
|
|
sprintf(buf, "%d", *((int *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_UINT: |
|
|
|
|
sprintf(buf, "%u", *((unsigned int *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_UINT64: |
|
|
|
|
sprintf(buf, "%"PRIu64, *((uint64_t *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_ULONG: |
|
|
|
|
case API_TIME: |
|
|
|
|
sprintf(buf, "%lu", *((unsigned long *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_DOUBLE: |
|
|
|
|
sprintf(buf, "%f", *((double *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_UTILITY: |
|
|
|
|
case API_MHS: |
|
|
|
|
sprintf(buf, "%.2f", *((double *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_VOLTS: |
|
|
|
|
sprintf(buf, "%.3f", *((double *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_MHTOTAL: |
|
|
|
|
sprintf(buf, "%.4f", *((double *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_HS: |
|
|
|
|
sprintf(buf, "%.15f", *((double *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
case API_BOOL: |
|
|
|
|
sprintf(buf, "%s", *((bool *)(root->data)) ? "true" : "false"); |
|
|
|
|
break; |
|
|
|
|
case API_TIMEVAL: |
|
|
|
|
sprintf(buf, "%ld.%06ld", |
|
|
|
|
((struct timeval *)(root->data))->tv_sec, |
|
|
|
|
((struct timeval *)(root->data))->tv_usec); |
|
|
|
|
break; |
|
|
|
|
case API_TEMP: |
|
|
|
|
sprintf(buf, "%.2f", *((float *)(root->data))); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
applog(LOG_ERR, "API: unknown2 data type %d ignored", root->type); |
|
|
|
|
sprintf(buf, "%s%s%s", quote, UNKNOWN, quote); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buf = strchr(buf, '\0'); |
|
|
|
|
|
|
|
|
|
if (root->data_was_malloc) |
|
|
|
|
free(root->data); |
|
|
|
|
|
|
|
|
|
if (root->next == root) { |
|
|
|
|
free(root); |
|
|
|
|
root = NULL; |
|
|
|
|
} else { |
|
|
|
|
tmp = root; |
|
|
|
|
root = tmp->next; |
|
|
|
|
root->prev = tmp->prev; |
|
|
|
|
root->prev->next = root; |
|
|
|
|
free(tmp); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (isjson) |
|
|
|
|
strcat(buf, "}"); |
|
|
|
|
|
|
|
|
|
return root; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_AN_FPGA |
|
|
|
|
static int numpgas() |
|
|
|
|
{ |
|
|
|
@ -819,15 +1008,33 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
@@ -819,15 +1008,33 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
|
|
|
|
|
|
|
|
|
|
static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) |
|
|
|
|
{ |
|
|
|
|
struct api_data *root = NULL; |
|
|
|
|
char buf[TMPBUFSIZ]; |
|
|
|
|
|
|
|
|
|
sprintf(io_buffer, isjson |
|
|
|
|
? "%s," JSON_VERSION |
|
|
|
|
: "%s" _VERSION, |
|
|
|
|
message(MSG_VERSION, 0, NULL, isjson)); |
|
|
|
|
|
|
|
|
|
root = api_add_data(root, "CGMiner", API_STRING, VERSION); |
|
|
|
|
root = api_add_data(root, "API", API_STRING, APIVERSION); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
sprintf(io_buffer, isjson |
|
|
|
|
? "%s," JSON_VERSION "{\"CGMiner\":\"%s\",\"API\":\"%s\"}" JSON_CLOSE |
|
|
|
|
: "%s" _VERSION ",CGMiner=%s,API=%s" SEPSTR, |
|
|
|
|
message(MSG_VERSION, 0, NULL, isjson), |
|
|
|
|
VERSION, APIVERSION); |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
root = print_data(root, buf, isjson); |
|
|
|
|
strcat(io_buffer, buf); |
|
|
|
|
strcat(io_buffer, isjson ? JSON_CLOSE : SEPSTR); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) |
|
|
|
|
{ |
|
|
|
|
struct api_data *root = NULL; |
|
|
|
|
char buf[TMPBUFSIZ]; |
|
|
|
|
int gpucount = 0; |
|
|
|
|
int pgacount = 0; |
|
|
|
@ -859,6 +1066,23 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -859,6 +1066,23 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
|
|
|
|
|
cpucount = opt_n_threads > 0 ? num_processors : 0; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
sprintf(io_buffer, isjson |
|
|
|
|
? "%s," JSON_MINECON |
|
|
|
|
: "%s" _MINECON ",", |
|
|
|
|
message(MSG_MINECON, 0, NULL, isjson)); |
|
|
|
|
|
|
|
|
|
root = api_add_data(root, "GPU Count", API_INT, &gpucount); |
|
|
|
|
root = api_add_data(root, "PGA Count", API_INT, &pgacount); |
|
|
|
|
root = api_add_data(root, "CPU Count", API_INT, &cpucount); |
|
|
|
|
root = api_add_data(root, "Pool Count", API_INT, &total_pools); |
|
|
|
|
root = api_add_data(root, "ADL", API_STRING, adl); |
|
|
|
|
root = api_add_data(root, "ADL in use", API_STRING, adlinuse); |
|
|
|
|
root = api_add_data(root, "Strategy", API_STRING, strategies[pool_strategy].s); |
|
|
|
|
root = api_add_data(root, "Log Interval", API_INT, &opt_log_interval); |
|
|
|
|
root = api_add_data(root, "Device Code", API_STRING, DEVICECODE); |
|
|
|
|
root = api_add_data(root, "OS", API_STRING, OSINFO); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
strcpy(io_buffer, message(MSG_MINECON, 0, NULL, isjson)); |
|
|
|
|
|
|
|
|
|
sprintf(buf, isjson |
|
|
|
@ -869,10 +1093,16 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -869,10 +1093,16 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
|
|
|
|
|
strategies[pool_strategy].s, opt_log_interval, DEVICECODE, OSINFO); |
|
|
|
|
|
|
|
|
|
strcat(io_buffer, buf); |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
root = print_data(root, buf, isjson); |
|
|
|
|
strcat(io_buffer, buf); |
|
|
|
|
strcat(io_buffer, isjson ? JSON_CLOSE : SEPSTR); |
|
|
|
|
} |
|
|
|
|
#ifdef HAVE_OPENCL |
|
|
|
|
static void gpustatus(int gpu, bool isjson) |
|
|
|
|
{ |
|
|
|
|
struct api_data *root = NULL; |
|
|
|
|
char intensity[20]; |
|
|
|
|
char buf[TMPBUFSIZ]; |
|
|
|
|
char *enabled; |
|
|
|
@ -909,6 +1139,38 @@ static void gpustatus(int gpu, bool isjson)
@@ -909,6 +1139,38 @@ static void gpustatus(int gpu, bool isjson)
|
|
|
|
|
else |
|
|
|
|
sprintf(intensity, "%d", cgpu->intensity); |
|
|
|
|
|
|
|
|
|
root = api_add_data(root, "GPU", API_INT, &gpu); |
|
|
|
|
root = api_add_data(root, "Enabled", API_STRING, &enabled); |
|
|
|
|
root = api_add_data(root, "Status", API_STRING, &status); |
|
|
|
|
root = api_add_data(root, "Temperature", API_TEMP, >); |
|
|
|
|
root = api_add_data(root, "Fan Speed", API_INT, &gf); |
|
|
|
|
root = api_add_data(root, "Fan Percent", API_INT, &gp); |
|
|
|
|
root = api_add_data(root, "GPU Clock", API_INT, &gc); |
|
|
|
|
root = api_add_data(root, "Memory Clock", API_INT, &gm); |
|
|
|
|
root = api_add_data(root, "GPU Voltage", API_VOLTS, &gv); |
|
|
|
|
root = api_add_data(root, "GPU Activity", API_INT, &ga); |
|
|
|
|
root = api_add_data(root, "Powertune", API_INT, &pt); |
|
|
|
|
|
|
|
|
|
double mhs = cgpu->total_mhashes / total_secs; |
|
|
|
|
root = api_add_data(root, "MHS av", API_MHS, &mhs); |
|
|
|
|
|
|
|
|
|
char mhsname[27]; |
|
|
|
|
sprintf(mhsname, "MHS %ds", opt_log_interval); |
|
|
|
|
root = api_add_data(root, mhsname, API_MHS, &(cgpu->rolling)); |
|
|
|
|
|
|
|
|
|
root = api_add_data(root, "Accepted", API_INT, &(cgpu->accepted)); |
|
|
|
|
root = api_add_data(root, "Rejected", API_INT, &(cgpu->rejected)); |
|
|
|
|
root = api_add_data(root, "Hardware Errors", API_INT, &(cgpu->hw_errors)); |
|
|
|
|
root = api_add_data(root, "Utility", API_UTILITY, &(cgpu->utility)); |
|
|
|
|
root = api_add_data(root, "Intensity", API_STRING, intensity); |
|
|
|
|
|
|
|
|
|
unsigned long last_share_pool = cgpu->last_share_pool_time > 0 ? cgpu->last_share_pool : -1; |
|
|
|
|
root = api_add_data(root, "Last Share Pool", API_INT, &last_share_pool); |
|
|
|
|
|
|
|
|
|
root = api_add_data(root, "Last Share Time", API_ULONG, &(cgpu->last_share_pool_time)); |
|
|
|
|
root = api_add_data(root, "Total MH", API_MHTOTAL, &(cgpu->total_mhashes)); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
sprintf(buf, isjson |
|
|
|
|
? "{\"GPU\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"Fan Speed\":%d,\"Fan Percent\":%d,\"GPU Clock\":%d,\"Memory Clock\":%d,\"GPU Voltage\":%.3f,\"GPU Activity\":%d,\"Powertune\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Intensity\":\"%s\",\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}" |
|
|
|
|
: "GPU=%d,Enabled=%s,Status=%s,Temperature=%.2f,Fan Speed=%d,Fan Percent=%d,GPU Clock=%d,Memory Clock=%d,GPU Voltage=%.3f,GPU Activity=%d,Powertune=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Intensity=%s,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f" SEPSTR, |
|
|
|
@ -920,6 +1182,10 @@ static void gpustatus(int gpu, bool isjson)
@@ -920,6 +1182,10 @@ static void gpustatus(int gpu, bool isjson)
|
|
|
|
|
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes); |
|
|
|
|
|
|
|
|
|
strcat(io_buffer, buf); |
|
|
|
|
*/ |
|
|
|
|
root = print_data(root, buf, isjson); |
|
|
|
|
strcat(io_buffer, buf); |
|
|
|
|
strcat(io_buffer, isjson ? BLANK : SEPSTR); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|