static const char *test_realloc(void) {
  struct json_token *p;
  ASSERT(parse_json2("{ foo: 2 }", 2) == NULL);
  ASSERT((p = parse_json2("{ foo: 2 }", 10)) != NULL);
  free(p);
  return NULL;
}
Exemple #2
0
int WebController::Setup(){
  log_info("Initialize");
  char fileName[256];
  absolutePath("settings/setup.cnf", fileName);
  MappedFile mmFile;
  if(mmapNamedFile(mmFile, fileName)){
    log_info("Failed to read setup file");
    return -1;
  }

  json_token *setup = NULL;
  setup = parse_json2(mmFile.addr, mmFile.filesize);

  json_str(setup,"machine",settings_file_);
  json_str(setup,"gcodefile",current_gcode_file_);

  free(setup);
  unmapFile(mmFile);
  return 0;
}
Exemple #3
0
static void clubby_proto_handle_frame(char *data, size_t len, void *context) {
  struct json_token *frame = parse_json2(data, len);

  if (frame == NULL) {
    LOG(LL_DEBUG, ("Error parsing clubby frame"));
    return;
  }

  struct json_token *tmp;

  tmp = find_json_token(frame, "resp");
  if (tmp != NULL) {
    clubby_proto_parse_resp(tmp, context);
  }

  tmp = find_json_token(frame, "cmds");
  if (tmp != NULL) {
    clubby_proto_parse_req(frame, tmp, context);
  }

  free(frame);
}
Exemple #4
0
static void clubby_proto_handle_frame(struct mg_str data) {
  struct json_token *frame = parse_json2(data.p, data.len);

  if (frame == NULL) {
    LOG(LL_DEBUG, ("Error parsing clubby frame"));
    return;
  }

  struct json_token *tmp;

  tmp = find_json_token(frame, "resp");
  if (tmp != NULL) {
    clubby_proto_parse_resp(tmp);
  }

  tmp = find_json_token(frame, "cmds");
  if (tmp != NULL) {
    clubby_proto_parse_req(frame, tmp);
  }

  free(frame);
}
static int fill_manifest(struct update_context *ctx) {
  struct json_token *toks =
      parse_json2((char *) ctx->data, ctx->file_info.file_size);
  if (toks == NULL) {
    LOG(LL_ERROR, ("Failed to parse manifest"));
    goto error;
  }

  struct json_token *parts_tok = find_json_token(toks, "parts");
  if (parts_tok == NULL) {
    LOG(LL_ERROR, ("parts token not found in manifest"));
    goto error;
  }

  if (fill_part_info(ctx, parts_tok, "fw", &ctx->fw_part) < 0 ||
      fill_part_info(ctx, parts_tok, "fs", &ctx->fs_part) < 0) {
    goto error;
  }

  struct json_token *version_tok = find_json_token(toks, "version");
  if (version_tok == NULL || version_tok->type != JSON_TYPE_STRING ||
      version_tok->len != sizeof(ctx->version)) {
    LOG(LL_ERROR, ("version token not found in manifest"));
    goto error;
  }

  memcpy(ctx->version, version_tok->ptr, sizeof(ctx->version));
  LOG(LL_DEBUG, ("Version: %.*s", sizeof(ctx->version), ctx->version));

  context_remove_data(ctx, ctx->file_info.file_size);

  return 1;

error:
  ctx->status_msg = "Invalid manifest";
  return -1;
}
Exemple #6
0
void WebController::SetMotionParams(const char *buf, size_t len) {
  log_info("SetMotionParams");
  json_token *jsontoken = NULL;
  jsontoken = parse_json2(buf, len);

  char * name = NULL;
  json_token *token;

  MOTION_PARAMS *p=Interpreter->GetMotionParams();
  double maxAccel,maxVel,countsPerUnit;
  double breakAngle,collinearTol,cornerTol,facetAngle,tpLookahead;

  breakAngle = collinearTol = cornerTol = facetAngle = tpLookahead = 0;
  json_double(jsontoken,"tplanner.breakangle",&breakAngle);
  json_double(jsontoken,"tplanner.cornertolerance",&cornerTol);
  json_double(jsontoken,"tplanner.lookahead",&tpLookahead);
  json_double(jsontoken,"tplanner.collineartolerance",&collinearTol);
  json_double(jsontoken,"tplanner.facetangle",&facetAngle);

  p->BreakAngle = breakAngle;
  p->CollinearTol = collinearTol;
  p->CornerTol = cornerTol;
  p->FacetAngle = facetAngle;
  p->TPLookahead = tpLookahead;

  //TODO
  //p->RadiusA = m_RadiusA;
  //p->RadiusB = m_RadiusB;
  //p->RadiusC = m_RadiusC;

  char path[64];
  for(int i= 0;i<6;i++){

    sprintf(path,"axes[%i]",i);
    token = find_json_token(jsontoken, path);
    if(token){
      maxAccel = maxVel = countsPerUnit = 0.0;
      json_str(token,"name",&name,1);
      json_double(token,"countsPerUnit",&countsPerUnit);
      json_double(token,"maxAccel",&maxAccel);
      json_double(token,"maxVel",&maxVel);

      // default values form KMotionCNCDlg.c
      maxAccel = maxAccel == 0.0?0.01:maxAccel;
      maxVel = maxVel == 0.0?0.1:maxVel;
      //Zero on countPerUnit will abort GCode
      countsPerUnit = countsPerUnit == 0.0?100.0:countsPerUnit;
      switch (name[0]) {
        case 'X':
          p->CountsPerInchX = countsPerUnit;
          p->MaxAccelX = maxAccel;
          p->MaxVelX = maxVel;
          break;
        case 'Y':
          p->CountsPerInchY = countsPerUnit;
          p->MaxAccelY = maxAccel;
          p->MaxVelY = maxVel;
          break;
        case 'Z':
          p->CountsPerInchZ = countsPerUnit;
          p->MaxAccelZ = maxAccel;
          p->MaxVelZ = maxVel;
          break;
        case 'A':
          p->CountsPerInchA = countsPerUnit;
          p->MaxAccelA = maxAccel;
          p->MaxVelA = maxVel;
          break;
        case 'B':
          p->CountsPerInchB = countsPerUnit;
          p->MaxAccelB = maxAccel;
          p->MaxVelB = maxVel;
          break;
        case 'C':
          p->CountsPerInchC = countsPerUnit;
          p->MaxAccelC = maxAccel;
          p->MaxVelC = maxVel;
          break;
      }

    } else {
      printf("Failed %s\n",path);
    }

  }
  free(name);
  //M2-M9,S index 2-9
  //userButtons index 11-20
  //M100-M119 index 21 -39
  //Special actions index 41 -48
  setInterpreterActionParams(jsontoken, 0,MAX_MCODE_ACTIONS_M1,"actions[%i]");
  setInterpreterActionParams(jsontoken, MCODE_ACTIONS_SPECIAL_OFFSET,MAX_MCODE_ACTIONS_SPECIAL,"specialActions[%i]");
  setInterpreterActionParams(jsontoken, MAX_MCODE_ACTIONS_M1,MAX_MCODE_ACTIONS_BUTTONS,"userActions[%i]");
  setInterpreterActionParams(jsontoken, MCODE_ACTIONS_M100_OFFSET,MAX_MCODE_ACTIONS_M100,"extendedActions[%i]");


  //printf("X %lf, %lf, %lf \n",p->CountsPerInchX,p->MaxAccelX, p->MaxVelX );
  //printf("Y %lf, %lf, %lf \n",p->CountsPerInchY,p->MaxAccelY, p->MaxVelY );
  //printf("Z %lf, %lf, %lf \n",p->CountsPerInchZ,p->MaxAccelZ, p->MaxVelZ );
  //printf("A %lf, %lf, %lf \n",p->CountsPerInchA,p->MaxAccelA, p->MaxVelA );
  //printf("B %lf, %lf, %lf \n",p->CountsPerInchB,p->MaxAccelB, p->MaxVelB );
  //printf("C %lf, %lf, %lf \n",p->CountsPerInchC,p->MaxAccelC, p->MaxVelC );

  //TODO
  //strcpy(Interpreter->ToolFile,m_ToolFile);
  //strcpy(Interpreter->SetupFile,m_SetupFile);
  //strcpy(Interpreter->GeoFile,m_GeoFile);
  //strcpy(Interpreter->VarsFile,m_VarsFile);
  //p->DegreesA = m_DegreesA!=0;
  //p->DegreesB = m_DegreesB!=0;
  //p->DegreesC = m_DegreesC!=0;
  p->ArcsToSegs = true;;

  Interpreter->CoordMotion->SetTPParams();

  free(jsontoken);
}
Exemple #7
0
int WebController::HandleJsonRequest(struct mg_connection *conn, const char *object, const char *func) {

  json_token *data = NULL;
  json_token *paramtoken;
  char *content;
  int params;
  int ret;

  content = strndup(conn->content, conn->content_len);
  debug("%s",content);

  free(content);

  data = parse_json2(conn->content, conn->content_len);
  if (data == NULL) {
    debug("parsing api request failed");
    return MG_FALSE;
  }

  params = 0;

  paramtoken = find_json_token(data, "params");
  if (paramtoken != NULL) {
    if (paramtoken->type == JSON_TYPE_OBJECT) {
      params = 1;

    } else if (paramtoken->type == JSON_TYPE_ARRAY) {
      params = paramtoken->num_desc;
    } else {
      params = 1;
    }
  }

  //Reset global response string
  gp_response[0] = '\0';
  //gp_response = (char*) malloc(sizeof(char) * ( MAX_LINE));
  ret = 0;
  if (!strcmp("kmx", object)) {
    if (FUNC_SIGP("loadGlobalFile", 2)) {
      int fileType = -1;
      char * file = NULL;
      toki(paramtoken + 1, &fileType);
      toks(paramtoken + 2, &file, 0);
      if (file != NULL) {
        if(strlen(file) > 0){
          if(fileType == 1){
            this->LoadGcode(file);
          } else if(fileType == 2){
            this->LoadMachineConfiguration(file);
          }
        }
        free(file);
      }
    } else if(FUNC_SIGP("listDir", 1)){
      ListDir(paramtoken);
    } else if (FUNC_SIGP("jog", 2)) {
      int axis;
      int speed;
      toki(paramtoken + 1, &axis);
      toki(paramtoken + 2, &speed);
      this->Jog(axis, speed);
    } else if (FUNC_SIGP("onFeedhold", 0)) {
      this->Feedhold();
    } else if (FUNC_SIGP("onSimulate", 0)) {
      this->Simulate();
    } else if (FUNC_SIGP("onEmergencyStop", 0)) {
      this->EmergencyStop();
    } else if (FUNC_SIGP("onHalt", 0)) {
      this->Halt();
    } else if (FUNC_SIGP("onStep", 0)) {
      this->Step();
    } else if (FUNC_SIGP("onReset", 0)) {
      this->Reset();
    } else if (FUNC_SIGP("onCycleStart", 0)) {
      this->CycleStart();
    } else if(FUNC_SIGP("onUpdateMotionParams", 0)) {
      this->UpdateMotionParams();
    } else if (FUNC_SIGP("onInvokeAction", 1)) {
      BOOL FlushBeforeUnbufferedOperation = FALSE;
      int action;
      toki(paramtoken + 1, &action);
      ret = this->InvokeAction(action,FlushBeforeUnbufferedOperation);
    } else if (FUNC_SIGP("onDoErrorMessage", 1)) {
      char *p1 = NULL;
      toks(paramtoken, &p1, 0);
      this->DoErrorMessage(p1);
      EMIT_RESPONSE("[S]", p1);
      free(p1);
    } else {
      log_info("Function request is not part of API %s",func);
    }
  } else {
    log_info("API not implemented %s",object);
  }

  mg_send_header(conn, "Content-Type", "application/json");

  //Need to send some data or connection will not be closed
  if (gp_response[0] == '\0') {
    EMIT_RESPONSE("N");
  }

  mg_printf_data(conn, "%s", gp_response);

  //free(gp_response);
  free(data);

  return MG_TRUE;
}
Exemple #8
0
void http()

{

	  CURL *curl;
	  CURLcode res;
	  curl = curl_easy_init();
	  if(curl) {
		struct string s;
		init_string(&s);

	    curl_easy_setopt(curl, CURLOPT_URL, "http://iotser.iots.com.tw:3000/channels/51/feeds/last.json");
	    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
	    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
	#ifdef SKIP_PEER_VERIFICATION
	    /*
	     * If you want to connect to a site who isn't using a certificate that is
	     * signed by one of the certs in the CA bundle you have, you can skip the
	     * verification of the server's certificate. This makes the connection
	     * A LOT LESS SECURE.
	     *
	     * If you have a CA cert for the server stored someplace else than in the
	     * default bundle, then the CURLOPT_CAPATH option might come handy for
	     * you.
	     */
	    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
	#endif

	#ifdef SKIP_HOSTNAME_VERIFICATION
	    /*
	     * If the site you're connecting to uses a different host name that what
	     * they have mentioned in their server certificate's commonName (or
	     * subjectAltName) fields, libcurl will refuse to connect. You can skip
	     * this check, but this will make the connection less secure.
	     */
	    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
	#endif
	    //curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_pt);
	    /* Perform the request, res will get the return code */
	    res = curl_easy_perform(curl);
	    /* Check for errors */
	    if(res != CURLE_OK)
	      fprintf(stderr, "curl_easy_perform() failed: %s\n",
	              curl_easy_strerror(res));

	   // printf("%s\n", s.ptr);
	    struct json_token *arr, *tok;
	    arr = parse_json2(s.ptr, strlen(s.ptr));
	    tok = find_json_token(arr, "field1");
	    if(tok!=NULL)
	    sprintf(data,"%.*s",tok->len,tok->ptr);
	   //printf("Value of field1 is: %.*s\n", tok->len, tok->ptr);
	    free(arr);
	    free(s.ptr);
	    /* always cleanup */
	    curl_easy_cleanup(curl);
	  }

	  curl_global_cleanup();

	  return 0;
}
unique_ptr<WSObj> WSObj_JSON::factory(const char* msg) {
    struct json_token *token = parse_json2(msg, (int) strlen(msg));
    //WSObj_JSON::factory(token);

    return WSObj_JSON::factory(token);
}
Exemple #10
0
/****************************************************************************************
Function Name 		:	main
Description		:	Initalize UART, Thread and publish if any status change
				in the current sensors
Parameters 		:	void
Return 			:	int, if error in the function returns -1 else 0
****************************************************************************************/
int main(int argc,char *argv[])
{
  	struct json_token *l_arr, *l_tok;
	if((uartInit(argv[1])) == 0)
	{
		while(1)
	    	{
			if (g_uart0_filestream != -1)
			{
				char l_rxBuffer[150];
				int l_rxLength = read(g_uart0_filestream,(void*)l_rxBuffer, 150);
				if (l_rxLength > 0)
				{
					l_rxBuffer[l_rxLength] = '\0';
				}
				printf("%c\n",l_rxLength[122]);
				/* Data Format: 
					{"LOAD_1":value,"LOAD_2":value,"current_1":value
					"energy_1:value,"current_2":value,"current_3":value,
					"energy_2":value"}
				*/
				
				//wait for complete data to be recived and process only that
				if((l_rxLength > 32) && (l_rxBuffer[l_rxLength-1] == '}') && (l_rxBuffer[0] == '{')){
					int l_load_1,l_load_2;
					char l_current_1_str[5];
					char l_energy_1_str[5];
					char l_current_2_str[5];
					char l_energy_2_str[5];
					char l_current_3_str[5];
					char l_energy_3_str[5];
					char l_load_1_str[2];
					char l_load_2_str[2];
					float l_sensor1_value,l_sensor2_value,l_sensor3_value,l_sensor4_value,l_sensor5_value,l_sensor6_value;
					l_arr = parse_json2(l_rxBuffer, strlen(l_rxBuffer));
					
					l_tok = find_json_token(l_arr, "LOAD_1");
					sprintf(l_load_1_str,"%.*s",l_tok->len,l_tok->ptr);
					l_load_1 = atof(l_load_1_str);

					l_tok = find_json_token(l_arr, "LOAD_2");
					sprintf(l_load_2_str,"%.*s",l_tok->len,l_tok->ptr);
					l_load_2 = atof(l_load_2_str);

					l_tok = find_json_token(l_arr, "current_1");
					sprintf(l_current_1_str,"%.*s",l_tok->len,l_tok->ptr);
					l_sensor1_value = atof(l_current_1_str);

					l_tok = find_json_token(l_arr, "energy_1");
					sprintf(l_energy_1_str,"%.*s",l_tok->len,l_tok->ptr);
					l_sensor2_value = atof(l_energy_1_str);
					

					l_tok = find_json_token(l_arr, "current_2");
					sprintf(l_current_2_str,"%.*s",l_tok->len,l_tok->ptr);
					l_sensor3_value = atof(l_current_2_str);

					l_tok = find_json_token(l_arr, "energy_2");
					sprintf(l_energy_2_str,"%.*s",l_tok->len,l_tok->ptr);
					l_sensor4_value = atof(l_energy_2_str);

					l_tok = find_json_token(l_arr, "current_2");
					sprintf(l_current_3_str,"%.*s",l_tok->len,l_tok->ptr);
					l_sensor5_value = atof(l_current_3_str);

					l_tok = find_json_token(l_arr, "energy_2");
					sprintf(l_energy_3_str,"%.*s",l_tok->len,l_tok->ptr);
					l_sensor6_value = atof(l_energy_3_str);

					prepare_json_data(l_load_1,l_load_2,l_sensor1_value,l_sensor2_value,l_sensor3_value,l_sensor4_value,l_sensor5_value,l_sensor6_value);
					pubnub_publishStatus(g_jsonResponse);
					memset(g_jsonResponse, 0, sizeof(g_jsonResponse));
	  				free(l_arr);
				}
			}
        		usleep(500000);
		}
		//Close the UART Connection
		close(g_uart0_filestream);
	}
	else
	{
		printf("UART Initialization Failed, Aborting");
		return -1;
	}
	return 0;
}
Exemple #11
0
int parse_sys_config(const char *json, struct sys_config *dst,
                     int require_keys) {
  struct json_token *toks = NULL;
  int result = 0;

  if (json == NULL) goto done;
  if ((toks = parse_json2(json, strlen(json))) == NULL) goto done;

  if (sj_conf_get_bool(toks, "tls.enable", &dst->tls.enable) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "tls.ca_file", &dst->tls.ca_file) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "tls.server_name", &dst->tls.server_name) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_bool(toks, "http.enable", &dst->http.enable) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "http.port", &dst->http.port) == 0 && require_keys)
    goto done;

  if (sj_conf_get_bool(toks, "http.enable_webdav", &dst->http.enable_webdav) ==
          0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.gw", &dst->wifi.ap.gw) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.ssid", &dst->wifi.ap.ssid) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.dhcp_start", &dst->wifi.ap.dhcp_start) ==
          0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.dhcp_end", &dst->wifi.ap.dhcp_end) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.ip", &dst->wifi.ap.ip) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "wifi.ap.trigger_on_gpio",
                      &dst->wifi.ap.trigger_on_gpio) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.netmask", &dst->wifi.ap.netmask) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "wifi.ap.mode", &dst->wifi.ap.mode) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.ap.pass", &dst->wifi.ap.pass) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "wifi.ap.hidden", &dst->wifi.ap.hidden) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "wifi.ap.channel", &dst->wifi.ap.channel) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_bool(toks, "wifi.sta.enable", &dst->wifi.sta.enable) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.sta.ssid", &dst->wifi.sta.ssid) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "wifi.sta.pass", &dst->wifi.sta.pass) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "update.manifest_url", &dst->update.manifest_url) ==
          0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "update.server_timeout",
                      &dst->update.server_timeout) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "clubby.memory_limit", &dst->clubby.memory_limit) ==
          0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "clubby.server_address",
                      &dst->clubby.server_address) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "clubby.device_psk", &dst->clubby.device_psk) ==
          0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "clubby.reconnect_timeout_min",
                      &dst->clubby.reconnect_timeout_min) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "clubby.backend", &dst->clubby.backend) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "clubby.reconnect_timeout_max",
                      &dst->clubby.reconnect_timeout_max) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_bool(toks, "clubby.connect_on_boot",
                       &dst->clubby.connect_on_boot) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "clubby.cmd_timeout", &dst->clubby.cmd_timeout) ==
          0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "clubby.device_id", &dst->clubby.device_id) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_bool(toks, "clubby.device_auto_registration",
                       &dst->clubby.device_auto_registration) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_str(toks, "clubby.device_registration_url",
                      &dst->clubby.device_registration_url) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "debug.mode", &dst->debug.mode) == 0 &&
      require_keys)
    goto done;

  if (sj_conf_get_int(toks, "debug.level", &dst->debug.level) == 0 &&
      require_keys)
    goto done;

  result = 1;
done:
  free(toks);
  return result;
}
Exemple #12
0
static void clubby_proto_handle_frame(char *data, size_t len, void *context) {
  struct clubby_event evt;
  struct json_token *frame = parse_json2(data, len);

  if (frame == NULL) {
    LOG(LL_DEBUG, ("Error parsing clubby frame"));
    return;
  }

  struct json_token *v_tok = find_json_token(frame, "v");
  if (v_tok == NULL || *v_tok->ptr != '2') {
    LOG(LL_ERROR, ("Only clubby v2 is supported (received: %.*s)",
                   v_tok ? 0 : v_tok->len, v_tok->ptr));
    goto clean;
  }

  memset(&evt, 0, sizeof(evt));
  evt.frame = frame;
  evt.context = context;

  struct json_token *id_tok = find_json_token(frame, "id");
  if (id_tok == NULL) {
    LOG(LL_ERROR, ("No id in frame"));
    goto clean;
  }

  evt.id = to64(id_tok->ptr);
  if (evt.id == 0) {
    LOG(LL_ERROR, ("Wrong id"));
    goto clean;
  }

  /* Allow empty dst */
  evt.dst = find_json_token(frame, "dst");

  evt.src = find_json_token(frame, "src");
  if (evt.src == NULL) {
    LOG(LL_ERROR, ("No src in frame"));
    goto clean;
  }

  struct json_token *method_tok = find_json_token(frame, "method");
  struct json_token *result_tok = find_json_token(frame, "result");
  struct json_token *error_tok = find_json_token(frame, "error");

  /*
   * if none of required token exist - this is positive response
   * if `method` and `error` (or `result`) are in the same
   * frame - this is an error
   */
  if (method_tok != NULL && (result_tok != NULL || error_tok != NULL)) {
    LOG(LL_ERROR, ("Malformed frame"));
    goto clean;
  }

  if (method_tok != NULL) {
    clubby_proto_parse_req(method_tok, frame, &evt);
  } else {
    clubby_proto_parse_resp(result_tok, error_tok, &evt);
  }

  s_clubby_cb(&evt);

clean:
  free(frame);
}