Skip to content
Snippets Groups Projects
Select Git revision
  • d14e1d7e029761f01a2adee25861be9324fb0330
  • main default protected
  • tags/misc
  • tags/version-0.5r2
  • tags/version-0.6
  • tags/version-0.4
  • tags/version-0.5r1
  • tags/libxaal_v01
  • tags/generic-feedback-renderer_complexAPI
  • tags/testing-libsodium
  • tags/testing-nettle
  • tags/testing_ajax
  • tags/testing_clearsilver
  • tags/testing_jansson
  • tags/testing_jsmn
  • tags/testing_json-c
16 results

proto-xaal.c

Blame
  • user avatar
    clohr authored
    git-svn-id: https://redmine.imt-atlantique.fr/svn/xaal/code/C/branches/version-0.7@2291 b32b6428-25c9-4566-ad07-03861ab6144f
    8a290cac
    History
    proto-xaal.c 3.76 KiB
    /* xaaws - xAAL web interface
     * Part of the 'xaaws' software
     * (c) 2019 Christophe Lohr <christophe.lohr@imt-atlantique.fr>
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    #include <libwebsockets.h>
    #include <sys/queue.h>
    #include <json-c/json.h>
    #include <sys/queue.h>
    
    
    #include "proto-xaal.h"
    #include "db.h"
    #include "xaaws.h"
    #include "xaagent.h"
    
    
    int callback_xaal_ctl(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
      struct per_session_data__xaal_ctl *pss = (struct per_session_data__xaal_ctl *)user;
    
      switch (reason) {
    
        case LWS_CALLBACK_ESTABLISHED: {
          req_t *req = (req_t *) malloc( sizeof(req_t) );
          req->wsi = wsi;
          TAILQ_INSERT_TAIL(&(db.jattrreqs), req, entries);
          pss->janswer = NULL;
          pss->tok = json_tokener_new();
          lws_callback_on_writable(wsi);
          break; }
    
    
        case LWS_CALLBACK_SERVER_WRITEABLE:
          if (pss->janswer) {
    	if ( serve_ws_stream(wsi, pss->janswer) ) {
    	  json_object_put(pss->janswer);
    	  pss->janswer = NULL;
    	  break;
    	} else {
    	  lwsl_err("Can't feed WebSocket 'xaal-ctl'\n");
    	  return -1;
    	}
          }
          break;
    
    
        case LWS_CALLBACK_RECEIVE: {
          json_object *jinput;
          enum json_tokener_error jerr;
    
          jinput = json_tokener_parse_ex(pss->tok, in, len);
          jerr = json_tokener_get_error(pss->tok);
    
          switch (jerr) {
    
    	case json_tokener_success:
    	  if (jinput) {
    	    if ( !ws_xAAL_json_request(&bus, &me, jinput) )
    	      lwsl_err("Can't forward xAAL request from 'xaal-ctl'\n");
    	    json_object_put(jinput);
    	  }
    	  json_tokener_free(pss->tok);
    	  pss->tok = json_tokener_new();
    	  break;
    
    	case json_tokener_continue:
    	  break;
    
    	default:
    	  lwsl_err("Can't read WebSocket 'xaal-ctl'. JSON error: %s\n", json_tokener_error_desc(jerr));
    	  json_object_put(jinput);
    	  json_tokener_free(pss->tok);
    	  pss->tok = json_tokener_new();
          }
    
          break; }
    
    
        case LWS_CALLBACK_CLOSED:
          json_tokener_free(pss->tok);
          break;
    
    
        default:
          break;
      }
    
      return 0;
    }
    
    
    
    int callback_xaal_dump(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
      struct per_session_data__xaal_dump *pss = (struct per_session_data__xaal_dump *)user;
    
      switch (reason) {
    
        case LWS_CALLBACK_ESTABLISHED: {
          req_t *req = (req_t *) malloc( sizeof(req_t) );
          req->wsi = wsi;
          TAILQ_INSERT_TAIL(&(db.jmsgreqs), req, entries);
          pss->janswer = NULL;
          lws_callback_on_writable(wsi);
          break; }
    
        case LWS_CALLBACK_SERVER_WRITEABLE:
          if (pss->janswer) {
    	if ( serve_ws_stream(wsi, pss->janswer) ) {
    	  json_object_put(pss->janswer);
    	  pss->janswer = NULL;
    	  break;
    	} else {
    	  lwsl_err("Can't feed WebSocket\n");
    	  return -1;
    	}
          }
          break;
    
        default:
          break;
      }
    
      return 0;
    }
    
    
    
    bool serve_ws_stream(struct lws *wsi, json_object *jobj) {
      const char *json = json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOZERO);
      char buf[ LWS_PRE + strlen(json) + 1 ];
      char *p = &buf[LWS_PRE];
      int n, m;
    
      n = sprintf((char *)p, "%s", json);
      m = lws_write(wsi, (unsigned char *)p, n, LWS_WRITE_TEXT);
      return (m >= n);
    }