Hi,
I would buy a FEZ Cerberus board but I need SSL support.
Has anyone used .Net Micro Framework SSL libraries on this board ? Are there any problem about Flash size ? FEZ Cerberus has 1 MB external Flash so I think that it is enough for SSL libraries…or not ?
Paolo.
I have implemented M2Mqtt library (http://m2mqtt.codeplex.com) and now I have added SSL support but I have a strange behaviour on emulator so I want to test on a real board.
The library works without SSL on emulator and other boards.
I have tested SSL support with a PC application and it works fine (my library i compatible with all .Net Framework version : full, compact and micro).
It seems that SslStream.Read hangs or lost bytes…but If I execute the code step by step all works fine.
Without SSL all works fine…however
This is the code that send a message using SslStream (inside “channel” instance)
private MqttMsgBase SendReceive(byte[] msgBytes, int timeout = MQTT_DEFAULT_TIMEOUT)
{
// reset handle before sending
this.endReceiving.Reset();
try
{
// send message
this.channel.Send(msgBytes);
// update last message sent ticks
this.lastSend = DateTime.Now.Ticks;
}
catch (SocketException e)
{
#if (!MF_FRAMEWORK_VERSION_V4_2 && !MF_FRAMEWORK_VERSION_V4_3)
// connection reset by broker
if (e.SocketErrorCode == SocketError.ConnectionReset)
this.IsConnected = false;
#endif
throw new MqttCommunicationException();
}
// wait for answer from broker
if (this.endReceiving.WaitOne(timeout, false))
{
// message received without exception
if (this.exReceiving == null)
return this.msgReceived;
// receiving thread catched exception
else
throw this.exReceiving;
}
else
{
// throw timeout exception
throw new MqttTimeoutException();
}
}
After sent the message, it wait on an event. There is another thread that receive from network, parses the message and sets the event. Following a part of receiver thread :
// read first byte (fixed header)
readBytes = this.channel.Receive(fixedHeaderFirstByte);
if (readBytes > 0)
{
// extract message type from received byte
msgType = (byte)((fixedHeaderFirstByte[0] & MqttMsgBase.MSG_TYPE_MASK) >> MqttMsgBase.MSG_TYPE_OFFSET);
switch (msgType)
{
// impossible, broker can't send CONNECT message
case MqttMsgBase.MQTT_MSG_CONNECT_TYPE:
throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage);
// CONNACK message received from broker
case MqttMsgBase.MQTT_MSG_CONNACK_TYPE:
this.msgReceived = MqttMsgConnack.Parse(fixedHeaderFirstByte[0], this.channel);
this.endReceiving.Set();
break;
The method MqttMsgConnack.Parse() riceive the channel because inside, it reads from SslStream and parses the message.
I have seen that if I arrive with “run” until MqttMsgConnack.Parse and then step on it, the message is received well. Then if I step on this.endReceiving.Set();, it unlock other thread but if I run (with “play”) the other thread isn’t unlocked !
However, If I set a breakpoint on this.endReceiving.Set(); so that the execution runs without step until it, the application doesn’t stop to that breakpoint; it seems that a problem is happened inside parse method (reading the stream).
It’s a strange behaviour as I said you…
Following send and receive …
/// <summary>
/// Send data on the network channel to the broker
/// </summary>
/// <param name="buffer">Data buffer to send</param>
/// <returns>Number of byte sent</returns>
public int Send(byte[] buffer)
{
#if SSL
if (this.secure)
{
this.sslStream.Write(buffer, 0, buffer.Length);
return buffer.Length;
}
else
return this.socket.Send(buffer);
#else
return this.socket.Send(buffer);
#endif
}
/// <summary>
/// Receive data from the network channel (from broker)
/// </summary>
/// <param name="buffer">Data buffer for receiving data</param>
/// <returns>Number of bytes received</returns>
public int Receive(byte[] buffer)
{
#if SSL
if (this.secure)
return this.sslStream.Read(buffer, 0, buffer.Length);
else
return this.socket.Receive(buffer);
#else
return this.socket.Receive(buffer);
#endif
}
SSL is too big for cerberus and so it is not implemented.
To be sure that read return all bytes I need, I have changed it a little bit for testing :
int idx = 0;
int len = buffer.Length;
while (len != 0)
{
int read = this.sslStream.Read(buffer, idx, len);
idx += read;
len -= read;
}
return buffer.Length;
However the result is the same…
Now I’m sure that the message is arrived and I put a breakpoint on this.endReceiving.Set();
When the breakpoint hit, if I click “play”…the app thread waiting for the response isn’t unlocked ! If I execute one step on it…it works well !!
There is some problem with Set and WaitOne on AutoResetEvent ???
You actually need to check how much you read from stream. Anyways according to Gus SSL is not implemented on Cerberus. So no matter what you will try it will not work at this moment.
How can I change post title ?
This post is evolved from request on FEZ Cerberus to a probabily synchronization problem…
I think I have solved…but I’m writing better code solution.
It seems that in some cases SslStream hangs on Read even if I have set ReadTimeout so now I check DataAvailable property before Read…
As soon as I will post the right code !
Thanks.