* add more detailed status printout to bs11_config
* add support for real LMT logon time * add support for abis external time * move 'create_trx1_objects' to separate function
This commit is contained in:
parent
4fc898a0d5
commit
268bb40b35
|
@ -403,16 +403,30 @@ enum abis_bs11_trx_power {
|
|||
BS11_TRX_POWER_DCS_160mW= 0x0d,
|
||||
};
|
||||
|
||||
enum abis_bs11_state {
|
||||
enum abis_bs11_phase {
|
||||
BS11_STATE_SOFTWARE_RQD = 0x01,
|
||||
BS11_STATE_LOAD_SMU_INTENDED = 0x11,
|
||||
BS11_STATE_LOAD_SMU_SAFETY = 0x21,
|
||||
BS11_STATE_WARM_UP = 0x51,
|
||||
BS11_STATE_WAIT_MIN_CFG = 0x62,
|
||||
BS11_STATE_MAINTENANCE = 0x72,
|
||||
BS11_STATE_LOAD_MBCCU = 0x92,
|
||||
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
|
||||
BS11_STATE_NORMAL = 0x03,
|
||||
};
|
||||
|
||||
struct abis_nm_bs11_state {
|
||||
u_int8_t unknown;
|
||||
u_int8_t unknown2;
|
||||
u_int8_t phase;
|
||||
u_int8_t mbccu;
|
||||
u_int8_t unknown3;
|
||||
u_int8_t ccu;
|
||||
u_int8_t t_link;
|
||||
u_int8_t abis_link;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
struct msgb;
|
||||
|
@ -463,5 +477,6 @@ int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
|
|||
int abis_nm_bs11_get_state(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
|
||||
u_int8_t win_size, gsm_cbfn *cbfn);
|
||||
int abis_nm_bs11_set_ext_time(struct gsm_bts *bts);
|
||||
|
||||
#endif /* _NM_H */
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
#include <libgen.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -836,6 +837,31 @@ int abis_nm_event_reports(struct gsm_bts *bts, int on)
|
|||
|
||||
/* Siemens (or BS-11) specific commands */
|
||||
|
||||
struct bs11_date_time {
|
||||
u_int16_t year;
|
||||
u_int8_t month;
|
||||
u_int8_t day;
|
||||
u_int8_t hour;
|
||||
u_int8_t min;
|
||||
u_int8_t sec;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
void get_bs11_date_time(struct bs11_date_time *aet)
|
||||
{
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
|
||||
t = time(NULL);
|
||||
tm = localtime(&t);
|
||||
aet->sec = tm->tm_sec;
|
||||
aet->min = tm->tm_min;
|
||||
aet->hour = tm->tm_hour;
|
||||
aet->day = tm->tm_mday;
|
||||
aet->month = tm->tm_mon;
|
||||
aet->year = htons(1900 + tm->tm_year);
|
||||
}
|
||||
|
||||
int abis_nm_bs11_reset_resource(struct gsm_bts *bts)
|
||||
{
|
||||
return __simple_cmd(bts, NM_MT_BS11_RESET_RESOURCE);
|
||||
|
@ -859,7 +885,7 @@ int abis_nm_bs11_create_object(struct gsm_bts *bts,
|
|||
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
fill_om_fom_hdr(oh, attr_len, NM_MT_BS11_CREATE_OBJ,
|
||||
NM_OC_BS11, type, idx, 0);
|
||||
NM_OC_BS11, type, 0, idx);
|
||||
cur = msgb_put(msg, attr_len);
|
||||
memcpy(cur, attr, attr_len);
|
||||
|
||||
|
@ -936,8 +962,7 @@ int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level)
|
|||
return abis_nm_sendmsg(trx->bts, msg);
|
||||
}
|
||||
|
||||
static const u_int8_t bs11_logon_c7[] =
|
||||
{ 0x07, 0xd9, 0x01, 0x11, 0x0d, 0x10, 0x20 };
|
||||
//static const u_int8_t bs11_logon_c7[] = { 0x07, 0xd9, 0x01, 0x11, 0x0d, 0x10, 0x20 };
|
||||
static const u_int8_t bs11_logon_c8[] = { 0x02 };
|
||||
static const u_int8_t bs11_logon_c9[] = "FACTORY";
|
||||
|
||||
|
@ -945,15 +970,18 @@ int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on)
|
|||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct msgb *msg = nm_msgb_alloc();
|
||||
struct bs11_date_time bdt;
|
||||
|
||||
get_bs11_date_time(&bdt);
|
||||
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
if (on) {
|
||||
u_int8_t len = 3*2 + sizeof(bs11_logon_c7)
|
||||
u_int8_t len = 3*2 + sizeof(bdt)
|
||||
+ sizeof(bs11_logon_c8) + sizeof(bs11_logon_c9);
|
||||
fill_om_fom_hdr(oh, len, NM_MT_BS11_LMT_LOGON,
|
||||
NM_OC_BS11_A3, 0xff, 0xff, 0xff);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_LOGIN_TIME,
|
||||
sizeof(bs11_logon_c7), bs11_logon_c7);
|
||||
sizeof(bdt), &bdt);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_ACC_LEV,
|
||||
sizeof(bs11_logon_c8), bs11_logon_c8);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_NAME,
|
||||
|
@ -1182,3 +1210,19 @@ int abis_nm_bs11_get_serno(struct gsm_bts *bts)
|
|||
|
||||
return abis_nm_sendmsg(bts, msg);
|
||||
}
|
||||
|
||||
int abis_nm_bs11_set_ext_time(struct gsm_bts *bts)
|
||||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct msgb *msg = nm_msgb_alloc();
|
||||
struct bs11_date_time aet;
|
||||
|
||||
get_bs11_date_time(&aet);
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
/* SiemensHW CCTRL object */
|
||||
fill_om_fom_hdr(oh, 2+sizeof(aet), NM_MT_BS11_SET_ATTR, NM_OC_SITE_MANAGER,
|
||||
0xff, 0xff, 0xff);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_ABIS_EXT_TIME, sizeof(aet), &aet);
|
||||
|
||||
return abis_nm_sendmsg(bts, msg);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,27 @@ static struct serial_handle _ser_handle, *ser_handle = &_ser_handle;
|
|||
|
||||
static int handle_serial_msg(struct msgb *rx_msg);
|
||||
|
||||
static int create_trx1_objects(struct gsm_bts *bts)
|
||||
{
|
||||
u_int8_t bbsig1_attr[sizeof(obj_bbsig0_attr)+12];
|
||||
u_int8_t *cur = bbsig1_attr;
|
||||
|
||||
abis_nm_bs11_set_trx1_pw(bts, trx1_password);
|
||||
|
||||
cur = tlv_put(cur, NM_ATT_BS11_PASSWORD, 10,
|
||||
(u_int8_t *)trx1_password);
|
||||
memcpy(cur, obj_bbsig0_attr, sizeof(obj_bbsig0_attr));
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_BBSIG, 1,
|
||||
sizeof(bbsig1_attr), bbsig1_attr);
|
||||
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 1,
|
||||
sizeof(obj_pa0_attr), obj_pa0_attr);
|
||||
|
||||
abis_nm_bs11_set_trx_power(&bts->trx[1], BS11_TRX_POWER_GSM_30mW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create all objects for an initial configuration */
|
||||
static int create_objects(struct gsm_bts *bts, int trx1)
|
||||
{
|
||||
|
@ -94,22 +115,6 @@ static int create_objects(struct gsm_bts *bts, int trx1)
|
|||
sizeof(obj_bbsig0_attr), obj_bbsig0_attr);
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 0,
|
||||
sizeof(obj_pa0_attr), obj_pa0_attr);
|
||||
if (trx1) {
|
||||
u_int8_t bbsig1_attr[sizeof(obj_bbsig0_attr)+12];
|
||||
u_int8_t *cur = bbsig1_attr;
|
||||
|
||||
abis_nm_bs11_set_trx1_pw(bts, trx1_password);
|
||||
|
||||
cur = tlv_put(cur, NM_ATT_BS11_PASSWORD, 10,
|
||||
(u_int8_t *)trx1_password);
|
||||
memcpy(cur, obj_bbsig0_attr, sizeof(obj_bbsig0_attr));
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_BBSIG, 1,
|
||||
sizeof(bbsig1_attr), bbsig1_attr);
|
||||
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_PA, 1,
|
||||
sizeof(obj_pa0_attr), obj_pa0_attr);
|
||||
}
|
||||
|
||||
abis_nm_bs11_create_envaBTSE(bts, 0);
|
||||
abis_nm_bs11_create_envaBTSE(bts, 1);
|
||||
abis_nm_bs11_create_envaBTSE(bts, 2);
|
||||
|
@ -119,10 +124,6 @@ static int create_objects(struct gsm_bts *bts, int trx1)
|
|||
abis_nm_bs11_set_oml_tei(bts, TEI_OML);
|
||||
|
||||
abis_nm_bs11_set_trx_power(&bts->trx[0], BS11_TRX_POWER_GSM_30mW);
|
||||
|
||||
if (trx1)
|
||||
abis_nm_bs11_set_trx_power(&bts->trx[1], BS11_TRX_POWER_GSM_30mW);
|
||||
|
||||
//abis_nm_bs11_factory_logon(bts, 0);
|
||||
|
||||
return 0;
|
||||
|
@ -336,24 +337,99 @@ static int swload_cbfn(unsigned int hook, unsigned int event, struct msgb *msg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* handle a response from the BTS to a GET STATE command */
|
||||
static int handle_state_resp(u_int8_t state)
|
||||
static const char *bs11_link_state[] = {
|
||||
[0x00] = "Down",
|
||||
[0x01] = "Up",
|
||||
[0x02] = "Restoring",
|
||||
};
|
||||
|
||||
static const char *linkstate_name(u_int8_t linkstate)
|
||||
{
|
||||
int rc = 0;
|
||||
if (linkstate > ARRAY_SIZE(bs11_link_state))
|
||||
return "Unknown";
|
||||
|
||||
printf("STATE: ");
|
||||
return bs11_link_state[linkstate];
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
static const char *mbccu_load[] = {
|
||||
[0] = "No Load",
|
||||
[1] = "Load BTSCAC",
|
||||
[2] = "Load BTSDRX",
|
||||
[3] = "Load BTSBBX",
|
||||
[4] = "Load BTSARC",
|
||||
[5] = "Load",
|
||||
};
|
||||
|
||||
static const char *mbccu_load_name(u_int8_t linkstate)
|
||||
{
|
||||
if (linkstate > ARRAY_SIZE(mbccu_load))
|
||||
return "Unknown";
|
||||
|
||||
return mbccu_load[linkstate];
|
||||
}
|
||||
|
||||
|
||||
static void print_state(struct abis_nm_bs11_state *st)
|
||||
{
|
||||
enum abis_bs11_phase phase = st->phase;
|
||||
|
||||
printf("T-Link: %-9s Abis-link: %-9s MBCCU0: %-11s MBCCU1: %-11s PHASE: %u SUBPHASE: ",
|
||||
linkstate_name(st->t_link), linkstate_name(st->abis_link),
|
||||
mbccu_load_name(st->mbccu >> 4), mbccu_load_name(st->mbccu & 0xf),
|
||||
phase & 0xf);
|
||||
|
||||
switch (phase) {
|
||||
case BS11_STATE_WARM_UP:
|
||||
printf("Warm Up...\n");
|
||||
sleep(5);
|
||||
break;
|
||||
case BS11_STATE_LOAD_SMU_SAFETY:
|
||||
printf("Load SMU Safety...\n");
|
||||
sleep(5);
|
||||
break;
|
||||
case BS11_STATE_LOAD_SMU_INTENDED:
|
||||
printf("Load SMU Intended...\n");
|
||||
break;
|
||||
case BS11_STATE_LOAD_MBCCU:
|
||||
printf("Load MBCCU...\n");
|
||||
break;
|
||||
case BS11_STATE_SOFTWARE_RQD:
|
||||
printf("Software required...\n");
|
||||
break;
|
||||
case BS11_STATE_WAIT_MIN_CFG:
|
||||
case BS11_STATE_WAIT_MIN_CFG_2:
|
||||
printf("Wait minimal config...\n");
|
||||
break;
|
||||
case BS11_STATE_MAINTENANCE:
|
||||
printf("Maintenance...\n");
|
||||
break;
|
||||
case BS11_STATE_NORMAL:
|
||||
printf("Normal...\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown phase 0x%02x\n", phase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle a response from the BTS to a GET STATE command */
|
||||
static int handle_state_resp(enum abis_bs11_phase state)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
printf("PHASE: %u STATE: ", state & 0xf);
|
||||
|
||||
switch (state) {
|
||||
case BS11_STATE_WARM_UP:
|
||||
sleep(5);
|
||||
break;
|
||||
case BS11_STATE_LOAD_SMU_SAFETY:
|
||||
sleep(5);
|
||||
break;
|
||||
case BS11_STATE_LOAD_SMU_INTENDED:
|
||||
sleep(5);
|
||||
break;
|
||||
case BS11_STATE_LOAD_MBCCU:
|
||||
break;
|
||||
case BS11_STATE_SOFTWARE_RQD:
|
||||
bs11cfg_state = STATE_SWLOAD;
|
||||
/* send safety load. Use g_bts as private 'param'
|
||||
* argument, so our swload_cbfn can distinguish
|
||||
|
@ -368,12 +444,10 @@ static int handle_state_resp(u_int8_t state)
|
|||
break;
|
||||
case BS11_STATE_WAIT_MIN_CFG:
|
||||
case BS11_STATE_WAIT_MIN_CFG_2:
|
||||
printf("Wait minimal config...\n");
|
||||
bs11cfg_state = STATE_SWLOAD;
|
||||
rc = create_objects(g_bts, have_trx1);
|
||||
break;
|
||||
case BS11_STATE_MAINTENANCE:
|
||||
printf("Maintenance...\n");
|
||||
bs11cfg_state = STATE_SWLOAD;
|
||||
/* send software (FIXME: over A-bis?) */
|
||||
if (file_is_readable(fname_software))
|
||||
|
@ -384,10 +458,10 @@ static int handle_state_resp(u_int8_t state)
|
|||
fname_software);
|
||||
break;
|
||||
case BS11_STATE_NORMAL:
|
||||
printf("Normal...\n");
|
||||
if (have_trx1)
|
||||
create_trx1_objects(g_bts);
|
||||
return 1;
|
||||
default:
|
||||
printf("Unknown state 0x%02u\n", state);
|
||||
sleep(5);
|
||||
break;
|
||||
}
|
||||
|
@ -399,6 +473,7 @@ static int handle_serial_msg(struct msgb *rx_msg)
|
|||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct abis_om_fom_hdr *foh;
|
||||
struct abis_nm_bs11_state *st;
|
||||
int rc = -1;
|
||||
|
||||
if (rx_msg->len < LAPD_HDR_LEN
|
||||
|
@ -427,7 +502,9 @@ static int handle_serial_msg(struct msgb *rx_msg)
|
|||
exit(0);
|
||||
break;
|
||||
case NM_MT_BS11_GET_STATE_ACK:
|
||||
rc = handle_state_resp(foh->data[2]);
|
||||
st = (struct abis_nm_bs11_state *) &foh->data[0];
|
||||
print_state(st);
|
||||
rc = handle_state_resp(st->phase);
|
||||
break;
|
||||
default:
|
||||
rc = abis_nm_rcvmsg(rx_msg);
|
||||
|
|
Loading…
Reference in New Issue