+/* read from OpenBSC via MNCC socket */
+static int mncc_fd_write(struct lcr_fd *lfd, void *inst, int idx)
+{
+ struct mncc_q_entry *qe, *qe2;
+ int rc;
+
+ while (1) {
+ qe = gsm->mncc_q_hd;
+ if (!qe) {
+ lfd->when &= ~LCR_FD_WRITE;
+ break;
+ }
+ rc = write(lfd->fd, qe->data, qe->len);
+ if (rc == 0)
+ return mncc_fd_close(lfd);
+ if (rc < 0)
+ return rc;
+ if (rc < (int)qe->len)
+ return -1;
+ /* dequeue the successfully sent message */
+ qe2 = mncc_q_dequeue();
+ assert(qe == qe2);
+ free(qe);
+ }
+ return 0;
+}
+
+/* read from OpenBSC via MNCC socket */
+static int mncc_fd_read(struct lcr_fd *lfd, void *inst, int idx)
+{
+ int rc;
+ static char buf[sizeof(struct gsm_mncc)+1024];
+ struct gsm_mncc *mncc_prim = (struct gsm_mncc *) buf;
+
+ memset(buf, 0, sizeof(buf));
+ rc = recv(lfd->fd, buf, sizeof(buf), 0);
+ if (rc == 0)
+ return mncc_fd_close(lfd);
+ if (rc < 0)
+ return rc;
+
+ /* Hand the MNCC message into LCR */
+ return message_bsc(NULL, mncc_prim->msg_type, mncc_prim);
+}
+
+/* file descriptor callback if we can read or write form MNCC socket */
+static int mncc_fd_cb(struct lcr_fd *lfd, unsigned int what, void *instance, int idx)
+{
+ int rc = 0;
+
+ if (what & LCR_FD_READ)
+ rc = mncc_fd_read(lfd, instance, idx);
+ if (rc < 0)
+ return rc;
+
+ if (what & LCR_FD_WRITE)
+ rc = mncc_fd_write(lfd, instance, idx);
+
+ return rc;
+}
+
+static int socket_retry_cb(struct lcr_timer *timer, void *instance, int index)