/* Return -1 for invalid response */
long
read_server_response_wait(nds_socket_type fd, int wt) {
    if (wt > 0 && _daq_wait_data(fd, wt) <= 0) {
	perror("read_server_response_wait: Error waiting for data");
	return -1;
    }
    return read_server_response(fd);
}
//-----------------------------------------------------------------------------
// Send NVQR_QUERY_DISCONNECT to the server and verify that it ACKs with
// NVQR_QUERY_DISCONNECT. Returns TRUE on success; FALSE on failure.
static bool disconnect_from_server(NVQRConnection c)
{
    NVQRQueryDataBuffer data;

    return write_server_command(c, NVQR_QUERY_DISCONNECT, 0, 0) &&
                            read_server_response(c, &data) &&
                            data.op == NVQR_QUERY_DISCONNECT;
}
/*  daq_recv_channel_groups()
 *
 *  Get channel groups description
 *  Returns zero on success.
 *  Sets `*num_channel_groups_received' to the actual number of 
 *  configured channel groups.
 */
int
daq_recv_channel_groups (daq_t *daq, daq_channel_group_t *group,
			 int num_groups, int *num_channel_groups_received)
{
    int i;
    int resp;
    int groups;

fprintf( stderr,
	 "daq_recv_channel_groups: entry\n" );
    if ((resp = daq_send (daq, "status channel-groups;")))
	return resp;

    /* Read the number of channels */
    if ( ( groups
	   = read_server_response (daq -> conceal -> sockfd)) <= 0) {
	fprintf (stderr, "couldn't determine the number of channel groups\n");
	return DAQD_ERROR;
    }

fprintf( stderr,
	 "daq_recv_channel_groups: num_groups: %d groups: %d\n",
	 num_groups, groups );

    *num_channel_groups_received = groups;
    if (num_groups < groups)
	groups = num_groups;

    for (i = 0; i < groups; i++) {
	int len=read_bytes(daq->conceal->sockfd,
			   group[i].name, 
			   (size_t)MAX_CHANNEL_NAME_LENGTH);
	if (len != MAX_CHANNEL_NAME_LENGTH)
	    return DAQD_ERROR;
	null_term(group [i].name, len);

	group [i].group_num
	    = read_server_response (daq -> conceal -> sockfd);
	if (group [i].group_num < 0) return DAQD_ERROR;
    }
    return 0;
}
//-----------------------------------------------------------------------------
// Send NVQR_QUERY_MEMINFO to the server and verify that it ACKs with
// NVQR_QUERY_MEMINFO. Pass the meminfo read from the server back to the caller.
nvqrReturn_t nvqr_request_meminfo(NVQRConnection c, GLenum queryType,
                                         NVQRQueryDataBuffer *buf)
{
    if (write_server_command(c, NVQR_QUERY_MEMORY_INFO, queryType, 0) &&
        read_server_response(c, buf) &&
        buf->op == NVQR_QUERY_MEMORY_INFO)
    {
        return NVQR_SUCCESS;
    }

    return NVQR_ERROR_UNKNOWN;
}
//-----------------------------------------------------------------------------
// Send NVQR_QUERY_CONNECT to the server and verify that it ACKs with
// NVQR_QUERY_CONNECT. Returns TRUE on success; FALSE on failure.
static bool connect_to_server(NVQRConnection *conn)
{
    NVQRQueryDataBuffer data;
    bool ret = write_server_command(*conn, NVQR_QUERY_CONNECT, 0, get_my_pid());

    if (ret) {
        ret = open_client_connection(conn);

        if (ret) {
            if (!read_server_response(*conn, &data) ||
                data.op != NVQR_QUERY_CONNECT) {
                close_client_connection(*conn);
            }
        }
    }

    return ret;
}