Merge branch 'pablo/cleanups'
This commit is contained in:
commit
755f7442dd
|
@ -70,10 +70,13 @@ int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa);
|
|||
int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
|
||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
|
||||
void ipaccess_prepend_header(struct msgb *msg, int proto);
|
||||
int ipaccess_send_pong(int fd);
|
||||
int ipaccess_send_id_ack(int fd);
|
||||
int ipaccess_send_id_req(int fd);
|
||||
|
||||
const char *ipaccess_idtag_name(int tag);
|
||||
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
|
||||
int ipaccess_parse_unitid(const char *str, u_int16_t *site_id, u_int16_t *bts_id, u_int16_t *trx_id);
|
||||
|
||||
int ipaccess_drop_oml(struct gsm_bts *bts);
|
||||
int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
|
||||
|
|
|
@ -18,4 +18,9 @@ ipaccess_config_LDADD = $(top_builddir)/src/libbsc/libbsc.a \
|
|||
-ldl -ldbi $(LIBCRYPT)
|
||||
|
||||
ipaccess_proxy_SOURCES = ipaccess-proxy.c
|
||||
ipaccess_proxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a
|
||||
ipaccess_proxy_LDADD = $(top_builddir)/src/libbsc/libbsc.a \
|
||||
$(top_builddir)/src/libmsc/libmsc.a \
|
||||
$(top_builddir)/src/libabis/libabis.a \
|
||||
$(top_builddir)/src/libbsc/libbsc.a \
|
||||
$(top_builddir)/src/libtrau/libtrau.a \
|
||||
$(top_builddir)/src/libcommon/libcommon.a
|
||||
|
|
|
@ -131,96 +131,6 @@ static int gprs_ns_cb(struct bsc_fd *bfd, unsigned int what);
|
|||
|
||||
#define PROXY_ALLOC_SIZE 1200
|
||||
|
||||
static const u_int8_t pong[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG };
|
||||
static const u_int8_t id_ack[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK };
|
||||
static const u_int8_t id_req[] = { 0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
|
||||
0x01, IPAC_IDTAG_UNIT,
|
||||
0x01, IPAC_IDTAG_MACADDR,
|
||||
0x01, IPAC_IDTAG_LOCATION1,
|
||||
0x01, IPAC_IDTAG_LOCATION2,
|
||||
0x01, IPAC_IDTAG_EQUIPVERS,
|
||||
0x01, IPAC_IDTAG_SWVERSION,
|
||||
0x01, IPAC_IDTAG_UNITNAME,
|
||||
0x01, IPAC_IDTAG_SERNR,
|
||||
};
|
||||
|
||||
static const char *idtag_names[] = {
|
||||
[IPAC_IDTAG_SERNR] = "Serial_Number",
|
||||
[IPAC_IDTAG_UNITNAME] = "Unit_Name",
|
||||
[IPAC_IDTAG_LOCATION1] = "Location_1",
|
||||
[IPAC_IDTAG_LOCATION2] = "Location_2",
|
||||
[IPAC_IDTAG_EQUIPVERS] = "Equipment_Version",
|
||||
[IPAC_IDTAG_SWVERSION] = "Software_Version",
|
||||
[IPAC_IDTAG_IPADDR] = "IP_Address",
|
||||
[IPAC_IDTAG_MACADDR] = "MAC_Address",
|
||||
[IPAC_IDTAG_UNIT] = "Unit_ID",
|
||||
};
|
||||
|
||||
static const char *ipac_idtag_name(int tag)
|
||||
{
|
||||
if (tag >= ARRAY_SIZE(idtag_names))
|
||||
return "unknown";
|
||||
|
||||
return idtag_names[tag];
|
||||
}
|
||||
|
||||
static int ipac_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)
|
||||
{
|
||||
u_int8_t t_len;
|
||||
u_int8_t t_tag;
|
||||
u_int8_t *cur = buf;
|
||||
|
||||
while (cur < buf + len) {
|
||||
t_len = *cur++;
|
||||
t_tag = *cur++;
|
||||
|
||||
DEBUGPC(DMI, "%s='%s' ", ipac_idtag_name(t_tag), cur);
|
||||
|
||||
dec->lv[t_tag].len = t_len;
|
||||
dec->lv[t_tag].val = cur;
|
||||
|
||||
cur += t_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_unitid(const char *str, u_int16_t *site_id, u_int16_t *bts_id,
|
||||
u_int16_t *trx_id)
|
||||
{
|
||||
unsigned long ul;
|
||||
char *endptr;
|
||||
const char *nptr;
|
||||
|
||||
nptr = str;
|
||||
ul = strtoul(nptr, &endptr, 10);
|
||||
if (endptr <= nptr)
|
||||
return -EINVAL;
|
||||
if (site_id)
|
||||
*site_id = ul & 0xffff;
|
||||
|
||||
if (*endptr++ != '/')
|
||||
return -EINVAL;
|
||||
|
||||
nptr = endptr;
|
||||
ul = strtoul(nptr, &endptr, 10);
|
||||
if (endptr <= nptr)
|
||||
return -EINVAL;
|
||||
if (bts_id)
|
||||
*bts_id = ul & 0xffff;
|
||||
|
||||
if (*endptr++ != '/')
|
||||
return -EINVAL;
|
||||
|
||||
nptr = endptr;
|
||||
ul = strtoul(nptr, &endptr, 10);
|
||||
if (endptr <= nptr)
|
||||
return -EINVAL;
|
||||
if (trx_id)
|
||||
*trx_id = ul & 0xffff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ipa_bts_conn *find_bts_by_unitid(struct ipa_proxy *ipp,
|
||||
u_int16_t site_id,
|
||||
u_int16_t bts_id)
|
||||
|
@ -529,13 +439,7 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,
|
|||
|
||||
switch (msg_type) {
|
||||
case IPAC_MSGT_PING:
|
||||
ret = write(bfd->fd, pong, sizeof(pong));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < sizeof(pong)) {
|
||||
DEBUGP(DINP, "short write\n");
|
||||
return -EIO;
|
||||
}
|
||||
ret = ipaccess_send_pong(bfd->fd);
|
||||
break;
|
||||
case IPAC_MSGT_PONG:
|
||||
DEBUGP(DMI, "PONG!\n");
|
||||
|
@ -543,8 +447,8 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,
|
|||
case IPAC_MSGT_ID_RESP:
|
||||
DEBUGP(DMI, "ID_RESP ");
|
||||
/* parse tags, search for Unit ID */
|
||||
ipac_idtag_parse(&tlvp, (u_int8_t *)msg->l2h + 2,
|
||||
msgb_l2len(msg)-2);
|
||||
ipaccess_idtag_parse(&tlvp, (u_int8_t *)msg->l2h + 2,
|
||||
msgb_l2len(msg)-2);
|
||||
DEBUGP(DMI, "\n");
|
||||
|
||||
if (!TLVP_PRESENT(&tlvp, IPAC_IDTAG_UNIT)) {
|
||||
|
@ -554,8 +458,8 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,
|
|||
|
||||
/* lookup BTS, create sign_link, ... */
|
||||
site_id = bts_id = trx_id = 0;
|
||||
parse_unitid((char *)TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT),
|
||||
&site_id, &bts_id, &trx_id);
|
||||
ipaccess_parse_unitid((char *)TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT),
|
||||
&site_id, &bts_id, &trx_id);
|
||||
ipbc = find_bts_by_unitid(ipp, site_id, bts_id);
|
||||
if (!ipbc) {
|
||||
/* We have not found an ipbc (per-bts proxy instance)
|
||||
|
@ -618,7 +522,7 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,
|
|||
break;
|
||||
case IPAC_MSGT_ID_ACK:
|
||||
DEBUGP(DMI, "ID_ACK? -> ACK!\n");
|
||||
ret = write(bfd->fd, id_ack, sizeof(id_ack));
|
||||
ret = ipaccess_send_id_ack(bfd->fd);
|
||||
break;
|
||||
default:
|
||||
LOGP(DMI, LOGL_ERROR, "Unhandled IPA type; %d\n", msg_type);
|
||||
|
@ -628,7 +532,7 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error)
|
||||
struct msgb *ipaccess_proxy_read_msg(struct bsc_fd *bfd, int *error)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc(PROXY_ALLOC_SIZE, "Abis/IP");
|
||||
struct ipaccess_head *hh;
|
||||
|
@ -868,7 +772,7 @@ static int handle_tcp_read(struct bsc_fd *bfd)
|
|||
else
|
||||
btsbsc = "BSC";
|
||||
|
||||
msg = ipaccess_read_msg(bfd, &ret);
|
||||
msg = ipaccess_proxy_read_msg(bfd, &ret);
|
||||
if (!msg) {
|
||||
if (ret == 0) {
|
||||
logp_ipbc_uid(DINP, LOGL_NOTICE, ipbc, bfd->priv_nr >> 8);
|
||||
|
@ -1025,7 +929,7 @@ static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
|
|||
}
|
||||
|
||||
/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
|
||||
ret = write(bfd->fd, id_req, sizeof(id_req));
|
||||
ret = ipaccess_send_id_req(bfd->fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1078,49 +982,6 @@ static int gprs_ns_cb(struct bsc_fd *bfd, unsigned int what)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int make_listen_sock(struct bsc_fd *bfd, u_int16_t port, int priv_nr,
|
||||
int (*cb)(struct bsc_fd *fd, unsigned int what))
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int ret, on = 1;
|
||||
|
||||
bfd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
bfd->cb = cb;
|
||||
bfd->when = BSC_FD_READ;
|
||||
bfd->priv_nr = priv_nr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
if (!listen_ipaddr)
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
inet_aton(listen_ipaddr, &addr.sin_addr);
|
||||
|
||||
setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
|
||||
ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
LOGP(DINP, LOGL_ERROR,
|
||||
"Could not bind listen socket for IP %s with error: %s.\n",
|
||||
listen_ipaddr, strerror(errno));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = listen(bfd->fd, 1);
|
||||
if (ret < 0) {
|
||||
perror("listen");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bsc_register_fd(bfd);
|
||||
if (ret < 0) {
|
||||
perror("register_listen_fd");
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_gprs_sock(struct bsc_fd *bfd, int (*cb)(struct bsc_fd*,unsigned int), void *data)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
@ -1206,14 +1067,14 @@ static int ipaccess_proxy_setup(void)
|
|||
ipp->reconn_timer.data = ipp;
|
||||
|
||||
/* Listen for OML connections */
|
||||
ret = make_listen_sock(&ipp->oml_listen_fd, IPA_TCP_PORT_OML,
|
||||
OML_FROM_BTS, listen_fd_cb);
|
||||
ret = make_sock(&ipp->oml_listen_fd, IPPROTO_TCP, INADDR_ANY,
|
||||
IPA_TCP_PORT_OML, OML_FROM_BTS, listen_fd_cb, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Listen for RSL connections */
|
||||
ret = make_listen_sock(&ipp->rsl_listen_fd, IPA_TCP_PORT_RSL,
|
||||
RSL_FROM_BTS, listen_fd_cb);
|
||||
ret = make_sock(&ipp->rsl_listen_fd, IPPROTO_TCP, INADDR_ANY,
|
||||
IPA_TCP_PORT_RSL, RSL_FROM_BTS, listen_fd_cb, NULL);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -1259,11 +1120,19 @@ static void print_help()
|
|||
|
||||
static void print_usage()
|
||||
{
|
||||
printf("Usage: ipaccess-proxy\n");
|
||||
printf("Usage: ipaccess-proxy [options]\n");
|
||||
}
|
||||
|
||||
enum {
|
||||
IPA_PROXY_OPT_LISTEN_NONE = 0,
|
||||
IPA_PROXY_OPT_LISTEN_IP = (1 << 0),
|
||||
IPA_PROXY_OPT_BSC_IP = (1 << 1),
|
||||
};
|
||||
|
||||
static void handle_options(int argc, char** argv)
|
||||
{
|
||||
int options_mask = 0;
|
||||
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
|
@ -1289,9 +1158,11 @@ static void handle_options(int argc, char** argv)
|
|||
exit(0);
|
||||
case 'l':
|
||||
listen_ipaddr = optarg;
|
||||
options_mask |= IPA_PROXY_OPT_LISTEN_IP;
|
||||
break;
|
||||
case 'b':
|
||||
bsc_ipaddr = optarg;
|
||||
options_mask |= IPA_PROXY_OPT_BSC_IP;
|
||||
break;
|
||||
case 'g':
|
||||
gprs_ns_ipaddr = optarg;
|
||||
|
@ -1310,15 +1181,20 @@ static void handle_options(int argc, char** argv)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if ((options_mask & (IPA_PROXY_OPT_LISTEN_IP | IPA_PROXY_OPT_BSC_IP))
|
||||
!= (IPA_PROXY_OPT_LISTEN_IP | IPA_PROXY_OPT_BSC_IP)) {
|
||||
printf("ERROR: You have to specify `--listen' and `--bsc' "
|
||||
"options at least.\n");
|
||||
print_usage();
|
||||
print_help();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
listen_ipaddr = "192.168.100.11";
|
||||
bsc_ipaddr = "192.168.100.239";
|
||||
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "ipaccess-proxy");
|
||||
|
||||
log_init(&log_info);
|
||||
|
|
|
@ -62,18 +62,31 @@ static struct ia_e1_handle *e1h;
|
|||
|
||||
#define TS1_ALLOC_SIZE 900
|
||||
|
||||
static const u_int8_t pong[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG };
|
||||
static const u_int8_t id_ack[] = { 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK };
|
||||
static const u_int8_t id_req[] = { 0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
|
||||
0x01, IPAC_IDTAG_UNIT,
|
||||
0x01, IPAC_IDTAG_MACADDR,
|
||||
0x01, IPAC_IDTAG_LOCATION1,
|
||||
0x01, IPAC_IDTAG_LOCATION2,
|
||||
0x01, IPAC_IDTAG_EQUIPVERS,
|
||||
0x01, IPAC_IDTAG_SWVERSION,
|
||||
0x01, IPAC_IDTAG_UNITNAME,
|
||||
0x01, IPAC_IDTAG_SERNR,
|
||||
};
|
||||
/*
|
||||
* Common propietary IPA messages:
|
||||
* - PONG: in reply to PING.
|
||||
* - ID_REQUEST: first messages once OML has been established.
|
||||
* - ID_ACK: in reply to ID_ACK.
|
||||
*/
|
||||
const u_int8_t ipa_pong_msg[] = {
|
||||
0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG
|
||||
};
|
||||
|
||||
const u_int8_t ipa_id_ack_msg[] = {
|
||||
0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK
|
||||
};
|
||||
|
||||
const u_int8_t ipa_id_req_msg[] = {
|
||||
0, 17, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_GET,
|
||||
0x01, IPAC_IDTAG_UNIT,
|
||||
0x01, IPAC_IDTAG_MACADDR,
|
||||
0x01, IPAC_IDTAG_LOCATION1,
|
||||
0x01, IPAC_IDTAG_LOCATION2,
|
||||
0x01, IPAC_IDTAG_EQUIPVERS,
|
||||
0x01, IPAC_IDTAG_SWVERSION,
|
||||
0x01, IPAC_IDTAG_UNITNAME,
|
||||
0x01, IPAC_IDTAG_SERNR,
|
||||
};
|
||||
|
||||
static const char *idtag_names[] = {
|
||||
[IPAC_IDTAG_SERNR] = "Serial_Number",
|
||||
|
@ -87,7 +100,7 @@ static const char *idtag_names[] = {
|
|||
[IPAC_IDTAG_UNIT] = "Unit_ID",
|
||||
};
|
||||
|
||||
static const char *ipac_idtag_name(int tag)
|
||||
const char *ipaccess_idtag_name(int tag)
|
||||
{
|
||||
if (tag >= ARRAY_SIZE(idtag_names))
|
||||
return "unknown";
|
||||
|
@ -113,7 +126,7 @@ int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)
|
|||
return -1;
|
||||
}
|
||||
|
||||
DEBUGPC(DMI, "%s='%s' ", ipac_idtag_name(t_tag), cur);
|
||||
DEBUGPC(DMI, "%s='%s' ", ipaccess_idtag_name(t_tag), cur);
|
||||
|
||||
dec->lv[t_tag].len = t_len;
|
||||
dec->lv[t_tag].val = cur;
|
||||
|
@ -142,8 +155,8 @@ struct gsm_bts *find_bts_by_unitid(struct gsm_network *net,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int parse_unitid(const char *str, u_int16_t *site_id, u_int16_t *bts_id,
|
||||
u_int16_t *trx_id)
|
||||
int ipaccess_parse_unitid(const char *str, u_int16_t *site_id,
|
||||
u_int16_t *bts_id, u_int16_t *trx_id)
|
||||
{
|
||||
unsigned long ul;
|
||||
char *endptr;
|
||||
|
@ -179,15 +192,33 @@ static int parse_unitid(const char *str, u_int16_t *site_id, u_int16_t *bts_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* send the id ack */
|
||||
static int ipaccess_send(int fd, const void *msg, size_t msglen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = write(fd, msg, msglen);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < msglen) {
|
||||
DEBUGP(DINP, "ipaccess_send: short write\n");
|
||||
return -EIO;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ipaccess_send_pong(int fd)
|
||||
{
|
||||
return ipaccess_send(fd, ipa_pong_msg, sizeof(ipa_pong_msg));
|
||||
}
|
||||
|
||||
int ipaccess_send_id_ack(int fd)
|
||||
{
|
||||
return write(fd, id_ack, sizeof(id_ack));
|
||||
return ipaccess_send(fd, ipa_id_ack_msg, sizeof(ipa_id_ack_msg));
|
||||
}
|
||||
|
||||
int ipaccess_send_id_req(int fd)
|
||||
{
|
||||
return write(fd, id_req, sizeof(id_req));
|
||||
return ipaccess_send(fd, ipa_id_req_msg, sizeof(ipa_id_req_msg));
|
||||
}
|
||||
|
||||
/* base handling of the ip.access protocol */
|
||||
|
@ -199,7 +230,7 @@ int ipaccess_rcvmsg_base(struct msgb *msg,
|
|||
|
||||
switch (msg_type) {
|
||||
case IPAC_MSGT_PING:
|
||||
ret = write(bfd->fd, pong, sizeof(pong));
|
||||
ret = ipaccess_send_pong(bfd->fd);
|
||||
break;
|
||||
case IPAC_MSGT_PONG:
|
||||
DEBUGP(DMI, "PONG!\n");
|
||||
|
@ -243,7 +274,7 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
|
|||
/* lookup BTS, create sign_link, ... */
|
||||
unitid = (char *) TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT);
|
||||
unitid[len - 1] = '\0';
|
||||
parse_unitid(unitid, &site_id, &bts_id, &trx_id);
|
||||
ipaccess_parse_unitid(unitid, &site_id, &bts_id, &trx_id);
|
||||
bts = find_bts_by_unitid(e1h->gsmnet, site_id, bts_id);
|
||||
if (!bts) {
|
||||
LOGP(DINP, LOGL_ERROR, "Unable to find BTS configuration for "
|
||||
|
@ -721,7 +752,7 @@ static int rsl_listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
|
|||
return ret;
|
||||
}
|
||||
/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
|
||||
ret = write(bfd->fd, id_req, sizeof(id_req));
|
||||
ret = ipaccess_send_id_req(bfd->fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue