08-02-2007 10:18 AM
Hi Makoto,
sData is binary (copied from pcData), and sHexData is human readable for debug display.
The stream << is an overload operator for send() of the ClientSocket Class, and
the stream >> is an overload operator for the recv(). See code below.
const ClientSocket& ClientSocket::operator << ( const std::string& s ) const
{
if ( ! Socket::send ( s ) )
{
throw SocketException ( "Could not write to socket." );
}
return *this;
}
const ClientSocket& ClientSocket::operator >> ( std::string& s ) const
{
if ( ! Socket::recv ( s ) )
{
throw SocketException ( "Could not read from socket." );
}
return *this;
}
and Socket Class is a base class of the ClientSocket class and has member functions: create, bind, listen, accept, connect, send, recv,...
08-02-2007 11:31 AM
Let me point out two more things about the following code:
<<<
for ( int i = 0; i < (int) sizeof(tdsIntrSrqData); i++)
{
sData += pcData[i];
sprintf(acTemp, "%02X", pcData[i]);
if ( i % 4 == 0 )
sHexData += "\n\t";
sHexData += acTemp;
}
08-02-2007 03:04 PM
(1). when using operator (+=), the data size dynamically allocate in std::string, so the data size based on the memory size and could be read from member function size(), length(), or capacity(). It's not like the data type char *, the length is based on the null terminated string. So, we use send ( m_sock, sData.c_str(), sData.size(), MSG_NOSIGNAL );
(2). The data I send back is exactly 40 bytes long as defined below, so I don't have to handle the 4-byte alignment:
The first 24 bytes received from VISA, and 26 bytes padding of zero. The newly declare variable structure tdsSrqData has to do the memset(&SrqData, 0, sizeof(SRQ_Data));
struct SRQ_Data
{
int i32ProcId;
int i32Pointer;
int i32EventType; //NI-VISA hard coded this value to 0x3FFF200B
int i32LinkId;
int i32IpAddr;
int i32Context;
char acZero[16]; // size of SRQ data is 40 bytes so 16 = 40 - 24 (the size of the 6 integers above)
};SRQ_Data SRQ_Data;
This data structure is useful for displaying, and usage. the handle_val and this data structure could be exchange using type-casting.
ptdsSRQ_Data = (SRQ_Data *) (ptdsDeviceSrqParms->handle.handle_val);
ptdsDeviceSrqParms->handle.handle_val = (char *) ptdsSRQ_Data;
07-06-2011 06:56 AM
Hi Dominator,
I am also trying to establish interrupt channel with NI-Max and This tread is very helpful for me.
I am able to establish interrupt channel with NI-Max client but still I am not getting VI_EVENT_SERVICE_REQ event at NI-Visa client side and viWaitonEvent() function giving timeout.
I have created new thread for my issue: -
Please help.
07-06-2011 09:30 AM
Hi C++Coder,
Do you have the function device_intr_srq_1() to handle the sending back the package that NI-VISA send you?
void * device_intr_srq_1(Device_SrqParms *argp, CLIENT *clnt)
{
static char *clnt_res;
static uint32_t ui32XId = 1;
static VISA_SRQ_PACKAGE_DATA_t *ptdsIRQ_Data = (VISA_SRQ_PACKAGE_DATA_t *) (argp->handle.handle_val);
bool bIsNetworkOrdered;
bIsNetworkOrdered = LXI_GetNetworkOrder();
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call (clnt, device_intr_srq,
(xdrproc_t) xdr_Device_SrqParms, (caddr_t) argp,
(xdrproc_t) xdr_void, (caddr_t) &clnt_res,
s_tdsTimeValTimeout) != RPC_SUCCESS)
{
DEBUG_INFO("device_intr_srq_1: Fail to sent package Device_SrqParms");
return (NULL);
}
DEBUG_INFO("device_intr_srq_1: clnt_call() success");
INTR_SRQ_DATA tdsIntrSrqData;
uint32_t ui32Length = (sizeof( INTR_SRQ_DATA ) - 4) | 0X80000000;
//Create RPC Header
tdsIntrSrqData.tdsRPC_Send_Header.length = BYTES_ORDER(bIsNetworkOrdered, ui32Length);
tdsIntrSrqData.tdsRPC_Send_Header.xid = BYTES_ORDER(bIsNetworkOrdered, ui32XId++);
tdsIntrSrqData.tdsRPC_Send_Header.msg_type = MSG_TYPE_SEND;
tdsIntrSrqData.tdsRPC_Send_Header.rpcvers = BYTES_ORDER(bIsNetworkOrdered, 2);
tdsIntrSrqData.tdsRPC_Send_Header.prog = BYTES_ORDER(bIsNetworkOrdered, DEVICE_INTR);
tdsIntrSrqData.tdsRPC_Send_Header.vers = BYTES_ORDER(bIsNetworkOrdered, DEVICE_INTR_VERSION);
tdsIntrSrqData.tdsRPC_Send_Header.proc = BYTES_ORDER(bIsNetworkOrdered, device_intr_srq);
memset(tdsIntrSrqData.tdsRPC_Send_Header.auth, 0, sizeof(tdsIntrSrqData.tdsRPC_Send_Header.auth));
//Append stored SRQ data
memcpy(&tdsIntrSrqData.tdsDevSrqData.handle.handle_val, argp->handle.handle_val, sizeof(DeviceSrqParms));
tdsIntrSrqData.tdsDevSrqData.handle.handle_len = BYTES_ORDER(bIsNetworkOrdered, argp->handle.handle_len);
char *pcData = (char *) &tdsIntrSrqData;
try
{
std::string sData = "";
for ( int i = 0; i < (int) sizeof(tdsIntrSrqData); i++)
{
sData += pcData[i];
}
*pobjTcpClientInterruptSocket << sData;
}
catch ( SocketException& )
{
std::cout << "Send data failed\n";
}
clnt_res = tdsIntrSrqData.tdsDevSrqData.handle.handle_val;
DEBUG_INFO("device_intr_srq_1: Success: clnt_res=%p", &clnt_res);
return ((void *)&clnt_res);
} // End device_intr_srq_1
07-07-2011 06:30 AM
Hi Dominator,
Thanks for response!
Yes I have device_intr_srq_1() function and it is being called manually when RQS bit is set. It sends the msg which contains rpc header + Device_SrqParms . Might be I am doing some silly mistake. Let me try with your code.
I have some questions please help me in reslving the same:-
Please let me know from where you get information about RPCHDR? I haven’t found any doc which describes this message format for NI-VISA?
What is VISA_SRQ_PACKAGE_DATA_t which you are using in your device_intr_srq_1()?
Thanks
07-07-2011 09:59 AM
Hi C++Coder,
Do you work on LXI for your company?
The data structure RPCHDR and VISA_SRQ_PACKAGE_DATA_t are captured using NI-Spy when SRQ Interrupt is enabled and sent to VXI-11 Client, that is where it got it from, and I use variable ptdsIRQ_Data for displaying purposes only which I removed in this thread. Here is the data structure defined:
//Enable Data structure passes in to be returned to requester if there is SQR interrupted.
struct VISA_SRQ_PACKAGE_DATA_t
{
int i32ProcId;
int i32Pointer;
int i32EventType; //NI-VISA hard coded this value to 0x3FFF200B
int i32LinkId;
int i32IpAddr;
int i32Context;
char acZero[16]; // size of IRQ data is 40 bytes so 16 = 40 - 24 (the size of the 6 integer above)
};
typedef struct VISA_SRQ_PACKAGE_DATA_t VISA_SRQ_PACKAGE_DATA_t;
07-20-2011 02:41 AM - edited 07-20-2011 02:42 AM
Hi Dominator,
Sorry for late reply, I was out of town for some days.
>Do you work on LXI for your company?
Yes, this is my first project.
> Please let me know from where you get information about RPCHDR?
Let me rephrase my question:- how do you know that we have to send RPCHDR as socket messge. Is there any standard document which explain this requirement?
ViEnableEvent is executed successfully but viWaitOnEvent is still giving time out.
> 1. viWaitOnEvent (TCPIP0::172.21.111.220::... (0x027C0580), SERVICE_REQ, 300, 0, 0x00000000)
> Process ID: 0x000002D4 Thread ID: 0x00001394
> Start Time: 07:57:36.218 Call Duration 00:00:00.313
> Status: 0xBFFF0015 (VI_ERROR_TMO)
Might be the message which I am sending to Ni-Client is not correct. Could you please verify my socket message mentioned below.
tdsIntrSrqData.tdsRPC_Send_Header.length 140928
tdsIntrSrqData.tdsRPC_Send_Header.xid 16777216
tdsIntrSrqData.tdsRPC_Send_Header.msg_type 0
tdsIntrSrqData.tdsRPC_Send_Header.rpcvers 33554
tdsIntrSrqData.tdsRPC_Send_Header.prog 29700275
tdsIntrSrqData.tdsRPC_Send_Header.vers 16777216
tdsIntrSrqData.tdsRPC_Send_Header.proc 41943040
tdsIntrSrqData.tdsRPC_Send_Header.auth 00D8F67C
tdsIntrSrqData.tdsDevSrqData.handle.handle_len
tdsIntrSrqData.tdsDevSrqData.handle.handle_val
FFFFFF80 00 00 54
00 00 00 01
00 00 00 00
00 00 00 02
00 06 07 FFFFFFB1
00 00 00 01
00 00 00 19
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 28
00 00 02 FFFFFFD4
02 7C 05 FFFFFF80
3F FFFFFFFF 20 0B
00 00 00 01
0A 78 01 08
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
ptdsIRQ_Data->i32ProcId -738066432
ptdsIRQ_Data->i32Pointer -2147124222
ptdsIRQ_Data->i32EventType 186711871
ptdsIRQ_Data->i32LinkId 16777216
ptdsIRQ_Data->i32IpAddr 134313994
ptdsIRQ_Data->i32Context 0
ptdsIRQ_Data->acZero
I am running VXI server and NI-client on my PC. There is no additional h/w attached with my PC.
Please find the attached wireshark snap shots logs and my code.
Thanks
07-20-2011 01:32 PM
Hi C++Coder,
Here is the link to document proviced by ICS Electronics: "SRQ HANDLING WITH A VXI-11 INTERRUPT CHANNEL ON ICS's MODEL 8065 ETHERNET-TO-GPIB CONTROLLER"
The RPC Header mentions on page 2, last paragraph on the right column.
http://www.icselect.com/pdfs/ab80_4.pdf
I don't have time to go over your code, I downloaded, but with weir code (html, xml ??), but I can say the data you have is wrong, the RPC header is garbage, but the handle_val contains RPC header.
The handle_len should be 40
The handle_val suppose to have 40 bytes, so your data is shifted by the RPC Header block.
00 00 02 D4 <== Process ID
02 7C 05 80 <== Pointer
3F FF 20 0B <== Event Type
00 00 00 01 <== Link ID
0A 78 01 08 <== IP Address
00 00 00 00 <== Context
00 00 00 00 <== Padded Zeros
00 00 00 00
00 00 00 00
00 00 00 00
05-24-2013 02:21 AM
Hi NI crew,
Following this thread, I come to you since I believe I implement SRQ mechanism as you describe in this thread.
However, I still encounter 2 issues:
when my VXI11 client is calling the following method:
ViStatus status = viEnableEvent (m_instr, VI_EVENT_SERVICE_REQ, VI_QUEUE, VI_NULL);
Then my VXI11 servers "Device_Error *device_enable_srq_1( Device_EnableSrqParms enableSrqParms )" receive a handle value that match the expected cvontent:
00 00 16 20
08 00 FF 88
3F FF 20 0B // expected hard coded value
00 00 03 E8
AC 1D 0C 41 // VXI11 client IP @ is 172.29.12.65
00 00 00 00 // context
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // padded zeros.
First issue, however, the handle length is not 40, but some random value ...
Then, My VXI11 server receives this "device_enable_srq_1" call, store the handle and cast it in a SRQ_Data structure as follows:
typedef struct _SRQ_Data
{
int i32ProcId;
int i32Pointer;
int i32EventType; //NI-VISA hard coded this value to 0x3FFF200B
int i32LinkId;
int i32IpAddr;
int i32Context;
char acZero[16]; // size of SRQ data is 40 bytes so 16 = 40 - 24 (the size of the 6 integers above)
} SRQ_Data;
then I set each integer in network endianess (htonl( XXX )
and finally send that 40 byrte long payload through the socket based INTR channel.
But on the VXI11 client side, the SRQ event is not detected, although I can see the TCP packet leaving the VXI11 server, and also arriving in the VXI11 client side.
but I always get "status = viWaitOnEvent (m_instr, VI_EVENT_SERVICE_REQ, timeout, &etype, &ehandle);"
time out ...
If you have any hint from similar previous experience, Id love to hear it
thanks for your support
Franck