aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-02-01 13:36:56 +0000
committerHarald Welte <laforge@gnumonks.org>2009-02-01 13:36:56 +0000
commit5e4d1b366366e60ca63c9a72a1e015ae0d4ddbd5 (patch)
treed225ff263076923aac36568ce65fbc7cb15f003c
parent8e1e3eece8f00a82079c879a21da94429f2ff1a0 (diff)
* 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
-rw-r--r--include/openbsc/abis_nm.h29
-rw-r--r--src/abis_nm.c275
-rw-r--r--src/bs11_config.c96
3 files changed, 364 insertions, 36 deletions
diff --git a/include/openbsc/abis_nm.h b/include/openbsc/abis_nm.h
index 1e59a4446..db02ae604 100644
--- a/include/openbsc/abis_nm.h
+++ b/include/openbsc/abis_nm.h
@@ -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 */
diff --git a/src/abis_nm.c b/src/abis_nm.c
index 2cff36ffc..259132029 100644
--- a/src/abis_nm.c
+++ b/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);
+}
diff --git a/src/bs11_config.c b/src/bs11_config.c
index 457e90f08..6166c8414 100644
--- a/src/bs11_config.c
+++ b/src/bs11_config.c
@@ -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();