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