-static void aws_on_close(struct afb_websock *ws, uint16_t code, size_t size)
-{
- /* do nothing */
-}
-
-static void aws_on_readable(struct afb_websock *ws)
-{
- websock_dispatch(ws->ws);
-}
-
-static int aws_handle_json(struct afb_websock *aws, struct json_object *obj)
-{
- struct afb_req r;
- int count, num;
- struct json_object *type, *id, *name, *req, *token;
- struct afb_wsreq *wsreq;
- const char *api, *verb;
- size_t lenapi, lenverb;
-
- /* protocol inspired by http://www.gir.fr/ocppjs/ocpp_srpc_spec.shtml */
-
- /* the object must be an array of 4 or 5 elements */
- if (!json_object_is_type(obj, json_type_array))
- goto error;
- count = json_object_array_length(obj);
- if (count < 4 || count > 5)
- goto error;
-
- /* get the 5 elements: type id name request token */
- type = json_object_array_get_idx(obj, 0);
- id = json_object_array_get_idx(obj, 1);
- name = json_object_array_get_idx(obj, 2);
- req = json_object_array_get_idx(obj, 3);
- token = json_object_array_get_idx(obj, 4);
-
- /* check the types: int string string object string */
- if (!json_object_is_type(type, json_type_int))
- goto error;
- if (!json_object_is_type(id, json_type_string))
- goto error;
- if (!json_object_is_type(name, json_type_string))
- goto error;
- if (!json_object_is_type(req, json_type_object))
- goto error;
- if (token != NULL && !json_object_is_type(token, json_type_string))
- goto error;
-
- /* the type is only 2 */
- num = json_object_get_int(type);
- if (num != 2)
- goto error;
-
- /* checks the api/verb structure of name */
- api = json_object_get_string(name);
- for (lenapi = 0 ; api[lenapi] && api[lenapi] != '/' ; lenapi++);
- if (!lenapi || !api[lenapi])
- goto error;
- verb = &api[lenapi+1];
- for (lenverb = 0 ; verb[lenverb] && verb[lenverb] != '/' ; lenverb++);
- if (!lenverb || verb[lenverb])
- goto error;
-
- /* allocates the request data */
- wsreq = malloc(sizeof *wsreq);
- if (wsreq == NULL)
- goto error;
-
- /* fill and record the request */
- wsreq->aws = aws;
- wsreq->id = json_object_get(id);
- wsreq->name = json_object_get(name);
- wsreq->token = json_object_get(token);
- wsreq->request = json_object_get(req);
- wsreq->next = aws->requests;
- aws->requests = wsreq;
- json_object_put(obj);
-
- r.data = wsreq;
- r.itf = &wsreq_itf;
- afb_apis_call(r, aws->context, api, lenapi, verb, lenverb);
- return 1;
-
-error:
- json_object_put(obj);
- return 0;
-}
-
-static void aws_on_content(struct afb_websock *ws, int last, size_t size)
-{
- ssize_t rrc;
- char buffer[8000];
- struct json_object *obj;
-
- json_tokener_reset(ws->tokener);
- while(size) {
- rrc = websock_read(ws->ws, buffer,
- size > sizeof buffer ? sizeof buffer : size);
- if (rrc < 0) {
- websock_close(ws->ws);
- return;
- }
- size -= (size_t)rrc;
- obj = json_tokener_parse_ex(ws->tokener, buffer, (int)rrc);
- if (obj != NULL) {
- if (!aws_handle_json(ws, obj)) {
- websock_close(ws->ws);
- return;
- }
- } else if (json_tokener_get_error(ws->tokener) != json_tokener_continue) {
- websock_close(ws->ws);
- return;
- }
- }
-}
-
-static struct afb_arg wsreq_get(struct afb_wsreq *wsreq, const char *name)
-{
- struct afb_arg arg;
- struct json_object *value;
-
- if (json_object_object_get_ex(wsreq->request, name, &value)) {
- arg.name = name;
- arg.value = json_object_get_string(value);
- arg.size = strlen(arg.value);
- } else {
- arg.name = NULL;
- arg.value = NULL;
- arg.size = 0;
- }
- arg.path = NULL;
- return arg;
-}
-
-static void wsreq_iterate(struct afb_wsreq *wsreq, int (*iterator)(void *closure, struct afb_arg arg), void *closure)
-{
- struct afb_arg arg;
- struct json_object_iterator it = json_object_iter_begin(wsreq->request);
- struct json_object_iterator end = json_object_iter_end(wsreq->request);
-
- arg.size = 0;
- arg.path = NULL;
- while(!json_object_iter_equal(&it, &end)) {
- arg.name = json_object_iter_peek_name(&it);
- arg.value = json_object_get_string(json_object_iter_peek_value(&it));
- if (!iterator(closure, arg))
- break;
- json_object_iter_next(&it);
- }
-}
-
-static int wsreq_session_create(struct afb_wsreq *wsreq)
-{
- struct AFB_clientCtx *context = wsreq->aws->context;
- if (context->created)
- return 0;
- return wsreq_session_check(wsreq, 1);
-}
-
-static int wsreq_session_check(struct afb_wsreq *wsreq, int refresh)
-{
- const char *token;
- struct AFB_clientCtx *context = wsreq->aws->context;
-
- if (wsreq->token == NULL)
- return 0;
-
- token = json_object_get_string(wsreq->token);
- if (token == NULL)
- return 0;
-
- if (!ctxTokenCheck (context, token))