1 /* Layer 1 normal data burst tx handling */
3 /* (C) 2010 by Dieter Spaar <spaar@mirider.augusta.de>
4 * (C) 2010,2017 by Harald Welte <laforge@gnumonks.org>
5 * (C) 2016 by Sebastian Stumpf <sebastian.stumpf87@googlemail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <osmocom/gsm/rsl.h>
31 #include <osmocom/gsm/gsm_utils.h>
32 #include <osmocom/gsm/protocol/gsm_08_58.h>
33 #include <osmocom/core/msgb.h>
34 #include <virtphy/l1ctl_sap.h>
35 #include <virtphy/virt_l1_sched.h>
36 #include <virtphy/logging.h>
37 #include <virtphy/gsmtapl1_if.h>
39 #include <l1ctl_proto.h>
42 * @brief Handler callback function for TRAFFIC request.
44 * @param [in] fn frame number
45 * @param [in] msg the msg to sent over virtual um.
47 static void virt_l1_sched_handler_cb(struct l1_model_ms
*ms
, uint32_t fn
, uint8_t tn
, struct msgb
* msg
)
49 gsmtapl1_tx_to_virt_um_inst(ms
, fn
, tn
, msg
);
50 l1ctl_tx_traffic_conf(ms
, fn
, 0, ms
->state
.serving_cell
.arfcn
);
54 * @brief Handler for received L1CTL_TRAFFIC_REQ from L23.
56 * -- traffic request --
58 * @param [in] msg the received message.
60 * Enqueue the message (traffic frame) to the L1 state machine's transmit queue. In virtual layer1 just submit it to the virt um.
63 void l1ctl_rx_traffic_req(struct l1_model_ms
*ms
, struct msgb
*msg
)
65 struct l1ctl_hdr
*l1h
= (struct l1ctl_hdr
*) msg
->data
;
66 struct l1ctl_info_ul
*ul
= (struct l1ctl_info_ul
*) l1h
->data
;
67 struct l1ctl_traffic_req
*tr
= (struct l1ctl_traffic_req
*) ul
->payload
;
68 uint8_t rsl_chantype
, subslot
, timeslot
;
69 uint32_t fn_sched
= sched_fn_ul(ms
->state
.current_time
, ul
->chan_nr
, ul
->link_id
);
71 rsl_dec_chan_nr(ul
->chan_nr
, &rsl_chantype
, &subslot
, ×lot
);
72 DEBUGPMS(DL1P
, ms
, "Rx L1CTL_TRAFFIC_REQ (chan_nr=0x%02x, link_id=0x%02x)\n",
73 ul
->chan_nr
, ul
->link_id
);
77 virt_l1_sched_schedule(ms
, msg
, fn_sched
, timeslot
, &virt_l1_sched_handler_cb
);
80 void l1ctl_tx_traffic_ind(struct l1_model_ms
*ms
, struct msgb
*msg
, uint16_t arfcn
, uint8_t link_id
,
81 uint8_t chan_nr
, uint32_t fn
, uint8_t snr
, uint8_t signal_dbm
,
82 uint8_t num_biterr
, uint8_t fire_crc
)
84 struct msgb
*l1ctl_msg
= NULL
;
85 struct l1ctl_traffic_ind
* l1ti
;
86 struct l1ctl_info_dl
* l1dl
;
89 uint8_t rsl_chan_type
, subchan
, timeslot
;
90 l1ctl_msg
= l1ctl_msgb_alloc(L1CTL_TRAFFIC_IND
);
91 l1dl
= (struct l1ctl_info_dl
*) msgb_put(l1ctl_msg
, sizeof(*l1dl
));
92 l1ti
= (struct l1ctl_traffic_ind
*) msgb_put(l1ctl_msg
, sizeof(*l1ti
));
94 rsl_dec_chan_nr(chan_nr
, &rsl_chan_type
, &subchan
, ×lot
);
96 l1dl
->band_arfcn
= htons(arfcn
);
97 l1dl
->link_id
= link_id
;
98 l1dl
->chan_nr
= chan_nr
;
99 l1dl
->frame_nr
= htonl(fn
);
101 l1dl
->rx_level
= signal_dbm
;
102 l1dl
->num_biterr
= 0; /* no biterrors */
105 /* The first byte indicates the type of voice frame (enum gsmtap_um_voice_type),
106 * which we simply ignore here and pass on the frame without that byte.
107 * TODO: Check for consistency with ms->state.tch_mode ? */
108 frame_len
= msgb_length(msg
) - 1;
110 msgb_free(l1ctl_msg
);
113 frame
= (uint8_t *) msgb_put(l1ctl_msg
, frame_len
);
114 memcpy(frame
, msgb_data(msg
)+1, frame_len
);
116 DEBUGPMS(DL1P
, ms
, "Tx L1CTL_TRAFFIC_IND (chan_nr=0x%02x, link_id=0x%02x)\n", chan_nr
, link_id
);
117 l1ctl_sap_tx_to_l23_inst(ms
, l1ctl_msg
);
121 * @brief Send a L1CTL_TRAFFIC_CONF to L23.
123 * @param [in] fn frame number
124 * @param [in] snr signal noise ratio
125 * @param [in] arfcn arfcn of the cell the message was send on
128 void l1ctl_tx_traffic_conf(struct l1_model_ms
*ms
, uint32_t fn
, uint16_t snr
, uint16_t arfcn
)
130 struct msgb
* l1ctl_msg
;
131 l1ctl_msg
= l1ctl_create_l2_msg(L1CTL_TRAFFIC_CONF
, fn
, snr
, arfcn
);
132 /* send confirm to layer23 */
133 DEBUGPMS(DL1P
, ms
, "Tx L1CTL_TRAFFIC_CONF\n");
134 l1ctl_sap_tx_to_l23_inst(ms
, l1ctl_msg
);