Exemplo n.º 1
0
void lan8720Tick(NetInterface *interface)
{
//STM32F4-DISCOVERY evaluation board?
#if defined(USE_STM32F4_DISCOVERY)
   uint16_t value;
   bool_t linkState;

   //Read basic status register
   value = lan8720ReadPhyReg(interface, LAN8720_PHY_REG_BMSR);
   //Retrieve current link state
   linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE;

   //Link up event?
   if(linkState && !interface->linkState)
   {
      //A PHY event is pending...
      interface->phyEvent = TRUE;
      //Notify the user that the link state has changed
      osEventSet(interface->nicRxEvent);
   }
   //Link down event?
   else if(!linkState && interface->linkState)
   {
      //A PHY event is pending...
      interface->phyEvent = TRUE;
      //Notify the user that the link state has changed
      osEventSet(interface->nicRxEvent);
   }
#endif
}
Exemplo n.º 2
0
void udpUpdateEvents(Socket *socket)
{
   //Clear event flags
   socket->eventFlags = 0;

   //The socket is marked as readable if a datagram is pending in the queue
   if(socket->receiveQueue)
      socket->eventFlags |= SOCKET_EVENT_RX_READY;

   //Check whether the socket is bound to a particular network interface
   if(socket->interface != NULL)
   {
      //Handle link up and link down events
      if(socket->interface->linkState)
         socket->eventFlags |= SOCKET_EVENT_LINK_UP;
      else
         socket->eventFlags |= SOCKET_EVENT_LINK_DOWN;
   }

   //Mask unused events
   socket->eventFlags &= socket->eventMask;

   //Any event to signal?
   if(socket->eventFlags)
   {
      //Unblock I/O operations currently in waiting state
      osEventSet(socket->event);

      //Set user event to signaled state if necessary
      if(socket->userEvent != NULL)
         osEventSet(socket->userEvent);
   }
}
Exemplo n.º 3
0
void dhcpv6RelayTask(void *param)
{
   error_t error;
   uint_t i;

   //Point to the DHCPv6 relay agent context
   Dhcpv6RelayCtx *context = (Dhcpv6RelayCtx *) param;

   //Specify the events the application is interested in for
   //each client-facing sockets
   for(i = 0; i < context->clientInterfaceCount; i++)
   {
      context->eventDesc[i].socket = context->clientSocket[i];
      context->eventDesc[i].eventMask = SOCKET_EVENT_RX_READY;
   }

   //Specify the events the application is interested in for
   //the network-facing socket
   context->eventDesc[i].socket = context->serverSocket;
   context->eventDesc[i].eventMask = SOCKET_EVENT_RX_READY;

   //Main loop
   while(1)
   {
      //Wait for incoming packets on network-facing or client-facing interfaces
      error = socketPoll(context->eventDesc, context->clientInterfaceCount + 1,
         context->event, INFINITE_DELAY);

      //Stop DHCPv6 relay agent?
      if(context->stopRequest)
      {
         //The DHCPv6 relay agent is about to stop
         context->stopRequest = FALSE;
         context->running = FALSE;
         //Acknowledge the reception of the user request
         osEventSet(context->ackEvent);
         //Kill ourselves
         osTaskDelete(NULL);
      }

      //Verify status code
      if(!error)
      {
         //Check the state of each client-facing socket
         for(i = 0; i < context->clientInterfaceCount; i++)
         {
            //Relay client messages if applicable
            if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
               dhcpv6ForwardClientMessage(context, i);
         }

         //Check the state of the network-facing socket
         if(context->eventDesc[i].eventFlags & SOCKET_EVENT_RX_READY)
         {
            //Forward Relay-Reply messages from the network
            dhcpv6ForwardRelayReplyMessage(context);
         }
      }
   }
}
Exemplo n.º 4
0
error_t dhcpv6RelayStop(Dhcpv6RelayCtx *context)
{
   uint_t i;

   //Debug message
   TRACE_INFO("Stopping DHCPv6 relay agent...\r\n");

   //Ensure the specified pointer is valid
   if(!context)
      return ERROR_INVALID_PARAMETER;
   //Check DHCPv6 relay agent state
   if(!context->running)
      return ERROR_WRONG_STATE;

   //Reset ACK event before sending the kill signal
   osEventReset(context->ackEvent);
   //Stop the DHCPv6 relay agent task
   context->stopRequest = TRUE;
   //Send a signal to the task in order to abort any blocking operation
   osEventSet(context->event);

   //Wait for the process to terminate...
   osEventWait(context->ackEvent, INFINITE_DELAY);

   //Leave the All_DHCP_Relay_Agents_and_Servers multicast group
   //for each client-facing interface
   dhcpv6RelayLeaveMulticastGroup(context);

   //Close the socket that carries traffic towards the DHCPv6 server
   socketClose(context->serverSocket);

   //Properly dispose the sockets that carry traffic towards the DHCPv6 clients
   for(i = 0; i < context->clientInterfaceCount; i++)
      socketClose(context->clientSocket[i]);

   //Close event objects
   osEventClose(context->event);
   osEventClose(context->ackEvent);

   //Successful processing
   return NO_ERROR;
}
Exemplo n.º 5
0
void icecastClientTask(void *param)
{
   error_t error;
   bool_t end;
   size_t n;
   size_t length;
   size_t received;
   IcecastClientContext *context;

   //Retrieve the Icecast client context
   context = (IcecastClientContext *) param;

   //Main loop
   while(1)
   {
      //Initiate a connection to the Icecast server
      error = icecastClientConnect(context);

      //Connection to server failed?
      if(error)
      {
         //Debug message
         TRACE_ERROR("Connection to Icecast server failed!\r\n");
         //Recovery delay
         osDelay(ICECAST_RECOVERY_DELAY);
         //Try to reconnect...
         continue;
      }

      //Debug message
      TRACE_INFO("Block size = %u\r\n", context->blockSize);

      //Check block size
      if(!context->blockSize)
      {
         socketClose(context->socket);
         continue;
      }

      //Initialize loop condition variable
      end = FALSE;

      //Read as much data as possible...
      while(!end)
      {
         //Process the stream block by block
         length = context->blockSize;

         //Read current block
         while(!end && length > 0)
         {
            //Wait for the buffer to be available for writing
            osEventWait(context->writeEvent, INFINITE_DELAY);

            //Enter critical section
            osMutexAcquire(context->mutex);
            //Compute the number of bytes to read at a time
            n = min(length, context->bufferSize - context->bufferLength);
            //Leave critical section
            osMutexRelease(context->mutex);

            //Check whether the specified data crosses buffer boundaries
            if((context->writeIndex + n) > context->bufferSize)
               n = context->bufferSize - context->writeIndex;

            //Receive data
            error = socketReceive(context->socket, context->streamBuffer +
               context->writeIndex, n, &received, SOCKET_FLAG_WAIT_ALL);

            //Make sure the expected number of bytes have been received
            if(error || received != n)
               end = TRUE;

            //Enter critical section
            osMutexAcquire(context->mutex);

            //Increment write index
            context->writeIndex += n;
            //Wrap around if necessary
            if(context->writeIndex >= context->bufferSize)
               context->writeIndex -= context->bufferSize;

            //Update buffer length
            context->bufferLength += n;
            //Check whether the buffer is available for writing
            if(context->bufferLength < context->bufferSize)
               osEventSet(context->writeEvent);
            //Check whether the buffer is available for reading
            if(context->bufferLength > 0)
               osEventSet(context->readEvent);

            //Leave critical section
            osMutexRelease(context->mutex);

            //Update the total number of bytes that have been received
            context->totalLength += n;
            //Number of remaining data to read
            length -= n;
         }

         //Debug message
         TRACE_DEBUG("Total bytes received = %u\r\n", context->totalLength);

         //Check whether the metadata block should be read
         if(!end)
         {
            //Process the metadata block
            error = icecastClientProcessMetadata(context);
            //Any error to report?
            if(error) end = TRUE;
         }
      }

      //Close connection
      socketClose(context->socket);
   }
}
Exemplo n.º 6
0
error_t icecastClientReadStream(IcecastClientContext *context,
   uint8_t *data, size_t size, size_t *length, time_t timeout)
{
   bool_t status;

   //Ensure the parameters are valid
   if(!context || !data)
      return ERROR_INVALID_PARAMETER;

   //Wait for the buffer to be available for reading
   status = osEventWait(context->readEvent, timeout);
   //Timeout error?
   if(!status) return ERROR_TIMEOUT;

   //Enter critical section
   osMutexAcquire(context->mutex);
   //Compute the number of bytes to read at a time
   *length = min(size, context->bufferLength);
   //Leave critical section
   osMutexRelease(context->mutex);

   //Check whether the specified data crosses buffer boundaries
   if((context->readIndex + *length) <= context->bufferSize)
   {
      //Copy the data
      memcpy(data, context->streamBuffer + context->readIndex, *length);
   }
   else
   {
      //Copy the first part of the data
      memcpy(data, context->streamBuffer + context->readIndex,
         context->bufferSize - context->readIndex);
      //Wrap around to the beginning of the circular buffer
      memcpy(data + context->bufferSize - context->readIndex, context->streamBuffer,
         *length - context->bufferSize + context->readIndex);
   }

   //Enter critical section
   osMutexAcquire(context->mutex);

   //Increment read index
   context->readIndex += *length;
   //Wrap around if necessary
   if(context->readIndex >= context->bufferSize)
      context->readIndex -= context->bufferSize;

   //Update buffer length
   context->bufferLength -= *length;
   //Check whether the buffer is available for writing
   if(context->bufferLength < context->bufferSize)
      osEventSet(context->writeEvent);
   //Check whether the buffer is available for reading
   if(context->bufferLength > 0)
      osEventSet(context->readEvent);

   //Leave critical section
   osMutexRelease(context->mutex);

   //Successful read operation
   return NO_ERROR;
}