2013-06-20 15:18:38 +00:00
|
|
|
/*
|
2014-08-09 07:17:14 +00:00
|
|
|
* (C) 2013,2014 by Holger Hans Peter Freyther
|
2013-06-20 15:18:38 +00:00
|
|
|
*
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <osmo-bts/bts.h>
|
2014-08-27 20:13:18 +00:00
|
|
|
#include <osmo-bts/l1sap.h>
|
2015-09-06 10:33:16 +00:00
|
|
|
#include <osmo-bts/power_control.h>
|
2013-06-20 15:18:38 +00:00
|
|
|
|
|
|
|
#include "femtobts.h"
|
2013-10-10 19:28:35 +00:00
|
|
|
#include "l1_if.h"
|
2013-06-20 15:18:38 +00:00
|
|
|
#include "utils.h"
|
|
|
|
|
2014-08-09 07:17:14 +00:00
|
|
|
#include <sysmocom/femtobts/gsml1prim.h>
|
|
|
|
|
2013-06-20 15:18:38 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
static int direct_map[][3] = {
|
|
|
|
{ GSM_BAND_850, GsmL1_FreqBand_850, 128 },
|
|
|
|
{ GSM_BAND_900, GsmL1_FreqBand_900, 1 },
|
|
|
|
{ GSM_BAND_1800, GsmL1_FreqBand_1800, 600 },
|
|
|
|
{ GSM_BAND_1900, GsmL1_FreqBand_1900, 600 },
|
|
|
|
};
|
|
|
|
|
|
|
|
static int dcs_to_dcs[][3] = {
|
|
|
|
{ GSM_BAND_900, GsmL1_FreqBand_1800, 600 },
|
|
|
|
{ GSM_BAND_1800, GsmL1_FreqBand_900, 1 },
|
|
|
|
{ GSM_BAND_900, -1, 438 },
|
|
|
|
};
|
|
|
|
|
|
|
|
static int pcs_to_pcs[][3] = {
|
|
|
|
{ GSM_BAND_850, GsmL1_FreqBand_1900, 512 },
|
|
|
|
{ GSM_BAND_1900, GsmL1_FreqBand_850, 128 },
|
|
|
|
{ GSM_BAND_900, -1, 438 },
|
|
|
|
};
|
|
|
|
|
|
|
|
static void test_sysmobts_auto_band(void)
|
|
|
|
{
|
|
|
|
struct gsm_bts bts;
|
2013-10-10 19:28:35 +00:00
|
|
|
struct gsm_bts_trx trx;
|
|
|
|
struct femtol1_hdl hdl;
|
2013-06-20 15:18:38 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
memset(&bts, 0, sizeof(bts));
|
2013-10-10 19:28:35 +00:00
|
|
|
memset(&trx, 0, sizeof(trx));
|
|
|
|
memset(&hdl, 0, sizeof(hdl));
|
|
|
|
trx.bts = &bts;
|
|
|
|
trx.role_bts.l1h = &hdl;
|
|
|
|
|
|
|
|
/* claim to support all hw_info's */
|
|
|
|
hdl.hw_info.band_support = GSM_BAND_850 | GSM_BAND_900 |
|
|
|
|
GSM_BAND_1800 | GSM_BAND_1900;
|
2013-06-20 15:18:38 +00:00
|
|
|
|
|
|
|
/* start with the current option */
|
|
|
|
printf("Testing the no auto-band mapping.\n");
|
|
|
|
for (i = 0; i < ARRAY_SIZE(direct_map); ++i) {
|
|
|
|
uint16_t arfcn;
|
|
|
|
int res;
|
|
|
|
|
2018-03-17 11:22:40 +00:00
|
|
|
bts.auto_band = 0;
|
2013-06-20 15:18:38 +00:00
|
|
|
bts.band = direct_map[i][0];
|
|
|
|
arfcn = direct_map[i][2];
|
2013-10-10 19:28:35 +00:00
|
|
|
res = sysmobts_select_femto_band(&trx, arfcn);
|
2013-06-20 15:18:38 +00:00
|
|
|
printf("No auto-band band(%d) arfcn(%u) want(%d) got(%d)\n",
|
|
|
|
bts.band, arfcn, direct_map[i][1], res);
|
|
|
|
OSMO_ASSERT(res == direct_map[i][1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if auto-band does not break things */
|
|
|
|
printf("Checking the mapping with auto-band.\n");
|
|
|
|
for (i = 0; i < ARRAY_SIZE(direct_map); ++i) {
|
|
|
|
uint16_t arfcn;
|
|
|
|
int res;
|
|
|
|
|
2018-03-17 11:22:40 +00:00
|
|
|
bts.auto_band = 1;
|
2013-06-20 15:18:38 +00:00
|
|
|
bts.band = direct_map[i][0];
|
|
|
|
arfcn = direct_map[i][2];
|
2013-10-10 19:28:35 +00:00
|
|
|
res = sysmobts_select_femto_band(&trx, arfcn);
|
2013-06-20 15:18:38 +00:00
|
|
|
printf("Auto-band band(%d) arfcn(%u) want(%d) got(%d)\n",
|
|
|
|
bts.band, arfcn, direct_map[i][1], res);
|
|
|
|
OSMO_ASSERT(res == direct_map[i][1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check DCS to DCS change */
|
|
|
|
printf("Checking DCS to DCS\n");
|
|
|
|
for (i = 0; i < ARRAY_SIZE(dcs_to_dcs); ++i) {
|
|
|
|
uint16_t arfcn;
|
|
|
|
int res;
|
|
|
|
|
2018-03-17 11:22:40 +00:00
|
|
|
bts.auto_band = 1;
|
2013-06-20 15:18:38 +00:00
|
|
|
bts.band = dcs_to_dcs[i][0];
|
|
|
|
arfcn = dcs_to_dcs[i][2];
|
2013-10-10 19:28:35 +00:00
|
|
|
res = sysmobts_select_femto_band(&trx, arfcn);
|
2013-06-20 15:18:38 +00:00
|
|
|
printf("DCS to DCS band(%d) arfcn(%u) want(%d) got(%d)\n",
|
|
|
|
bts.band, arfcn, dcs_to_dcs[i][1], res);
|
|
|
|
OSMO_ASSERT(res == dcs_to_dcs[i][1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for a PCS to PCS change */
|
|
|
|
printf("Checking PCS to PCS\n");
|
|
|
|
for (i = 0; i < ARRAY_SIZE(pcs_to_pcs); ++i) {
|
|
|
|
uint16_t arfcn;
|
|
|
|
int res;
|
|
|
|
|
2018-03-17 11:22:40 +00:00
|
|
|
bts.auto_band = 1;
|
2013-06-20 15:18:38 +00:00
|
|
|
bts.band = pcs_to_pcs[i][0];
|
|
|
|
arfcn = pcs_to_pcs[i][2];
|
2013-10-10 19:28:35 +00:00
|
|
|
res = sysmobts_select_femto_band(&trx, arfcn);
|
2013-06-20 15:18:38 +00:00
|
|
|
printf("PCS to PCS band(%d) arfcn(%u) want(%d) got(%d)\n",
|
|
|
|
bts.band, arfcn, pcs_to_pcs[i][1], res);
|
|
|
|
OSMO_ASSERT(res == pcs_to_pcs[i][1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-09 07:17:14 +00:00
|
|
|
static void test_sysmobts_cipher(void)
|
|
|
|
{
|
|
|
|
static const uint8_t cipher_cmd[] = {
|
|
|
|
0x03, 0x00, 0x0d, 0x06, 0x35, 0x11, 0x2b, 0x2b,
|
|
|
|
0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
|
|
|
|
0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b };
|
|
|
|
static const uint8_t too_early_classmark[] = {
|
|
|
|
0x01, 0x00, 0x4d, 0x06, 0x16, 0x03, 0x30, 0x18,
|
|
|
|
0xa2, 0x20, 0x0b, 0x60, 0x14, 0x4c, 0xa7, 0x7b,
|
|
|
|
0x29, 0x11, 0xdc, 0x40, 0x04, 0x00, 0x2b };
|
|
|
|
static const uint8_t first_ciphered_cipher_cmpl[] = {
|
|
|
|
0x01, 0x30, 0x4d, 0x06, 0x16, 0x03, 0x30, 0x18,
|
|
|
|
0xa2, 0x20, 0x0b, 0x60, 0x14, 0x4c, 0xa7, 0x7b,
|
|
|
|
0x29, 0x11, 0xdc, 0x40, 0x04, 0x00, 0x2b };
|
|
|
|
|
|
|
|
struct gsm_lchan lchan;
|
|
|
|
struct femtol1_hdl fl1h;
|
|
|
|
struct msgb *msg;
|
|
|
|
GsmL1_MsgUnitParam_t unit;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
memset(&lchan, 0, sizeof(lchan));
|
|
|
|
memset(&fl1h, 0, sizeof(fl1h));
|
|
|
|
|
|
|
|
/* Inject the cipher mode command */
|
|
|
|
msg = msgb_alloc_headroom(128, 64, "ciphering mode command");
|
|
|
|
lchan.ciph_state = LCHAN_CIPH_NONE;
|
|
|
|
memcpy(msgb_put(msg, ARRAY_SIZE(cipher_cmd)), cipher_cmd, ARRAY_SIZE(cipher_cmd));
|
|
|
|
rc = bts_check_for_ciph_cmd(&fl1h, msg, &lchan);
|
|
|
|
OSMO_ASSERT(rc == 1);
|
|
|
|
OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_RX_REQ);
|
|
|
|
OSMO_ASSERT(lchan.ciph_ns == 1);
|
|
|
|
msgb_free(msg);
|
|
|
|
|
|
|
|
/* Move to the confirmed state */
|
|
|
|
lchan.ciph_state = LCHAN_CIPH_RX_CONF;
|
|
|
|
|
|
|
|
/* Handle message sent before ciphering was received */
|
|
|
|
memcpy(&unit.u8Buffer[0], too_early_classmark, ARRAY_SIZE(too_early_classmark));
|
|
|
|
unit.u8Size = ARRAY_SIZE(too_early_classmark);
|
2014-08-27 20:13:18 +00:00
|
|
|
rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size);
|
|
|
|
OSMO_ASSERT(rc == 0);
|
2014-08-09 07:17:14 +00:00
|
|
|
OSMO_ASSERT(lchan.ciph_state == LCHAN_CIPH_RX_CONF);
|
|
|
|
|
|
|
|
/* Now send the first ciphered message */
|
|
|
|
memcpy(&unit.u8Buffer[0], first_ciphered_cipher_cmpl, ARRAY_SIZE(first_ciphered_cipher_cmpl));
|
|
|
|
unit.u8Size = ARRAY_SIZE(first_ciphered_cipher_cmpl);
|
2014-08-27 20:13:18 +00:00
|
|
|
rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size);
|
|
|
|
OSMO_ASSERT(rc == 1);
|
|
|
|
/* we cannot test for lchan.ciph_state == * LCHAN_CIPH_RX_CONF_TX_REQ, as
|
|
|
|
* this happens asynchronously on the other side of the l1sap queue */
|
2014-08-09 07:17:14 +00:00
|
|
|
}
|
|
|
|
|
2013-06-20 15:18:38 +00:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
printf("Testing sysmobts routines\n");
|
|
|
|
test_sysmobts_auto_band();
|
2014-08-09 07:17:14 +00:00
|
|
|
test_sysmobts_cipher();
|
2017-10-11 14:37:44 +00:00
|
|
|
|
2013-06-20 15:18:38 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2014-08-09 07:17:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* some local stubs. We need to pull in a lot more code and can't
|
|
|
|
* use the generic stubs unless we make all of them weak
|
|
|
|
*/
|
|
|
|
void bts_update_status(enum bts_global_status which, int on)
|
|
|
|
{}
|
|
|
|
|
|
|
|
int bts_model_init(struct gsm_bts *bts)
|
|
|
|
{ return 0; }
|
2018-11-12 11:50:23 +00:00
|
|
|
int bts_model_trx_init(struct gsm_bts_trx *trx)
|
|
|
|
{ return 0; }
|
2014-08-09 07:17:14 +00:00
|
|
|
int bts_model_oml_estab(struct gsm_bts *bts)
|
|
|
|
{ return 0; }
|
2013-02-05 15:47:57 +00:00
|
|
|
void bts_model_abis_close(struct gsm_bts *bts)
|
|
|
|
{ }
|
2016-01-19 19:22:07 +00:00
|
|
|
void bts_model_phy_link_set_defaults(struct phy_link *plink)
|
|
|
|
{ }
|
|
|
|
void bts_model_phy_instance_set_defaults(struct phy_instance *pinst)
|
|
|
|
{ }
|