daniel has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/30935 )
Change subject: libosmogsm: Add osmo_io support to ipa ......................................................................
libosmogsm: Add osmo_io support to ipa
* ipa_iofd_segmentation_cb() to segment ipa-style messages * add ipa_ccm_send_*iofd() that work with an osmo_io_fd
Change-Id: I0f955d5a36afe7a08d31b8ba4185260362c2bcca --- M TODO-RELEASE M include/osmocom/gsm/ipa.h M src/gsm/ipa.c M src/gsm/libosmogsm.map 4 files changed, 146 insertions(+), 0 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/35/30935/1
diff --git a/TODO-RELEASE b/TODO-RELEASE index ef629c7..2308756 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -10,3 +10,4 @@ libosmocore new API osmo_sockaddr_is_any() libosmocore ABI breakage OSMO_NUM_DLIB change affecting internal_cat[] libosmocore new API osmo_io_* +libosmogsm new API ipa_ccm_*_iofd, ipa_iofd_segmentation_cb diff --git a/include/osmocom/gsm/ipa.h b/include/osmocom/gsm/ipa.h index 851b58e..c3fb615 100644 --- a/include/osmocom/gsm/ipa.h +++ b/include/osmocom/gsm/ipa.h @@ -5,6 +5,7 @@ #include <stdint.h>
#include <osmocom/core/msgb.h> +#include <osmocom/core/osmo_io.h> #include <osmocom/gsm/tlv.h>
struct osmo_fd; @@ -56,12 +57,15 @@
/* Send an IPA CCM PONG via the given FD */ int ipa_ccm_send_pong(int fd); +int ipa_ccm_send_pong_iofd(struct osmo_io_fd *iofd);
/* Send an IPA CCM ID_ACK via the given FD */ int ipa_ccm_send_id_ack(int fd); +int ipa_ccm_send_id_ack_iofd(struct osmo_io_fd *iofd);
/* Send an IPA CCM ID_REQ via the given FD */ int ipa_ccm_send_id_req(int fd); +int ipa_ccm_send_id_req_iofd(struct osmo_io_fd *iofd);
/* Common handling of IPA CCM, BSC side */ int ipa_ccm_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd); @@ -69,6 +73,12 @@ /* Common handling of IPA CCM, BTS side */ int ipa_ccm_rcvmsg_bts_base(struct msgb *msg, struct osmo_fd *bfd);
+/* Common handling of IPA CCM, BSC side */ +int ipa_ccm_rcvmsg_base_iofd(struct msgb *msg, struct osmo_io_fd *iofd); + +/* Common handling of IPA CCM, BTS side */ +int ipa_ccm_rcvmsg_bts_base_iofd(struct msgb *msg, struct osmo_io_fd *iofd); + /* prepend (push) an ipaccess_head_ext to the msgb */ void ipa_prepend_header_ext(struct msgb *msg, int proto);
@@ -79,3 +89,5 @@
int ipa_msg_recv(int fd, struct msgb **rmsg); int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg); + +int ipa_iofd_segmentation_cb(struct msgb *msg, int read); \ No newline at end of file diff --git a/src/gsm/ipa.c b/src/gsm/ipa.c index 447e8e3..c48b5cc 100644 --- a/src/gsm/ipa.c +++ b/src/gsm/ipa.c @@ -39,6 +39,7 @@ #include <osmocom/core/logging.h> #include <osmocom/core/macaddr.h> #include <osmocom/core/select.h> +#include <osmocom/core/osmo_io.h>
#include <osmocom/gsm/tlv.h> #include <osmocom/gsm/protocol/ipaccess.h> @@ -468,6 +469,36 @@ return ipa_send(fd, ipa_id_req_msg, sizeof(ipa_id_req_msg)); }
+int ipa_ccm_send_pong_iofd(struct osmo_io_fd *iofd) +{ + uint8_t *data; + struct msgb *msg = msgb_alloc(sizeof(ipa_pong_msg), "IPA PONG"); + data = msgb_put(msg, sizeof(ipa_pong_msg)); + memcpy(data, ipa_pong_msg, sizeof(ipa_pong_msg)); + + return osmo_iofd_write_msgb(iofd, msg); +} + +int ipa_ccm_send_id_ack_iofd(struct osmo_io_fd *iofd) +{ + uint8_t *data; + struct msgb *msg = msgb_alloc(sizeof(ipa_id_ack_msg), "IPA ID ACK"); + data = msgb_put(msg, sizeof(ipa_id_ack_msg)); + memcpy(data, ipa_id_ack_msg, sizeof(ipa_id_ack_msg)); + + return osmo_iofd_write_msgb(iofd, msg); +} + +int ipa_ccm_send_id_req_iofd(struct osmo_io_fd *iofd) +{ + uint8_t *data; + struct msgb *msg = msgb_alloc(sizeof(ipa_id_req_msg), "IPA ID REQ"); + data = msgb_put(msg, sizeof(ipa_id_req_msg)); + memcpy(data, ipa_id_req_msg, sizeof(ipa_id_req_msg)); + + return osmo_iofd_write_msgb(iofd, msg); +} + /* base handling of the ip.access protocol */ int ipa_ccm_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd) { @@ -507,6 +538,44 @@ }
/* base handling of the ip.access protocol */ +int ipa_ccm_rcvmsg_base_iofd(struct msgb *msg, struct osmo_io_fd *iofd) +{ + uint8_t msg_type = *(msg->l2h); + int ret; + + switch (msg_type) { + case IPAC_MSGT_PING: + ret = ipa_ccm_send_pong_iofd(iofd); + 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 = ipa_ccm_send_id_ack_iofd(iofd); + 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 ipa_ccm_rcvmsg_bts_base(struct msgb *msg, struct osmo_fd *bfd) { uint8_t msg_type = *(msg->l2h); @@ -530,6 +599,30 @@ return ret; }
+/* base handling of the ip.access protocol */ +int ipa_ccm_rcvmsg_bts_base_iofd(struct msgb *msg, struct osmo_io_fd *iofd) +{ + uint8_t msg_type = *(msg->l2h); + int ret = 0; + + switch (msg_type) { + case IPAC_MSGT_PING: + ret = ipa_ccm_send_pong_iofd(iofd); + 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 ipa_prepend_header_ext(struct msgb *msg, int proto) { @@ -718,4 +811,38 @@ return nmsg; }
+void ipa_iofd_read_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) +{ + +} + +void ipa_iofd_write_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) +{ + +} + +int ipa_iofd_segmentation_cb(struct msgb *msg, int read) +{ + struct ipaccess_head *hh; + int len; + if (read < sizeof(*hh)) + return sizeof(*hh); + + msg->l1h = msg->data; + hh = (struct ipaccess_head *) msg->data; + + /* then read the length as specified in header */ + len = osmo_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); + return -EIO; + } + + msg->l2h = hh->data; + + return sizeof(*hh) + len; +} + /*! @} */ diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index 7b5cd94..8498ffa 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -618,10 +618,15 @@ gan_pdisc_vals;
ipa_ccm_rcvmsg_base; +ipa_ccm_rcvmsg_base_iofd; ipa_ccm_rcvmsg_bts_base; +ipa_ccm_rcvmsg_bts_base_iofd; ipa_ccm_send_id_ack; +ipa_ccm_send_id_ack_iofd; ipa_ccm_send_id_req; +ipa_ccm_send_id_req_iofd; ipa_ccm_send_pong; +ipa_ccm_send_pong_iofd; ipa_ccm_tlv_to_unitdata; ipa_ccm_idtag_name; ipa_ccm_idtag_parse; @@ -637,6 +642,7 @@ ipa_prepend_header; ipa_prepend_header_ext; ipa_send; +ipa_iofd_segmentation_cb;
osmo_apn_qualify; osmo_apn_qualify_buf;