diff options
Diffstat (limited to 'src/host/virt_phy')
-rw-r--r-- | src/host/virt_phy/src/Makefile.am | 1 | ||||
-rw-r--r-- | src/host/virt_phy/src/gsmtapl1_if.c | 164 | ||||
-rw-r--r-- | src/host/virt_phy/src/gsmtapl1_if.h | 4 | ||||
-rw-r--r-- | src/host/virt_phy/src/l1ctl_sap.c | 90 | ||||
-rw-r--r-- | src/host/virt_phy/src/l1ctl_sap.h | 1 | ||||
-rw-r--r-- | src/host/virt_phy/src/l1ctl_sock.c | 8 | ||||
-rw-r--r-- | src/host/virt_phy/src/virt_l1_model.h | 1 |
7 files changed, 159 insertions, 110 deletions
diff --git a/src/host/virt_phy/src/Makefile.am b/src/host/virt_phy/src/Makefile.am index a110435a..2dac297c 100644 --- a/src/host/virt_phy/src/Makefile.am +++ b/src/host/virt_phy/src/Makefile.am @@ -8,6 +8,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OSMO_BB_DIR)/include - # TODO: somehow this include path causes errors, thus the needed files are copied into $(top_srcdir)/include. Would be better to include directly from $(OSMO_BB_DIR)/src/target/firmware/include to avoid redundancy. # -I$(OSMO_BB_DIR)/src/target/firmware/include +# disable optimization and enable debugging CFLAGS = -g -O0 sbin_PROGRAMS = virtphy diff --git a/src/host/virt_phy/src/gsmtapl1_if.c b/src/host/virt_phy/src/gsmtapl1_if.c index 11214cf8..53cc9525 100644 --- a/src/host/virt_phy/src/gsmtapl1_if.c +++ b/src/host/virt_phy/src/gsmtapl1_if.c @@ -89,28 +89,23 @@ void gsmtapl1_init(struct l1_model_ms *model) } /** - * Append a gsmtap header to msg and send it over the virt um. + * Replace l11 header of given msgb by a gsmtap header and send it over the virt um. */ -void gsmtapl1_tx_to_virt_um_inst(struct virt_um_inst *vui, struct msgb *msg) +void gsmtapl1_tx_to_virt_um_inst(struct virt_um_inst *vui, uint8_t tn, uint32_t fn, uint8_t gsmtap_chan, struct msgb *msg) { - struct l1ctl_hdr *l1hdr = (struct l1ctl_hdr *)msg->l1h; - struct l1ctl_info_dl *l1dl = (struct l1ctl_info_dl *)msg->data; + struct l1ctl_hdr *l1h = (struct l1ctl_hdr *)msg->data; + struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *)l1h->data; uint8_t ss = 0; - uint8_t gsmtap_chan; + uint8_t *data = msgb_l2(msg); // data bits to transmit (whole message without l1 header) + uint8_t data_len = msgb_l2len(msg); struct msgb *outmsg; - switch (l1hdr->msg_type) { - case L1CTL_DATA_REQ: - // TODO: check what data request and set gsmtap_chan depending on that - gsmtap_chan = 0; - break; - } - outmsg = gsmtap_makemsg(l1dl->band_arfcn, l1dl->chan_nr, gsmtap_chan, - ss, l1dl->frame_nr, 0, 0, msgb_l2(msg), - msgb_l2len(msg)); + outmsg = gsmtap_makemsg(l1_model_ms->state->serving_cell.arfcn, ul->chan_nr, gsmtap_chan, + ss, fn, 0, 0, data, + data_len); if (outmsg) { - struct gsmtap_hdr *gh = (struct gsmtap_hdr *)outmsg->l1h; - virt_um_write_msg(vui, outmsg); + struct gsmtap_hdr *gh = msgb_data(msg); + virt_um_write_msg(l1_model_ms->vui, outmsg); DEBUGP(DVIRPHY, "Sending gsmtap msg to virt um - (arfcn=%u, type=%u, subtype=%u, timeslot=%u, subslot=%u)\n", gh->arfcn, gh->type, gh->sub_type, gh->timeslot, @@ -124,11 +119,11 @@ void gsmtapl1_tx_to_virt_um_inst(struct virt_um_inst *vui, struct msgb *msg) } /** - * @see void gsmtapl1_tx_to_virt_um(struct virt_um_inst *vui, struct msgb *msg). + * @see void gsmtapl1_tx_to_virt_um(struct virt_um_inst *vui, uint8_t tn, uint32_t fn, uint8_t gsmtap_chan, struct msgb *msg). */ -void gsmtapl1_tx_to_virt_um(struct msgb *msg) +void gsmtapl1_tx_to_virt_um(uint8_t tn, uint32_t fn, uint8_t gsmtap_chan, struct msgb *msg) { - gsmtapl1_tx_to_virt_um_inst(l1_model_ms->vui, msg); + gsmtapl1_tx_to_virt_um_inst(l1_model_ms->vui, tn, fn, gsmtap_chan, msg); } /* This is the header as it is used by gsmtap peer virtual layer 1. @@ -155,77 +150,77 @@ void gsmtapl1_rx_from_virt_um_inst_cb(struct virt_um_inst *vui, struct msgb *msg) { if (msg) { - struct gsmtap_hdr *gh; - struct l1ctl_info_dl *l1dl; - struct msgb *l1ctl_msg = NULL; - struct l1ctl_data_ind * l1di; + // we assume we only receive msgs if we actually camp on a cell + if (l1_model_ms->state->camping) { + struct gsmtap_hdr *gh; + struct l1ctl_info_dl *l1dl; + struct msgb *l1ctl_msg = NULL; + struct l1ctl_data_ind * l1di; - msg->l1h = msgb_data(msg); - msg->l2h = msgb_pull(msg, sizeof(*gh)); - gh = msgb_l1(msg); + msg->l1h = msgb_data(msg); + msg->l2h = msgb_pull(msg, sizeof(*gh)); + gh = msgb_l1(msg); - DEBUGP(DVIRPHY, - "Receiving gsmtap msg from virt um - (arfcn=%u, framenumber=%u, type=%s, subtype=%s, timeslot=%u, subslot=%u)\n", - ntohs(gh->arfcn), ntohl(gh->frame_number), get_value_string(gsmtap_types, gh->type), get_value_string(gsmtap_channels, gh->sub_type), gh->timeslot, - gh->sub_slot); + DEBUGP(DVIRPHY, + "Receiving gsmtap msg from virt um - (arfcn=%u, framenumber=%u, type=%s, subtype=%s, timeslot=%u, subslot=%u)\n", + ntohs(gh->arfcn), ntohl(gh->frame_number), get_value_string(gsmtap_types, gh->type), get_value_string(gsmtap_channels, gh->sub_type), gh->timeslot, + gh->sub_slot); - // compose the l1ctl message for layer 2 - switch (gh->sub_type) { - case GSMTAP_CHANNEL_RACH: - LOGP(DL1C, LOGL_NOTICE, - "Ignoring gsmtap msg from virt um - channel type is uplink only!\n"); - break; - case GSMTAP_CHANNEL_SDCCH: - case GSMTAP_CHANNEL_SDCCH4: - case GSMTAP_CHANNEL_SDCCH8: - l1ctl_msg = l1ctl_msgb_alloc(L1CTL_DATA_IND); - // TODO: implement channel handling - break; - case GSMTAP_CHANNEL_TCH_F: - l1ctl_msg = l1ctl_msgb_alloc(L1CTL_TRAFFIC_IND); - // TODO: implement channel handling - break; - case GSMTAP_CHANNEL_AGCH: - case GSMTAP_CHANNEL_PCH: - case GSMTAP_CHANNEL_BCCH: - l1ctl_msg = l1ctl_msgb_alloc(L1CTL_DATA_IND); - l1dl = (struct l1ctl_info_dl *) msgb_put(l1ctl_msg, sizeof(struct l1ctl_info_dl)); - l1di = (struct l1ctl_data_ind *) msgb_put(l1ctl_msg, sizeof(struct l1ctl_data_ind)); + // compose the l1ctl message for layer 2 + switch (gh->sub_type) { + case GSMTAP_CHANNEL_RACH: + LOGP(DL1C, LOGL_NOTICE, + "Ignoring gsmtap msg from virt um - channel type is uplink only!\n"); + break; + case GSMTAP_CHANNEL_TCH_F: + l1ctl_msg = l1ctl_msgb_alloc(L1CTL_TRAFFIC_IND); + // TODO: implement channel handling + break; + case GSMTAP_CHANNEL_SDCCH: + case GSMTAP_CHANNEL_SDCCH4: + case GSMTAP_CHANNEL_SDCCH8: + // TODO: we might need to implement own channel handling for standalone dedicated channels + case GSMTAP_CHANNEL_AGCH: + case GSMTAP_CHANNEL_PCH: + case GSMTAP_CHANNEL_BCCH: + l1ctl_msg = l1ctl_msgb_alloc(L1CTL_DATA_IND); + l1dl = (struct l1ctl_info_dl *) msgb_put(l1ctl_msg, sizeof(struct l1ctl_info_dl)); + l1di = (struct l1ctl_data_ind *) msgb_put(l1ctl_msg, sizeof(struct l1ctl_data_ind)); - l1dl->band_arfcn = htons(ntohs(gh->arfcn)); - l1dl->link_id = gh->timeslot; - // see GSM 8.58 -> 9.3.1 for channel number encoding - l1dl->chan_nr = rsl_enc_chan_nr(chantype_gsmtap2rsl(gh->sub_type), gh->sub_slot, gh->timeslot); - l1dl->frame_nr = htonl(ntohl(gh->frame_number)); - l1dl->snr = gh->snr_db; - l1dl->rx_level = gh->signal_dbm; - l1dl->num_biterr = 0; - l1dl->fire_crc = 0; + l1dl->band_arfcn = htons(ntohs(gh->arfcn)); + l1dl->link_id = gh->timeslot; + // see GSM 8.58 -> 9.3.1 for channel number encoding + l1dl->chan_nr = rsl_enc_chan_nr(chantype_gsmtap2rsl(gh->sub_type), gh->sub_slot, gh->timeslot); + l1dl->frame_nr = htonl(ntohl(gh->frame_number)); + l1dl->snr = gh->snr_db; + l1dl->rx_level = gh->signal_dbm; + l1dl->num_biterr = 0; + l1dl->fire_crc = 0; - memcpy(l1di->data, msgb_data(msg), msgb_length(msg)); + memcpy(l1di->data, msgb_data(msg), msgb_length(msg)); - break; - case GSMTAP_CHANNEL_CCCH: - case GSMTAP_CHANNEL_TCH_H: - case GSMTAP_CHANNEL_PACCH: - case GSMTAP_CHANNEL_PDCH: - case GSMTAP_CHANNEL_PTCCH: - case GSMTAP_CHANNEL_CBCH51: - case GSMTAP_CHANNEL_CBCH52: - LOGP(DL1C, LOGL_NOTICE, - "Ignoring gsmtap msg from virt um - channel type not supported!\n"); - break; - default: - LOGP(DL1C, LOGL_NOTICE, - "Ignoring gsmtap msg from virt um - channel type unknown.\n"); - break; - } + break; + case GSMTAP_CHANNEL_CCCH: + case GSMTAP_CHANNEL_TCH_H: + case GSMTAP_CHANNEL_PACCH: + case GSMTAP_CHANNEL_PDCH: + case GSMTAP_CHANNEL_PTCCH: + case GSMTAP_CHANNEL_CBCH51: + case GSMTAP_CHANNEL_CBCH52: + LOGP(DL1C, LOGL_NOTICE, + "Ignoring gsmtap msg from virt um - channel type not supported!\n"); + break; + default: + LOGP(DL1C, LOGL_NOTICE, + "Ignoring gsmtap msg from virt um - channel type unknown.\n"); + break; + } - /* forward l1ctl message to l2 */ - if(l1ctl_msg) { - l1ctl_sap_tx_to_l23(l1ctl_msg); + /* forward l1ctl message to l2 */ + if(l1ctl_msg) { + l1ctl_sap_tx_to_l23(l1ctl_msg); + } } - // handle memory deallocation talloc_free(msg); } @@ -240,9 +235,8 @@ void gsmtapl1_rx_from_virt_um(struct msgb *msg) } /*! \brief convert GSMTAP channel type to RSL channel number - * \param[in] rsl_chantype RSL channel type - * \param[in] link_id RSL link identifier - * \returns GSMTAP channel type + * \param[in] gsmtap_chantype GSMTAP channel type + * \returns RSL channel type */ uint8_t chantype_gsmtap2rsl(uint8_t gsmtap_chantype) { diff --git a/src/host/virt_phy/src/gsmtapl1_if.h b/src/host/virt_phy/src/gsmtapl1_if.h index 8c7491c0..09d34f4d 100644 --- a/src/host/virt_phy/src/gsmtapl1_if.h +++ b/src/host/virt_phy/src/gsmtapl1_if.h @@ -12,7 +12,7 @@ void gsmtapl1_init(struct l1_model_ms *model); void gsmtapl1_rx_from_virt_um_inst_cb(struct virt_um_inst *vui, struct msgb *msg); void gsmtapl1_rx_from_virt_um(struct msgb *msg); -void gsmtapl1_tx_to_virt_um_inst(struct virt_um_inst *vui, struct msgb *msg); -void gsmtapl1_tx_to_virt_um(struct msgb *msg); +void gsmtapl1_tx_to_virt_um_inst(struct virt_um_inst *vui, uint8_t tn, uint32_t fn, uint8_t gsmtap_chan, struct msgb *msg); +void gsmtapl1_tx_to_virt_um(uint8_t tn, uint32_t fn, uint8_t gsmtap_chan, struct msgb *msg); uint8_t chantype_gsmtap2rsl(uint8_t gsmtap_chantype); diff --git a/src/host/virt_phy/src/l1ctl_sap.c b/src/host/virt_phy/src/l1ctl_sap.c index 46121ed1..b5fb0f07 100644 --- a/src/host/virt_phy/src/l1ctl_sap.c +++ b/src/host/virt_phy/src/l1ctl_sap.c @@ -3,6 +3,7 @@ #include <osmocom/core/linuxlist.h> #include <osmocom/core/msgb.h> #include <osmocom/core/utils.h> +#include <osmocom/core/gsmtap.h> #include <stdio.h> #include <l1ctl_proto.h> #include <netinet/in.h> @@ -12,6 +13,7 @@ #include "virt_l1_model.h" #include "l1ctl_sap.h" #include "logging.h" +#include "gsmtapl1_if.h" static struct l1_model_ms *l1_model_ms = NULL; @@ -30,6 +32,7 @@ void l1ctl_sap_init(struct l1_model_ms *model) */ void l1ctl_sap_rx_from_l23_inst_cb(struct l1ctl_sock_inst *lsi, struct msgb *msg) { + // check if the received msg is not empty if (msg) { DEBUGP(DL1C, "Message incoming from layer 2: %s\n", osmo_hexdump(msg->data, msg->len)); @@ -177,6 +180,8 @@ void l1ctl_sap_handler(struct msgb *msg) break; case L1CTL_RACH_REQ: l1ctl_rx_rach_req(msg); + // msg is freed by rx routine + goto exit_nofree; break; case L1CTL_DATA_REQ: l1ctl_rx_data_req(msg); @@ -232,11 +237,18 @@ void l1ctl_rx_fbsb_req(struct msgb *msg) struct l1ctl_hdr *l1h = (struct l1ctl_hdr *)msg->data; struct l1ctl_fbsb_req *sync_req = (struct l1ctl_fbsb_req *)l1h->data; - DEBUGP(DL1C, - "Received and handled from l23 - L1CTL_FBSB_REQ (arfcn=%u, flags=0x%x)\n", + DEBUGP(DL1C, "Received and handled from l23 - L1CTL_FBSB_REQ (arfcn=%u, flags=0x%x)\n", ntohs(sync_req->band_arfcn), sync_req->flags); - l1ctl_tx_fbsb_conf(0, ntohs(sync_req->band_arfcn)); + l1_model_ms->state->camping = 1; + l1_model_ms->state->serving_cell.arfcn = ntohs(sync_req->band_arfcn); + l1_model_ms->state->serving_cell.ccch_mode = sync_req->ccch_mode; + l1_model_ms->state->serving_cell.fn_offset = 0; + l1_model_ms->state->serving_cell.bsic = 0; + l1_model_ms->state->serving_cell.time_alignment = 0; + // TODO: reset and synchronize the ms uplink schedulers with bts multiframe structure. + + l1ctl_tx_fbsb_conf(0, l1_model_ms->state->serving_cell.arfcn); } /** @@ -418,16 +430,37 @@ void l1ctl_rx_param_req(struct msgb *msg) */ void l1ctl_rx_rach_req(struct msgb *msg) { - struct l1ctl_hdr *l1h = (struct l1ctl_hdr *)msg->data; - struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *)l1h->data; - struct l1ctl_rach_req *rach_req = (struct l1ctl_rach_req *)ul->payload; + struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data; + struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *) l1h->data; + struct l1ctl_rach_req *rach_req = (struct l1ctl_rach_req *) ul->payload; + + uint32_t fn_sched; + uint8_t ts; DEBUGP(DL1C, "Received and handled from l23 - L1CTL_RACH_REQ (ra=0x%02x, offset=%d combined=%d)\n", rach_req->ra, ntohs(rach_req->offset), rach_req->combined); -// l1a_rach_req(ntohs(rach_req->offset), rach_req->combined, + // TODO: calculate correct fn/ts for a RACH (if needed by bts) + // TODO: implement scheduler for uplink! + fn_sched = 42; + ts = 0; + // for the rach channel request, there is no layer2 header, but only the one bit ra content to submit + // see 4.18-9.1.8 CHannel Request + // that means we have to set l2h of msgb to the ra content + msg->l2h = &rach_req->ra; + // avoid all data after ra to also be submitted + msgb_trim(msg, sizeof(rach_req->ra)); + // TODO: check if we need to submit more data than the ra content to the bts + + // send rach over virt um + gsmtapl1_tx_to_virt_um(ts, fn_sched, GSMTAP_CHANNEL_RACH, msg); + + // send confirm to layer23 + l1ctl_tx_rach_conf(fn_sched, l1_model_ms->state->serving_cell.arfcn); + +// l1a_rach_req(ntohs(rach_req->offset), rach_req->combined, // rach_req->ra); } @@ -481,7 +514,9 @@ void l1ctl_rx_data_req(struct msgb *msg) * * Process power measurement for a given range of arfcns to calculate signal power and connection quality. * - * Note: We do not need to calculate that for the virtual physical layer, but l23 apps can expect a response. So this response is mocked here. + * Note: We do not need to calculate that for the virtual physical layer, + * but l23 apps can expect a response. So this response is mocked here. + * TODO: Might be possible to sync to different virtual BTS. Mapping from arfcn to mcast address would be needed. Configurable rx_lev for each mcast address. */ void l1ctl_rx_pm_req(struct msgb *msg) { @@ -499,11 +534,11 @@ void l1ctl_rx_pm_req(struct msgb *msg) for(arfcn_next = pm_req->range.band_arfcn_from; arfcn_next <= pm_req->range.band_arfcn_to; ++arfcn_next) { struct l1ctl_pm_conf *pm_conf = (struct l1ctl_pm_conf *)msgb_put(resp_msg, sizeof(*pm_conf)); pm_conf->band_arfcn = htons(arfcn_next); - // rxlev 63 is great, 0 is bad the two values are probably min and max + // rxlev 63 is great, 0 is bad the two values are min and max pm_conf->pm[0] = 63; pm_conf->pm[1] = 63; if(arfcn_next == pm_req->range.band_arfcn_to) { - struct l1ctl_hdr *resp_l1h = resp_msg->l1h; + struct l1ctl_hdr *resp_l1h = msgb_l1(resp_msg); resp_l1h->flags |= L1CTL_F_DONE; } // no more space in msgb, flush to l2 @@ -526,6 +561,10 @@ void l1ctl_rx_pm_req(struct msgb *msg) * * Reset layer 1 (state machine, scheduler, transceiver) depending on the reset type. * + * Note: Currently we do not perform anything else than response with a reset confirm + * to just tell l2 that we are rdy. + * TODO: Validate if an action has to be done here. + * */ void l1ctl_rx_reset_req(struct msgb *msg) { @@ -534,22 +573,16 @@ void l1ctl_rx_reset_req(struct msgb *msg) switch (reset_req->type) { case L1CTL_RES_T_FULL: - DEBUGP(DL1C, - "Received and handled from l23 - L1CTL_RESET_REQ (type=FULL)\n"); -// l1s_reset(); -// l1s_reset_hw(); -// audio_set_enabled(GSM48_CMODE_SIGN, 0); + DEBUGP(DL1C, "Received and handled from l23 - L1CTL_RESET_REQ (type=FULL)\n"); + l1_model_ms->state->camping = 0; l1ctl_tx_reset(L1CTL_RESET_CONF, reset_req->type); break; case L1CTL_RES_T_SCHED: - DEBUGP(DL1C, - "Received and handled from l23 - L1CTL_RESET_REQ (type=SCHED)\n"); -// sched_gsmtime_reset(); + DEBUGP(DL1C, "Received and handled from l23 - L1CTL_RESET_REQ (type=SCHED)\n"); l1ctl_tx_reset(L1CTL_RESET_CONF, reset_req->type); break; default: - LOGP(DL1C, LOGL_ERROR, - "Received and ignored from l23 - L1CTL_RESET_REQ (type=unknown)\n"); + LOGP(DL1C, LOGL_ERROR, "Received and ignored from l23 - L1CTL_RESET_REQ (type=unknown)\n"); break; } } @@ -738,6 +771,23 @@ void l1ctl_tx_reset(uint8_t msg_type, uint8_t reset_type) } /** + * @brief Transmit L1CTL_RESET_IND or L1CTL_RESET_CONF to layer 23. + * + * -- reset indication / confirm -- + * + * @param [in] msg_type L1CTL primitive message type. + * @param [in] reset_type reset type (full, boot or just scheduler reset). + */ +void l1ctl_tx_rach_conf(uint32_t fn, uint16_t arfcn) +{ + struct msgb * msg = l1ctl_create_l2_msg(L1CTL_RACH_CONF, fn, 0, arfcn); + + DEBUGP(DL1C, "Sending to l23 - %s (fn: %u, arfcn: %u)\n", + getL1ctlPrimName(L1CTL_RACH_CONF), fn, arfcn); + l1ctl_sap_tx_to_l23(msg); +} + +/** * @brief Transmit L1CTL msg of a given type to layer 23. * * @param [in] msg_type L1CTL primitive message type. diff --git a/src/host/virt_phy/src/l1ctl_sap.h b/src/host/virt_phy/src/l1ctl_sap.h index 2d671287..f540197a 100644 --- a/src/host/virt_phy/src/l1ctl_sap.h +++ b/src/host/virt_phy/src/l1ctl_sap.h @@ -46,6 +46,7 @@ void l1ctl_rx_sim_req(struct msgb *msg); /* transmit routines */ void l1ctl_tx_reset(uint8_t msg_type, uint8_t reset_type); +void l1ctl_tx_rach_conf(uint32_t fn, uint16_t arfcn); void l1ctl_tx_pm_conf(struct l1ctl_pm_req *pm_req); void l1ctl_tx_fbsb_conf(uint8_t res, uint16_t arfcn); void l1ctl_tx_ccch_mode_conf(uint8_t ccch_mode); diff --git a/src/host/virt_phy/src/l1ctl_sock.c b/src/host/virt_phy/src/l1ctl_sock.c index e52b731a..b507369f 100644 --- a/src/host/virt_phy/src/l1ctl_sock.c +++ b/src/host/virt_phy/src/l1ctl_sock.c @@ -42,6 +42,8 @@ #include <arpa/inet.h> +#include <l1ctl_proto.h> + #include "l1ctl_sock.h" #include "virtual_um.h" #include "logging.h" @@ -59,14 +61,13 @@ static int l1ctl_sock_data_cb(struct osmo_fd *ofd, unsigned int what) { struct l1ctl_sock_inst *lsi = ofd->data; - int cnt = 0; // Check if request is really read request if (what & BSC_FD_READ) { struct msgb *msg = msgb_alloc(L1CTL_SOCK_MSGB_SIZE, "L1CTL sock rx"); int rc; uint16_t len; - + struct l1ctl_hdr *l1h; // read length of the message first and convert to host byte order rc = read(ofd->fd, &len, sizeof(len)); if (rc < sizeof(len)) { @@ -81,7 +82,8 @@ static int l1ctl_sock_data_cb(struct osmo_fd *ofd, unsigned int what) if (rc == len) { msgb_put(msg, rc); - msg->l1h = msgb_data(msg); + l1h = msgb_data(msg); + msg->l1h = l1h; lsi->recv_cb(lsi, msg); return 0; } diff --git a/src/host/virt_phy/src/virt_l1_model.h b/src/host/virt_phy/src/virt_l1_model.h index 55a1e3ae..f0619ab7 100644 --- a/src/host/virt_phy/src/virt_l1_model.h +++ b/src/host/virt_phy/src/virt_l1_model.h @@ -13,6 +13,7 @@ struct l1_model_ms { //TODO: must contain logical channel information (fram number, ciphering mode, ...) struct l1_state_ms { + uint8_t camping; /* the cell on which we are camping right now */ struct l1_cell_info serving_cell; |