rest API for logconfig, also post to /api/pins should now work (untested).

This commit is contained in:
btsimonh
2022-02-10 22:07:30 +00:00
parent 04f28b3d6e
commit 570702dc05
2 changed files with 142 additions and 27 deletions

View File

@ -13,6 +13,9 @@ static int http_rest_app(http_request_t *request);
static int http_rest_post_pins(http_request_t *request);
static int http_rest_get_pins(http_request_t *request);
static int http_rest_post_logconfig(http_request_t *request);
static int http_rest_get_logconfig(http_request_t *request);
void init_rest(){
HTTP_RegisterCallback( "/api/", HTTP_GET, http_rest_get);
HTTP_RegisterCallback( "/api/", HTTP_POST, http_rest_post);
@ -64,6 +67,10 @@ static int http_rest_get(http_request_t *request){
if (!strcmp(request->url, "api/pins")){
return http_rest_get_pins(request);
}
if (!strcmp(request->url, "api/logconfig")){
return http_rest_get_logconfig(request);
}
http_setup(request, httpMimeTypeHTML);
poststr(request, "GET of ");
@ -75,7 +82,6 @@ static int http_rest_get(http_request_t *request){
static int http_rest_get_pins(http_request_t *request){
int i;
char tmp[20];
/*typedef struct pinsState_s {
byte roles[32];
byte channels[32];
@ -87,30 +93,27 @@ static int http_rest_get_pins(http_request_t *request){
poststr(request, "{\"rolenames\":[");
for (i = 0; i < IOR_Total_Options; i++){
if (i){
sprintf(tmp, ",\"%s\"", htmlPinRoleNames[i]);
hprintf128(request, ",\"%s\"", htmlPinRoleNames[i]);
} else {
sprintf(tmp, "\"%s\"", htmlPinRoleNames[i]);
hprintf128(request, "\"%s\"", htmlPinRoleNames[i]);
}
poststr(request, tmp);
}
poststr(request, "],\"roles\":[");
for (i = 0; i < 32; i++){
if (i){
sprintf(tmp, ",%d", g_pins.roles[i]);
hprintf128(request, ",%d", g_pins.roles[i]);
} else {
sprintf(tmp, "%d", g_pins.roles[i]);
hprintf128(request, "%d", g_pins.roles[i]);
}
poststr(request, tmp);
}
poststr(request, "],\"channels\":[");
for (i = 0; i < 32; i++){
if (i){
sprintf(tmp, ",%d", g_pins.channels[i]);
hprintf128(request, ",%d", g_pins.channels[i]);
} else {
sprintf(tmp, "%d", g_pins.channels[i]);
hprintf128(request, "%d", g_pins.channels[i]);
}
poststr(request, tmp);
}
poststr(request, "]}");
poststr(request, NULL);
@ -119,12 +122,116 @@ static int http_rest_get_pins(http_request_t *request){
////////////////////////////
// log config
static int http_rest_get_logconfig(http_request_t *request){
int i;
http_setup(request, httpMimeTypeJson);
hprintf128(request, "{\"level\":%d,", loglevel);
hprintf128(request, "\"features\":%d,", logfeatures);
poststr(request, "\"levelnames\":[");
for (i = 0; i < LOG_MAX; i++){
if (i){
hprintf128(request, ",\"%s\"", loglevelnames[i]);
} else {
hprintf128(request, "\"%s\"", loglevelnames[i]);
}
}
poststr(request, "],\"featurenames\":[");
for (i = 0; i < LOG_FEATURE_MAX; i++){
if (i){
hprintf128(request, ",\"%s\"", logfeaturenames[i]);
} else {
hprintf128(request, "\"%s\"", logfeaturenames[i]);
}
}
poststr(request, "]}");
poststr(request, NULL);
return 0;
}
static int http_rest_post_logconfig(http_request_t *request){
int i;
int r;
char tmp[64];
//https://github.com/zserge/jsmn/blob/master/example/simple.c
//jsmn_parser p;
jsmn_parser *p = malloc(sizeof(jsmn_parser));
//jsmntok_t t[128]; /* We expect no more than 128 tokens */
#define TOKEN_COUNT 128
jsmntok_t *t = malloc(sizeof(jsmntok_t)*TOKEN_COUNT);
char *json_str = request->bodystart;
int json_len = strlen(json_str);
http_setup(request, httpMimeTypeText);
memset(p, 0, sizeof(jsmn_parser));
memset(t, 0, sizeof(jsmntok_t)*128);
jsmn_init(p);
r = jsmn_parse(p, json_str, json_len, t, TOKEN_COUNT);
if (r < 0) {
ADDLOG_ERROR(LOG_FEATURE_API, "Failed to parse JSON: %d", r);
poststr(request, NULL);
free(p);
free(t);
return 0;
}
/* Assume the top-level element is an object */
if (r < 1 || t[0].type != JSMN_OBJECT) {
ADDLOG_ERROR(LOG_FEATURE_API, "Object expected", r);
poststr(request, NULL);
free(p);
free(t);
return 0;
}
//sprintf(tmp,"parsed JSON: %s\n", json_str);
//poststr(request, tmp);
//poststr(request, NULL);
/* Loop over all keys of the root object */
for (i = 1; i < r; i++) {
if (jsoneq(json_str, &t[i], "level") == 0) {
if (t[i + 1].type != JSMN_PRIMITIVE) {
continue; /* We expect groups to be an array of strings */
}
loglevel = atoi(json_str + t[i + 1].start);
i += t[i + 1].size + 1;
} else if (jsoneq(json_str, &t[i], "features") == 0) {
if (t[i + 1].type != JSMN_PRIMITIVE) {
continue; /* We expect groups to be an array of strings */
}
logfeatures = atoi(json_str + t[i + 1].start);;
i += t[i + 1].size + 1;
} else {
ADDLOG_ERROR(LOG_FEATURE_API, "Unexpected key: %.*s", t[i].end - t[i].start,
json_str + t[i].start);
sprintf(tmp,"Unexpected key: %.*s\n", t[i].end - t[i].start,
json_str + t[i].start);
poststr(request, tmp);
}
}
poststr(request, NULL);
free(p);
free(t);
return 0;
}
/////////////////////////////////////////////////
static int http_rest_post(http_request_t *request){
char tmp[20];
ADDLOG_DEBUG(LOG_FEATURE_API, "POST to %s", request->url);
if (!strcmp(request->url, "api/pins")){
return http_rest_post_pins(request);
}
if (!strcmp(request->url, "api/logconfig")){
return http_rest_post_logconfig(request);
}
http_setup(request, httpMimeTypeHTML);
poststr(request, "POST to ");
@ -145,6 +252,7 @@ static int http_rest_post_pins(http_request_t *request){
int i;
int r;
char tmp[64];
int iChanged = 0;
//https://github.com/zserge/jsmn/blob/master/example/simple.c
//jsmn_parser p;
@ -182,46 +290,48 @@ static int http_rest_post_pins(http_request_t *request){
return 0;
}
//sprintf(tmp,"parsed JSON: %s\n", json_str);
//poststr(request, tmp);
//poststr(request, NULL);
/* Loop over all keys of the root object */
/* Loop over all keys of the root object */
for (i = 1; i < r; i++) {
if (jsoneq(json_str, &t[i], "roles") == 0) {
int j;
sprintf(tmp,"- Roles:\n");
poststr(request, tmp);
if (t[i + 1].type != JSMN_ARRAY) {
continue; /* We expect groups to be an array of strings */
}
for (j = 0; j < t[i + 1].size; j++) {
int roleval, pr;
jsmntok_t *g = &t[i + j + 2];
sprintf(tmp," * %.*s\n", g->end - g->start, json_str + g->start);
poststr(request, tmp);
roleval = atoi(json_str + g->start);
pr = PIN_GetPinRoleForPinIndex(i);
if(pr != roleval) {
PIN_SetPinRoleForPinIndex(i,roleval);
iChanged++;
}
}
i += t[i + 1].size + 1;
} else if (jsoneq(json_str, &t[i], "channels") == 0) {
int j;
sprintf(tmp,"- Channels:\n");
poststr(request, tmp);
if (t[i + 1].type != JSMN_ARRAY) {
continue; /* We expect groups to be an array of strings */
}
for (j = 0; j < t[i + 1].size; j++) {
int chanval, pr;
jsmntok_t *g = &t[i + j + 2];
sprintf(tmp," * %.*s\n", g->end - g->start, json_str + g->start);
poststr(request, tmp);
chanval = atoi(json_str + g->start);
pr = PIN_GetPinChannelForPinIndex(j);
if(pr != chanval) {
PIN_SetPinChannelForPinIndex(j,chanval);
iChanged++;
}
}
i += t[i + 1].size + 1;
} else {
ADDLOG_ERROR(LOG_FEATURE_API, "Unexpected key: %.*s", t[i].end - t[i].start,
json_str + t[i].start);
sprintf(tmp,"Unexpected key: %.*s\n", t[i].end - t[i].start,
json_str + t[i].start);
poststr(request, tmp);
}
}
if (iChanged){
PIN_SaveToFlash();
}
poststr(request, NULL);
free(p);