Split generic CCM handling out of ipaccess_bts_read_cb()

The generic functionality of responding to IPA CCM messages doesn't need
to be intertwined with our e1input abstraction.  We split this out
as new exported function ipaccess_bts_handle_ccm() and modify
ipaccess_bts_read_cb() to make use of that function.
diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h
index bc34ca3..648f105 100644
--- a/include/osmocom/abis/ipa.h
+++ b/include/osmocom/abis/ipa.h
@@ -4,6 +4,7 @@
 #include <stdint.h>
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/timer.h>
+#include <osmocom/abis/ipaccess.h>
 
 struct ipa_server_link {
 	struct e1inp_line		*line;
@@ -83,6 +84,8 @@
 int ipa_msg_recv_buffered(int fd, struct msgb **rmsg, struct msgb **tmp_msg);
 
 int ipaccess_rcvmsg_base(struct msgb *msg, struct osmo_fd *bfd);
+int ipaccess_bts_handle_ccm(struct ipa_client_conn *link,
+			    struct ipaccess_unit *dev, struct msgb *msg);
 
 void ipaccess_prepend_header(struct msgb *msg, int proto);
 void ipaccess_prepend_header_ext(struct msgb *msg, int proto);
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 7ac5ad1..f62e4b0 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -880,11 +880,12 @@
 		line->ops->sign_link_down(line);
 }
 
-static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg)
+/* handle incoming message to BTS, check if it is an IPA CCM, and if yes,
+ * handle it accordingly (PING/PONG/ID_REQ/ID_RESP/ID_ACK) */
+int ipaccess_bts_handle_ccm(struct ipa_client_conn *link,
+			    struct ipaccess_unit *dev, struct msgb *msg)
 {
 	struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
-	struct e1inp_ts *e1i_ts = NULL;
-	struct e1inp_sign_link *sign_link;
 	struct msgb *rmsg;
 	int ret = 0;
 
@@ -899,20 +900,11 @@
 
 		/* this is a request for identification from the BSC. */
 		if (msg_type == IPAC_MSGT_ID_GET) {
-			struct e1inp_sign_link *sign_link;
 			uint8_t *data = msgb_l2(msg);
 			int len = msgb_l2len(msg);
 
 			LOGP(DLINP, LOGL_NOTICE, "received ID get\n");
-			if (!link->line->ops->sign_link_up) {
-				LOGP(DLINP, LOGL_ERROR,
-					"Unable to set signal link, "
-					"closing socket.\n");
-				ret = -EINVAL;
-				goto err;
-			}
-			rmsg = ipa_bts_id_resp(link->line->ops->cfg.ipa.dev,
-						data + 1, len - 1);
+			rmsg = ipa_bts_id_resp(dev, data + 1, len - 1);
 			ret = ipaccess_send(link->ofd->fd, rmsg->data,
 						rmsg->len);
 			if (ret != rmsg->len) {
@@ -932,7 +924,51 @@
 				goto err_rmsg;
 			}
 			msgb_free(rmsg);
+		}
+		return 1;
+	}
 
+	return 0;
+
+err_rmsg:
+	msgb_free(rmsg);
+err:
+	ipa_client_conn_close(link);
+	return -1;
+}
+
+static int ipaccess_bts_read_cb(struct ipa_client_conn *link, struct msgb *msg)
+{
+	struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
+	struct e1inp_ts *e1i_ts = NULL;
+	struct e1inp_sign_link *sign_link;
+	int ret = 0;
+
+	/* special handling for IPA CCM. */
+	if (hh->proto == IPAC_PROTO_IPACCESS) {
+		uint8_t msg_type = *(msg->l2h);
+
+		/* this is a request for identification from the BSC. */
+		if (msg_type == IPAC_MSGT_ID_GET) {
+			if (!link->line->ops->sign_link_up) {
+				LOGP(DLINP, LOGL_ERROR,
+					"Unable to set signal link, "
+					"closing socket.\n");
+				ret = -EINVAL;
+				goto err;
+			}
+		}
+	}
+
+	/* core CCM handling */
+	ret = ipaccess_bts_handle_ccm(link, link->line->ops->cfg.ipa.dev, msg);
+	if (ret < 0)
+		goto err;
+
+	if (ret == 1 && hh->proto == IPAC_PROTO_IPACCESS) {
+		uint8_t msg_type = *(msg->l2h);
+
+		if (msg_type == IPAC_MSGT_ID_GET) {
 			sign_link = link->line->ops->sign_link_up(msg,
 					link->line,
 					link->ofd->priv_nr);
@@ -973,12 +1009,8 @@
 	link->line->ops->sign_link(msg);
 	return 0;
 
-err_rmsg:
-	msgb_free(rmsg);
 err:
-	osmo_fd_unregister(link->ofd);
-	close(link->ofd->fd);
-	link->ofd->fd = -1;
+	ipa_client_conn_close(link);
 	msgb_free(msg);
 	return ret;
 }