ipa: Use enhanced ipa_msg_recv_buffered() to cope with partioned IPA messages

The old ipa_msg_recv() implementation didn't support partial receive,
so IPA connections got disconnected when this happened.

This patch adds the handling of the temporary message buffers and uses
ipa_msg_recv_buffered().

It has been successfully tested by jerlbeck with osmo-nitb and
osmo-bsc.

Ticket: OW#768
Sponsored-by: On-Waves ehf
diff --git a/openbsc/include/openbsc/control_cmd.h b/openbsc/include/openbsc/control_cmd.h
index 725dce0..8aede15 100644
--- a/openbsc/include/openbsc/control_cmd.h
+++ b/openbsc/include/openbsc/control_cmd.h
@@ -39,6 +39,9 @@
 	/* The queue for sending data back */
 	struct osmo_wqueue write_queue;
 
+	/* Buffer for partial input data */
+	struct msgb *pending_msg;
+
 	/* Callback if the connection was closed */
 	void (*closed_cb)(struct ctrl_connection *conn);
 
diff --git a/openbsc/src/libctrl/control_if.c b/openbsc/src/libctrl/control_if.c
index 2727d0d..ca59d8c 100644
--- a/openbsc/src/libctrl/control_if.c
+++ b/openbsc/src/libctrl/control_if.c
@@ -123,6 +123,7 @@
 	llist_del(&ccon->list_entry);
 	if (ccon->closed_cb)
 		ccon->closed_cb(ccon);
+	msgb_free(ccon->pending_msg);
 	talloc_free(ccon);
 }
 
@@ -140,8 +141,10 @@
 	queue = container_of(bfd, struct osmo_wqueue, bfd);
 	ccon = container_of(queue, struct ctrl_connection, write_queue);
 
-	ret = ipa_msg_recv(bfd->fd, &msg);
+	ret = ipa_msg_recv_buffered(bfd->fd, &msg, &ccon->pending_msg);
 	if (ret <= 0) {
+		if (ret == -EAGAIN)
+			return 0;
 		if (ret == 0)
 			LOGP(DCTRL, LOGL_INFO, "The control connection was closed\n");
 		else