/** Free a receive packet This routine performs the network specific operations necessary to free a receive packet. This routine is called by ::EslSocketPortCloseTxDone to free a receive packet. @param [in] pPacket Address of an ::ESL_PACKET structure. @param [in, out] pRxBytes Address of the count of RX bytes **/ VOID EslUdp6PacketFree ( IN ESL_PACKET * pPacket, IN OUT size_t * pRxBytes ) { EFI_UDP6_RECEIVE_DATA * pRxData; DBG_ENTER ( ); // // Account for the receive bytes // pRxData = pPacket->Op.Udp6Rx.pRxData; *pRxBytes -= pRxData->DataLength; // // Disconnect the buffer from the packet // pPacket->Op.Udp6Rx.pRxData = NULL; // // Return the buffer to the UDP6 driver // gBS->SignalEvent ( pRxData->RecycleSignal ); DBG_EXIT ( ); }
/****************************************************************************** * 関数名 * _neo_init_itimer() * 機能 * インタバルタイマ 初期化 * 関数値 * 無し * 注意 ******************************************************************************/ void _neo_init_itimer() { DBG_ENT( M_SKL, "_neo_init_itimer" ); _dl_init( &_itimer_entry ); DBG_EXIT(0); }
/****************************************************************************** * 関数名 * _neo_init_prcs() * 機能 * プロセス管理 初期化 * 関数値 * 無し * 注意 ******************************************************************************/ void _neo_init_prcs() { DBG_ENT( M_SKL, "_neo_init_prcs" ); _dl_init( &_child_entry ); _isterm_flag = 0; DBG_EXIT(0); }
/** Process the receive completion This routine keeps the UDPv4 driver's buffer and queues it in in FIFO order to the data queue. The UDP6 driver's buffer will be returned by either ::EslUdp6Receive or ::EslSocketPortCloseTxDone. See the \ref ReceiveEngine section. This routine is called by the UDPv4 driver when data is received. @param [in] Event The receive completion event @param [in] pIo Address of an ::ESL_IO_MGMT structure **/ VOID EslUdp6RxComplete ( IN EFI_EVENT Event, IN ESL_IO_MGMT * pIo ) { size_t LengthInBytes; ESL_PACKET * pPacket; EFI_UDP6_RECEIVE_DATA * pRxData; EFI_STATUS Status; DBG_ENTER ( ); // // Get the operation status. // Status = pIo->Token.Udp6Rx.Status; // // Get the packet length // pRxData = pIo->Token.Udp6Rx.Packet.RxData; LengthInBytes = pRxData->DataLength; // // +--------------------+ +-----------------------+ // | ESL_IO_MGMT | | Data Buffer | // | | | (Driver owned) | // | +---------------+ +-----------------------+ // | | Token | ^ // | | Rx Event | | // | | | +-----------------------+ // | | RxData --> | EFI_UDP6_RECEIVE_DATA | // +----+---------------+ | (Driver owned) | // +-----------------------+ // +--------------------+ ^ // | ESL_PACKET | . // | | . // | +---------------+ . // | | pRxData --> NULL ....... // +----+---------------+ // // // Save the data in the packet // pPacket = pIo->pPacket; pPacket->Op.Udp6Rx.pRxData = pRxData; // // Complete this request // EslSocketRxComplete ( pIo, Status, LengthInBytes, FALSE ); DBG_EXIT ( ); }
/** Process the transmit completion This routine use ::EslSocketTxComplete to perform the transmit completion processing for data packets. This routine is called by the UDPv4 network layer when a data transmit request completes. @param [in] Event The normal transmit completion event @param [in] pIo Address of an ::ESL_IO_MGMT structure **/ VOID EslUdp6TxComplete ( IN EFI_EVENT Event, IN ESL_IO_MGMT * pIo ) { UINT32 LengthInBytes; ESL_PORT * pPort; ESL_PACKET * pPacket; ESL_SOCKET * pSocket; EFI_STATUS Status; DBG_ENTER ( ); // // Locate the active transmit packet // pPacket = pIo->pPacket; pPort = pIo->pPort; pSocket = pPort->pSocket; // // Get the transmit length and status // LengthInBytes = pPacket->Op.Udp6Tx.TxData.DataLength; pSocket->TxBytes -= LengthInBytes; Status = pIo->Token.Udp6Tx.Status; // // Ignore the transmit error // if ( EFI_ERROR ( Status )) { DEBUG (( DEBUG_TX, "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n", pPort, pPacket, Status )); Status = EFI_SUCCESS; } // // Complete the transmit operation // EslSocketTxComplete ( pIo, LengthInBytes, Status, "UDP ", &pSocket->pTxPacketListHead, &pSocket->pTxPacketListTail, &pPort->pTxActive, &pPort->pTxFree ); DBG_EXIT ( ); }
/****************************************************************************** * 関数名 * neo_fork() * 機能 * 子プロセスの生成 * 関数値 * 正常: 親: 0< (プロセスid) * : 子: 0 * 異常: -1 * 注意 ******************************************************************************/ int neo_fork() { _neo_child_t *pt; int pid = -1, before; DBG_ENT( M_SKL, "neo_fork" ); if( !(pt = (_neo_child_t *)neo_malloc(sizeof(_neo_child_t))) ) { goto end; } switch( pid = fork() ) { /* * Child process */ case 0: neo_free( pt ); _neo_child_clean(); break; /* * Error */ case -1: neo_free( pt ); /* * UNIX ERR */ neo_errno = unixerr2neo(); break; /* * Parent process */ default: before = sigblock( sigmask( SIGCLD ) ); pt->pid = pid; _dl_insert( pt, &_child_entry ); sigsetmask( before ); break; } end:; DBG_EXIT(pid); return( pid ); }
/** Process the transmit completion This routine use ::EslSocketTxComplete to perform the transmit completion processing for data packets. This routine is called by the UDPv4 network layer when a data transmit request completes. @param [in] Event The normal transmit completion event @param [in] pIo Address of an ::ESL_IO_MGMT structure **/ VOID EslUdp6TxComplete ( IN EFI_EVENT Event, IN ESL_IO_MGMT * pIo ) { UINT32 LengthInBytes; ESL_PORT * pPort; ESL_PACKET * pPacket; ESL_SOCKET * pSocket; EFI_STATUS Status; DBG_ENTER ( ); // // Locate the active transmit packet // pPacket = pIo->pPacket; pPort = pIo->pPort; pSocket = pPort->pSocket; // // Get the transmit length and status // LengthInBytes = pPacket->Op.Udp6Tx.TxData.DataLength; pSocket->TxBytes -= LengthInBytes; Status = pIo->Token.Udp6Tx.Status; // // Complete the transmit operation // EslSocketTxComplete ( pIo, LengthInBytes, Status, "UDP ", &pSocket->pTxPacketListHead, &pSocket->pTxPacketListTail, &pPort->pTxActive, &pPort->pTxFree ); DBG_EXIT ( ); }
/** Get the local socket address This routine returns the IPv4 address associated with the local socket. This routine is called by ::EslSocketGetLocalAddress to determine the network address for the SOCK_RAW socket. @param [in] pPort Address of an ::ESL_PORT structure. @param [out] pAddress Network address to receive the local system address **/ VOID EslIp4LocalAddressGet ( IN ESL_PORT * pPort, OUT struct sockaddr * pAddress ) { struct sockaddr_in * pLocalAddress; ESL_IP4_CONTEXT * pIp4; DBG_ENTER ( ); // // Return the local address // pIp4 = &pPort->Context.Ip4; pLocalAddress = (struct sockaddr_in *)pAddress; pLocalAddress->sin_family = AF_INET; CopyMem ( &pLocalAddress->sin_addr, &pIp4->ModeData.ConfigData.StationAddress.Addr[0], sizeof ( pLocalAddress->sin_addr )); DBG_EXIT ( ); }
/** Get the remote socket address This routine returns the address of the remote connection point associated with the SOCK_DGRAM socket. This routine is called by ::EslSocketGetPeerAddress to detemine the UDPv4 address and port number associated with the network adapter. @param [in] pPort Address of an ::ESL_PORT structure. @param [out] pAddress Network address to receive the remote system address **/ VOID EslUdp6RemoteAddressGet ( IN ESL_PORT * pPort, OUT struct sockaddr * pAddress ) { struct sockaddr_in6 * pRemoteAddress; ESL_UDP6_CONTEXT * pUdp6; DBG_ENTER ( ); // // Return the remote address // pUdp6 = &pPort->Context.Udp6; pRemoteAddress = (struct sockaddr_in6 *)pAddress; pRemoteAddress->sin6_family = AF_INET6; pRemoteAddress->sin6_port = SwapBytes16 ( pUdp6->ConfigData.RemotePort ); CopyMem ( &pRemoteAddress->sin6_addr, &pUdp6->ConfigData.RemoteAddress.Addr[0], sizeof ( pRemoteAddress->sin6_addr )); DBG_EXIT ( ); }
/** Get the local socket address This routine returns the IPv6 address and UDP port number associated with the local socket. This routine is called by ::EslSocketGetLocalAddress to determine the network address for the SOCK_DGRAM socket. @param [in] pPort Address of an ::ESL_PORT structure. @param [out] pSockAddr Network address to receive the local system address **/ VOID EslUdp6LocalAddressGet ( IN ESL_PORT * pPort, OUT struct sockaddr * pSockAddr ) { struct sockaddr_in6 * pLocalAddress; ESL_UDP6_CONTEXT * pUdp6; DBG_ENTER ( ); // // Return the local address // pUdp6 = &pPort->Context.Udp6; pLocalAddress = (struct sockaddr_in6 *)pSockAddr; pLocalAddress->sin6_family = AF_INET6; pLocalAddress->sin6_port = SwapBytes16 ( pUdp6->ConfigData.StationPort ); CopyMem ( &pLocalAddress->sin6_addr, &pUdp6->ConfigData.StationAddress.Addr[0], sizeof ( pLocalAddress->sin6_addr )); DBG_EXIT ( ); }
/** Remove a port from the list of ports to be polled. @param [in] pWebServer The web server control structure address. @param [in] SocketFD The socket's file descriptor to add to the list. **/ VOID PortRemove ( IN DT_WEB_SERVER * pWebServer, IN int SocketFD ) { nfds_t Entries; nfds_t Index; struct pollfd * pFdList; WSDT_PORT ** ppPortList; DBG_ENTER ( ); // // Attempt to remove the entry from the list // Entries = pWebServer->Entries; pFdList = pWebServer->pFdList; ppPortList = pWebServer->ppPortList; for ( Index = 0; Entries > Index; Index++ ) { // // Locate the specified socket file descriptor // if ( SocketFD == pFdList[ Index ].fd ) { // // Determine if this is the listen port // if ( SocketFD == pWebServer->HttpListenPort ) { pWebServer->HttpListenPort = -1; } // // Close the socket // close ( SocketFD ); // // Free the port structure // gBS->FreePool ( ppPortList[ Index ]); // // Remove this port from the list by copying // the rest of the list down one entry // Entries -= 1; for ( ; Entries > Index; Index++ ) { pFdList[ Index ] = pFdList[ Index + 1 ]; ppPortList[ Index ] = ppPortList[ Index + 1 ]; } pFdList[ Index ].fd = -1; pFdList[ Index ].events = 0; pFdList[ Index ].revents = 0; ppPortList[ Index ] = NULL; // // Update the number of entries in the list // pWebServer->Entries = Entries; DEBUG (( DEBUG_PORT_WORK | DEBUG_INFO, "WebServer handling %d ports\r\n", pWebServer->Entries )); break; } } DBG_EXIT ( ); }