public static OtpErlangObject CallMFASync(ErlStream stream,
string module, string function, OtpErlangObject[] args)
{
OtpErlangObject[] mfaArray = null;
OtpOutputStream eouts = new OtpOutputStream();
mfaArray = new OtpErlangObject[4];
// mod and fun and args as list
// ['mod', 'fun', arg1, arg2, ...]
mfaArray[0] = new OtpErlangAtom("c#ref");
mfaArray[1] = new OtpErlangAtom(module);
mfaArray[2] = new OtpErlangAtom(function);
if (null != args)
mfaArray[3] = new OtpErlangList(args);
else
mfaArray[3] = new OtpErlangList();
OtpErlangTuple mfaTouple = new OtpErlangTuple(mfaArray);
eouts = new OtpOutputStream();
mfaTouple.encode(eouts);
uint payloadLen = (uint)(eouts.Length + 1);
byte[] buf = new byte[eouts.Length + 5];
// added payload size (including protocol id byte)
// and the missing protocol id byte after it
buf[0] = (byte)((payloadLen & 0xFF000000) >> 24);
buf[1] = (byte)((payloadLen & 0x00FF0000) >> 16);
buf[2] = (byte)((payloadLen & 0x0000FF00) >> 8);
buf[3] = (byte)((payloadLen & 0x000000FF));
buf[4] = 131;
Array.Copy(eouts.GetBuffer(), 0, buf, 5, eouts.Length); // rest of the buffer copied
stream.Write(buf, 0, buf.Length);
// wait for data
DateTime startToWaitForData = DateTime.Now;
while (!stream.DataAvailable)
{
if ((DateTime.Now - startToWaitForData).Seconds > Properties.Settings.Default.StreamResponseTimeout)
throw new ErlnetException("Response timeout in call to " + module + ":" + function);
else
Thread.Sleep(0);
}
// read till empty
int readCount = 0;
payloadLen = 0;
// read payload length (4 byte header)
byte[] payloadbuf = new byte[4];
do {
readCount += stream.Read(payloadbuf, readCount, payloadbuf.Length - readCount);
if (readCount != 4)
continue;
else
payloadLen = ((uint)payloadbuf[3] & 0x000000FF)
+ (((uint)payloadbuf[2] << 8) & 0x0000FF00)
+ (((uint)payloadbuf[1] << 16) & 0x00FF0000)
+ (((uint)payloadbuf[0] << 24) & 0xFF000000);
break;
} while(true);
//Console.WriteLine("RX " + payloadLen + " bytes");
// read the payload of length 'payloadLen'
readCount = 0;
buf = new byte[payloadLen];
MemoryStream resp = new MemoryStream();
do
{
readCount += stream.Read(buf, readCount, buf.Length - readCount);
if (readCount != payloadLen)
continue;
else
break;
} while (true);
// rebuild term
resp.Write(buf, 0, buf.Length);
OtpErlangTuple res = (OtpErlangTuple)OtpErlangObject.decode(new OtpInputStream(resp.GetBuffer()));
//Console.WriteLine("RX " + res.elementAt(0).ToString());
return res.elementAt(1);
}