Ejemplo n.º 1
0
/**
 * Link Get Parameters Confirm message handler.
 *
 * @param in input message.
 * @param out output message.
 * @return true if the response is sent immediately or false otherwise.
 */
bool command_service::link_get_parameters_confirm(meta_message_ptr &in,
						   meta_message_ptr &out)
{
	ODTONE_LOG(1, "(mics) received Link_Get_Parameters.confirm from ",
	    in->source().to_string());

	_link_abook.reset(in->source().to_string());

	if(_lpool.set_user_tid(in)) {
		mih::status st;
		boost::optional<mih::link_param_list> lpl;
		boost::optional<mih::link_states_rsp_list> lsrl;
		boost::optional<mih::link_desc_rsp_list> ldrl;

		*in >> mih::confirm(mih::confirm::link_get_parameters)
		       & mih::tlv_status(st)
		       & mih::tlv_link_parameters_status_list(lpl)
		       & mih::tlv_link_states_rsp(lsrl)
		       & mih::tlv_link_descriptor_rsp(ldrl);

		if(st == mih::status_success) {
			mih::link_status_rsp link_status;

			link_status.states_rsp_list = lsrl.get();
			link_status.param_list = lpl.get();
			link_status.desc_rsp_list = ldrl.get();

			_lrpool.add(in->source().to_string(),
			           in->tid(),
			           link_status);
		}

		return false;
	}
Ejemplo n.º 2
0
// This message is handled by the Link SAP.
//
// If this MIHF is the destination of the message, forward it to the
// default Link SAP. If not then forward it to a peer MIHF.
bool command_service::link_actions_request(meta_message_ptr &in,
					   meta_message_ptr &out)
{
	log(1, "(mics) received a Link_Actions.request from",
	    in->source().to_string());

	if(utils::this_mihf_is_destination(in)) {
		//
		// Kick this message to MIH_Link SAP.
		//
		// The solution found to handle this corner case in the
		// 802.21 standard was to send the message, as is, to the
		// link sap.
		//
		in->destination(mih::id("link"));
		_lpool.add(in);
		in->source(mihfid);
		_transmit(in);

		return false;
	} else {
		utils::forward_request(in, _lpool, _transmit);
		return false;
	}

	return false;
}
Ejemplo n.º 3
0
// Check if there's a handler for this message and call it, else
// discard message.
void sac_dispatch::operator()(meta_message_ptr& in)
{
	/** __no__ authentication at this point */

	uint mid = in->mid();

	log(1, "(sac) dispatching message with mid: ", mid);
	//
	// no thread safety because insertion should __only__ be made
	// on MIHF initialization
	//
	std::map<uint, handler_t>::iterator it;
	it = _callbacks.find(mid);

	if(it != _callbacks.end()) {
		handler_t process_message = it->second;
		meta_message_ptr out(new meta_message);

		out->tid(in->tid());
		// send response if it was generated
		if (process_message(in, out))
		 	_transmit(out);
        } else {
		log(1, "(sac) (warning) message with mid: ", mid,
		    " unknown, discarding.");
	}
}
Ejemplo n.º 4
0
// This message is handled by the Link SAP.
//
// If this MIHF is the destination of the message, forward it to the
// default Link SAP. If not then forward it to a peer MIHF.
bool command_service::link_get_parameters_request(meta_message_ptr &in,
						  meta_message_ptr &out)
{
	log(1, "(mics) received a Link_Get_Parameters.request from",
	    in->source().to_string());


	if(utils::this_mihf_is_destination(in)) {
		//
		// Kick this message to MIH_Link SAP.
		//
		// The solution found to handle this corner case in the
		// 802.21 standard was to send the message, as is, to the
		// link sap.
		//
		// local_transactions was made to handle request's
		// from users to peer mihf's but in this case we add an
		// entry to handle the MIH_Link_Get_Parameters and
		// Link_Get_Parameters.
		//
		in->destination(mih::id("link"));
		_lpool.add(in);
		in->source(mihfid);
		_transmit(in);

		return false;
	} else {
		utils::forward_request(in, _lpool, _transmit);
		return false;
	}

	return false;
}
Ejemplo n.º 5
0
//
// Currently Command_Service messages are handled by a default local
// user. If this MIHF is the destination of the message, check for a
// pending transaction and forward the message.
//
bool command_service::generic_command_response(const char *recv_msg,
					       const char *send_msg,
					       meta_message_ptr &in,
					       meta_message_ptr &out)
{
	log(1, recv_msg, in->source().to_string());

	if(utils::this_mihf_is_destination(in)) {
		//
		// Kick this message to default MIH User as an indication
		//
		log(1, send_msg);
		in->opcode(mih::operation::confirm);
		in->destination(mih::id("user"));
		//
		// source identifier is the remote MIHF
		//
		_transmit(in);

		return false;
	} else {
		utils::forward_request(in, _lpool, _transmit);
		return false;
	}

}
Ejemplo n.º 6
0
/**
 * Check if there's a handler for this message and call it, else
 * discard message.
 *
 * @param in The input message.
 * @param out The output message.
 */
bool sac_process_message(meta_message_ptr& in, meta_message_ptr& out)
{
	// discard messages that this MIHF broadcasted to itself
	// discard messages that are not destined to this MIHF or if
	// multicast messages are not supported
	if(in->source() == mihfid) {
		ODTONE_LOG(1, "(sac) Discarding message! Reason: ",
					  "message was broadcasted to itself");
		return false;
	}

	if(!utils::this_mihf_is_destination(in) && !utils::is_multicast(in)) {
		ODTONE_LOG(1, "(sac) Discarding message! Reason: ",
					  "this is not the message destination");
		return false;
	}

	/** __no__ authentication at this point */

	uint mid = in->mid();

	//
	// no thread safety because insertion should __only__ be made
	// on MIHF initialization
	//
	std::map<uint, handler_t>::iterator it;
	it = _callbacks.find(mid);

	if(it != _callbacks.end()) {
		handler_t process_message = it->second;

		bool rsp;

		try {

			rsp = process_message(in, out);

		} catch(mih::bad_tlv) {
			ODTONE_LOG(1, "Discarding malformed message.");
			return false;
		}

		// set ip and port of response message
		out->ip(in->ip());
		out->scope(in->scope());
		out->port(in->port());

		// response message must have the same tid
		out->tid(in->tid());

		return rsp;
	} else {
		ODTONE_LOG(1, "(sac) (warning) message with mid: ", mid,
		    " unknown, discarding.");
	}

	return false;
}
Ejemplo n.º 7
0
/**
 * Send message to a local entity. If the output message destination is a peer
 * MIHF redirect it to the message_out module.
 *
 * @param msg The output message.
 */
void transmit::operator()(meta_message_ptr& msg)
{
	// TODO: remove try catch
	try{
		// FIXME: Response shouldn't be send to MIH Users
		if(msg->opcode() != mih::operation::request) {
			user_entry user = _user_abook.get(msg->destination().to_string());
			if(msg->opcode() == mih::operation::response) {
				msg->opcode(mih::operation::confirm);
			}
			utils::udp_send(_io, msg, user.ip.c_str(), user.port, _port);
			ODTONE_LOG(1, "(transmit) sending local message to: ",
			    msg->destination().to_string(), " : ", user.ip, " : ", user.port);
		}
		else {
			link_entry link = _link_abook.get(msg->destination().to_string());
			utils::udp_send(_io, msg, link.ip.c_str(), link.port, _port);
			ODTONE_LOG(1, "(transmit) sending local message to: ",
			    msg->destination().to_string(), " : ", link.ip, " : ", link.port);
		}
	} catch (...) {
		if(msg->opcode() == mih::operation::confirm) {
			msg->opcode(mih::operation::response);
		}
		ODTONE_LOG(1, "(transmit) forwarding to message_out");
		_msg_out(msg);
	}
}
Ejemplo n.º 8
0
/**
 * Parse all capabilities from MIH Capability Discover message and stores
 * them.
 *
 * @param in input message.
 * @param out output message.
 */
void service_management::get_capabilities(meta_message_ptr& in,
										  meta_message_ptr& out)
{
	address_entry mihf_info;
	mihf_info.ip = in->ip();
	mihf_info.port = in->port();

	if(in->opcode() == mih::operation::request) {
		*in >> mih::request(mih::request::capability_discover)
				& mih::tlv_net_type_addr_list(mihf_info.capabilities_list_net_type_addr)
				& mih::tlv_event_list(mihf_info.capabilities_event_list)
				& mih::tlv_command_list(mihf_info.capabilities_cmd_list)
				& mih::tlv_query_type_list(mihf_info.capabilities_query_type)
				& mih::tlv_transport_option_list(mihf_info.capabilities_trans_list)
				& mih::tlv_mbb_ho_supp_list(mihf_info.capabilities_mbb_ho_supp);
	} else if(in->opcode() == mih::operation::response) {
Ejemplo n.º 9
0
/**
 * Asks for the capabilities of all local Link SAPs.
 *
 * @param in The input message.
 * @param out The output message.
 * @return Always false, because it does not send any response directly.
 */
bool service_management::link_capability_discover_request(meta_message_ptr &in,
														  meta_message_ptr &out)
{
	// Asks for local Link SAPs capabilities
	ODTONE_LOG(1, "(mism) gathering information about local Link SAPs capabilities");

	*out << mih::request(mih::request::capability_discover);
	out->tid(in->tid());
	out->destination(in->source());

	// Check if the Link SAP is still active
	uint16 fails = _link_abook.fail(out->destination().to_string());
	if(fails > kConf_MIHF_Link_Delete_Value) {
		mih::octet_string dst = out->destination().to_string();
		_link_abook.inactive(dst);

		// Update MIHF capabilities
		utils::update_local_capabilities(_abook, _link_abook, _user_abook);
	}
	else {
		ODTONE_LOG(1, "(mics) forwarding Link_Capability_Discover.request to ",
			out->destination().to_string());
		utils::forward_request(out, _lpool, _transmit);
	}

	return false;
}
Ejemplo n.º 10
0
/**
 * Checks, in the transaction pool, if the outgoing message belongs to a pending
 * transaction. If true it runs the transaction, otherwise it creates a new
 * transaction.
 *
 * @param out The output message.
 */
void message_out::operator()(meta_message_ptr& out)
{
	out->ackreq(true);	// FIXME: read from config file

	if (out->opcode() == mih::operation::response) {
		dst_transaction_ptr t;
		dst_transaction_set::iterator it;

		_tpool.find(out->destination(), out->tid(), t);

		if (t) {
			t->out = out;
			t->msg_out_avail = true;

			if (t->start_ack_requestor)
				t->ack_requestor();

			if (t->start_ack_responder)
				t->ack_responder();

			if(t->transaction_status == ONGOING)
				t->run();

			if (t->transaction_status != ONGOING && t->ack_requestor_status != ONGOING)
				_tpool.del(t);
		} else {
			new_src_transaction(out);
		}
	} else if ((out->opcode() == mih::operation::indication) || (out->opcode() == mih::operation::request)) {

		src_transaction_ptr t;
		_tpool.find(out->destination(), out->tid(), t);

		if (t) {
			t->out = out;
			t->msg_out_avail = true;

			if (t->start_ack_requestor)
				t->ack_requestor();

			if (t->start_ack_responder)
				t->ack_responder();

			if(t->transaction_status == ONGOING)
				t->run();

			if (t->transaction_status != ONGOING && t->ack_requestor_status != ONGOING)
				_tpool.del(t);
		} else {
			new_src_transaction(out);
		}
	}
}
Ejemplo n.º 11
0
/**
 * Link Get Parameters Response message handler.
 *
 * @param in The input message.
 * @param out The output message.
 * @return True if the response is sent immediately or false otherwise.
 */
bool command_service::link_get_parameters_response(meta_message_ptr &in,
						   meta_message_ptr &out)
{
	ODTONE_LOG(1, "(mics) received Link_Get_Parameters.response from ",
	    in->source().to_string());

	if(!_lpool.set_user_tid(in)) {
		ODTONE_LOG(1, "(mics) warning: no local transaction for this msg ",
			"discarding it");
		return false;
	}

	ODTONE_LOG(1, "(mics) forwarding Link_Get_Parameters.response to ",
	    in->destination().to_string());

	_transmit(in);

	return false;
}
Ejemplo n.º 12
0
// send message for all users subscribed to event from link identifier
void event_service::msg_forward(meta_message_ptr &msg,
				mih::link_tuple_id &li,
				mih::event_list_enum event)
{
	std::list<event_registration_t>::iterator it;
	int i = 0; // for logging purposes

	msg->source(mihfid);
	for(it = _event_subscriptions.begin();
	    it != _event_subscriptions.end();
	    it++, i++) {
		if ((it->event == event)  &&(it->link == li)) {
			log(3, i, " (mies) found registration of user: "******" for event type ", event);
			msg->destination(mih::id(it->user));
			_transmit(msg);
		}
	}
}
Ejemplo n.º 13
0
// Check if there's a pending transaction and forward the message in
// case there is.
bool command_service::link_configure_thresholds_response(meta_message_ptr &in,
							 meta_message_ptr &out)
{
	log(1, "(mics) received Link_Configure_Thresholds.response from ",
	    in->source().to_string());

	if(!_lpool.set_user_tid(in)) {
		log(1, "(mics) warning: no local transaction for this msg ",
		    "discarding it");
		return false;
	}

	in->source(mihfid);

	log(1, "(mics) forwarding Link_Configure_Thresholds.response to ", in->destination().to_string());

	_transmit(in);

	return false;
}
Ejemplo n.º 14
0
/**
 * Create a new source transaction for the outgoing message.
 *
 * @param m The output message.
 */
void message_out::new_src_transaction(meta_message_ptr& m)
{
	src_transaction_ptr t(new src_transaction_t(process_message, _netsap));

	_tid++;
	if (_tid == 0)		// don't send a message with a
		_tid = 1;	// transaction id of 0

	_lpool.set_remote_tid(m->destination().to_string(), m->tid(), _tid);
	m->tid(_tid);

	t->out = m;
	t->mid = m->mid();
	t->msg_out_avail = true;

	t->run();

	if (t->transaction_status == ONGOING)
		_tpool.add(t);
}
Ejemplo n.º 15
0
// Check if there's a pending transaction and forward the message in
// case there is.
bool command_service::link_actions_response(meta_message_ptr &in,
					    meta_message_ptr &out)
{
	log(1, "(mics) received Link_Actions.response from ",
	    in->source().to_string());

	if(!_lpool.set_user_tid(in))
		{
			log(1, "(mics) no local pending transaction for this message, discarding");
			return false;
		}

	in->source(mihfid);

	log(1, "(mics) forwarding Link_Actions.response to ", in->destination().to_string());

	_transmit(in);

	return false;
}
Ejemplo n.º 16
0
// log received message type, and forward it
bool event_service::link_down_indication(meta_message_ptr &in, meta_message_ptr&)
{
	// if(in->payload().size() == 0)
	// 	return false;
	log(1, "(mies) received Link_Down.indication from ",
	    in->source().to_string());

	link_event_forward(in, mih::link_down);

	return false;
}
Ejemplo n.º 17
0
bool event_service::link_pdu_transmit_status_indication(meta_message_ptr &in,
							meta_message_ptr&)
{
	// if(in->payload().size() == 0)
	// 	return false;
	log(1, "(mies) received Link_PDU_Transmit_Status.indication from ",
	    in->source().to_string());

	link_event_forward(in, mih::link_pdu_transmit_status);

	return false;
}
Ejemplo n.º 18
0
/**
 * Create a new destination transaction for the incoming message.
 *
 * @param m The input message.
 */
void message_in::new_dst_transaction(meta_message_ptr& m)
{
	dst_transaction_ptr t(new dst_transaction_t(process_message, _netsap));
	t->in = m;
	t->mid = m->mid();
	t->msg_in_avail = true;

	t->run();

	if (t->transaction_status == ONGOING)
		_tpool.add(t);
}
Ejemplo n.º 19
0
// This MIHF is the destination of the Event_Unsubscribe.request.
// Deserialize message, unsubscribe user and send a response
bool event_service::local_event_unsubscribe_request(meta_message_ptr &in,
						    meta_message_ptr &out)
{
	mih::status st;
	mih::link_tuple_id link;
	mih::event_list events;

	*in >> mih::request(mih::request::event_unsubscribe)
		& mih::tlv_link_identifier(link)
		& mih::tlv_event_list(events);

	st = unsubscribe(in->source(), link, events);

	*out << mih::response(mih::response::event_unsubscribe)
		& mih::tlv_status(st)
		& mih::tlv_link_identifier(link)
		& mih::tlv_event_list(events);

	out->tid(in->tid());
	out->destination(in->source());

	return true;
}
Ejemplo n.º 20
0
/**
 * Check if there is a handler for this message and call it, else
 * discard message.
 *
 * @param in The input message.
 */
void sac_dispatch::operator()(meta_message_ptr& in)
{
	/** __no__ authentication at this point */

	uint mid = in->mid();

	ODTONE_LOG(1, "(sac) dispatching message with mid: ", mid);
	//
	// no thread safety because insertion should __only__ be made
	// on MIHF initialization
	//
	std::map<uint, handler_t>::iterator it;
	it = _callbacks.find(mid);

	if(it != _callbacks.end()) {
		handler_t process_message = it->second;
		meta_message_ptr out(new meta_message);

		out->tid(in->tid());
		// send response if it was generated
		try {

			if (process_message(in, out))
				_transmit(out);

		} catch(mih::bad_tlv) {
			ODTONE_LOG(1, "Discarding malformed message.");
		} catch(unknown_link_sap) {
			ODTONE_LOG(1, "Received message from an unknown Link SAP. Discarding message.");
		} catch(unknown_mih_user) {
			ODTONE_LOG(1, "Received message from an unknown MIH-User. Discarding message.");
		}
	} else {
			ODTONE_LOG(1, "(sac) (warning) message with mid: ", mid,
						  " unknown, discarding.");
	}
}
Ejemplo n.º 21
0
// A peer MIHF sent a Event_Unubscribe.response, check if we have a
// pending transaction with a local user. If so, then remove the
// subscription of the user to the link and events that came in the
// response.
bool event_service::event_unsubscribe_response(meta_message_ptr &in,
					       meta_message_ptr &)
{
	log(1, "(mies) received Event_Unsubscribe.response from ",
	    in->source().to_string());

	// do we have a request from a user?
	if (!_lpool.set_user_tid(in)) {
		log(1, "(mics) warning: no local transaction for this msg ",
		    "discarding it");

		return false;
	}

	mih::status		st;
	mih::link_tuple_id	link;
	mih::event_list		events;
	mih::message		pin;

	// parse incoming message to (event_registration_t) reg
	*in >>  mih::response()
		& mih::tlv_status(st)
		& mih::tlv_link_identifier(link)
		& mih::tlv_event_list(events);

	// remove subscription
	if (st == mih::status_success)
		st = unsubscribe(mih::id(in->destination().to_string()), link, events);

	log(1, "(mies) forwarding Event_Unsubscribe.response to ",
	    in->destination().to_string());

	// forward to user
	_transmit(in);

	return false;
}
Ejemplo n.º 22
0
// Check if this MIHF is the destination of the message or if it needs
// to forward the message to a peer MIHF.
bool event_service::event_subscribe_request(meta_message_ptr &in,
					    meta_message_ptr &out)
{
	log(1, "(mies) received Event_Subscribe.request from ",
	    in->source().to_string());

	if (utils::this_mihf_is_destination(in))  {
		return local_event_subscribe_request(in, out);
	} else {
		utils::forward_request(in, _lpool, _transmit);
		return false;
	}

	return false;
}
Ejemplo n.º 23
0
bool sac_process_message(meta_message_ptr& in, meta_message_ptr& out)
{
	// discard messages that this MIHF broadcasted to itself
	if (in->source() == mihfid)
		return false;

	/** __no__ authentication at this point */

	uint mid = in->mid();

	//
	// no thread safety because insertion should __only__ be made
	// on MIHF initialization
	//
	std::map<uint, handler_t>::iterator it;
	it = _callbacks.find(mid);

	if(it != _callbacks.end()) {
		handler_t process_message = it->second;

		bool rsp = process_message(in, out);

		// set ip and port of response message
		out->ip(in->ip());
		out->port(in->port());

		// response message must have the same tid
		out->tid(in->tid());

		return rsp;
	} else {
		log(1, "(sac) (warning) message with mid: ", mid,
		    " unknown, discarding.");
	}

	return false;
}
Ejemplo n.º 24
0
/**
 * Piggyback local MIHF Capabilities in request message.
 *
 * @param in input message.
 * @param out output message.
 */
void service_management::piggyback_capabilities(meta_message_ptr& in,
												meta_message_ptr& out)
{
	// Get local capabilities
	address_entry mihf_cap = _abook.get(mihfid_t::instance()->to_string());

	*out << mih::request(mih::request::capability_discover)
			& mih::tlv_net_type_addr_list(mihf_cap.capabilities_list_net_type_addr)
			& mih::tlv_event_list(mihf_cap.capabilities_event_list)
			& mih::tlv_command_list(mihf_cap.capabilities_cmd_list)
			& mih::tlv_query_type_list(mihf_cap.capabilities_query_type)
			& mih::tlv_transport_option_list(mihf_cap.capabilities_trans_list)
			& mih::tlv_mbb_ho_supp_list(mihf_cap.capabilities_mbb_ho_supp);

	out->tid(in->tid());
	out->source(in->source());
	out->destination(in->destination());
}
Ejemplo n.º 25
0
// parse link identifiers from list and for each one forward the
// message to the subscribed users
bool event_service::link_detected_indication(meta_message_ptr &in,
					     meta_message_ptr &out)
{
	// if(in->payload().size() == 0)
	// 	return false;

	log(1, "(mies) received Link_Detected.indication from ",
	    in->source().to_string());
	// link detected info from incoming message
	mih::link_det_info_list		list_ids;

	// link detected info on outgoing message
	mih::link_det_info_list		list_rsp;
	mih::link_det_info_list::iterator	it;

	*in >>  mih::response()
		& mih::tlv_link_det_info_list(list_ids);

	for(it = list_ids.begin(); it != list_ids.end(); it++) {
		// construct new link detected indication message
		// with just the link detected in the payload
		list_rsp.push_back(*it);

		*out << mih::indication(mih::indication::link_detected)
			& mih::tlv_link_det_info_list(list_rsp);

		// forward message to subscribed users
		msg_forward(out, it->id, mih::link_detected);

		list_rsp.clear();

		// FIXME: clear out before continuing
	}

	return false;
}
Ejemplo n.º 26
0
	/**
	 * Run Acknowledge Requestor State Machine transaction.
	 */
	void ack_requestor()
		{
			switch (ack_req_state)
			{
			case ACK_REQ_INIT: goto _req_init_lbl_;
			case ACK_REQ_WAIT_ACK: goto _req_wait_ack_lbl_;
			case ACK_REQ_RETRANSMIT: goto _req_retransmit_lbl_;
			case ACK_REQ_SUCCESS: goto _req_success_lbl_;
			case ACK_REQ_FAILURE: goto _req_failure_lbl_;
			}

		  _req_init_lbl_:
			{
				ack_requestor_status = ONGOING;
				rtxctr = 0;
				// unconditional transition to wait_ack
			}

		  _req_wait_ack_begin_lbl_:
			{
				ack_req_state = ACK_REQ_WAIT_ACK;
				retransmission_when = 5; // FIXME
			}

		  _req_wait_ack_lbl_:
			{
				if (retransmission_when == 0) {
					if  (rtxctr < 2)
						goto _req_retransmit_lbl_;
					else
						goto _req_failure_lbl_;
				}

				if ((msg_in_avail && in->ackrsp()))
					goto _req_success_lbl_;

				return;
			}

		  _req_retransmit_lbl_:
			{
				ack_req_state = ACK_REQ_RETRANSMIT;

				_netsap.send(out);
				rtxctr++;

				goto _req_wait_ack_begin_lbl_;
			}

		  _req_failure_lbl_:
			{
				ack_req_state = ACK_REQ_FAILURE;
				ack_requestor_status = FAILURE;
				return;
			}

		  _req_success_lbl_:
			{
				ack_req_state = ACK_REQ_SUCCESS;
				ack_requestor_status = SUCCESS;
				return;
			}
		}
Ejemplo n.º 27
0
/**
 * Checks, in the transaction pool, if the incoming message belongs to a pending
 * transaction. If true it runs the transaction, otherwise it creates a new
 * transaction.
 *
 * @param in The input message.
 */
void message_in::operator()(meta_message_ptr& in)
{
	// TODO: FIXME: check page 143 when adding support for fragment payload
	if ((in->ackrsp() && (in->opcode() == mih::operation::request || in->opcode() == mih::operation::indication))
		    ||
	   (!in->ackrsp() && in->opcode() == mih::operation::response)
	        ||
	   (in->ackrsp() && in->opcode() == mih::operation::response && in->has_service_specific_tlv()))
	{		
		// src
		src_transaction_ptr t;
		_tpool.find(in->source(), in->tid(), t);

		if (t) {
			t->in = in;
			t->msg_in_avail = true;

			if (t->start_ack_requestor)
				t->ack_requestor();

			if (t->start_ack_responder)
				t->ack_responder();

			if(t->transaction_status == ONGOING)
				if(!(in->ackrsp() == true && in->opcode() == mih::operation::request))
					t->run();

			if (t->transaction_status != ONGOING && t->ack_requestor_status != ONGOING)
				_tpool.del(t);
		} else {
			new_dst_transaction(in);
		}
	} else {
		dst_transaction_ptr t;
		_tpool.find(in->source(), in->tid(), t);

		if (t) {
			t->in = in;
			t->msg_in_avail = true;

			if (t->start_ack_requestor)
				t->ack_requestor();

			if(t->transaction_status == ONGOING)
				t->run();

			if (t->start_ack_responder && t->transaction_status == ONGOING)
				t->ack_responder();

			if (t->transaction_status != ONGOING && t->ack_requestor_status != ONGOING)
				_tpool.del(t);
		} else {
			new_dst_transaction(in);
		}
        }
}
Ejemplo n.º 28
0
	/**
	 * Run Acknowledge Responder State Machine transaction.
	 */
	void ack_responder()
		{
			switch(ack_rsp_state)
			{
			case ACK_RSP_INIT:
				goto _rsp_init_lbl_;
			case ACK_RSP_RETURN_ACK:
				goto _rsp_return_ack_lbl_;
			case ACK_RSP_PIGGYBACKING:
				goto _rsp_piggybacking_lbl_;
			case ACK_RSP_RETURN_DUPLICATE:
				goto _rsp_return_duplicate_lbl_;
			}

		  _rsp_init_lbl_:
			{
				ack->ackreq(false);
				ack->ackrsp(true);
				ack->opcode((mih::operation::type)opcode);
				ack->tid(tid);
				ack->mid(in->mid());
				ack->source(my_mihf_id);
				ack->destination(peer_mihf_id);
				ack->ip(in->ip());
				ack->port(in->port());

				if (msg_out_avail)
					goto _rsp_piggybacking_lbl_;
				else
				{			
					_netsap.send(ack);
					msg_in_avail = false;
					goto _rsp_return_ack_lbl_;
				}
					

				return;
			}

		  _rsp_return_ack_lbl_:
			{
				ack_rsp_state = ACK_RSP_RETURN_ACK;
				if(msg_in_avail)
				{					
					_netsap.send(ack);
					msg_in_avail = false;
				}
				else if (msg_out_avail)
					goto _rsp_piggybacking_lbl_;

				return;
			}

		  _rsp_piggybacking_lbl_:
			{
				ack_rsp_state = ACK_RSP_PIGGYBACKING;

				out->ackrsp(true);
				dup = out;

				if (msg_in_avail)
					goto _rsp_return_duplicate_lbl_;

				return;
			}

		  _rsp_return_duplicate_lbl_:
			{
				ack_rsp_state = ACK_RSP_RETURN_DUPLICATE;
				if (msg_in_avail) {
					_netsap.send(dup);
					msg_in_avail = false;
				}
			}
		}