Beispiel #1
0
int main(int argc, char **argv) {

  // header information
  std::cout << "Blackbird Bitcoin Arbitrage\nVersion 0.0.2" << std::endl;
  std::cout << "DISCLAIMER: USE THE SOFTWARE AT YOUR OWN RISK.\n" << std::endl;

  // read the config file (config.json)
  json_error_t error;
  json_t *root = json_load_file("config.json", 0, &error);
  if (!root) {
    std::cout << "ERROR: config.json incorrect (" << error.text << ")\n" << std::endl;
    return 1;
  }
 
  // get config variables
  int gapSec = json_integer_value(json_object_get(root, "GapSec"));
  unsigned  debugMaxIteration = json_integer_value(json_object_get(root, "DebugMaxIteration"));

  bool useFullCash = json_boolean_value(json_object_get(root, "UseFullCash")); 
  double untouchedCash = json_real_value(json_object_get(root, "UntouchedCash"));
  double cashForTesting = json_real_value(json_object_get(root, "CashForTesting"));

  if (!useFullCash && cashForTesting < 15.0) {
    std::cout << "ERROR: Minimum test cash is $15.00.\n" << std::endl;
    return 1;
  }
  
  // function arrays 
  getQuoteType getQuote[] = {Bitfinex::getQuote, OkCoin::getQuote, Bitstamp::getQuote, Kraken::getQuote};
  getAvailType getAvail[] = {Bitfinex::getAvail, OkCoin::getAvail, Bitstamp::getAvail, Kraken::getAvail};
  sendOrderType sendOrder[] = {Bitfinex::sendOrder, OkCoin::sendOrder, Bitstamp::sendOrder};
  isOrderCompleteType isOrderComplete[] = {Bitfinex::isOrderComplete, OkCoin::isOrderComplete, Bitstamp::isOrderComplete};
  getActivePosType getActivePos[] = {Bitfinex::getActivePos, OkCoin::getActivePos, Bitstamp::getActivePos, Kraken::getActivePos};
  getLimitPriceType getLimitPrice[] = {Bitfinex::getLimitPrice, OkCoin::getLimitPrice, Bitstamp::getLimitPrice, Kraken::getLimitPrice};

  // thousand separator
  std::locale mylocale("");
  std::cout.imbue(mylocale);

  // print precision of two digits
  std::cout.precision(2);
  std::cout << std::fixed;

  // create a parameters structure
  Parameters params(root);
  params.addExchange("Bitfinex", 0.0020, true);
  params.addExchange("OKCoin", 0.0020, false);
  params.addExchange("Bitstamp", 0.0025, false);
  params.addExchange("Kraken", 0.0025, true);

  // CSV file
  std::string csvFileName;
  csvFileName = "result_" + printDateTimeFileName() + ".csv";
  std::ofstream csvFile;
  csvFile.open(csvFileName.c_str(), std::ofstream::trunc);
  // CSV header
  csvFile << "TRADE_ID,EXCHANGE_LONG,EXHANGE_SHORT,ENTRY_TIME,EXIT_TIME,DURATION,TOTAL_EXPOSURE,BALANCE_BEFORE,BALANCE_AFTER,RETURN\n";
  csvFile.flush();

  // time structure
  time_t rawtime;
  rawtime = time(NULL);
  struct tm * timeinfo;
  timeinfo = localtime(&rawtime);
  
  bool inMarket = false;
  int resultId = 0;
  Result res;
  res.clear();
  // Vector of Bitcoin
  std::vector<Bitcoin*> btcVec;

  // create Bitcoin objects
  for (unsigned i = 0; i < params.nbExch(); ++i) {
    btcVec.push_back(new Bitcoin(i, params.exchName[i], params.fees[i], params.hasShort[i]));
  }

  // cURL
  CURL* curl;
  curl_global_init(CURL_GLOBAL_ALL);
  curl = curl_easy_init();

  std::cout << "[ Targets ]" << std::endl;
  std::cout << "   Spread to enter: " << params.spreadEntry * 100.0 << "%" << std::endl;
  std::cout << "   Spread to exit: " << params.spreadExit * 100.0  << "%" << std::endl;
  std::cout << std::endl;

  // store current balances
  std::cout << "[ Current balances ]" << std::endl;
  std::vector<double> balanceUsd;
  std::vector<double> balanceBtc;
 
  for (unsigned i = 0; i < params.nbExch(); ++i) {
    balanceUsd.push_back(getAvail[i](curl, params, "usd"));
    balanceBtc.push_back(getAvail[i](curl, params, "btc"));
  }

  // vectors that contains balances after a completed trade
  std::vector<double> newBalUsd(params.nbExch(), 0.0);
  std::vector<double> newBalBtc(params.nbExch(), 0.0);
  
  for (unsigned i = 0; i < params.nbExch(); ++i) {
    std::cout << "   " << params.exchName[i] << ":\t";
    std::cout << balanceUsd[i] << " USD\t" << std::setprecision(6) << balanceBtc[i]  << std::setprecision(2) << " BTC" << std::endl;
  }
  std::cout << std::endl;

  std::cout << "[ Cash exposure ]" << std::endl;
  if (useFullCash) {
    std::cout << "   FULL cash used!" << std::endl;
  } else {
    std::cout << "   TEST cash used\n   Value: $" << cashForTesting << std::endl;
  }
  std::cout << std::endl;

  // wait the next gapSec seconds before starting
  time(&rawtime);
  timeinfo = localtime(&rawtime);
  while ((int)timeinfo->tm_sec % gapSec != 0) {
    sleep(0.01);
    time(&rawtime);
    timeinfo = localtime(&rawtime);
  }

  // main loop
  if (!params.verbose) {
    std::cout << "Running..." << std::endl;  
  }

  unsigned currIteration = 0;
  bool stillRunning = true;
  while (stillRunning) {

    time_t currTime = mktime(timeinfo);
    time(&rawtime);

    // check if we are already too late
    if (difftime(rawtime, currTime) > 0) {
      std::cout << "WARNING: " << difftime(rawtime, currTime) << " second(s) too late at " << printDateTime(currTime) << std::endl;
      unsigned skip = (unsigned)ceil(difftime(rawtime, currTime) / gapSec);
      for (unsigned i = 0; i < skip; ++i) {
        // std::cout << "         Skipped iteration " << printDateTime(currTime) << std::endl;
        for (unsigned e = 0; e < params.nbExch(); ++e) {
          btcVec[e]->addData(currTime, btcVec[e]->getLastBid(), btcVec[e]->getLastAsk(), 0.0);
        }
        // go to next iteration
        timeinfo->tm_sec = timeinfo->tm_sec + gapSec;
        currTime = mktime(timeinfo);
      }
      std::cout << std::endl;
    }
    // wait for the next iteration
    while (difftime(rawtime, currTime) != 0) {
      sleep(0.01);
      time(&rawtime);
    }
    if (params.verbose) {
      if (!inMarket) {
        std::cout << "[ " << printDateTime(currTime) << " ]" << std::endl;
      }
      else {
        std::cout << "[ " << printDateTime(currTime) << " IN MARKET: Long " << res.exchNameLong << " / Short " << res.exchNameShort << " ]" << std::endl;
      }
    }
    // download the exchanges prices
    for (unsigned e = 0; e < params.nbExch(); ++e) {

      double bid = getQuote[e](curl, true);
      double ask = getQuote[e](curl, false);
      
      // add previous price if bid or ask is 0.0
      if (bid == 0.0) {
        bid = btcVec[e]->getLastBid();
	std::cout << "   WARNING: " << params.exchName[e] << " bid is null, use previous one" << std::endl;
      }
      if (ask == 0.0) {
        ask = btcVec[e]->getLastAsk();
	std::cout << "   WARNING: " << params.exchName[e] << " ask is null, use previous one" << std::endl;
      }


      if (params.verbose) {
        std::cout << "   " << params.exchName[e] << ": \t" << bid << " / " << ask << std::endl;
      }
      btcVec[e]->addData(currTime, bid, ask, 0.0);
      curl_easy_reset(curl);
    }
    // load data terminated
    if (params.verbose) {
      std::cout << "   ----------------------------" << std::endl;
    }
    // compute entry point
    if (!inMarket) {
      for (unsigned i = 0; i < params.nbExch(); ++i) {
        for (unsigned j = 0; j < params.nbExch(); ++j) {
          if (i != j) {
            if (checkEntry(btcVec[i], btcVec[j], res, params)) {
              // entry opportunity found
              // compute exposure
              res.exposure = std::min(balanceUsd[res.idExchLong], balanceUsd[res.idExchShort]);
              if (res.exposure == 0.0) {
                std::cout << "   WARNING: Opportunity found but no cash available. Trade canceled." << std::endl;
                break;
              }
              if (useFullCash == false && res.exposure <= cashForTesting) {
                std::cout << "   WARNING: Opportunity found but no enough cash. Need more than TEST cash (min. $" << cashForTesting << "). Trade canceled." << std::endl;
                break;        
              }

              if (useFullCash) {
                // leave untouchedCash
                res.exposure -= untouchedCash * res.exposure;
              }
              else {
	        // use test money
                res.exposure = cashForTesting;
              }

	      // check volumes
	      double volumeLong = res.exposure / btcVec[res.idExchLong]->getLastAsk();
	      double volumeShort = res.exposure / btcVec[res.idExchShort]->getLastBid();
	      double limPriceLong = getLimitPrice[res.idExchLong](curl, volumeLong, false);	
	      double limPriceShort = getLimitPrice[res.idExchShort](curl, volumeShort, true);
	      
	      if (limPriceLong - res.priceLongIn > 0.30 || res.priceShortIn - limPriceShort > 0.30) {
                std::cout << "   WARNING: Opportunity found but not enough volume. Trade canceled." << std::endl;
		break;
	      }

              inMarket = true;
              resultId++;
              // update result
              res.id = resultId;
              res.entryTime = currTime;
              res.printEntry();
              res.maxSpread[res.idExchLong][res.idExchShort] = -1.0;
              res.minSpread[res.idExchLong][res.idExchShort] = 1.0;
              int longOrderId = 0;
              int shortOrderId = 0;

              // send Long order
              longOrderId = sendOrder[res.idExchLong](curl, params, "buy", volumeLong, btcVec[res.idExchLong]->getLastAsk());
              // send Short order
              shortOrderId = sendOrder[res.idExchShort](curl, params, "sell", volumeShort, btcVec[res.idExchShort]->getLastBid());
              
              // wait for the orders to be filled
              sleep(3.0);
              std::cout << "Waiting for the two orders to be filled..." << std::endl;
              while (!isOrderComplete[res.idExchLong](curl, params, longOrderId) || !isOrderComplete[res.idExchShort](curl, params, shortOrderId)) {
                sleep(3.0);
              }
              std::cout << "Done" << std::endl;
              longOrderId = 0;
              shortOrderId = 0;
              break;
            }
          }
        }
        if (inMarket) {
          break;
        }
      }
      if (params.verbose) {
        std::cout << std::endl;
      }
    }
    // in market, looking to exit
    else if (inMarket) {

      if (checkExit(btcVec[res.idExchLong], btcVec[res.idExchShort], res, params, currTime)) {
        // exit opportunity found


        // check current exposure
        std::vector<double> btcUsed;
        for (unsigned i = 0; i < params.nbExch(); ++i) {
          btcUsed.push_back(getActivePos[i](curl, params));
        }  
       
        // check volumes
	double volumeLong = btcUsed[res.idExchLong];
	double volumeShort = btcUsed[res.idExchShort];
        double limPriceLong = getLimitPrice[res.idExchLong](curl, volumeLong, true);
        double limPriceShort = getLimitPrice[res.idExchShort](curl, volumeShort, false);
        if (res.priceLongOut - limPriceLong > 0.30 || limPriceShort - res.priceShortOut > 0.30) {
          std::cout << "   WARNING: Opportunity found but not enough volume. Trade canceled." << std::endl;
	} else {
	  res.exitTime = currTime;
          res.printExit();
          // send orders
          int longOrderId = 0;
          int shortOrderId = 0;
          std::cout << std::setprecision(6) << "BTC exposure on " << params.exchName[res.idExchLong] << ": " << volumeLong << std::setprecision(2) << std::endl;
          std::cout << std::setprecision(6) << "BTC exposure on " << params.exchName[res.idExchShort] << ": " << volumeShort << std::setprecision(2) << std::endl;
          std::cout << std::endl;
        
          // Close Long
          longOrderId = sendOrder[res.idExchLong](curl, params, "sell", fabs(btcUsed[res.idExchLong]), btcVec[res.idExchLong]->getLastBid());
          // Close Short
          shortOrderId = sendOrder[res.idExchShort](curl, params, "buy", fabs(btcUsed[res.idExchShort]), btcVec[res.idExchShort]->getLastAsk());
        
          // wait for the orders to be filled
          sleep(3.0);
          std::cout << "Waiting for the two orders to be filled..." << std::endl;
          while (!isOrderComplete[res.idExchLong](curl, params, longOrderId) || !isOrderComplete[res.idExchShort](curl, params, shortOrderId)) {
            sleep(3.0);
          }
          std::cout << "Done\n" << std::endl;
          longOrderId = 0;
          shortOrderId = 0;

          // market exited
          inMarket = false;
        
          // new balances
          for (unsigned i = 0; i < params.nbExch(); ++i) {
            newBalUsd[i] = getAvail[i](curl, params, "usd");
            newBalBtc[i] = getAvail[i](curl, params, "btc");
          }
        
          for (unsigned i = 0; i < params.nbExch(); ++i) {
            std::cout << "New balance on " << params.exchName[i] << ":  \t";
            std::cout << newBalUsd[i] << " USD (perf $" << newBalUsd[i] - balanceUsd[i] << "), ";
            std::cout << std::setprecision(6) << newBalBtc[i]  << std::setprecision(2) << " BTC" << std::endl;
          }
          std::cout << std::endl;

          // update res with total balance
          res.befBalUsd = std::accumulate(balanceUsd.begin(), balanceUsd.end(), 0.0);
          res.aftBalUsd = std::accumulate(newBalUsd.begin(), newBalUsd.end(), 0.0);

          // update current balances with new values
          for (unsigned i = 0; i < params.nbExch(); ++i) {
            balanceUsd[i] = newBalUsd[i];
            balanceBtc[i] = newBalBtc[i];
          }

          // display performance
          std::cout << "ACTUAL PERFORMANCE: " << "$" << res.aftBalUsd - res.befBalUsd << " (" << res.totPerf() * 100.0 << "%)\n" << std::endl; 
        
          // new csv line with result
          csvFile << res.id << "," << res.exchNameLong << "," << res.exchNameShort << "," << printDateTimeCsv(res.entryTime) << "," << printDateTimeCsv(res.exitTime);
          csvFile << "," << res.getLength() << "," << res.exposure * 2.0 << "," << res.befBalUsd << "," << res.aftBalUsd << "," << res.totPerf() << "\n";
          csvFile.flush();

          // send email
          if (params.sendEmail) {
            sendEmail(res, params);
            std::cout << "Email sent" << std::endl;
          }

          // delete result information
          res.clear();
        
          // if "stop_after_exit" file exists then return
          std::ifstream infile("stop_after_exit");
          if (infile.good()) {
            std::cout << "Exit after last trade (file stop_after_exit found)" << std::endl;
            stillRunning = false;
          }
        }
      }
      if (params.verbose) {
        std::cout << std::endl;
      }
    }
    // activities for this iteration terminated
    timeinfo->tm_sec = timeinfo->tm_sec + gapSec;
    currIteration++;
    if (currIteration >= debugMaxIteration) {
      std::cout << "Max iteration reached (" << debugMaxIteration << ")" <<std::endl;
      stillRunning = false;
    }
  }
  // delete Bitcoin objects
  for (unsigned i = 0; i < params.nbExch(); ++i) {
    delete(btcVec[i]);
  }
  json_decref(root);
  // close cURL
  curl_easy_cleanup(curl);
  curl_global_cleanup();
  // close csv file
  csvFile.close();
  
  return 0;
}
Beispiel #2
0
int main(int argc, char* argv[])
{
	// parse command line
	const char* config_file = NULL;
	const char* zlog_config_file = NULL;
	if (argc == 2) 
	{
		config_file = argv[1];
	}
	else if (argc == 3)
	{
		config_file = argv[1];
		zlog_config_file = argv[2];	
	}
	else 
	{
		fprintf(stderr, "usage: raptor <application_config> [zlog_config]\n");
		return -1;
	}

	// zlog init
    int ret = dzlog_init(zlog_config_file, "raptor");
    if (ret) 
    {
        fprintf(stderr, "zlog init failed\n");
        return -1;
    }

    // load config file
    json_t* json_root = NULL;
	json_error_t error;

	dzlog_info("load config file: %s", config_file);

	json_root = json_load_file(config_file, 0, &error);
	if (!json_root) 
	{
		dzlog_error("load config file failed: %s", error.text);
		goto to_exit;
	}

	// create mysql proxy 
	RaptorProxy rp;
	
	json_t* json_raptor_server = json_object_get(json_root, "raptor_proxy");
	if (!json_is_object(json_raptor_server)) 
	{
		dzlog_error("get 'raptor_proxy' config item failed");
		goto to_exit;
	}

	json_t* json_raptor_server_address = json_object_get(json_raptor_server, "address");
	if (!json_is_string(json_raptor_server_address))
	{
		dzlog_error("get 'raptor_proxy:address' config item failed");
		goto to_exit;
	}
	rp.address = json_string_value(json_raptor_server_address);

	json_t* json_raptor_server_workers = json_object_get(json_raptor_server, "workers");
	if (!json_is_integer(json_raptor_server_workers))
	{
		dzlog_error("get 'raptor_proxy:workers' config item failed");
		goto to_exit;
	}
	rp.workers = json_integer_value(json_raptor_server_workers);

	if (raptor_proxy_init(&rp) != 0)
	{
		dzlog_error("create raptor proxy failed");
		goto to_exit;
	}
	/*
	json_t* json_raptor_server = json_object_get(json_root, "raptor_server");
	json_t* json_raptor_server_address = json_object_get(json_raptor_server, "address");
	printf("%s\n", json_string_value(json_raptor_server_address));
	*/
to_exit:
	if (raptor_proxy_finit(&rp) != 0)
		dzlog_error("destroy raptor proxy failed");
	if (!json_root) 
		json_decref(json_root);
	dzlog_info("raptor exit!");
    zlog_fini();
	return 0;
}
Beispiel #3
0
/**
 * Variable size object (in network byte order, encoded using
 * Crockford Base32hex encoding).
 *
 * @param name name of the JSON field
 * @param[out] obj pointer where to write the data, will be allocated
 * @param[out] size where to store the number of bytes allocated for @a obj
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_varsize (const char *name,
                          void **obj,
                          size_t *size)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_variable_data,
    .cleaner = &clean_variable_data,
    .cls = NULL,
    .field = name,
    .ptr = obj,
    .ptr_size = 0,
    .size_ptr = size
  };
  *obj = NULL;
  *size = 0;
  return ret;
}


/**
 * Parse given JSON object to string.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_string (void *cls,
              json_t *root,
              struct GNUNET_JSON_Specification *spec)
{
  const char *str;

  str = json_string_value (root);
  if (NULL == str)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  *(const char **) spec->ptr = str;
  return GNUNET_OK;
}


/**
 * The expected field stores a string.
 *
 * @param name name of the JSON field
 * @param strptr where to store a pointer to the field
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_string (const char *name,
                         const char **strptr)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_string,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = strptr,
    .ptr_size = 0,
    .size_ptr = NULL
  };
  *strptr = NULL;
  return ret;
}


/**
 * Parse given JSON object to a JSON object. (Yes, trivial.)
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_object (void *cls,
              json_t *root,
              struct GNUNET_JSON_Specification *spec)
{
  if (! (json_is_object (root) || json_is_array (root)) )
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  json_incref (root);
  *(json_t **) spec->ptr = root;
  return GNUNET_OK;
}


/**
 * Cleanup data left from parsing JSON object.
 *
 * @param cls closure, NULL
 * @param[out] spec where to free the data
 */
static void
clean_object (void *cls,
              struct GNUNET_JSON_Specification *spec)
{
  json_t **ptr = (json_t **) spec->ptr;

  if (NULL != *ptr)
  {
    json_decref (*ptr);
    *ptr = NULL;
  }
}


/**
 * JSON object.
 *
 * @param name name of the JSON field
 * @param[out] jsonp where to store the JSON found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_json (const char *name,
                       json_t **jsonp)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_object,
    .cleaner = &clean_object,
    .cls = NULL,
    .field = name,
    .ptr = jsonp,
    .ptr_size = 0,
    .size_ptr = NULL
  };
  *jsonp = NULL;
  return ret;
}


/**
 * Parse given JSON object to a uint8_t.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_u8 (void *cls,
          json_t *root,
          struct GNUNET_JSON_Specification *spec)
{
  json_int_t val;
  uint8_t *up = spec->ptr;

  if (! json_is_integer (root))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  val = json_integer_value (root);
  if ( (0 > val) || (val > UINT8_MAX) )
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  *up = (uint8_t) val;
  return GNUNET_OK;
}


/**
 * 8-bit integer.
 *
 * @param name name of the JSON field
 * @param[out] u8 where to store the integer found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_uint8 (const char *name,
                        uint8_t *u8)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_u8,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = u8,
    .ptr_size = sizeof (uint8_t),
    .size_ptr = NULL
  };
  return ret;
}


/**
 * Parse given JSON object to a uint16_t.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_u16 (void *cls,
           json_t *root,
           struct GNUNET_JSON_Specification *spec)
{
  json_int_t val;
  uint16_t *up = spec->ptr;

  if (! json_is_integer (root))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  val = json_integer_value (root);
  if ( (0 > val) || (val > UINT16_MAX) )
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  *up = (uint16_t) val;
  return GNUNET_OK;
}


/**
 * 16-bit integer.
 *
 * @param name name of the JSON field
 * @param[out] u16 where to store the integer found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_uint16 (const char *name,
                         uint16_t *u16)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_u16,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = u16,
    .ptr_size = sizeof (uint16_t),
    .size_ptr = NULL
  };
  return ret;
}


/**
 * Parse given JSON object to a uint32_t.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_u32 (void *cls,
           json_t *root,
           struct GNUNET_JSON_Specification *spec)
{
  json_int_t val;
  uint32_t *up = spec->ptr;

  if (! json_is_integer (root))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  val = json_integer_value (root);
  if ( (0 > val) || (val > UINT32_MAX) )
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  *up = (uint32_t) val;
  return GNUNET_OK;
}


/**
 * 32-bit integer.
 *
 * @param name name of the JSON field
 * @param[out] u32 where to store the integer found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_uint32 (const char *name,
                         uint32_t *u32)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_u32,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = u32,
    .ptr_size = sizeof (uint32_t),
    .size_ptr = NULL
  };
  return ret;
}


/**
 * Parse given JSON object to a uint8_t.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_u64 (void *cls,
           json_t *root,
           struct GNUNET_JSON_Specification *spec)
{
  json_int_t val;
  uint64_t *up = spec->ptr;

  if (! json_is_integer (root))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  val = json_integer_value (root);
  *up = (uint64_t) val;
  return GNUNET_OK;
}


/**
 * 64-bit integer.
 *
 * @param name name of the JSON field
 * @param[out] u64 where to store the integer found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_uint64 (const char *name,
                         uint64_t *u64)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_u64,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = u64,
    .ptr_size = sizeof (uint64_t),
    .size_ptr = NULL
  };
  return ret;
}


/* ************ GNUnet-specific parser specifications ******************* */

/**
 * Parse given JSON object to absolute time.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_abs_time (void *cls,
                json_t *root,
                struct GNUNET_JSON_Specification *spec)
{
  struct GNUNET_TIME_Absolute *abs = spec->ptr;
  const char *val;
  unsigned long long int tval;

  val = json_string_value (root);
  if (NULL == val)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if ( (0 == strcasecmp (val,
                         "/forever/")) ||
       (0 == strcasecmp (val,
                         "/end of time/")) ||
       (0 == strcasecmp (val,
                         "/never/")) )
  {
    *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
    return GNUNET_OK;
  }
  if (1 != sscanf (val,
                   "/Date(%llu)/",
                   &tval))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
  abs->abs_value_us = tval * 1000LL * 1000LL;
  if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
  {
    /* Integer overflow */
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}


/**
 * Absolute time.
 *
 * @param name name of the JSON field
 * @param[out] at where to store the absolute time found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_absolute_time (const char *name,
                                struct GNUNET_TIME_Absolute *at)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_abs_time,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = at,
    .ptr_size = sizeof (uint64_t),
    .size_ptr = NULL
  };
  return ret;
}


/**
 * Parse given JSON object to relative time.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_rel_time (void *cls,
                json_t *root,
                struct GNUNET_JSON_Specification *spec)
{
  struct GNUNET_TIME_Relative *rel = spec->ptr;
  const char *val;
  unsigned long long int tval;

  val = json_string_value (root);
  if (NULL == val)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if ( (0 == strcasecmp (val,
                         "/forever/")) )
  {
    *rel = GNUNET_TIME_UNIT_FOREVER_REL;
    return GNUNET_OK;
  }
  if (1 != sscanf (val,
                   "/Delay(%llu)/",
                   &tval))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
  rel->rel_value_us = tval * 1000LL * 1000LL;
  if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
  {
    /* Integer overflow */
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}


/**
 * Relative time.
 *
 * @param name name of the JSON field
 * @param[out] rt where to store the relative time found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_relative_time (const char *name,
                                struct GNUNET_TIME_Relative *rt)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_rel_time,
    .cleaner = NULL,
    .cls = NULL,
    .field = name,
    .ptr = rt,
    .ptr_size = sizeof (uint64_t),
    .size_ptr = NULL
  };
  return ret;
}


/**
 * Parse given JSON object to RSA public key.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_rsa_public_key (void *cls,
                      json_t *root,
                      struct GNUNET_JSON_Specification *spec)
{
  struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
  const char *enc;
  char *buf;
  size_t len;
  size_t buf_len;

  if (NULL == (enc = json_string_value (root)))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  len = strlen (enc);
  buf_len =  (len * 5) / 8;
  buf = GNUNET_malloc (buf_len);
  if (GNUNET_OK !=
      GNUNET_STRINGS_string_to_data (enc,
                                     len,
                                     buf,
                                     buf_len))
  {
    GNUNET_break_op (0);
    GNUNET_free (buf);
    return GNUNET_SYSERR;
  }
  if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
                                                          buf_len)))
  {
    GNUNET_break_op (0);
    GNUNET_free (buf);
    return GNUNET_SYSERR;
  }
  GNUNET_free (buf);
  return GNUNET_OK;
}


/**
 * Cleanup data left from parsing RSA public key.
 *
 * @param cls closure, NULL
 * @param[out] spec where to free the data
 */
static void
clean_rsa_public_key (void *cls,
                      struct GNUNET_JSON_Specification *spec)
{
  struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;

  if (NULL != *pk)
  {
    GNUNET_CRYPTO_rsa_public_key_free (*pk);
    *pk = NULL;
  }
}


/**
 * Specification for parsing an RSA public key.
 *
 * @param name name of the JSON field
 * @param pk where to store the RSA key found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_rsa_public_key (const char *name,
                                 struct GNUNET_CRYPTO_RsaPublicKey **pk)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_rsa_public_key,
    .cleaner = &clean_rsa_public_key,
    .cls = NULL,
    .field = name,
    .ptr = pk,
    .ptr_size = 0,
    .size_ptr = NULL
  };
  *pk = NULL;
  return ret;
}


/**
 * Parse given JSON object to RSA signature.
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_rsa_signature (void *cls,
                     json_t *root,
                     struct GNUNET_JSON_Specification *spec)
{
  struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
  size_t size;
  const char *str;
  int res;
  void *buf;

  str = json_string_value (root);
  if (NULL == str)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  size = (strlen (str) * 5) / 8;
  buf = GNUNET_malloc (size);
  res = GNUNET_STRINGS_string_to_data (str,
                                       strlen (str),
                                       buf,
                                       size);
  if (GNUNET_OK != res)
  {
    GNUNET_free (buf);
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
                                                          size)))
  {
    GNUNET_break_op (0);
    GNUNET_free (buf);
    return GNUNET_SYSERR;
  }
  GNUNET_free (buf);
  return GNUNET_OK;
}


/**
 * Cleanup data left from parsing RSA signature.
 *
 * @param cls closure, NULL
 * @param[out] spec where to free the data
 */
static void
clean_rsa_signature (void *cls,
                     struct GNUNET_JSON_Specification *spec)
{
  struct GNUNET_CRYPTO_RsaSignature  **sig = spec->ptr;

  if (NULL != *sig)
  {
    GNUNET_CRYPTO_rsa_signature_free (*sig);
    *sig = NULL;
  }
}


/**
 * Specification for parsing an RSA signature.
 *
 * @param name name of the JSON field
 * @param sig where to store the RSA signature found under @a name
 */
struct GNUNET_JSON_Specification
GNUNET_JSON_spec_rsa_signature (const char *name,
                                struct GNUNET_CRYPTO_RsaSignature **sig)
{
  struct GNUNET_JSON_Specification ret = {
    .parser = &parse_rsa_signature,
    .cleaner = &clean_rsa_signature,
    .cls = NULL,
    .field = name,
    .ptr = sig,
    .ptr_size = 0,
    .size_ptr = NULL
  };
  *sig = NULL;
  return ret;
}
Beispiel #4
0
static void handle_request(int sock)
{
    char *buf = NULL;
    size_t len;
    json_t *req = NULL, *ret = NULL, *arg;
    json_error_t json_error;
    int req_id, err_code = -1;

    ret = json_object();
    if(ret == NULL)
        goto end;

    if(recv_full(sock, &len, sizeof(len)) == -1) {
        log_error_errno();
        goto end;
    }

    buf = (char *)malloc(len + 1);
    if(buf == NULL) {
        log_error_errno();
        goto end;
    }

    if(recv_full(sock, buf, len) == -1) {
        log_error_errno();
        goto end;
    }
    buf[len] = '\0';

    enable_listening_fd(sock);

    req = json_loads(buf, 0, &json_error);
    if(req == NULL) {
        log_error(LOG_COLOR_ERROR, "%d: %s", sock, json_error.text);
        goto end;
    }

    if(!json_is_object(req))
        goto invalid_request;

    arg = json_object_get(req, "req_id");
    if(arg == NULL || !json_is_integer(arg))
        goto invalid_request;
    req_id = json_integer_value(arg);

    if(req_id < 0 || req_id >= sizeof(g_req_handler) / sizeof(*g_req_handler))
        goto invalid_request;

    arg = json_object_get(req, "arg");
    if(arg == NULL || !json_is_object(arg))
        goto invalid_request;

    err_code = g_req_handler[req_id](arg, ret);

end:
    send_response(sock, err_code, ret);

    if(req)
        json_decref(req);
    if(buf)
        free(buf);
    if(ret)
        json_decref(ret);

    return;

invalid_request:
    log_error(LOG_COLOR_ERROR, "%d: Invalid request", sock);

    goto end;
}
Beispiel #5
0
janus_turnrest_response *janus_turnrest_request(void) {
	janus_mutex_lock(&api_mutex);
	if(api_server == NULL) {
		janus_mutex_unlock(&api_mutex);
		return NULL;
	}
	/* Prepare the request URI */
	char query_string[512];
	g_snprintf(query_string, 512, "service=turn");
	if(api_key != NULL) {
		char buffer[256];
		g_snprintf(buffer, 256, "&api=%s", api_key);
		g_strlcat(query_string, buffer, 512);
	}
	char request_uri[1024];
	g_snprintf(request_uri, 1024, "%s?%s", api_server, query_string);
	JANUS_LOG(LOG_VERB, "Sending request: %s\n", request_uri);
	janus_mutex_unlock(&api_mutex);
	/* Prepare the libcurl context */
	CURLcode res;
	CURL *curl = curl_easy_init();
	if(curl == NULL) {
		JANUS_LOG(LOG_ERR, "libcurl error\n");
		return NULL;
	}
	curl_easy_setopt(curl, CURLOPT_URL, request_uri);
	curl_easy_setopt(curl, CURLOPT_POST, 1);
	/* FIXME Some servers don't like a POST with no data */
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query_string);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);	/* FIXME Max 10 seconds */
	/* For getting data, we use an helper struct and the libcurl callback */
	janus_turnrest_buffer data;
	data.buffer = malloc(1);
	data.size = 0;
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, janus_turnrest_callback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&data);
	curl_easy_setopt(curl, CURLOPT_USERAGENT, "Janus/1.0");
	/* Send the request */
	res = curl_easy_perform(curl);
	if(res != CURLE_OK) {
		JANUS_LOG(LOG_ERR, "Couldn't send the request: %s\n", curl_easy_strerror(res));
		free(data.buffer);
		curl_easy_cleanup(curl);
		return NULL;
	}
	/* Cleanup the libcurl context */
	curl_easy_cleanup(curl);
	/* Process the response */
	JANUS_LOG(LOG_VERB, "Got %zu bytes from the TURN REST API server\n", data.size);
	JANUS_LOG(LOG_VERB, "%s\n", data.buffer);
	json_error_t error;
	json_t *root = json_loads(data.buffer, 0, &error);
	if(!root) {
		JANUS_LOG(LOG_ERR, "Couldn't parse response: error on line %d: %s", error.line, error.text);
		free(data.buffer);
		return NULL;
	}
	free(data.buffer);
	json_t *username = json_object_get(root, "username");
	if(!username) {
		JANUS_LOG(LOG_ERR, "Invalid response: missing username\n");
		return NULL;
	}
	if(!json_is_string(username)) {
		JANUS_LOG(LOG_ERR, "Invalid response: username should be a string\n");
		return NULL;
	}
	json_t *password = json_object_get(root, "password");
	if(!password) {
		JANUS_LOG(LOG_ERR, "Invalid response: missing password\n");
		return NULL;
	}
	if(!json_is_string(password)) {
		JANUS_LOG(LOG_ERR, "Invalid response: password should be a string\n");
		return NULL;
	}
	json_t *ttl = json_object_get(root, "ttl");
	if(ttl && !json_is_integer(ttl)) {
		JANUS_LOG(LOG_ERR, "Invalid response: ttl should be an integer\n");
		return NULL;
	}
	json_t *uris = json_object_get(root, "uris");
	if(!uris) {
		JANUS_LOG(LOG_ERR, "Invalid response: missing uris\n");
		return NULL;
	}
	if(!json_is_array(uris) || json_array_size(uris) == 0) {
		JANUS_LOG(LOG_ERR, "Invalid response: uris should be a non-empty array\n");
		return NULL;
	}
	/* Turn the response into a janus_turnrest_response object we can use */
	janus_turnrest_response *response = calloc(1, sizeof(janus_turnrest_response));
	response->username = g_strdup(json_string_value(username));
	response->password = g_strdup(json_string_value(password));
	response->ttl = ttl ? json_integer_value(ttl) : 0;
	response->servers = NULL;
	size_t i = 0;
	for(i=0; i<json_array_size(uris); i++) {
		json_t *uri = json_array_get(uris, i);
		if(uri == NULL || !json_is_string(uri)) {
			JANUS_LOG(LOG_WARN, "Skipping invalid TURN URI (not a string)...\n");
			continue;
		}
		const char *turn_uri = json_string_value(uri);
		if(strstr(turn_uri, "turn:") != turn_uri && strstr(turn_uri, "turns:") != turn_uri) {
			JANUS_LOG(LOG_WARN, "Skipping invalid TURN URI '%s' (not a TURN URI)...\n", turn_uri);
			continue;
		}
		janus_turnrest_instance *instance = calloc(1, sizeof(janus_turnrest_instance));
		instance->transport = NICE_RELAY_TYPE_TURN_UDP;
		if(strstr(turn_uri, "turns:") == turn_uri)
			instance->transport = NICE_RELAY_TYPE_TURN_TLS;
		else if(strstr(turn_uri, "transport=tcp") == turn_uri)
			instance->transport = NICE_RELAY_TYPE_TURN_TCP;
		gchar **parts = NULL;
		if(strstr(turn_uri, "?") != NULL) {
			parts = g_strsplit(turn_uri, "?", -1);
			turn_uri = parts[0];
		}
		gchar **uri_parts = g_strsplit(turn_uri, ":", -1);
		/* Resolve the TURN URI address */
		struct hostent *he = gethostbyname(uri_parts[1]);
		if(he == NULL) {
			JANUS_LOG(LOG_WARN, "Skipping invalid TURN URI '%s' (could not resolve the address)...\n", uri_parts[1]);
			g_strfreev(uri_parts);
			continue;
		}
		struct in_addr **addr_list = (struct in_addr **)he->h_addr_list;
		if(addr_list[0] == NULL) {
			JANUS_LOG(LOG_WARN, "Skipping invalid TURN URI '%s' (could not resolve the address)...\n", uri_parts[1]);
			g_strfreev(uri_parts);
			continue;
		}
		instance->server = g_strdup(inet_ntoa(*addr_list[0]));
		if(uri_parts[2] == NULL) {
			/* No port? USe 3478 by default */
			instance->port = 3478;
		} else {
			instance->port = atoi(uri_parts[2]);
		}
		g_strfreev(uri_parts);
		g_strfreev(parts);
		/* Add the server to the list */
		response->servers = g_list_append(response->servers, instance);
	}
	if(response->servers == NULL) {
		JANUS_LOG(LOG_ERR, "Couldn't find any valid TURN URI in the response...\n");
		janus_turnrest_response_destroy(response);
		return NULL; 
	}
	/* Done */
	return response;
}
Beispiel #6
0
/* return error */
int DEFAULT_CC
lib_mod_connect(struct mod *mod)
{
    int error;
    int len;
    int i;
    int index;
    int use_uds;
    struct stream *s;
    char con_port[256];
    int retry = 0;
    int send_error = 0;

    int rc = 0;
    unsigned int nbytes;
    char pidfile[128];
    char ip[16];

    char cookie[33];
    char sessionid[128];
    char sessiontoken[128];

    struct passwd pwd;
    struct passwd *pwdresult;
    char pwdbuffer[16384];
    char message[256];
    char reply[256];

    int sock;
    struct sockaddr_in server;

    json_t *request;
    json_t *response;
    json_t *display;
    json_error_t js_error;

    mod->server_msg(mod, "GoPCNX started connection", 0);

    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1) {
        mod->server_msg(mod, "Socket creation failed", 0);    
        return 1;
    }

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(9999);

    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) {
        mod->server_msg(mod, "Server connection failed", 0);
        return 1;
    }

    request = json_object();
    json_object_set(request, "username", json_string(mod->username));
    json_object_set(request, "password", json_string(mod->password));
    json_object_set(request, "ip", json_string("127.0.0.1"));
    json_object_set(request, "link", json_string("lan"));
    display = json_object();
    json_object_set(display, "width", json_integer(mod->width));
    json_object_set(display, "height", json_integer(mod->height));
    json_object_set(request, "display", display);
    json_decref(display);

    g_snprintf(message, sizeof(message)-1, "%s\n", json_dumps(request, 0));
    json_decref(request);

    if (send(sock, message, strlen(message), 0) < 0) {
        mod->server_msg(mod, "Server request failed", 0);
        return 1;
    }

    if (recv(sock, reply, sizeof(reply), 0) < 0) {
        mod->server_msg(mod, "Server reply failed", 0);
        return 1;
    }

    response = json_loads(reply, 0, &js_error);
        
    if (response == NULL) {
        mod->server_msg(mod, "Decoding response failed", 0);
        return 1;
    } else {
        json_t *nxsession = json_object_get(response, "session");
        json_t *err = json_object_get(response, "err");
        int resume = json_is_true(json_object_get(response, "resume"));

        if (err) {
            mod->server_msg(mod, json_string_value(err), 0);
            return 1;
        } else if (resume) {
            resize_nxproxy(mod);
        } else {
            char sessionstash[512];
            const char *cookie = json_string_value(json_object_get(nxsession, "cookie"));
            const char *host = json_string_value(json_object_get(nxsession, "host"));
            json_int_t port = json_integer_value(json_object_get(nxsession, "port"));            

            getpwnam_r(mod->username, &pwd, pwdbuffer, sizeof(pwdbuffer), &pwdresult);
            if (pwdresult == NULL) {
                mod->server_msg(mod, "Uid lookup failed", 0);
                return 1;
            }

            if (!start_nxproxy(mod, cookie, (int)port)) {
                mod->server_msg(mod, "nxproxy failed to start", 0);
                return 1;
            }

            json_decref(nxsession);
        }
    }

    json_decref(response);

    LIB_DEBUG(mod, "in lib_mod_connect");
    /* clear screen */
    mod->server_begin_update(mod);
    mod->server_set_fgcolor(mod, 0);
    mod->server_fill_rect(mod, 0, 0, mod->width, mod->height);
    mod->server_end_update(mod);
    mod->server_msg(mod, "started connecting", 0);

    /* only support 8, 15, 16, and 24 bpp connections from rdp client */
    if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24)
    {
        mod->server_msg(mod,
                        "error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0);
        LIB_DEBUG(mod, "out lib_mod_connect error");
        return 1;
    }

    if (g_strcmp(mod->ip, "") == 0)
    {
        mod->server_msg(mod, "error - no ip set", 0);
        LIB_DEBUG(mod, "out lib_mod_connect error");
        return 1;
    }

    make_stream(s);

    g_snprintf(con_port, 255, "%s", mod->port);
    use_uds = 0;

    if (con_port[0] == '/')
    {
        use_uds = 1;
    }

    mod->sck_closed = 0;
    i = 0;

RECONNECT:
    while (1)
    {
        if (use_uds)
        {
            mod->sck = g_tcp_local_socket();
        }
        else
        {
            mod->sck = g_tcp_socket();
            g_tcp_set_non_blocking(mod->sck);
            g_tcp_set_no_delay(mod->sck);
        }

        /* mod->server_msg(mod, "connecting...", 0); */

        if (use_uds)
        {
            error = g_tcp_local_connect(mod->sck, con_port);
        }
        else
        {
            error = g_tcp_connect(mod->sck, mod->ip, con_port);
        }

        if (error == -1)
        {
            if (g_tcp_last_error_would_block(mod->sck))
            {
                error = 0;
                index = 0;

                while (!g_tcp_can_send(mod->sck, 100))
                {
                    index++;

                    if ((index >= 30) || mod->server_is_term(mod))
                    {
                        mod->server_msg(mod, "connect timeout", 0);
                        error = 1;
                        break;
                    }
                }
            }
            else
            {
                /* mod->server_msg(mod, "connect error", 0); */
            }
        }

        if (error == 0)
        {
            break;
        }

        g_tcp_close(mod->sck);
        mod->sck = 0;
        i++;

        if (i >= 20)
        {
            mod->server_msg(mod, "connection problem, giving up", 0);
            break;
        }

        g_sleep(500);
    }

    if (error == 0)
    {
        if (use_uds)
        {
            lib_mod_log_peer(mod);
        }
    }

    if (error == 0)
    {
        /* send version message */
        init_stream(s, 8192);
        s_push_layer(s, iso_hdr, 4);
        out_uint16_le(s, 103);
        out_uint32_le(s, 301);
        out_uint32_le(s, 0);
        out_uint32_le(s, 0);
        out_uint32_le(s, 0);
        out_uint32_le(s, 1);
        s_mark_end(s);
        len = (int)(s->end - s->data);
        s_pop_layer(s, iso_hdr);
        out_uint32_le(s, len);
        lib_send(mod, s->data, len);
    }

    if (error == 0)
    {
        /* send screen size message */
        init_stream(s, 8192);
        s_push_layer(s, iso_hdr, 4);
        out_uint16_le(s, 103);
        out_uint32_le(s, 300);
        out_uint32_le(s, mod->width);
        out_uint32_le(s, mod->height);
        out_uint32_le(s, mod->bpp);
        out_uint32_le(s, 0);
        s_mark_end(s);
        len = (int)(s->end - s->data);
        s_pop_layer(s, iso_hdr);
        out_uint32_le(s, len);
        lib_send(mod, s->data, len);
    }

    if (error == 0)
    {
        /* send invalidate message */
        init_stream(s, 8192);
        s_push_layer(s, iso_hdr, 4);
        out_uint16_le(s, 103);
        out_uint32_le(s, 200);
        /* x and y */
        i = 0;
        out_uint32_le(s, i);
        /* width and height */
        i = ((mod->width & 0xffff) << 16) | mod->height;
        out_uint32_le(s, i);
        out_uint32_le(s, 0);
        out_uint32_le(s, 0);
        s_mark_end(s);
        len = (int)(s->end - s->data);
        s_pop_layer(s, iso_hdr);
        out_uint32_le(s, len);
        send_error = lib_send(mod, s->data, len);
    }

    if (send_error) {
        if (retry < 50) {
            g_tcp_close(mod->sck);
            mod->server_msg(mod, "Doing a retry", 0);
            retry++;
            g_sleep(1000);
            goto RECONNECT;
        }

        error = send_error;
    }

    free_stream(s);

    if (error != 0)
    {
        mod->server_msg(mod, "some problem", 0);
        LIB_DEBUG(mod, "out lib_mod_connect error");
        return 1;
    }
    else
    {
        mod->server_msg(mod, "connected ok", 0);
        mod->sck_obj = g_create_wait_obj_from_socket(mod->sck, 0);
    }

    LIB_DEBUG(mod, "out lib_mod_connect");
    return 0;
}
Beispiel #7
0
int handle_response(json_t* response)
{
	int retval = 0;
	jsonrpc_request_t* req = NULL;
	json_t* return_obj = NULL;
	json_t* internal = NULL;
	char* freeme = NULL;


	/* check if json object */
	if(!json_is_object(response)){
		WARN("jsonrpc response is not an object\n");
		return -1;
	}

	/* check version */
	json_t* version = json_object_get(response, "jsonrpc");
	if(!version) {
		WARN("jsonrpc response does not have a version.\n");
		retval = -1;
		goto end;
	}

	const char* version_s = json_string_value(version);
	if(!version_s){
		WARN("jsonrpc response version is not a string.\n");
		retval = -1;
		goto end;
	}

	if (strlen(version_s) != (sizeof(JSONRPC_VERSION)-1)
			|| strncmp(version_s, JSONRPC_VERSION, sizeof(JSONRPC_VERSION)-1) != 0) {
		WARN("jsonrpc response version is not %s. version: %s\n",
				JSONRPC_VERSION, version_s);
		retval = -1;
		goto end;
	}

	/* check for an id */
	json_t* _id = json_object_get(response, "id");
	if(!_id) {
		WARN("jsonrpc response does not have an id.\n");
		retval = -1;
		goto end;
	}

	int id = json_integer_value(_id);
	if (!(req = pop_request(id))) {
		/* don't fail the server for an unrecognized id */
		retval = 0;
		goto end;
	}

	return_obj = json_object();

	json_t* error = json_object_get(response, "error");
	// if the error value is null, we don't care
	bool _error = error && (json_typeof(error) != JSON_NULL);

	json_t* result = json_object_get(response, "result");

	if(_error) {
		json_object_set(return_obj, "error", error);
	}

	if(result) {
		json_object_set(return_obj, "result", result);
	}

	if ((!result && !_error) || (result && _error)) {
		WARN("bad response\n");
		internal = internal_error(JRPC_ERR_BAD_RESP, req->payload);
		json_object_update(return_obj, internal);
		if(internal) json_decref(internal);
	}

	pv_value_t val;

	if(jsontoval(&val, &freeme, return_obj)<0) {
		fail_request(
				JRPC_ERR_TO_VAL,
				req,
				"Failed to convert response json to pv\n");
		retval = -1;
		goto end;
	}

	char* error_s = NULL;

	if(send_to_script(&val, req->cmd)>=0) {
		goto free_and_end;
	}

	if(_error) {
		// get code from error
		json_t* _code = json_object_get(error, "code");
		if(_code) {
			int code = json_integer_value(_code);

			// check if code is in global_retry_ranges
			retry_range_t* tmpr;
			for(tmpr = global_retry_ranges;
					tmpr != NULL;
					tmpr = tmpr->next) {
				if((tmpr->start < tmpr->end
						&& tmpr->start <= code && code <= tmpr->end)
				|| (tmpr->end < tmpr->start
						&& tmpr->end <= code && code <= tmpr->start)
				|| (tmpr->start == tmpr->end && tmpr->start == code)) {
					if(schedule_retry(req)==0) {
						goto end;
					}
					break;
				}
			}

		}
		error_s = json_dumps(error, JSON_COMPACT);
		if(error_s) {
			WARN("Request received an error: \n%s\n", error_s);
			free(error_s);
		} else {
			fail_request(
					JRPC_ERR_BAD_RESP,
					req,
					"Could not convert 'error' response to string");
			retval = -1;
			goto end;
		}
	}


free_and_end:
	free_req_cmd(req->cmd);
	free_request(req);

end:
	if(freeme) free(freeme);
	if(return_obj) json_decref(return_obj);
	return retval;
}
Beispiel #8
0
static void run_tests()
{
    json_t *value;
    int i;
    char buffer[4] = {'t', 'e', 's', 't'};
    json_error_t error;

    /*
     * Simple, valid json_pack cases
     */
    /* true */
    value = json_pack("b", 1);
    if(!json_is_true(value))
        fail("json_pack boolean failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack boolean refcount failed");
    json_decref(value);

    /* false */
    value = json_pack("b", 0);
    if(!json_is_false(value))
        fail("json_pack boolean failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack boolean refcount failed");
    json_decref(value);

    /* null */
    value = json_pack("n");
    if(!json_is_null(value))
        fail("json_pack null failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack null refcount failed");
    json_decref(value);

    /* integer */
    value = json_pack("i", 1);
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack integer failed");
    if(value->refcount != (size_t)1)
        fail("json_pack integer refcount failed");
    json_decref(value);

    /* integer from json_int_t */
    value = json_pack("I", (json_int_t)555555);
    if(!json_is_integer(value) || json_integer_value(value) != 555555)
        fail("json_pack json_int_t failed");
    if(value->refcount != (size_t)1)
        fail("json_pack integer refcount failed");
    json_decref(value);

    /* real */
    value = json_pack("f", 1.0);
    if(!json_is_real(value) || json_real_value(value) != 1.0)
        fail("json_pack real failed");
    if(value->refcount != (size_t)1)
        fail("json_pack real refcount failed");
    json_decref(value);

    /* string */
    value = json_pack("s", "test");
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string refcount failed");
    json_decref(value);

    /* nullable string (defined case) */
    value = json_pack("s?", "test");
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack nullable string (defined case) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack nullable string (defined case) refcount failed");
    json_decref(value);

    /* nullable string (NULL case) */
    value = json_pack("s?", NULL);
    if(!json_is_null(value))
        fail("json_pack nullable string (NULL case) failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack nullable string (NULL case) refcount failed");
    json_decref(value);

    /* string and length (int) */
    value = json_pack("s#", "test asdf", 4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length refcount failed");
    json_decref(value);

    /* string and length (size_t) */
    value = json_pack("s%", "test asdf", (size_t)4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length refcount failed");
    json_decref(value);

    /* string and length (int), non-NUL terminated string */
    value = json_pack("s#", buffer, 4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length (int) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length (int) refcount failed");
    json_decref(value);

    /* string and length (size_t), non-NUL terminated string */
    value = json_pack("s%", buffer, (size_t)4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length (size_t) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length (size_t) refcount failed");
    json_decref(value);

    /* string concatenation */
    value = json_pack("s++", "te", "st", "ing");
    if(!json_is_string(value) || strcmp("testing", json_string_value(value)))
        fail("json_pack string concatenation failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string concatenation refcount failed");
    json_decref(value);

    /* string concatenation and length (int) */
    value = json_pack("s#+#+", "test", 1, "test", 2, "test");
    if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
        fail("json_pack string concatenation and length (int) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string concatenation and length (int) refcount failed");
    json_decref(value);

    /* string concatenation and length (size_t) */
    value = json_pack("s%+%+", "test", (size_t)1, "test", (size_t)2, "test");
    if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
        fail("json_pack string concatenation and length (size_t) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string concatenation and length (size_t) refcount failed");
    json_decref(value);

    /* empty object */
    value = json_pack("{}", 1.0);
    if(!json_is_object(value) || json_object_size(value) != 0)
        fail("json_pack empty object failed");
    if(value->refcount != (size_t)1)
        fail("json_pack empty object refcount failed");
    json_decref(value);

    /* empty list */
    value = json_pack("[]", 1.0);
    if(!json_is_array(value) || json_array_size(value) != 0)
        fail("json_pack empty list failed");
    if(value->refcount != (size_t)1)
        fail("json_pack empty list failed");
    json_decref(value);

    /* non-incref'd object */
    value = json_pack("o", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack object failed");
    if(value->refcount != (size_t)1)
        fail("json_pack integer refcount failed");
    json_decref(value);

    /* non-incref'd nullable object (defined case) */
    value = json_pack("o?", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack nullable object (defined case) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack nullable object (defined case) refcount failed");
    json_decref(value);

    /* non-incref'd nullable object (NULL case) */
    value = json_pack("o?", NULL);
    if(!json_is_null(value))
        fail("json_pack nullable object (NULL case) failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack nullable object (NULL case) refcount failed");
    json_decref(value);

    /* incref'd object */
    value = json_pack("O", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack object failed");
    if(value->refcount != (size_t)2)
        fail("json_pack integer refcount failed");
    json_decref(value);
    json_decref(value);

    /* incref'd nullable object (defined case) */
    value = json_pack("O?", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack incref'd nullable object (defined case) failed");
    if(value->refcount != (size_t)2)
        fail("json_pack incref'd nullable object (defined case) refcount failed");
    json_decref(value);
    json_decref(value);

    /* incref'd nullable object (NULL case) */
    value = json_pack("O?", NULL);
    if(!json_is_null(value))
        fail("json_pack incref'd nullable object (NULL case) failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack incref'd nullable object (NULL case) refcount failed");

    /* simple object */
    value = json_pack("{s:[]}", "foo");
    if(!json_is_object(value) || json_object_size(value) != 1)
        fail("json_pack array failed");
    if(!json_is_array(json_object_get(value, "foo")))
        fail("json_pack array failed");
    if(json_object_get(value, "foo")->refcount != (size_t)1)
        fail("json_pack object refcount failed");
    json_decref(value);

    /* object with complex key */
    value = json_pack("{s+#+: []}", "foo", "barbar", 3, "baz");
    if(!json_is_object(value) || json_object_size(value) != 1)
        fail("json_pack array failed");
    if(!json_is_array(json_object_get(value, "foobarbaz")))
        fail("json_pack array failed");
    if(json_object_get(value, "foobarbaz")->refcount != (size_t)1)
        fail("json_pack object refcount failed");
    json_decref(value);

    /* simple array */
    value = json_pack("[i,i,i]", 0, 1, 2);
    if(!json_is_array(value) || json_array_size(value) != 3)
        fail("json_pack object failed");
    for(i=0; i<3; i++)
    {
        if(!json_is_integer(json_array_get(value, i)) ||
           json_integer_value(json_array_get(value, i)) != i)

            fail("json_pack integer array failed");
    }
    json_decref(value);

    /* Whitespace; regular string */
    value = json_pack(" s ", "test");
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string (with whitespace) failed");
    json_decref(value);

    /* Whitespace; empty array */
    value = json_pack("[ ]");
    if(!json_is_array(value) || json_array_size(value) != 0)
        fail("json_pack empty array (with whitespace) failed");
    json_decref(value);

    /* Whitespace; array */
    value = json_pack("[ i , i,  i ] ", 1, 2, 3);
    if(!json_is_array(value) || json_array_size(value) != 3)
        fail("json_pack array (with whitespace) failed");
    json_decref(value);

    /*
     * Invalid cases
     */

    /* newline in format string */
    if(json_pack_ex(&error, 0, "{\n\n1"))
        fail("json_pack failed to catch invalid format '1'");
    check_error("Expected format 's', got '1'", "<format>", 3, 1, 4);

    /* mismatched open/close array/object */
    if(json_pack_ex(&error, 0, "[}"))
        fail("json_pack failed to catch mismatched '}'");
    check_error("Unexpected format character '}'", "<format>", 1, 2, 2);

    if(json_pack_ex(&error, 0, "{]"))
        fail("json_pack failed to catch mismatched ']'");
    check_error("Expected format 's', got ']'", "<format>", 1, 2, 2);

    /* missing close array */
    if(json_pack_ex(&error, 0, "["))
        fail("json_pack failed to catch missing ']'");
    check_error("Unexpected end of format string", "<format>", 1, 2, 2);

    /* missing close object */
    if(json_pack_ex(&error, 0, "{"))
        fail("json_pack failed to catch missing '}'");
    check_error("Unexpected end of format string", "<format>", 1, 2, 2);

    /* garbage after format string */
    if(json_pack_ex(&error, 0, "[i]a", 42))
        fail("json_pack failed to catch garbage after format string");
    check_error("Garbage after format string", "<format>", 1, 4, 4);

    if(json_pack_ex(&error, 0, "ia", 42))
        fail("json_pack failed to catch garbage after format string");
    check_error("Garbage after format string", "<format>", 1, 2, 2);

    /* NULL string */
    if(json_pack_ex(&error, 0, "s", NULL))
        fail("json_pack failed to catch null argument string");
    check_error("NULL string argument", "<args>", 1, 1, 1);

    /* + on its own */
    if(json_pack_ex(&error, 0, "+", NULL))
        fail("json_pack failed to a lone +");
    check_error("Unexpected format character '+'", "<format>", 1, 1, 1);

    /* NULL format */
    if(json_pack_ex(&error, 0, NULL))
        fail("json_pack failed to catch NULL format string");
    check_error("NULL or empty format string", "<format>", -1, -1, 0);

    /* NULL key */
    if(json_pack_ex(&error, 0, "{s:i}", NULL, 1))
        fail("json_pack failed to catch NULL key");
    check_error("NULL string argument", "<args>", 1, 2, 2);

    /* More complicated checks for row/columns */
    if(json_pack_ex(&error, 0, "{ {}: s }", "foo"))
        fail("json_pack failed to catch object as key");
    check_error("Expected format 's', got '{'", "<format>", 1, 3, 3);

    /* Complex object */
    if(json_pack_ex(&error, 0, "{ s: {},  s:[ii{} }", "foo", "bar", 12, 13))
        fail("json_pack failed to catch missing ]");
    check_error("Unexpected format character '}'", "<format>", 1, 19, 19);

    /* Complex array */
    if(json_pack_ex(&error, 0, "[[[[[   [[[[[  [[[[ }]]]] ]]]] ]]]]]"))
        fail("json_pack failed to catch extra }");
    check_error("Unexpected format character '}'", "<format>", 1, 21, 21);

    /* Invalid UTF-8 in object key */
    if(json_pack_ex(&error, 0, "{s:i}", "\xff\xff", 42))
        fail("json_pack failed to catch invalid UTF-8 in an object key");
    check_error("Invalid UTF-8 object key", "<args>", 1, 2, 2);

    /* Invalid UTF-8 in a string */
    if(json_pack_ex(&error, 0, "{s:s}", "foo", "\xff\xff"))
        fail("json_pack failed to catch invalid UTF-8 in a string");
    check_error("Invalid UTF-8 string", "<args>", 1, 4, 4);
}
Beispiel #9
0
void graph_response_retrieveResponse(req_t * req, json_t * response,
				     int32_t requestId, void *sweb,
				     req_store_t * req_store)
{

	json_t *nodeArray = json_object_get(req->response, "nodeArray");
	json_t *nodeDataArray = json_object_get(response, "nodeArray");

//TODO handle this case
/*	assert(json_array_size(nodeArray) == json_array_size(nodeDataArray));  */
	//add the content data to the location data
	int i;
	for (i = 0; i < json_array_size(nodeArray); i++) {

		json_t *node = json_array_get(nodeArray, i);

		int64_t id = json_integer_value(json_object_get(node, "id"));
		int j;
		for (j = 0; j < json_array_size(nodeDataArray); j++) {

			json_t *dataNode = json_array_get(nodeDataArray, j);
			if (id ==
			    json_integer_value(json_object_get
					       (dataNode, "id"))) {

				json_object_set(node, "node", dataNode);
				break;
			}

		}

		//TODO Put an assert here so that we are sure that all nodes have content

	}

	json_t *web_resp = json_object();

	json_object_set(web_resp, "sessionId",
			json_object_get(req->request, "sessionId"));
	json_object_set_new(web_resp, "type", json_string("response"));
	json_t *clientResponse = json_object();
	json_object_set(clientResponse, "clientRequestId",
			json_object_get(json_object_get
					(req->request,
					 "clientRequest"), "clientRequestId"));
	json_t *cl_response = json_object();
	json_object_set_new(cl_response, "type", json_string("searchResponse"));
	json_object_set(cl_response, "nodeArray", nodeArray);
	json_object_set_new(clientResponse, "response", cl_response);
	json_object_set_new(web_resp, "clientResponse", clientResponse);
	zmsg_t *res = zmsg_new();
	char *web_res_str = json_dumps(web_resp,
				       JSON_COMPACT);
	printf("\nbroker:sweb sent: %s\n", web_res_str);
	zmsg_addstr(res, web_res_str);
	free(web_res_str);
	zmsg_wrap(res, req->address);
	zmsg_send(&res, sweb);
	request_store_delete(req_store, requestId);
	json_decref(web_resp);

}
Beispiel #10
0
void get_data(const char *recording, double start, double duration)
/*===============================================================*/
{
  int CHUNKSIZE = 10000 ;

  double *data = NULL ;
  int channels = 0 ;
  json_t *siguris = NULL ;

  const char *DATAFORMAT = STREAM_DOUBLE ;


  // Setup stream, set options (e.g. block size), add signals, etc,
  // then bsml_stream_start(strm)
  bsml_streamdata *strm = bsml_streamdata_request(recording, start, duration, DATAFORMAT, CHUNKSIZE) ;

  bsml_streamblock *sb ;
  int frameno = 0 ;

  while ((sb = bsml_streamdata_read(strm)) != NULL) {
#ifdef LOG_HEADER
    fprintf(stderr, "%s Block %c: %d\n  ", run_id, sb->type, sb->length) ;
    json_dumpf(sb->header, stderr, JSON_ENSURE_ASCII) ;
    fprintf(stderr, "\n") ;
#endif
    if      (sb->type == BSML_STREAM_ERROR_BLOCK) {
      fprintf(stderr, "ERROR: %-*s\n", sb->length, sb->content) ;
      }

    else if (sb->type == BSML_STREAM_INFO_BLOCK) {
      if (siguris) json_decref(siguris) ;
      siguris = json_object_get(sb->header, "signals") ;
      // Also have "channels" field (plus "rates" and "units").
      if (siguris && json_is_array(siguris)) {
        size_t n = json_array_size(siguris) ;
        json_incref(siguris) ;
        if (channels != n) {
          channels = n ;
          if (data) free(data) ;
          data = calloc(sizeof(double), channels*CHUNKSIZE) ;
          }
        }
      }

    else if (sb->type == BSML_STREAM_RDF_BLOCK) {

      }

    else if (sb->type == BSML_STREAM_DATA_BLOCK) {
      // Need to check rates match...
      // Or have rates in Info block and check when it's received...
      // What about signals where the rate changes??
      json_t *info = json_object_get(sb->header, "info") ;
      if (info && json_is_integer(info)) {
        int chan = json_integer_value(info) ;
        double *dp = data + chan ;
        double *cp = (double *)sb->content ;
        int l = sb->length/sizeof(double) ;
        while (l > 0) {
          *dp = *cp ;
          dp += channels ;
          ++cp ;
          --l ;
          }
        if (chan == (channels-1)) {
          double *dp = data ;
          int i ;
          l = sb->length/sizeof(double) ;
          while (l > 0) {
            printf("%d ", frameno) ;
            for (i = 0 ;  i < channels ;  ++i) {
              if (i > 0) printf(" ") ;
              printf("%8g", *dp) ;
              ++dp ;
              }
            printf("\n") ;
            ++frameno ;
            --l ;
            }
          }
        }
      // get dtype from sb->header
      // JSON *header ;
//      dtype *buffer = calloc(sb->length, sizeof(dtype)) ;
//      memcpy(buffer, (double *)sb->content, sb->length*sizeof(dtype)) ;
      }
    bsml_streamblock_free(sb) ;
    }

  if (strm->error != BSML_STREAM_ERROR_NONE)  // Always check for errors...
    fprintf(stderr, "ERROR %d: %s\n", strm->error, bsml_stream_error_text(strm->error)) ;


  bsml_streamdata_free(strm) ;
  if (data) free(data) ;
  if (siguris) json_decref(siguris) ;
  }
Beispiel #11
0
static void LedActorOnRequestTurnOn(PVOID pParam)
{
	char* message = (char*)pParam;
	char **znpSplitMessage;
	if (pLedActor == NULL) return;
	json_t* payloadJson = NULL;
	json_t* paramsJson = NULL;
	json_t* redJson = NULL;
	json_t* greenJson = NULL;
	json_t* blueJson = NULL;
	json_t* responseJson = NULL;
	json_t* statusJson = NULL;
	BYTE red, green, blue;
	PACTORHEADER header;
	char* responseTopic;
	char* responseMessage;
	char* colorMessage;
	znpSplitMessage = ActorSplitMessage(message);
	if (znpSplitMessage == NULL)
		return;
	// parse header to get origin of message
	header = ActorParseHeader(znpSplitMessage[0]);
	if (header == NULL)
	{
		ActorFreeSplitMessage(znpSplitMessage);
		return;
	}
	//parse payload
	payloadJson = json_loads(znpSplitMessage[1], JSON_DECODE_ANY, NULL);
	if (payloadJson == NULL)
	{
		ActorFreeSplitMessage(znpSplitMessage);
		ActorFreeHeaderStruct(header);
		return;
	}
	paramsJson = json_object_get(payloadJson, "params");
	if (paramsJson == NULL)
	{
		json_decref(payloadJson);
		ActorFreeSplitMessage(znpSplitMessage);
		ActorFreeHeaderStruct(header);
		return;
	}
	redJson = json_object_get(paramsJson, "red");
	if (redJson == NULL)
		red = 255;
	else
		red = json_integer_value(redJson);

	greenJson = json_object_get(paramsJson, "green");
	if (greenJson == NULL)
		green = 255;
	else
		green = json_integer_value(greenJson);

	blueJson = json_object_get(paramsJson, "blue");
	if (blueJson == NULL)
		blue = 255;
	else
		blue = json_integer_value(blueJson);
	int result = LedTurnOn(red, green, blue);

	//make response package
	responseJson = json_object();
	statusJson = json_object();
	json_t* requestJson = json_loads(znpSplitMessage[1], JSON_DECODE_ANY, NULL);
	json_object_set(responseJson, "request", requestJson);
	json_decref(requestJson);
	json_t* resultJson;
	colorMessage = calloc(20, sizeof(BYTE));
	sprintf(colorMessage, "0x%02X%02X%02X", red, green, blue);
	if (result == 0)
	{
		LedActorPublishStateChange(colorMessage, LED_ON, 0);
		resultJson = json_string("status.success");
	}
	else
	{
		LedActorPublishStateChange(colorMessage, LED_OFF, 0);
		resultJson = json_string("status.failure");
	}
	if (redJson)
		json_decref(redJson);
	if (greenJson)
		json_decref(greenJson);
	if (blueJson)
		json_decref(blueJson);
	json_decref(paramsJson);
	json_decref(payloadJson);
	json_object_set(statusJson, "status", resultJson);
	json_decref(resultJson);
	json_object_set(responseJson, "response", statusJson);
	json_decref(statusJson);
	responseMessage = json_dumps(responseJson, JSON_INDENT(4) | JSON_REAL_PRECISION(4));
	//responseTopic = ActorMakeTopicName(header->origin, "/:response");
	responseTopic = StrDup(header->origin);
	ActorFreeHeaderStruct(header);
	json_decref(responseJson);
	ActorFreeSplitMessage(znpSplitMessage);
	ActorSend(pLedActor, responseTopic, responseMessage, NULL, FALSE, "response");
	free(colorMessage);
	free(responseMessage);
	free(responseTopic);
}
Beispiel #12
0
static char *
add_task_common (SeafCloneManager *mgr, 
                 const char *repo_id,
                 int repo_version,
                 const char *peer_id,
                 const char *repo_name,
                 const char *token,
                 const char *passwd,
                 int enc_version,
                 const char *random_key,
                 const char *worktree,
                 const char *peer_addr,
                 const char *peer_port,
                 const char *email,
                 const char *more_info,
                 gboolean sync_wt_name,
                 GError **error)
{
    CloneTask *task;

    task = clone_task_new (repo_id, peer_id, repo_name,
                           token, worktree, passwd,
                           peer_addr, peer_port, email);
    task->manager = mgr;
    task->enc_version = enc_version;
    task->random_key = g_strdup (random_key);
    task->repo_version = repo_version;
    task->sync_wt_name = sync_wt_name;
    if (more_info) {
        json_error_t jerror;
        json_t *object = NULL;

        object = json_loads (more_info, 0, &jerror);
        if (!object) {
            seaf_warning ("Failed to load more sync info from json: %s.\n", jerror.text);
            clone_task_free (task);
            return NULL;
        }
        
        json_t *integer = json_object_get (object, "is_readonly");
        task->is_readonly = json_integer_value (integer);
        json_t *string = json_object_get (object, "server_url");
        if (string)
            task->server_url = canonical_server_url (json_string_value (string));
        json_decref (object);
    }

    if (save_task_to_db (mgr, task) < 0) {
        seaf_warning ("[Clone mgr] failed to save task.\n");
        clone_task_free (task);
        return NULL;
    }

    if (task->repo_version > 0) {
        if (task->server_url) {
            check_http_protocol (task);
        } else {
            clone_task_free (task);
            return NULL;
        }
    } 

    /* The old task for this repo will be freed. */
    g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task);

    return g_strdup(repo_id);
}
Beispiel #13
0
static size_t http_write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {
    json_t *response, *value, *in;
    json_error_t error;
    const char *etcd_value;
    const char *errmsg;
    struct etcd_data *data;
    int val;

    data = userdata;

    response = json_loads(ptr, 0, &error);
    if (!json_is_object(response)) {
        strcpy(data->errmsg, "'response' returned is not a json object");
        goto error;
    }

    in = json_object_get(response, "index");
    if (json_is_integer(in)) {
        data->index = json_integer_value(in);
    }

    value = json_object_get(response, "value");
    if (!json_is_string(value)) {
        value = json_object_get(response, "action");
        etcd_value = "";
        if (json_is_string(value)) {
            etcd_value = json_string_value(value);
        }
        if (strcmp(etcd_value, DELETE_KEY) == 0) {
            value = json_object_get(response, "key");
            etcd_value = json_string_value(value);
            strcpy(data->value, ++etcd_value);
            data->response = ETCD_SUCCESS;

            json_decref(response);
            return size * nmemb;

        } else {
            value = json_object_get(response, "errorCode");
            if (!json_is_integer(value)) {
                strcpy(data->errmsg, "Invalid error message.");
                goto error;
            }
            val = json_integer_value(value);

            value = json_object_get(response, "message");
            if (!json_is_string(value)) {
                strcpy(data->errmsg, "Invalid error message.");
                goto error;
            }

            errmsg = json_string_value(value);
            sprintf(data->errmsg, "%d:%s", val, errmsg);
            goto error;
        }
    }
    etcd_value = json_string_value(value);
    memcpy(data->value, etcd_value, strlen(etcd_value) + 1);
    data->response = ETCD_SUCCESS;

    json_decref(response);
    return size * nmemb;

error:
    json_decref(response);
    data->value = NULL;
    data->response = ETCD_FAILURE;
    return size * nmemb;
}
Beispiel #14
0
Datei: urn.c Projekt: Ba5ik7/urn
int urn_game_create(urn_game **game_ptr, const char *path) {
    int error = 0;
    urn_game *game;
    int i;
    json_t *json = 0;
    json_t *ref;
    json_error_t json_error;
    // allocate game
    game = calloc(1, sizeof(urn_game));
    if (!game) {
        error = 1;
        goto game_create_done;
    }
    // copy path to file
    game->path = strdup(path);
    if (!game->path) {
        error = 1;
        goto game_create_done;
    }
    // load json
    json = json_load_file(game->path, 0, &json_error);
    if (!json) {
        error = 1;
        goto game_create_done;
    }
    // copy title
    ref = json_object_get(json, "title");
    if (ref) {
        game->title = strdup(json_string_value(ref));
        if (!game->title) {
            error = 1;
            goto game_create_done;
        }
    }
    // copy theme
    ref = json_object_get(json, "theme");
    if (ref) {
        game->theme = strdup(json_string_value(ref));
        if (!game->theme) {
            error = 1;
            goto game_create_done;
        }
    }
    // copy theme variant
    ref = json_object_get(json, "theme_variant");
    if (ref) {
        game->theme_variant = strdup(json_string_value(ref));
        if (!game->theme_variant) {
            error = 1;
            goto game_create_done;
        }
    }
    // get attempt count
    ref = json_object_get(json, "attempt_count");
    if (ref) {
        game->attempt_count = json_integer_value(ref);
    }
    // get width
    ref = json_object_get(json, "width");
    if (ref) {
        game->width = json_integer_value(ref);
    }
    // get height
    ref = json_object_get(json, "height");
    if (ref) {
        game->height = json_integer_value(ref);
    }
    // get delay
    ref = json_object_get(json, "start_delay");
    if (ref) {
        game->start_delay = urn_time_value(
            json_string_value(ref));
    }
    // get wr
    ref = json_object_get(json, "world_record");
    if (ref) {
        game->world_record = urn_time_value(
            json_string_value(ref));
    }
    // get splits
    ref = json_object_get(json, "splits");
    if (ref) {
        game->split_count = json_array_size(ref);
        // allocate titles
        game->split_titles = calloc(game->split_count,
                                    sizeof(char *));
        if (!game->split_titles) {
            error = 1;
            goto game_create_done;
        }
        // allocate splits
        game->split_times = calloc(game->split_count,
                                   sizeof(long long));
        if (!game->split_times) {
            error = 1;
            goto game_create_done;
        }
        game->segment_times = calloc(game->split_count,
                                     sizeof(long long));
        if (!game->segment_times) {
            error = 1;
            goto game_create_done;
        }
        game->best_splits = calloc(game->split_count,
                                   sizeof(long long));
        if (!game->best_splits) {
            error = 1;
            goto game_create_done;
        }
        game->best_segments = calloc(game->split_count,
                                     sizeof(long long));
        if (!game->best_segments) {
            error = 1;
            goto game_create_done;
        }
        // copy splits
        for (i = 0; i < game->split_count; ++i) {
            json_t *split;
            json_t *split_ref;
            split = json_array_get(ref, i);
            split_ref = json_object_get(split, "title");
            if (split_ref) {
                game->split_titles[i] = strdup(
                    json_string_value(split_ref));
                if (!game->split_titles[i]) {
                    error = 1;
                    goto game_create_done;
                }
            }
            split_ref = json_object_get(split, "time");
            if (split_ref) {
                game->split_times[i] = urn_time_value(
                    json_string_value(split_ref));
            }
            if (i && game->split_times[i] && game->split_times[i-1]) {
                game->segment_times[i] = game->split_times[i] - game->split_times[i-1];
            } else if (!i && game->split_times[0]) {
                game->segment_times[0] = game->split_times[0];
            }
            split_ref = json_object_get(split, "best_time");
            if (split_ref) {
                game->best_splits[i] = urn_time_value(
                    json_string_value(split_ref));
            } else if (game->split_times[i]) {
                game->best_splits[i] = game->split_times[i];
            }
            split_ref = json_object_get(split, "best_segment");
            if (split_ref) {
                game->best_segments[i] = urn_time_value(
                    json_string_value(split_ref));
            } else if (game->segment_times[i]) {
                game->best_segments[i] = game->segment_times[i];
            }
        }
    }
 game_create_done:
    if (!error) {
        *game_ptr = game;
    } else if (game) {
        urn_game_release(game);
    }
    if (json) {
        json_decref(json);
    }
    return error;
}
Beispiel #15
0
/*
 * resolve and validate an access_token against the configured Authorization Server
 */
static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c,
		const char *access_token, json_t **token, char **response) {

	json_t *result = NULL;
	const char *json = NULL;

	/* see if we've got the claims for this access_token cached already */
	c->cache->get(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, &json);

	if (json == NULL) {

		/* not cached, go out and validate the access_token against the Authorization server and get the JSON claims back */
		if (oidc_oauth_validate_access_token(r, c, access_token, &json) == FALSE) {
			oidc_error(r,
					"could not get a validation response from the Authorization server");
			return FALSE;
		}

		/* decode and see if it is not an error response somehow */
		if (oidc_util_decode_json_and_check_error(r, json, &result) == FALSE)
			return FALSE;

		json_t *active = json_object_get(result, "active");
		if (active != NULL) {

			if ((!json_is_boolean(active)) || (!json_is_true(active))) {
				oidc_debug(r,
						"no \"active\" boolean object with value \"true\" found in response JSON object");
				json_decref(result);
				return FALSE;
			}

			json_t *exp = json_object_get(result, "exp");
			if ((exp != NULL) && (json_is_number(exp))) {
				/* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */
				c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json,
						apr_time_from_sec(json_integer_value(exp)));
			} else if (json_integer_value(exp) <= 0) {
				oidc_debug(r,
						"response JSON object did not contain an \"exp\" integer number; introspection result will not be cached");
			}

		} else {

			/* assume PingFederate validation: get and check the expiry timestamp */
			json_t *expires_in = json_object_get(result, "expires_in");
			if ((expires_in == NULL) || (!json_is_number(expires_in))) {
				oidc_error(r,
						"response JSON object did not contain an \"expires_in\" number");
				json_decref(result);
				return FALSE;
			}
			if (json_integer_value(expires_in) <= 0) {
				oidc_warn(r,
						"\"expires_in\" number <= 0 (%" JSON_INTEGER_FORMAT "); token already expired...",
						json_integer_value(expires_in));
				json_decref(result);
				return FALSE;
			}

			/* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */
			c->cache->set(r, OIDC_CACHE_SECTION_ACCESS_TOKEN, access_token, json,
					apr_time_now() + apr_time_from_sec(json_integer_value(expires_in)));
		}


	} else {

		/* we got the claims for this access_token in our cache, decode it in to a JSON structure */
		json_error_t json_error;
		result = json_loads(json, 0, &json_error);
		if (result == NULL) {
			oidc_error(r, "cached JSON was corrupted: %s", json_error.text);
			return FALSE;
		}
	}

	/* return the access_token JSON object */
	json_t *tkn = json_object_get(result, "access_token");
	if ((tkn != NULL) && (json_is_object(tkn))) {

		/*
		 * assume PingFederate validation: copy over those claims from the access_token
		 * that are relevant for authorization purposes
		 */
		json_object_set(tkn, "client_id", json_object_get(result, "client_id"));
		json_object_set(tkn, "scope", json_object_get(result, "scope"));

		//oidc_oauth_spaced_string_to_array(r, result, "scope", tkn, "scopes");

		/* return only the pimped access_token results */
		*token = json_deep_copy(tkn);
		char *s_token = json_dumps(*token, 0);
		*response = apr_pstrdup(r->pool, s_token);
		free(s_token);

		json_decref(result);

	} else  {

		//oidc_oauth_spaced_string_to_array(r, result, "scope", result, "scopes");

		/* assume spec compliant introspection */
		*token = result;
		*response = apr_pstrdup(r->pool, json);

	}

	return TRUE;
}
Beispiel #16
0
void graph_response(void *sgraph, req_store_t * req_store, void *sweb,
		    void *spss)
{

	zmsg_t *msg = zmsg_recv(sgraph);
	zframe_t *null = zmsg_unwrap(msg);
	zframe_destroy(&null);
	json_error_t error;
	printf("\nbroker:sgraph received: %s\n",
	       (const char *)zframe_data(zmsg_first(msg)));
	const char *data;
	size_t data_size = zframe_size(zmsg_first(msg));
	data = zframe_data(zmsg_first(msg));

	json_t *graph_resp_json = json_loadb(data,
					     data_size, 0,
					     &error);
	zmsg_destroy(&msg);

	//identify the request
	int32_t requestId =
	    json_integer_value(json_object_get(graph_resp_json, "requestId"));

	req_t *req = request_store_req(req_store, requestId);

	json_t *response = json_object_get(graph_resp_json, "response");

	const char *resp_type =
	    json_string_value(json_object_get(response, "type"));

	json_t *request =
	    json_object_get(json_object_get(req->request, "clientRequest"),
			    "request");
	const char *req_type =
	    json_string_value(json_object_get(request, "type"));

	if ((strcmp(resp_type, "retrieveResponse") == 0)
	    && (strcmp(req_type, "searchRequest") == 0))

		graph_response_retrieveResponse(req, response,
						requestId, sweb, req_store);

	else if ((strcmp(resp_type, "newNodeResponse") == 0)
		 && (strcmp(req_type, "newNode") == 0))

		graph_response_newNodeResponse(request,
					       response,
					       requestId, spss, req_store);

	else if ((strcmp(resp_type, "newLinkResponse") == 0)
		 && (strcmp(req_type, "newLink") == 0))

		graph_response_newLinkResponse(req,
					       request,
					       response,
					       requestId, sweb, req_store);

	else if ((strcmp(resp_type, "delLinkResponse")
		  == 0) && (strcmp(req_type, "delLink")
			    == 0))

		graph_response_delLinkResponse(req,
					       request,
					       response,
					       requestId, sweb, req_store);

	else if ((strcmp(resp_type, "delNode") == 0)
		 && (strcmp(req_type, "delNode")
		     == 0))
		graph_response_delNodeResponse(req,
					       request,
					       response,
					       requestId, spss, req_store);

	else if ((strcmp(resp_type, "newNodeData")
		  == 0) && (strcmp(req_type, "newNodeData")
			    == 0))

		graph_response_newNodeDataResponse(req,
						   request,
						   response,
						   requestId, sweb, req_store);

	else if ((strcmp(resp_type, "newLinkData")
		  == 0) && (strcmp(req_type, "newLinkData")
			    == 0))

		graph_response_newLinkDataResponse(req,
						   request,
						   response,
						   requestId, sweb, req_store);

	json_decref(graph_resp_json);
}
Beispiel #17
0
status_t windows_system_map_lookup(
        const char *rekall_profile,
        const char *symbol,
        const char *subsymbol,
        addr_t *address,
        addr_t *size)
{

    status_t ret = VMI_FAILURE;

    json_error_t error;
    json_t *root = json_load_file(rekall_profile, 0, &error);
    if (!root) {
        PRINT_DEBUG("Rekall profile error on line %d: %s\n", error.line, error.text);
        goto exit;
    }

    if (!json_is_object(root)) {
        PRINT_DEBUG("Rekall profile: root is not an objet\n");
        goto err_exit;
    }

    if (!subsymbol && !size) {
        json_t *constants = json_object_get(root, "$CONSTANTS");
        json_t *jsymbol = json_object_get(constants, symbol);
        if (!jsymbol) {
            PRINT_DEBUG("Rekall profile: constant '%s' not found\n", symbol);
            goto err_exit;
        }

        *address = json_integer_value(jsymbol);
        ret = VMI_SUCCESS;

    } else {
        json_t *structs = json_object_get(root, "$STRUCTS");
        json_t *jstruct = json_object_get(structs, symbol);
        if (!jstruct) {
            PRINT_DEBUG("Rekall profile: structure '%s' not found\n", symbol);
            goto err_exit;
        }

        if (size) {
            json_t *jsize = json_array_get(jstruct, 0);
            *size = json_integer_value(jsize);
        }

        if (address) {
            json_t *jstruct2 = json_array_get(jstruct, 1);
            json_t *jmember = json_object_get(jstruct2, subsymbol);
            if (!jmember) {
                PRINT_DEBUG("Rekall profile: structure member '%s' not found\n", subsymbol);
                goto err_exit;
            }
            json_t *jvalue = json_array_get(jmember, 0);

            *address = json_integer_value(jvalue);
        }
        ret = VMI_SUCCESS;

    }

    err_exit: json_decref(root);

    exit: return ret;
}
Beispiel #18
0
bool TwitPic::parseJSON(const string& json, TwitPicResult& result) {
	printf("result:\n%s\n", json.c_str());
	json_t* root;
	json_error_t error;
	
	root = json_loads(json.c_str(), 0, &error);
	if(!root) {
		printf("Error: on line: %d, %s\n", error.line, error.text);
		json_decref(root);
		return false;
	}
	
	// id
	json_t* node = json_object_get(root, "id");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no id found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.id_str = json_string_value(node);
	}
	
	// text
	node = json_object_get(root, "text");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no text found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.text = json_string_value(node);
	}

	// url
	node = json_object_get(root, "url");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no url found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.url = json_string_value(node);
	}
	
	// width
	node = json_object_get(root, "width");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no width found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_integer(node)) {
		result.width = json_integer_value(node);
	}

	// height
	node = json_object_get(root, "height");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no height found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_integer(node)) {
		result.height = json_integer_value(node);
	}
	
	// size
	node = json_object_get(root, "size");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no size found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_integer(node)) {
		result.size = json_integer_value(node);
	}

	// type
	node = json_object_get(root, "type");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no type found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.type = json_string_value(node);
	}
	
	// timestamp
	node = json_object_get(root, "timestamp");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no timestamp found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.timestamp = json_string_value(node);
	}
	
	// user
	// --------------
	json_t* subnode = json_object_get(root, "user");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no user found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_object(subnode)) {
		// user_id
		node = json_object_get(subnode, "id");
		if(node == NULL) {
			printf("Error: cannot parse twitpic result, no user id found.\n");
			json_decref(root);
			return false;
		}
		if(json_is_integer(node)) {
			result.user_id = json_integer_value(node);
		}
		
		// user_screen_name
		node = json_object_get(subnode, "screen_name");
		if(node == NULL) {
			printf("Error: cannot parse twitpic result, no user screen_name found.\n");
			json_decref(root);
			return false;
		}
		if(json_is_string(node)) {
			result.user_screen_name = json_string_value(node);
		}
	}
	result.print();
	return true;
}
Beispiel #19
0
static void send_json(char* str, size_t len)
{
	json_t* root, *cmd, *data, *data_len, *ip, *port;
	json_error_t error;
	root = json_loads(str, 0, &error);

	if(!root || !json_is_object(root))
	{
		fprintf(stderr, "JSON: Error on line %d: %s\n", error.line, error.text);
		return;
	}
	cmd = json_object_get(root, "cmd");
	if(!json_is_integer(cmd))
	{
		fprintf(stderr, "JSON: cmd is not an integer\n");
		json_decref(root);
		return;
	}
	data = json_object_get(root, "data");
	if(!json_is_null(data) && !json_is_string(data))
	{
		fprintf(stderr, "JSON: data is not a string\n");
		json_decref(root);
		return;
	}
	data_len = json_object_get(root, "data_len");
	if(!json_is_integer(cmd))
	{
		fprintf(stderr, "JSON: data_len is not an integer\n");
		json_decref(root);
		return;
	}

	ip = json_object_get(root, "ip");
	if(!ip || !json_is_string(ip))
	{
		json_decref(ip);
		ip=NULL;
	}

	port = json_object_get(root, "port");
	if(!port || !json_is_integer(port))
	{
		json_decref(port);
		port=NULL;
	}

	int t_int = json_integer_value(cmd);
	if(t_int == -1)
	{
		welcome_message_sent=0;
		json_decref(root);
		return;
	}
	EventType t=(EventType)t_int;
	int datalen=json_integer_value(data_len);
	printf("Got: %s\n", str);
	if(ip && port)
	{
		event_send_simple_to_addr(t, datalen ? json_string_value(data) : NULL, datalen, json_string_value(ip), json_integer_value(port), corefd);
	}
	else
	{
		event_send_simple(t, datalen ? json_string_value(data) : NULL, datalen, corefd);
	}
	json_decref(root);
	// TODO: Does other json_t* variables need to be decref'd?
	return;
}
Beispiel #20
0
int VtUrlDist_parse(struct VtUrlDist* url_dist,
                    void (*cb)(const char *url, unsigned long long timestamp, int total, int positives, json_t *raw_json, void *data),
                    void *user_data) {
  json_t *resp_json, *url_obj;
  json_t *url_str_json, *timestamp_json, *total_json, *positives_json;
  unsigned int index;

  if (!url_dist || !url_dist->response) {
    VT_ERROR("No data recieved\n");
    return -1;
  }

  resp_json =  VtResponse_getJanssonObj(url_dist->response);

  if (!json_is_array(resp_json)) {
    VT_ERROR("JSON is not array\n");
    return -1;
  }

  json_array_foreach(resp_json, index, url_obj) {

    if (!json_is_object(url_obj)) {
      VT_ERROR("Parse error not a URL object\n");
      return -1;
    }

    url_str_json = json_object_get(url_obj, "url");
    if (!url_str_json || !json_is_string(url_str_json)) {
      VT_ERROR("Parse error: url string\n");
      return -1;
    }

    timestamp_json = json_object_get(url_obj, "timestamp");
    if (!timestamp_json || !json_is_integer(timestamp_json)) {
      VT_ERROR("JSON parse error timestamp\n");
      return -1;
    }

    total_json = json_object_get(url_obj, "total");
    if (!total_json || !json_is_integer(total_json)) {
      VT_ERROR("JSON parse error total\n");
      return -1;
    }

    positives_json = json_object_get(url_obj, "positives");
    if (!positives_json || !json_is_integer(positives_json)) {
      VT_ERROR("JSON parse error positives\n");
      return -1;
    }

    // set the after value, so if we do another query, we will not repeat the same data
    url_dist->after = json_integer_value(timestamp_json);

    // Call user defined callback function
    if (cb)
      cb(json_string_value(url_str_json), json_integer_value(timestamp_json),
         (int) json_integer_value(total_json), (int) json_integer_value(positives_json),
         url_obj, user_data);

  }

  return 0;
}
Beispiel #21
0
qeo_mgmt_client_retcode_t qeo_mgmt_json_util_parseGetFWDMessage(const char* data, ssize_t length, qeo_mgmt_client_forwarder_cb callback, void* cookie)
{
    json_error_t json_error = {0};
    qeo_mgmt_client_retcode_t result = QMGMTCLIENT_EBADREPLY;
    json_t* message = json_loadb(data, length, JSON_REJECT_DUPLICATES, &json_error);
    qeo_mgmt_client_forwarder_t* fwd = NULL;
    do {
       json_t* fwdArray;
       ssize_t fwdSize;
       ssize_t i;
       if (message == NULL) {
           qeo_log_w("Failed to parse json message %s (%s:%d:%d)", json_error.text, json_error.source, json_error.line, json_error.column);
           qeo_log_w("Data = (%s)", data);
           //JSON parsing error
           break;
       }
       if (!json_is_object(message)) {
           qeo_log_w("invalid message received - top level is not a JSON object");
           break;
       }
       fwdArray = json_object_get(message, "forwarders");
       if (fwdArray == NULL || !json_is_array(fwdArray)) {
           qeo_log_w("root object did not contain a field 'forwarders' of type array (%p)", fwdArray);
       }
       fwdSize = json_array_size(fwdArray);
       qeo_log_i("Found an array of %d forwarder(s) in message\n", fwdSize);

       for (i = 0; i < fwdSize; i++) {
           qeo_mgmt_client_retcode_t cb_result;
           json_t* fwdObject = json_array_get(fwdArray, i);
           json_t* idString;
           json_t* locatorArray;
           ssize_t nrOfLocators;
           ssize_t j;

           if (!json_is_object(fwdObject)) {
               qeo_log_w("unexpected content in fwdArray - object expected");
               break;
           }
           idString = json_object_get(fwdObject, "id");
           if (idString == NULL || !json_is_string(idString)) {
               qeo_log_w("forwarder object did not contain a string field called 'id' (%p)",  idString);
               break;
           }
           locatorArray = json_object_get(fwdObject, "locators");
           if (locatorArray == NULL || !json_is_array(locatorArray)) {
               qeo_log_w("forwarder object did not contain an array field called 'nrOfLocators' (%p)",  locatorArray);
               break;

           }
           nrOfLocators = json_array_size(locatorArray);
           qeo_log_i("found forwarder with id='%s' and %d locator(s)", json_string_value(idString), nrOfLocators);
           fwd = malloc(sizeof(qeo_mgmt_client_forwarder_t));
           if (fwd == NULL) {
               qeo_log_w("fwd == NULL");
               result = QMGMTCLIENT_EMEM;
               break;
           }
           fwd->nrOfLocators = nrOfLocators;
           fwd->locators = calloc(nrOfLocators, sizeof(qeo_mgmt_client_locator_t));
           fwd->deviceID = qeo_mgmt_util_hex_to_int(json_string_value(idString));
           if (fwd->deviceID == -1){
               qeo_log_w("Invalid device id inside json message");
               break;
           }

           if (fwd->locators == NULL) {
               qeo_log_w("fwd->locators == NULL");
               result = QMGMTCLIENT_EMEM;
               break;
           }

           for (j = 0; j < nrOfLocators; j++) {
               json_t* endpointObj = json_array_get(locatorArray, j);
               json_t* typeString = json_object_get(endpointObj,"type");
               json_t* addrString = json_object_get(endpointObj,"address");
               json_t* portInt = json_object_get(endpointObj,"port");

               if (portInt == NULL || !json_is_integer(portInt)) {
                   qeo_log_w("locator object did not contain a integer field called 'port' (%p)",  portInt);
                   break;
               }
               if (addrString == NULL || !json_is_string(addrString)) {
                   qeo_log_w("locator object did not contain a string field called 'address' (%p)",  addrString);
                   break;
               }
               if (typeString == NULL || !json_is_string(typeString)) {
                   qeo_log_w("locator object did not contain a string field called 'type' (%p)",  typeString);
                   break;
               }
               qeo_log_i("locator object %d = {type = '%s', address = '%s', port = %d}",  j, json_string_value(typeString),
                         json_string_value(addrString), (int) json_integer_value(portInt));
               //valid locator

               fwd->locators[j].port = (int) json_integer_value(portInt);
               if (fwd->locators[j].port < -1 || fwd->locators[j].port > 0xffff){
                   qeo_log_w("Invalid port inside locator");
                   break;
               }
               fwd->locators[j].type = _get_locator_type(json_string_value(typeString));
               fwd->locators[j].address = strdup(json_string_value(addrString)); //check value; don't forget to free!
               if (fwd->locators[j].address == NULL) {
                   qeo_log_w("locator->address == NULL");
                   break;
               }
           }
           if (j != nrOfLocators){
               break;
           }
           cb_result = callback(fwd, cookie);
           fwd = NULL; //pointer is handed over; set it to NULL so we wont free it.
           if (cb_result != QMGMTCLIENT_OK) {//the callback reports an error abort.
               result = cb_result;
               break;

           }
       }
       if (i != fwdSize){
           break;
       }
       qeo_log_i("Successfully walked JSON object tree...");
       result = QMGMTCLIENT_OK;
    }
    while(0);
    if (message) {
        json_decref(message);
    }
    if (fwd) { //if an error occurred, then the 'fwd' is not freed.
        qeo_mgmt_client_free_forwarder(fwd);
    }

    return result;
}
Beispiel #22
0
void net_json_convert_min3(json_t* r) {
 
  // ADC has changed i/o count from [2,2] to [3,2],
  // and likewise size of byte-arry of state data.

  // there is only one ADC operator, so this isn't too bad.
  
  /// magic number based on what 0.3.x scenes looked like.
  int lastAdcIn = 29;

  json_t* ins = json_object_get(r, "ins");
  json_t* insData = json_object_get(ins, "data");
  int insCount = json_integer_value(json_object_get(ins, "count"));
  json_integer_set(json_object_get(ins, "count"), insCount + 1);

  // need to f*x 

  // all we should have to do for input nodes is: 
  // - insert a new node
  // - fix everyone's index
  json_t* o = json_object();
  json_object_set(o, "idx", json_integer(lastAdcIn));
  json_object_set(o, "name", json_string("MODE    "));
  json_object_set(o, "opIdx", json_integer(10));
  json_object_set(o, "opInIdx", json_integer(2));
  json_object_set(o, "value", json_integer(0));
  json_object_set(o, "play", json_integer(0));
  int err  = json_array_insert(insData, lastAdcIn + 1, o );

  if(err != 0) { printf(" error inserting input node in ADC op conversion."); }
  
  // loop over input nodes and fix idx fields
  for(int i=0; i<NET_INS_MAX; i++) {
    json_integer_set(json_object_get(json_array_get(insData, i), "idx"), i);
  }

  // we also have to add some dummy values to the byte array of the ADC op's state.
  json_t* ops = json_object_get(r, "ops");
  // 10 is the magic number of the ADC op in 0.3.x
  json_t* adc = json_array_get(json_object_get(ops, "data"), 10);
  // mode pickle: 2 bytes input value, zero is fine
  json_array_append(json_object_get(adc, "state"),  json_integer(0));
  json_array_append(json_object_get(adc, "state"),  json_integer(0));

  /* // copy all input nodes above this operator's... */
  /* // count down from top. src has fewer input nodes; otherwise we would lose last value. */
  /* for(int i = NET_INS_MAX - 1; i > lastAdcIn; i--) { */
  /*   // get json object at this index in node array */
  /*   json_t* dst = json_array_get(insData, i); */
  /*   json_t* src = json_array_get(insData, i - 1);     */
  /*   if(src != NULL) { */
  /*     if(dst == NULL) { */
  /* 	int err; */
  /* 	dst = json_object(); */
  /* 	json_object_set(dst, "idx", json_integer(i)); */
  /* 	err = json_array_insert(insData, i, dst); */
  /* 	if(err != 0) { printf(" error inserting input node in ADC op conversion."); } */
  /*     } */
  /*     // shallow copy ok? */
  /*     json_array_set(insData, src); */
  /*     // custom-copy, leaving idx */
  /*     /\* json_object_(dst, "name", json_object_get(src, "name")); *\/ */
  /*     /\* json_object_set(dst, "opIdx", json_object_get(src, "opIdx")); *\/ */
  /*     /\* json_object_set(dst, "opInIdx", json_object_get(src, "opInIdx")); *\/ */
  /*     /\* json_object_set(dst, "value", json_object_get(src, "value")); *\/ */
  /*     /\* json_object_set(dst, "play", json_object_get(src, "play")); *\/ */
  /*   } */
  /* } */
  /* // finally, we need to fix up the values for the new input ("mode");   */
  /* ///... FIXME */

  
  //---- -outs
  json_t* outs = json_object_get(r, "outs");
  json_t* outsData = json_object_get(outs, "data");
  // loop over all outputs and check targets
  for(int i = 0; i< NET_OUTS_MAX; i++) {
    json_t* o = json_array_get(outsData, i);
    int t = json_integer_value(json_object_get(o, "target"));
      if(t > lastAdcIn) {
	json_integer_set(json_object_get(o, "target"), t + 1);
      }
  }

  // i don't think anyone really used presets in this rev, so skipping those for now.

  // write the output of the converted json for a visual check.
  json_dump_file(r, "converted.json", JSON_INDENT(4) | JSON_PRESERVE_ORDER | JSON_ESCAPE_SLASH);
}
Beispiel #23
0
static void test_misc()
{
    json_t *object, *string, *other_string, *value;

    object = json_object();
    string = json_string("test");
    other_string = json_string("other");

    if(!object)
        fail("unable to create object");
    if(!string || !other_string)
        fail("unable to create string");

    if(json_object_get(object, "a"))
        fail("value for nonexisting key");

    if(json_object_set(object, "a", string))
        fail("unable to set value");

    if(!json_object_set(object, NULL, string))
        fail("able to set NULL key");

    if(!json_object_set(object, "a", NULL))
        fail("able to set NULL value");

    /* invalid UTF-8 in key */
    if(!json_object_set(object, "a\xefz", string))
        fail("able to set invalid unicode key");

    value = json_object_get(object, "a");
    if(!value)
        fail("no value for existing key");
    if(value != string)
        fail("got different value than what was added");

    /* "a", "lp" and "px" collide in a five-bucket hashtable */
    if(json_object_set(object, "b", string) ||
       json_object_set(object, "lp", string) ||
       json_object_set(object, "px", string))
        fail("unable to set value");

    value = json_object_get(object, "a");
    if(!value)
        fail("no value for existing key");
    if(value != string)
        fail("got different value than what was added");

    if(json_object_set(object, "a", other_string))
        fail("unable to replace an existing key");

    value = json_object_get(object, "a");
    if(!value)
        fail("no value for existing key");
    if(value != other_string)
        fail("got different value than what was set");

    if(!json_object_del(object, "nonexisting"))
        fail("able to delete a nonexisting key");

    if(json_object_del(object, "px"))
        fail("unable to delete an existing key");

    if(json_object_del(object, "a"))
        fail("unable to delete an existing key");

    if(json_object_del(object, "lp"))
        fail("unable to delete an existing key");


    /* add many keys to initiate rehashing */

    if(json_object_set(object, "a", string))
        fail("unable to set value");

    if(json_object_set(object, "lp", string))
        fail("unable to set value");

    if(json_object_set(object, "px", string))
        fail("unable to set value");

    if(json_object_set(object, "c", string))
        fail("unable to set value");

    if(json_object_set(object, "d", string))
        fail("unable to set value");

    if(json_object_set(object, "e", string))
        fail("unable to set value");


    if(json_object_set_new(object, "foo", json_integer(123)))
        fail("unable to set new value");

    value = json_object_get(object, "foo");
    if(!json_is_integer(value) || json_integer_value(value) != 123)
        fail("json_object_set_new works incorrectly");

    if(!json_object_set_new(object, NULL, json_integer(432)))
        fail("able to set_new NULL key");

    if(!json_object_set_new(object, "foo", NULL))
        fail("able to set_new NULL value");

    json_decref(string);
    json_decref(other_string);
    json_decref(object);
}
Beispiel #24
0
bool TrafficNetwork::loadFromFile(const string fileName){
	int nbBands;
	long currentNode,otherNode;
	string roadName;
	double roadLength;
	double roadSpeedLimit;
	int metric;

	json_t *root;
	json_error_t error;

	root = json_load_file(fileName.c_str(), 0, &error);

	if(!root){
		std::cout<<std::endl<<"ERROR: while opening "<<fileName<<" at line "<<error.line<<" - "<<error.text<<std::endl;
		return false;
	}

	if(!json_is_object(root)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - expected root to be an object"<<std::endl;
		json_decref(root);
		return false;
	}

	json_t *_metric, *_roads, *_nodes;
	_metric = json_object_get(root,"metric");

	if(!json_is_integer(_metric)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'metric' field not present or wrong type"<<std::endl;
		json_decref(root);
		return false;
	}
	metric = json_integer_value(_metric);

	_nodes = json_object_get(root,"nodes");
	if(!json_is_array(_nodes)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'nodes' field not present or not an array"<<std::endl;
		json_decref(root);
		return false;
	}

	size_t n = json_array_size(_nodes);
	nbNodes = n;
	nodes = NodeVec(nbNodes);
	json_t *nodeId,*_node, *nodeType;
	for(size_t i = 0; i < n; i++){
		_node = json_array_get(_nodes,i);
		if(!json_is_object(_node)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - expected node "<<i<<" to be an object"<<std::endl;
			json_decref(root);
			return false;
		}
		nodeId = json_object_get(_node,"id");
		if(!json_is_integer(nodeId)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'id' field of node "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		nodeType = json_object_get(_node,"type");
		if(json_is_integer(nodeType)){
			nodes[i] = new Node(json_integer_value(nodeId),json_integer_value(nodeType));
		}else{
			nodes[i] = new Node(json_integer_value(nodeId));
		}

	}

	_roads = json_object_get(root,"roads");
	if(!json_is_array(_roads)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'roads' field not present or not an array"<<std::endl;
		json_decref(root);
		return false;
	}

	n = json_array_size(_roads);
	json_t *_roadName,*_roadSpeedLimit,*_roadNbBands,*_roadLength,*_road,*startId,*endId;
	for(size_t i = 0; i < n; i++){
		_road = json_array_get(_roads,i);
		if(!json_is_object(_road)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - expected road "<<i<<" to be an object"<<std::endl;
			json_decref(root);
			return false;
		}

		_roadName = json_object_get(_road,"name");
		if(!json_is_string(_roadName)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'name' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		roadName = json_string_value(_roadName);

		_roadSpeedLimit = json_object_get(_road,"speedLimit");
		if(!json_is_integer(_roadSpeedLimit)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'speedLimit' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		roadSpeedLimit = formatSpeedLimit(json_integer_value(_roadSpeedLimit),metric);

		_roadLength = json_object_get(_road,"length");
		if(!json_is_real(_roadLength)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'length' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		roadLength = formatLength(json_real_value(_roadLength),metric);

		_roadNbBands = json_object_get(_road,"nbBands");
		if(!json_is_integer(_roadNbBands)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'nbBands' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		nbBands = json_integer_value(_roadNbBands);

		startId = json_object_get(_road,"startId");
		if(!json_is_integer(startId)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'startId' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		currentNode = json_integer_value(startId);

		endId = json_object_get(_road,"endId");
		if(!json_is_integer(endId)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'endId' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		otherNode = json_integer_value(endId);
		addRoad(currentNode, otherNode, roadName, roadLength, roadSpeedLimit,nbBands);
	}
	//clean up
	json_array_clear(_nodes);
	json_object_clear(_road);
	json_array_clear(_roads);
	json_object_clear(root);
	json_decref(root);
	return true;
}
Beispiel #25
0
/* Call the simple functions not covered by other tests of the public API */
static void run_tests()
{
    json_t *value;

    value = json_boolean(1);
    if(!json_is_true(value))
        fail("json_boolean(1) failed");
    json_decref(value);

    value = json_boolean(-123);
    if(!json_is_true(value))
        fail("json_boolean(-123) failed");
    json_decref(value);

    value = json_boolean(0);
    if(!json_is_false(value))
        fail("json_boolean(0) failed");
    if(json_boolean_value(value) != 0)
        fail("json_boolean_value failed");
    json_decref(value);


    value = json_integer(1);
    if(json_typeof(value) != JSON_INTEGER)
        fail("json_typeof failed");

    if(json_is_object(value))
        fail("json_is_object failed");

    if(json_is_array(value))
        fail("json_is_array failed");

    if(json_is_string(value))
        fail("json_is_string failed");

    if(!json_is_integer(value))
        fail("json_is_integer failed");

    if(json_is_real(value))
        fail("json_is_real failed");

    if(!json_is_number(value))
        fail("json_is_number failed");

    if(json_is_true(value))
        fail("json_is_true failed");

    if(json_is_false(value))
        fail("json_is_false failed");

    if(json_is_boolean(value))
        fail("json_is_boolean failed");

    if(json_is_null(value))
        fail("json_is_null failed");

    json_decref(value);


    value = json_string("foo");
    if(!value)
        fail("json_string failed");
    if(strcmp(json_string_value(value), "foo"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    if(json_string_set(value, "barr"))
        fail("json_string_set failed");
    if(strcmp(json_string_value(value), "barr"))
        fail("invalid string value");
    if (json_string_length(value) != 4)
        fail("invalid string length");

    if(json_string_setn(value, "hi\0ho", 5))
        fail("json_string_set failed");
    if(memcmp(json_string_value(value), "hi\0ho\0", 6))
        fail("invalid string value");
    if (json_string_length(value) != 5)
        fail("invalid string length");

    json_decref(value);

    value = json_string(NULL);
    if(value)
        fail("json_string(NULL) failed");

    /* invalid UTF-8  */
    value = json_string("a\xefz");
    if(value)
        fail("json_string(<invalid utf-8>) failed");

    value = json_string_nocheck("foo");
    if(!value)
        fail("json_string_nocheck failed");
    if(strcmp(json_string_value(value), "foo"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    if(json_string_set_nocheck(value, "barr"))
        fail("json_string_set_nocheck failed");
    if(strcmp(json_string_value(value), "barr"))
        fail("invalid string value");
    if (json_string_length(value) != 4)
        fail("invalid string length");

    if(json_string_setn_nocheck(value, "hi\0ho", 5))
        fail("json_string_set failed");
    if(memcmp(json_string_value(value), "hi\0ho\0", 6))
        fail("invalid string value");
    if (json_string_length(value) != 5)
        fail("invalid string length");

    json_decref(value);

    /* invalid UTF-8 */
    value = json_string_nocheck("qu\xff");
    if(!value)
        fail("json_string_nocheck failed");
    if(strcmp(json_string_value(value), "qu\xff"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    if(json_string_set_nocheck(value, "\xfd\xfe\xff"))
        fail("json_string_set_nocheck failed");
    if(strcmp(json_string_value(value), "\xfd\xfe\xff"))
        fail("invalid string value");
    if (json_string_length(value) != 3)
        fail("invalid string length");

    json_decref(value);


    value = json_integer(123);
    if(!value)
        fail("json_integer failed");
    if(json_integer_value(value) != 123)
        fail("invalid integer value");
    if(json_number_value(value) != 123.0)
        fail("invalid number value");

    if(json_integer_set(value, 321))
        fail("json_integer_set failed");
    if(json_integer_value(value) != 321)
        fail("invalid integer value");
    if(json_number_value(value) != 321.0)
        fail("invalid number value");

    json_decref(value);

    value = json_real(123.123);
    if(!value)
        fail("json_real failed");
    if(json_real_value(value) != 123.123)
        fail("invalid integer value");
    if(json_number_value(value) != 123.123)
        fail("invalid number value");

    if(json_real_set(value, 321.321))
        fail("json_real_set failed");
    if(json_real_value(value) != 321.321)
        fail("invalid real value");
    if(json_number_value(value) != 321.321)
        fail("invalid number value");

    json_decref(value);

    value = json_true();
    if(!value)
        fail("json_true failed");
    json_decref(value);

    value = json_false();
    if(!value)
        fail("json_false failed");
    json_decref(value);

    value = json_null();
    if(!value)
        fail("json_null failed");
    json_decref(value);

    /* Test reference counting on singletons (true, false, null) */
    value = json_true();
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");

    value = json_false();
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");

    value = json_null();
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
}
HueOutputLightRGB::HueOutputLightRGB(Params &p):
    OutputLightRGB(p)
{
    ioDoc->friendlyNameSet("HueOutputLightRGB");
    ioDoc->descriptionSet(_("RGB Light dimmer using a Philips Hue"));
    ioDoc->linkAdd("Meet Hue", _("http://www.meethue.com"));
    ioDoc->paramAdd("host", _("Hue bridge IP address"), IODoc::TYPE_STRING, true);
    ioDoc->paramAdd("api", _("API key return by Hue bridge when assciation has been made. Use Hue Wizard in calaos_installer to get this value automatically."), IODoc::TYPE_STRING, true);
    ioDoc->paramAdd("id_hue", _("Unique ID describing the Hue Light. This value is returned by the Hue Wizard."), IODoc::TYPE_STRING, true);

    m_host = get_param("host");
    m_api = get_param("api");
    m_idHue = get_param("id_hue");

    m_timer = new EcoreTimer(2.0,[=](){
        std::string url = "http://" + m_host + "/api/" + m_api + "/lights/" + m_idHue;
        UrlDownloader *dl = new UrlDownloader(url, true);
        dl->m_signalCompleteData.connect([&](Eina_Binbuf *downloadedData, int status)
    {
         if (status)
         {
              json_error_t error;
              const unsigned char* c = eina_binbuf_string_get(downloadedData);
              json_t *root = json_loads((const char*)eina_binbuf_string_get(downloadedData), 0, &error);
              if (!root)
              {
                   cErrorDom("hue") << "Json received malformed : " << error.source
                                    << " " << error.text << " (" << Utils::to_string(error.line) << " )";
                   return;
              }
              if (!json_is_object(root))
              {
                   cErrorDom("hue") << "Protocol changed ? date received : " << eina_binbuf_string_get(downloadedData);
                   return;
              }

              json_t *tstate = json_object_get(root, "state");
              if (!tstate || !json_is_object(tstate))
              {
                   cErrorDom("hue") << "Protocol changed ? date received : " << eina_binbuf_string_get(downloadedData);
                   return;
              }

              int sat, bri, hue;
              bool on, reachable;

              sat = json_integer_value(json_object_get(tstate, "sat"));
              bri = json_integer_value(json_object_get(tstate, "bri"));
              hue = json_integer_value(json_object_get(tstate, "hue"));
              on = jansson_bool_get(tstate, "on");
              reachable = jansson_bool_get(tstate, "reachable");

              cDebugDom("hue") << "State: " << on << " Hue : " << hue << " Bri: " << bri << " Hue : " << hue << "Data : " << c;

              if (reachable)
                   stateUpdated(ColorValue::fromHsl((int)(hue * 360.0 / 65535.0),
                                                    (int)(sat * 100.0 / 255.0),
                                                    (int)(bri * 100.0 / 255.0)), on);
              else
                   stateUpdated(ColorValue(0,0,0), reachable);

              json_decref(root);
         }
         else
         {
              stateUpdated(ColorValue(0,0,0), false);
         }
    });

        if (!dl->httpGet())
             delete dl;
         });
}
Beispiel #27
0
/* Main Code */
int main(int argc, char *argv[])
{
	janus_log_init(FALSE, TRUE, NULL);
	atexit(janus_log_destroy);

	/* Check the JANUS_PPREC_DEBUG environment variable for the debugging level */
	if(g_getenv("JANUS_PPREC_DEBUG") != NULL) {
		int val = atoi(g_getenv("JANUS_PPREC_DEBUG"));
		if(val >= LOG_NONE && val <= LOG_MAX)
			janus_log_level = val;
		JANUS_LOG(LOG_INFO, "Logging level: %d\n", janus_log_level);
	}
	
	/* Evaluate arguments */
	if(argc != 3) {
		JANUS_LOG(LOG_INFO, "Usage: %s source.mjr destination.[opus|wav|webm|mp4]\n", argv[0]);
		JANUS_LOG(LOG_INFO, "       %s --header source.mjr (only parse header)\n", argv[0]);
		JANUS_LOG(LOG_INFO, "       %s --parse source.mjr (only parse and re-order packets)\n", argv[0]);
		return -1;
	}
	char *source = NULL, *destination = NULL;
	gboolean header_only = !strcmp(argv[1], "--header");
	gboolean parse_only = !strcmp(argv[1], "--parse");
	if(header_only || parse_only) {
		/* Only parse the .mjr header and/or re-order the packets, no processing */
		source = argv[2];
	} else {
		/* Post-process the .mjr recording */
		source = argv[1];
		destination = argv[2];
		JANUS_LOG(LOG_INFO, "%s --> %s\n", source, destination);
	}
	FILE *file = fopen(source, "rb");
	if(file == NULL) {
		JANUS_LOG(LOG_ERR, "Could not open file %s\n", source);
		return -1;
	}
	fseek(file, 0L, SEEK_END);
	long fsize = ftell(file);
	fseek(file, 0L, SEEK_SET);
	JANUS_LOG(LOG_INFO, "File is %zu bytes\n", fsize);

	/* Handle SIGINT */
	working = 1;
	signal(SIGINT, janus_pp_handle_signal);

	/* Pre-parse */
	JANUS_LOG(LOG_INFO, "Pre-parsing file to generate ordered index...\n");
	gboolean parsed_header = FALSE;
	int video = 0;
	int opus = 0, g711 = 0, vp8 = 0, vp9 = 0, h264 = 0;
	gint64 c_time = 0, w_time = 0;
	int bytes = 0, skip = 0;
	long offset = 0;
	uint16_t len = 0, count = 0;
	uint32_t last_ts = 0, reset = 0;
	int times_resetted = 0;
	uint32_t post_reset_pkts = 0;
	char prebuffer[1500];
	memset(prebuffer, 0, 1500);
	/* Let's look for timestamp resets first */
	while(working && offset < fsize) {
		if(header_only && parsed_header) {
			/* We only needed to parse the header */
			exit(0);
		}
		/* Read frame header */
		skip = 0;
		fseek(file, offset, SEEK_SET);
		bytes = fread(prebuffer, sizeof(char), 8, file);
		if(bytes != 8 || prebuffer[0] != 'M') {
			JANUS_LOG(LOG_WARN, "Invalid header at offset %ld (%s), the processing will stop here...\n",
				offset, bytes != 8 ? "not enough bytes" : "wrong prefix");
			break;
		}
		if(prebuffer[1] == 'E') {
			/* Either the old .mjr format header ('MEETECHO' header followed by 'audio' or 'video'), or a frame */
			offset += 8;
			bytes = fread(&len, sizeof(uint16_t), 1, file);
			len = ntohs(len);
			offset += 2;
			if(len == 5 && !parsed_header) {
				/* This is the main header */
				parsed_header = TRUE;
				JANUS_LOG(LOG_WARN, "Old .mjr header format\n");
				bytes = fread(prebuffer, sizeof(char), 5, file);
				if(prebuffer[0] == 'v') {
					JANUS_LOG(LOG_INFO, "This is a video recording, assuming VP8\n");
					video = 1;
					vp8 = 1;
				} else if(prebuffer[0] == 'a') {
					JANUS_LOG(LOG_INFO, "This is an audio recording, assuming Opus\n");
					video = 0;
					opus = 1;
				} else {
					JANUS_LOG(LOG_WARN, "Unsupported recording media type...\n");
					exit(1);
				}
				offset += len;
				continue;
			} else if(len < 12) {
				/* Not RTP, skip */
				JANUS_LOG(LOG_VERB, "Skipping packet (not RTP?)\n");
				offset += len;
				continue;
			}
		} else if(prebuffer[1] == 'J') {
			/* New .mjr format, the header may contain useful info */
			offset += 8;
			bytes = fread(&len, sizeof(uint16_t), 1, file);
			len = ntohs(len);
			offset += 2;
			if(len > 0 && !parsed_header) {
				/* This is the info header */
				JANUS_LOG(LOG_WARN, "New .mjr header format\n");
				bytes = fread(prebuffer, sizeof(char), len, file);
				parsed_header = TRUE;
				prebuffer[len] = '\0';
				json_error_t error;
				json_t *info = json_loads(prebuffer, 0, &error);
				if(!info) {
					JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
					JANUS_LOG(LOG_WARN, "Error parsing info header...\n");
					exit(1);
				}
				/* Is it audio or video? */
				json_t *type = json_object_get(info, "t");
				if(!type || !json_is_string(type)) {
					JANUS_LOG(LOG_WARN, "Missing/invalid recording type in info header...\n");
					exit(1);
				}
				const char *t = json_string_value(type);
				if(!strcasecmp(t, "v")) {
					video = 1;
				} else if(!strcasecmp(t, "a")) {
					video = 0;
				} else {
					JANUS_LOG(LOG_WARN, "Unsupported recording type '%s' in info header...\n", t);
					exit(1);
				}
				/* What codec was used? */
				json_t *codec = json_object_get(info, "c");
				if(!codec || !json_is_string(codec)) {
					JANUS_LOG(LOG_WARN, "Missing recording codec in info header...\n");
					exit(1);
				}
				const char *c = json_string_value(codec);
				if(video) {
					if(!strcasecmp(c, "vp8")) {
						vp8 = 1;
					} else if(!strcasecmp(c, "vp9")) {
						vp9 = 1;
					} else if(!strcasecmp(c, "h264")) {
						h264 = 1;
					} else {
						JANUS_LOG(LOG_WARN, "The post-processor only supports VP8, VP9 and H.264 video for now (was '%s')...\n", c);
						exit(1);
					}
				} else if(!video) {
					if(!strcasecmp(c, "opus")) {
						opus = 1;
					} else if(!strcasecmp(c, "g711")) {
						g711 = 1;
					} else {
						JANUS_LOG(LOG_WARN, "The post-processor only suupports Opus and G.711 audio for now (was '%s')...\n", c);
						exit(1);
					}
				}
				/* When was the file created? */
				json_t *created = json_object_get(info, "s");
				if(!created || !json_is_integer(created)) {
					JANUS_LOG(LOG_WARN, "Missing recording created time in info header...\n");
					exit(1);
				}
				c_time = json_integer_value(created);
				/* When was the first frame written? */
				json_t *written = json_object_get(info, "u");
				if(!written || !json_is_integer(written)) {
					JANUS_LOG(LOG_WARN, "Missing recording written time in info header...\n");
					exit(1);
				}
				w_time = json_integer_value(written);
				/* Summary */
				JANUS_LOG(LOG_INFO, "This is %s recording:\n", video ? "a video" : "an audio");
				JANUS_LOG(LOG_INFO, "  -- Codec:   %s\n", c);
				JANUS_LOG(LOG_INFO, "  -- Created: %"SCNi64"\n", c_time);
				JANUS_LOG(LOG_INFO, "  -- Written: %"SCNi64"\n", w_time);
			}
		} else {
			JANUS_LOG(LOG_ERR, "Invalid header...\n");
			exit(1);
		}
		/* Only read RTP header */
		bytes = fread(prebuffer, sizeof(char), 16, file);
		janus_pp_rtp_header *rtp = (janus_pp_rtp_header *)prebuffer;
		if(last_ts > 0) {
			/* Is the new timestamp smaller than the next one, and if so, is it a timestamp reset or simply out of order? */
			if(ntohl(rtp->timestamp) < last_ts && (last_ts-ntohl(rtp->timestamp) > 2*1000*1000*1000)) {
				reset = ntohl(rtp->timestamp);
				JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
				times_resetted++;
				post_reset_pkts = 0;
			} else if(ntohl(rtp->timestamp) < reset) {
				if(post_reset_pkts < 1000) {
					JANUS_LOG(LOG_WARN, "Updating latest timestamp reset: %"SCNu32" (was %"SCNu32")\n", ntohl(rtp->timestamp), reset);
					reset = ntohl(rtp->timestamp);
				} else {
					reset = ntohl(rtp->timestamp);
					JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
					times_resetted++;
					post_reset_pkts = 0;
				}
			}
		}
		last_ts = ntohl(rtp->timestamp);
		post_reset_pkts++;
		/* Skip data for now */
		offset += len;
	}
	if(!working)
		exit(0);
	JANUS_LOG(LOG_WARN, "Counted %d timestamp resets\n", times_resetted);
	/* Now let's parse the frames and order them */
	offset = 0;
	/* Timestamp reset related stuff */
	last_ts = 0;
	reset = 0;
	times_resetted = 0;
	post_reset_pkts = 0;
	uint64_t max32 = UINT32_MAX;
	/* Start loop */
	while(working && offset < fsize) {
		/* Read frame header */
		skip = 0;
		fseek(file, offset, SEEK_SET);
		bytes = fread(prebuffer, sizeof(char), 8, file);
		if(bytes != 8 || prebuffer[0] != 'M') {
			/* Broken packet? Stop here */
			break;
		}
		prebuffer[8] = '\0';
		JANUS_LOG(LOG_VERB, "Header: %s\n", prebuffer);
		offset += 8;
		bytes = fread(&len, sizeof(uint16_t), 1, file);
		len = ntohs(len);
		JANUS_LOG(LOG_VERB, "  -- Length: %"SCNu16"\n", len);
		offset += 2;
		if(prebuffer[1] == 'J' || len < 12) {
			/* Not RTP, skip */
			JANUS_LOG(LOG_VERB, "  -- Not RTP, skipping\n");
			offset += len;
			continue;
		}
		if(len > 2000) {
			/* Way too large, very likely not RTP, skip */
			JANUS_LOG(LOG_VERB, "  -- Too large packet (%d bytes), skipping\n", len);
			offset += len;
			continue;
		}
		/* Only read RTP header */
		bytes = fread(prebuffer, sizeof(char), 16, file);
		janus_pp_rtp_header *rtp = (janus_pp_rtp_header *)prebuffer;
		JANUS_LOG(LOG_VERB, "  -- RTP packet (ssrc=%"SCNu32", pt=%"SCNu16", ext=%"SCNu16", seq=%"SCNu16", ts=%"SCNu32")\n",
				ntohl(rtp->ssrc), rtp->type, rtp->extension, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
		if(rtp->extension) {
			janus_pp_rtp_header_extension *ext = (janus_pp_rtp_header_extension *)(prebuffer+12);
		JANUS_LOG(LOG_VERB, "  -- -- RTP extension (type=%"SCNu16", length=%"SCNu16")\n",
				ntohs(ext->type), ntohs(ext->length)); 
			skip = 4 + ntohs(ext->length)*4;
		}
		/* Generate frame packet and insert in the ordered list */
		janus_pp_frame_packet *p = g_malloc0(sizeof(janus_pp_frame_packet));
		if(p == NULL) {
			JANUS_LOG(LOG_ERR, "Memory error!\n");
			return -1;
		}
		p->seq = ntohs(rtp->seq_number);
		p->pt = rtp->type;
		/* Due to resets, we need to mess a bit with the original timestamps */
		if(last_ts == 0) {
			/* Simple enough... */
			p->ts = ntohl(rtp->timestamp);
		} else {
			/* Is the new timestamp smaller than the next one, and if so, is it a timestamp reset or simply out of order? */
			if(ntohl(rtp->timestamp) < last_ts && (last_ts-ntohl(rtp->timestamp) > 2*1000*1000*1000)) {
				reset = ntohl(rtp->timestamp);
				JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
				times_resetted++;
				post_reset_pkts = 0;
			} else if(ntohl(rtp->timestamp) < reset) {
				if(post_reset_pkts < 1000) {
					JANUS_LOG(LOG_WARN, "Updating latest timestamp reset: %"SCNu32" (was %"SCNu32")\n", ntohl(rtp->timestamp), reset);
					reset = ntohl(rtp->timestamp);
				} else {
					reset = ntohl(rtp->timestamp);
					JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
					times_resetted++;
					post_reset_pkts = 0;
				}
			}
			/* Take into account the number of resets when setting the internal, 64-bit, timestamp */
			p->ts = (times_resetted*max32)+ntohl(rtp->timestamp);
		}
		p->len = len;
		p->drop = 0;
		if(rtp->padding) {
			/* There's padding data, let's check the last byte to see how much data we should skip */
			fseek(file, offset + len - 1, SEEK_SET);
			fread(prebuffer, sizeof(char), 1, file);
			uint8_t padlen = (uint8_t)prebuffer[0];
			JANUS_LOG(LOG_VERB, "Padding at sequence number %hu: %d/%d\n",
				ntohs(rtp->seq_number), padlen, p->len);
			p->len -= padlen;
			if((p->len - skip - 12) <= 0) {
				/* Only padding, take note that we should drop the packet later */
				p->drop = 1;
				JANUS_LOG(LOG_VERB, "  -- All padding, marking packet as dropped\n");
			}
		}
		last_ts = ntohl(rtp->timestamp);
		post_reset_pkts++;
		/* Fill in the rest of the details */
		p->offset = offset;
		p->skip = skip;
		p->next = NULL;
		p->prev = NULL;
		if(list == NULL) {
			/* First element becomes the list itself (and the last item), at least for now */
			list = p;
			last = p;
		} else {
			/* Check where we should insert this, starting from the end */
			int added = 0;
			janus_pp_frame_packet *tmp = last;
			while(tmp) {
				if(tmp->ts < p->ts) {
					/* The new timestamp is greater than the last one we have, append */
					added = 1;
					if(tmp->next != NULL) {
						/* We're inserting */
						tmp->next->prev = p;
						p->next = tmp->next;
					} else {
						/* Update the last packet */
						last = p;
					}
					tmp->next = p;
					p->prev = tmp;
					break;
				} else if(tmp->ts == p->ts) {
					/* Same timestamp, check the sequence number */
					if(tmp->seq < p->seq && (abs(tmp->seq - p->seq) < 10000)) {
						/* The new sequence number is greater than the last one we have, append */
						added = 1;
						if(tmp->next != NULL) {
							/* We're inserting */
							tmp->next->prev = p;
							p->next = tmp->next;
						} else {
							/* Update the last packet */
							last = p;
						}
						tmp->next = p;
						p->prev = tmp;
						break;
					} else if(tmp->seq > p->seq && (abs(tmp->seq - p->seq) > 10000)) {
						/* The new sequence number (resetted) is greater than the last one we have, append */
						added = 1;
						if(tmp->next != NULL) {
							/* We're inserting */
							tmp->next->prev = p;
							p->next = tmp->next;
						} else {
							/* Update the last packet */
							last = p;
						}
						tmp->next = p;
						p->prev = tmp;
						break;
					}
				}
				/* If either the timestamp ot the sequence number we just got is smaller, keep going back */
				tmp = tmp->prev;
			}
			if(!added) {
				/* We reached the start */
				p->next = list;
				list->prev = p;
				list = p;
			}
		}
		/* Skip data for now */
		offset += len;
		count++;
	}
	if(!working)
		exit(0);
	
	JANUS_LOG(LOG_INFO, "Counted %"SCNu16" RTP packets\n", count);
	janus_pp_frame_packet *tmp = list;
	count = 0;
	while(tmp) {
		count++;
		JANUS_LOG(LOG_VERB, "[%10lu][%4d] seq=%"SCNu16", ts=%"SCNu64", time=%"SCNu64"s\n", tmp->offset, tmp->len, tmp->seq, tmp->ts, (tmp->ts-list->ts)/90000);
		tmp = tmp->next;
	}
	JANUS_LOG(LOG_INFO, "Counted %"SCNu16" frame packets\n", count);

	if(video) {
		/* Look for maximum width and height, if possible, and for the average framerate */
		if(vp8 || vp9) {
			if(janus_pp_webm_preprocess(file, list, vp8) < 0) {
				JANUS_LOG(LOG_ERR, "Error pre-processing %s RTP frames...\n", vp8 ? "VP8" : "VP9");
				exit(1);
			}
		} else if(h264) {
			if(janus_pp_h264_preprocess(file, list) < 0) {
				JANUS_LOG(LOG_ERR, "Error pre-processing H.264 RTP frames...\n");
				exit(1);
			}
		}
	}

	if(parse_only) {
		/* We only needed to parse and re-order the packets, we're done here */
		JANUS_LOG(LOG_INFO, "Parsing and reordering completed, bye!\n");
		exit(0);
	}

	if(!video) {
		if(opus) {
			if(janus_pp_opus_create(destination) < 0) {
				JANUS_LOG(LOG_ERR, "Error creating .opus file...\n");
				exit(1);
			}
		} else if(g711) {
			if(janus_pp_g711_create(destination) < 0) {
				JANUS_LOG(LOG_ERR, "Error creating .wav file...\n");
				exit(1);
			}
		}
	} else {
		if(vp8 || vp9) {
			if(janus_pp_webm_create(destination, vp8) < 0) {
				JANUS_LOG(LOG_ERR, "Error creating .webm file...\n");
				exit(1);
			}
		} else if(h264) {
			if(janus_pp_h264_create(destination) < 0) {
				JANUS_LOG(LOG_ERR, "Error creating .mp4 file...\n");
				exit(1);
			}
		}
	}
	
	/* Loop */
	if(!video) {
		if(opus) {
			if(janus_pp_opus_process(file, list, &working) < 0) {
				JANUS_LOG(LOG_ERR, "Error processing Opus RTP frames...\n");
			}
		} else if(g711) {
			if(janus_pp_g711_process(file, list, &working) < 0) {
				JANUS_LOG(LOG_ERR, "Error processing G.711 RTP frames...\n");
			}
		}
	} else {
		if(vp8 || vp9) {
			if(janus_pp_webm_process(file, list, vp8, &working) < 0) {
				JANUS_LOG(LOG_ERR, "Error processing %s RTP frames...\n", vp8 ? "VP8" : "VP9");
			}
		} else {
			if(janus_pp_h264_process(file, list, &working) < 0) {
				JANUS_LOG(LOG_ERR, "Error processing H.264 RTP frames...\n");
			}
		}
	}

	/* Clean up */
	if(video) {
		if(vp8 || vp9) {
			janus_pp_webm_close();
		} else {
			janus_pp_h264_close();
		}
	} else {
		if(opus) {
			janus_pp_opus_close();
		} else if(g711) {
			janus_pp_g711_close();
		}
	}
	fclose(file);
	
	file = fopen(destination, "rb");
	if(file == NULL) {
		JANUS_LOG(LOG_INFO, "No destination file %s??\n", destination);
	} else {
		fseek(file, 0L, SEEK_END);
		fsize = ftell(file);
		fseek(file, 0L, SEEK_SET);
		JANUS_LOG(LOG_INFO, "%s is %zu bytes\n", destination, fsize);
		fclose(file);
	}
	janus_pp_frame_packet *temp = list, *next = NULL;
	while(temp) {
		next = temp->next;
		g_free(temp);
		temp = next;
	}

	JANUS_LOG(LOG_INFO, "Bye!\n");
	return 0;
}
/* Thread to handle incoming messages */
static void *janus_videocall_handler(void *data) {
	JANUS_LOG(LOG_VERB, "Joining VideoCall handler thread\n");
	janus_videocall_message *msg = NULL;
	int error_code = 0;
	char error_cause[512];
	json_t *root = NULL;
	while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
		msg = g_async_queue_pop(messages);
		if(msg == NULL)
			continue;
		if(msg == &exit_message)
			break;
		if(msg->handle == NULL) {
			janus_videocall_message_free(msg);
			continue;
		}
		janus_videocall_session *session = (janus_videocall_session *)msg->handle->plugin_handle;
		if(!session) {
			JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
			janus_videocall_message_free(msg);
			continue;
		}
		if(session->destroyed) {
			janus_videocall_message_free(msg);
			continue;
		}
		/* Handle request */
		error_code = 0;
		root = NULL;
		JANUS_LOG(LOG_VERB, "Handling message: %s\n", msg->message);
		if(msg->message == NULL) {
			JANUS_LOG(LOG_ERR, "No message??\n");
			error_code = JANUS_VIDEOCALL_ERROR_NO_MESSAGE;
			g_snprintf(error_cause, 512, "%s", "No message??");
			goto error;
		}
		json_error_t error;
		root = json_loads(msg->message, 0, &error);
		if(!root) {
			JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
			error_code = JANUS_VIDEOCALL_ERROR_INVALID_JSON;
			g_snprintf(error_cause, 512, "JSON error: on line %d: %s", error.line, error.text);
			goto error;
		}
		if(!json_is_object(root)) {
			JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
			error_code = JANUS_VIDEOCALL_ERROR_INVALID_JSON;
			g_snprintf(error_cause, 512, "JSON error: not an object");
			goto error;
		}
		JANUS_VALIDATE_JSON_OBJECT(root, request_parameters,
			error_code, error_cause, TRUE,
			JANUS_VIDEOCALL_ERROR_MISSING_ELEMENT, JANUS_VIDEOCALL_ERROR_INVALID_ELEMENT);
		if(error_code != 0)
			goto error;
		json_t *request = json_object_get(root, "request");
		const char *request_text = json_string_value(request);
		json_t *result = NULL;
		char *sdp_type = NULL, *sdp = NULL;
		if(!strcasecmp(request_text, "list")) {
			result = json_object();
			json_t *list = json_array();
			JANUS_LOG(LOG_VERB, "Request for the list of peers\n");
			/* Return a list of all available mountpoints */
			janus_mutex_lock(&sessions_mutex);
			GHashTableIter iter;
			gpointer value;
			g_hash_table_iter_init(&iter, sessions);
			while (g_hash_table_iter_next(&iter, NULL, &value)) {
				janus_videocall_session *user = value;
				if(user != NULL && user->username != NULL)
					json_array_append_new(list, json_string(user->username));
			}
			json_object_set_new(result, "list", list);
			janus_mutex_unlock(&sessions_mutex);
		} else if(!strcasecmp(request_text, "register")) {
			/* Map this handle to a username */
			if(session->username != NULL) {
				JANUS_LOG(LOG_ERR, "Already registered (%s)\n", session->username);
				error_code = JANUS_VIDEOCALL_ERROR_ALREADY_REGISTERED;
				g_snprintf(error_cause, 512, "Already registered (%s)", session->username);
				goto error;
			}
			JANUS_VALIDATE_JSON_OBJECT(root, username_parameters,
				error_code, error_cause, TRUE,
				JANUS_VIDEOCALL_ERROR_MISSING_ELEMENT, JANUS_VIDEOCALL_ERROR_INVALID_ELEMENT);
			if(error_code != 0)
				goto error;
			json_t *username = json_object_get(root, "username");
			const char *username_text = json_string_value(username);
			janus_mutex_lock(&sessions_mutex);
			if(g_hash_table_lookup(sessions, username_text) != NULL) {
				janus_mutex_unlock(&sessions_mutex);
				JANUS_LOG(LOG_ERR, "Username '%s' already taken\n", username_text);
				error_code = JANUS_VIDEOCALL_ERROR_USERNAME_TAKEN;
				g_snprintf(error_cause, 512, "Username '%s' already taken", username_text);
				goto error;
			}
			janus_mutex_unlock(&sessions_mutex);
			session->username = g_strdup(username_text);
			if(session->username == NULL) {
				JANUS_LOG(LOG_FATAL, "Memory error!\n");
				error_code = JANUS_VIDEOCALL_ERROR_UNKNOWN_ERROR;
				g_snprintf(error_cause, 512, "Memory error");
				goto error;
			}
			janus_mutex_lock(&sessions_mutex);
			g_hash_table_insert(sessions, (gpointer)session->username, session);
			janus_mutex_unlock(&sessions_mutex);
			result = json_object();
			json_object_set_new(result, "event", json_string("registered"));
			json_object_set_new(result, "username", json_string(username_text));
		} else if(!strcasecmp(request_text, "call")) {
			/* Call another peer */
			if(session->username == NULL) {
				JANUS_LOG(LOG_ERR, "Register a username first\n");
				error_code = JANUS_VIDEOCALL_ERROR_REGISTER_FIRST;
				g_snprintf(error_cause, 512, "Register a username first");
				goto error;
			}
			if(session->peer != NULL) {
				JANUS_LOG(LOG_ERR, "Already in a call\n");
				error_code = JANUS_VIDEOCALL_ERROR_ALREADY_IN_CALL;
				g_snprintf(error_cause, 512, "Already in a call");
				goto error;
			}
			JANUS_VALIDATE_JSON_OBJECT(root, username_parameters,
				error_code, error_cause, TRUE,
				JANUS_VIDEOCALL_ERROR_MISSING_ELEMENT, JANUS_VIDEOCALL_ERROR_INVALID_ELEMENT);
			if(error_code != 0)
				goto error;
			json_t *username = json_object_get(root, "username");
			const char *username_text = json_string_value(username);
			if(!strcmp(username_text, session->username)) {
				JANUS_LOG(LOG_ERR, "You can't call yourself... use the EchoTest for that\n");
				error_code = JANUS_VIDEOCALL_ERROR_USE_ECHO_TEST;
				g_snprintf(error_cause, 512, "You can't call yourself... use the EchoTest for that");
				goto error;
			}
			janus_mutex_lock(&sessions_mutex);
			janus_videocall_session *peer = g_hash_table_lookup(sessions, username_text);
			if(peer == NULL || peer->destroyed) {
				janus_mutex_unlock(&sessions_mutex);
				JANUS_LOG(LOG_ERR, "Username '%s' doesn't exist\n", username_text);
				error_code = JANUS_VIDEOCALL_ERROR_NO_SUCH_USERNAME;
				g_snprintf(error_cause, 512, "Username '%s' doesn't exist", username_text);
				goto error;
			}
			if(peer->peer != NULL) {
				janus_mutex_unlock(&sessions_mutex);
				JANUS_LOG(LOG_VERB, "%s is busy\n", username_text);
				result = json_object();
				json_object_set_new(result, "event", json_string("hangup"));
				json_object_set_new(result, "username", json_string(session->username));
				json_object_set_new(result, "reason", json_string("User busy"));
			} else {
				janus_mutex_unlock(&sessions_mutex);
				/* Any SDP to handle? if not, something's wrong */
				if(!msg->sdp) {
					JANUS_LOG(LOG_ERR, "Missing SDP\n");
					error_code = JANUS_VIDEOCALL_ERROR_MISSING_SDP;
					g_snprintf(error_cause, 512, "Missing SDP");
					goto error;
				}
				janus_mutex_lock(&sessions_mutex);
				session->peer = peer;
				peer->peer = session;
				session->has_audio = (strstr(msg->sdp, "m=audio") != NULL);
				session->has_video = (strstr(msg->sdp, "m=video") != NULL);
				janus_mutex_unlock(&sessions_mutex);
				JANUS_LOG(LOG_VERB, "%s is calling %s\n", session->username, session->peer->username);
				JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg->sdp_type, msg->sdp);
				/* Send SDP to our peer */
				json_t *call = json_object();
				json_object_set_new(call, "videocall", json_string("event"));
				json_t *calling = json_object();
				json_object_set_new(calling, "event", json_string("incomingcall"));
				json_object_set_new(calling, "username", json_string(session->username));
				json_object_set_new(call, "result", calling);
				char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
				json_decref(call);
				/* Make also sure we get rid of ULPfec, red, etc. */
				char *sdp = g_strdup(msg->sdp);
				if(strstr(sdp, "ulpfec")) {
					/* FIXME This really needs some better code */
					sdp = janus_string_replace(sdp, "a=rtpmap:116 red/90000\r\n", "");
					sdp = janus_string_replace(sdp, "a=rtpmap:117 ulpfec/90000\r\n", "");
					sdp = janus_string_replace(sdp, "a=rtpmap:96 rtx/90000\r\n", "");
					sdp = janus_string_replace(sdp, "a=fmtp:96 apt=100\r\n", "");
					sdp = janus_string_replace(sdp, "a=rtpmap:97 rtx/90000\r\n", "");
					sdp = janus_string_replace(sdp, "a=fmtp:97 apt=101\r\n", "");
					sdp = janus_string_replace(sdp, "a=rtpmap:98 rtx/90000\r\n", "");
					sdp = janus_string_replace(sdp, "a=fmtp:98 apt=116\r\n", "");
					sdp = janus_string_replace(sdp, " 116", "");
					sdp = janus_string_replace(sdp, " 117", "");
					sdp = janus_string_replace(sdp, " 96", "");
					sdp = janus_string_replace(sdp, " 97", "");
					sdp = janus_string_replace(sdp, " 98", "");
				}
				g_atomic_int_set(&session->hangingup, 0);
				JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
				int ret = gateway->push_event(peer->handle, &janus_videocall_plugin, NULL, call_text, msg->sdp_type, sdp);
				g_free(sdp);
				JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
				g_free(call_text);
				/* Send an ack back */
				result = json_object();
				json_object_set_new(result, "event", json_string("calling"));
			}
		} else if(!strcasecmp(request_text, "accept")) {
			/* Accept a call from another peer */
			if(session->peer == NULL) {
				JANUS_LOG(LOG_ERR, "No incoming call to accept\n");
				error_code = JANUS_VIDEOCALL_ERROR_NO_CALL;
				g_snprintf(error_cause, 512, "No incoming call to accept");
				goto error;
			}
			/* Any SDP to handle? if not, something's wrong */
			if(!msg->sdp) {
				JANUS_LOG(LOG_ERR, "Missing SDP\n");
				error_code = JANUS_VIDEOCALL_ERROR_MISSING_SDP;
				g_snprintf(error_cause, 512, "Missing SDP");
				goto error;
			}
			JANUS_LOG(LOG_VERB, "%s is accepting a call from %s\n", session->username, session->peer->username);
			JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg->sdp_type, msg->sdp);
			session->has_audio = (strstr(msg->sdp, "m=audio") != NULL);
			session->has_video = (strstr(msg->sdp, "m=video") != NULL);
			/* Send SDP to our peer */
			json_t *call = json_object();
			json_object_set_new(call, "videocall", json_string("event"));
			json_t *calling = json_object();
			json_object_set_new(calling, "event", json_string("accepted"));
			json_object_set_new(calling, "username", json_string(session->username));
			json_object_set_new(call, "result", calling);
			char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
			json_decref(call);
			g_atomic_int_set(&session->hangingup, 0);
			JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
			int ret = gateway->push_event(session->peer->handle, &janus_videocall_plugin, NULL, call_text, msg->sdp_type, msg->sdp);
			JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
			g_free(call_text);
			/* Send an ack back */
			result = json_object();
			json_object_set_new(result, "event", json_string("accepted"));
		} else if(!strcasecmp(request_text, "set")) {
			/* Update the local configuration (audio/video mute/unmute, bitrate cap or recording) */
			JANUS_VALIDATE_JSON_OBJECT(root, set_parameters,
				error_code, error_cause, TRUE,
				JANUS_VIDEOCALL_ERROR_MISSING_ELEMENT, JANUS_VIDEOCALL_ERROR_INVALID_ELEMENT);
			if(error_code != 0)
				goto error;
			json_t *audio = json_object_get(root, "audio");
			json_t *video = json_object_get(root, "video");
			json_t *bitrate = json_object_get(root, "bitrate");
			json_t *record = json_object_get(root, "record");
			json_t *recfile = json_object_get(root, "filename");
			if(audio) {
				session->audio_active = json_is_true(audio);
				JANUS_LOG(LOG_VERB, "Setting audio property: %s\n", session->audio_active ? "true" : "false");
			}
			if(video) {
				if(!session->video_active && json_is_true(video)) {
					/* Send a PLI */
					JANUS_LOG(LOG_VERB, "Just (re-)enabled video, sending a PLI to recover it\n");
					char buf[12];
					memset(buf, 0, 12);
					janus_rtcp_pli((char *)&buf, 12);
					gateway->relay_rtcp(session->handle, 1, buf, 12);
				}
				session->video_active = json_is_true(video);
				JANUS_LOG(LOG_VERB, "Setting video property: %s\n", session->video_active ? "true" : "false");
			}
			if(bitrate) {
				session->bitrate = json_integer_value(bitrate);
				JANUS_LOG(LOG_VERB, "Setting video bitrate: %"SCNu64"\n", session->bitrate);
				if(session->bitrate > 0) {
					/* FIXME Generate a new REMB (especially useful for Firefox, which doesn't send any we can cap later) */
					char buf[24];
					memset(buf, 0, 24);
					janus_rtcp_remb((char *)&buf, 24, session->bitrate);
					JANUS_LOG(LOG_VERB, "Sending REMB\n");
					gateway->relay_rtcp(session->handle, 1, buf, 24);
					/* FIXME How should we handle a subsequent "no limit" bitrate? */
				}
			}
			if(record) {
				if(msg->sdp) {
					session->has_audio = (strstr(msg->sdp, "m=audio") != NULL);
					session->has_video = (strstr(msg->sdp, "m=video") != NULL);
				}
				gboolean recording = json_is_true(record);
				const char *recording_base = json_string_value(recfile);
				JANUS_LOG(LOG_VERB, "Recording %s (base filename: %s)\n", recording ? "enabled" : "disabled", recording_base ? recording_base : "not provided");
				janus_mutex_lock(&session->rec_mutex);
				if(!recording) {
					/* Not recording (anymore?) */
					if(session->arc) {
						janus_recorder_close(session->arc);
						JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
						janus_recorder_free(session->arc);
					}
					session->arc = NULL;
					if(session->vrc) {
						janus_recorder_close(session->vrc);
						JANUS_LOG(LOG_INFO, "Closed video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
						janus_recorder_free(session->vrc);
					}
					session->vrc = NULL;
				} else {
					/* We've started recording, send a PLI and go on */
					char filename[255];
					gint64 now = janus_get_real_time();
					if(session->has_audio) {
						/* FIXME We assume we're recording Opus, here */
						memset(filename, 0, 255);
						if(recording_base) {
							/* Use the filename and path we have been provided */
							g_snprintf(filename, 255, "%s-audio", recording_base);
							session->arc = janus_recorder_create(NULL, "opus", filename);
							if(session->arc == NULL) {
								/* FIXME We should notify the fact the recorder could not be created */
								JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this VideoCall user!\n");
							}
						} else {
							/* Build a filename */
							g_snprintf(filename, 255, "videocall-%s-%s-%"SCNi64"-audio",
								session->username ? session->username : "******",
								(session->peer && session->peer->username) ? session->peer->username : "******",
								now);
							session->arc = janus_recorder_create(NULL, "opus", filename);
							if(session->arc == NULL) {
								/* FIXME We should notify the fact the recorder could not be created */
								JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this VideoCall user!\n");
							}
						}
					}
					if(session->has_video) {
						/* FIXME We assume we're recording VP8, here */
						memset(filename, 0, 255);
						if(recording_base) {
							/* Use the filename and path we have been provided */
							g_snprintf(filename, 255, "%s-video", recording_base);
							session->vrc = janus_recorder_create(NULL, "vp8", filename);
							if(session->vrc == NULL) {
								/* FIXME We should notify the fact the recorder could not be created */
								JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this VideoCall user!\n");
							}
						} else {
							/* Build a filename */
							g_snprintf(filename, 255, "videocall-%s-%s-%"SCNi64"-video",
								session->username ? session->username : "******",
								(session->peer && session->peer->username) ? session->peer->username : "******",
								now);
							session->vrc = janus_recorder_create(NULL, "vp8", filename);
							if(session->vrc == NULL) {
								/* FIXME We should notify the fact the recorder could not be created */
								JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this VideoCall user!\n");
							}
						}
						/* Send a PLI */
						JANUS_LOG(LOG_VERB, "Recording video, sending a PLI to kickstart it\n");
						char buf[12];
						memset(buf, 0, 12);
						janus_rtcp_pli((char *)&buf, 12);
						gateway->relay_rtcp(session->handle, 1, buf, 12);
					}
				}
				janus_mutex_unlock(&session->rec_mutex);
			}
			/* Send an ack back */
			result = json_object();
			json_object_set_new(result, "event", json_string("set"));
		} else if(!strcasecmp(request_text, "hangup")) {
			/* Hangup an ongoing call or reject an incoming one */
			janus_mutex_lock(&sessions_mutex);
			janus_videocall_session *peer = session->peer;
			if(peer == NULL) {
				JANUS_LOG(LOG_WARN, "No call to hangup\n");
			} else {
				JANUS_LOG(LOG_VERB, "%s is hanging up the call with %s\n", session->username, peer->username);
				session->peer = NULL;
				peer->peer = NULL;
			}
			janus_mutex_unlock(&sessions_mutex);
			/* Notify the success as an hangup message */
			result = json_object();
			json_object_set_new(result, "event", json_string("hangup"));
			json_object_set_new(result, "username", json_string(session->username));
			json_object_set_new(result, "reason", json_string("We did the hangup"));
			if(peer != NULL) {
				/* Send event to our peer too */
				json_t *call = json_object();
				json_object_set_new(call, "videocall", json_string("event"));
				json_t *calling = json_object();
				json_object_set_new(calling, "event", json_string("hangup"));
				json_object_set_new(calling, "username", json_string(session->username));
				json_object_set_new(calling, "reason", json_string("Remote hangup"));
				json_object_set_new(call, "result", calling);
				char *call_text = json_dumps(call, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
				json_decref(call);
				JANUS_LOG(LOG_VERB, "Pushing event to peer: %s\n", call_text);
				int ret = gateway->push_event(peer->handle, &janus_videocall_plugin, NULL, call_text, NULL, NULL);
				JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
				g_free(call_text);
			}
		} else {
			JANUS_LOG(LOG_ERR, "Unknown request (%s)\n", request_text);
			error_code = JANUS_VIDEOCALL_ERROR_INVALID_REQUEST;
			g_snprintf(error_cause, 512, "Unknown request (%s)", request_text);
			goto error;
		}

		json_decref(root);
		/* Prepare JSON event */
		json_t *event = json_object();
		json_object_set_new(event, "videocall", json_string("event"));
		if(result != NULL)
			json_object_set_new(event, "result", result);
		char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
		json_decref(event);
		JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
		int ret = gateway->push_event(msg->handle, &janus_videocall_plugin, msg->transaction, event_text, sdp_type, sdp);
		JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
		g_free(event_text);
		if(sdp)
			g_free(sdp);
		janus_videocall_message_free(msg);
		continue;
		
error:
		{
			if(root != NULL)
				json_decref(root);
			/* Prepare JSON error event */
			json_t *event = json_object();
			json_object_set_new(event, "videocall", json_string("event"));
			json_object_set_new(event, "error_code", json_integer(error_code));
			json_object_set_new(event, "error", json_string(error_cause));
			char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
			json_decref(event);
			JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
			int ret = gateway->push_event(msg->handle, &janus_videocall_plugin, msg->transaction, event_text, NULL, NULL);
			JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
			g_free(event_text);
			janus_videocall_message_free(msg);
		}
	}
	JANUS_LOG(LOG_VERB, "Leaving VideoCall handler thread\n");
	return NULL;
}
Beispiel #29
0
int
auth_user(char *authbuf, const char *peername, int *is_reg, int *reconnect_id)
{
    json_error_t err;
    json_t *obj, *cmd, *name, *pass, *email, *reconn;
    const char *namestr, *passstr, *emailstr;
    int userid = 0;

    obj = json_loads(authbuf, 0, &err);
    if (!obj)
        return 0;

    /* try 1: is it an auth command? */
    *is_reg = 0;
    cmd = json_object_get(obj, "auth");
    if (!cmd) {
        /* try 2: register? */
        *is_reg = 1;
        cmd = json_object_get(obj, "register");
    }
    if (!cmd)   /* not a recognized command */
        goto err;

    name = json_object_get(cmd, "username");
    pass = json_object_get(cmd, "password");
    email = json_object_get(cmd, "email");      /* is null for auth */
    reconn = json_object_get(cmd, "reconnect");

    if (!name || !pass)
        goto err;

    namestr = json_string_value(name);
    passstr = json_string_value(pass);

    if (!namestr || !passstr || strlen(namestr) < 3 || strlen(passstr) < 3 ||
        !is_valid_username(namestr))
        goto err;

    *reconnect_id = 0;
    if (!*is_reg) {
        if (reconn && json_is_integer(reconn))
            *reconnect_id = json_integer_value(reconn);

        /* authenticate against a user database */
        userid = db_auth_user(namestr, passstr);
        if (userid > 0)
            log_msg("%s has logged in as \"%s\" (userid %d)", peername, namestr,
                    userid);
        else if (userid < 0)
            log_msg("%s has failed to log in as \"%s\" (userid %d)", peername,
                    namestr, -userid);
    } else {
        /* register a new user */
        emailstr = email ? json_string_value(email) : "";
        if (strlen(emailstr) > 100)
            goto err;

        userid = db_register_user(namestr, passstr, emailstr);
        if (userid) {
            char savedir[1024];

            snprintf(savedir, 1024, "%s/save/%s", settings.workdir, namestr);
            mkdir(savedir, 0700);
            log_msg("%s has registered as \"%s\" (userid: %d)", peername,
                    namestr, userid);
        }
    }

    json_decref(obj);
    return userid;

err:
    json_decref(obj);
    return 0;
}
Beispiel #30
0
        } else if (val->type == JSON_INTEGER) {
            printf("%s = %lli\n", json_string_value(name), json_integer_value(val));
        } else if (val->type == JSON_REAL) {
            printf("%s = %f\n", json_string_value(name), json_real_value(val));
        } else if (val->type == JSON_NULL) {
            printf("%s = NULL\n", json_string_value(name));
        } else if (val->type == JSON_TRUE) {
            printf("%s = true\n", json_string_value(name));
        } else if (val->type == JSON_FALSE) {
            printf("%s = false\n", json_string_value(name));
        } else {
            printf("%s = (Unknown Type)\n", json_string_value(name));
        }
    }

    dslink_requester_close(link, (uint32_t) json_integer_value(json_object_get(resp, "rid")));
}

void on_value_update(struct DSLink *link, uint32_t sid, json_t *val, json_t *ts) {
    (void) link;
    (void) ts;
    (void) sid;
    printf("Got value %f\n", json_real_value(val));
    dslink_requester_unsubscribe(link, sid);
}

void init(DSLink *link) {
    (void) link;
    log_info("Initialized!\n");
}