Browse Source

api.c data structure - 2nd - untested

Kano 13 years ago
parent
commit
538653a53e
2 changed files with 455 additions and 104 deletions
  1. 434 100
      api.c
  2. 21 4
      miner.h

+ 434 - 100
api.c

@@ -251,7 +251,8 @@ static const char ISJSON = '{';
 #define JSON1		"\""
 #define JSON2		"\":["
 #define JSON3		"]"
-#define JSON4		",\"id\":1}"
+#define JSON4		",\"id\":1"
+#define JSON5		"}"
 
 #define JSON_START	JSON0
 #define JSON_DEVS	JSON1 _DEVS JSON2
@@ -280,7 +281,7 @@ static const char ISJSON = '{';
 #define JSON_CLOSE	JSON3
 #define JSON_MINESTATS	JSON1 _MINESTATS JSON2
 #define JSON_CHECK	JSON1 _CHECK JSON2
-#define JSON_END	JSON4
+#define JSON_END	JSON4 JSON5
 
 static const char *JSON_COMMAND = "command";
 static const char *JSON_PARAMETER = "parameter";
@@ -630,14 +631,14 @@ 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)
+static 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;
+	api_data->type = type;
 
 	if (root == NULL) {
 		root = api_data;
@@ -659,6 +660,7 @@ struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_d
 		switch(type) {
 		case API_ESCAPE:
 		case API_STRING:
+		case API_CONST:
 			api_data->data = (void *)malloc(strlen((char *)data) + 1);
 			strcpy((char*)(api_data->data), (char *)data);
 			break;
@@ -670,19 +672,19 @@ struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_d
 			api_data->data = (void *)malloc(sizeof(unsigned int));
 			*((unsigned int *)(api_data->data)) = *((unsigned int *)data);
 			break;
+		case API_UINT32:
+			api_data->data = (void *)malloc(sizeof(uint32_t));
+			*((uint32_t *)(api_data->data)) = *((uint32_t *)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_FREQ:
 		case API_HS:
 			api_data->data = (void *)malloc(sizeof(double));
 			*((double *)(api_data->data)) = *((double *)data);
@@ -699,6 +701,7 @@ struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_d
 			api_data->data = (void *)malloc(sizeof(time_t));
 			*(time_t *)(api_data->data) = *((time_t *)data);
 			break;
+		case API_VOLTS:
 		case API_TEMP:
 			api_data->data = (void *)malloc(sizeof(float));
 			*((float *)(api_data->data)) = *((float *)data);
@@ -714,21 +717,109 @@ struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_d
 	return root;
 }
 
+struct api_data *api_add_escape(struct api_data *root, char *name, char *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_ESCAPE, (void *)data, copy_data);
+}
+
+struct api_data *api_add_string(struct api_data *root, char *name, char *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_STRING, (void *)data, copy_data);
+}
+
+struct api_data *api_add_const(struct api_data *root, char *name, const char *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_CONST, (void *)data, copy_data);
+}
+
+struct api_data *api_add_int(struct api_data *root, char *name, int *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_INT, (void *)data, copy_data);
+}
+
+struct api_data *api_add_uint(struct api_data *root, char *name, unsigned int *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_UINT, (void *)data, copy_data);
+}
+
+struct api_data *api_add_uint32(struct api_data *root, char *name, uint32_t *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_UINT32, (void *)data, copy_data);
+}
+
+struct api_data *api_add_uint64(struct api_data *root, char *name, uint64_t *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_UINT64, (void *)data, copy_data);
+}
+
+struct api_data *api_add_double(struct api_data *root, char *name, double *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_DOUBLE, (void *)data, copy_data);
+}
+
+struct api_data *api_add_bool(struct api_data *root, char *name, bool *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_BOOL, (void *)data, copy_data);
+}
+
+struct api_data *api_add_timeval(struct api_data *root, char *name, struct timeval *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_TIMEVAL, (void *)data, copy_data);
+}
+
+struct api_data *api_add_time(struct api_data *root, char *name, time_t *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_TIME, (void *)data, copy_data);
+}
+
+struct api_data *api_add_mhs(struct api_data *root, char *name, double *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_MHS, (void *)data, copy_data);
+}
+
+struct api_data *api_add_mhtotal(struct api_data *root, char *name, double *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_MHTOTAL, (void *)data, copy_data);
+}
+
+struct api_data *api_add_temp(struct api_data *root, char *name, float *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_TEMP, (void *)data, copy_data);
+}
+
+struct api_data *api_add_utility(struct api_data *root, char *name, double *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_UTILITY, (void *)data, copy_data);
+}
+
+struct api_data *api_add_freq(struct api_data *root, char *name, double *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_FREQ, (void *)data, copy_data);
+}
+
+struct api_data *api_add_volts(struct api_data *root, char *name, float *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_VOLTS, (void *)data, copy_data);
+}
+
+struct api_data *api_add_hs(struct api_data *root, char *name, double *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_HS, (void *)data, copy_data);
+}
+
 static struct api_data *print_data(struct api_data *root, char *buf, bool isjson)
 {
 	struct api_data *tmp;
 	bool first = true;
+	char *original, *escape;
 	char *quote;
 
 	if (isjson) {
 		strcpy(buf, JSON0);
+		buf = strchr(buf, '\0');
 		quote = JSON1;
-	} else {
-		strcpy(buf, COMMA);
+	} else
 		quote = (char *)BLANK;
-	}
-
-	buf = strchr(buf, '\0');
 
 	while (root) {
 		if (!first)
@@ -742,13 +833,15 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
 
 		switch(root->type) {
 		case API_STRING:
+		case API_CONST:
 			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);
+			original = (char *)(root->data);
+			escape = escape_string((char *)(root->data), isjson);
+			sprintf(buf, "%s%s%s", quote, escape, quote);
+			if (escape != original)
+				free(escape);
 			break;
 		case API_INT:
 			sprintf(buf, "%d", *((int *)(root->data)));
@@ -756,10 +849,12 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
 		case API_UINT:
 			sprintf(buf, "%u", *((unsigned int *)(root->data)));
 			break;
+		case API_UINT32:
+			sprintf(buf, "%"PRIu32, *((uint32_t *)(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;
@@ -767,11 +862,12 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
 			sprintf(buf, "%f", *((double *)(root->data)));
 			break;
 		case API_UTILITY:
+		case API_FREQ:
 		case API_MHS:
 			sprintf(buf, "%.2f", *((double *)(root->data)));
 			break;
 		case API_VOLTS:
-			sprintf(buf, "%.3f", *((double *)(root->data)));
+			sprintf(buf, "%.3f", *((float *)(root->data)));
 			break;
 		case API_MHTOTAL:
 			sprintf(buf, "%.4f", *((double *)(root->data)));
@@ -813,8 +909,7 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
 		}
 	}
 
-	if (isjson)
-		strcat(buf, "}");
+	strcpy(buf, isjson ? JSON5 : SEPSTR);
 
 	return root;
 }
@@ -880,7 +975,9 @@ static int pgadevice(int pgaid)
 //  and send_result() adds JSON_END at the end
 static char *message(int messageid, int paramid, char *param2, bool isjson)
 {
-	char severity;
+	struct api_data *root = NULL;
+	char buf[TMPBUFSIZ];
+	char severity[2];
 	char *ptr;
 #ifdef HAVE_AN_FPGA
 	int pga;
@@ -890,49 +987,50 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
 #endif
 	int i;
 
+	if (!isjson)
+		msg_buffer[0] = '\0';
+	else
+		strcpy(msg_buffer, JSON_START JSON_STATUS);
+
+	ptr = strchr(msg_buffer, '\0');
+
 	for (i = 0; codes[i].severity != SEVERITY_FAIL; i++) {
 		if (codes[i].code == messageid) {
 			switch (codes[i].severity) {
 			case SEVERITY_WARN:
-				severity = 'W';
+				severity[0] = 'W';
 				break;
 			case SEVERITY_INFO:
-				severity = 'I';
+				severity[0] = 'I';
 				break;
 			case SEVERITY_SUCC:
-				severity = 'S';
+				severity[0] = 'S';
 				break;
 			case SEVERITY_ERR:
 			default:
-				severity = 'E';
+				severity[0] = 'E';
 				break;
 			}
-
-			sprintf(msg_buffer, isjson
-				? JSON_START JSON_STATUS "{\"" _STATUS "\":\"%c\",\"When\":%lu,\"Code\":%d,\"Msg\":\""
-				: _STATUS "=%c,When=%lu,Code=%d,Msg=",
-				severity, (unsigned long)when, messageid);
-
-			ptr = msg_buffer + strlen(msg_buffer);
+			severity[1] = '\0';
 
 			switch(codes[i].params) {
 			case PARAM_GPU:
 			case PARAM_PGA:
 			case PARAM_CPU:
-				sprintf(ptr, codes[i].description, paramid);
+				sprintf(buf, codes[i].description, paramid);
 				break;
 			case PARAM_POOL:
-				sprintf(ptr, codes[i].description, paramid, pools[paramid]->rpc_url);
+				sprintf(buf, codes[i].description, paramid, pools[paramid]->rpc_url);
 				break;
 #ifdef HAVE_OPENCL
 			case PARAM_GPUMAX:
-				sprintf(ptr, codes[i].description, paramid, nDevs - 1);
+				sprintf(buf, codes[i].description, paramid, nDevs - 1);
 				break;
 #endif
 #ifdef HAVE_AN_FPGA
 			case PARAM_PGAMAX:
 				pga = numpgas();
-				sprintf(ptr, codes[i].description, paramid, pga - 1);
+				sprintf(buf, codes[i].description, paramid, pga - 1);
 				break;
 #endif
 #ifdef WANT_CPUMINE
@@ -941,14 +1039,14 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
 					cpu = num_processors;
 				else
 					cpu = 0;
-				sprintf(ptr, codes[i].description, paramid, cpu - 1);
+				sprintf(buf, codes[i].description, paramid, cpu - 1);
 				break;
 #endif
 			case PARAM_PMAX:
-				sprintf(ptr, codes[i].description, total_pools);
+				sprintf(buf, codes[i].description, total_pools);
 				break;
 			case PARAM_POOLMAX:
-				sprintf(ptr, codes[i].description, paramid, total_pools - 1);
+				sprintf(buf, codes[i].description, paramid, total_pools - 1);
 				break;
 			case PARAM_DMAX:
 #ifdef HAVE_AN_FPGA
@@ -961,7 +1059,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
 					cpu = 0;
 #endif
 
-				sprintf(ptr, codes[i].description
+				sprintf(buf, codes[i].description
 #ifdef HAVE_OPENCL
 					, nDevs
 #endif
@@ -974,36 +1072,52 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
 					);
 				break;
 			case PARAM_CMD:
-				sprintf(ptr, codes[i].description, JSON_COMMAND);
+				sprintf(buf, codes[i].description, JSON_COMMAND);
 				break;
 			case PARAM_STR:
-				sprintf(ptr, codes[i].description, param2);
+				sprintf(buf, codes[i].description, param2);
 				break;
 			case PARAM_BOTH:
-				sprintf(ptr, codes[i].description, paramid, param2);
+				sprintf(buf, codes[i].description, paramid, param2);
 				break;
 			case PARAM_NONE:
 			default:
-				strcpy(ptr, codes[i].description);
+				strcpy(buf, codes[i].description);
 			}
 
-			ptr = msg_buffer + strlen(msg_buffer);
-
-			sprintf(ptr, isjson
-				? "\",\"Description\":\"%s\"}" JSON_CLOSE
-				: ",Description=%s" SEPSTR,
-				opt_api_description);
+			root = api_add_string(root, _STATUS, severity, false);
+			root = api_add_time(root, "When", &when, false);
+			root = api_add_int(root, "Code", &messageid, false);
+			root = api_add_string(root, "Msg", buf, false);
+			root = api_add_string(root, "Description", opt_api_description, false);
 
+			root = print_data(root, ptr, isjson);
+			if (isjson)
+				strcat(ptr, JSON_CLOSE);
 			return msg_buffer;
 		}
 	}
 
+	root = api_add_string(root, _STATUS, "F", false);
+	root = api_add_time(root, "When", &when, false);
+	int id = -1;
+	root = api_add_int(root, "Code", &id, false);
+	sprintf(buf, "%d", messageid);
+	root = api_add_string(root, "Msg", buf, false);
+	root = api_add_string(root, "Description", opt_api_description, false);
+
+	root = print_data(root, ptr, isjson);
+	if (isjson)
+		strcat(ptr, JSON_CLOSE);
+	return msg_buffer;
+/*
 	sprintf(msg_buffer, isjson
 		? JSON_START JSON_STATUS "{\"" _STATUS "\":\"F\",\"When\":%lu,\"Code\":-1,\"Msg\":\"%d\",\"Description\":\"%s\"}" JSON_CLOSE
 		: _STATUS "=F,When=%lu,Code=-1,Msg=%d,Description=%s" SEPSTR,
 		(unsigned long)when, messageid, opt_api_description);
 
 	return msg_buffer;
+*/
 }
 
 static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
@@ -1013,11 +1127,11 @@ static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 
 	sprintf(io_buffer, isjson
 		? "%s," JSON_VERSION
-		: "%s" _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);
+	root = api_add_string(root, "CGMiner", VERSION, false);
+	root = api_add_const(root, "API", APIVERSION, false);
 
 /*
 	sprintf(io_buffer, isjson
@@ -1028,8 +1142,9 @@ static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 */
 
 	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
 	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)
@@ -1071,16 +1186,16 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 		: "%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);
+	root = api_add_int(root, "GPU Count", &gpucount, false);
+	root = api_add_int(root, "PGA Count", &pgacount, false);
+	root = api_add_int(root, "CPU Count", &cpucount, false);
+	root = api_add_int(root, "Pool Count", &total_pools, false);
+	root = api_add_const(root, "ADL", (char *)adl, false);
+	root = api_add_string(root, "ADL in use", adlinuse, false);
+	root = api_add_const(root, "Strategy", strategies[pool_strategy].s, false);
+	root = api_add_int(root, "Log Interval", &opt_log_interval, false);
+	root = api_add_const(root, "Device Code", DEVICECODE, false);
+	root = api_add_const(root, "OS", OSINFO, false);
 
 /*
 	strcpy(io_buffer, message(MSG_MINECON, 0, NULL, isjson));
@@ -1096,8 +1211,9 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 */
 
 	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
 	strcat(io_buffer, buf);
-	strcat(io_buffer, isjson ? JSON_CLOSE : SEPSTR);
 }
 #ifdef HAVE_OPENCL
 static void gpustatus(int gpu, bool isjson)
@@ -1139,36 +1255,32 @@ 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, &gt);
-		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);
-
+		root = api_add_int(root, "GPU", &gpu, false);
+		root = api_add_string(root, "Enabled", enabled, false);
+		root = api_add_string(root, "Status", status, false);
+		root = api_add_temp(root, "Temperature", &gt, false);
+		root = api_add_int(root, "Fan Speed", &gf, false);
+		root = api_add_int(root, "Fan Percent", &gp, false);
+		root = api_add_int(root, "GPU Clock", &gc, false);
+		root = api_add_int(root, "Memory Clock", &gm, false);
+		root = api_add_volts(root, "GPU Voltage", &gv, false);
+		root = api_add_int(root, "GPU Activity", &ga, false);
+		root = api_add_int(root, "Powertune", &pt, false);
 		double mhs = cgpu->total_mhashes / total_secs;
-		root = api_add_data(root, "MHS av", API_MHS, &mhs);
-
+		root = api_add_mhs(root, "MHS av", &mhs, false);
 		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));
+		root = api_add_mhs(root, mhsname, &(cgpu->rolling), false);
+		root = api_add_int(root, "Accepted", &(cgpu->accepted), false);
+		root = api_add_int(root, "Rejected", &(cgpu->rejected), false);
+		root = api_add_int(root, "Hardware Errors", &(cgpu->hw_errors), false);
+		root = api_add_utility(root, "Utility", &(cgpu->utility), false);
+		root = api_add_string(root, "Intensity", intensity, false);
+		int last_share_pool = cgpu->last_share_pool_time > 0 ?
+					cgpu->last_share_pool : -1;
+		root = api_add_int(root, "Last Share Pool", &last_share_pool, false);
+		root = api_add_time(root, "Last Share Time", &(cgpu->last_share_pool_time), false);
+		root = api_add_mhtotal(root, "Total MH", &(cgpu->total_mhashes), false);
 
 		/*
 		sprintf(buf, isjson
@@ -1185,13 +1297,13 @@ static void gpustatus(int gpu, bool isjson)
 		*/
 		root = print_data(root, buf, isjson);
 		strcat(io_buffer, buf);
-		strcat(io_buffer, isjson ? BLANK : SEPSTR);
 	}
 }
 #endif
 #ifdef HAVE_AN_FPGA
 static void pgastatus(int pga, bool isjson)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	char *enabled;
 	char *status;
@@ -1250,6 +1362,31 @@ static void pgastatus(int pga, bool isjson)
 		else
 			status = (char *)ALIVE;
 
+		root = api_add_int(root, "PGA", &pga, false);
+		root = api_add_string(root, "Name", cgpu->api->name, false);
+		root = api_add_int(root, "ID", &(cgpu->device_id), false);
+		root = api_add_string(root, "Enabled", enabled, false);
+		root = api_add_string(root, "Status", status, false);
+		root = api_add_temp(root, "Temperature", &temp, false);
+		double mhs = cgpu->total_mhashes / total_secs;
+		root = api_add_mhs(root, "MHS av", &mhs, false);
+		char mhsname[27];
+		sprintf(mhsname, "MHS %ds", opt_log_interval);
+		root = api_add_mhs(root, mhsname, &(cgpu->rolling), false);
+		root = api_add_int(root, "Accepted", &(cgpu->accepted), false);
+		root = api_add_int(root, "Rejected", &(cgpu->rejected), false);
+		root = api_add_int(root, "Hardware Errors", &(cgpu->hw_errors), false);
+		root = api_add_utility(root, "Utility", &(cgpu->utility), false);
+		int last_share_pool = cgpu->last_share_pool_time > 0 ?
+					cgpu->last_share_pool : -1;
+		root = api_add_int(root, "Last Share Pool", &last_share_pool, false);
+		root = api_add_time(root, "Last Share Time", &(cgpu->last_share_pool_time), false);
+		root = api_add_mhtotal(root, "Total MH", &(cgpu->total_mhashes), false);
+		root = api_add_freq(root, "Frequency", &frequency, false);
+
+		root = print_data(root, buf, isjson);
+		strcat(io_buffer, buf);
+/*
 		sprintf(buf, isjson
 			? "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f,\"Frequency\":%.2f}"
 			: "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f,Frequency=%.2f" SEPSTR,
@@ -1261,6 +1398,7 @@ static void pgastatus(int pga, bool isjson)
 			(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, frequency);
 
 		strcat(io_buffer, buf);
+*/
 	}
 }
 #endif
@@ -1268,6 +1406,7 @@ static void pgastatus(int pga, bool isjson)
 #ifdef WANT_CPUMINE
 static void cpustatus(int cpu, bool isjson)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 
 	if (opt_n_threads > 0 && cpu >= 0 && cpu < num_processors) {
@@ -1275,6 +1414,24 @@ static void cpustatus(int cpu, bool isjson)
 
 		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
 
+		root = api_add_int(root, "CPU", &cpu, false);
+		double mhs = cgpu->total_mhashes / total_secs;
+		root = api_add_mhs(root, "MHS av", &mhs, false);
+		char mhsname[27];
+		sprintf(mhsname, "MHS %ds", opt_log_interval);
+		root = api_add_mhs(root, mhsname, &(cgpu->rolling), false);
+		root = api_add_int(root, "Accepted", &(cgpu->accepted), false);
+		root = api_add_int(root, "Rejected", &(cgpu->rejected), false);
+		root = api_add_utility(root, "Utility", &(cgpu->utility), false);
+		int last_share_pool = cgpu->last_share_pool_time > 0 ?
+					cgpu->last_share_pool : -1;
+		root = api_add_int(root, "Last Share Pool", &last_share_pool, false);
+		root = api_add_time(root, "Last Share Time", &(cgpu->last_share_pool_time), false);
+		root = api_add_mhtotal(root, "Total MH", &(cgpu->total_mhashes), false);
+
+		root = print_data(root, buf, isjson);
+		strcat(io_buffer, buf);
+/*
 		sprintf(buf, isjson
 			? "{\"CPU\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}"
 			: "CPU=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f" SEPSTR,
@@ -1286,6 +1443,7 @@ static void cpustatus(int cpu, bool isjson)
 			(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes);
 
 		strcat(io_buffer, buf);
+*/
 	}
 }
 #endif
@@ -1557,10 +1715,9 @@ static void cpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __mayb
 
 static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	char *status, *lp;
-	char *rpc_url;
-	char *rpc_user;
 	int i;
 
 	if (total_pools == 0) {
@@ -1601,6 +1758,22 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 		else
 			lp = (char *)NO;
 
+		root = api_add_int(root, "POOL", &i, false);
+		root = api_add_escape(root, "URL", pool->rpc_url, false);
+		root = api_add_string(root, "Status", status, false);
+		root = api_add_int(root, "Priority", &(pool->prio), false);
+		root = api_add_string(root, "Long Poll", lp, false);
+		root = api_add_uint(root, "Getworks", &(pool->getwork_requested), false);
+		root = api_add_int(root, "Accepted", &(pool->accepted), false);
+		root = api_add_int(root, "Rejected", &(pool->rejected), false);
+		root = api_add_uint(root, "Discarded", &(pool->discarded_work), false);
+		root = api_add_uint(root, "Stale", &(pool->stale_shares), false);
+		root = api_add_uint(root, "Get Failures", &(pool->getfail_occasions), false);
+		root = api_add_uint(root, "Remote Failures", &(pool->remotefail_occasions), false);
+		root = api_add_escape(root, "User", pool->rpc_user, false);
+		root = api_add_time(root, "Last Share Time", &(pool->last_share_time), false);
+
+/*
 		rpc_url = escape_string(pool->rpc_url, isjson);
 		rpc_user = escape_string(pool->rpc_user, isjson);
 
@@ -1626,6 +1799,12 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 		if (rpc_user != pool->rpc_user)
 			free(rpc_user);
 		rpc_user = NULL;
+*/
+		if (isjson && (i > 0))
+			strcat(io_buffer, COMMA);
+
+		root = print_data(root, buf, isjson);
+		strcat(io_buffer, buf);
 	}
 
 	if (isjson)
@@ -1634,6 +1813,8 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 
 static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
+	char buf[TMPBUFSIZ];
 	double utility, mhs;
 
 #ifdef WANT_CPUMINE
@@ -1645,6 +1826,30 @@ static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo
 	utility = total_accepted / ( total_secs ? total_secs : 1 ) * 60;
 	mhs = total_mhashes_done / total_secs;
 
+	sprintf(io_buffer, isjson
+		? "%s," JSON_SUMMARY
+		: "%s" _SUMMARY ",",
+		message(MSG_SUMM, 0, NULL, isjson));
+
+	root = api_add_double(root, "Elapsed", &(total_secs), false);
+#ifdef WANT_CPUMINE
+	root = api_add_string(root, "Algorithm", algo, false);
+#endif
+	root = api_add_mhs(root, "MHS av", &(mhs), false);
+	root = api_add_uint(root, "Found Blocks", &(found_blocks), false);
+	root = api_add_int(root, "Getworks", &(total_getworks), false);
+	root = api_add_int(root, "Accepted", &(total_accepted), false);
+	root = api_add_int(root, "Rejected", &(total_rejected), false);
+	root = api_add_int(root, "Hardware Errors", &(hw_errors), false);
+	root = api_add_utility(root, "Utility", &(utility), false);
+	root = api_add_int(root, "Discarded", &(total_discarded), false);
+	root = api_add_int(root, "Stale", &(total_stale), false);
+	root = api_add_uint(root, "Get Failures", &(total_go), false);
+	root = api_add_uint(root, "Local Work", &(local_work), false);
+	root = api_add_uint(root, "Remote Failures", &(total_ro), false);
+	root = api_add_uint(root, "Network Blocks", &(new_blocks), false);
+	root = api_add_mhs(root, "Total MH", &(total_mhashes_done), false);
+/*
 #ifdef WANT_CPUMINE
 	sprintf(io_buffer, isjson
 		? "%s," JSON_SUMMARY "{\"Elapsed\":%.0f,\"Algorithm\":\"%s\",\"MHS av\":%.2f,\"Found Blocks\":%d,\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Local Work\":%u,\"Remote Failures\":%u,\"Network Blocks\":%u,\"Total MH\":%.4f}" JSON_CLOSE
@@ -1664,6 +1869,12 @@ static void summary(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, boo
 		hw_errors, utility, total_discarded, total_stale,
 		total_go, local_work, total_ro, new_blocks, total_mhashes_done);
 #endif
+*/
+
+	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
+	strcat(io_buffer, buf);
 }
 #ifdef HAVE_OPENCL
 static void gpuenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
@@ -1769,6 +1980,7 @@ static void gpurestart(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __
 #endif
 static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	int numgpu = 0;
 
@@ -1776,6 +1988,13 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
 	numgpu = nDevs;
 #endif
 
+	sprintf(io_buffer, isjson
+		? "%s," JSON_GPUS
+		: "%s" _GPUS ",",
+		message(MSG_NUMGPU, 0, NULL, isjson));
+
+	root = api_add_int(root, "Count", &numgpu, false);
+/*
 	strcpy(io_buffer, message(MSG_NUMGPU, 0, NULL, isjson));
 
 	sprintf(buf, isjson
@@ -1784,10 +2003,17 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
 		numgpu);
 
 	strcat(io_buffer, buf);
+*/
+
+	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
+	strcat(io_buffer, buf);
 }
 
 static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	int count = 0;
 
@@ -1795,6 +2021,13 @@ static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
 	count = numpgas();
 #endif
 
+	sprintf(io_buffer, isjson
+		? "%s," JSON_PGAS
+		: "%s" _PGAS ",",
+		message(MSG_NUMPGA, 0, NULL, isjson));
+
+	root = api_add_int(root, "Count", &count, false);
+/*
 	strcpy(io_buffer, message(MSG_NUMPGA, 0, NULL, isjson));
 
 	sprintf(buf, isjson
@@ -1803,10 +2036,17 @@ static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
 		count);
 
 	strcat(io_buffer, buf);
+*/
+
+	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
+	strcat(io_buffer, buf);
 }
 
 static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	int count = 0;
 
@@ -1814,6 +2054,13 @@ static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
 	count = opt_n_threads > 0 ? num_processors : 0;
 #endif
 
+	sprintf(io_buffer, isjson
+		? "%s," JSON_CPUS
+		: "%s" _CPUS ",",
+		message(MSG_NUMCPU, 0, NULL, isjson));
+
+	root = api_add_int(root, "Count", &count, false);
+/*
 	strcpy(io_buffer, message(MSG_NUMCPU, 0, NULL, isjson));
 
 	sprintf(buf, isjson
@@ -1822,6 +2069,12 @@ static void cpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
 		count);
 
 	strcat(io_buffer, buf);
+*/
+
+	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
+	strcat(io_buffer, buf);
 }
 
 static void switchpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group)
@@ -2234,6 +2487,7 @@ void privileged(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool is
 
 void notifystatus(int device, struct cgpu_info *cgpu, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	char *reason;
 
@@ -2271,7 +2525,23 @@ void notifystatus(int device, struct cgpu_info *cgpu, bool isjson, __maybe_unuse
 		}
 
 	// ALL counters (and only counters) must start the name with a '*'
-	// Simplifies future external support for adding new counters
+	// Simplifies future external support for identifying new counters
+	root = api_add_int(root, "NOTIFY", &device, false);
+	root = api_add_string(root, "Name", cgpu->api->name, false);
+	root = api_add_int(root, "ID", &(cgpu->device_id), false);
+	root = api_add_time(root, "Last Well", &(cgpu->device_last_well), false);
+	root = api_add_time(root, "Last Not Well", &(cgpu->device_last_not_well), false);
+	root = api_add_string(root, "Reason Not Well", reason, false);
+	root = api_add_int(root, "*Thread Fail Init", &(cgpu->thread_fail_init_count), false);
+	root = api_add_int(root, "*Thread Zero Hash", &(cgpu->thread_zero_hash_count), false);
+	root = api_add_int(root, "*Thread Fail Queue", &(cgpu->thread_fail_queue_count), false);
+	root = api_add_int(root, "*Dev Sick Idle 60s", &(cgpu->dev_sick_idle_60_count), false);
+	root = api_add_int(root, "*Dev Dead Idle 600s", &(cgpu->dev_dead_idle_600_count), false);
+	root = api_add_int(root, "*Dev Nostart", &(cgpu->dev_nostart_count), false);
+	root = api_add_int(root, "*Dev Over Heat", &(cgpu->dev_over_heat_count), false);
+	root = api_add_int(root, "*Dev Thermal Cutoff", &(cgpu->dev_thermal_cutoff_count), false);
+
+/*
 	sprintf(buf, isjson
 		? "%s{\"NOTIFY\":%d,\"Name\":\"%s\",\"ID\":%d,\"Last Well\":%lu,\"Last Not Well\":%lu,\"Reason Not Well\":\"%s\",\"*Thread Fail Init\":%d,\"*Thread Zero Hash\":%d,\"*Thread Fail Queue\":%d,\"*Dev Sick Idle 60s\":%d,\"*Dev Dead Idle 600s\":%d,\"*Dev Nostart\":%d,\"*Dev Over Heat\":%d,\"*Dev Thermal Cutoff\":%d}"
 		: "%sNOTIFY=%d,Name=%s,ID=%d,Last Well=%lu,Last Not Well=%lu,Reason Not Well=%s,*Thread Fail Init=%d,*Thread Zero Hash=%d,*Thread Fail Queue=%d,*Dev Sick Idle 60s=%d,*Dev Dead Idle 600s=%d,*Dev Nostart=%d,*Dev Over Heat=%d,*Dev Thermal Cutoff=%d" SEPSTR,
@@ -2284,6 +2554,13 @@ void notifystatus(int device, struct cgpu_info *cgpu, bool isjson, __maybe_unuse
 		cgpu->dev_over_heat_count, cgpu->dev_thermal_cutoff_count);
 
 	strcat(io_buffer, buf);
+*/
+
+	if (isjson && (device > 0))
+		strcat(io_buffer, COMMA);
+
+	root = print_data(root, buf, isjson);
+	strcat(io_buffer, buf);
 }
 
 static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, char group)
@@ -2311,6 +2588,7 @@ static void notify(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool
 
 static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	struct cgpu_info *cgpu;
 	int i;
@@ -2330,6 +2608,15 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 	for (i = 0; i < total_devices; i++) {
 		cgpu = devices[i];
 
+		root = api_add_int(root, "DEVDETAILS", &i, false);
+		root = api_add_string(root, "Name", cgpu->api->name, false);
+		root = api_add_int(root, "ID", &(cgpu->device_id), false);
+		root = api_add_string(root, "Driver", cgpu->api->dname, false);
+		root = api_add_const(root, "Kernel", cgpu->kname ? : BLANK, false);
+		root = api_add_const(root, "Model", cgpu->name ? : BLANK, false);
+		root = api_add_const(root, "Device Path", cgpu->device_path ? : BLANK, false);
+
+/*
 		sprintf(buf, isjson
 			? "%s{\"DEVDETAILS\":%d,\"Name\":\"%s\",\"ID\":%d,\"Driver\":\"%s\",\"Kernel\":\"%s\",\"Model\":\"%s\",\"Device Path\":\"%s\"}"
 			: "%sDEVDETAILS=%d,Name=%s,ID=%d,Driver=%s,Kernel=%s,Model=%s,Device Path=%s" SEPSTR,
@@ -2339,6 +2626,12 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 			cgpu->name ? : BLANK, cgpu->device_path ? : BLANK);
 
 		strcat(io_buffer, buf);
+*/
+		if (isjson && (i > 0))
+			strcat(io_buffer, COMMA);
+
+		root = print_data(root, buf, isjson);
+		strcat(io_buffer, buf);
 	}
 
 	if (isjson)
@@ -2378,13 +2671,33 @@ void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unuse
 
 static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgminer_pool_stats *pool_stats, char *extra, bool isjson)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 
-	if (stats->getwork_calls || (extra != NULL && *extra))
-	{
+	if (stats->getwork_calls || (extra != NULL && *extra)) {
 		if (extra == NULL)
 			extra = (char *)BLANK;
 
+		root = api_add_int(root, "STATS", &i, false);
+		root = api_add_string(root, "ID", id, false);
+		root = api_add_double(root, "Elapsed", &(total_secs), false);
+		root = api_add_uint32(root, "Calls", &(stats->getwork_calls), false);
+		root = api_add_timeval(root, "Wait", &(stats->getwork_wait), false);
+		root = api_add_timeval(root, "Max", &(stats->getwork_wait_max), false);
+		root = api_add_timeval(root, "Min", &(stats->getwork_wait_min), false);
+
+		if (pool_stats) {
+			root = api_add_uint32(root, "Pool Calls", &(pool_stats->getwork_calls), false);
+			root = api_add_uint32(root, "Pool Attempts", &(pool_stats->getwork_attempts), false);
+			root = api_add_timeval(root, "Pool Wait", &(pool_stats->getwork_wait), false);
+			root = api_add_timeval(root, "Pool Max", &(pool_stats->getwork_wait_max), false);
+			root = api_add_timeval(root, "Pool Min", &(pool_stats->getwork_wait_min), false);
+			root = api_add_double(root, "Pool Av", &(pool_stats->getwork_wait_rolling), false);
+		}
+
+// TODO: zzzz handle extra <- rewrite the api interface
+
+/*
 		sprintf(buf, isjson
 			? "%s{\"STATS\":%d,\"ID\":\"%s\",\"Elapsed\":%.0f,\"Calls\":%d,\"Wait\":%ld.%06ld,\"Max\":%ld.%06ld,\"Min\":%ld.%06ld"
 			: "%sSTATS=%d,ID=%s,Elapsed=%.0f,Calls=%d,Wait=%ld.%06ld,Max=%ld.%06ld,Min=%ld.%06ld",
@@ -2415,6 +2728,12 @@ static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgmine
 			*extra ? COMMA : BLANK, extra);
 
 		strcat(io_buffer, buf);
+*/
+		if (isjson && (i > 0))
+			strcat(io_buffer, COMMA);
+
+		root = print_data(root, buf, isjson);
+		strcat(io_buffer, buf);
 
 		i++;
 	}
@@ -2515,6 +2834,7 @@ struct CMDS {
 
 static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group)
 {
+	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
 	char cmdbuf[100];
 	bool found, access;
@@ -2539,6 +2859,14 @@ static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson,
 		}
 	}
 
+	sprintf(io_buffer, isjson
+		? "%s," JSON_CHECK
+		: "%s" _CHECK ",",
+		message(MSG_CHECK, 0, NULL, isjson));
+
+	root = api_add_const(root, "Exists", found ? YES : NO, false);
+	root = api_add_const(root, "Access", access ? YES : NO, false);
+/*
 	strcpy(io_buffer, message(MSG_CHECK, 0, NULL, isjson));
 
 	sprintf(buf, isjson
@@ -2548,6 +2876,12 @@ static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson,
 		access ? YES : NO);
 
 	strcat(io_buffer, buf);
+*/
+
+	root = print_data(root, buf, isjson);
+	if (isjson)
+		strcat(buf, JSON_CLOSE);
+	strcat(io_buffer, buf);
 }
 
 static void send_result(SOCKETTYPE c, bool isjson)

+ 21 - 4
miner.h

@@ -794,10 +794,11 @@ extern void app_restart(void);
 enum api_data_type {
 	API_ESCAPE,
 	API_STRING,
+	API_CONST,
 	API_INT,
 	API_UINT,
+	API_UINT32,
 	API_UINT64,
-	API_ULONG,
 	API_DOUBLE,
 	API_BOOL,
 	API_TIMEVAL,
@@ -806,6 +807,7 @@ enum api_data_type {
 	API_MHTOTAL,
 	API_TEMP,
 	API_UTILITY,
+	API_FREQ,
 	API_VOLTS,
 	API_HS
 };
@@ -819,8 +821,23 @@ struct api_data {
 	struct api_data *next;
 };
 
-extern struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_data_type type, void *data, bool copy_data);
-#define api_add_data_copy(r, n, t, d) api_add_data_full((r), (n), (t), (void *)(d), true)
-#define api_add_data(r, n, t, d) api_add_data_full((r), (n), (t), (void *)(d), false)
+extern struct api_data *api_add_escape(struct api_data *root, char *name, char *data, bool copy_data);
+extern struct api_data *api_add_string(struct api_data *root, char *name, char *data, bool copy_data);
+extern struct api_data *api_add_const(struct api_data *root, char *name, const char *data, bool copy_data);
+extern struct api_data *api_add_int(struct api_data *root, char *name, int *data, bool copy_data);
+extern struct api_data *api_add_uint(struct api_data *root, char *name, unsigned int *data, bool copy_data);
+extern struct api_data *api_add_uint32(struct api_data *root, char *name, uint32_t *data, bool copy_data);
+extern struct api_data *api_add_uint64(struct api_data *root, char *name, uint64_t *data, bool copy_data);
+extern struct api_data *api_add_double(struct api_data *root, char *name, double *data, bool copy_data);
+extern struct api_data *api_add_bool(struct api_data *root, char *name, bool *data, bool copy_data);
+extern struct api_data *api_add_timeval(struct api_data *root, char *name, struct timeval *data, bool copy_data);
+extern struct api_data *api_add_time(struct api_data *root, char *name, time_t *data, bool copy_data);
+extern struct api_data *api_add_mhs(struct api_data *root, char *name, double *data, bool copy_data);
+extern struct api_data *api_add_mhstotal(struct api_data *root, char *name, double *data, bool copy_data);
+extern struct api_data *api_add_temp(struct api_data *root, char *name, float *data, bool copy_data);
+extern struct api_data *api_add_utility(struct api_data *root, char *name, double *data, bool copy_data);
+extern struct api_data *api_add_freq(struct api_data *root, char *name, double *data, bool copy_data);
+extern struct api_data *api_add_volts(struct api_data *root, char *name, float *data, bool copy_data);
+extern struct api_data *api_add_hs(struct api_data *root, char *name, double *data, bool copy_data);
 
 #endif /* __MINER_H__ */