/** * 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); } }
/** * 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); } } }
/** * 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); } } }
// // 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; } }
/** * 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) {
/** * 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; } } }