static int w_save_pending(struct sip_msg* _m, char* _d, char* _cflags) { return save_pending(_m, (udomain_t*)_d); }
NI_Code ni_send_msg_wait( ServiceType service, /* ACKD, UNACKD_RPT, UNACKD, REQUEST */ const SendAddrDtl * out_addr, /* address of outgoing message */ const MsgData * out_data, /* data of outgoing message */ int out_length, /* length of outgoing message */ bool priority, /* outgoing message priority */ bool out_auth, /* outgoing message authenticated */ ComplType * completion, /* MSG_SUCCEEDS or MSG_FAILS */ int * num_responses, /* number of received responses */ RespAddrDtl * in_addr, /* address of first response */ MsgData * in_data, /* data of first response */ int * in_length /* length of first response */ ) { bool local; // Is it addressed to net intfc? bool implicit; // Does it use implicit addressing? NI_Code ni_error; int response_count = 0; ComplType cmpl_code; byte incoming_tag; byte outgoing_tag; byte msg_length; if( num_responses ) * num_responses = 0; /* clear count */ init_response_list( ); /* clear out any responses from previous */ implicit = ( out_addr->im.type == IMPLICIT ); outgoing_tag = implicit ? out_addr->im.msg_tag : msg_tag_any; local = ( out_addr->lc.type == LOCAL ); ni_msg_hdr_init( out_length, /* msg size */ service, /* service type */ priority, /* priority */ local, /* addressed to net intfc */ out_auth, /* authenticated */ implicit, /* explicitly addressed */ outgoing_tag ); if( !implicit ) msg_out.addr.snd = * out_addr; /* destination address */ memcpy( &msg_out.data.exp, out_data, out_length ); /* outgoing data */ if( ( ni_error = ni_put_msg( ) ) != NI_OK ) /* send message */ return( ni_error ); if( local && service != REQUEST ) { // local, not req/resp, all done if( completion ) * completion = MSG_SUCCEEDS; return( NI_OK ); } usleep(1000); // karl test for( ;; ) { /* look for completion events and responses */ if( ( ni_error = ni_get_msg( niWAIT_TIME ) ) != NI_OK ) return( ni_error ); msg_length = msg_in.msg_hdr.exp.length; incoming_tag = msg_in.msg_hdr.exp.tag; if( msg_in.msg_hdr.exp.response ) { /* a response */ if( incoming_tag != outgoing_tag ) { save_pending( msg_length ); /* a response to another tag */ continue; /* keep looking for completion */ } /* a response to our tag */ if( !response_count ) { /* first response, copy it */ if( in_addr ) * in_addr = msg_in.addr.rsp; if( in_data ) memcpy( in_data, &msg_in.data, msg_length ); if( in_length ) * in_length = msg_length; } else save_response( msg_length ); /* subsequent response to our tag */ response_count++; /* got another one */ if( ! local ) continue; /* not local, keep looking for completion */ /* no completion events for local msgs, only one response */ if( completion ) * completion = MSG_SUCCEEDS; if( num_responses ) * num_responses = response_count; return( NI_OK ); /* This transaction is done */ // sleep(1); // karl test } /* here if incoming is not a response */ cmpl_code = (ComplType) msg_in.msg_hdr.exp.cmpl_code; switch( cmpl_code ) { case MSG_NOT_COMPL: save_pending( msg_length ); /* some other incoming message */ continue; /* keep looking for completion */ case MSG_FAILS: case MSG_SUCCEEDS: /* found the completion event */ if( incoming_tag != outgoing_tag ) return( NI_INTERNAL_ERR ); if( completion ) * completion = cmpl_code; if( num_responses ) * num_responses = response_count; return( NI_OK ); /* This transaction is done */ default: return( NI_INTERNAL_ERR ); /* Invalid completion code */ } /* end switch( cmpl_code ) */ } /* end for( ;; ) */ }