Esempio n. 1
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);
	}
}
Esempio n. 2
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);
		}
        }
}
Esempio n. 3
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);
		}
	}
}
Esempio n. 4
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;
	}

}
Esempio n. 5
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) {
Esempio n. 6
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;
				}
			}
		}