1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
/*
* (C) 2013,2014 by Holger Hans Peter Freyther
*
* 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>
#include <osmo-bts/l1sap.h>
#include <osmo-bts/power_control.h>
#include "femtobts.h"
#include "l1_if.h"
#include "utils.h"
#include <sysmocom/femtobts/gsml1prim.h>
#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;
struct gsm_bts_trx trx;
struct phy_instance pinst;
struct femtol1_hdl hdl;
int i;
memset(&bts, 0, sizeof(bts));
memset(&trx, 0, sizeof(trx));
memset(&pinst, 0, sizeof(pinst));
memset(&hdl, 0, sizeof(hdl));
trx.bts = &bts;
trx.pinst = &pinst;
trx.pinst->u.sysmobts.hdl = &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;
/* 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;
bts.auto_band = 0;
bts.band = direct_map[i][0];
arfcn = direct_map[i][2];
res = sysmobts_select_femto_band(&trx, arfcn);
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;
bts.auto_band = 1;
bts.band = direct_map[i][0];
arfcn = direct_map[i][2];
res = sysmobts_select_femto_band(&trx, arfcn);
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;
bts.auto_band = 1;
bts.band = dcs_to_dcs[i][0];
arfcn = dcs_to_dcs[i][2];
res = sysmobts_select_femto_band(&trx, arfcn);
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;
bts.auto_band = 1;
bts.band = pcs_to_pcs[i][0];
arfcn = pcs_to_pcs[i][2];
res = sysmobts_select_femto_band(&trx, arfcn);
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]);
}
}
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);
rc = bts_check_for_first_ciphrd(&lchan, unit.u8Buffer, unit.u8Size);
OSMO_ASSERT(rc == 0);
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);
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 */
}
int main(int argc, char **argv)
{
printf("Testing sysmobts routines\n");
test_sysmobts_auto_band();
test_sysmobts_cipher();
return 0;
}
/*
* 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; }
int bts_model_trx_init(struct gsm_bts_trx *trx)
{ return 0; }
int bts_model_oml_estab(struct gsm_bts *bts)
{ return 0; }
void bts_model_abis_close(struct gsm_bts *bts)
{ }
void bts_model_phy_link_set_defaults(struct phy_link *plink)
{ }
void bts_model_phy_instance_set_defaults(struct phy_instance *pinst)
{ }
|