static void req_bcsple_msg(abcsp *_this, lemsgid id) { /* <Sigh.> The bitfield abcsp_txrx means we can't table-drive. */ switch (id) { case lemsgid_sync: _this->txrx.txsync_req = 1; break; case lemsgid_sync_resp: _this->txrx.txsyncresp_req = 1; break; case lemsgid_conf: _this->txrx.txconf_req = 1; break; case lemsgid_conf_resp: _this->txrx.txconfresp_req = 1; break; default: return; } /* Kick the transmit path into wakefulness. */ ABCSP_REQ_PUMPTXMSGS(_this); }
unsigned abcsp_sendmsg(ABCSP_TXMSG *msg, unsigned chan, unsigned rel) { TXMSG *m; /* Reject all traffic if the choke is applied. BCSP-LE messages are transmitted from code below this entry point. The choke should be applied at the "mux" layer. Applying it here means that if the choke is turned on while messages are queued for transmission then those messages will drain out. This is strictly incorrect, but this won't harm any real system as the choke is only set TRUE by abcsp library init, so any peer is going to see disrupted traffic for a while anyway. (Ideally, bcsp-le messages from here will tell the peer that we've restarted, so it should reinit and rechoke.) */ if(abcsp_txrx.choke) { ABCSP_EVENT(ABCSP_EVT_TX_CHOKE_DISCARD); return(0); } /* Parameter sanity checks. */ if(rel > 1 || chan < 2 || chan > 15 || msg == (ABCSP_TXMSG*)(NULL)) return(0); /* We queue enough reliable messages to fill the WINSIZE window. */ if(rel && msgq_len(relq) >= ABCSP_TXWINSIZE) { ABCSP_EVENT(ABCSP_EVT_TX_WINDOW_FULL_DISCARD); return(0); } /* Package the message. */ if((m = ZNEW(TXMSG)) == (TXMSG*)(NULL)) return(0); m->m = msg; m->chan = chan; if(rel) { /* We've already checked the reliable queue has room. */ m->seq = msgq_txseq; msgq_txseq = incrmod8(msgq_txseq); msgq_add(&relq, m); } else { /* The unreliable channel is biased towards supporting sco, for which the data has to be fresh. The queue holds only one message, so we displace any message that's already in the queue. */ (void) msgq_pop_destroy(&unrelq); msgq_add(&unrelq, m); } /* Tell external code that it needs to call abcsp_pumptxmsgs(). */ ABCSP_REQ_PUMPTXMSGS(); /* Report message accepted. */ return(1); }