/// <summary>
    /// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests.
    /// (Also, we don't want lots of excess unused titles)
    /// </summary>
    bool SetTitleInfo(Document &testInputs)
    {
        CCLOG("%s", "SetTitleInfo");

        // Parse all the inputs
        auto end = testInputs.MemberEnd();
        auto each = testInputs.FindMember("titleId");
        if (each != end) PlayFabSettings::titleId = each->value.GetString(); else return false;
        each = testInputs.FindMember("developerSecretKey");
        if (each != end) PlayFabSettings::developerSecretKey = each->value.GetString(); else return false;

        string blah;
        each = testInputs.FindMember("titleCanUpdateSettings");
        if (each != end) blah = each->value.GetString(); else return false;
        TITLE_CAN_UPDATE_SETTINGS = (blah.compare("true") == 0 || blah.compare("True") == 0 || blah.compare("TRUE") == 0);

        each = testInputs.FindMember("userName");
        if (each != end) USER_NAME = each->value.GetString(); else return false;
        each = testInputs.FindMember("userEmail");
        if (each != end) USER_EMAIL = each->value.GetString(); else return false;
        each = testInputs.FindMember("userPassword");
        if (each != end) USER_PASSWORD = each->value.GetString(); else return false;

        each = testInputs.FindMember("characterName");
        if (each != end) CHAR_NAME = each->value.GetString(); else return false;

        // Verify all the inputs won't cause crashes in the tests
        return !PlayFabSettings::titleId.empty()
            && !PlayFabSettings::developerSecretKey.empty()
            && !USER_NAME.empty()
            && !USER_EMAIL.empty()
            && !USER_PASSWORD.empty()
            && !CHAR_NAME.empty();
    }
// Issue 226: Value of string type should not point to NULL
TEST(Document, AssertAcceptInvalidNameType) {
    Document doc;
    doc.SetObject();
    doc.AddMember("a", 0, doc.GetAllocator());
    doc.FindMember("a")->name.SetNull(); // Change name to non-string type.

    OutputStringStream os;
    Writer<OutputStringStream> writer(os);
    ASSERT_THROW(doc.Accept(writer), AssertException);
}
Exemple #3
0
void GameShow::processWebMessages()
{
  Document* document = pGameController->socketServer()->getNextIncomingMessage();
  if(0 != document){
    // cout << "Got document " << document;

    string message = document->FindMember("message")->value.GetString();
    // cout << "Got message " << document;

    if(message.compare("get_buttons") == 0){
      pGameController->sendWebMessage(pGameController->buttonController()->getInfoString());

    }else if(message.compare("get_lamps") == 0){
      pGameController->sendWebMessage(pGameController->lampController()->getInfoString());

    }else if(message.compare("get_coils") == 0){
      pGameController->sendWebMessage(pGameController->coilController()->getInfoString());

    }else if(message.compare("set_lamp_state") == 0){
      string name = document->FindMember("name")->value.GetString();
      LampState state = (LampState)document->FindMember("value")->value.GetInt();
      pGameController->lampController()->setLampState(name, state);

    }else if(message.compare("set_coil_state") == 0){
      string name = document->FindMember("name")->value.GetString();
      int state = document->FindMember("value")->value.GetInt();
      pGameController->coilController()->setCoilState(name, state);

    }else if(message.compare("set_button_state") == 0){
      string name = document->FindMember("name")->value.GetString();
      int state = document->FindMember("value")->value.GetInt();
      pGameController->buttonController()->overrideButtonState(name, state);

    }else if(message.compare("get_game_states") == 0){ //note the plural S

      pGameState->sendAllStatesToWeb();
    }else if(message.compare("get_game_state") == 0){
      pGameState->sendToWeb();

    }else if(message.compare("set_game_state") == 0){
      string state = document->FindMember("value")->value.GetString();
      setGameState(state);
    }

    //I don't like this here.
    delete(document);
  }
}
	Config::ElementGroupType
	getAllElementGroups(const Document& doc, const std::vector<SvgElement>& all_elements_)
	{
		const auto element_groups_it = doc.FindMember("element_groups");
		assert(element_groups_it != doc.MemberEnd());
		assert(element_groups_it->value.IsArray());
		const auto raw_array_of_groups = element_groups_it->value.GetArray();

		Config::ElementGroupType all_element_groups;
		all_element_groups.set_empty_key(std::string{""});
		for (const auto& raw_single_group: raw_array_of_groups)
		{
			assert(raw_single_group.IsObject());
			const auto& single_group = raw_single_group.GetObject();
			//group name
			const auto group_name_it = single_group.FindMember("name");
			assert(group_name_it != single_group.MemberEnd());
			assert(group_name_it->value.IsString());
			const auto group_name = std::string {group_name_it->value.GetString(), group_name_it->value.GetStringLength()};

			//all the elements that are part of the group
			std::vector<std::string> single_group_members;
			const auto raw_single_group_members = single_group.FindMember("elements");
			assert(raw_single_group_members != single_group.MemberEnd());
			assert(raw_single_group_members->value.IsArray());
			const auto raw_array_of_group_members = raw_single_group_members->value.GetArray();

			for (const auto& raw_single_group_element : raw_array_of_group_members)
			{
				assert(raw_single_group_element.IsString());
				single_group_members.emplace_back(std::string{raw_single_group_element.GetString(),
				                                              raw_single_group_element.GetStringLength()});
			}
			all_element_groups[group_name] = std::move(single_group_members);
		}


		for (auto& array_name_pair : all_element_groups)
		{
			auto& element_vector = array_name_pair.second;
			std::sort(std::begin(element_vector), std::end(element_vector));
		}
		// TODO: this line is for debug purposes, should be removed
		std::cout << all_elements_;
		return all_element_groups;
	}
	Config::ElementContainerType getAllElements(const Document& doc)
	{
		// load elements
		const auto elements_it = doc.FindMember("elements");
		assert(elements_it != doc.MemberEnd());
		assert(elements_it->value.IsArray());

		std::vector<SvgElement> all_elements;
		const auto raw_elements = elements_it->value.GetArray();;
		for (SizeType i = 0; i < raw_elements.Size(); ++i)
		{
			const Value& singleElement = raw_elements[i];
			assert(singleElement.IsString());
			all_elements.emplace_back(SvgElement{singleElement.GetString()});
		}
		std::sort(std::begin(all_elements), std::end(all_elements));
		return all_elements;
	}
    /// <summary>
    /// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests.
    /// (Also, we don't want lots of excess unused titles)
    /// </summary>
    static void SetTitleInfo(Document &testInputs)
    {
        // Parse all the inputs
        auto end = testInputs.MemberEnd();
        auto each = testInputs.FindMember("titleId");
        if (each != end) playFabSettings->titleId = each->value.GetString();

        string blah;
        each = testInputs.FindMember("titleCanUpdateSettings");
        if (each != end) blah = each->value.GetString();
        TITLE_CAN_UPDATE_SETTINGS = (blah.compare("true") == 0 || blah.compare("True") == 0 || blah.compare("TRUE") == 0);

        each = testInputs.FindMember("userName");
        if (each != end) userName = each->value.GetString();
        each = testInputs.FindMember("userEmail");
        if (each != end) userEmail = each->value.GetString();
        each = testInputs.FindMember("userPassword");
        if (each != end) userPassword = each->value.GetString();

        each = testInputs.FindMember("characterName");
        if (each != end) characterName = each->value.GetString();
    }
int main(int, char*[]) {
	////////////////////////////////////////////////////////////////////////////
	// 1. Parse a JSON text string to a document.

	const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
	printf("Original JSON:\n %s\n", json);

	Document document;  // Default template parameter uses UTF8 and MemoryPoolAllocator.

#if 0
	// "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream().
	if (document.Parse(json).HasParseError())
		return 1;
#else
	// In-situ parsing, decode strings directly in the source string. Source must be string.
	char buffer[sizeof(json)];
	memcpy(buffer, json, sizeof(json));
	if (document.ParseInsitu(buffer).HasParseError())
		return 1;
#endif

	printf("\nParsing to document succeeded.\n");

	////////////////////////////////////////////////////////////////////////////
	// 2. Access values in document. 

	printf("\nAccess values in document:\n");
	assert(document.IsObject());    // Document is a JSON value represents the root of DOM. Root can be either an object or array.

	assert(document.HasMember("hello"));
	assert(document["hello"].IsString());
	printf("hello = %s\n", document["hello"].GetString());

	// Since version 0.2, you can use single lookup to check the existing of member and its value:
	Value::MemberIterator hello = document.FindMember("hello");
	assert(hello != document.MemberEnd());
	assert(hello->value.IsString());
	assert(strcmp("world", hello->value.GetString()) == 0);
	(void)hello;

	assert(document["t"].IsBool());     // JSON true/false are bool. Can also uses more specific function IsTrue().
	printf("t = %s\n", document["t"].GetBool() ? "true" : "false");

	assert(document["f"].IsBool());
	printf("f = %s\n", document["f"].GetBool() ? "true" : "false");

	printf("n = %s\n", document["n"].IsNull() ? "null" : "?");

	assert(document["i"].IsNumber());   // Number is a JSON type, but C++ needs more specific type.
	assert(document["i"].IsInt());      // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
	printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]

	assert(document["pi"].IsNumber());
	assert(document["pi"].IsDouble());
	printf("pi = %g\n", document["pi"].GetDouble());

	{
		const Value& a = document["a"]; // Using a reference for consecutive access is handy and faster.
		assert(a.IsArray());
		for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
			printf("a[%d] = %d\n", i, a[i].GetInt());

		int y = a[0].GetInt();
		(void)y;

		// Iterating array with iterators
		printf("a = ");
		for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
			printf("%d ", itr->GetInt());
		printf("\n");
	}

	// Iterating object members
	static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
	for (Value::ConstMemberIterator itr = document.MemberBegin(); itr != document.MemberEnd(); ++itr)
		printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);

	////////////////////////////////////////////////////////////////////////////
	// 3. Modify values in document.

	// Change i to a bigger number
	{
		uint64_t f20 = 1;   // compute factorial of 20
		for (uint64_t j = 1; j <= 20; j++)
			f20 *= j;
		document["i"] = f20;    // Alternate form: document["i"].SetUint64(f20)
		assert(!document["i"].IsInt()); // No longer can be cast as int or uint.
	}

	// Adding values to array.
	{
		Value& a = document["a"];   // This time we uses non-const reference.
		Document::AllocatorType& allocator = document.GetAllocator();
		for (int i = 5; i <= 10; i++)
			a.PushBack(i, allocator);   // May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's.

		// Fluent API
		a.PushBack("Lua", allocator).PushBack("Mio", allocator);
	}

	// Making string values.

	// This version of SetString() just store the pointer to the string.
	// So it is for literal and string that exists within value's life-cycle.
	{
		document["hello"] = "rapidjson";    // This will invoke strlen()
		// Faster version:
		// document["hello"].SetString("rapidjson", 9);
	}

	// This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
	Value author;
	{
		char buffer[10];
		int len = sprintf(buffer, "%s %s", "Milo", "Yip");  // synthetic example of dynamically created string.

		author.SetString(buffer, static_cast<size_t>(len), document.GetAllocator());
		// Shorter but slower version:
		// document["hello"].SetString(buffer, document.GetAllocator());

		// Constructor version: 
		// Value author(buffer, len, document.GetAllocator());
		// Value author(buffer, document.GetAllocator());
		memset(buffer, 0, sizeof(buffer)); // For demonstration purpose.
	}
	// Variable 'buffer' is unusable now but 'author' has already made a copy.
	document.AddMember("author", author, document.GetAllocator());

	assert(author.IsNull());        // Move semantic for assignment. After this variable is assigned as a member, the variable becomes null.

	////////////////////////////////////////////////////////////////////////////
	// 4. Stringify JSON

	printf("\nModified JSON with reformatting:\n");
	StringBuffer sb;
	PrettyWriter<StringBuffer> writer(sb);
	document.Accept(writer);    // Accept() traverses the DOM and generates Handler events.
	puts(sb.GetString());

	return 0;
}
void ResultSet::aggregate(const std::string& prefix,
                          const std::string& filename) {
  // Parse prefix
  char* prefix_data = strdup(prefix.data());
  char* reason          = strtok(prefix_data, "/");
  char* appName         = strtok(NULL, "/");
  char* channel         = strtok(NULL, "/");
  char* version         = strtok(NULL, "/");
  char* strBuildId      = strtok(NULL, ".");
  char* submissionDate  = strtok(NULL, ".");
  if (!reason || !appName || !channel || !version || !strBuildId ||
      !submissionDate) {
    fprintf(stderr, "Prefix '%s' missing parts \n", prefix.data());
    free(prefix_data);
    return;
  }
  // Intern strBuildId
  InternedString buildId = Aggregate::internBuildIdString(strBuildId);

  // Get build date, ignore the rest
  if (strlen(strBuildId) < 8) {
    fprintf(stderr, "BuildId '%s' is not valid, too short\n", strBuildId);
    free(prefix_data);
    return;
  }
  string buildDate(strBuildId, 8);

  // Decide if we should skip submission date
  bool skipBySubmissionDate = false;
  {
    // Parse submission date and buildDate
    time_t submissionTime = parseDate(submissionDate);
    time_t buildTime      = parseDate(buildDate.data());

    // Skip aggregation by submission date of it's been more than 60 days since
    // build date
    if (difftime(submissionTime, buildTime) > 60 * 60 * 24 * 60) {
      skipBySubmissionDate = true;
    }
  }

  // Reduce version to major version (discard everything after the dot)
  {
    char* c = version;
    while(*c != '.' && *c != '\0') c++;
    *c = '\0';
  }

  // Find/create ChannelVersion object
  ChannelVersion* cv = nullptr;
  {
    string channelVersion = string(channel) + "/" + string(version);
    // Find channel version in hash table
    auto it = _channelVersionMap.find(channelVersion);
    // If not present create ChannelVersion
    if (it == _channelVersionMap.end()) {
      cv = new ChannelVersion(_measureStringCtx, _filterStringCtx);
      it = _channelVersionMap.insert({channelVersion, cv}).first;
    }
    cv = it->second;
  }
  assert(cv);

  // Create filterPath start
  string reasonAppName = string(reason) + "/" + string(appName) + "/";

  // Allocate a string to hold <measure>/<by-date-type>
  string measureFilename;
  measureFilename.reserve(2048);

  FILE* input = fopen(filename.data(), "r");
  {
    // Read file line by line
    CompressedFileReader reader(input);
    char* line = nullptr;
    int nb_line = 0;
    while ((line = reader.nextLine()) != nullptr) {
      nb_line++;
      // Find tab
      char* tab = strchr(line, '\t');
      if (!tab) {
        fprintf(stderr, "No tab on line %i\n", nb_line);
        continue;
      }

      // Set tab = \0 creating two C-strings
      *tab = '\0';
      char* uuid = line;
      char* json = tab + 1;

      UNUSED(uuid);

      // Parse the JSON line
      Document d;
      d.Parse<0>(json);

      // Check that we have an object
      if (!d.IsObject()) {
        fprintf(stderr, "JSON root is not an object on line %i\n", nb_line);
        continue;
      }

      // Find the info field
      Value::Member* infoField = d.FindMember("info");
      if (!infoField || !infoField->value.IsObject()) {
        fprintf(stderr, "'info' in payload isn't an object, line %i\n", nb_line);
        continue;
      }
      Value& info = infoField->value;

      // Find OS, osVersion, arch and revision
      Value::Member* osField    = info.FindMember("OS");
      Value::Member* osVerField = info.FindMember("version");
      Value::Member* archField  = info.FindMember("arch");
      Value::Member* revField   = info.FindMember("revision");
      if (!osField || !osField->value.IsString()) {
        fprintf(stderr, "'OS' in 'info' isn't a string\n");
        continue;
      }
      if (!osVerField || !(osVerField->value.IsString() ||
                           osVerField->value.IsNumber())) {
        fprintf(stderr, "'version' in 'info' isn't a string or number\n");
        continue;
      }
      if (!archField || !archField->value.IsString()) {
        fprintf(stderr, "'arch' in 'info' isn't a string\n");
        continue;
      }
      InternedString revision;
      if (revField) {
        if (!revField->value.IsString()) {
          fprintf(stderr, "'revision' in 'info' isn't a string\n");
          continue;
        }
        // Get InternedString for revision
        revision = Aggregate::internRevisionString(revField->value.GetString());
      } else {
        // Get InternedString for revision
        revision = Aggregate::internRevisionString(FALLBACK_REVISION);
      }

      // Create filterPath as <reason>/<appName>/<OS>/<osVersion>/<arch>
      const char* OS = osField->value.GetString();
      string filterPath = reasonAppName + OS;
      filterPath += "/";
      string osVersion;
      if (osVerField->value.IsString()) {
        osVersion = osVerField->value.GetString();
      } else {
        char b[64];
        modp_dtoa2(osVerField->value.GetDouble(), b, 9);
        osVersion = b;
      }
      // For Linux we only add 3 first characters
      if (strcmp(OS, "Linux") == 0) {
        filterPath += osVersion.substr(0, 3);
      } else {
        filterPath += osVersion;
      }
      filterPath += "/";

      // Append arch to filterPath
      filterPath += archField->value.GetString();

      // Aggregate histograms

      Value::Member* hgramField = d.FindMember("histograms");
      if (hgramField && hgramField->value.IsObject()) {
        Value& hgrams = hgramField->value;
        for (auto hgram = hgrams.MemberBegin(); hgram != hgrams.MemberEnd();
                                                                      ++hgram) {
          // Get histogram name and values
          const char* name  = hgram->name.GetString();
          Value& values     = hgram->value;

          // MeasureFilename
          measureFilename = name;
          measureFilename += "/by-build-date";

          // Get measure file
          MeasureFile* mf = cv->measure(measureFilename.data());
          Aggregate*   aggregate = mf->aggregate(buildDate.data(), filterPath.data());

          // Add to aggregate
          aggregate->aggregate(revision, buildId, values);

          // Skip aggregation by submission date, unless requested
          if (skipBySubmissionDate) {
            continue;
          }
          // MeasureFilename
          measureFilename = name;
          measureFilename += "/by-submission-date";

          // Get measure file
          mf = cv->measure(measureFilename.data());
          aggregate = mf->aggregate(submissionDate, filterPath.data());

          // Add to aggregate
          aggregate->aggregate(revision, buildId, values);
        }
      } else {
        fprintf(stderr, "'histograms' of payload isn't an object\n");
      }

      // Aggregate simple measures
      Value::Member* smField = d.FindMember("simpleMeasurements");
      if (smField && smField->value.IsObject()) {
        Value& sms = smField->value;
        for (auto sm = sms.MemberBegin(); sm != sms.MemberEnd(); ++sm) {
          // Get simple measure name and values
          string name   = sm->name.GetString();
          Value& value  = sm->value;

          // Convert name to uppercase
          for(size_t i = 0; i < name.length(); i++) {
            name[i] = toupper(name[i]);
          }

          // Aggregate numbers
          if (value.IsNumber()) {
            // Create measure filename
            measureFilename = "SIMPLE_MEASURES_";
            measureFilename += name;
            measureFilename += "/by-build-date";

            // Get measure file
            MeasureFile* mf = cv->measure(measureFilename.data());
            Aggregate*   aggregate = mf->aggregate(buildDate.data(),
                                                   filterPath.data());

            // Aggregate simple measure
            aggregate->aggregate(value.GetDouble());

            // Aggregate by submission date if desired
            if (!skipBySubmissionDate) {
              // Create measure filename
              measureFilename = "SIMPLE_MEASURES_";
              measureFilename += name;
              measureFilename += "/by-submission-date";

              mf = cv->measure(measureFilename.data());
              aggregate = mf->aggregate(submissionDate, filterPath.data());

              // Aggregate simple measure
              aggregate->aggregate(value.GetDouble());
            }
          } else if (value.IsObject()) {
            // If we have an object read key/values of it
            for (auto ssm = value.MemberBegin(); ssm != value.MemberEnd();
                                                                        ++ssm) {
              string subname   = ssm->name.GetString();
              Value& subvalue  = ssm->value;

              // Convert subname to uppercase
              for(size_t i = 0; i < subname.length(); i++) {
                subname[i] = toupper(subname[i]);
              }

              // Aggregate subvalue, if number, ignore errors there are lots of
              // weird simple measures
              if (subvalue.IsNumber()) {
                // Create measure filename
                measureFilename = "SIMPLE_MEASURES_";
                measureFilename += name;
                measureFilename += "_";
                measureFilename += subname;
                measureFilename += "/by-build-date";

                // Get measure file
                MeasureFile* mf = cv->measure(measureFilename.data());
                Aggregate*   aggregate = mf->aggregate(buildDate.data(),
                                                       filterPath.data());

                // Aggregate simple measure
                aggregate->aggregate(subvalue.GetDouble());

                // Aggregate by submission date if desired
                if (!skipBySubmissionDate) {
                  // Create measure filename
                  measureFilename = "SIMPLE_MEASURES_";
                  measureFilename += name;
                  measureFilename += "_";
                  measureFilename += subname;
                  measureFilename += "/by-submission-date";

                  mf = cv->measure(measureFilename.data());
                  aggregate = mf->aggregate(submissionDate, filterPath.data());

                  // Aggregate simple measure
                  aggregate->aggregate(subvalue.GetDouble());
                }
              }
            }
          }
        }
      }
    }
  }
  fclose(input);

  free(prefix_data);
}
bool PlayFabRequestHandler::DecodeRequest(int httpStatus, HttpRequest* request, void* userData, PlayFabBaseModel& outResult, PlayFabError& outError)
{
	std::string response = request->GetReponse();
	Document rawResult;
	rawResult.Parse<0>(response.c_str());

	// Check for bad responses
	if (response.length() == 0 // Null response
		|| rawResult.GetParseError() != NULL) // Non-Json response
	{
		// If we get here, we failed to connect meaningfully to the server - Assume a timeout
		outError.HttpCode = 408;
		outError.ErrorCode = PlayFabErrorConnectionTimeout;
		// For text returns, use the non-json response if possible, else default to no response
		outError.ErrorName = outError.ErrorMessage = outError.HttpStatus = response.length() == 0 ? "Request Timeout or null response" : response;
		return false;
	}

	// Check if the returned json indicates an error
	const Value::Member* errorCodeJson = rawResult.FindMember("errorCode");
	if (errorCodeJson != NULL)
	{
		// There was an error, BUMMER
		if (!errorCodeJson->value.IsNumber())
		{
			// unexpected json formatting - If we get here, we failed to connect meaningfully to the server - Assume a timeout
			outError.HttpCode = 408;
			outError.ErrorCode = PlayFabErrorConnectionTimeout;
			// For text returns, use the non-json response if possible, else default to no response
			outError.ErrorName = outError.ErrorMessage = outError.HttpStatus = response.length() == 0 ? "Request Timeout or null response" : response;
			return false;
		}
		// TODO: what happens when the error is not in the enum?
		outError.ErrorCode = static_cast<PlayFabErrorCode>(errorCodeJson->value.GetInt());

		const Value::Member* codeJson = rawResult.FindMember("code");
		if (codeJson != NULL && codeJson->value.IsNumber())
			outError.HttpCode = codeJson->value.GetInt();

		const Value::Member* statusJson = rawResult.FindMember("status");
		if (statusJson != NULL && statusJson->value.IsString())
			outError.HttpStatus = statusJson->value.GetString();

		const Value::Member* errorNameJson = rawResult.FindMember("error");
		if (errorNameJson != NULL && errorNameJson->value.IsString())
			outError.ErrorName = errorNameJson->value.GetString();

		const Value::Member* errorMessageJson = rawResult.FindMember("errorMessage");
		if (errorMessageJson != NULL && errorMessageJson->value.IsString())
			outError.ErrorMessage = errorMessageJson->value.GetString();

		const Value::Member* errorDetailsJson = rawResult.FindMember("errorDetails");
		if (errorDetailsJson != NULL && errorDetailsJson->value.IsObject())
		{
			const Value& errorDetailsObj = errorDetailsJson->value;

			for (Value::ConstMemberIterator itr = errorDetailsObj.MemberBegin(); itr != errorDetailsObj.MemberEnd(); ++itr)
			{
				if (itr->name.IsString() && itr->value.IsArray())
				{
					const Value& errorList = itr->value;
					for (Value::ConstValueIterator erroListIter = errorList.Begin(); erroListIter != errorList.End(); ++erroListIter)
						outError.ErrorDetails.insert(std::pair<std::string, std::string>(itr->name.GetString(), erroListIter->GetString()));
				}
			}
		}
		// We encountered no errors parsing the error
		return false;
	}

	const Value::Member* data = rawResult.FindMember("data");
	if (data == NULL || !data->value.IsObject())
		return false;

	return outResult.readFromValue(data->value);
}
Exemple #10
0
int NodeBtHandler (int argc, char *argv[])
{
  // DDS değişkenleri
  DDSEntityManager                    mgrBtPub;
  DDSEntityManager                    mgrReqSub;
  ReturnCode_t                        status;
  SampleInfoSeq_var                   infoSeq = new SampleInfoSeq();
  BtSeq*                              btSeqInstance = new BtSeq();
  ServerReqSeq                        serverReqSeq;

  // Zaman ile alakalı değişkenler
  long int                            messageIDCount = 0;
  Time_t                              tsBeforeTheScan = { 0, 0 };
  Time_t                              tsAfterTheScan = { 0, 0 };
  //Time_t                              tsWifiPub = { 0, 0 };
  struct timeval                      tsConverter;
  DDS::Duration_t                     waitAckTime = { 0, 800000000 }; //800ms
  int                                 refreshRate = 60;

  // Veri tutucular (data structures)
  vector<string>                      btMacHolder;
  vector<int>                         btRssiHolder;
  string                              btFileContenHolder;

  // Bluetooth tarama sonuçlarının yazdırıldığı dosyadan okuma yapacak
  // olan değişken
  boost::filesystem::ifstream         fIn;

  // Bluetooth tarama sıklığı ayarlayan değişken
  int                                 refreshRateCounter = -1;

  char                                hostName[1024];
  gethostname(hostName, 1024);


  // !!! Bluetooth tarama mesajlarını Publish edecek Topic yaratılıyor
  // ve o Topic'e ait konfigürasyon ayarları yapılıyor.

  // Domain participant yaratılıyor
  mgrBtPub.createParticipant ("KonSens_BtSeq_Participant");

  // BtSeq tipi yaratılıyor
  BtSeqTypeSupport_var btSeqTs = new BtSeqTypeSupport();
  mgrBtPub.registerType(btSeqTs.in());

  // Topic yaratılıyor
  char btPubTopicName[] = "KonSensData_BtSeq_Topic";
  mgrBtPub.createTopic(btPubTopicName);

  // Publisher yaratılıyor
  mgrBtPub.createPublisher();

  // DataWriter yaratılıyor
  bool autodispose_unregistered_instances = false;
  mgrBtPub.createWriter(autodispose_unregistered_instances,
                        KEEP_ALL_HISTORY_QOS,
                        BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS);

  // Yaratılan DataWriter, BtSeq tipi için özelleştiriliyor
  DataWriter_var dWriter = mgrBtPub.getWriter ();
  BtSeqDataWriter_var btSeqWriter = BtSeqDataWriter::_narrow(dWriter.in());

  // Düğüm numarasını atanıyor
  btSeqInstance->userID = 13;

  // Publish edilecek olan mesajlara zaman etiketi takabilmek için
  // btSeqInstance değişkeni register ediliyor
  //userHandle = btSeqWriter->register_instance_w_timestamp(*btSeqInstance,
  //                                                        tsWifiPub);

  cout << "=== [Publisher of KonSensData_BtSeq_Topic] Ready ..." << endl;


  // !!! Sunucudan gelen komutlara Subscribe olacak olan Topic yaratılıyor
  // ve o Topic için gerekli konfigürasyon ayarları yapılıyor

  // Domain participant yaratılıyor
  mgrReqSub.createParticipant(
        "KonSensData_ServerReq_Participant_Server_to_Node");

  // ServerReq tipi yaratılıyor.
  ServerReqTypeSupport_var mgrSubscriberTS = new ServerReqTypeSupport();
  mgrReqSub.registerType(mgrSubscriberTS.in());

  // Topic yaratılıyor
  char reqSubTopicName[] = "KonSensData_ServerReq_Topic_Server_to_Node";
  mgrReqSub.createTopic(reqSubTopicName, RELIABLE_RELIABILITY_QOS,
                        VOLATILE_DURABILITY_QOS);

  // Subscriber yaratılıyor
  mgrReqSub.createSubscriber();

  // DataReader yaratılıyor
  mgrReqSub.createReader(KEEP_LAST_HISTORY_QOS, 1);

  // Yaratılan DataReader, ServerReq tipi için özelleştiriliyor.
  DataReader_var dReaderSub = mgrReqSub.getReader();
  ServerReqDataReader_var serverReqReader =
      ServerReqDataReader::_narrow(dReaderSub.in());
  checkHandle(serverReqReader.in(), "ServerReqDataReader::_narrow");

  cout << "=== [Subscriber KonSensData_ServerReq_Topic_Server_to_Node]"
          " Ready ..." << endl;


  // Bluetooth aktif hale getiriliyor.
  system("sudo hciconfig -a hci0 up");
  stringstream ssBtName;
  ssBtName << "sudo bt-adapter -a hci0 --set Name \"" << hostName << "\"";
  system(ssBtName.str().c_str());
  system("sudo bt-adapter -a hci0 --set Discoverable 1");

  // Yenileme sıklığını belirleyecek olan 'timelimit' değişkeni yaratılıyor.
  Timeout timelimit(std::chrono::milliseconds(refreshRate*1000));


  while (true)
  {
    if (timelimit.isExpired() || refreshRateCounter == -1)
    {

      // BT mesajını Publish etmek için hazırlık yapılıyor.

      cout << "-----------------------------------" << endl;

      btSeqInstance->messageID = messageIDCount;

      // Tarama öncesi alınan zaman etiketi (timestamp[0])
      gettimeofday(&tsConverter, NULL);
      tsBeforeTheScan.sec = tsConverter.tv_sec;
      tsBeforeTheScan.nanosec = (tsConverter.tv_usec * 1000);
      cout << " timestamp[0] (before the scan) = " << tsBeforeTheScan.sec
           << '.';
      cout << setfill('0') << setw(9) << (tsBeforeTheScan.nanosec)
           << endl;

      // BT taraması yapılıyor ve ardından tarama sonuçları 'bt_rssi'
      // dosyasına yazdırılıyor.
      system("sudo hciconfig hci0 reset");
      FakeDelay();
      system("sudo bt-adapter -a hci0 -d >> bt_rssi.txt");
      FakeDelay();

      cout << "Bluetooth message is publishing..." << endl;

      try
      {
        // BT tarama dosyası okunuyor
        fIn.open ("bt_rssi.txt", ios::in);
        stringstream ssBt;
        ssBt << fIn.rdbuf();
        btFileContenHolder = ssBt.str();
        system("rm bt_rssi.txt");

        // Okunan dosya boost kütüphane yardımıyla ayrıştırılıyor
        boost::regex expAd( "Address: ([0-9A-F:]{17})" ) ;
        boost::regex expBt( "RSSI:.*?([0-9]+)") ;
        boost::match_results<string::const_iterator> whatAd;

        string::const_iterator startAd = btFileContenHolder.begin();
        string::const_iterator finishAd = btFileContenHolder.end();

        while (boost::regex_search(startAd, finishAd, whatAd, expAd))
        {
          btMacHolder.push_back(whatAd[1]);
          startAd = whatAd[0].second ;
        }

        boost::match_results<string::const_iterator> whatBt;
        startAd = btFileContenHolder.begin() ;
        finishAd = btFileContenHolder.end() ;

        while (boost::regex_search(startAd, finishAd, whatBt, expBt))
        {
          string foundRssi(whatBt[1]);
          btRssiHolder.push_back(atoi(foundRssi.c_str()));
          startAd = whatBt[0].second ;
        }

        cout << "Number of BT connection that has been found: "
             << btRssiHolder.size() << endl;
        cout << "MessageID: " << btSeqInstance->messageID << endl;

        // Tarama sonrası alınan zaman etiketi (timestamp[1])
        gettimeofday(&tsConverter, NULL);
        tsAfterTheScan.sec = tsConverter.tv_sec;
        tsAfterTheScan.nanosec =( tsConverter.tv_usec * 1000);
        cout << " timestamp[1] (after the scan) = "
             << tsAfterTheScan.sec << '.';
        cout << setfill('0') << setw(9) << (tsAfterTheScan.nanosec)
             << endl;


        // Ayrıştırılan BT tarama dosyası ve alınan zaman etiketleri,
        // Publish edilecek olan mesaj değişkenlerine kaydediliyor.
        btSeqInstance->timestamp[0][0] = tsBeforeTheScan.nanosec;
        btSeqInstance->timestamp[0][1] = tsBeforeTheScan.sec;
        btSeqInstance->timestamp[1][0] = tsAfterTheScan.nanosec;
        btSeqInstance->timestamp[1][1] = tsAfterTheScan.sec;

        btSeqInstance->messages.length(btMacHolder.size());
        for(int i = 0; i < btMacHolder.size(); i++)
        {
          Msg msg;
          msg.devID = DDS::string_dup(btMacHolder[i].c_str());
          msg.hostName = DDS::string_dup(hostName);
          msg.dbm = -btRssiHolder[i];
          btSeqInstance->messages[i] = msg;
        }

        // Publish edilmeden önce, bir önceki mesajın acknowlegde mesajı
        // bekleniyor
        btSeqWriter->wait_for_acknowledgments(waitAckTime);

        status = btSeqWriter->write(*btSeqInstance,
                                    DDS::HANDLE_NIL);
        checkStatus(status, "BtSeqDataWriter::write");
        messageIDCount++;
      }

      catch ( boost::bad_expression & ex )
      {
        std::cout << ex.what() ;
        break;
      }

      btMacHolder.clear();
      btRssiHolder.clear();
      fIn.close();

      cout << "-----------------------------------" << endl;

      // Tarama sıklığını belirleyen değişken sıfırlanıyor
      timelimit.setTimerToZero();
      refreshRateCounter = 0;
      cout << refreshRateCounter << endl;

    } // BT Publisher kısmının sonu


    // Sunucu tarafından gönderilen Matlab komutlarına Subscribe olunuyor
    else
    {
      status = serverReqReader->take(serverReqSeq,
                                     infoSeq,
                                     LENGTH_UNLIMITED,
                                     ANY_SAMPLE_STATE,
                                     ANY_VIEW_STATE,
                                     ANY_INSTANCE_STATE);
      checkStatus(status, "severReqDataReader::read");

      for (DDS::ULong j = 0; j < serverReqSeq.length(); j++)
      {
        if(infoSeq[j].valid_data)
        {
          cout << "=== [Subscriber] message received :" << endl;
          cout << "    Received Request Message  : "
               << serverReqSeq[j].request << endl;
          cout << "    Received RequestID : \""
               << serverReqSeq[j].requestID << "\"" << endl;

          // Rapidjson yapılandırıcısı yaratılıyor
          Document d;
          if(d.Parse(serverReqSeq[j].request).HasParseError())
            cout << " Parsing Error!" << endl;

          StringBuffer nodeIdBuffer;
          Writer<StringBuffer> nodeIdWriter(nodeIdBuffer);
          d["NodeID"].Accept(nodeIdWriter);

          string tempNodeId = nodeIdBuffer.GetString();

          // Subscribe olunan mesajın düğüme ait olup olmadığı kontrol ediliyor
          if (tempNodeId == "\"SensDug13\"")
          {
            StringBuffer buffer;

            Value::ConstMemberIterator itr = d.FindMember("SetRefreshRate");
            // Ref Rate komutunun gelip gelmediği kontrol ediliyor
            if(itr != d.MemberEnd())
            {
              string refreshRateString;
              int refreshRateInt;

              // Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
              Writer<StringBuffer> writer(buffer);
              d["SetRefreshRate"].Accept(writer);
              refreshRateString = buffer.GetString();

              // Gelen mesajda fazladan çift tırnak ile bulunuyor
              // Örneğin, ""15""
              // Bu yüzden ilk son karakterler kırpılıyor
              refreshRateString =
                  refreshRateString.substr(1, refreshRateString.size()-1);
              // Refresh rate değeri stringden integera çevriliyor
              refreshRateInt = atoi(refreshRateString.c_str());

              refreshRate = refreshRateInt;
              timelimit.setMaxDuration(std::chrono::milliseconds
                                       (refreshRate*1000));

            }
          }
          else
            cout << "Invalid NodeID!" << endl;
        }
      }

      status = serverReqReader->return_loan(serverReqSeq, infoSeq);
      checkStatus(status, "ServerReqDataReader::return_loan");

      refreshRateCounter++;
      cout << refreshRateCounter << endl;

    } // Matlab komutuna Subscribe olma kısmının sonu

    // Terminalde akacak olan çıktıları dah gözle görülebilir bir şekilde
    // yazdırmak için koyulmuştur
    FakeDelay();
  }

  // Hafıza temizle işlemleri gerçekleştiriliyor

  mgrBtPub.deleteWriter();
  mgrBtPub.deletePublisher();
  mgrBtPub.deleteTopic();
  mgrBtPub.deleteParticipant();

  mgrReqSub.deleteReader();
  mgrReqSub.deleteSubscriber();
  mgrReqSub.deleteTopic();
  mgrReqSub.deleteParticipant();

  return 0;
}
Exemple #11
0
int NodeWifiHandler (int argc, char *argv[])
{

  // DDS değişkenleri
  ReturnCode_t                        status;
  InstanceHandle_t                    userHandle;
  DDSEntityManager                    mgrReqSub;
  DDSEntityManager                    mgrReqPub;
  DDSEntityManager                    mgrWifiPub;
  WifiSeq                             *wifiSeqInstance = new WifiSeq();;
  ServerReqSeq                        serverReqSeq;
  ServerReq                           *serverReq = new ServerReq();
  SampleInfoSeq_var                   infoSeq = new SampleInfoSeq();

  // Zaman ile alakalı değişkenler
  DDS::Duration_t                     waitAckTime = { 0, 800000000 }; //800ms
  int                                 refreshRate = 60;
  long int                            messageIDCount = 0;
  Time_t                              tsBeforeTheScan = { 0, 0 };
  Time_t                              tsAfterTheScan = { 0, 0 };
  struct timeval                      tsConverter;

  // Veri tutucular (data structures)
  vector<string>                      modemIdHolder;
  vector<int>                         dbmHolder;
  string                              wifiFileContenHolder;
  string                              ifconfigFileContentHolder;


  // Wifi tarama sonuçlarının yazdırıldığı dosyadan okuma yapacak
  // olan değişken
  boost::filesystem::ifstream         fInWifiScan, fInIfconfig;

  // Matlab komutları ayrıştırılmasında kullanılacak olan değişkenler
  string                              ip, subnet, gateway, dns, nodeName;

  char                                hostName[1024];
  gethostname(hostName, 1024);

  // Bluetooth tarama sıklığı ayarlayan değişken
  int refreshRateCounter = -1;


  // !!! Wifi tarama mesajlarını Publish edecek Topic yaratılıyor
  // ve o Topic'e ait konfigürasyon ayarları yapılıyor

  // Domain participant yaratılıyor
  mgrWifiPub.createParticipant("KonSensData_WifiSeq_Participant");

  // WifiSeq tipi yaratılıyor
  WifiSeqTypeSupport_var wifiSeqTS = new WifiSeqTypeSupport();
  mgrWifiPub.registerType(wifiSeqTS.in());

  // Topic yaratılıyor
  char wifiPubTopicName[] = "KonSensData_WifiSeq_Topic";
  mgrWifiPub.createTopic(wifiPubTopicName);

  // Publisher yaratılıyor
  mgrWifiPub.createPublisher();

  // DataWriter yaratılıyor
  bool autodisposeUnregisteredInstances = false;
  mgrWifiPub.createWriter(autodisposeUnregisteredInstances,
                          KEEP_ALL_HISTORY_QOS,
                          BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS);

  // Yaratılan DataWriter, WifiSeq tipi için özelleştiriliyor
  DataWriter_var dWriterWifPub = mgrWifiPub.getWriter();
  WifiSeqDataWriter_var wifiSeqWriter =
      WifiSeqDataWriter::_narrow(dWriterWifPub.in());

  // Düğüm numarası atanıyor
  wifiSeqInstance->userID = 13;

  cout << "=== [Publisher of KonSensData_WifiSeq_Topic] Ready ..." << endl;


  // !!! Sunucudan gelen komutlara Subscribe olacak olan Topic yaratılıyor
  // ve o Topic için gerekli konfigürasyon ayarları yapılıyor

  // Domain participant yaratılıyor
  mgrReqSub.createParticipant(
        "KonSensData_ServerReq_Participant_Server_to_Node");

  // ServerReq tipi yaratılıyor.
  ServerReqTypeSupport_var mgrSubscriberTS = new ServerReqTypeSupport();
  mgrReqSub.registerType(mgrSubscriberTS.in());

  // Topic yaratılıyor
  char reqSubTopicName[] = "KonSensData_ServerReq_Topic_Server_to_Node";
  mgrReqSub.createTopic(reqSubTopicName, RELIABLE_RELIABILITY_QOS,
                        VOLATILE_DURABILITY_QOS);

  // Subscriber yaratılıyor
  mgrReqSub.createSubscriber();

  // DataReader yaratılıyor
  mgrReqSub.createReader(KEEP_LAST_HISTORY_QOS, 1);

  // Yaratılan DataReader, ServerReq tipi için özelleştiriliyor.
  DataReader_var dReadeSub = mgrReqSub.getReader();
  ServerReqDataReader_var serverReqReader =
      ServerReqDataReader::_narrow(dReadeSub.in());
  checkHandle(serverReqReader.in(), "ServerReqDataReader::_narrow");

  cout << "=== [Subscriber of KonSensData_ServerReq_Topic_Server_to_Node]"
          " Ready ..." << endl;


  // !!! Sunucudan gelen komutlar ayrıştırılıp işlendikten sonra Response
  // mesajını Publish edecek olan Topic yaratılıyor

  // Domain participant yaratılıyor
  mgrReqPub.createParticipant(
        "KonSensData_ServerReq_Participant_Node_to_Server");

  // ServerReq tipi yaratılıyor.
  ServerReqTypeSupport_var mgrPublisherTS = new ServerReqTypeSupport();
  mgrReqPub.registerType(mgrPublisherTS.in());

  // Topic yaratılıyor
  char reqPubTopicName[] = "KonSensData_ServerReq_Topic_Node_to_Server";
  mgrReqPub.createTopic(reqPubTopicName, RELIABLE_RELIABILITY_QOS,
                        VOLATILE_DURABILITY_QOS);

  // Publisher yaratılıyor
  mgrReqPub.createPublisher();

  // DataWriter yaratılıyor
  // Not: Kullanılan autodisposeUnregisteredInstances değişkeni
  // WifiSeqDataWriter yaratılırken ki kullananla aynıdır
  mgrReqPub.createWriter(autodisposeUnregisteredInstances,
                         KEEP_LAST_HISTORY_QOS, 1);

  // Yaratılan DataReader, ServerReq tipi için özelleştiriliyor.
  DataWriter_var dWriterPub = mgrReqPub.getWriter();
  ServerReqDataWriter_var serverReqWriter =
      ServerReqDataWriter::_narrow(dWriterPub.in());

  cout << "=== [Publisher of KonSensData_ServerReq_Topic_Node_to_Server] "
          "Ready ..." << endl;

  // Yenileme sıklığını belirleyecek olan 'timelimit' değişkeni yaratılıyor.
  Timeout timeLimit(std::chrono::milliseconds(refreshRate*1000));

  while(true)
  {
    if (timeLimit.isExpired() || refreshRateCounter == -1)
    {

      // Wifi mesajını Publish etmek için hazırlık yapılıyor.
      cout << "-----------------------------------" << endl;

      wifiSeqInstance->messageID = messageIDCount;

      // Tarama öncesi alınan zaman etiketi (timestamp[0])
      gettimeofday(&tsConverter, NULL);
      tsBeforeTheScan.sec = tsConverter.tv_sec;
      tsBeforeTheScan.nanosec = (tsConverter.tv_usec * 1000);
      cout << " timestamp[0] (before the scan) = " << tsBeforeTheScan.sec
           << '.';
      cout << setfill('0') << setw(9) << (tsBeforeTheScan.nanosec)
           << endl;

      // Wifi taraması yapılıyor ve ardından tarama sonuçları 'wifi_rssi'
      // dosyasına yazdırılıyor.
      system("sudo iwlist wlan0 scanning >> wifi_rssi.txt");

      // Wifi bağlantısı kapatılıyor
      system("sudo ifconfig wlan0 down");

      // Wifi tarama dosyası okunuyor
      fInWifiScan.open("wifi_rssi.txt",ios::in);

      stringstream ssWifi;
      ssWifi << fInWifiScan.rdbuf();
      wifiFileContenHolder = ssWifi.str();
      system("rm wifi_rssi.txt");
      try
      {
        // Okunan dosya boost kütüphane yardımıyla ayrıştırılıyor
        boost::regex exp( "Signal level=.*?([0-9]+)") ;
        boost::regex expAd( "Address: ([0-9A-F:]{17})" ) ;
        boost::match_results<string::const_iterator> whatAd;
        string::const_iterator startAd =
            wifiFileContenHolder.begin() ;
        string::const_iterator finishAd =
            wifiFileContenHolder.end() ;

        while (boost::regex_search(startAd, finishAd,
                                   whatAd, expAd))
        {
          modemIdHolder.push_back(whatAd[1]);
          startAd = whatAd[0].second ;
        }

        boost::match_results<string::const_iterator> what;

        string::const_iterator start = wifiFileContenHolder.begin();
        string::const_iterator finish = wifiFileContenHolder.end();

        while (boost::regex_search(start, finish, what, exp))
        {
          string foundDbm(what[1]);
          dbmHolder.push_back(atoi(foundDbm.c_str()));
          start = what[0].second ;
        }

        cout << " Number of Wifi Network that has been founded: "
             << dbmHolder.size() << endl;

        // Tarama sonrası alınan zaman etiketi (timestamp[1])
        gettimeofday(&tsConverter, NULL);
        tsAfterTheScan.sec = tsConverter.tv_sec;
        tsAfterTheScan.nanosec = (tsConverter.tv_usec * 1000);
        cout << " timestamp[1] (after the scan) = "
             << tsAfterTheScan.sec << '.';
        cout << setfill('0') << setw(9) << (tsAfterTheScan.nanosec)
             << endl;

        // Ayrıştırılan Wifi tarama dosyası ve alınan zaman etiketleri,
        // Publish edilecek olan mesaj değişkenlerine kaydediliyor
        wifiSeqInstance->timestamp[0][0] = tsBeforeTheScan.nanosec;
        wifiSeqInstance->timestamp[0][1] = tsBeforeTheScan.sec;
        wifiSeqInstance->timestamp[1][0] = tsAfterTheScan.nanosec;
        wifiSeqInstance->timestamp[1][1] = tsAfterTheScan.sec;

        wifiSeqInstance->messages.length(modemIdHolder.size());
        cout << " MessageID: " << wifiSeqInstance->messageID << endl;
        for(int i = 0; i < modemIdHolder.size(); i++)
        {
          Msg msg;
          msg.devID = DDS::string_dup(modemIdHolder[i].c_str());
          msg.hostName = DDS::string_dup(hostName);
          msg.dbm = -dbmHolder[i];
          wifiSeqInstance->messages[i] = msg;

        }

        // Publish edilmeden önce, bir önceki mesajın acknowlegde mesajı
        // bekleniyor
        wifiSeqWriter->wait_for_acknowledgments(waitAckTime);
        status = wifiSeqWriter->write(*wifiSeqInstance,DDS::HANDLE_NIL);

        checkStatus(status, "konsensSensDugWifiSeqTopic::"
                            "WifiSeqDataWriter::write_w_timestamp");

        // Wifi bağlantısı tekrar açılıyor
        system("sudo ifconfig wlan0 up");

        messageIDCount++;
      }

      catch ( boost::bad_expression & ex )
      {
        cout << ex.what() ;
      }

      modemIdHolder.clear();
      dbmHolder.clear();
      wifiFileContenHolder.clear();
      fInWifiScan.close();

      cout << "-----------------------------------" << endl;

      timeLimit.setTimerToZero();

      // Tarama sıklığını belirleyen değişken sıfırlanıyor
      refreshRateCounter = 0;
      cout << refreshRateCounter << endl;

    } // Wifi Publisher kısmının sonu


    // Sunucu tarafından gönderilen Matlab komutlarına Subscribe olunuyor
    else
    {
      status = serverReqReader->take(serverReqSeq,
                                     infoSeq,
                                     LENGTH_UNLIMITED,
                                     ANY_SAMPLE_STATE,
                                     ANY_VIEW_STATE,
                                     ANY_INSTANCE_STATE);
      checkStatus(status, "severReqDataReader::take");

      // isDataReceived değişkeni bir kontrol değişkeni olup, Matlab komut
      // bilgisini içeren mesaja Subscribe olunduysa true, olunmadıysa false
      // değerini tutar
      bool isDataReceived = false;

      for (DDS::ULong j = 0; j < serverReqSeq.length(); j++)
      {

        if(infoSeq[j].valid_data)
        {
          cout << "=== [Subscriber] message received :" << endl;
          cout << "    Received Request Message  : "
               << serverReqSeq[j].request << endl;
          cout << "    Received RequestID : \""
               << serverReqSeq[j].requestID << "\"" << endl;

          // Rapidjson yapılandırıcısı yaratılıyor
          Document d;
          if(d.Parse(serverReqSeq[j].request).HasParseError())
            cout << " Parsing Error!" << endl;
          StringBuffer nodeIdBuffer;
          Writer<StringBuffer> nodeIdWriter(nodeIdBuffer);
          d["NodeID"].Accept(nodeIdWriter);
          string tempNodeId = nodeIdBuffer.GetString();

          // Subscribe olunan mesajın düğüme ait olup olmadığı kontrol ediliyor
          if (tempNodeId == "\"SensDug13\"")
          {
            StringBuffer buffer;

            // Reset komutunun gelip gelmediği kontrol ediliyor.
            Value::ConstMemberIterator itr = d.FindMember("Reset");
            if(itr != d.MemberEnd())
            {
              // Resetin değeri falsedan trueya çevriliyor
              Value& s = d["Reset"];
              s.SetBool(true);

              // Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
              Writer<StringBuffer> writer(buffer);
              d.Accept(writer);

              cout << "    Request Message is modified to  : "
                   << buffer.GetString() << endl;

              // Publish edilecek Response mesajı hazırlanıyor
              string str = buffer.GetString();
              str.append("\n");
              serverReq->request = DDS::string_dup(str.c_str());
              serverReq->requestID = serverReqSeq[j].requestID;

              if(!isDataReceived && status == DDS::RETCODE_OK)
              {
                // Response mesajı gönderiliyor
                ReturnCode_t tempStatus = serverReqWriter->write(
                      *serverReq, DDS::HANDLE_NIL);
                checkStatus(tempStatus, "severReqDataReader::write");
                isDataReceived = true;

                cout << "    Response Request Message is sent : "
                     << serverReq->request << endl;
                cout << "    Response RequestID is sent : \""
                     << serverReq->requestID << "\"" << endl;

              }

              // Sistem yeniden başlatılıyor !!!
              cout << "reboot" << endl;
              system("sudo reboot");
            }

            // GetRefreshRate ve SetRefreshRate komutundan herhangi birinin
            // gelip gelmediği kontrol ediliyor
            itr = d.FindMember("SetRefreshRate");
            if(itr != d.MemberEnd())
            {
              string refreshRateString;
              int refreshRateInt;

              // Status değeri falsedan trueya çevriliyor
              Value& s = d["Status"];
              s.SetBool(true);

              // Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
              Writer<StringBuffer> writer(buffer);
              d["SetRefreshRate"].Accept(writer);
              refreshRateString = buffer.GetString();

              // Gelen mesajda fazladan çift tırnak ile bulunuyor
              // Örneğin, ""15""
              // Bu yüzden ilk son karakterler kırpılıyor
              refreshRateString =
                  refreshRateString.substr(1, refreshRateString.size()-1);
              // Refresh rate değeri stringden integera çevriliyor
              refreshRateInt = atoi(refreshRateString.c_str());

              // Refresh rate değişkeni güncelleniyor
              refreshRate = refreshRateInt;
              timeLimit.setMaxDuration(std::chrono::milliseconds
                                       (refreshRate*1000));

            }

            itr = d.FindMember("GetRefreshRate");
            if(itr != d.MemberEnd())
            {
              // Status değeri falsedan trueya çevriliyor
              Value& s = d["Status"];
              s.SetBool(true);

              Value& tempRefreshRate = d["GetRefreshRate"];

              // Güncel refresh rate değişken bilgisi alınıyor
              string str = to_string(refreshRate);
              tempRefreshRate.SetString(str.c_str(), str.length());
            }

            // GetAliveStatus komutunun gönderilip gönderilmediği kontrol
            // ediliyor.
            itr = d.FindMember("Alive");
            if(itr != d.MemberEnd())
            {
              // Alive değeri truedan false çevriliyor
              Value& s = d["Alive"];
              s.SetBool(true);

              // Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
              Writer<StringBuffer> writer(buffer);
              d.Accept(writer);
            }

            // GetNetStatus komutunun gelip gelmediği kontrol ediliyor
            itr = d.FindMember("IP");
            if(itr != d.MemberEnd())
            {
              cout << "-----------------------------------" << endl;

              // Ağ durum bilgisi ifconfig.txt dosyasına yazdırılıyor
              system("cat /etc/network/interfaces >> ifconfig.txt");
              system("cat /etc/resolv.conf >> ifconfig.txt");
              system("echo -n hostname >> ifconfig.txt && hostname "
                     ">> ifconfig.txt");

              // ifconfig.txt dosyası açılıyor
              fInIfconfig.open("ifconfig.txt",ios::in);
              stringstream ssIfconfig;
              ssIfconfig << fInIfconfig.rdbuf();
              ifconfigFileContentHolder = ssIfconfig.str();
              system("rm ifconfig.txt");

              // Dosya içeriği ayrıştırılıyor
              try
              {
                boost::regex expIp
                    ("address (\\d{1,3}(\\.\\d{1,3}){3})");
                boost::regex expSubnet
                    ("netmask (\\d{1,3}(\\.\\d{1,3}){3})");
                boost::regex expGateway
                    ("gateway (\\d{1,3}(\\.\\d{1,3}){3})");
                boost::regex expDns
                    ("nameserver (\\d{1,3}(\\.\\d{1,3}){3})");
                boost::regex expNoneName
                    ("hostname.*");

                string::const_iterator startAd =
                    ifconfigFileContentHolder.begin() ;
                string::const_iterator finishAd =
                    ifconfigFileContentHolder.end() ;

                boost::match_results<string::const_iterator> whatIp;
                if ( boost::regex_search(startAd, finishAd,
                                         whatIp, expIp) )
                {
                  ip = whatIp[0];
                  cout << ip << endl;
                  string chopped_str = "address ";
                  string::size_type i = ip.find(chopped_str);
                  if (i != string::npos)
                    ip.erase(i, chopped_str.length());

                  Value& tempIp = d["IP"];
                  tempIp.SetString(ip.c_str(), ip.length());
                }

                startAd = ifconfigFileContentHolder.begin() ;
                finishAd = ifconfigFileContentHolder.end() ;

                boost::match_results<string::const_iterator> whatSubnet;
                if ( boost::regex_search(startAd, finishAd,
                                         whatSubnet, expSubnet) )
                {
                  subnet = whatSubnet[0];
                  cout << subnet << endl;
                  string chopped_str = "netmask ";
                  string::size_type i = subnet.find(chopped_str);
                  if (i != string::npos)
                    subnet.erase(i, chopped_str.length());

                  Value& tempSubnet = d["Subnet"];
                  tempSubnet.SetString(subnet.c_str(),
                                       subnet.length());

                }

                startAd = ifconfigFileContentHolder.begin() ;
                finishAd = ifconfigFileContentHolder.end() ;
                boost::match_results<string::const_iterator> whatGateway;

                if ( boost::regex_search(startAd, finishAd,
                                         whatGateway, expGateway) )
                {
                  gateway = whatGateway[0];
                  cout << gateway << endl;
                  string chopped_str = "gateway ";
                  string::size_type i = gateway.find(chopped_str);
                  if (i != string::npos)
                    gateway.erase(i, chopped_str.length());

                  Value& tempGateway = d["Gateway"];
                  tempGateway.SetString(gateway.c_str(),
                                        gateway.length());


                }

                startAd = ifconfigFileContentHolder.begin() ;
                finishAd = ifconfigFileContentHolder.end() ;
                boost::match_results<string::const_iterator> whatDns;

                if ( boost::regex_search(startAd, finishAd,
                                         whatDns, expDns) )
                {
                  dns = whatDns[0];
                  cout << dns << endl;
                  string chopped_str = "nameserver ";
                  string::size_type i = dns.find(chopped_str);
                  if (i != string::npos)
                    dns.erase(i, chopped_str.length());

                  Value& tempDns = d["DNS"];
                  tempDns.SetString(dns.c_str(), dns.length());
                }

                startAd = ifconfigFileContentHolder.begin() ;
                finishAd = ifconfigFileContentHolder.end() ;
                boost::match_results<string::const_iterator> whatNodeName;

                if ( boost::regex_search(startAd, finishAd,
                                         whatNodeName, expNoneName) )
                {
                  nodeName = whatNodeName[0];
                  cout << nodeName << endl;
                  string chopped_str = "hostname";
                  string::size_type i = nodeName.find(chopped_str);
                  if (i != string::npos)
                    nodeName.erase(i, chopped_str.length());
                  nodeName.erase(remove(nodeName.begin(),
                                        nodeName.end(),
                                        '\n'),
                                 nodeName.end());

                  Value& tempNodeName = d["Name"];
                  tempNodeName.SetString(nodeName.c_str(),
                                         nodeName.length());
                }

                cout << ip << endl;
                cout << subnet << endl;
                cout << dns << endl;
                cout << nodeName << endl;
              } // Dosya ayrıştırma işlemi bitti

              catch ( boost::bad_expression & ex )
              {
                cout << ex.what() ;
              }

              ifconfigFileContentHolder.clear();
              fInIfconfig.close();

              cout << "-----------------------------------" << endl;

              // GetNetStatus komutuna ait status değeri falsedan trueya
              // çevriliyor.
              Value& s = d["Status"];
              s.SetBool(true);
            }

            // Matlab'dan gelen mesaj içeriğinin ayrıştırılıp düzenlenme işlemi
            // tamamlandı ve sunucuya Response mesajını Publish etmek için
            // aşağıdaki adımlar gerçekleştiriliyor

            // Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
            StringBuffer responseBuffer;
            Writer<StringBuffer> writer(responseBuffer);
            d.Accept(writer);

            cout << "    Request Message is modified to  : "
                 << responseBuffer.GetString() << endl;

            // Response mesajı hazırlanıyor
            string str = responseBuffer.GetString();
            str.append("\n");
            serverReq->request = DDS::string_dup(str.c_str());
            //serverReq->request = DDS::string_dup("Hello World\n");
            serverReq->requestID = serverReqSeq[j].requestID;

            if(!isDataReceived && status == DDS::RETCODE_OK)
            {
              // Response mesajı Publish ediliyor
              ReturnCode_t tempStatus = serverReqWriter->write(
                    *serverReq, DDS::HANDLE_NIL);
              checkStatus(tempStatus, "severReqDataReader::write");
              isDataReceived = true;

              cout << "    Response Request Message is sent : "
                   << serverReq->request << endl;
              cout << "    Response RequestID is sent : \""
                   << serverReq->requestID << "\"" << endl;
            }
          }

          else
            cout << "Invalid NodeID!" << endl;
        }

      }

      status = serverReqReader->return_loan(serverReqSeq, infoSeq);
      checkStatus(status, "MsgDataReader::return_loan");

      refreshRateCounter++;
      cout << refreshRateCounter << endl;

    } // Matlab komutuna Subscribe olma kısmının sonu

    // Terminalde akacak olan çıktıları dah gözle görülebilir bir şekilde
    // yazdırmak için koyulmuştur
    fake_delay();
  }

  // Hafıza temizle işlemleri gerçekleştiriliyor

  status = wifiSeqWriter->dispose(*wifiSeqInstance, userHandle);
  checkStatus(status, "WifiSeqDataWriter::dispose");
  status = wifiSeqWriter->unregister_instance(*wifiSeqInstance, userHandle);
  checkStatus(status, "WifiSeqDataWriter::unregister_instance");

  delete wifiSeqInstance;
  delete serverReq;

  mgrWifiPub.deleteWriter();
  mgrWifiPub.deletePublisher();
  mgrWifiPub.deleteTopic();
  mgrWifiPub.deleteParticipant();

  mgrReqSub.deleteReader();
  mgrReqSub.deleteSubscriber();
  mgrReqSub.deleteTopic();
  mgrReqSub.deleteParticipant();

  mgrReqPub.deletePublisher();
  mgrReqPub.deleteWriter();
  mgrReqPub.deleteTopic();
  mgrReqPub.deleteParticipant();

  return 0;
}
Exemple #12
0
AbstractWorkSource::Events AbstractWorkSource::Refresh(bool canRead, bool canWrite) {
    // This is public and due to TCP async connect nature, we cannot assume we're ready to go so shortcircuit if still waiting.
    if(!stratum) return Events();

    // As a start, dispatch my data to the server. It is required to do this first as we need to
    // initiate connection with a mining.subscribe. Each tick, we send as many bytes as we can until
    // write buffer is exhausted.
	const time_t PREV_WORK_STAMP(stratum->LastNotifyTimestamp());
    if(stratum->pending.size() && canWrite) {
        asizei count = 1;
        while(count && stratum->pending.size()) {
			StratumState::Blob &msg(stratum->pending.front());
            auto sent(Send(msg.data + msg.sent, msg.total - msg.sent));
            if(sent.first == false) {
                Events ohno;
                ohno.connFailed = true;
                return ohno;
            }
            count = sent.second;
            msg.sent += count;
            if(msg.sent == msg.total) {
#if STRATUM_DUMPTRAFFIC
				stratumDump<<">>sent to server:"<<std::endl;
				for(asizei i = 0; i < msg.total; i++) stratumDump<<msg.data[i];
				stratumDump<<std::endl;
#endif
				stratum->pending.pop();
			}
		}
	}
    Events ret;
	if(canRead == false) return ret; // sends are still considered nops, as they don't really change the hi-level state
    auto received(Receive(recvBuffer.NextBytes(), recvBuffer.Remaining()));
    if(received.first == false) {
        ret.connFailed = true;
        return ret;
    }
    else if(received.second == 0) return ret;
    ret.bytesReceived += received.second;
	recvBuffer.used += received.second;
	if(recvBuffer.Full()) recvBuffer.Grow();
	
	using namespace rapidjson;
	Document object;
	char *pos = recvBuffer.data.get();
	char *lastEndl = nullptr;
    const auto prevDiff(GetCurrentDiff());
    const auto prevJob(stratum->GetCurrentJob());
	while(pos < recvBuffer.NextBytes()) {
		char *limit = std::find(pos, recvBuffer.NextBytes(), '\n');
		if(limit >= recvBuffer.NextBytes()) pos = limit;
		else { // I process one line at time
#if STRATUM_DUMPTRAFFIC
			stratumDump<<">>from server:";
			for(asizei i = 0; pos + i < limit; i++) stratumDump<<pos[i];
			stratumDump<<std::endl;
#endif
			lastEndl = limit;
			ScopedFuncCall restoreChar([limit]() { *limit = '\n'; }); // not really necessary but I like the idea
			*limit = 0;
			object.ParseInsitu(pos);
			const Value::ConstMemberIterator &id(object.FindMember("id"));
			const Value::ConstMemberIterator &method(object.FindMember("method"));
			// There was a time in which stratum had "notifications" and "requests". They were the same thing basically but requests had an id 
			// to be used for confirmations. Besides some idiot wanted to use 0 as an ID, P2Pool servers always attach an ID even to notifications,
			// which is a less brain-damaged thing but still mandated some changes here.
			std::string idstr;
			aulong idvalue = 0;
			if(id != object.MemberEnd()) {
				switch(id->value.GetType()) {
				case kNumberType: {
					if(id->value.IsUint()) idvalue = id->value.GetUint();
					else if(id->value.IsInt()) idvalue = id->value.GetInt();
					else if(id->value.IsUint64()) idvalue = id->value.GetUint64();
					else if(id->value.IsInt64()) idvalue = id->value.GetInt64();
					idstr = std::to_string(idvalue);
					break;
				}
				case kStringType: 
					idstr.assign(id->value.GetString(), id->value.GetStringLength());
					for(size_t check = 0; check < idstr.length(); check++) {
						char c = idstr[check];
						if(c < '0' || c > '9') throw std::exception("All my ids are naturals>0, this should be a natural>0 number!");
					}
					idvalue = strtoul(idstr.c_str(), NULL, 10);
					break;
				}
			}
			/* If you read the minimalistic documentation of stratum you get the idea you can trust on some things.
			No, you don't. The only real thing you can do is figure out if something is a request from the server or a reply. */
			if(method != object.MemberEnd() && method->value.IsString()) {
				if(method->value.GetString()) MangleMessageFromServer(idstr, method->value.GetString(), object["params"]);
			}
			else { // I consider it a reply. Then it has .result or .error... MAYBE. P2Pool for example sends .result=.error=null as AUTH replies to say it doesn't care about who's logging in!
				MangleReplyFromServer(idvalue, object["result"], object["error"]);
			}
			pos = lastEndl + 1;
		}
	}
	if(lastEndl) { // at least a line has been mangled
		const char *src = lastEndl + 1;
		char *dst = recvBuffer.data.get();
		for(; src < recvBuffer.NextBytes(); src++, dst++) *dst = *src;
		recvBuffer.used = src - (lastEndl + 1);
#if _DEBUG
		for(; dst < recvBuffer.data.get() + recvBuffer.allocated; dst++) *dst = 0;
#endif
	}
	else return ret;
    const auto nowDiff(GetCurrentDiff());
    const auto nowJob(stratum->GetCurrentJob());
    auto different = [](const stratum::MiningNotify &one, const stratum::MiningNotify &two) {
        if(one.job != two.job || one.ntime != two.ntime || one.clear != two.clear) return true; // most likely
        if(one.prevHash != two.prevHash) return true; // fairly likely
        // blockVer is mostly constant,
        // nbits is... ?
        if(one.merkles.size() != two.merkles.size()) return true; // happens quite often
        if(one.coinBaseOne.size() != two.coinBaseOne.size() || one.coinBaseTwo.size() != two.coinBaseTwo.size()) return true; // not likely, if at all possible
        bool diff = false;
        for(asizei i = 0; i < one.merkles.size(); i++) diff |= one.merkles[i].hash != two.merkles[i].hash;
        for(asizei i = 0; i < one.coinBaseOne.size(); i++) diff |= one.coinBaseOne[i] != two.coinBaseOne[i];
        for(asizei i = 0; i < one.coinBaseTwo.size(); i++) diff |= one.coinBaseTwo[i] != two.coinBaseTwo[i];
        return diff;
    };
    ret.diffChanged = nowDiff != prevDiff;
    ret.newWork = different(prevJob, nowJob) && GetCurrentDiff().shareDiff != .0; // new work is to be delayed as long as diff is 0
    if(prevDiff.shareDiff == .0 && nowDiff.shareDiff != .0) {
        // When this happens and we already have a job of any sort we can finally flush the new work to the outer code
        if(nowJob.job.size()) ret.newWork = true;
    }
    return ret;
}