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 }
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); } }
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); } } } }
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; }
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); } }
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; }