};
static void lapdm_t200_cb(void *data);
-static int rslms_send_i(struct lapdm_msg_ctx *mctx);
+static int rslms_send_i(struct lapdm_msg_ctx *mctx, int line);
/* UTILITY FUNCTIONS */
send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
/* send MDL ERROR INIDCATION to L3 */
rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- /* flush buffers */
+ /* flush tx buffers */
lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
/* go back to idle state */
lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
/* NOTE: we must not change any other states or buffers
/* enter multiple-frame-established state */
lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
/* send outstanding frames, if any (resume / reconnect) */
- rslms_send_i(mctx);
+ rslms_send_i(mctx, __LINE__);
/* send notification to L3 */
rc = send_rll_simple(RSL_MT_EST_CONF, mctx);
msgb_free(msg);
}
}
/* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx);
+ rslms_send_i(mctx, __LINE__);
break;
case LAPDm_S_RNR:
"received\n");
/* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx);
+ rslms_send_i(mctx, __LINE__);
break;
case LAPDm_S_REJ:
/* FIXME: 5.5.4.2 2) */
/* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx);
+ rslms_send_i(mctx, __LINE__);
break;
default:
/* check if we are not in own receiver busy */
if (!dl->own_busy) {
/* NOTE: V(R) is already set above */
- rc = rslms_send_i(mctx);
+ rc = rslms_send_i(mctx, __LINE__);
if (rc) {
LOGP(DLAPDM, LOGL_INFO, "we are not busy and "
"have no pending data, send RR\n");
/* Send RR with F=0 */
return lapdm_send_rr(mctx, 0);
}
+ /* all I or one RR is sent, we are done */
+ return 0;
} else {
LOGP(DLAPDM, LOGL_INFO, "we are busy, send RNR\n");
/* Send RNR with F=0 */
}
/* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx);
+ rslms_send_i(mctx, __LINE__);
return rc;
}
msgb_enqueue(&dl->send_queue, msg);
/* Send message, if possible */
- rslms_send_i(&dl->mctx);
+ rslms_send_i(&dl->mctx, __LINE__);
return 0;
}
/* Send next I frame from queued/buffered data */
-static int rslms_send_i(struct lapdm_msg_ctx *mctx)
+static int rslms_send_i(struct lapdm_msg_ctx *mctx, int line)
{
struct lapdm_datalink *dl = mctx->dl;
uint8_t chan_nr = mctx->chan_nr;
int length, left;
int rc = -1; /* we sent nothing */
+ LOGP(DLAPDM, LOGL_INFO, "%s() called from line %d\n", __func__, line);
+
next_frame:
if (dl->peer_busy) {
/* put back the send-buffer to the send-queue (first position) */
if (dl->send_buffer) {
+ LOGP(DLAPDM, LOGL_INFO, "put frame in sendbuffer back to "
+ "queue\n");
llist_add(&dl->send_buffer->list, &dl->send_queue);
dl->send_buffer = NULL;
- }
+ } else
+ LOGP(DLAPDM, LOGL_INFO, "no frame in sendbuffer\n");
- /* Clear transmit and send buffer, if any */
+ /* Clear transmit buffer, but keep send buffer */
lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
msgb_free(msg);
}
length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- LOGP(DLAPDM, LOGL_INFO, "perform re-establishment (SABM)\n");
+ LOGP(DLAPDM, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
+ length);
/* Replace message in the send-buffer (reconnect) */
if (dl->send_buffer)
msgb_free(dl->send_buffer);
dl->send_out = 0;
- dl->send_buffer = msg;
+ if (length) {
+ /* Remove the RSL/RLL header */
+ msgb_pull_l2h(msg);
+ /* Write data into the send buffer, to be sent first */
+ dl->send_buffer = msg;
+ }
/* Discard partly received L3 message */
if (dl->rcv_buffer) {
RSL_MT_RES_REQ, rslms_rx_rll_res_req},
/* create and send SABM command (reconnect) */
- {SBIT(LAPDm_STATE_MF_EST) |
+ {SBIT(LAPDm_STATE_IDLE) |
+ SBIT(LAPDm_STATE_MF_EST) |
SBIT(LAPDm_STATE_TIMER_RECOV),
RSL_MT_RECON_REQ, rslms_rx_rll_res_req},