diff options
| author | Harald Welte <laforge@gnumonks.org> | 2014-08-20 22:28:23 +0200 |
|---|---|---|
| committer | Harald Welte <laforge@gnumonks.org> | 2014-08-20 23:16:36 +0200 |
| commit | e391996947f9aa2b42377c4b797eda7db4f78c5c (patch) | |
| tree | 919b1315d488d6b26cd89f410459ba3a1998f9e0 /src/gsm/ipaccess.c | |
| parent | 28aa991c2fa8c27a3100530bf9d7ab5d592f4792 (diff) | |
ipa: rename functions for consistency
As we are breaking builds by moving functions from libosmo-abis to
libosmocore anyway, we might as well give functions more appropriate
names. ipaccess is a company, while IPA is the multiplex protocol, and
CCM is the protocol used for establishing identities on the IPA
multiplex.
Diffstat (limited to 'src/gsm/ipaccess.c')
| -rw-r--r-- | src/gsm/ipaccess.c | 447 |
1 files changed, 0 insertions, 447 deletions
diff --git a/src/gsm/ipaccess.c b/src/gsm/ipaccess.c deleted file mode 100644 index cddbd534..00000000 --- a/src/gsm/ipaccess.c +++ /dev/null @@ -1,447 +0,0 @@ -/* OpenBSC Abis input driver for ip.access */ - -/* (C) 2009 by Harald Welte <laforge@gnumonks.org> - * (C) 2010 by Holger Hans Peter Freyther - * (C) 2010 by On-Waves - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <unistd.h> -#include <stdint.h> -#include <errno.h> -#include <stdlib.h> - -#include <arpa/inet.h> - -#include <osmocom/core/msgb.h> -#include <osmocom/core/talloc.h> -#include <osmocom/core/logging.h> -#include <osmocom/core/macaddr.h> -#include <osmocom/core/select.h> - -#include <osmocom/gsm/tlv.h> -#include <osmocom/gsm/protocol/ipaccess.h> -#include <osmocom/gsm/ipaccess.h> - -#define IPA_ALLOC_SIZE 1200 - -/* - * 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. - */ -static const uint8_t ipa_pong_msg[] = { - 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_PONG -}; - -static const uint8_t ipa_id_ack_msg[] = { - 0, 1, IPAC_PROTO_IPACCESS, IPAC_MSGT_ID_ACK -}; - -static const uint8_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", - [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", -}; - -const char *ipaccess_idtag_name(uint8_t tag) -{ - if (tag >= ARRAY_SIZE(idtag_names)) - return "unknown"; - - return idtag_names[tag]; -} - -int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len) -{ - uint8_t t_len; - uint8_t t_tag; - uint8_t *cur = buf; - - memset(dec, 0, sizeof(*dec)); - - while (len >= 2) { - len -= 2; - t_len = *cur++; - t_tag = *cur++; - - if (t_len > len + 1) { - LOGP(DLMI, LOGL_ERROR, "The tag does not fit: %d\n", t_len); - return -EINVAL; - } - - DEBUGPC(DLMI, "%s='%s' ", ipaccess_idtag_name(t_tag), cur); - - dec->lv[t_tag].len = t_len; - dec->lv[t_tag].val = cur; - - cur += t_len; - len -= t_len; - } - return 0; -} - -int ipaccess_parse_unitid(const char *str, struct ipaccess_unit *unit_data) -{ - unsigned long ul; - char *endptr; - const char *nptr; - - nptr = str; - ul = strtoul(nptr, &endptr, 10); - if (endptr <= nptr) - return -EINVAL; - unit_data->site_id = ul & 0xffff; - - if (*endptr++ != '/') - return -EINVAL; - - nptr = endptr; - ul = strtoul(nptr, &endptr, 10); - if (endptr <= nptr) - return -EINVAL; - unit_data->bts_id = ul & 0xffff; - - if (*endptr++ != '/') - return -EINVAL; - - nptr = endptr; - ul = strtoul(nptr, &endptr, 10); - if (endptr <= nptr) - return -EINVAL; - unit_data->trx_id = ul & 0xffff; - - return 0; -} - -int ipaccess_tlv_to_unitdata(struct ipaccess_unit *ud, - const struct tlv_parsed *tp) -{ - int rc = 0; - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_SERNR, 1)) - ud->serno = talloc_strdup(ud, (char *) - TLVP_VAL(tp, IPAC_IDTAG_SERNR)); - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_UNITNAME, 1)) - ud->unit_name = talloc_strdup(ud, (char *) - TLVP_VAL(tp, IPAC_IDTAG_UNITNAME)); - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_LOCATION1, 1)) - ud->location1 = talloc_strdup(ud, (char *) - TLVP_VAL(tp, IPAC_IDTAG_LOCATION1)); - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_LOCATION2, 1)) - ud->location2 = talloc_strdup(ud, (char *) - TLVP_VAL(tp, IPAC_IDTAG_LOCATION2)); - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_EQUIPVERS, 1)) - ud->equipvers = talloc_strdup(ud, (char *) - TLVP_VAL(tp, IPAC_IDTAG_EQUIPVERS)); - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_SWVERSION, 1)) - ud->swversion = talloc_strdup(ud, (char *) - TLVP_VAL(tp, IPAC_IDTAG_SWVERSION)); - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_MACADDR, 17)) { - rc = osmo_macaddr_parse(ud->mac_addr, (char *) - TLVP_VAL(tp, IPAC_IDTAG_MACADDR)); - if (rc < 0) - goto out; - } - - if (TLVP_PRES_LEN(tp, IPAC_IDTAG_UNIT, 1)) - rc = ipaccess_parse_unitid((char *) - TLVP_VAL(tp, IPAC_IDTAG_UNIT), ud); - -out: - return rc; -} - -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) { - LOGP(DLINP, LOGL_ERROR, "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 ipaccess_send(fd, ipa_id_ack_msg, sizeof(ipa_id_ack_msg)); -} - -int ipaccess_send_id_req(int fd) -{ - return ipaccess_send(fd, ipa_id_req_msg, sizeof(ipa_id_req_msg)); -} - -/* base handling of the ip.access protocol */ -int ipaccess_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd) -{ - uint8_t msg_type = *(msg->l2h); - int ret; - - switch (msg_type) { - case IPAC_MSGT_PING: - ret = ipaccess_send_pong(bfd->fd); - if (ret < 0) { - LOGP(DLINP, LOGL_ERROR, "Cannot send PING " - "message. Reason: %s\n", strerror(errno)); - break; - } - ret = 1; - break; - case IPAC_MSGT_PONG: - DEBUGP(DLMI, "PONG!\n"); - ret = 1; - break; - case IPAC_MSGT_ID_ACK: - DEBUGP(DLMI, "ID_ACK? -> ACK!\n"); - ret = ipaccess_send_id_ack(bfd->fd); - if (ret < 0) { - LOGP(DLINP, LOGL_ERROR, "Cannot send ID_ACK " - "message. Reason: %s\n", strerror(errno)); - break; - } - ret = 1; - break; - default: - /* This is not an IPA PING, PONG or ID_ACK message */ - ret = 0; - break; - } - return ret; -} - -/* base handling of the ip.access protocol */ -int ipaccess_rcvmsg_bts_base(struct msgb *msg, - struct osmo_fd *bfd) -{ - uint8_t msg_type = *(msg->l2h); - int ret = 0; - - switch (msg_type) { - case IPAC_MSGT_PING: - ret = ipaccess_send_pong(bfd->fd); - if (ret < 0) { - LOGP(DLINP, LOGL_ERROR, "Cannot send PONG " - "message. Reason: %s\n", strerror(errno)); - } - break; - case IPAC_MSGT_PONG: - DEBUGP(DLMI, "PONG!\n"); - break; - case IPAC_MSGT_ID_ACK: - DEBUGP(DLMI, "ID_ACK\n"); - break; - } - return ret; -} - - -void ipaccess_prepend_header_ext(struct msgb *msg, int proto) -{ - struct ipaccess_head_ext *hh_ext; - - /* prepend the osmo ip.access header extension */ - hh_ext = (struct ipaccess_head_ext *) msgb_push(msg, sizeof(*hh_ext)); - hh_ext->proto = proto; -} - -void ipaccess_prepend_header(struct msgb *msg, int proto) -{ - struct ipaccess_head *hh; - - /* prepend the ip.access header */ - hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh)); - hh->len = htons(msg->len - sizeof(*hh)); - hh->proto = proto; -} - -int ipa_msg_recv(int fd, struct msgb **rmsg) -{ - int rc = ipa_msg_recv_buffered(fd, rmsg, NULL); - if (rc < 0) { - errno = -rc; - rc = -1; - } - return rc; -} - -int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg) -{ - struct msgb *msg = tmp_msg ? *tmp_msg : NULL; - struct ipaccess_head *hh; - int len, ret; - int needed; - - if (msg == NULL) { - msg = ipa_msg_alloc(0); - if (msg == NULL) { - ret = -ENOMEM; - goto discard_msg; - } - msg->l1h = msg->tail; - } - - if (msg->l2h == NULL) { - /* first read our 3-byte header */ - needed = sizeof(*hh) - msg->len; - ret = recv(fd, msg->tail, needed, 0); - if (ret == 0) - goto discard_msg; - - if (ret < 0) { - if (errno == EAGAIN || errno == EINTR) - ret = 0; - else { - ret = -errno; - goto discard_msg; - } - } - - msgb_put(msg, ret); - - if (ret < needed) { - if (msg->len == 0) { - ret = -EAGAIN; - goto discard_msg; - } - - LOGP(DLINP, LOGL_INFO, - "Received part of IPA message header (%d/%d)\n", - msg->len, sizeof(*hh)); - if (!tmp_msg) { - ret = -EIO; - goto discard_msg; - } - *tmp_msg = msg; - return -EAGAIN; - } - - msg->l2h = msg->tail; - } - - hh = (struct ipaccess_head *) msg->data; - - /* then read the length as specified in header */ - len = ntohs(hh->len); - - if (len < 0 || IPA_ALLOC_SIZE < len + sizeof(*hh)) { - LOGP(DLINP, LOGL_ERROR, "bad message length of %d bytes, " - "received %d bytes\n", len, msg->len); - ret = -EIO; - goto discard_msg; - } - - needed = len - msgb_l2len(msg); - - if (needed > 0) { - ret = recv(fd, msg->tail, needed, 0); - - if (ret == 0) - goto discard_msg; - - if (ret < 0) { - if (errno == EAGAIN || errno == EINTR) - ret = 0; - else { - ret = -errno; - goto discard_msg; - } - } - - msgb_put(msg, ret); - - if (ret < needed) { - LOGP(DLINP, LOGL_INFO, - "Received part of IPA message L2 data (%d/%d)\n", - msgb_l2len(msg), len); - if (!tmp_msg) { - ret = -EIO; - goto discard_msg; - } - *tmp_msg = msg; - return -EAGAIN; - } - } - - ret = msgb_l2len(msg); - - if (ret == 0) { - LOGP(DLINP, LOGL_INFO, - "Discarding IPA message without payload\n"); - ret = -EAGAIN; - goto discard_msg; - } - - if (tmp_msg) - *tmp_msg = NULL; - *rmsg = msg; - return ret; - -discard_msg: - if (tmp_msg) - *tmp_msg = NULL; - msgb_free(msg); - return ret; -} - -struct msgb *ipa_msg_alloc(int headroom) -{ - struct msgb *nmsg; - - headroom += sizeof(struct ipaccess_head); - - nmsg = msgb_alloc_headroom(1200 + headroom, headroom, "Abis/IP"); - if (!nmsg) - return NULL; - return nmsg; -} |
