diff --git a/include/openbsc/abis_nm.h b/include/openbsc/abis_nm.h index b86e0221a..c980d1850 100644 --- a/include/openbsc/abis_nm.h +++ b/include/openbsc/abis_nm.h @@ -187,6 +187,8 @@ enum abis_nm_msgtype { NM_MT_BS11_SET_ATTR = 0xd0, NM_MT_BS11_SET_ATTR_ACK, + NM_MT_BS11_GET_STATE = 0xe3, + NM_MT_BS11_GET_STATE_ACK, NM_MT_BS11_FACTORY_LOGON = 0xe5, NM_MT_BS11_FACTORY_LOGON_ACK, NM_MT_BS11_RESTART = 0xe7, @@ -290,6 +292,8 @@ enum abis_nm_attr { NM_ATT_FILE_DATA, NM_ATT_MEAS_RES, NM_ATT_MEAS_TYPE, + + NM_ATT_BS11_PASSWORD = 0xfd, }; /* Section 9.4.4: Administrative State */ @@ -332,6 +336,20 @@ enum abis_bs11_objtype { BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/ }; +enum abis_bs11_trx_power { + BS11_TRX_POWER_30mW = 0x09, +}; + +enum abis_bs11_state { + BS11_STATE_SOFTWARE_RQD = 0x01, + BS11_STATE_NORMAL = 0x03, + BS11_STATE_LOAD_SMU_SAFETY = 0x21, + BS11_STATE_WARM_UP = 0x51, + BS11_STATE_WAIT_MIN_CFG = 0x62, + BS11_STATE_MAINTENANCE = 0x72, + BS11_STATE_WAIT_MIN_CFG_2 = 0xA2, +}; + /* PUBLIC */ struct msgb; @@ -365,13 +383,15 @@ int abis_nm_reset_resource(struct gsm_bts *bts); /* Siemens / BS-11 specific */ int abis_nm_bs11_db_transmission(struct gsm_bts *bts, int begin); int abis_nm_bs11_create_object(struct gsm_bts *bts, enum abis_bs11_objtype type, - u_int8_t idx); + u_int8_t idx, u_int8_t attr_len, const u_int8_t *attr); int abis_nm_bs11_create_envaBTSE(struct gsm_bts *bts, u_int8_t idx); int abis_nm_bs11_create_bport(struct gsm_bts *bts, u_int8_t idx); int abis_nm_bs11_set_oml_tei(struct gsm_bts *bts, u_int8_t tei); int abis_nm_bs11_conn_oml(struct gsm_bts *bts, u_int8_t e1_port, u_int8_t e1_timeslot, u_int8_t e1_subslot); int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level); -int abis_nm_bs11_factory_logon(struct gsm_bts *bts); +int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on); +int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password); +int abis_nm_bs11_get_state(struct gsm_bts *bts); #endif /* _NM_H */ diff --git a/src/abis_nm.c b/src/abis_nm.c index 2ce5923a3..ecbb94868 100644 --- a/src/abis_nm.c +++ b/src/abis_nm.c @@ -444,14 +444,18 @@ int abis_nm_bs11_db_transmission(struct gsm_bts *bts, int begin) } int abis_nm_bs11_create_object(struct gsm_bts *bts, - enum abis_bs11_objtype type, u_int8_t idx) + enum abis_bs11_objtype type, u_int8_t idx, + u_int8_t attr_len, const u_int8_t *attr) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); + u_int8_t *cur; oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); - fill_om_fom_hdr(oh, 0, NM_MT_BS11_CREATE_OBJ, NM_OC_BS11, - type, idx, 0); + fill_om_fom_hdr(oh, sizeof(*oh)+attr_len, NM_MT_BS11_CREATE_OBJ, + NM_OC_BS11, type, idx, 0); + cur = msgb_put(msg, attr_len); + memcpy(cur, attr, attr_len); return abis_nm_sendmsg(bts, msg); } @@ -460,10 +464,12 @@ int abis_nm_bs11_create_envaBTSE(struct gsm_bts *bts, u_int8_t idx) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); + u_int8_t zero = 0x00; oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); - fill_om_fom_hdr(oh, 0, NM_MT_BS11_CREATE_OBJ, NM_OC_BS11_ENVABTSE, - 0, idx, 0); + fill_om_fom_hdr(oh, sizeof(*oh)+3, NM_MT_BS11_CREATE_OBJ, + NM_OC_BS11_ENVABTSE, 0, idx, 0xff); + msgb_tlv_put(msg, 0x99, 1, &zero); return abis_nm_sendmsg(bts, msg); } @@ -532,7 +538,7 @@ static const u_int8_t bs11_logon_c7[] = static const u_int8_t bs11_logon_c8[] = { 0x01, 0x02 }; static const u_int8_t bs11_logon_c9[] = "FACTORY"; -int abis_nm_bs11_factory_logon(struct gsm_bts *bts) +int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on) { struct abis_om_hdr *oh; struct msgb *msg = nm_msgb_alloc(); @@ -540,11 +546,38 @@ int abis_nm_bs11_factory_logon(struct gsm_bts *bts) + sizeof(bs11_logon_c8) + sizeof(bs11_logon_c9); oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); - fill_om_fom_hdr(oh, len, NM_MT_BS11_FACTORY_LOGON, - NM_OC_BS11_A3, 0xff, 0xff, 0xff); - msgb_tlv_put(msg, 0xc7, sizeof(bs11_logon_c7), bs11_logon_c7); - msgb_tlv_put(msg, 0xc8, sizeof(bs11_logon_c8), bs11_logon_c8); - msgb_tlv_put(msg, 0xc9, sizeof(bs11_logon_c9), bs11_logon_c9); + if (on) { + fill_om_fom_hdr(oh, len, NM_MT_BS11_FACTORY_LOGON, + NM_OC_BS11_A3, 0xff, 0xff, 0xff); + msgb_tlv_put(msg, 0xc7, sizeof(bs11_logon_c7), bs11_logon_c7); + msgb_tlv_put(msg, 0xc8, sizeof(bs11_logon_c8), bs11_logon_c8); + msgb_tlv_put(msg, 0xc9, sizeof(bs11_logon_c9), bs11_logon_c9); + } else { + fill_om_fom_hdr(oh, sizeof(*oh), NM_MT_BS11_LOGOFF, + NM_OC_BS11_A3, 0xff, 0xff, 0xff); + } return abis_nm_sendmsg(bts, msg); } + +int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password) +{ + struct abis_om_hdr *oh; + struct msgb *msg; + + if (strlen(password) != 10) + return -EINVAL; + + msg = nm_msgb_alloc(); + oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE); + fill_om_fom_hdr(oh, sizeof(*oh)+2+strlen(password), NM_MT_BS11_SET_ATTR, + NM_OC_BS11, BS11_OBJ_TRX1, 0x00, 0x00); + msgb_tlv_put(msg, NM_ATT_BS11_PASSWORD, 10, (const u_int8_t *)password); + + return abis_nm_sendmsg(bts, msg); +} + +int abis_nm_bs11_get_state(struct gsm_bts *bts) +{ + return __simple_cmd(bts, NM_MT_BS11_GET_STATE); +}