Ejemplo n.º 1
0
Archivo: atom.c Proyecto: deviker/lldpd
/**
 * Get somethin with IO.
 *
 * @param conn       The connection to lldpd.
 * @param state_send State to be when "sending"
 * @param state_recv State to be when "receiving"
 * @param state_data Ancillary data for state handling
 * @param type       Type of message to send (and receive)
 * @param to_send    Data to send.
 * @param mi_send    Marshalling info for data to send.
 * @param to_recv    Data to receive.
 * @param mi_recv    Marshalling info for data to recive.
 * @return 0 in case of success, a negative integer in case of failure.
 *
 * The current state must match one of @c CONN_STATE_IDLE, @c state_send or @c
 * state_recv and in the two later cases, the provided @c state_data must match.
 */
int
_lldpctl_do_something(lldpctl_conn_t *conn,
    int state_send, int state_recv, const char *state_data,
    enum hmsg_type type,
    void *to_send, struct marshal_info *mi_send,
    void **to_recv, struct marshal_info *mi_recv)
{
	ssize_t rc;

	if (conn->state == CONN_STATE_IDLE) {
		/* We need to build the message to send, then send
		 * it. */
		if (ctl_msg_send_unserialized(&conn->output_buffer, &conn->output_buffer_len,
			type, to_send, mi_send) != 0)
			return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION);
		conn->state = state_send;
		if (state_data)
			conn->state_data = strdup(state_data);
	}
	if (conn->state == state_send &&
	    (state_data == NULL || !strcmp(conn->state_data, state_data))) {
		/* We need to send the currently built message */
		rc = lldpctl_send(conn);
		if (rc < 0)
			return SET_ERROR(conn, rc);
		conn->state = state_recv;
	}
	if (conn->state == state_recv &&
	    (state_data == NULL || !strcmp(conn->state_data, state_data))) {
		/* We need to receive the answer */
		while ((rc = ctl_msg_recv_unserialized(&conn->input_buffer,
			    &conn->input_buffer_len,
			    type, to_recv, mi_recv)) > 0) {
			/* We need more bytes */
			rc = _lldpctl_needs(conn, rc);
			if (rc < 0)
				return SET_ERROR(conn, rc);
		}
		if (rc < 0)
			return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION);
		/* rc == 0 */
		conn->state = CONN_STATE_IDLE;
		free(conn->state_data);
		conn->state_data = NULL;
		return 0;
	} else
		return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE);
}
Ejemplo n.º 2
0
int
lldpctl_watch(lldpctl_conn_t *conn)
{
    int rc = 0;

    RESET_ERROR(conn);

    if (conn->state != CONN_STATE_IDLE)
        return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE);

    conn->watch_triggered = 0;
    while (!conn->watch_triggered) {
        rc = _lldpctl_needs(conn, 1);
        if (rc < 0)
            return SET_ERROR(conn, rc);
    }

    RESET_ERROR(conn);
    return 0;
}