int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) { printf("BSSGP primitive, SAP %d, prim = %d, op = %d, msg = %s\n", oph->sap, oph->primitive, oph->operation, msgb_hexdump(oph->msg)); last_oph.sap = oph->sap; last_oph.primitive = oph->primitive; last_oph.operation = oph->operation; last_oph.msg = NULL; return -1; }
static void test_bssgp_flow_control_bvc(void) { struct bssgp_bvc_ctx bctx = { .nsei = 0x1234, .bvci = 0x5678, }; const uint8_t tag = 42; const uint32_t bmax = 0x1022 * 100; const uint32_t rate = 0xc040 / 8 * 100; const uint32_t bmax_ms = bmax / 2; const uint32_t rate_ms = rate / 2; uint8_t ratio = 0x78; uint32_t qdelay = 0x1144 * 10; int rc; static uint8_t expected_simple_msg[] = { 0x26, 0x1e, 0x81, 0x2a, /* tag */ 0x05, 0x82, 0x10, 0x22, /* Bmax */ 0x03, 0x82, 0xc0, 0x40, /* R */ 0x01, 0x82, 0x08, 0x11, /* Bmax_MS */ 0x1c, 0x82, 0x60, 0x20, /* R_MS */ }; static uint8_t expected_ext_msg[] = { 0x26, 0x1e, 0x81, 0x2a, /* tag */ 0x05, 0x82, 0x10, 0x22, /* Bmax */ 0x03, 0x82, 0xc0, 0x40, /* R */ 0x01, 0x82, 0x08, 0x11, /* Bmax_MS */ 0x1c, 0x82, 0x60, 0x20, /* R_MS */ 0x3c, 0x81, 0x78, /* ratio */ 0x06, 0x82, 0x11, 0x44, /* Qdelay */ }; printf("----- %s START\n", __func__); rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms, NULL, NULL); OSMO_ASSERT(rc >= 0); OSMO_ASSERT(last_ns_tx_msg != NULL); printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg)); OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_simple_msg)); OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg), expected_simple_msg, sizeof(expected_simple_msg))); rc = bssgp_tx_fc_bvc(&bctx, tag, bmax, rate, bmax_ms, rate_ms, &ratio, &qdelay); OSMO_ASSERT(rc >= 0); OSMO_ASSERT(last_ns_tx_msg != NULL); printf("Got message: %s\n", msgb_hexdump(last_ns_tx_msg)); OSMO_ASSERT(msgb_length(last_ns_tx_msg) == sizeof(expected_ext_msg)); OSMO_ASSERT(0 == memcmp(msgb_data(last_ns_tx_msg), expected_ext_msg, sizeof(expected_ext_msg))); msgb_free(last_ns_tx_msg); last_ns_tx_msg = NULL; printf("----- %s END\n", __func__); } static struct log_info info = {}; int main(int argc, char **argv) { struct sockaddr_in bss_peer= {0}; osmo_init_logging(&info); log_set_use_color(osmo_stderr_target, 0); log_set_print_filename(osmo_stderr_target, 0); bssgp_nsi = gprs_ns_instantiate(gprs_ns_callback, NULL); bss_peer.sin_family = AF_INET; bss_peer.sin_port = htons(32000); bss_peer.sin_addr.s_addr = htonl(0x7f0000ff); gprs_ns_nsip_connect(bssgp_nsi, &bss_peer, BSS_NSEI, BSS_NSEI+1); printf("===== BSSGP test START\n"); test_bssgp_suspend_resume(); test_bssgp_status(); test_bssgp_bad_reset(); test_bssgp_flow_control_bvc(); printf("===== BSSGP test END\n\n"); exit(EXIT_SUCCESS); }
/** * @brief General handler for incoming L1CTL messages from layer 2/3. * * This handler will call the specific routine dependent on the L1CTL message type. */ void l1ctl_sap_handler(struct l1_model_ms *ms, struct msgb *msg) { struct l1ctl_hdr *l1h; int log_subsys; if (!msg) return; l1h = (struct l1ctl_hdr *) msg->data; if (sizeof(*l1h) > msg->len) { LOGPMS(DL1C, LOGL_NOTICE, ms, "Malformed message: too short. %u\n", msg->len); goto exit_msgbfree; } if (is_l1ctl_control(l1h->msg_type)) log_subsys = DL1C; else log_subsys = DL1P; DEBUGPMS(log_subsys, ms, "Rx RAW from MS: %s\n", msgb_hexdump(msg)); switch (l1h->msg_type) { case L1CTL_FBSB_REQ: l1ctl_rx_fbsb_req(ms, msg); break; case L1CTL_DM_EST_REQ: l1ctl_rx_dm_est_req(ms, msg); break; case L1CTL_DM_REL_REQ: l1ctl_rx_dm_rel_req(ms, msg); break; case L1CTL_PARAM_REQ: l1ctl_rx_param_req(ms, msg); break; case L1CTL_DM_FREQ_REQ: l1ctl_rx_dm_freq_req(ms,msg); break; case L1CTL_CRYPTO_REQ: l1ctl_rx_crypto_req(ms, msg); break; case L1CTL_RACH_REQ: l1ctl_rx_rach_req(ms, msg); goto exit_nofree; case L1CTL_DATA_REQ: l1ctl_rx_data_req(ms, msg); goto exit_nofree; case L1CTL_PM_REQ: l1ctl_rx_pm_req(ms, msg); break; case L1CTL_RESET_REQ: l1ctl_rx_reset_req(ms, msg); break; case L1CTL_CCCH_MODE_REQ: l1ctl_rx_ccch_mode_req(ms, msg); break; case L1CTL_TCH_MODE_REQ: l1ctl_rx_tch_mode_req(ms, msg); break; case L1CTL_NEIGH_PM_REQ: l1ctl_rx_neigh_pm_req(ms, msg); break; case L1CTL_TRAFFIC_REQ: l1ctl_rx_traffic_req(ms, msg); goto exit_nofree; case L1CTL_SIM_REQ: l1ctl_rx_sim_req(ms, msg); break; case L1CTL_TBF_CFG_REQ: l1ctl_rx_tbf_cfg_req(ms, msg); break; case L1CTL_DATA_TBF_REQ: l1ctl_rx_data_tbf_req(ms, msg); goto exit_nofree; } exit_msgbfree: msgb_free(msg); exit_nofree: return; /* msg is scheduled for uplink and mustn't be freed here */ }