parent
6665b5c183
commit
dca02976a7
@ -1 +1 @@ |
||||
Subproject commit 7fce9474395e208c83325ff6150fdd21ba16c9a4 |
||||
Subproject commit a2fe09bb4d610d08806afcc4cc008fc01c0dcee0 |
@ -0,0 +1,220 @@ |
||||
//
|
||||
// Created by MightyPork on 2017/10/01.
|
||||
//
|
||||
|
||||
#include <esp8266.h> |
||||
#include "cgi_d2d.h" |
||||
#include "apars_logging.h" |
||||
#include "version.h" |
||||
#include "ansi_parser_callbacks.h" |
||||
#include <httpclient.h> |
||||
#include <esp_utils.h> |
||||
|
||||
#define D2D_TIMEOUT_MS 2000 |
||||
|
||||
#define D2D_HEADERS \ |
||||
"User-Agent: ESPTerm/"FIRMWARE_VERSION"\r\n" \
|
||||
"Content-Type: text/plain; charset=utf-8\r\n" \
|
||||
"Cache-Control: max-age=0\r\n" |
||||
|
||||
struct d2d_request_opts { |
||||
bool want_body; |
||||
bool want_head; |
||||
char *nonce; |
||||
}; |
||||
|
||||
static void ICACHE_FLASH_ATTR |
||||
requestCb(int http_status, |
||||
const char *response_headers, |
||||
const char *response_body, |
||||
size_t body_size, |
||||
void *userArg) |
||||
{ |
||||
if (userArg == NULL) return; |
||||
struct d2d_request_opts *opts = userArg; |
||||
|
||||
char buff100[100]; |
||||
int len = 0; |
||||
if (opts->want_head) len += strlen(response_headers); |
||||
if (opts->want_body) len += body_size + (opts->want_head*2); |
||||
char *bb = buff100; |
||||
bb += sprintf(bb, "\x1b^h;%d;", http_status); |
||||
const char *comma = ""; |
||||
|
||||
if (opts->want_head) { |
||||
bb += sprintf(bb, "%sH", comma); |
||||
comma = ","; |
||||
} |
||||
|
||||
if (opts->want_body) { |
||||
bb += sprintf(bb, "%sB", comma); |
||||
comma = ","; |
||||
} |
||||
|
||||
if (opts->nonce) { |
||||
bb += sprintf(bb, "%sN=%s", comma, opts->nonce); |
||||
comma = ","; |
||||
} |
||||
|
||||
if (opts->want_head || opts->want_body) { |
||||
bb += sprintf(bb, "%sL=%d", comma, len); |
||||
//comma = ",";
|
||||
} |
||||
|
||||
// semicolon only if more data is to be sent
|
||||
if (opts->want_head || opts->want_body) |
||||
sprintf(bb, ";"); |
||||
|
||||
apars_respond(buff100); |
||||
|
||||
dbg("Response %d, nonce %s", http_status, opts->nonce); |
||||
dbg("Headers %s", response_headers); |
||||
dbg("Body %s", response_body); |
||||
|
||||
// head and payload separated by \r\n\r\n (one \r\n is at the end of head - maybe)
|
||||
if (opts->want_head) { |
||||
apars_respond(response_headers); |
||||
if(opts->want_body) apars_respond("\r\n"); |
||||
} |
||||
|
||||
if(opts->want_body) { |
||||
apars_respond(response_body); |
||||
} |
||||
|
||||
apars_respond("\a"); |
||||
|
||||
free(opts->nonce); |
||||
free(userArg); |
||||
} |
||||
|
||||
bool ICACHE_FLASH_ATTR |
||||
d2d_parse_command(char *msg) |
||||
{ |
||||
char buff40[40]; |
||||
char *p; |
||||
|
||||
#define FIND_NEXT(target, delim) do { \ |
||||
p = strchr(msg, (delim)); \
|
||||
if (p == NULL) return false; \
|
||||
*p = '\0'; \
|
||||
(target) = msg; \
|
||||
msg = p + 1; \
|
||||
} while(0) \
|
||||
|
||||
if (strstarts(msg, "M;")) { |
||||
// Send a esp-esp message
|
||||
msg += 2; |
||||
const char *ip; |
||||
FIND_NEXT(ip, ';'); |
||||
const char *payload = msg; |
||||
|
||||
ansi_dbg("D2D Tx,dest=%s,msg=%s", ip, payload); |
||||
sprintf(buff40, "http://%s" D2D_MSG_ENDPOINT, ip); |
||||
|
||||
httpclient_args args; |
||||
httpclient_args_init(&args); |
||||
args.method = HTTPD_METHOD_POST; |
||||
args.body = payload; |
||||
args.headers = D2D_HEADERS; |
||||
args.timeout = D2D_TIMEOUT_MS; |
||||
args.url = buff40; // "escapes scope" warning - can ignore, strdup is used
|
||||
http_request(&args, NULL); |
||||
return true; |
||||
} |
||||
else if (strstarts(msg, "H;")) { |
||||
// Send a esp-esp message
|
||||
msg += 2; |
||||
const char *method = NULL; |
||||
const char *params = NULL; |
||||
const char *nonce = NULL; |
||||
const char *url = NULL; |
||||
const char *payload = NULL; |
||||
httpd_method methodNum = HTTPD_METHOD_GET; |
||||
|
||||
FIND_NEXT(method, ';'); |
||||
|
||||
if (streq(method, "GET")) methodNum = HTTPD_METHOD_GET; |
||||
else if (streq(method, "POST")) methodNum = HTTPD_METHOD_POST; |
||||
else if (streq(method, "OPTIONS")) methodNum = HTTPD_METHOD_OPTIONS; |
||||
else if (streq(method, "PUT")) methodNum = HTTPD_METHOD_PUT; |
||||
else if (streq(method, "DELETE")) methodNum = HTTPD_METHOD_DELETE; |
||||
else if (streq(method, "PATCH")) methodNum = HTTPD_METHOD_PATCH; |
||||
else if (streq(method, "HEAD")) methodNum = HTTPD_METHOD_HEAD; |
||||
else { |
||||
warn("BAD METHOD: %s, using GET", method); |
||||
} |
||||
|
||||
FIND_NEXT(params, ';'); |
||||
|
||||
dbg("Method %s", method); |
||||
dbg("Params %s", params); |
||||
|
||||
size_t max_len = HTTPCLIENT_DEF_MAX_LEN; |
||||
int timeout = HTTPCLIENT_DEF_TIMEOUT_MS; |
||||
bool want_body = 0; |
||||
bool want_head = 0; |
||||
bool no_resp = 0; |
||||
|
||||
do { |
||||
p = strchr(params, ','); |
||||
if (p != NULL) *p = '\0'; |
||||
const char *param = params; |
||||
if (params[0] == 0) break; // no params
|
||||
|
||||
if(streq(param, "H")) want_head = 1; // Return head
|
||||
else if(streq(param, "B")) want_body = 1; // Return body
|
||||
else if(streq(param, "X")) no_resp = 1; // X - no response, no callback
|
||||
else if(strstarts(param, "L=")) { // max length
|
||||
max_len = atoi(param+2); |
||||
} else if(strstarts(param, "T=")) { // timeout
|
||||
timeout = atoi(param+2); |
||||
} else if(strstarts(param, "N=")) { // Nonce
|
||||
nonce = param+2; |
||||
} else { |
||||
warn("BAD PARAM: %s", param); |
||||
return false; |
||||
} |
||||
|
||||
dbg("- param %s", params); |
||||
|
||||
if (p == NULL) break; |
||||
params = p + 1; |
||||
} while(1); |
||||
|
||||
p = strchr(msg, '\n'); |
||||
if (p != NULL) *p = '\0'; |
||||
url = msg; |
||||
dbg("URL: %s", url); |
||||
|
||||
if (p != NULL) { |
||||
payload = p + 1; |
||||
dbg("Payload: %s", payload); |
||||
} else { |
||||
payload = NULL; |
||||
} |
||||
|
||||
httpclient_args args; |
||||
httpclient_args_init(&args); |
||||
args.method = methodNum; |
||||
args.body = payload; |
||||
args.headers = D2D_HEADERS; |
||||
args.timeout = timeout; |
||||
args.max_response_len = max_len; |
||||
args.url = url; |
||||
|
||||
if (!no_resp) { |
||||
struct d2d_request_opts *opts = malloc(sizeof(struct d2d_request_opts)); |
||||
opts->want_body = want_body; |
||||
opts->want_head = want_head; |
||||
opts->nonce = esp_strdup(nonce); |
||||
args.userData = opts; |
||||
} |
||||
|
||||
http_request(&args, no_resp ? NULL : requestCb); |
||||
|
||||
dbg("Done"); |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
@ -0,0 +1,14 @@ |
||||
//
|
||||
// Created by MightyPork on 2017/10/01.
|
||||
//
|
||||
|
||||
#ifndef ESPTERM_CGI_D2D_H |
||||
#define ESPTERM_CGI_D2D_H |
||||
|
||||
#include <esp8266.h> |
||||
|
||||
#define D2D_MSG_ENDPOINT "/api/v1/msg" |
||||
|
||||
bool d2d_parse_command(char *msg); |
||||
|
||||
#endif //ESPTERM_CGI_D2D_H
|
Loading…
Reference in new issue