int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len);
+/* Transmit L1CTL_RESET_REQ */
+int l1ctl_tx_reset_req(struct osmocom_ms *ms, uint8_t type);
+
/* Transmit L1CTL_PM_REQ */
int l1ctl_tx_pm_req_range(struct osmocom_ms *ms, uint16_t arfcn_from,
uint16_t arfcm_to);
/* input into layer2 (from layer 1) */
int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, struct l1ctl_info_dl *l1i);
+int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le);
/* input into layer2 (from layer 3) */
int rslms_recvmsg(struct msgb *msg, struct osmocom_ms *ms);
switch (signal) {
case S_L1CTL_RESET:
- if (started) {
- printf("L1_RESET, TODO: resend last radio request "
- "(CCCH / dedicated / power scan)\n");
+ if (started)
break;
- }
started = 1;
ms = signal_data;
/* insert test card, if enabled */
static int gsm322_sync_to_cell(struct osmocom_ms *ms, struct gsm322_cellsel *cs)
{
+// l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
return l1ctl_tx_fbsb_req(ms, cs->arfcn,
L1CTL_FBSB_F_FB01SB, 100, 0,
CCCH_MODE_COMBINED);
ms = rc->ms;
gsm48_rr_rach_conf(ms, rc->fn);
break;
+ case S_L1CTL_RESET:
+ LOGP(DCS, LOGL_INFO, "Reset\n");
+ break;
}
return 0;
struct msgb *msg, *nmsg;
/* release dedicated mode, if any */
- tx_ph_dm_rel_req(rr->ms);
+// tx_ph_dm_rel_req(rr->ms);
+ l1ctl_tx_reset_req(rr->ms, L1CTL_RES_T_FULL);
/* free establish message, if any */
rr->rr_est_req = 0;
if (rr->rr_est_msg) {
return 0;
}
+/* Receive L1CTL_DATA_CONF (Data Confirm from L1) */
+static int rx_ph_data_conf(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct l1ctl_info_dl *dl;
+ struct lapdm_entity *le;
+
+ dl = (struct l1ctl_info_dl *) msg->l1h;
+
+ /* determine LAPDm entity based on SACCH or not */
+ if (dl->link_id & 0x40)
+ le = &ms->l2_entity.lapdm_acch;
+ else
+ le = &ms->l2_entity.lapdm_dcch;
+
+ /* send it up into LAPDm */
+ l2_ph_data_conf(msg, le);
+
+ return 0;
+}
+
/* Transmit L1CTL_DATA_REQ */
int tx_ph_data_req(struct osmocom_ms *ms, struct msgb *msg,
uint8_t chan_nr, uint8_t link_id)
return osmo_send_l1(ms, msg);
}
+/* Transmit L1CTL_RESET_REQ */
+int l1ctl_tx_reset_req(struct osmocom_ms *ms, uint8_t type)
+{
+ struct msgb *msg;
+ struct l1ctl_reset *res;
+
+ msg = osmo_l1_alloc(L1CTL_RESET_REQ);
+ if (!msg)
+ return -1;
+
+ printf("Tx Reset Req (%u)\n", type);
+ res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
+ res->type = type;
+
+ return osmo_send_l1(ms, msg);
+}
+
/* Receive L1CTL_RESET_IND */
static int rx_l1_reset(struct osmocom_ms *ms)
{
case L1CTL_DATA_IND:
rc = rx_ph_data_ind(ms, msg);
break;
+ case L1CTL_DATA_CONF:
+ rc = rx_ph_data_conf(ms, msg);
+ break;
case L1CTL_RESET_IND:
+ case L1CTL_RESET_CONF:
rc = rx_l1_reset(ms);
msgb_free(msg);
break;
if (l1h->flags & L1CTL_F_DONE)
dispatch_signal(SS_L1CTL, S_L1CTL_PM_DONE, ms);
break;
- case L1CTL_RESET_CONF:
- LOGP(DL1C, LOGL_NOTICE, "L1CTL_RESET_CONF\n");
- msgb_free(msg);
- break;
case L1CTL_RACH_CONF:
- LOGP(DL1C, LOGL_NOTICE, "L1CTL_RACH_CONF\n");
rc = rx_l1_rach_conf(ms, msg);
msgb_free(msg);
break;
- case L1CTL_DATA_CONF:
- LOGP(DL1C, LOGL_NOTICE, "L1CTL_DATA_CONF\n");
- msgb_free(msg);
- break;
default:
fprintf(stderr, "Unknown MSG: %u\n", l1h->msg_type);
msgb_free(msg);
/* send the frame now */
le->tx_pending = 1;
-#warning HACK: no confirm yet! (queue is always empty now)
-le->tx_pending = 0;
+#if 0
printf("-> tx chan_nr 0x%x link_id 0x%x len %d data", chan_nr, link_id, msgb_l2len(msg));
int i;
for (i = 0; i < msgb_l2len(msg); i++)
printf(" %02x", msg->l2h[i]);
printf("\n");
-//usleep(100000);
+#endif
lapdm_pad_msgb(msg, n201);
return tx_ph_data_req(ms, msg, chan_nr, link_id);
}
/* get next frame from the tx queue. because the ms has multiple datalinks,
* each datalink's queue is read round-robin.
*/
-static int tx_ph_data_dequeue(struct lapdm_entity *le)
+int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
{
struct osmocom_ms *ms = le->ms;
struct lapdm_datalink *dl;
int last = le->last_tx_dequeue;
int i = last, n = ARRAY_SIZE(le->datalink);
- struct msgb *msg;
uint8_t chan_nr, link_id, n201;
+ /* we may send again */
+ le->tx_pending = 0;
+
+#if 0
+printf("-> tx confirm\n");
+#endif
+ /* free confirm message */
+ msgb_free(msg);
+
/* round-robin dequeue */
do {
/* next */
} while (i != last);
/* no message in all queues */
- if (msg)
+ if (!msg)
return 0;
/* Pull chan_nr and link_id */
/* Pad the frame, we can transmit now */
le->tx_pending = 1;
+#if 0
+printf("-> more tx chan_nr 0x%x link_id 0x%x len %d data", chan_nr, link_id, msgb_l2len(msg));
+for (i = 0; i < msgb_l2len(msg); i++)
+ printf(" %02x", msg->l2h[i]);
+printf("\n");
+#endif
lapdm_pad_msgb(msg, n201);
return tx_ph_data_req(ms, msg, chan_nr, link_id);
}
{
int rc;
+#if 0
+printf("-> rx chan_nr 0x%x link_id 0x%x len %d data", mctx->chan_nr, mctx->link_id, msgb_l2len(msg));
+int i;
+for (i = 0; i < msgb_l2len(msg); i++)
+ printf(" %02x", msg->l2h[i]);
+printf("\n");
+#endif
/* G.2.3 EA bit set to "0" is not allowed in GSM */
if (!LAPDm_ADDR_EA(mctx->addr)) {
LOGP(DLAPDM, LOGL_NOTICE, "EA bit 0 is not allowed in GSM\n");
"LAPDm_STATE_SABM_SENT",
"LAPDm_STATE_MF_EST",
"LAPDm_STATE_TIMER_RECOV",
- "LAPDm_STATE_OWN_RCVR_BUSY"
+ "LAPDm_STATE_DISC_SENT",
};
/* statefull handling for RSLms RLL messages from L3 */