public static void ioctl(int handle, uint cmd, ref uint arg)
        {
            if (!_isInitialized)
            {
                Initialize();
            }

            switch (cmd)
            {
            case FIONREAD:
            {
                UInt32 bytesToRead = 0;
                CC3100.CC3100SocketInfo socketInfo = _cc3100.GetSocketInfo(handle);

                if (poll(handle, 0 /* SelectRead */, 0))
                {
                    /* if data is available, read it into a buffer in the background and return the actual # of available bytes to read */
                    lock (socketInfo.SocketReceiveBufferLockObject)
                    {
                        Int32 RX_BUFFER_SIZE = 1500;
                        if (socketInfo.SocketReceiveBuffer == null)
                        {
                            socketInfo.SocketReceiveBuffer = new byte[RX_BUFFER_SIZE];         // maximum rx buffer size
                        }
                        Int32 bytesRead = _cc3100.sl_Recv(handle, socketInfo.SocketReceiveBuffer, socketInfo.SocketReceiveBufferFirstAvailableIndex,
                                                          RX_BUFFER_SIZE - socketInfo.SocketReceiveBufferFirstAvailableIndex, 0);
                        if (bytesRead >= 0)
                        {
                            socketInfo.SocketReceiveBufferFirstAvailableIndex += bytesRead;
                        }
                    }
                }

                // whether or not we retrieved more data into the cached managed-code buffer, return the number of bytes now available.
                lock (socketInfo.SocketReceiveBufferLockObject)
                {
                    bytesToRead = (UInt32)socketInfo.SocketReceiveBufferFirstAvailableIndex;
                }
                arg = bytesToRead;
            }
            break;

            default:
            {
                throw new NotImplementedException();
            }
            }
        }
        public static int recv(int handle, byte[] buf, int offset, int count, int flags, int timeout_ms)
        {
            if (!_isInitialized)
            {
                Initialize();
            }

            /* TODO: enable flags */
            if (flags != 0)
            {
                throw new ArgumentException("flags");
            }
            /* TODO: enable receive timeout */
            //if (timeout_ms != System.Threading.Timeout.Infinite)
            //    throw new ArgumentOutOfRangeException("timeout_ms");

            /* if data is buffered locally, use the local buffer; if not, then read from the CC3100's buffers */
            CC3100.CC3100SocketInfo socketInfo = _cc3100.GetSocketInfo(handle);
            lock (socketInfo.SocketReceiveBufferLockObject)
            {
                if (socketInfo.SocketReceiveBuffer != null && socketInfo.SocketReceiveBufferFirstAvailableIndex > 0)
                {
                    Int32 bytesRead = System.Math.Min(count, socketInfo.SocketReceiveBufferFirstAvailableIndex);
                    Array.Copy(socketInfo.SocketReceiveBuffer, 0, buf, offset, bytesRead);
                    Array.Copy(socketInfo.SocketReceiveBuffer, bytesRead,
                               socketInfo.SocketReceiveBuffer, 0, socketInfo.SocketReceiveBufferFirstAvailableIndex - bytesRead);
                    socketInfo.SocketReceiveBufferFirstAvailableIndex -= bytesRead;
                    return(bytesRead);
                }
            }

            /* if no data was buffered locally, read from the CC3100's buffers */
            Int32 retVal = _cc3100.sl_Recv(handle, buf, offset, count, 0);

            if (retVal < 0)
            {
                throw new CC3100SimpleLinkException(retVal); /* TODO: determine the best exception, based on retVal */
            }

            return(retVal); // positive value indicates # of bytes received
        }