예제 #1
0
void Normalize::normalizeMPPortDescReplyV4() {
  using deprecated::PortV2;

  // Verify size of port list.
  size_t portListSize = buf_.size() - sizeof(MultipartReply);
  if ((portListSize % sizeof(PortV2)) != 0) {
    markInputInvalid("MultipartReply.PortDesc has invalid size");
    return;
  }

  // Normalize the port structures from V2 to normal size.
  size_t portCount = portListSize / sizeof(PortV2);
  UInt8 *pkt = buf_.mutableData();
  const PortV2 *portV2 =
      reinterpret_cast<const PortV2 *>(pkt + sizeof(MultipartReply));

  PortList ports;
  for (size_t i = 0; i < portCount; ++i) {
    PortBuilder newPort{*portV2};
    ports.add(newPort);
    ++portV2;
  }

  // Copy new port list into packet.
  buf_.addUninitialized(ports.size() - portListSize);
  pkt = buf_.mutableData();
  assert(buf_.size() == sizeof(MultipartReply) + ports.size());
  std::memcpy(pkt + sizeof(MultipartReply), ports.data(), ports.size());
}
예제 #2
0
void Normalize::normalizeFeaturesReplyV1() {
  using deprecated::PortV1;

  Header *hdr = header();

  // Check minimum size requirement.
  if (hdr->length() < sizeof(FeaturesReply)) {
    markInputInvalid("FeaturesReply is too short");
    return;
  }

  // Verify size of port list.
  size_t portListSize = hdr->length() - sizeof(FeaturesReply);
  if ((portListSize % sizeof(PortV1)) != 0) {
    markInputInvalid("FeaturesReply has invalid port list size");
    return;
  }

  // Normalize the port structures from V1 to normal size.
  size_t portCount = portListSize / sizeof(PortV1);
  UInt8 *pkt = buf_.mutableData();
  const PortV1 *portV1 =
      reinterpret_cast<const PortV1 *>(pkt + sizeof(FeaturesReply));

  PortList ports;
  for (size_t i = 0; i < portCount; ++i) {
    PortBuilder newPort{*portV1};
    ports.add(newPort);
    ++portV1;
  }

  if (ports.size() > 65535 - sizeof(FeaturesReply)) {
    markInputTooBig("FeaturesReply has too many ports");
    return;
  }

  // Copy new port list into packet.
  buf_.addUninitialized(ports.size() - portListSize);
  pkt = buf_.mutableData();
  assert(buf_.size() == sizeof(FeaturesReply) + ports.size());
  std::memcpy(pkt + sizeof(FeaturesReply), ports.data(), ports.size());
}
예제 #3
0
파일: gipsy.cpp 프로젝트: milanmichna/gipsy
/* Thread that scans for new GPSes, removals etc. */
void Gipsy::scanner_thread()
{
    while (!exit_thread) {
	// Scan for new ports
	PortList plist = get_ports(true);

	vector<unsigned int> changed;
	vector<unsigned int> removed;

	PR_Lock(lock);
	/* Remove non-existent ports */
	for (unsigned int i=0; i < gpslist.size(); i++) {
	    if (! gpslist[i] || gpslist[i]->watcher_running)
		continue;

	    /* Find port */
	    unsigned int j;
	    for (j=0; j < plist.size(); j++)
		if (plist[j].device == gpslist[i]->portinfo.device)
		    break;
	    if (j < plist.size())
		continue;

	    /* Device does not exist anymore, remove it */
	    NS_RELEASE(gpslist[i]);
	    gpslist[i] = NULL;
	    removed.push_back(i);
	}

	/* Find new ports */
	for (unsigned int i=0; i < plist.size(); i++) {
	    int pos;
	    if (find_gps(plist[i].device, pos)) {
		// Start watcher if not already started
		// may happen when scanner is stopped and started again
		if (gpslist[pos]->scan_enabled && !gpslist[pos]->watcher_running)
		    gpslist[pos]->start_watcher();
		continue; // Port already in list
	    }

	    /* Add new */
	    GpsItem *newitem = new GpsItem();
	    NS_ADDREF(newitem);

	    newitem->portinfo = plist[i];
	    // Scan_enable according prefs
	    newitem->scan_enabled = prefs_scan_enabled(*newitem);
	    newitem->gpstype = prefs_gpstype(*newitem);
	    newitem->auto_download = newitem->gpstype == GPS_MLR ? false : auto_download;

	    /* Find new slot */
	    for (pos=0; pos < (int)gpslist.size(); pos++)
		if (!gpslist[pos])
		    break;
	    if (pos < (int)gpslist.size())
		gpslist[pos] = newitem;
	    else
		gpslist.push_back(newitem);

	    newitem->pos = pos;
	    changed.push_back(pos);

	    if (newitem->scan_enabled)
		newitem->start_watcher();
	}
	PR_Unlock(lock);
	// End of critical section

	// Send updates to observers
	for (unsigned int i=0; i < removed.size(); i++) {
	    GpsItem *tmp = new GpsItem();
	    tmp->pos = removed[i];
	    NS_ADDREF(tmp);
	    notify(tmp, "gps_removed", true);
	    // - NS_RELEASE will be called in notify
	}
	
	for (unsigned int i=0; i < changed.size(); i++) {
	    int32_t idx = changed[i];
	    notify(gpslist[idx], "gps_changed");
	}
	sleep(1);
    }
    // Abort watchers on scanner exit
    // TODO: Join them?
    PR_Lock(lock);
    for (unsigned int i=0; i < gpslist.size(); i++)
	if (gpslist[i])
	    gpslist[i]->exit_thread = true;
    PR_Unlock(lock);
}