Пример #1
0
static int ipa_client_write_default_cb(struct ipa_client_conn *link)
{
	struct osmo_fd *ofd = link->ofd;
	struct msgb *msg;
	struct llist_head *lh;
	int ret;

	LOGIPA(link, LOGL_DEBUG, "sending data\n");

	if (llist_empty(&link->tx_queue)) {
		ofd->when &= ~BSC_FD_WRITE;
		return 0;
	}
	lh = link->tx_queue.next;
	llist_del(lh);
	msg = llist_entry(lh, struct msgb, list);

	ret = send(link->ofd->fd, msg->data, msg->len, 0);
	if (ret < 0) {
		if (errno == EPIPE || errno == ENOTCONN) {
			ipa_client_conn_close(link);
			if (link->updown_cb)
				link->updown_cb(link, 0);
		}
		LOGIPA(link, LOGL_ERROR, "error to send\n");
	}
	msgb_free(msg);
	return 0;
}
Пример #2
0
static int ipa_client_read(struct ipa_client_conn *link)
{
	struct osmo_fd *ofd = link->ofd;
	struct msgb *msg;
	int ret;

	LOGIPA(link, LOGL_DEBUG, "message received\n");

	ret = ipa_msg_recv_buffered(ofd->fd, &msg, &link->pending_msg);
	if (ret <= 0) {
		if (ret == -EAGAIN)
			return 0;
		else if (ret == -EPIPE || ret == -ECONNRESET)
			LOGIPA(link, LOGL_ERROR, "lost connection with server\n");
		else if (ret == 0)
			LOGIPA(link, LOGL_ERROR, "connection closed with server\n");
		ipa_client_conn_close(link);
		if (link->updown_cb)
			link->updown_cb(link, 0);
		return -EBADF;
	}
	if (link->read_cb)
		return link->read_cb(link, msg);
	return 0;
}
Пример #3
0
static int hsl_bts_connect(struct ipa_client_conn *link)
{
    struct msgb *msg;
    uint8_t *serno;
    char serno_buf[16];
    struct hsl_unit *unit = link->line->ops->cfg.ipa.dev;
    struct e1inp_sign_link *sign_link;

    /* send the minimal message to identify this BTS. */
    msg = ipa_msg_alloc(0);
    if (!msg)
        return -ENOMEM;

    *msgb_put(msg, 1) = 0x80;
    *msgb_put(msg, 1) = 0x80;
    *msgb_put(msg, 1) = unit->swversion;
    snprintf(serno_buf, sizeof(serno_buf), "%"PRIx64, unit->serno);
    serno = msgb_put(msg, strlen(serno_buf)+1);
    memcpy(serno, serno_buf, strlen(serno_buf));
    ipa_msg_push_header(msg, 0);
    send(link->ofd->fd, msg->data, msg->len, 0);
    msgb_free(msg);

    /* ... and enable the signalling link. */
    if (!link->line->ops->sign_link_up) {
        LOGP(DLINP, LOGL_ERROR,
             "Unable to set signal link, closing socket.\n");
        ipa_client_conn_close(link);
        return -EINVAL;
    }
    sign_link = link->line->ops->sign_link_up(&unit,
                link->line, E1INP_SIGN_NONE);
    if (sign_link == NULL) {
        LOGP(DLINP, LOGL_ERROR,
             "Unable to set signal link, closing socket.\n");
        ipa_client_conn_close(link);
        return -EINVAL;
    }
    return 0;
}
Пример #4
0
static int ipa_client_fd_cb(struct osmo_fd *ofd, unsigned int what)
{
	struct ipa_client_conn *link = ofd->data;
	int error, ret = 0;
	socklen_t len = sizeof(error);

	switch(link->state) {
	case IPA_CLIENT_LINK_STATE_CONNECTING:
		ret = getsockopt(ofd->fd, SOL_SOCKET, SO_ERROR, &error, &len);
		if (ret >= 0 && error > 0) {
			ipa_client_conn_close(link);
			if (link->updown_cb)
				link->updown_cb(link, 0);
			return 0;
		}
		ofd->when &= ~BSC_FD_WRITE;
		LOGIPA(link, LOGL_NOTICE, "connection done\n");
		link->state = IPA_CLIENT_LINK_STATE_CONNECTED;
		if (link->updown_cb)
			link->updown_cb(link, 1);
		break;
	case IPA_CLIENT_LINK_STATE_CONNECTED:
		if (what & BSC_FD_READ) {
			LOGIPA(link, LOGL_DEBUG, "connected read\n");
			ret = ipa_client_read(link);
		}
		if (ret != -EBADF && (what & BSC_FD_WRITE)) {
			LOGIPA(link, LOGL_DEBUG, "connected write\n");
			ipa_client_write(link);
		}
		break;
	default:
		break;
	}
        return 0;
}