* rename NM_MT_BS11_LOGOFF to NM_MT_BS11_LMT_LOGOFF
* add more BS11 specific attributes * define all valid BS11 PA power classes * add callback function to software load * introduce SWL load function for BS-11 style SWL file lists * separate activation of software from loading of software * add function to obtain BS-11 serial number
This commit is contained in:
parent
8e1e3eece8
commit
5e4d1b3663
|
@ -196,8 +196,8 @@ enum abis_nm_msgtype {
|
|||
NM_MT_BS11_RESTART_ACK,
|
||||
NM_MT_BS11_DISCONNECT = 0xe9,
|
||||
NM_MT_BS11_DISCONNECT_ACK,
|
||||
NM_MT_BS11_LOGOFF = 0xec,
|
||||
NM_MT_BS11_LOGOFF_ACK,
|
||||
NM_MT_BS11_LMT_LOGOFF = 0xec,
|
||||
NM_MT_BS11_LMT_LOGOFF_ACK,
|
||||
NM_MT_BS11_RECONNECT = 0xf1,
|
||||
NM_MT_BS11_RECONNECT_ACK,
|
||||
};
|
||||
|
@ -296,6 +296,11 @@ enum abis_nm_attr {
|
|||
NM_ATT_MEAS_RES,
|
||||
NM_ATT_MEAS_TYPE,
|
||||
|
||||
NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c,
|
||||
NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f,
|
||||
|
||||
NM_ATT_BS11_ESN_PCB_SERIAL = 0x55,
|
||||
|
||||
NM_ATT_BS11_ALL_TEST_CATG = 0x60,
|
||||
NM_ATT_BS11_BTSLS_HOPPING,
|
||||
NM_ATT_BS11_CELL_ALLOC_NR,
|
||||
|
@ -330,7 +335,7 @@ enum abis_nm_attr {
|
|||
NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0,
|
||||
NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb,
|
||||
NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc,
|
||||
NM_ATT_BS11_SW_LOAD_SSTORED = 0xbd,
|
||||
NM_ATT_BS11_SW_LOAD_STORED = 0xbd,
|
||||
|
||||
NM_ATT_BS11_VENDOR_NAME = 0xc1,
|
||||
NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6,
|
||||
|
@ -388,17 +393,24 @@ enum abis_bs11_objtype {
|
|||
};
|
||||
|
||||
enum abis_bs11_trx_power {
|
||||
BS11_TRX_POWER_30mW = 0x09,
|
||||
BS11_TRX_POWER_GSM_2W = 0x06,
|
||||
BS11_TRX_POWER_GSM_250mW= 0x07,
|
||||
BS11_TRX_POWER_GSM_80mW = 0x08,
|
||||
BS11_TRX_POWER_GSM_30mW = 0x09,
|
||||
BS11_TRX_POWER_DCS_3W = 0x0a,
|
||||
BS11_TRX_POWER_DCS_1W6 = 0x0b,
|
||||
BS11_TRX_POWER_DCS_500mW= 0x0c,
|
||||
BS11_TRX_POWER_DCS_160mW= 0x0d,
|
||||
};
|
||||
|
||||
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,
|
||||
BS11_STATE_NORMAL = 0x03,
|
||||
};
|
||||
|
||||
/* PUBLIC */
|
||||
|
@ -430,7 +442,10 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, u_int8_t chan_comb);
|
|||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
|
||||
int abis_nm_event_reports(struct gsm_bts *bts, int on);
|
||||
int abis_nm_reset_resource(struct gsm_bts *bts);
|
||||
int abis_nm_software_load(struct gsm_bts *bts, const char *fname, u_int8_t win);
|
||||
int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
|
||||
u_int8_t win_size, gsm_cbfn *cbfn, void *cb_data);
|
||||
int abis_nm_software_activate(struct gsm_bts *bts, const char *fname,
|
||||
gsm_cbfn *cbfn, void *cb_data);
|
||||
|
||||
/* Siemens / BS-11 specific */
|
||||
int abis_nm_bs11_reset_resource(struct gsm_bts *bts);
|
||||
|
@ -446,5 +461,7 @@ 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 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);
|
||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
|
||||
u_int8_t win_size, gsm_cbfn *cbfn);
|
||||
|
||||
#endif /* _NM_H */
|
||||
|
|
275
src/abis_nm.c
275
src/abis_nm.c
|
@ -26,6 +26,8 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <malloc.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -291,6 +293,9 @@ enum sw_state {
|
|||
|
||||
struct abis_nm_sw {
|
||||
struct gsm_bts *bts;
|
||||
gsm_cbfn *cbfn;
|
||||
void *cb_data;
|
||||
|
||||
/* this will become part of the SW LOAD INITIATE */
|
||||
u_int8_t obj_class;
|
||||
u_int8_t obj_instance[3];
|
||||
|
@ -416,6 +421,7 @@ static int sw_load_end(struct abis_nm_sw *sw)
|
|||
|
||||
return abis_nm_sendmsg(sw->bts, msg);
|
||||
}
|
||||
|
||||
/* Activate the specified software into the BTS */
|
||||
static int sw_activate(struct abis_nm_sw *sw)
|
||||
{
|
||||
|
@ -518,11 +524,19 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
|
|||
switch (foh->msg_type) {
|
||||
case NM_MT_LOAD_INIT_ACK:
|
||||
/* fill window with segments */
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_LOAD_INIT_ACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
rc = sw_fill_window(sw);
|
||||
sw->state = SW_STATE_WAIT_SEGACK;
|
||||
break;
|
||||
case NM_MT_LOAD_INIT_NACK:
|
||||
DEBUGP(DNM, "Software Load Init NACK\n");
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_LOAD_INIT_NACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
sw->state = SW_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
@ -547,26 +561,42 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
|
|||
switch (foh->msg_type) {
|
||||
case NM_MT_LOAD_END_ACK:
|
||||
sw_close_file(sw);
|
||||
/* send activate request */
|
||||
sw->state = SW_STATE_WAIT_ACTACK;
|
||||
rc = sw_activate(sw);
|
||||
DEBUGP(DNM, "Software Load End (BTS %u)\n",
|
||||
sw->bts->nr);
|
||||
sw->state = SW_STATE_NONE;
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_LOAD_END_ACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
break;
|
||||
case NM_MT_LOAD_END_NACK:
|
||||
DEBUGP(DNM, "Software Load End NACK\n");
|
||||
sw->state = SW_STATE_ERROR;
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_LOAD_END_NACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
break;
|
||||
}
|
||||
case SW_STATE_WAIT_ACTACK:
|
||||
switch (foh->msg_type) {
|
||||
case NM_MT_ACTIVATE_SW_ACK:
|
||||
/* we're done */
|
||||
DEBUGP(DNM, "Activate Software DONE!\n");
|
||||
sw->state = SW_STATE_NONE;
|
||||
rc = 0;
|
||||
DEBUGP(DMM, "DONE!\n");
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_ACTIVATE_SW_ACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
break;
|
||||
case NM_MT_ACTIVATE_SW_NACK:
|
||||
DEBUGP(DNM, "Activate Software NACK\n");
|
||||
sw->state = SW_STATE_ERROR;
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_ACTIVATE_SW_NACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
break;
|
||||
}
|
||||
case SW_STATE_NONE:
|
||||
|
@ -583,11 +613,14 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
|
|||
|
||||
/* Load the specified software into the BTS */
|
||||
int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
|
||||
u_int8_t win_size)
|
||||
u_int8_t win_size, gsm_cbfn *cbfn, void *cb_data)
|
||||
{
|
||||
struct abis_nm_sw *sw = &g_sw;
|
||||
int rc;
|
||||
|
||||
DEBUGP(DNM, "Software Load (BTS %u, File \"%s\")\n",
|
||||
bts->nr, fname);
|
||||
|
||||
if (sw->state != SW_STATE_NONE)
|
||||
return -EBUSY;
|
||||
|
||||
|
@ -598,6 +631,8 @@ int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
|
|||
sw->obj_instance[2] = 0xff;
|
||||
sw->window_size = win_size;
|
||||
sw->state = SW_STATE_WAIT_INITACK;
|
||||
sw->cbfn = cbfn;
|
||||
sw->cb_data = cb_data;
|
||||
|
||||
rc = sw_open_file(sw, fname);
|
||||
if (rc < 0) {
|
||||
|
@ -624,6 +659,39 @@ int abis_nm_software_load_status(struct gsm_bts *bts)
|
|||
return percent;
|
||||
}
|
||||
|
||||
/* Activate the specified software into the BTS */
|
||||
int abis_nm_software_activate(struct gsm_bts *bts, const char *fname,
|
||||
gsm_cbfn *cbfn, void *cb_data)
|
||||
{
|
||||
struct abis_nm_sw *sw = &g_sw;
|
||||
int rc;
|
||||
|
||||
DEBUGP(DNM, "Activating Software (BTS %u, File \"%s\")\n",
|
||||
bts->nr, fname);
|
||||
|
||||
if (sw->state != SW_STATE_NONE)
|
||||
return -EBUSY;
|
||||
|
||||
sw->bts = bts;
|
||||
sw->obj_class = NM_OC_SITE_MANAGER;
|
||||
sw->obj_instance[0] = 0xff;
|
||||
sw->obj_instance[1] = 0xff;
|
||||
sw->obj_instance[2] = 0xff;
|
||||
sw->state = SW_STATE_WAIT_ACTACK;
|
||||
sw->cbfn = cbfn;
|
||||
sw->cb_data = cb_data;
|
||||
|
||||
/* Open the file in order to fill some sw struct members */
|
||||
rc = sw_open_file(sw, fname);
|
||||
if (rc < 0) {
|
||||
sw->state = SW_STATE_NONE;
|
||||
return rc;
|
||||
}
|
||||
sw_close_file(sw);
|
||||
|
||||
return sw_activate(sw);
|
||||
}
|
||||
|
||||
static void fill_nm_channel(struct abis_nm_channel *ch, u_int8_t bts_port,
|
||||
u_int8_t ts_nr, u_int8_t subslot_nr)
|
||||
{
|
||||
|
@ -891,7 +959,7 @@ int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on)
|
|||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_NAME,
|
||||
sizeof(bs11_logon_c9), bs11_logon_c9);
|
||||
} else {
|
||||
fill_om_fom_hdr(oh, 0, NM_MT_BS11_LOGOFF,
|
||||
fill_om_fom_hdr(oh, 0, NM_MT_BS11_LMT_LOGOFF,
|
||||
NM_OC_BS11_A3, 0xff, 0xff, 0xff);
|
||||
}
|
||||
|
||||
|
@ -919,3 +987,198 @@ int abis_nm_bs11_get_state(struct gsm_bts *bts)
|
|||
{
|
||||
return __simple_cmd(bts, NM_MT_BS11_GET_STATE);
|
||||
}
|
||||
|
||||
/* BS11 SWL */
|
||||
|
||||
struct abis_nm_bs11_sw {
|
||||
struct gsm_bts *bts;
|
||||
char swl_fname[PATH_MAX];
|
||||
u_int8_t win_size;
|
||||
struct llist_head file_list;
|
||||
gsm_cbfn *user_cb; /* specified by the user */
|
||||
};
|
||||
static struct abis_nm_bs11_sw _g_bs11_sw, *g_bs11_sw = &_g_bs11_sw;
|
||||
|
||||
struct file_list_entry {
|
||||
struct llist_head list;
|
||||
char fname[PATH_MAX];
|
||||
};
|
||||
|
||||
struct file_list_entry *fl_dequeue(struct llist_head *queue)
|
||||
{
|
||||
struct llist_head *lh;
|
||||
|
||||
if (llist_empty(queue))
|
||||
return NULL;
|
||||
|
||||
lh = queue->next;
|
||||
llist_del(lh);
|
||||
|
||||
return llist_entry(lh, struct file_list_entry, list);
|
||||
}
|
||||
|
||||
static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw)
|
||||
{
|
||||
char linebuf[255];
|
||||
struct llist_head *lh, *lh2;
|
||||
FILE *swl;
|
||||
int rc = 0;
|
||||
|
||||
swl = fopen(bs11_sw->swl_fname, "r");
|
||||
if (!swl)
|
||||
return -ENODEV;
|
||||
|
||||
/* zero the stale file list, if any */
|
||||
llist_for_each_safe(lh, lh2, &bs11_sw->file_list) {
|
||||
llist_del(lh);
|
||||
free(lh);
|
||||
}
|
||||
|
||||
while (fgets(linebuf, sizeof(linebuf), swl)) {
|
||||
char file_id[12+1];
|
||||
char file_version[80+1];
|
||||
struct file_list_entry *fle;
|
||||
static char dir[PATH_MAX];
|
||||
|
||||
if (strlen(linebuf) < 4)
|
||||
continue;
|
||||
printf("linebuf='%s'\n", linebuf);
|
||||
rc = sscanf(linebuf+4, "%12s:%80s\r\n", file_id, file_version);
|
||||
if (rc < 0) {
|
||||
perror("ERR parsing SWL file");
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (rc < 2)
|
||||
continue;
|
||||
|
||||
fle = malloc(sizeof(*fle));
|
||||
if (!fle) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memset(fle, 0, sizeof(*fle));
|
||||
|
||||
/* construct new filename */
|
||||
strncpy(dir, bs11_sw->swl_fname, sizeof(dir));
|
||||
strncat(fle->fname, dirname(dir), sizeof(fle->fname) - 1);
|
||||
strcat(fle->fname, "/");
|
||||
strncat(fle->fname, file_id, sizeof(fle->fname) - 1 -strlen(fle->fname));
|
||||
printf("fname='%s'\n", fle->fname);
|
||||
|
||||
llist_add_tail(&fle->list, &bs11_sw->file_list);
|
||||
}
|
||||
|
||||
out:
|
||||
fclose(swl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* bs11 swload specific callback, passed to abis_nm core swload */
|
||||
static int bs11_swload_cbfn(unsigned int hook, unsigned int event,
|
||||
struct msgb *msg, void *data, void *param)
|
||||
{
|
||||
struct abis_nm_bs11_sw *bs11_sw = data;
|
||||
struct file_list_entry *fle;
|
||||
int rc = 0;
|
||||
|
||||
printf("bs11_swload_cbfn(%u, %u, %p, %p, %p)\n", hook, event, msg, data, param);
|
||||
|
||||
switch (event) {
|
||||
case NM_MT_LOAD_END_ACK:
|
||||
fle = fl_dequeue(&bs11_sw->file_list);
|
||||
if (fle) {
|
||||
/* start download the next file of our file list */
|
||||
rc = abis_nm_software_load(bs11_sw->bts, fle->fname,
|
||||
bs11_sw->win_size,
|
||||
&bs11_swload_cbfn, bs11_sw);
|
||||
free(fle);
|
||||
} else {
|
||||
/* activate the SWL */
|
||||
rc = abis_nm_software_activate(bs11_sw->bts,
|
||||
bs11_sw->swl_fname,
|
||||
bs11_swload_cbfn,
|
||||
bs11_sw);
|
||||
}
|
||||
break;
|
||||
case NM_MT_LOAD_END_NACK:
|
||||
case NM_MT_LOAD_INIT_ACK:
|
||||
case NM_MT_LOAD_INIT_NACK:
|
||||
case NM_MT_ACTIVATE_SW_NACK:
|
||||
case NM_MT_ACTIVATE_SW_ACK:
|
||||
default:
|
||||
/* fallthrough to the user callback */
|
||||
rc = bs11_sw->user_cb(hook, event, msg, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Siemens provides a SWL file that is a mere listing of all the other
|
||||
* files that are part of a software release. We need to upload first
|
||||
* the list file, and then each file that is listed in the list file */
|
||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
|
||||
u_int8_t win_size, gsm_cbfn *cbfn)
|
||||
{
|
||||
struct abis_nm_bs11_sw *bs11_sw = g_bs11_sw;
|
||||
struct file_list_entry *fle;
|
||||
int rc = 0;
|
||||
|
||||
INIT_LLIST_HEAD(&bs11_sw->file_list);
|
||||
bs11_sw->bts = bts;
|
||||
bs11_sw->win_size = win_size;
|
||||
bs11_sw->user_cb = cbfn;
|
||||
|
||||
strncpy(bs11_sw->swl_fname, fname, sizeof(bs11_sw->swl_fname));
|
||||
rc = bs11_read_swl_file(bs11_sw);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* dequeue next item in file list */
|
||||
fle = fl_dequeue(&bs11_sw->file_list);
|
||||
if (!fle)
|
||||
return -EINVAL;
|
||||
|
||||
/* start download the next file of our file list */
|
||||
rc = abis_nm_software_load(bts, fle->fname, win_size,
|
||||
bs11_swload_cbfn, bs11_sw);
|
||||
free(fle);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static u_int8_t req_attr_btse[] = {
|
||||
NM_ATT_ADM_STATE, NM_ATT_BS11_LMT_LOGON_SESSION,
|
||||
NM_ATT_BS11_LMT_LOGIN_TIME, NM_ATT_BS11_LMT_USER_ACC_LEV,
|
||||
NM_ATT_BS11_LMT_USER_NAME,
|
||||
|
||||
0xaf, NM_ATT_BS11_RX_OFFSET, NM_ATT_BS11_VENDOR_NAME,
|
||||
|
||||
NM_ATT_BS11_SW_LOAD_INTENDED, NM_ATT_BS11_SW_LOAD_SAFETY,
|
||||
|
||||
NM_ATT_BS11_SW_LOAD_STORED };
|
||||
|
||||
static u_int8_t req_attr_btsm[] = {
|
||||
NM_ATT_ABIS_CHANNEL, NM_ATT_TEI, NM_ATT_BS11_ABIS_EXT_TIME,
|
||||
NM_ATT_ADM_STATE, NM_ATT_AVAIL_STATUS, 0xce, NM_ATT_FILE_ID,
|
||||
NM_ATT_FILE_VERSION, NM_ATT_OPER_STATE, 0xe8, NM_ATT_BS11_ALL_TEST_CATG,
|
||||
NM_ATT_SW_DESCR, NM_ATT_GET_ARI };
|
||||
|
||||
static u_int8_t req_attr[] = {
|
||||
NM_ATT_ADM_STATE, NM_ATT_AVAIL_STATUS, 0xa8, NM_ATT_OPER_STATE,
|
||||
0xd5, 0xa1, NM_ATT_BS11_ESN_FW_CODE_NO, NM_ATT_BS11_ESN_HW_CODE_NO,
|
||||
0x42, NM_ATT_BS11_ESN_PCB_SERIAL };
|
||||
|
||||
int abis_nm_bs11_get_serno(struct gsm_bts *bts)
|
||||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct msgb *msg = nm_msgb_alloc();
|
||||
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
/* SiemensHW CCTRL object */
|
||||
fill_om_fom_hdr(oh, 2+sizeof(req_attr), NM_MT_GET_ATTR, NM_OC_BS11,
|
||||
0x03, 0x00, 0x00);
|
||||
msgb_tlv_put(msg, NM_ATT_LIST_REQ_ATTR, sizeof(req_attr), req_attr);
|
||||
|
||||
return abis_nm_sendmsg(bts, msg);
|
||||
}
|
||||
|
|
|
@ -52,16 +52,16 @@ enum bs11cfg_state {
|
|||
static enum bs11cfg_state bs11cfg_state = STATE_NONE;
|
||||
|
||||
static const u_int8_t obj_li_attr[] = {
|
||||
0xa0, 0x09, 0x00,
|
||||
0xab, 0x00,
|
||||
0xac, 0x00,
|
||||
NM_ATT_BS11_BIT_ERR_THESH, 0x09, 0x00,
|
||||
NM_ATT_BS11_L1_PROT_TYPE, 0x00,
|
||||
NM_ATT_BS11_LINE_CFG, 0x00,
|
||||
};
|
||||
static const u_int8_t obj_bbsig0_attr[] = {
|
||||
0x3d, 0x02, 0x00, 0x00,
|
||||
0x3f, 0x01, 0x00,
|
||||
NM_ATT_BS11_RSSI_OFFS, 0x02, 0x00, 0x00,
|
||||
NM_ATT_BS11_DIVERSITY, 0x01, 0x00,
|
||||
};
|
||||
static const u_int8_t obj_pa0_attr[] = {
|
||||
NM_ATT_BS11_TXPWR, 0x01, BS11_TRX_POWER_30mW,
|
||||
NM_ATT_BS11_TXPWR, 0x01, BS11_TRX_POWER_GSM_30mW,
|
||||
};
|
||||
static const char *trx1_password = "1111111111";
|
||||
#define TEI_OML 25
|
||||
|
@ -84,7 +84,7 @@ static int handle_serial_msg(struct msgb *rx_msg);
|
|||
/* create all objects for an initial configuration */
|
||||
static int create_objects(struct gsm_bts *bts, int trx1)
|
||||
{
|
||||
abis_nm_bs11_factory_logon(bts, 1);
|
||||
//abis_nm_bs11_factory_logon(bts, 1);
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_LI, 0, sizeof(obj_li_attr),
|
||||
obj_li_attr);
|
||||
abis_nm_bs11_create_object(bts, BS11_OBJ_GPSU, 0, 0, NULL);
|
||||
|
@ -118,12 +118,12 @@ static int create_objects(struct gsm_bts *bts, int trx1)
|
|||
abis_nm_bs11_conn_oml(bts, 0, 1, 0xff);
|
||||
abis_nm_bs11_set_oml_tei(bts, TEI_OML);
|
||||
|
||||
abis_nm_bs11_set_trx_power(&bts->trx[0], BS11_TRX_POWER_30mW);
|
||||
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_30mW);
|
||||
abis_nm_bs11_set_trx_power(&bts->trx[1], BS11_TRX_POWER_GSM_30mW);
|
||||
|
||||
abis_nm_bs11_factory_logon(bts, 0);
|
||||
//abis_nm_bs11_factory_logon(bts, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -172,6 +172,7 @@ int _abis_nm_sendmsg(struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* select.c callback in case we can write to the RS232 */
|
||||
static int handle_ser_write(struct bsc_fd *bfd)
|
||||
{
|
||||
struct serial_handle *sh = bfd->data;
|
||||
|
@ -203,6 +204,7 @@ static int handle_ser_write(struct bsc_fd *bfd)
|
|||
|
||||
#define SERIAL_ALLOC_SIZE 300
|
||||
|
||||
/* select.c callback in case we can read from the RS232 */
|
||||
static int handle_ser_read(struct bsc_fd *bfd)
|
||||
{
|
||||
struct serial_handle *sh = bfd->data;
|
||||
|
@ -265,6 +267,7 @@ static int handle_ser_read(struct bsc_fd *bfd)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* select.c callback */
|
||||
static int serial_fd_cb(struct bsc_fd *bfd, unsigned int what)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -296,7 +299,44 @@ static int file_is_readable(const char *fname)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* callback function passed to the ABIS OML code */
|
||||
static int swload_cbfn(unsigned int hook, unsigned int event, struct msgb *msg,
|
||||
void *data, void *param)
|
||||
{
|
||||
if (hook != GSM_HOOK_NM_SWLOAD)
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case NM_MT_LOAD_INIT_ACK:
|
||||
fprintf(stdout, "Software Load Initiate ACK\n");
|
||||
break;
|
||||
case NM_MT_LOAD_INIT_NACK:
|
||||
fprintf(stderr, "ERROR: Software Load Initiate NACK\n");
|
||||
exit(5);
|
||||
break;
|
||||
case NM_MT_LOAD_END_ACK:
|
||||
/* FIXME: activate in case we want to */
|
||||
if (data)
|
||||
abis_nm_software_activate(g_bts, fname_safety,
|
||||
swload_cbfn, g_bts);
|
||||
break;
|
||||
case NM_MT_LOAD_END_NACK:
|
||||
fprintf(stderr, "ERROR: Software Load End NACK\n");
|
||||
exit(3);
|
||||
break;
|
||||
case NM_MT_ACTIVATE_SW_NACK:
|
||||
fprintf(stderr, "ERROR: Activate Software NACK\n");
|
||||
exit(4);
|
||||
break;
|
||||
case NM_MT_ACTIVATE_SW_ACK:
|
||||
bs11cfg_state = STATE_NONE;
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handle a response from the BTS to a GET STATE command */
|
||||
static int handle_state_resp(u_int8_t state)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -315,10 +355,13 @@ static int handle_state_resp(u_int8_t state)
|
|||
case BS11_STATE_SOFTWARE_RQD:
|
||||
printf("Software required...\n");
|
||||
bs11cfg_state = STATE_SWLOAD;
|
||||
/* send safety load */
|
||||
/* send safety load. Use g_bts as private 'param'
|
||||
* argument, so our swload_cbfn can distinguish
|
||||
* a safety load from a regular software */
|
||||
if (file_is_readable(fname_safety))
|
||||
rc = abis_nm_software_load(g_bts, fname_safety,
|
||||
win_size);
|
||||
win_size, swload_cbfn,
|
||||
g_bts);
|
||||
else
|
||||
fprintf(stderr, "No valid Safety Load file \"%s\"\n",
|
||||
fname_safety);
|
||||
|
@ -334,8 +377,8 @@ static int handle_state_resp(u_int8_t state)
|
|||
bs11cfg_state = STATE_SWLOAD;
|
||||
/* send software (FIXME: over A-bis?) */
|
||||
if (file_is_readable(fname_software))
|
||||
rc = abis_nm_software_load(g_bts, fname_software,
|
||||
win_size);
|
||||
rc = abis_nm_bs11_load_swl(g_bts, fname_software,
|
||||
win_size, swload_cbfn);
|
||||
else
|
||||
fprintf(stderr, "No valid Software file \"%s\"\n",
|
||||
fname_software);
|
||||
|
@ -351,6 +394,7 @@ static int handle_state_resp(u_int8_t state)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* handle a fully-received message/packet from the RS232 port */
|
||||
static int handle_serial_msg(struct msgb *rx_msg)
|
||||
{
|
||||
struct abis_om_hdr *oh;
|
||||
|
@ -379,6 +423,9 @@ static int handle_serial_msg(struct msgb *rx_msg)
|
|||
bs11cfg_state = STATE_LOGON_ACK;
|
||||
rc = 0;
|
||||
break;
|
||||
case NM_MT_BS11_LMT_LOGOFF_ACK:
|
||||
exit(0);
|
||||
break;
|
||||
case NM_MT_BS11_GET_STATE_ACK:
|
||||
rc = handle_state_resp(foh->data[2]);
|
||||
break;
|
||||
|
@ -409,19 +456,19 @@ static int handle_serial_msg(struct msgb *rx_msg)
|
|||
static void print_banner(void)
|
||||
{
|
||||
printf("bs11_config (C) 2009 by Harald Welte and Dieter Spaar\n");
|
||||
printf("THIS SOFTWARE IS FREE SOFTWARE WIH NO WARRANTY\n\n");
|
||||
printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");
|
||||
}
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
printf("Supported arguments:\n");
|
||||
printf("\t--help\t\t\t-h\tPrint this help text\n");
|
||||
printf("\t--port /dev/ttyXXX\t-p\tSpecify serial port\n");
|
||||
printf("\t--with-trx1\t\t-t\tAssume the BS-11 has 2 TRX\n");
|
||||
printf("\t--software file\t\t-s\tSpecify Software file\n");
|
||||
printf("\t--safety file\t\t-S\tSpecify Safety Load file\n");
|
||||
printf("\t--delay file\t\t-d\tSpecify delay\n");
|
||||
printf("\t--win-size num\t\t-w\tSpecify Window Size\n");
|
||||
printf("\t-h --help\t\t\tPrint this help text\n");
|
||||
printf("\t-p --port </dev/ttyXXX>\t\tSpecify serial port\n");
|
||||
printf("\t-t --with-trx1\t\t\tAssume the BS-11 has 2 TRX\n");
|
||||
printf("\t-s --software <file>\t\tSpecify Software file\n");
|
||||
printf("\t-S --safety <file>\t\tSpecify Safety Load file\n");
|
||||
printf("\t-d --delay <file>\t\tSpecify delay\n");
|
||||
printf("\t-w --win-size <num>\t\tSpecify Window Size\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
|
@ -479,7 +526,7 @@ static void signal_handler(int signal)
|
|||
fprintf(stdout, "signal %u received\n", signal);
|
||||
|
||||
switch (signal) {
|
||||
case SIGABRT:
|
||||
case SIGINT:
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -538,9 +585,10 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGINT, &signal_handler);
|
||||
|
||||
abis_nm_bs11_factory_logon(g_bts, 1);
|
||||
//abis_nm_bs11_get_serno(g_bts);
|
||||
|
||||
while (1) {
|
||||
bsc_select_main();
|
||||
|
|
Loading…
Reference in New Issue