示例#1
0
void Server::loadServers(const std::string & path) {
    // The add server lambda function:
    auto addServer = [] (const std::string & host, const std::string & service) {
        try {
            NetworkNode node;
            node.Initialize(host, service);
            Network::AddNode(node);
        } catch (std::exception & e) {
            std::cerr << "[Server::loadServers::addServer] catch => std::exception" << std::endl;
            std::cerr << "+ WHAT: " << e.what() << std::endl;
        }
    };
    // Clear the current nodes:
    Network::ClearNodes();
    // Add the local node to the table:
    auto & portNumber = Options::Get(Options::PortNumberKey);
    addServer(LOCAL_HOST, portNumber);
    // Load the lines inside the servers configuration file:
    std::string line, address, port;
    std::ifstream file(path);
    while (std::getline(file, line)) {
        // This is a Comma-separated values file:
        std::stringstream sline(line);
        bool ok = std::getline(sline, address, ',') &&
                  std::getline(sline, port, ',') &&
                  IsPortNumber(port);
        if (ok) {
            addServer(address, port);
        } else {
            std::cerr << "[Server::loadServers] Wrong line!" << std::endl;
            std::cerr << "+ FILE: " << path << std::endl;
            std::cerr << "+ LINE: " << line << std::endl;
        }
    }
}
double
MacroCellUrbanAreaChannelRealization::GetPathLoss (void)
{
  /*
   * According to  ---  insert standard 3gpp ---
   * the Path Loss Model For Urban Environment is
   * L = I + 37.6log10(R)
   * R, in kilometers, is the distance between two nodes
   * I = 128.1 at 2GHz
   */
  double distance;
  double externalWallAttenuation = 20; //[dB]

  NetworkNode* src = GetSourceNode ();
  NetworkNode* dst = GetDestinationNode ();

  distance = src->GetMobilityModel ()->GetAbsolutePosition ()->GetDistance (
		  dst->GetMobilityModel ()->GetAbsolutePosition ());

  /*
  if (GetSourceNode ()->GetNodeType () == NetworkNode::TYPE_UE
		  && GetDestinationNode ()->GetNodeType () == NetworkNode::TYPE_ENODEB)
    {
	  UserEquipment* ue = (UserEquipment*) GetSourceNode ();
	  ENodeB* enb = (ENodeB*) GetDestinationNode ();

	  distance =  ue->GetMobilityModel ()->GetAbsolutePosition ()->GetDistance (enb->GetMobilityModel ()->GetAbsolutePosition ());
    }

  else if (GetDestinationNode ()->GetNodeType () == NetworkNode::TYPE_UE
		  && GetSourceNode ()->GetNodeType () == NetworkNode::TYPE_ENODEB)
    {
	  UserEquipment* ue = (UserEquipment*) GetDestinationNode ();
	  ENodeB* enb = (ENodeB*) GetSourceNode ();

	  distance =  ue->GetMobilityModel ()->GetAbsolutePosition ()->GetDistance (enb->GetMobilityModel ()->GetAbsolutePosition ());
    }
  */

  m_pathLoss = 128.1 + (37.6 * log10 (distance * 0.001));

  UserEquipment* ue;
  if (GetSourceNode ()->GetNodeType () == NetworkNode::TYPE_UE)
    {
	  ue = (UserEquipment*) GetSourceNode ();
    }
  else
   {
	  ue = (UserEquipment*) GetDestinationNode ();
   }

  if ( ue->IsIndoor() )
  {
	  m_pathLoss = m_pathLoss + externalWallAttenuation;
  }


  return m_pathLoss;
}
/**
 * Given a NodeInfoMsg inserts the node into NetworkNode database.
 * @param session can be null
 * Returns true if new node inserted, false if already present
 * Delete the message
 */
bool NodeNetworkSystem::_addNetworkNode(Session* session, NodeInfoMsg* msg) {
	if (_DEBUG)
		cout << "NodeNetworkSystem::_addNetworkNode" << endl;

	bool retval = false;
	NetworkNode* connectedNode = NetworkNode::getNodeById(msg->getId());
	if (connectedNode == NULL) {
		/* The connected node is unknown. Add it */
		retval = true;
		if (_DEBUG)
			cout
					<< "NodeNetworkSystem::_addNetworkNode: creating a new NetworkNode"
					<< endl;
		switch (msg->getNodeType()) {
		case NODETYPE_CAMERA:
			connectedNode = NetworkNode::addCamera(msg->getId(),
					msg->getAmAddress(), msg->getIpAddress(),
					msg->getServerPort());
			break;
		case NODETYPE_COOPERATOR:
			connectedNode = NetworkNode::addCooperator(msg->getId());
			break;
		default:
			if (_DEBUG)
				cerr
						<< "NodeNetworkSystem::_addNetworkNode: Error! Notification of a type "
						<< msg->getNodeType() << " node!" << endl;
			return false;
		}
		if (_DEBUG) {
			cout
					<< "NodeNetworkSystem::_addNetworkNode: Network Topology updated "
					<< endl;
			NetworkNode::printNetwork();
		}
	}
	if (session) {
		connectedNode->setSession(session);
	}
	if (connectedNode->getType() == NODETYPE_COOPERATOR) {
		switch (NetworkNode::getMyself()->getType()) {
		case NODETYPE_CAMERA: {
			_offloadingManager->addCooperator(connectedNode);
			CoopInfoMsg* infoMsg = new CoopInfoMsg(NetworkNode::getMyself(),
					NetworkNode::getSink(), LINKTYPE_TCP,
					_offloadingManager->getCooperatorsIds());
			sendMessage(infoMsg);
			break;
		}
		default:
			break;
		}
	}

	delete msg;

	return retval;
}
示例#4
0
void Network::buildExecutionNetwork() {
  E_DEBUG(ENetwork, "building execution network");
  clearExecutionNetwork();

  // 1- First build the visible network
  E_DEBUG(ENetwork, "  1- build visible network");
  E_DEBUG_INDENT;

  FractalNode* executionNetworkRoot = visibleNetwork<FractalNode>(_generator);

  FNodeVector visibleNodes = depthFirstSearch(executionNetworkRoot);

  // 2- Expand all the nodes of this first graph
  E_DEBUG_OUTDENT;
  E_DEBUG(ENetwork, "  2- expand nodes");
  E_DEBUG_INDENT;

  expandNodes(visibleNodes);

  // 3- connect the expanded versions of the nodes together
  E_DEBUG_OUTDENT;
  E_DEBUG(ENetwork, "  3- connect expanded network");
  E_DEBUG_INDENT;
  connectExpandedNodes(visibleNodes);

  // 4- construct our "clean" execution network and clean up the FractalNodes
  E_DEBUG_OUTDENT;
  E_DEBUG(ENetwork, "  4- construct final network");
  E_DEBUG_INDENT;
  FNodeVector expandedNodes = depthFirstSearch(executionNetworkRoot->expanded);
  E_DEBUG(ENetwork, "num connected expanded nodes: " << expandedNodes.size());
  map<FractalNode*, NetworkNode*> falgoMap; // expanded → final network node

  for (int i=0; i<(int)expandedNodes.size(); i++) {
    falgoMap[expandedNodes[i]] = new NetworkNode(expandedNodes[i]->algorithm());
  }
  for (int i=0; i<(int)expandedNodes.size(); i++) {
    NetworkNode* parent = falgoMap[expandedNodes[i]];
    vector<FractalNode*> children = expandedNodes[i]->children();
    for (int j=0; j<(int)children.size(); j++) {
      E_DEBUG(ENetwork, "  -  " << parent->algorithm()->name() << " → " << falgoMap[children[j]]->algorithm()->name());
      parent->addChild(falgoMap[children[j]]);
    }
  }

  _executionNetworkRoot = falgoMap[executionNetworkRoot->expanded];

  // delete the FractalNodes which we just used temporarily for building the network
  E_DEBUG(ENetwork, "cleaning up temp visible fractal nodes");
  for (int i=0; i<(int)visibleNodes.size(); i++) delete visibleNodes[i];
  E_DEBUG(ENetwork, "cleaning up temp expanded fractal nodes");
  for (int i=0; i<(int)expandedNodes.size(); i++) delete expandedNodes[i];

  E_DEBUG_OUTDENT;
  E_DEBUG(ENetwork, "execution network ok");

}
示例#5
0
NetworkNode *NetworkNode::create(
	pubnub::context *pb,
	const string &channel)
{
	NetworkNode *b = new NetworkNode();
	if (b && b->initialize(pb, channel)) {
		b->autorelease();
		return b;
	}
	CC_SAFE_DELETE(b);
	return nullptr;
}
示例#6
0
void Network::topologicalSortExecutionNetwork() {
  // Note: we don't need to do a full-fledged topological sort here, as we do not
  // have any DAG, we actually have a dependency tree. This way we can just do a
  // depth-first search, with ref-counting to account for diamond shapes in the tree.
  // this is similar to the wavefront design pattern used in parallelization

  // Using DFS here also has the advantage that it makes as much as possible use
  // of cache locality

  // 1- get all the nodes and count the number of refs they have
  NodeVector nodes = depthFirstSearch(_executionNetworkRoot);
  map<NetworkNode*, int> refs;

  // this initialization should be useless, but let's do it anyway for clarity
  for (int i=0; i<(int)nodes.size(); i++) refs[nodes[i]] = 0;

  // count the number of refs for each node
  for (int i=0; i<(int)nodes.size(); i++) {
    const NodeVector& children = nodes[i]->children();
    for (int j=0; j<(int)children.size(); j++) {
      refs[children[j]] += 1;
    }
  }

  // 2- do DFS again, manually this time and only visit node which have no refs anymore
  _toposortedNetwork.clear();

  NodeStack toVisit;
  toVisit.push(_executionNetworkRoot);
  refs[_executionNetworkRoot] = 1;

  while (!toVisit.empty()) {
    NetworkNode* currentNode = toVisit.top();
    toVisit.pop();

    if (--refs[currentNode] == 0) {
      _toposortedNetwork.push_back(currentNode->algorithm()); // keep this node, it is good

      const NodeVector& children = currentNode->children();
      for (int i=0; i<(int)children.size(); i++) {
        toVisit.push(children[i]);
      }
    }
  }

  E_DEBUG(ENetwork, "-------------------------------------------------------------------------------------------");
  for (int i=0; i<(int)_toposortedNetwork.size(); i++) {
    E_DEBUG_NONL(ENetwork, " → " << _toposortedNetwork[i]->name());
  }
  E_DEBUG(ENetwork, ""); // for adding a newline
  E_DEBUG(ENetwork, "-------------------------------------------------------------------------------------------");
}
/**
 * Send message on the correct interface
 */
void NodeNetworkSystem::sendMessage(Message* msg) {
	if (!msg) {
		if (_DEBUG)
			cerr << "NodeNetworkSystem::sendMessage: Empty message" << endl;

		return;
	}

	NetworkNode* dst = msg->getDst();
	if (!dst) {
		if (_DEBUG)
			cerr << "NodeNetworkSystem::sendMessage: Empty destination" << endl;
		delete msg;
		return;
	}

	if (msg->getType() == MESSAGETYPE_DATA_ATC
			|| msg->getType() == MESSAGETYPE_DATA_CTA) {
		boost::mutex::scoped_lock lock(_countMutex);
		_queuedMessages++;
		_gpios[5]->setValue(BlackLib::high); //Set transmission pin
		lock.unlock();
	}

	switch (msg->getLinkType()) {
	case LINKTYPE_TCP: {
		Session* ses = dst->getSession();
		if (!ses) {
			if (_DEBUG)
				cerr << "NodeNetworkSystem::sendMessage: Empty session" << endl;
			delete msg;
			return;
		}
		ses->writeMessage(msg);
		break;
	}
	case LINKTYPE_TELOS: {
		_telosbRadioSystem->writeMessage(msg);
		break;
	}
	default: {
		if (_DEBUG)
			cout << "NodeNetworkSystem::sendMessage: Not yet implemented"
					<< endl;
		delete msg;
		break;
	}
	}

}
示例#8
0
void
NetworkManager::SelectTargetNode (UserEquipment* ue)
{
   NetworkNode* targetNode = ue->GetTargetNode ();

   if (targetNode->GetProtocolStack ()->GetRrcEntity ()->
		   GetHandoverEntity ()->CheckHandoverNeed (ue))
     {
	   NetworkNode* newTagertNode =
			   targetNode->GetProtocolStack ()->GetRrcEntity ()->
			   GetHandoverEntity ()->GetHoManager ()->m_target;

	   ue->SetTargetNode (newTagertNode);
     }
}
示例#9
0
 static std::string getTarget( NetworkNode& iNode )
 {
     std::string result;
     iNode.getTarget( result );
     
     return result;
 }
示例#10
0
    static std::string getNodeType( NetworkNode& iNode )
    {
        std::string result;
        iNode.getNodeType( result );

        return result;
    }
示例#11
0
bool RoutingAlg<Point, HoleType>::GreedyRouting() {
	NetworkNode<Point>	currentNode  = StartNode;
	NetworkNode<Point>	previousNode = StartNode;
	string				closestNeighborName;

	Path.push_back(StartNode);
	while(!currentNode.HasNeighbor(DestinationNode.GetName()) && currentNode.GetName() != DestinationNode.GetName()){
		if(previousNode.FindClosestNeighborToNode(DestinationNode.GetName(), closestNeighborName)
		&& NetworkPtr -> GetNodeByName(closestNeighborName, currentNode)){
			Path.push_back(currentNode);
				previousNode = currentNode;
		}
		else
			return false;
	}
	Path.push_back(DestinationNode);
	return true;
}
示例#12
0
void NetworkPlan::findCriticalPaths(NetworkNode* cur) {
	// Статическая переменная, инициализируется при первом вызове функции.
	// Является счётчиком путей.
	static int pathNum = 0;
	bool isFirst = true;
	NetworkNode* tmpNode = NULL;
	const vector<NetworkNode*>* nodes = cur->getOutgoingNodes();
	vector<NetworkNode*>::iterator itr;
	vector<NetworkNode*>::iterator itr2;
	int size = nodes->size();

	_critPaths->at(pathNum)->push_back(cur);

	for (int i = 0; i < size; i++) {
		tmpNode = nodes->at(i);

		if (tmpNode->getReserve() == 0) {
			if (isFirst) {
				findCriticalPaths(tmpNode);

				isFirst = false;
			} else {
				_critPaths->push_back(new vector<NetworkNode*>());

				// Получаем итератор на начало текущего пути.
				itr = _critPaths->at(pathNum)->begin();
				// Находим в пути текущий узел...
				itr2 = find(itr, _critPaths->at(pathNum)->end(), cur);

				// ... и копируем вершины в новый путь дублирующуюся часть.
				while (itr++ != (itr2 + 1)) {
					_critPaths->at(pathNum + 1)->push_back(*(itr - 1));
				}

				pathNum++;

				findCriticalPaths(tmpNode);
			}
		}
	}
}
示例#13
0
void StopNodePacket::processPacket(Application* app, TCPSocket* client) const {
	NetworkNode* node = app->getNetworkNode();

	//Did we already receive this one?
	vector<Packet*> rcvPackets = node->getReceivedPackets();
	bool found = false;
	for (auto itr = rcvPackets.begin(); itr != rcvPackets.end(); itr++) {
		if (*this == **itr) {
			//the order "this then itr" is crucial, else the equality check will not work proper!
			found = true;
			break;
		}
	}

	if (!found) {
		if (targetNodeId == node->getOwnId()) {
			node->stop();
		}
		else {

			if (!app->getNetworkNode()->send(targetNodeId, this)) {
				// we don't know the target, broadcast packet
				node->sendToNeighbors(this, node->getNodeId(client));
			}
		}
	}
}
/**
 * A client component has connected. Notify the server this node
 */
void NodeNetworkSystem::clientConnectHandler(Session* session) {
	if (_DEBUG)
		cout << "NodeNetworkSystem::clientConnectHandler" << endl;

	NetworkNode* serverNode = NetworkNode::getNodeBySession(session);
	NetworkNode* myself = NetworkNode::getMyself();

	NodeInfoMsg* msg = new NodeInfoMsg(myself, serverNode, LINKTYPE_TCP,
			myself->getId(), myself->getAmAddr(),
			session->getSocket()->local_endpoint().address().to_string(),
			session->getSocket()->local_endpoint().port(), myself->getType());

	session->writeMessage(msg);

	if (myself->getType() == NODETYPE_CAMERA) {
		CoopInfoMsg* infoMsg = new CoopInfoMsg(NetworkNode::getMyself(),
				NetworkNode::getSink(), LINKTYPE_TCP,
				_offloadingManager->getCooperatorsIds());
		sendMessage(infoMsg);
	}

}
示例#15
0
    static dict getConnectionByIndex( NetworkNode& iNode, size_t iIndex )
    {
        std::string inputName, connectedNodeName, connectedOutputName;

        iNode.getConnection( iIndex, inputName, connectedNodeName,
                             connectedOutputName );

        dict ret;
        ret["inputName"] = inputName;
        ret["connectedNodeName"] = connectedNodeName;
        ret["connectedOuputName"] = connectedOutputName;

        return ret;
    }
示例#16
0
    static dict getConnectionByName( NetworkNode& iNode,
                                     const std::string& iInputName )
    {
        std::string connectedNodeName, connectedOutputName;

        iNode.getConnection( iInputName, connectedNodeName,
                             connectedOutputName );

        dict ret;
        ret["connectedNodeName"] = connectedNodeName;
        ret["connectedOuputName"] = connectedOutputName;

        return ret;
    }
示例#17
0
bool NetworkPlan::buildModel(vector<NodeInfo> nodes) {
	// Установка указателей на начальную и конечную вершины.
	_S = nodes.at(0).n;
	_F = nodes.at(nodes.size() - 1).n;

	// Построение сети по считанной информации.
	_total = nodes.size();

	for (int i = 0; i < _total; i++) {
		NodeInfo* inf = &nodes.at(i);
		NetworkNode* cur = inf->n;
		int size = inf->outLinks.size();

		// Проходим по исходящим номерам, ищем совпадающие
		// узлы и создаём для них ссылки-работы. Попутно проверяем
		// наличие ссылок узлов на самих себя.
		for (int j = 0; j < size; j++) {
			for (int k = 0; k < _total; k++) {
				NodeInfo* tmpInf = &nodes.at(k);

				if (inf->outLinks.at(j).num == tmpInf->n->getNumber()) {
					if (tmpInf->n->getNumber() == inf->n->getNumber())
						throw NetworkException("Ошибка исходных данных:"
							" недопустимы ссылки вершин на самих себя");
					else
						cur->addOutgoingNode(tmpInf->n, inf->outLinks.at(j).len);
				}
			}
		}
	}

	extractLayers();
	numberNodes();

	return true;
}
void NodeNetworkSystem::serverRemoveSessionHandler(Session* session) {
	switch (_nodeProcessingSystem->getNodeType()) {
	case NODETYPE_SINK: {
		NetworkNode* camera = NetworkNode::getCameraBySession(session);
		if (camera) {
			if (_DEBUG)
				cout << "NodeNetworkSystem::serverAddSessionHandler: Camera "
						<< (unsigned short) camera->getId() << " disconnected "
						<< endl;
			camera->setSession(NULL);
		}
		break;
	}
	case NODETYPE_CAMERA: {
		NetworkNode* cooperator = NetworkNode::getCooperatorBySession(session);
		if (cooperator) {
			if (_DEBUG)
				cout
						<< "NodeNetworkSystem::serverAddSessionHandler: Cooperator "
						<< (unsigned short) cooperator->getId()
						<< " disconnected " << endl;
			cooperator->setSession(NULL);
			_offloadingManager->removeCooperator(cooperator);
			CoopInfoMsg* infoMsg = new CoopInfoMsg(NetworkNode::getMyself(),
					NetworkNode::getSink(), LINKTYPE_TCP,
					_offloadingManager->getCooperatorsIds());
			sendMessage(infoMsg);
		}
		break;
	}
	default: {
		if (_DEBUG)
			cerr << "NodeNetworkSystem::serverAddSessionHandler: Node of type "
					<< _nodeProcessingSystem->getNodeType()
					<< " can't reach this point" << endl;
	}
	}
}
示例#19
0
void
NetworkManager::UpdateUserPosition (double time)
{
  std::vector<UserEquipment*> *records = GetUserEquipmentContainer ();
  std::vector<UserEquipment*>::iterator iter;
  UserEquipment *record;

#ifdef MOBILITY_DEBUG
  std::cout << "MOBILITY_DEBUG: UPDATE POSITION, "
      "number of UE = " << records->size () <<
      " time = " << time << std::endl;
#endif

  for (iter = records->begin(); iter != records->end(); iter++)
    {
      record = *iter;

#ifdef MOBILITY_DEBUG
    std::cout << "\t USER  " << record->GetIDNetworkNode ()
	              << std::endl;
#endif

      record->UpdateUserPosition (time);
      record->SetIndoorFlag( CheckIndoorUsers(record) );

#ifdef AMC_MAPPING
  std::cout << "time: " << time << "\n\t position: "
		  << record->GetMobilityModel ()->GetAbsolutePosition ()->GetCoordinateX () <<
		  " " << record->GetMobilityModel ()->GetAbsolutePosition ()->GetCoordinateY ()
		  << std::endl;
#endif
#ifdef MOBILITY_DEBUG
  std::cout << "time: " << time << "\t position: "
		  << record->GetMobilityModel ()->GetAbsolutePosition ()->GetCoordinateX () <<
		  " " << record->GetMobilityModel ()->GetAbsolutePosition ()->GetCoordinateY ()
		  << std::endl;
#endif


      if (record->GetMobilityModel ()->GetHandover () == true)
        {
    	  NetworkNode* targetNode = record->GetTargetNode ();

          if (targetNode->GetProtocolStack ()->GetRrcEntity ()->
        		  GetHandoverEntity ()->CheckHandoverNeed (record))
            {
        	  NetworkNode* newTagertNode = targetNode->GetProtocolStack ()
        			  ->GetRrcEntity ()->GetHandoverEntity ()->GetHoManager ()->m_target;

#ifdef HANDOVER_DEBUG
              std::cout << "** HO ** \t time: " << time << " user " <<  record->GetIDNetworkNode () <<
            		  " old eNB " << targetNode->GetIDNetworkNode () <<
            		  " new eNB " << newTagertNode->GetIDNetworkNode () << std::endl;
#endif
              HandoverProcedure(time, record, targetNode, newTagertNode);
            }
        }
    }

  //PrintUEsForEachCell();
}
示例#20
0
bool
PowerBasedHoManager::CheckHandoverNeed (UserEquipment* ue)
{
	/*//test RX cqi success?
	  std::cout<<"PBHM: UE "<<ue->GetIDNetworkNode();
		ENodeB *testenb=nm->GetENodeBByID(ue->GetTargetNode()->GetIDNetworkNode());
		std::vector<int> testtemp=testenb->GetUserEquipmentRecord(ue->GetIDNetworkNode())->GetCQI();
		int testj=0;
		for(std::vector<int>::iterator testit=testtemp.begin();testit!=testtemp.end();testit++,testj++){
			std::cout<<"cqi="<<testtemp.at(testj)<<std::endl;
		}*/
	return false;
	//std::cout<<"power based ho"<<std::endl;//test
	/*
  NetworkNode *targetNode = ue->GetTargetNode ();

  double TXpower = 10 * log10 (
		  pow (10., (targetNode->GetPhy()->GetTxPower() - 30)/10)
		  /
		  targetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
  double pathLoss = ComputePathLossForInterference(targetNode, ue);

  double targetRXpower = TXpower - pathLoss;
  double RXpower;


  std::vector<ENodeB*> *listOfNodes = NetworkManager::Init ()->GetENodeBContainer ();
  std::vector<ENodeB*>::iterator it;
  for (it = listOfNodes->begin (); it != listOfNodes->end (); it++)
    {
	  if ((*it)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it);

	      TXpower = 10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  std::vector<HeNodeB*> *listOfNodes2 = NetworkManager::Init ()->GetHomeENodeBContainer();
  std::vector<HeNodeB*>::iterator it2;
  for (it2 = listOfNodes2->begin (); it2 != listOfNodes2->end (); it2++)
    {
	  if ((*it2)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it2);

	      TXpower =   10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );

	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  if (ue->GetTargetNode ()->GetIDNetworkNode () != targetNode->GetIDNetworkNode ())
    {
	  m_target = targetNode;
	  return true;
    }
  else
    {
	  return false;
    }*/
	//mouan
	//NetworkNode *targetNode = ue->GetTargetNode ();
	NetworkNode *targetNode;

	//if(targetNode->GetNodeType()==NetworkNode::TYPE_ENODEB){
	std::cout<<"enb vs ue"<<std::endl;//test
	ENodeB *targetenb;
		int compare[2];
		int selected_bus_id=0;
		{
			std::vector<ENodeB *> *enbs=nm->GetENodeBContainer();
			double mindis=9999999.0;
			for(std::vector<ENodeB *>::iterator ie=enbs->begin();ie!=enbs->end();ie++){
				CartesianCoordinates *dis=(*ie)->GetCell()->GetCellCenterPosition();
				double temp=dis->GetDistance(ue->GetMobilityModel()->GetAbsolutePosition());
				if(mindis>temp){
					mindis=temp;
					targetenb=(*ie);
				}
			}
			if(targetenb==NULL){
				std::cout<<"ERROR! targetenb==NULL"<<std::endl;
			}
			else{
				targetNode=nm->GetNetworkNodeByID(targetenb->GetIDNetworkNode());
			}
		//ENodeB *targetenb=nm->GetENodeBByID(targetNode->GetIDNetworkNode());
		//std::vector<int> uecqi=targetenb->GetUserEquipmentRecord(ue->GetIDNetworkNode())->GetCQI();
			std::vector<double> mouan_bstoueSinr;
			  std::vector<double> rxSignalValues;
			  std::vector<double>::iterator it;

			  rxSignalValues = ue->GetPhy()->GetTxSignal()->Getvalues();

			  //compute noise + interference
			  double interference;
			  if (ue->GetPhy()->GetInterference () != NULL)
				{
					ENodeB *node;
					interference = 0;

					std::vector<ENodeB*> *eNBs = NetworkManager::Init ()->GetENodeBContainer ();
					std::vector<ENodeB*>::iterator it;

					//std::cout << "Compute interference for UE " << ue->GetIDNetworkNode () << " ,target node " << ue->GetTargetNode ()->GetIDNetworkNode ()<< std::endl;

					for (it = eNBs->begin (); it != eNBs->end (); it++)
					{
					  node = (*it);
					  if (node->GetIDNetworkNode () != targetenb->GetIDNetworkNode () &&
						  node->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw () ==
						  ue->GetTargetNode ()->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw ())
						{
						  double powerTXForSubBandwidth = 10 * log10 (
								  pow (10., (node->GetPhy()->GetTxPower() - 30)/10)
								  /
								  node->GetPhy()->GetBandwidthManager ()->GetUlSubChannels().size ());


						  double nodeInterference_db = powerTXForSubBandwidth - 10 - ComputePathLossForInterference (node, ue); // in dB
						  double nodeInterference = pow(10, nodeInterference_db/10);

						  interference += nodeInterference;

						  /*
						  std::cout << "\t add interference from eNB " << node->GetIDNetworkNode ()
								  << " " << powerTXForSubBandwidth << " "  << ComputePathLossForInterference (node, ue)
								  << " " << nodeInterference_db << " " << nodeInterference
								  << " --> tot: " << interference
								  << std::endl;
						  */
						}
					}
				}
			  else
				{
				  interference = 0;
				}

			  double noise_interference = 10. * log10 (pow(10., -148.95/10) + interference); // dB


			  for (it = rxSignalValues.begin(); it != rxSignalValues.end(); it++)
				{
				  double power; // power transmission for the current sub channel [dB]
				  if ((*it) != 0.)
					{
					  power = (*it);
					}
				  else
					{
					  power = 0.;
					}
				  mouan_bstoueSinr.push_back (power - noise_interference);
				}
			  AMCModule *amc = ue->GetProtocolStack ()->GetMacEntity ()->GetAmcModule ();
			  std::vector<int> uecqi = amc->CreateCqiFeedbacks (mouan_bstoueSinr);
			  
		/*std::vector<double> spectralEfficiency;
		//std::vector<int> cqiFeedbacks = ueRecord->GetCQI ();
		int numberOfCqi = uecqi.size ();
		for (int i = 0; i < numberOfCqi; i++)
		{
		  double sEff = GetMacEntity ()->GetAmcModule ()->GetEfficiencyFromCQI (uecqi.at (i));
		  spectralEfficiency.push_back (sEff);//i didn't do * 180000.0,because just for compare
		}*/

		//copy start (from enhance-uplink-scheduler.cpp)

		UplinkPacketScheduler *ulps=targetenb->GetULScheduler();

		UplinkPacketScheduler::UsersToSchedule *users = ulps->GetUsersToSchedule();
		UplinkPacketScheduler::UserToSchedule* scheduledUser;
		int nbOfRBs = ulps->GetMacEntity()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

		int availableRBs;     // No of RB's not allocated
		int unallocatedUsers; // No of users who remain unallocated
		int selectedUser;     // user to be selected for allocation
		int selectedPRB;      // PRB to be selected for allocation
		double bestMetric;    // best metric to identify user/RB combination
		int left, right;      // index of left and left PRB's to check
		if(nbOfRBs>1000||users->size()>1000){
			std::cout<<"ERROR! some value wrong."<<std::endl;
			return false;
		}
		bool Allocated[nbOfRBs];
		bool allocationMade;
		double metrics[nbOfRBs][users->size ()];
		int requiredPRBs[users->size ()];
		//std::vector<int> m_mouan;
		int m_mouan[users->size()];
		int ueat=-1;

		//test
		int tt=0;
		for(UplinkPacketScheduler::UsersToSchedule::iterator test=users->begin();test!=users->end();test++){
			tt++;
		}
		std::cout<<"3:"<<users->size()<<"="<<tt<<std::endl;//test

		for(int i=0 ; i < users->size() ; i++){
			std::cout<<"A ";//test
			m_mouan[i]=0;
		}
std::cout<<"3end"<<std::endl;//test

std::cout<<"4"<<std::endl;//test

		//Some initialization
		availableRBs = nbOfRBs;
		unallocatedUsers = users->size ();
		for(int i=0; i < nbOfRBs; i++)
			Allocated[i] = false;

		//create a matrix of flow metrics
		for (int i = 0; i < nbOfRBs; i++)
		{
			for (int j = 0; j < users->size (); j++)
			{
				//metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
				double spectralEfficiency = ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (uecqi.at(i));
				metrics[i][j] = spectralEfficiency * 180000;
			}
		}
std::cout<<"5"<<std::endl;//test
		//create number of required PRB's per scheduled users
		for(int j=0; j < users->size(); j++)
		{
			std::cout<<"1 "<<std::endl;//test
			scheduledUser = users->at(j);
std::cout<<"2 "<<std::endl;//test
			std::vector<double> sinrs;
			for(int c=0;c<scheduledUser->m_channelContition.size();c++)
			//for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
			//		c != scheduledUser->m_channelContition.end (); c++)
			{
				//cout << *c <<" ";
				std::cout<<"a="<<c<<"="<<scheduledUser->m_channelContition.at(c)<<std::endl;//test
				std::cout<<"size="<<scheduledUser->m_channelContition.size()<<std::endl;//test
				std::cout<<"id="<<scheduledUser->m_userToSchedule->GetIDNetworkNode()<<std::endl;//test

				//if(scheduledUser->m_channelContition.at(c)>14)scheduledUser->m_channelContition.at(c)=14;
				//else if(scheduledUser->m_channelContition.at(c)<0)scheduledUser->m_channelContition.at(c)=0;
				if(scheduledUser->m_channelContition.at(c)>14||scheduledUser->m_channelContition.at(c)<0){
					return false;
				}

				sinrs.push_back (ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (scheduledUser->m_channelContition.at(c)));
				
				std::cout<<"b "<<std::endl;//test
			}
std::cout<<"3 "<<std::endl;//test

			double effectiveSinr =  GetEesmEffectiveSinr (sinrs);
std::cout<<"4 "<<std::endl;//test
			int mcs = ulps->GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
				  ulps->GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
			//scheduledUser->m_selectedMCS = mcs;
std::cout<<"5 "<<std::endl;//test
			requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
					  (ulps->GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
			std::cout<<"6end"<<std::endl;//test
		}
std::cout<<"6"<<std::endl;//test
		  //RBs allocation

		  while(availableRBs > 0 && unallocatedUsers > 0) //
		  {
			  // First step: find the best user-RB combo
			  selectedPRB = -1;
			  selectedUser = -1;
			  bestMetric = (double) (-(1<<30));

			  for(int i=0; i < nbOfRBs; i++)
			  {
				  if (!Allocated[i]){ // check only unallocated PRB's
					  for(int j=0; j < users->size (); j++)
					  {
						  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
								  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
							  if (bestMetric < metrics[i][j]){
								  selectedPRB = i;
								  selectedUser = j;
								  bestMetric = metrics[i][j];
							  }
					  }

				  }
			  }
			  // Now start allocating for the selected user at the selected PRB the required blocks
			  // using how many PRB's are needed for the user
			  if (selectedUser != -1)
			  {
				  scheduledUser = users->at(selectedUser);
				  //scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
				  m_mouan[selectedUser]++;
				  Allocated[selectedPRB] = true;
				  left =  selectedPRB - 1;
				  right = selectedPRB + 1;
				  availableRBs--;
				  unallocatedUsers--;

				  allocationMade = true;
				  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
				  { // search right and left of initial allocation
					  allocationMade = false;
					  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
						  break; // nothing is available, since we need to have contiguous allocation

					  if (    (right < nbOfRBs) && (! Allocated[right]) &&
							  (
									  ((left >=0) &&
									  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
									  || (left < 0) || Allocated[left]// OR no more left
							  )
						)
					  {
						  //Allocate PRB at right to the user
						  Allocated[right] = true;
						  //scheduledUser->m_listOfAllocatedRBs.push_back (right);
						  m_mouan[selectedUser]++;
						  right++;
						  allocationMade = true;
						  availableRBs--;
					  } else if ( (left >=0) && (! Allocated[left]) &&
								  (
									  ((right < nbOfRBs) &&
									  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
									  || (right >= nbOfRBs) || Allocated[right]// OR no more right
								   )
								)
					  {
						  //Allocate PRB at left to the user
						  Allocated[left] = true;
						  //scheduledUser->m_listOfAllocatedRBs.push_back (left);
						  m_mouan[selectedUser]++;
						  left--;
						  allocationMade = true;
						  availableRBs--;
					  }
				  } // end of for
				  
				  if(scheduledUser->m_userToSchedule->GetIDNetworkNode()==ue->GetIDNetworkNode()){
					ueat=selectedUser;
					printf("selected user %d is ueat\n",ueat);//test
				  }
			  } else { // nothing to do exit the allocation loop
				  break;
			  }
		  } //while
std::cout<<"7"<<std::endl;//test
			//copy end
if(ueat==-1)return false;//temp
			compare[1]=m_mouan[ueat];//m_mouan[ueat];//bs vs ue result
		  }
			std::cout<<"enb vs ue end"<<std::endl;//test

			//bus route
		  
		  std::vector<Bus *> *buses=nm->GetBusContainer();
		  std::vector<Bus *>::iterator select_bus;

		  for(select_bus=buses->begin();select_bus != buses->end();select_bus++)
		  {

			  Bus *selectedbus=(*select_bus);

			  std::vector<double> mouan_bustoueSinr;
			  std::vector<double> rxSignalValues;
			  std::vector<double>::iterator it;

			  rxSignalValues = ue->GetPhy()->GetTxSignal()->Getvalues();

			  //compute noise + interference
			  double interference;
			  if (ue->GetPhy()->GetInterference () != NULL)
				{
					ENodeB *node;
					interference = 0;

					std::vector<ENodeB*> *eNBs = NetworkManager::Init ()->GetENodeBContainer ();
					std::vector<ENodeB*>::iterator it;

					//std::cout << "Compute interference for UE " << ue->GetIDNetworkNode () << " ,target node " << ue->GetTargetNode ()->GetIDNetworkNode ()<< std::endl;

					for (it = eNBs->begin (); it != eNBs->end (); it++)
					{
					  node = (*it);
					  if (//node->GetIDNetworkNode () != ue->GetTargetNode ()->GetIDNetworkNode () &&
						  node->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw () ==
						  ue->GetTargetNode ()->GetPhy ()->GetBandwidthManager ()->GetUlOffsetBw ())
						{
						  double powerTXForSubBandwidth = 10 * log10 (
								  pow (10., (node->GetPhy()->GetTxPower() - 30)/10)
								  /
								  node->GetPhy()->GetBandwidthManager ()->GetUlSubChannels().size ());


						  double nodeInterference_db = powerTXForSubBandwidth - 10 - ComputePathLossForInterference (node, ue); // in dB
						  double nodeInterference = pow(10, nodeInterference_db/10);

						  interference += nodeInterference;

						  /*
						  std::cout << "\t add interference from eNB " << node->GetIDNetworkNode ()
								  << " " << powerTXForSubBandwidth << " "  << ComputePathLossForInterference (node, ue)
								  << " " << nodeInterference_db << " " << nodeInterference
								  << " --> tot: " << interference
								  << std::endl;
						  */
						}
					}
				}
			  else
				{
				  interference = 0;
				}

			  double noise_interference = 10. * log10 (pow(10., -148.95/10) + interference); // dB


			  for (it = rxSignalValues.begin(); it != rxSignalValues.end(); it++)
				{
				  double power; // power transmission for the current sub channel [dB]
				  if ((*it) != 0.)
					{
					  power = (*it);
					}
				  else
					{
					  power = 0.;
					}
				  mouan_bustoueSinr.push_back (power - noise_interference);
				}
			  AMCModule *amc = ue->GetProtocolStack ()->GetMacEntity ()->GetAmcModule ();
			  std::vector<int> mouan_bustouecqi = amc->CreateCqiFeedbacks (mouan_bustoueSinr);

			  //run the bus scheduler

			    UplinkPacketScheduler *ulps=selectedbus->GetULScheduler();

				UplinkPacketScheduler::UsersToSchedule *users = ulps->GetUsersToSchedule();
				UplinkPacketScheduler::UserToSchedule* scheduledUser;
				int nbOfRBs = ulps->GetMacEntity()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

				int availableRBs;     // No of RB's not allocated
				int unallocatedUsers; // No of users who remain unallocated
				int selectedUser;     // user to be selected for allocation
				int selectedPRB;      // PRB to be selected for allocation
				double bestMetric;    // best metric to identify user/RB combination
				int left, right;      // index of left and left PRB's to check
				bool Allocated[nbOfRBs];
				bool allocationMade;
				double metrics[nbOfRBs][users->size ()];
				int requiredPRBs[users->size ()];
				//std::vector<int> m_mouan;
				int m_mouan[users->size()];
				int ueat;
				for(int i=0;i<users->size();i++)m_mouan[i]=0;


				//Some initialization
				availableRBs = nbOfRBs;
				unallocatedUsers = users->size ();
				for(int i=0; i < nbOfRBs; i++)
					Allocated[i] = false;

				//create a matrix of flow metrics
				for (int i = 0; i < nbOfRBs; i++)
				{
					for (int j = 0; j < users->size (); j++)
					{
						//metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
						double spectralEfficiency = ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (mouan_bustouecqi.at(i));
						metrics[i][j] = spectralEfficiency * 180000;
					}
				}

				//create number of required PRB's per scheduled users
				for(int j=0; j < users->size(); j++)
				{
					scheduledUser = users->at(j);

					std::vector<double> sinrs;
					for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
							c != scheduledUser->m_channelContition.end (); c++)
					{
						//cout << *c <<" ";
						sinrs.push_back (ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (*c));
					}


					double effectiveSinr =  GetEesmEffectiveSinr (sinrs);

					int mcs = ulps->GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
						  ulps->GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
					//scheduledUser->m_selectedMCS = mcs;
					requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
							  (ulps->GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
				}

				  //RBs allocation

				  while(availableRBs > 0 && unallocatedUsers > 0) //
				  {
					  // First step: find the best user-RB combo
					  selectedPRB = -1;
					  selectedUser = -1;
					  bestMetric = (double) (-(1<<30));

					  for(int i=0; i < nbOfRBs; i++)
					  {
						  if (!Allocated[i]){ // check only unallocated PRB's
							  for(int j=0; j < users->size (); j++)
							  {
								  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
										  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
									  if (bestMetric < metrics[i][j]){
										  selectedPRB = i;
										  selectedUser = j;
										  bestMetric = metrics[i][j];
									  }
							  }

						  }
					  }
					  // Now start allocating for the selected user at the selected PRB the required blocks
					  // using how many PRB's are needed for the user
					  if (selectedUser != -1)
					  {
						  scheduledUser = users->at(selectedUser);
						  //scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
						  m_mouan[selectedUser]++;
						  Allocated[selectedPRB] = true;
						  left =  selectedPRB - 1;
						  right = selectedPRB + 1;
						  availableRBs--;
						  unallocatedUsers--;

						  allocationMade = true;
						  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
						  { // search right and left of initial allocation
							  allocationMade = false;
							  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
								  break; // nothing is available, since we need to have contiguous allocation

							  if (    (right < nbOfRBs) && (! Allocated[right]) &&
									  (
											  ((left >=0) &&
											  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
											  || (left < 0) || Allocated[left]// OR no more left
									  )
								)
							  {
								  //Allocate PRB at right to the user
								  Allocated[right] = true;
								  //scheduledUser->m_listOfAllocatedRBs.push_back (right);
								  m_mouan[selectedUser]++;
								  right++;
								  allocationMade = true;
								  availableRBs--;
							  } else if ( (left >=0) && (! Allocated[left]) &&
										  (
											  ((right < nbOfRBs) &&
											  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
											  || (right >= nbOfRBs) || Allocated[right]// OR no more right
										   )
										)
							  {
								  //Allocate PRB at left to the user
								  Allocated[left] = true;
								  //scheduledUser->m_listOfAllocatedRBs.push_back (left);
								  m_mouan[selectedUser]++;
								  left--;
								  allocationMade = true;
								  availableRBs--;
							  }
						  } // end of for
						  
						  if(scheduledUser->m_userToSchedule->GetIDNetworkNode()==ue->GetIDNetworkNode()){
							ueat=selectedUser;
							printf("selected user %d is ueat\n",ueat);//test
						  }
					  } else { // nothing to do exit the allocation loop
						  break;
					  }
				  }//end while
				  if(m_mouan[ueat]>compare[0]){
					compare[0]=m_mouan[ueat];//bus vs ue
					selected_bus_id=selectedbus->GetIDNetworkNode();
				  }
		  }//end for
std::cout<<"bus vs ue end"<<std::endl;//test
		  //bus vs bs

		  {
			//ENodeB *targetenb=nm->GetENodeBByID(targetNode->GetIDNetworkNode());
			std::vector<int> buscqi=targetenb->GetUserEquipmentRecord(selected_bus_id)->GetCQI();
			/*std::vector<double> spectralEfficiency;
			//std::vector<int> cqiFeedbacks = ueRecord->GetCQI ();
			int numberOfCqi = uecqi.size ();
			for (int i = 0; i < numberOfCqi; i++)
			{
			  double sEff = GetMacEntity ()->GetAmcModule ()->GetEfficiencyFromCQI (uecqi.at (i));
			  spectralEfficiency.push_back (sEff);//i didn't do * 180000.0,because just for compare
			}*/

			//copy start (from enhance-uplink-scheduler.cpp)
			UplinkPacketScheduler *ulps=targetenb->GetULScheduler();

			UplinkPacketScheduler::UsersToSchedule *users = ulps->GetUsersToSchedule();
			UplinkPacketScheduler::UserToSchedule* scheduledUser;
			int nbOfRBs = ulps->GetMacEntity()->GetDevice ()->GetPhy ()->GetBandwidthManager ()->GetUlSubChannels ().size ();

			int availableRBs;     // No of RB's not allocated
			int unallocatedUsers; // No of users who remain unallocated
			int selectedUser;     // user to be selected for allocation
			int selectedPRB;      // PRB to be selected for allocation
			double bestMetric;    // best metric to identify user/RB combination
			int left, right;      // index of left and left PRB's to check
			bool Allocated[nbOfRBs];
			bool allocationMade;
			double metrics[nbOfRBs][users->size ()];
			int requiredPRBs[users->size ()];
			//std::vector<int> m_mouan;
			int m_mouan[users->size()];
			int busat;
			for(int i=0;i<users->size();i++)m_mouan[i]=0;


			//Some initialization
			availableRBs = nbOfRBs;
			unallocatedUsers = users->size ();
			for(int i=0; i < nbOfRBs; i++)
				Allocated[i] = false;

			//create a matrix of flow metrics
			for (int i = 0; i < nbOfRBs; i++)
			{
				for (int j = 0; j < users->size (); j++)
				{
					//metrics[i][j] = ComputeSchedulingMetric (users->at (j), i);
					double spectralEfficiency = ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (buscqi.at(i));
					metrics[i][j] = spectralEfficiency * 180000;
				}
			}

			//create number of required PRB's per scheduled users
			for(int j=0; j < users->size(); j++)
			{
				scheduledUser = users->at(j);

				std::vector<double> sinrs;
				for (std::vector<int>::iterator c = scheduledUser->m_channelContition.begin ();
						c != scheduledUser->m_channelContition.end (); c++)
				{
					//cout << *c <<" ";
					sinrs.push_back (ulps->GetMacEntity ()->GetAmcModule ()->GetSinrFromCQI (*c));
				}


				double effectiveSinr =  GetEesmEffectiveSinr (sinrs);

				int mcs = ulps->GetMacEntity ()->GetAmcModule ()->GetMCSFromCQI (
					  ulps->GetMacEntity ()->GetAmcModule ()->GetCQIFromSinr (effectiveSinr));
				//scheduledUser->m_selectedMCS = mcs;
				requiredPRBs[j] = (floor) (scheduledUser->m_dataToTransmit /
						  (ulps->GetMacEntity ()->GetAmcModule ()->GetTBSizeFromMCS (mcs, 1) / 8));
			}

			  //RBs allocation

			  while(availableRBs > 0 && unallocatedUsers > 0) //
			  {
				  // First step: find the best user-RB combo
				  selectedPRB = -1;
				  selectedUser = -1;
				  bestMetric = (double) (-(1<<30));

				  for(int i=0; i < nbOfRBs; i++)
				  {
					  if (!Allocated[i]){ // check only unallocated PRB's
						  for(int j=0; j < users->size (); j++)
						  {
							  if ( users->at (j)->m_listOfAllocatedRBs.size() == 0
									  && requiredPRBs[j] > 0) //only unallocated users requesting some RB's
								  if (bestMetric < metrics[i][j]){
									  selectedPRB = i;
									  selectedUser = j;
									  bestMetric = metrics[i][j];
								  }
						  }

					  }
				  }
				  // Now start allocating for the selected user at the selected PRB the required blocks
				  // using how many PRB's are needed for the user
				  if (selectedUser != -1)
				  {
					  scheduledUser = users->at(selectedUser);
					  //scheduledUser->m_listOfAllocatedRBs.push_back (selectedPRB);
					  m_mouan[selectedUser]++;
					  Allocated[selectedPRB] = true;
					  left =  selectedPRB - 1;
					  right = selectedPRB + 1;
					  availableRBs--;
					  unallocatedUsers--;

					  allocationMade = true;
					  for(int i = 1; i < requiredPRBs[selectedUser] && availableRBs > 0 && allocationMade; i++ )
					  { // search right and left of initial allocation
						  allocationMade = false;
						  if (left >=0 && Allocated[left] && right < nbOfRBs && Allocated[right])
							  break; // nothing is available, since we need to have contiguous allocation

						  if (    (right < nbOfRBs) && (! Allocated[right]) &&
								  (
										  ((left >=0) &&
										  (metrics[right][selectedUser] >= metrics[left][selectedUser])) // right is better than left
										  || (left < 0) || Allocated[left]// OR no more left
								  )
							)
						  {
							  //Allocate PRB at right to the user
							  Allocated[right] = true;
							  //scheduledUser->m_listOfAllocatedRBs.push_back (right);
							  m_mouan[selectedUser]++;
							  right++;
							  allocationMade = true;
							  availableRBs--;
						  } else if ( (left >=0) && (! Allocated[left]) &&
									  (
										  ((right < nbOfRBs) &&
										  (metrics[left][selectedUser] > metrics[right][selectedUser])) //left better than right
										  || (right >= nbOfRBs) || Allocated[right]// OR no more right
									   )
									)
						  {
							  //Allocate PRB at left to the user
							  Allocated[left] = true;
							  //scheduledUser->m_listOfAllocatedRBs.push_back (left);
							  m_mouan[selectedUser]++;
							  left--;
							  allocationMade = true;
							  availableRBs--;
						  }
					  } // end of for
					  
					  if(scheduledUser->m_userToSchedule->GetIDNetworkNode()==selected_bus_id){
						busat=selectedUser;
						printf("selected bus %d is busat\n",busat);//test
					  }
				  } else { // nothing to do exit the allocation loop
					  break;
				  }
			  } //while
				//copy end
			  if(compare[0]>m_mouan[busat]){
				  compare[0]=m_mouan[busat];
			  }
				//compare[1]=m_mouan[ueat];//m_mouan[ueat];//bs vs ue result
		  }
		  if(compare[0]>compare[1]){//using bs
			  if(ue->GetTargetNode()->GetIDNetworkNode()==targetenb->GetIDNetworkNode()){
				  return false;
			  }
			  else{
				  m_target=nm->GetNetworkNodeByID(targetenb->GetIDNetworkNode());
				  //std::cout<<"HO TRUE"<<std::endl;//test

				  NetworkNode* newTagertNode = m_target;

		#ifdef HANDOVER_DEBUG
				  std::cout << "** HO ** \t time: " << time << " user " <<  ue->GetIDNetworkNode () <<
        				  " old eNB " << targetNode->GetIDNetworkNode () <<
        				  " new eNB " << newTagertNode->GetIDNetworkNode () << std::endl;
		#endif
				  double time=0;
				  nm->HandoverProcedure(time, ue, targetNode, newTagertNode);

				  return true;
			  }
		  }
		  else{//using bus
			  if(ue->GetTargetNode()->GetIDNetworkNode()==selected_bus_id){
				  return false;
			  }
			  else{
				  m_target=nm->GetNetworkNodeByID(selected_bus_id);
				  //std::cout<<"HO TRUE"<<std::endl;//test
				  
				  NetworkNode* newTagertNode = m_target;

		#ifdef HANDOVER_DEBUG
				  std::cout << "** HO ** \t time: " << time << " user " <<  ue->GetIDNetworkNode () <<
        				  " old eNB " << targetNode->GetIDNetworkNode () <<
        				  " new eNB " << newTagertNode->GetIDNetworkNode () << std::endl;
		#endif
				  double time=0;
				  nm->HandoverProcedure(time, ue, targetNode, newTagertNode);

				  return true;
			  }
		  }
		  //std::cout<<"enb vs bus end"<<std::endl;//test
	/*}
	else{//default bus route
		;
	}

  double TXpower = 10 * log10 (
		  pow (10., (targetNode->GetPhy()->GetTxPower() - 30)/10)
		  /
		  targetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
  double pathLoss = ComputePathLossForInterference(targetNode, ue);

  double targetRXpower = TXpower - pathLoss;
  double RXpower;


  std::vector<ENodeB*> *listOfNodes = NetworkManager::Init ()->GetENodeBContainer ();
  std::vector<ENodeB*>::iterator it;
  for (it = listOfNodes->begin (); it != listOfNodes->end (); it++)
    {
	  if ((*it)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it);

	      TXpower = 10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );
	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  std::vector<HeNodeB*> *listOfNodes2 = NetworkManager::Init ()->GetHomeENodeBContainer();
  std::vector<HeNodeB*>::iterator it2;
  for (it2 = listOfNodes2->begin (); it2 != listOfNodes2->end (); it2++)
    {
	  if ((*it2)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
	    {

	      NetworkNode *probableNewTargetNode = (*it2);

	      TXpower =   10 * log10 (
				  pow (10., (probableNewTargetNode->GetPhy()->GetTxPower() - 30)/10)
				  /
				  probableNewTargetNode->GetPhy()->GetBandwidthManager()->GetDlSubChannels().size () );

	      pathLoss = ComputePathLossForInterference(probableNewTargetNode, ue);

	      RXpower = TXpower - pathLoss;

	      if (RXpower > targetRXpower)
	        {
	    	  if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
	    	  {
		    	  targetRXpower = RXpower;
			      targetNode = probableNewTargetNode;
	    	  }
	        }
	    }
    }

  if (ue->GetTargetNode ()->GetIDNetworkNode () != targetNode->GetIDNetworkNode ())
    {
	  m_target = targetNode;
	  return true;
    }
  else
    {
	  return false;
    }*/
}
示例#21
0
void NetworkPlan::extractLayers() {
	int size = 0;
	int size2 = 0;
	int size3 = 0;
	vector<NetworkNode*>* curLayer = new vector<NetworkNode*>();
	vector<NetworkNode*>* nextLayer = NULL;
	NetworkNode* tmpNode = NULL;
	NetworkNode* tmpNode2 = NULL;
	bool noMoreIncoming = false;
	bool isFirst = true;
	bool finishAdded = false;

	while (true) {
		if (isFirst) {
			curLayer->push_back(_S);
			_layers->push_back(curLayer);

			isFirst = false;
		} else if (finishAdded) break;

		nextLayer = new vector<NetworkNode*>(); 
		size = curLayer->size();

		// Исключаем исходящие ссылки из узлов текущего слоя.
		for (int j = 0; j < size; j++) {
			tmpNode = curLayer->at(j);
			size2 = tmpNode->getOutgoingLinks()->size();

			for (int k = 0; k < size2; k++) {
				tmpNode->getOutgoingLinks()->at(k)->excluded = true;
			}
		}

		// Проверяем, есть ли другие входящие работы для узлов,
		// являющихся следующими для узлов текущего слоя.
		for (int j = 0; j < size; j++) {
			tmpNode = curLayer->at(j);
			size2 = tmpNode->getOutgoingLinks()->size();

			for (int k = 0; k < size2; k++) {
				tmpNode2 = tmpNode->getOutgoingLinks()->at(k)->dst;
				size3 = tmpNode2->getIncomingLinks()->size();
				noMoreIncoming = true;

				for (int l = 0; l < size3; l++) {
					if (tmpNode2->getIncomingLinks()->at(l)->excluded != true) {
						noMoreIncoming = false;

						break;
					}
				}

				// Если для узла нет работ, не отмеченных как исключённые,
				// и он не добавлен в следующий слой, добавляем.
				if (noMoreIncoming
					&& find(nextLayer->begin(), nextLayer->end(), tmpNode2) == nextLayer->end()) {
						nextLayer->push_back(tmpNode2);

						if (tmpNode2 == _F) finishAdded = true;
				}
			}
		}

		_layers->push_back(nextLayer);

		curLayer = nextLayer;
	}
}
示例#22
0
void
Manhattan::UpdatePosition (double timestamp)
{
#ifdef MOBILITY_DEBUG
//	cout << "\t START MOBILITY MODEL for "<< GetNodeID () << endl;
#endif

  if (GetSpeed () == 0)
    {
#ifdef MOBILITY_DEBUG
	cout << "\t\t speed = 0 --> position has not been updated!"<< endl;
#endif
      return;
    }

  double timeInterval = timestamp - GetPositionLastUpdate ();
  double speedDirection;

  UserEquipment *thisNode = NetworkManager::Init ()->GetUserEquipmentByID (GetNodeID ());
  Cell *thisCell = thisNode->GetCell ();


  NetworkNode *targetNode = thisNode->GetTargetNode ();

#ifdef MOBILITY_DEBUG
	cout << "MOBILITY_DEBUG: User ID: " << GetNodeID ()
	    << "\n\t Cell ID " <<
					NetworkManager::Init()->GetCellIDFromPosition (GetAbsolutePosition()->GetCoordinateX(),
																   GetAbsolutePosition()->GetCoordinateY())
		<< "\n\t Initial Position (X): " << GetAbsolutePosition()->GetCoordinateX()
		<< "\n\t Initial Position (Y): " << GetAbsolutePosition()->GetCoordinateY()
		<< "\n\t Speed: " << GetSpeed()
		<< "\n\t Speed Direction: " << GetSpeedDirection()
		<< "\n\t Time Last Update: " << GetPositionLastUpdate()
		<< "\n\t Time Interval: " << timeInterval
		<< endl;
#endif
#ifdef MOBILITY_DEBUG_TAB
	cout <<  GetNodeID () << " "
		<< GetAbsolutePosition()->GetCoordinateX() << " "
		<< GetAbsolutePosition()->GetCoordinateY() << " "
		<< GetSpeed() << " "
		<< GetSpeedDirection() << " "
		<< GetPositionLastUpdate() << " "
		<< timeInterval << " "
		<< "-> ";
#endif
	const double pi = 3.14;

//  Init speedDirection if its not pointing into the direction of Manhattans Streets
	vector<double> directions;
	for(int i=0;i<=3;i++) {
	  directions.push_back(i * 1.57); // 1.57 = 90.0 * ((2.0*pi)/360.0))
	}

	double newdir;
	vector<double>::iterator it;
	it = find(directions.begin(), directions.end(), GetSpeedDirection());

	if(it == directions.end()) {
	  newdir = (double)(pi / 2) * round(GetSpeedDirection() * (double)(2 / pi));
	  if(newdir==6.28) newdir = 0;
	  SetSpeedDirection(newdir);
#ifdef MOBILITY_DEBUG_TAB
	  cout << "NEW SPEED-DIRECTION: " << newdir << " -> ";
#endif
	}

	double shift = timeInterval * (GetSpeed()*(1000.0/3600.0));

	CartesianCoordinates *newPosition = new CartesianCoordinates(GetAbsolutePosition()->GetCoordinateX(), GetAbsolutePosition()->GetCoordinateY());
	CartesianCoordinates *ENodeBPosition = targetNode->GetMobilityModel ()->GetAbsolutePosition ();

// Init Manhattan grid position
  if(fmod(GetAbsolutePosition()->GetCoordinateY(),100)!=0 && fmod(GetAbsolutePosition()->GetCoordinateX(),100)!=0){
	CartesianCoordinates *Correction = new CartesianCoordinates();
	double distfromEnB = newPosition->GetDistance (ENodeBPosition);
	double azim = newPosition->GetPolarAzimut (ENodeBPosition);

	//if it was randomly put outside the cell -> shift it inside
	if(distfromEnB > (thisCell->GetRadius()*1000)) {
	  Correction->SetCoordinates((newPosition->GetDistance (ENodeBPosition) - (thisCell->GetRadius()*1000)) * cos(azim),
			  (newPosition->GetDistance (ENodeBPosition) - (thisCell->GetRadius()*1000)) * sin(azim));
	  newPosition->SetCoordinates(newPosition->GetCoordinateX() - Correction->GetCoordinateX(),
			  newPosition->GetCoordinateY() - Correction->GetCoordinateY());
	}
	delete Correction;


	if(GetSpeedDirection()==0 || GetSpeedDirection()==3.14) {
			  if(newPosition->GetCoordinateY() < 0)
				  newPosition->SetCoordinateY( ceil( (double)(newPosition->GetCoordinateY() / 100) ) * 100);
			  else
				  newPosition->SetCoordinateY( floor( (double)(newPosition->GetCoordinateY() / 100) ) * 100);
		  }
	else {
			  if(newPosition->GetCoordinateX() < 0)
				  newPosition->SetCoordinateX( ceil( (double)(newPosition->GetCoordinateX() / 100)) * 100);
			  else
				  newPosition->SetCoordinateX( floor( (double)(newPosition->GetCoordinateX() / 100) ) * 100);
	}
  }

//Shift it
  double shift_x = shift * cos(GetSpeedDirection());
  double shift_y = shift * sin(GetSpeedDirection());
  if(GetSpeedDirection()==0 || GetSpeedDirection()==3.14) {
	  newPosition->SetCoordinateX(newPosition->GetCoordinateX()+shift_x);
  }
  else {
	  newPosition->SetCoordinateY(newPosition->GetCoordinateY()+shift_y);
  }

// if a node reaches a crossing, choose new speedDirection
  double old_x = abs( ((int)( GetAbsolutePosition()->GetCoordinateX() *1000))/1000.0 ); //cut after 3 decimal places
  double new_x = abs( ((int)( newPosition->GetCoordinateX() *1000))/1000.0 );
  double old_y = abs( ((int)( GetAbsolutePosition()->GetCoordinateY() *1000))/1000.0 );
  double new_y = abs( ((int)( newPosition->GetCoordinateY() *1000))/1000.0 );
  double rounded_x = abs( round(old_x/100)*100 );
  double rounded_y = abs( round(old_y/100)*100 );

  if( ((old_x<rounded_x && rounded_x<=new_x) || (old_x>rounded_x && rounded_x>=new_x)) ||
		  ((old_y<rounded_y && rounded_y<=new_y) || (old_y>rounded_y && rounded_y>=new_y)) ||
		  (rounded_x==0 && old_x<rounded_x && rounded_x<=new_x) || (rounded_x==0 && old_x>rounded_x && rounded_x>=new_x) ||
		  (rounded_y==0 && old_y<rounded_y && rounded_y<=new_y) || (rounded_y==0 && old_y>rounded_y && rounded_y>=new_y) )
  {
	  srand ( time(NULL) );
	  double prob_turn = (rand()%100)*0.01;
	  if(prob_turn<=0.25) {
		  speedDirection = GetSpeedDirection() + 1.57; //turn left;
		  newPosition->SetCoordinates(round(newPosition->GetCoordinateX()),round(newPosition->GetCoordinateY()));
#ifdef MOBILITY_DEBUG_TAB
		  cout << "TURN LEFT: " << speedDirection << " -> ";
#endif
	  }
	  if(prob_turn>0.25 && prob_turn<0.75) {
		  newPosition->SetCoordinates(round(newPosition->GetCoordinateX()),round(newPosition->GetCoordinateY()) );
		  speedDirection = GetSpeedDirection();
#ifdef MOBILITY_DEBUG_TAB
		  cout << "no TURN: straight -> ";
#endif
	  }
	  if(prob_turn>=0.75) {
		  newPosition->SetCoordinates(round(newPosition->GetCoordinateX()),round(newPosition->GetCoordinateY()) );
		  speedDirection = GetSpeedDirection() - 1.57;
#ifdef MOBILITY_DEBUG_TAB
		  cout << "TURN RIGHT: " << speedDirection << " -> ";
#endif
	  }

	  //Correction if speedDirection €! [0,2pi[
	  if(speedDirection>=2*pi) speedDirection -= 2*pi;
	  if(speedDirection<0) speedDirection += 2*pi;
	  SetSpeedDirection(speedDirection);
  }



//If node moves beyond the cell edge
  double azimut = newPosition->GetPolarAzimut (ENodeBPosition);
  double newDistanceFromTheENodeB = newPosition->GetDistance (ENodeBPosition);

  if (newDistanceFromTheENodeB >= (thisCell->GetRadius()*1000))
    {
	  if (GetHandover()== false)
		{
		  newPosition->SetCoordinateX(GetAbsolutePosition()->GetCoordinateX());
		  newPosition->SetCoordinateY(GetAbsolutePosition()->GetCoordinateY());

		  speedDirection = GetSpeedDirection() - pi;
#ifdef MOBILITY_DEBUG_TAB
		  cout << "Moved back to cell: SPEED DIRECTION CHANGE (HO): " << speedDirection << " -> ";
#endif
		  if(speedDirection<0) speedDirection = speedDirection + 2*pi;
		  SetSpeedDirection(speedDirection);
		}
	  else if (newPosition->GetDistance(0.0, 0.0) >= GetTopologyBorder ())
	      {
		  newPosition->SetCoordinateX(GetAbsolutePosition()->GetCoordinateX());
		  newPosition->SetCoordinateY(GetAbsolutePosition()->GetCoordinateY());

		  speedDirection = GetSpeedDirection() - 1.57;
#ifdef MOBILITY_DEBUG_TAB
		  cout << "Moved back to cell: SPEED DIRECTION CHANGE (TOPOLOGY-BORDER): " << speedDirection << " -> ";
#endif
		  if(speedDirection<0) speedDirection = speedDirection + 2*pi;
		  SetSpeedDirection(speedDirection);
	      }
    }

  SetAbsolutePosition(newPosition);
  SetPositionLastUpdate (timestamp);

#ifdef MOBILITY_DEBUG
  cout << "\n\t Final Position (X): " << GetAbsolutePosition()->GetCoordinateX()
			<< "\n\t Final Position (Y): " << GetAbsolutePosition()->GetCoordinateY()
			<< endl;
#endif
#ifdef MOBILITY_DEBUG_TAB
  cout << GetAbsolutePosition()->GetCoordinateX() << " "
			<< GetAbsolutePosition()->GetCoordinateY() << " " << GetSpeedDirection()
			<< endl;
#endif
  delete newPosition;
}
bool
PositionBasedHoManager::CheckHandoverNeed (UserEquipment* ue)
{
    NetworkNode *targetNode = ue->GetTargetNode ();

    CartesianCoordinates *uePosition = ue->GetMobilityModel ()->GetAbsolutePosition ();
    CartesianCoordinates *targetPosition;

    targetPosition = targetNode->GetMobilityModel ()->GetAbsolutePosition ();
    double targetDistance = uePosition->GetDistance (targetPosition);

    /*
    if (targetDistance <= (ue->GetCell ()->GetRadius () * 0.8))
      {
      return false;
      }
    */

    std::vector<ENodeB*> *listOfNodes = NetworkManager::Init ()->GetENodeBContainer ();
    std::vector<ENodeB*>::iterator it;
    for (it = listOfNodes->begin (); it != listOfNodes->end (); it++)
    {
        if ((*it)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
        {

            NetworkNode *probableNewTargetNode = (*it);


            double distance = probableNewTargetNode->GetMobilityModel ()->
                              GetAbsolutePosition ()->GetDistance (uePosition);

            if (distance < targetDistance)
            {
                if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
                {
                    targetDistance = distance;
                    targetNode = probableNewTargetNode;
                }
            }
        }
    }
    std::vector<HeNodeB*> *listOfNodes2 = NetworkManager::Init ()->GetHomeENodeBContainer();
    std::vector<HeNodeB*>::iterator it2;
    for (it2 = listOfNodes2->begin (); it2 != listOfNodes2->end (); it2++)
    {
        if ((*it2)->GetIDNetworkNode () != targetNode->GetIDNetworkNode () )
        {

            NetworkNode *probableNewTargetNode = (*it2);


            double distance = probableNewTargetNode->GetMobilityModel ()->
                              GetAbsolutePosition ()->GetDistance (uePosition);

            if (distance < targetDistance)
            {
                if (NetworkManager::Init()->CheckHandoverPermissions(probableNewTargetNode,ue))
                {
                    targetDistance = distance;
                    targetNode = probableNewTargetNode;
                }
            }
        }
    }

    if (ue->GetTargetNode ()->GetIDNetworkNode () != targetNode->GetIDNetworkNode ())
    {
        m_target = targetNode;
        return true;
    }
    else
    {
        return false;
    }
}
示例#24
0
int main(int argc, char ** argv) {

	float startupTime = cv::getTickCount();

	BlackLib::BlackGPIO* gpios[6];
	/* Loading pin */
	gpios[0] = new BlackLib::BlackGPIO(BlackLib::GPIO_80, BlackLib::output,
			BlackLib::FastMode);
	/* Acquisition pin */
	gpios[1] = new BlackLib::BlackGPIO(BlackLib::GPIO_79, BlackLib::output,
			BlackLib::FastMode);
	/* Detection pin */
	gpios[2] = new BlackLib::BlackGPIO(BlackLib::GPIO_77, BlackLib::output,
			BlackLib::FastMode);
	/* Extraction pin */
	gpios[3] = new BlackLib::BlackGPIO(BlackLib::GPIO_75, BlackLib::output,
			BlackLib::FastMode);
	/* Coding pin */
	gpios[4] = new BlackLib::BlackGPIO(BlackLib::GPIO_73, BlackLib::output,
			BlackLib::FastMode);
	/* Transmission pin */
	gpios[5] = new BlackLib::BlackGPIO(BlackLib::GPIO_71, BlackLib::output,
			BlackLib::FastMode);

	gpios[0]->setValue(BlackLib::high); //Set loading pin
	gpios[1]->setValue(BlackLib::low);  //Reset acquisition pin
	gpios[2]->setValue(BlackLib::low);  //Reset detection pin
	gpios[3]->setValue(BlackLib::low);  //Reset extraction pin
	gpios[4]->setValue(BlackLib::low);  //Reset coding pin
	gpios[5]->setValue(BlackLib::low);  //Reset transmission pin

	/**
	 * Command line arguments parser
	 */
	NodeType nodeType = NODETYPE_UNDEF;
	string telosDevPath, networkConfigPath;

	vector<string> remoteIps;
	vector<uint16_t> remotePorts;
	vector<uint16_t> localPorts;

	uint8_t nodeId = 0;
	int cameraId = 0;
	string objPath = "";
	string pklotPath = "";
	string fallbackPath = "";
	bool cameraFlip = false;
	bool nodeIdFound = false;

	bool oneShot = false;
	string mode = "cta";
	int ctaQf = 100;
	int ctaSlices = 1;
	int atcDetTh = 60;
	int atcNumfeat = 40;
	int atcBinShift = 0;
	int atcValShift = 0;

	try {

		TCLAP::CmdLine cmd("GreenEyes Testbed", ' ', "2.0");

		vector<string> nodeTypeArgValues;
		nodeTypeArgValues.push_back("sink");
		nodeTypeArgValues.push_back("camera");
		nodeTypeArgValues.push_back("cooperator");
		TCLAP::ValuesConstraint<string>* nodeTypeArgValuesAllowed =
				new TCLAP::ValuesConstraint<string>(nodeTypeArgValues);

		/* Positional arguments */
		TCLAP::UnlabeledValueArg<string> nodeTypeArg("type", "Node type", true,
				"null", "string", nodeTypeArgValuesAllowed);
		cmd.add(nodeTypeArg);

		TCLAP::UnlabeledValueArg<int> nodeIdArg("id", "Node id", true, -1,
				"int");
		cmd.add(nodeIdArg);

		/* Non positional arguments */
		TCLAP::ValueArg<string> networkConfigArg("", "network-config",
				"Network configuration path", false, "network_config.xml",
				"string");
		cmd.add(networkConfigArg);

		TCLAP::ValueArg<string> telosDevPathArg("", "telos",
				"Telos device path", false, "null", "string");
		cmd.add(telosDevPathArg);

		TCLAP::ValueArg<int> cameraIdArg("", "camera-id", "Camera device id",
				false, 0, "int");
		cmd.add(cameraIdArg);

		TCLAP::ValueArg<string> objPathArg("", "obj-path",
				"Recorded objects file path", false, "", "string");
		cmd.add(objPathArg);

		TCLAP::ValueArg<string> pklotPathArg("", "pklot-path",
				"Recorded pklot file path", false, "", "string");
		cmd.add(pklotPathArg);

		TCLAP::ValueArg<string> fallbackPathArg("", "fallback-path",
				"Recorded fallback file path", false, "", "string");
		cmd.add(fallbackPathArg);

		TCLAP::SwitchArg cameraFlipArg("", "camera-flip",
				"Camera horizontal flip", false);
		cmd.add(cameraFlipArg);

		/* One-shot non positional arguments */
		TCLAP::SwitchArg oneShotArg("", "oneshot", "Enable One-shot mode",
				false);
		cmd.add(oneShotArg);

		vector<string> oneshotModeArgValues;
		oneshotModeArgValues.push_back("atc-object");
		oneshotModeArgValues.push_back("atc-pklot");
		oneshotModeArgValues.push_back("cta");
		TCLAP::ValuesConstraint<string>* oneshotModeArgValuesAllowed =
				new TCLAP::ValuesConstraint<string>(oneshotModeArgValues);
		TCLAP::ValueArg<string> modeTypeArg("", "mode", "One-shot mode", false,
				"null", oneshotModeArgValuesAllowed);
		cmd.add(modeTypeArg);

		TCLAP::ValueArg<int> ctaQfArg("", "qf", "CTA quality factor", false, 20,
				"int");
		cmd.add(ctaQfArg);

		TCLAP::ValueArg<int> ctaSlicesArg("", "slices", "CTA slices", false, 5,
				"int");
		cmd.add(ctaSlicesArg);

		TCLAP::ValueArg<int> atcThArg("", "det-th", "ATC detection threshold",
				false, 60, "int");
		cmd.add(atcThArg);

		TCLAP::ValueArg<int> atcFeatArg("", "num-feat",
				"ATC number of features", false, 20, "int");
		cmd.add(atcFeatArg);

		TCLAP::ValueArg<int> atcBinShiftArg("", "bin-shift",
				"ATC PKLot bin shift", false, 0, "int");
		cmd.add(atcBinShiftArg);

		TCLAP::ValueArg<int> atcValShiftArg("", "val-shift",
				"ATC PKLot val shift", false, 0, "int");
		cmd.add(atcValShiftArg);

		/* Parse the argv array. */
		cmd.parse(argc, argv);

		if (nodeTypeArg.getValue() == "sink") {
			nodeType = NODETYPE_SINK;
		} else if (nodeTypeArg.getValue() == "camera") {
			nodeType = NODETYPE_CAMERA;
		} else {
			nodeType = NODETYPE_COOPERATOR;
		}
		nodeId = nodeIdArg.getValue();
		cameraId = cameraIdArg.getValue();
		objPath = objPathArg.getValue();
		pklotPath = pklotPathArg.getValue();
		fallbackPath = fallbackPathArg.getValue();
		telosDevPath = telosDevPathArg.getValue();
		networkConfigPath = networkConfigArg.getValue();
		cameraFlip = cameraFlipArg.getValue();

		oneShot = oneShotArg.getValue();
		mode = modeTypeArg.getValue();
		ctaQf = ctaQfArg.getValue();
		ctaSlices = ctaSlicesArg.getValue();
		atcDetTh = atcThArg.getValue();
		atcNumfeat = atcFeatArg.getValue();
		atcBinShift = atcBinShiftArg.getValue();
		atcValShift = atcValShiftArg.getValue();

	} catch (TCLAP::ArgException &e) {
		cerr << "Parser error: " << e.error() << " for arg " << e.argId()
				<< endl;
	}

	/*
	 * Network config parser
	 */
	tinyxml2::XMLDocument* xmlDoc = new tinyxml2::XMLDocument();
	xmlDoc->LoadFile(networkConfigPath.c_str());
	if (xmlDoc->Error()) {
		cerr << "Main: xmlDoc error: " << xmlDoc->GetErrorStr1() << endl;
		exit(-1);
	}
	tinyxml2::XMLElement* xmlNetwork = xmlDoc->FirstChildElement("network");

	/*
	 * Parse network items to find the identity of this node and the connection parameters to the server(s)
	 */
	tinyxml2::XMLElement* xmlItem = xmlNetwork->FirstChildElement("item");
	while (xmlItem) {
		const char* itemEnabled = xmlItem->Attribute("enabled");
		if (itemEnabled == NULL || !strcmp(itemEnabled, "1")) {
			/* Item enabled or not specified */

			const char* itemClassStr = xmlItem->Attribute("class");
			string itemClass(itemClassStr);

			const char* itemIdStr = xmlItem->Attribute("id");
			uint8_t itemId = itemIdStr ? atoi(itemIdStr) : 0;

			const char* itemAmAddrStr = xmlItem->Attribute("am_address");
			uint16_t itemAmAddr = itemAmAddrStr ? atoi(itemAmAddrStr) : 0;

			const char* itemIpAddr = xmlItem->Attribute("ip_address");
			const char* itemIpPortServerStr = xmlItem->Attribute(
					"ip_port_server");
			uint16_t itemIpPortServer =
					itemIpPortServerStr ? atoi(itemIpPortServerStr) : -1;

			if (itemClass == "gui") {
				/* The gui is relevant only for the SINK node */
				if (nodeType == NODETYPE_SINK) {
					NetworkNode::setGui(itemIpAddr, itemIpPortServer);
					remoteIps.push_back(itemIpAddr);
					remotePorts.push_back(itemIpPortServer);
				}
			} else if (itemClass == "sink") {
				/* The sink node is relevant only for SINK and CAMERA nodes */
				switch (nodeType) {
				case NODETYPE_SINK:
					NetworkNode::setMyself(
							NetworkNode::setSink(itemId, itemAmAddr, itemIpAddr,
									itemIpPortServer));
					nodeIdFound = true;
					break;
				case NODETYPE_CAMERA:
					NetworkNode::setSink(itemId, itemAmAddr, itemIpAddr,
							itemIpPortServer);
					remoteIps.push_back(itemIpAddr);
					remotePorts.push_back(itemIpPortServer);
					break;
				default:
					break;
				}
			} else if (itemClass == "camera") {
				/* The camera node is relevant only for SINK, CAMERA with the same id and for COOPERATORs */
				switch (nodeType) {
				case NODETYPE_SINK:
					NetworkNode::addCamera(itemId, itemAmAddr, itemIpAddr,
							itemIpPortServer);
					break;
				case NODETYPE_CAMERA:
					if (nodeId == itemId) {
						NetworkNode::setMyself(
								NetworkNode::addCamera(itemId, itemAmAddr,
										itemIpAddr, itemIpPortServer));
						nodeIdFound = true;
					}
					break;
				case NODETYPE_COOPERATOR:
					NetworkNode::addCamera(itemId, itemAmAddr, itemIpAddr,
							itemIpPortServer);
					/* Not adding the camera port here since not all the cooperators connect to all the cameras. Links are parsed later on */
					break;
				default:
					break;
				}
			} else if (itemClass == "cooperator") {
				/* The cooperator node is only relevant for the COOPERATOR with the same id */
				switch (nodeType) {
				case NODETYPE_COOPERATOR:
					if (nodeId == itemId) {
						NetworkNode::setMyself(
								NetworkNode::addCooperator(itemId));
						nodeIdFound = true;
					}
					break;
				default:
					break;
				}
			}
			xmlItem = xmlItem->NextSiblingElement("item");
		}
	}

	/*
	 * If this is a COOPERATOR node parse the links to find to which cameras connect
	 */
	if (nodeType == NODETYPE_COOPERATOR) {
		tinyxml2::XMLElement* xmlLink = xmlNetwork->FirstChildElement("link");
		while (xmlLink) {
			const char* itemEnabled = xmlLink->Attribute("enabled");
			if (itemEnabled == NULL || !strcmp(itemEnabled, "1")) {
				/* Item enabled or not specified */

				const char* sourceIdStr = xmlLink->Attribute("source_id");
				uint8_t sourceId = sourceIdStr ? atoi(sourceIdStr) : 0;
				const char* destIdStr = xmlLink->Attribute("dest_id");
				uint8_t destId = destIdStr ? atoi(destIdStr) : 0;

				if (sourceId == nodeId) {
					NetworkNode* camera = NetworkNode::getCameraById(destId);
					if (camera) {
						remoteIps.push_back(camera->getIpAddrString());
						remotePorts.push_back(camera->getIpPort());
					} else {
						cerr << "Main: Camera with id " << destId
								<< " not found " << endl;
						exit(-1);
					}
				}
			}
			xmlLink = xmlLink->NextSiblingElement("link");
		}
	}

	delete (xmlDoc);
	xmlDoc = NULL;

	if (!nodeIdFound) {
		cerr << "Node id not found." << endl;
		exit(1);
	}

	NetworkNode::printNetwork();

	/* Create the io_service */
	boost::asio::io_service io_service;

	/* Create the NodeNetworkSystem. Needs to be instantiated before the NodeProcessingSystem */
	NodeNetworkSystem* nodeNetworkSystem = NodeNetworkSystem::getInstance(
			io_service, remoteIps, remotePorts, telosDevPath, gpios);

	/* Determine camera parameters */
	stringstream ss;
	if (objPath.length() == 0) {
		ss.str("");
		ss << "obj/camera" << (int) nodeId << "_%04d.jpg";
		objPath = ss.str();
	}
	if (pklotPath.length() == 0) {
		ss.str("");
		ss << "pklot/camera" << (int) nodeId << "_%04d.jpg";
		pklotPath = ss.str();
	}
	if (fallbackPath.length() == 0) {
		ss.str("");
		ss << "oneshot/test_%02d.jpg";
		fallbackPath = ss.str();
	}
	CameraParameters camParms(cameraId, objPath, pklotPath, fallbackPath,
			cv::Size(640, 480), cameraFlip);

	/* Create the NodeProcessingSystem */
	NodeProcessingSystem* nodeProcessingSystem =
			NodeProcessingSystem::getInstance(nodeNetworkSystem, nodeType,
					camParms, oneShot, gpios);

	gpios[0]->setValue(BlackLib::low);  //Reset loading pin

	startupTime = (cv::getTickCount() - startupTime) / cv::getTickFrequency();
	cout << "Startup time: " << startupTime << "s" << endl;

	/* OneShot mode */
	if (oneShot) {

		cout << "One-shot Mode" << endl;
		Message* fakeStart;
		LinkType fakeStartLinkType;
		if (telosDevPath != "null") {
			fakeStartLinkType = LINKTYPE_TELOS;
		} else {
			fakeStartLinkType = LINKTYPE_TCP;
		}
		if (mode == "atc-object") {
			Bitstream emptyBitstream;
			fakeStart = (Message*) new StartATCMsg(NetworkNode::getSink(),
					NetworkNode::getMyself(), fakeStartLinkType,
					DETECTORTYPE_BRISK, atcDetTh, //Detection Threshold
					DESCRIPTORTYPE_BRISK, 256, //Description Length
					atcNumfeat, //Number of features
					true, //Rotation invariance
					true, //Keypoints encoding
					true, //Features encoding
					true, //Keypoints transfer
					true, //Scale transfer
					true, //Orientation transfer
					atcNumfeat, //Number of features per block
					cv::Size(0, 0), //topLeft
					cv::Size(640, 480), //bottomRight
					0, //binShift
					0, //valShift
					0, //numcoops
					OPERATIVEMODE_OBJECT, IMAGESOURCE_LIVE, emptyBitstream, //kpts bitstream
					80 //wifi bw
					);
		} else if (mode == "atc-pklot") {

			cv::Mat atcOneShotKeypoints = cv::imread(
					"pklot/camera_12_kptsBitstream.bmp", cv::IMREAD_UNCHANGED);
			Bitstream atcOneShotKeypointsBitstream(
					atcOneShotKeypoints.datastart, atcOneShotKeypoints.dataend);
			fakeStart = (Message*) new StartATCMsg(NetworkNode::getSink(),
					NetworkNode::getMyself(), fakeStartLinkType,
					DETECTORTYPE_NONE,
					0, //Detection Threshold (ignore)
					DESCRIPTORTYPE_HIST,
					0, //Description Length (ignored)
					0, //Number of features (ignored)
					true, //Rotation invariance
					true, //Keypoints encoding
					true, //Features encoding
					true, //Keypoints transfer
					true, //Scale transfer
					true, //Orientation transfer
					200, //Number of features per block
					cv::Size(0, 0), //top left
					cv::Size(640, 480), //bottom right
					atcBinShift, atcValShift,
					0, //Num coops
					OPERATIVEMODE_PKLOT, IMAGESOURCE_REC,
					atcOneShotKeypointsBitstream, 80 //kpbs wifibw
					);
		} else {
			fakeStart = (Message*) new StartCTAMsg(NetworkNode::getSink(),
					NetworkNode::getMyself(), fakeStartLinkType, ctaQf, // Quality factor
					cv::Size(640, 480), //Frame size
					ctaSlices, // Number of slices
					OPERATIVEMODE_OBJECT, IMAGESOURCE_LIVE, 80 //kpbs wifibw
					);
		}
		nodeProcessingSystem->queueMessage(fakeStart);
	}

	signal(SIGINT, NodeNetworkSystem::shutdown);
	signal(SIGQUIT, NodeNetworkSystem::shutdown);
	//signal(SIGABRT, NodeNetworkSystem::shutdown);
	//signal(SIGTERM, NodeNetworkSystem::shutdown);
	//signal(SIGKILL, NodeNetworkSystem::shutdown);

	/* Start the io_service */
	try {
		io_service.run();
	} catch (exception &e) {
		cerr << "Main: " << e.what() << endl;
	}

	return 0;
}