extern int32_t ciaaSerialDevices_read(ciaaDevices_deviceType const * const device, uint8_t * const buf, uint32_t nbyte)
{
   /* get serial device */
   ciaaSerialDevices_deviceType * serialDevice =
      (ciaaSerialDevices_deviceType*) device->layer;
   int32_t ret = 0;

   /* if the rx buffer is not empty */
   if (!ciaaLibs_circBufEmpty(&serialDevice->rxBuf))
   {
      /* try to read nbyte from rxBuf and store it to the user buffer */
      ret = ciaaLibs_circBufGet(&serialDevice->rxBuf,
            buf,
            nbyte);
   }
   else
   {
      /* There aren't data */
      if(serialDevice->flags & ciaaSerialDevices_NONBLOCK_MODE)
      {
         /* We are in non blocking mode */
         /* We should do a blocking call...*/
         ciaaPOSIX_errno = EAGAIN; /* shall return -1 and set errno to [EAGAIN]. */
         ret = -1;
      }
      else
      {
         /* We are in blocking mode */
         /* TODO improve this: https://github.com/ciaa/Firmware/issues/88 */
         serialDevice->device->ioctl(device->loLayer, ciaaPOSIX_IOCTL_SET_ENABLE_RX_INTERRUPT, (void*)false);

         /* get task id and function for waking up the task later */
         GetTaskID(&serialDevice->blocked.taskID);
         serialDevice->blocked.fct = (void*) ciaaSerialDevices_read;

         /* TODO improve this: https://github.com/ciaa/Firmware/issues/88 */
         serialDevice->device->ioctl(device->loLayer, ciaaPOSIX_IOCTL_SET_ENABLE_RX_INTERRUPT, (void*)true);

         /* if no data wait for it */
#ifdef POSIXE
         WaitEvent(POSIXE);
         ClearEvent(POSIXE);
#endif

         /* after the wait is not needed to check if data is avaibale on the
          * buffer. The event will be set first after adding some data into it */

         /* try to read nbyte from rxBuf and store it to the user buffer */
         ret = ciaaLibs_circBufGet(&serialDevice->rxBuf,
               buf,
               nbyte);
      }
   }
   return ret;
}
/** \brief test ciaaLibs_circBufEmpty and ciaaLibs_circBufFull
 **/
void test_ciaaLibs_circBufEmptyFull(void) {
   ciaaLibs_CircBufType * cbuf;
   size_t ret;
   char * from = "0hallo123-10HALLO12-20hallo12-30HALLO12-40HALLO12-50hallo12-60-4";
                /*0123456789012345678901234567890123456789012345678901234567890123*/
   char to[100];

   /* use linux malloc, free and memcpy */
   ciaaPOSIX_malloc_StubWithCallback(malloc);
   ciaaPOSIX_memcpy_StubWithCallback(memcpy);
   ciaaPOSIX_free_StubWithCallback(free);

   /* creates a cicular buffer with 64 bytes */
   cbuf = ciaaLibs_circBufNew(64);
   TEST_ASSERT_TRUE(NULL != cbuf);

   /* buffer is empty */
   TEST_ASSERT_TRUE(ciaaLibs_circBufEmpty(cbuf));
   TEST_ASSERT_FALSE(ciaaLibs_circBufFull(cbuf));

   ciaaLibs_circBufPut(cbuf, (void*)from, 10);

   /* buffer is not empty neither full */
   TEST_ASSERT_FALSE(ciaaLibs_circBufEmpty(cbuf));
   TEST_ASSERT_FALSE(ciaaLibs_circBufFull(cbuf));

   ciaaLibs_circBufPut(cbuf, (void*)from, 53);

   /* buffer is full */
   TEST_ASSERT_FALSE(ciaaLibs_circBufEmpty(cbuf));
   TEST_ASSERT_TRUE(ciaaLibs_circBufFull(cbuf));

   ciaaLibs_circBufGet(cbuf, to, 30);

   /* buffer is not empty neither full */
   TEST_ASSERT_FALSE(ciaaLibs_circBufEmpty(cbuf));
   TEST_ASSERT_FALSE(ciaaLibs_circBufFull(cbuf));

   ciaaLibs_circBufPut(cbuf, from, 30);

   /* buffer is full */
   TEST_ASSERT_FALSE(ciaaLibs_circBufEmpty(cbuf));
   TEST_ASSERT_TRUE(ciaaLibs_circBufFull(cbuf));

   ciaaLibs_circBufGet(cbuf, to, 63);

   /* buffer is empty */
   TEST_ASSERT_TRUE(ciaaLibs_circBufEmpty(cbuf));
   TEST_ASSERT_FALSE(ciaaLibs_circBufFull(cbuf));

   /* release buffer */
   ciaaLibs_circBufRel(cbuf);
}