error_t dhcpv6ForwardClientMessage(Dhcpv6RelayCtx *context, uint_t index) { error_t error; uint32_t interfaceId; size_t inputMessageLen; size_t outputMessageLen; Dhcpv6RelayMessage *inputMessage; Dhcpv6RelayMessage *outputMessage; Dhcpv6Option *option; IpAddr ipAddr; //Point to the buffer where to store the incoming DHCPv6 message inputMessage = (Dhcpv6RelayMessage *) (context->buffer + DHCPV6_RELAY_FORW_OVERHEAD); //Message that will be forwarded by the DHCPv6 relay agent outputMessage = (Dhcpv6RelayMessage *) context->buffer; //Read incoming message error = socketReceiveFrom(context->clientSocket[index], &ipAddr, NULL, inputMessage, DHCPV6_MAX_MSG_SIZE - DHCPV6_RELAY_FORW_OVERHEAD, &inputMessageLen, 0); //Any error to report? if(error) return error; //Debug message TRACE_INFO("\r\nDHCPv6 message received on client-facing interface %s (%u bytes)...\r\n", context->clientInterface[index]->name, inputMessageLen); //Dump the contents of the message for debugging purpose dhcpv6DumpMessage(inputMessage, inputMessageLen); //The source address must be a valid IPv6 address if(ipAddr.length != sizeof(Ipv6Addr)) return ERROR_INVALID_ADDRESS; //Check the length of the DHCPv6 message if(inputMessageLen < sizeof(Dhcpv6Message)) return ERROR_INVALID_MESSAGE; //When the relay agent receives a valid message to be relayed, //it constructs a new Relay-Forward message outputMessage->msgType = DHCPV6_MSG_TYPE_RELAY_FORW; //Inspect the message type switch(inputMessage->msgType) { //Message received from a client? case DHCPV6_MSG_TYPE_SOLICIT: case DHCPV6_MSG_TYPE_REQUEST: case DHCPV6_MSG_TYPE_CONFIRM: case DHCPV6_MSG_TYPE_RENEW: case DHCPV6_MSG_TYPE_REBIND: case DHCPV6_MSG_TYPE_RELEASE: case DHCPV6_MSG_TYPE_DECLINE: case DHCPV6_MSG_TYPE_INFO_REQUEST: //If the relay agent received the message to be relayed from a client //the hop-count in the Relay-Forward message is set to 0 outputMessage->hopCount = 0; //Continue processing break; //Message received from another relay agent? case DHCPV6_MSG_TYPE_RELAY_FORW: //If the message received by the relay agent is a Relay-Forward message //and the hop-count in the message is greater than or equal to 32, the //relay agent discards the received message if(inputMessage->hopCount >= DHCPV6_HOP_COUNT_LIMIT) return ERROR_INVALID_MESSAGE; //Set the hop-count field to the value of the hop-count field in //the received message incremented by 1 outputMessage->hopCount = inputMessage->hopCount + 1; //Continue processing break; //Message received from a server? default: //Discard ADVERTISE, REPLY, RECONFIGURE and RELAY-REPL messages return ERROR_INVALID_MESSAGE; } //Set the link-address field to the unspecified address outputMessage->linkAddress = IPV6_UNSPECIFIED_ADDR; //Copy the source address from the header of the IP datagram in //which the message was received to the peer-address field outputMessage->peerAddress = ipAddr.ipv6Addr; //Size of the Relay-Forward message outputMessageLen = sizeof(Dhcpv6RelayMessage); //Get the interface identifier interfaceId = context->clientInterface[index]->identifier; //Convert the 32-bit integer to network byte order interfaceId = htonl(interfaceId); //If the relay agent cannot use the address in the link-address field //to identify the interface through which the response to the client //will be relayed, the relay agent must include an Interface ID option dhcpv6AddOption(outputMessage, &outputMessageLen, DHCPV6_OPTION_INTERFACE_ID, &interfaceId, sizeof(interfaceId)); //Copy the received DHCPv6 message into a Relay Message option option = dhcpv6AddOption(outputMessage, &outputMessageLen, DHCPV6_OPTION_RELAY_MSG, NULL, 0); //Set the appropriate length of the option option->length = htons(inputMessageLen); //Adjust the length of the Relay-Forward message outputMessageLen += inputMessageLen; //Debug message TRACE_INFO("Forwarding DHCPv6 message on network-facing interface %s (%u bytes)...\r\n", context->serverInterface->name, outputMessageLen); //Dump the contents of the message for debugging purpose dhcpv6DumpMessage(outputMessage, outputMessageLen); //Destination address to be used when relaying the client message ipAddr.length = sizeof(Ipv6Addr); ipAddr.ipv6Addr = context->serverAddress; //Relay the client message to the server return socketSendTo(context->serverSocket, &ipAddr, DHCPV6_SERVER_PORT, outputMessage, outputMessageLen, NULL, 0); }
//------------------------------------------------------------------------------ /// Loads the logical mapping contained in the given physical block. /// Returns 0 if successful; otherwise, returns a NandCommon_ERROR code. /// \param mapped Pointer to a MappedNandFlash instance. /// \param physicalBlock Physical block number. //------------------------------------------------------------------------------ static unsigned char LoadLogicalMapping( struct MappedNandFlash *mapped, unsigned short physicalBlock) { unsigned char error; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); unsigned short numBlocks = ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)); unsigned char *pDataBuffer = RawNandFlash_GetDataBuffer(RAW(mapped)); unsigned int remainingSize; unsigned char *currentBuffer; unsigned short currentPage; unsigned int readSize; unsigned int i; unsigned char status; signed short logicalBlock; //signed short firstBlock, lastBlock; TRACE_INFO("LoadLogicalMapping(B#%d)\r\n", physicalBlock); // Load mapping from pages #1 - #XXX of block currentBuffer = (unsigned char *) mapped->logicalMapping; remainingSize = sizeof(mapped->logicalMapping); currentPage = 1; while (remainingSize > 0) { // Read page readSize = min(remainingSize, pageDataSize); error = ManagedNandFlash_ReadPage(MANAGED(mapped), physicalBlock, currentPage, pDataBuffer, 0); if (error) { RawNandFlash_ReleaseDataBuffer(RAW(mapped)); TRACE_ERROR( "LoadLogicalMapping: Failed to load mapping\r\n"); return error; } // Copy page info memcpy(currentBuffer, pDataBuffer, readSize); currentBuffer += readSize; remainingSize -= readSize; currentPage++; } // Store mapping block index mapped->logicalMappingBlock = physicalBlock; // Power-loss recovery for (i=0; i < numBlocks; i++) { // Check that this is not the logical mapping block if (i != physicalBlock) { status = mapped->managed.blockStatuses[i].status; logicalBlock = MappedNandFlash_PhysicalToLogical(mapped, i); // Block is LIVE if (status == NandBlockStatus_LIVE) { // Block is not mapped -> release it if (logicalBlock == -1) { TRACE_WARNING_WP("-I- Release unmapped LIVE #%d\r\n", i); ManagedNandFlash_ReleaseBlock(MANAGED(mapped), i); } } // Block is DIRTY else if (status == NandBlockStatus_DIRTY) { // Block is mapped -> fake it as live if (logicalBlock != -1) { TRACE_WARNING_WP("-I- Mark mapped DIRTY #%d -> LIVE\r\n", i); mapped->managed.blockStatuses[i].status = NandBlockStatus_LIVE; } } // Block is FREE or BAD else { // Block is mapped -> remove it from mapping if (logicalBlock != -1) { TRACE_WARNING_WP("-I- Unmap FREE or BAD #%d\r\n", i); mapped->logicalMapping[logicalBlock] = -1; } } } } RawNandFlash_ReleaseDataBuffer(RAW(mapped)); TRACE_WARNING_WP("-I- Mapping loaded from block #%d\r\n", physicalBlock); return 0; }
//------------------------------------------------------------------------------ /// Scans a mapped nandflash to find an existing logical block mapping. If a /// block contains the mapping, its index is stored in the provided variable (if /// pointer is not 0). /// Returns 0 if mapping has been found; otherwise returns /// NandCommon_ERROR_NOMAPPING if no mapping exists, or another /// NandCommon_ERROR_xxx code. /// \param mapped Pointer to a MappedNandFlash instance. /// \param logicalMappingBlock Pointer to a variable for storing the block /// number. //------------------------------------------------------------------------------ static unsigned char FindLogicalMappingBlock( const struct MappedNandFlash *mapped, signed short *logicalMappingBlock) { unsigned short block; unsigned char found; unsigned short numBlocks = ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)); unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); unsigned char *pDataBuffer = RawNandFlash_GetDataBuffer(RAW(mapped)); unsigned char error; //unsigned char data[NandCommon_MAXPAGEDATASIZE]; unsigned int i; TRACE_INFO("FindLogicalMappingBlock()~%d\r\n", numBlocks); // Search each LIVE block found = 0; block = 0; while (!found && (block < numBlocks)) { // Check that block is LIVE if (MANAGED(mapped)->blockStatuses[block].status == NandBlockStatus_LIVE) { // Read block TRACE_INFO("Checking LIVE block #%d\r\n", block); error = ManagedNandFlash_ReadPage(MANAGED(mapped), block, 0, pDataBuffer, 0); if (!error) { // Compare data with logical mapping pattern i = 0; found = 1; while ((i < pageDataSize) && found) { if (pDataBuffer[i] != PATTERN(i)) { found = 0; } i++; } // If this is the mapping, stop looking if (found) { TRACE_WARNING_WP("-I- Logical mapping in block #%d\r\n", block); if (logicalMappingBlock) { *logicalMappingBlock = block; } RawNandFlash_ReleaseDataBuffer(RAW(mapped)); return 0; } } else if (error != NandCommon_ERROR_WRONGSTATUS) { TRACE_ERROR( "FindLogicalMappingBlock: Failed to scan block #%d\r\n", block); RawNandFlash_ReleaseDataBuffer(RAW(mapped)); return error; } } block++; } RawNandFlash_ReleaseDataBuffer(RAW(mapped)); TRACE_WARNING("No logical mapping found in device\r\n"); return NandCommon_ERROR_NOMAPPING; }
//----------------------------------------------------------------------------- /// Invoked when a new SETUP request is received from the host. Forwards the /// request to the Mass Storage device driver handler function. /// \param request Pointer to a USBGenericRequest instance. /// \return 0 if the request is Unsupported, 1 if the request handled. //----------------------------------------------------------------------------- unsigned char MSDDFunctionDriver_RequestHandler( const USBGenericRequest *request) { // Handle requests switch (USBGenericRequest_GetRequest(request)) { //--------------------- case USBGenericRequest_CLEARFEATURE: //--------------------- TRACE_INFO("ClrFeat "); switch (USBFeatureRequest_GetFeatureSelector(request)) { //--------------------- case USBFeatureRequest_ENDPOINTHALT: //--------------------- TRACE_INFO("Hlt "); // Do not clear the endpoint halt status if the device is waiting // for a reset recovery sequence if (!msdDriver.waitResetRecovery) { // Forward the request to the standard handler return 0; } else { TRACE_INFO("No "); } USBD_Write(0, 0, 0, 0, 0); break; //------ default: //------ // Forward the request to the standard handler return 0; } break; //------------------- case MSD_GET_MAX_LUN: //------------------- TRACE_INFO("gMaxLun "); // Check request parameters if ((request->wValue == 0) && (request->wIndex == MSDD_Descriptors_INTERFACENUM) && (request->wLength == 1)) { USBD_Write(0, &(msdDriver.maxLun), 1, 0, 0); } else { TRACE_WARNING( "MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r", request->wValue, request->wIndex, request->wLength); USBD_Stall(0); } break; //----------------------- case MSD_BULK_ONLY_RESET: //----------------------- TRACE_INFO("Rst "); // Check parameters if ((request->wValue == 0) && (request->wIndex == MSDD_Descriptors_INTERFACENUM) && (request->wLength == 0)) { // Reset the MSD driver MSDD_Reset(); USBD_Write(0, 0, 0, 0, 0); } else { TRACE_WARNING( "MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r", request->wValue, request->wIndex, request->wLength); USBD_Stall(0); } break; //------ default: //------ // Forward request to standard handler return 0; } return 1; }
void dnsProcessResponse(NetInterface *interface, const IpPseudoHeader *pseudoHeader, const UdpHeader *udpHeader, const ChunkedBuffer *buffer, size_t offset, void *params) { uint_t i; uint_t j; size_t pos; size_t length; DnsHeader *message; DnsQuestion *question; DnsResourceRecord *resourceRecord; DnsCacheEntry *entry; //Retrieve the length of the DNS message length = chunkedBufferGetLength(buffer) - offset; //Ensure the DNS message is valid if(length < sizeof(DnsHeader)) return; if(length > DNS_MESSAGE_MAX_SIZE) return; //Point to the DNS message header message = chunkedBufferAt(buffer, offset); //Sanity check if(!message) return; //Debug message TRACE_INFO("DNS message received (%" PRIuSIZE " bytes)...\r\n", length); //Dump message dnsDumpMessage(message, length); //Check message type if(!message->qr) return; //The DNS message shall contain one question if(ntohs(message->qdcount) != 1) return; //Acquire exclusive access to the DNS cache osAcquireMutex(&dnsCacheMutex); //Loop through DNS cache entries for(i = 0; i < DNS_CACHE_SIZE; i++) { //Point to the current entry entry = &dnsCache[i]; //DNS name resolution in progress? if(entry->state == DNS_STATE_IN_PROGRESS && entry->protocol == HOST_NAME_RESOLVER_DNS) { //Check destination port number if(entry->port == ntohs(udpHeader->destPort)) { //Compare identifier against the expected one if(ntohs(message->id) != entry->id) break; //Point to the first question pos = sizeof(DnsHeader); //Parse domain name pos = dnsParseName(message, length, pos, NULL, 0); //Invalid name? if(!pos) break; //Malformed mDNS message? if((pos + sizeof(DnsQuestion)) > length) break; //Compare domain name if(!dnsCompareName(message, length, sizeof(DnsHeader), entry->name, 0)) break; //Point to the corresponding entry question = DNS_GET_QUESTION(message, pos); //Check the class of the query if(ntohs(question->qclass) != DNS_RR_CLASS_IN) break; //Check the type of the query if(entry->type == HOST_TYPE_IPV4 && ntohs(question->qtype) != DNS_RR_TYPE_A) break; if(entry->type == HOST_TYPE_IPV6 && ntohs(question->qtype) != DNS_RR_TYPE_AAAA) break; //Make sure recursion is available if(!message->ra) { //The entry should be deleted since name resolution has failed dnsDeleteEntry(entry); //Exit immediately break; } //Check return code if(message->rcode != DNS_RCODE_NO_ERROR) { //The entry should be deleted since name resolution has failed dnsDeleteEntry(entry); //Exit immediately break; } //Point to the first answer pos += sizeof(DnsQuestion); //Parse answer resource records for(j = 0; j < ntohs(message->ancount); j++) { //Parse domain name pos = dnsParseName(message, length, pos, NULL, 0); //Invalid name? if(!pos) break; //Point to the associated resource record resourceRecord = DNS_GET_RESOURCE_RECORD(message, pos); //Point to the resource data pos += sizeof(DnsResourceRecord); //Make sure the resource record is valid if(pos > length) break; if((pos + ntohs(resourceRecord->rdlength)) > length) break; #if (IPV4_SUPPORT == ENABLED) //IPv4 address expected? if(entry->type == HOST_TYPE_IPV4) { //A resource record found? if(ntohs(resourceRecord->rtype) == DNS_RR_TYPE_A && ntohs(resourceRecord->rdlength) == sizeof(Ipv4Addr)) { //Copy the IPv4 address entry->ipAddr.length = sizeof(Ipv4Addr); ipv4CopyAddr(&entry->ipAddr.ipv4Addr, resourceRecord->rdata); //Save current time entry->timestamp = osGetSystemTime(); //Save TTL value entry->timeout = ntohl(resourceRecord->ttl) * 1000; //Limit the lifetime of the DNS cache entries entry->timeout = MIN(entry->timeout, DNS_MAX_LIFETIME); //Unregister UDP callback function udpDetachRxCallback(interface, entry->port); //Host name successfully resolved entry->state = DNS_STATE_RESOLVED; //Exit immediately break; } } #endif #if (IPV6_SUPPORT == ENABLED) //IPv6 address expected? if(entry->type == HOST_TYPE_IPV6) { //AAAA resource record found? if(ntohs(resourceRecord->rtype) == DNS_RR_TYPE_AAAA && ntohs(resourceRecord->rdlength) == sizeof(Ipv6Addr)) { //Copy the IPv6 address entry->ipAddr.length = sizeof(Ipv6Addr); ipv6CopyAddr(&entry->ipAddr.ipv6Addr, resourceRecord->rdata); //Save current time entry->timestamp = osGetSystemTime(); //Save TTL value entry->timeout = ntohl(resourceRecord->ttl) * 1000; //Limit the lifetime of the DNS cache entries entry->timeout = MIN(entry->timeout, DNS_MAX_LIFETIME); //Unregister UDP callback function udpDetachRxCallback(interface, entry->port); //Host name successfully resolved entry->state = DNS_STATE_RESOLVED; //Exit immediately break; } } #endif //Point to the next resource record pos += ntohs(resourceRecord->rdlength); } //We are done break; } } } //Release exclusive access to the DNS cache osReleaseMutex(&dnsCacheMutex); }
DynamixelSimpleAPI::DynamixelSimpleAPI(int servoSerie) { if (servoSerie != SERVO_UNKNOWN) { if (servoSerie >= SERVO_HERKULEX) { ackPolicy = 1; maxId = 253; protocolVersion = 1; servoSerie = SERVO_DRS; if (servoSerie == SERVO_DRS_0402 || servoSerie == SERVO_DRS_0602) { ct = DRS0x02_control_table; } else if (servoSerie == SERVO_DRS_0401 || servoSerie == SERVO_DRS_0601) { ct = DRS0x01_control_table; } else { ct = DRS0101_control_table; } TRACE_INFO(DAPI, "- Using HerkuleX communication protocol\n"); } else //if (servos >= SERVO_DYNAMIXEL) { ackPolicy = 2; maxId = 252; if (servoSerie >= SERVO_PRO) { protocolVersion = 2; servoSerie = SERVO_PRO; ct = PRO_control_table; } else if (servoSerie >= SERVO_XL) { protocolVersion = 2; servoSerie = SERVO_XL; ct = XL320_control_table; } else // SERVO AX to MX { // Default is Dynamixel MX, the more 'capable' of the Dynamixel v1 series protocolVersion = 1; servoSerie = SERVO_MX; ct = MX_control_table; if (serialDevice == SERIAL_USB2AX) { // The USB2AX device uses the ID 253 for itself maxId = 252; } else { maxId = 253; } } if (protocolVersion == 2) { TRACE_INFO(DAPI, "- Using Dynamixel communication protocol version 2\n"); } else { TRACE_INFO(DAPI, "- Using Dynamixel communication protocol version 1\n"); } } } else { TRACE_WARNING(DAPI, "Warning: Unknown servo serie!\n"); } }
/* FreeRTOS Callbacks */ void vApplicationTickHook(void) { static int i = 0; if (i < 1000) i++; else { TRACE_INFO("tick\n"); i = 0; } }
int_t main(void) { error_t error; NetInterface *interface; OsTask *task; MacAddr macAddr; #if (APP_USE_DHCP == DISABLED) Ipv4Addr ipv4Addr; #endif #if (APP_USE_SLAAC == DISABLED) Ipv6Addr ipv6Addr; #endif //System initialization systemInit(); //Initialize kernel osInitKernel(); //Configure debug UART debugInit(115200); //Start-up message TRACE_INFO("\r\n"); TRACE_INFO("******************************\r\n"); TRACE_INFO("*** CycloneSSL Client Demo ***\r\n"); TRACE_INFO("******************************\r\n"); TRACE_INFO("Copyright: 2010-2014 Oryx Embedded\r\n"); TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__); TRACE_INFO("Target: PIC32MX795F512L\r\n"); TRACE_INFO("\r\n"); //Configure I/Os ioInit(); //Generate a random seed //PRNG initialization error = yarrowInit(&yarrowContext); //Any error to report? if(error) { //Debug message TRACE_ERROR("Failed to initialize PRNG!\r\n"); //Exit immediately return ERROR_FAILURE; } //Properly seed the PRNG error = yarrowSeed(&yarrowContext, (uint8_t *) seed, 32); //Any error to report? if(error) { //Debug message TRACE_ERROR("Failed to seed PRNG!\r\n"); //Exit immediately return error; } //Debug message TRACE_INFO("Loading credentials...\r\n"); //Start of exception handling block do { //Load trusted CA certificates error = resGetData(APP_CA_CERT_BUNDLE, (uint8_t **) &trustedCaList, &trustedCaListLength); //Any error to report? if(error) break; //Load client's certificate error = resGetData(APP_CLIENT_CERT, (uint8_t **) &clientCert, &clientCertLength); //Any error to report? if(error) break; //Load client's private key error = resGetData(APP_CLIENT_PRIVATE_KEY, (uint8_t **) &clientPrivateKey, &clientPrivateKeyLength); //Any error to report? if(error) break; //End of exception handling block } while(0); //Check error code if(error) { //Debug message TRACE_ERROR("Failed to load credentials!\r\n"); } //TCP/IP stack initialization error = tcpIpStackInit(); //Any error to report? if(error) { //Debug message TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n"); } //Configure the first Ethernet interface interface = &netInterface[0]; //Set interface name tcpIpStackSetInterfaceName(interface, "eth0"); //Set host name tcpIpStackSetHostname(interface, "SSLClientDemo"); //Select the relevant network adapter tcpIpStackSetDriver(interface, &pic32mxEthDriver); tcpIpStackSetPhyDriver(interface, &dp83848PhyDriver); //Set external interrupt line driver tcpIpStackSetExtIntDriver(interface, &extIntDriver); #if (APP_USE_DEFAULT_MAC_ADDR == ENABLED) //Use the factory preprogrammed MAC address macStringToAddr("00-00-00-00-00-00", &macAddr); tcpIpStackSetMacAddr(interface, &macAddr); #else //Override the factory preprogrammed address macStringToAddr(APP_MAC_ADDR, &macAddr); tcpIpStackSetMacAddr(interface, &macAddr); #endif //Initialize network interface error = tcpIpStackConfigInterface(interface); //Any error to report? if(error) { //Debug message TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name); } #if (IPV4_SUPPORT == ENABLED) #if (APP_USE_DHCP == ENABLED) //Get default settings dhcpClientGetDefaultSettings(&dhcpClientSettings); //Set the network interface to be configured by DHCP dhcpClientSettings.interface = interface; //Disable rapid commit option dhcpClientSettings.rapidCommit = FALSE; //DHCP client initialization error = dhcpClientInit(&dhcpClientContext, &dhcpClientSettings); //Failed to initialize DHCP client? if(error) { //Debug message TRACE_ERROR("Failed to initialize DHCP client!\r\n"); } //Start DHCP client error = dhcpClientStart(&dhcpClientContext); //Failed to start DHCP client? if(error) { //Debug message TRACE_ERROR("Failed to start DHCP client!\r\n"); } #else //Set IPv4 host address ipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr); ipv4SetHostAddr(interface, ipv4Addr); //Set subnet mask ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr); ipv4SetSubnetMask(interface, ipv4Addr); //Set default gateway ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr); ipv4SetDefaultGateway(interface, ipv4Addr); //Set primary and secondary DNS servers ipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr); ipv4SetDnsServer(interface, 0, ipv4Addr); ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr); ipv4SetDnsServer(interface, 1, ipv4Addr); #endif #endif #if (IPV6_SUPPORT == ENABLED) #if (APP_USE_SLAAC == ENABLED) //Get default settings slaacGetDefaultSettings(&slaacSettings); //Set the network interface to be configured slaacSettings.interface = interface; //SLAAC initialization error = slaacInit(&slaacContext, &slaacSettings); //Failed to initialize SLAAC? if(error) { //Debug message TRACE_ERROR("Failed to initialize SLAAC!\r\n"); } //Start IPv6 address autoconfiguration process error = slaacStart(&slaacContext); //Failed to start SLAAC process? if(error) { //Debug message TRACE_ERROR("Failed to start SLAAC!\r\n"); } #else //Set link-local address ipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr); ipv6SetLinkLocalAddr(interface, &ipv6Addr, IPV6_ADDR_STATE_VALID); //Set IPv6 prefix ipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr); ipv6SetPrefix(interface, &ipv6Addr, APP_IPV6_PREFIX_LENGTH); //Set global address ipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr); ipv6SetGlobalAddr(interface, &ipv6Addr, IPV6_ADDR_STATE_VALID); //Set router ipv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr); ipv6SetRouter(interface, &ipv6Addr); //Set primary and secondary DNS servers ipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr); ipv6SetDnsServer(interface, 0, &ipv6Addr); ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr); ipv6SetDnsServer(interface, 1, &ipv6Addr); #endif #endif //Create user task task = osCreateTask("User Task", userTask, NULL, 500, 1); //Failed to create the task? if(task == OS_INVALID_HANDLE) { //Debug message TRACE_ERROR("Failed to create task!\r\n"); } //Create a task to blink the LED task = osCreateTask("Blink", blinkTask, NULL, 500, 1); //Failed to create the task? if(task == OS_INVALID_HANDLE) { //Debug message TRACE_ERROR("Failed to create task!\r\n"); } //Start the execution of tasks osStartKernel(); //This function should never return return 0; }
void dm9000EventHandler(NetInterface *interface) { error_t error; uint8_t status; size_t length; //Read interrupt status register status = dm9000ReadReg(DM9000_REG_ISR); //Check whether the link status has changed? if(status & ISR_LNKCHG) { //Clear interrupt flag dm9000WriteReg(DM9000_REG_ISR, ISR_LNKCHG); //Read network status register status = dm9000ReadReg(DM9000_REG_NSR); //Check link state if(status & NSR_LINKST) { //Link is up interface->linkState = TRUE; //Get current speed interface->speed100 = (status & NSR_SPEED) ? FALSE : TRUE; //Read network control register status = dm9000ReadReg(DM9000_REG_NCR); //Determine the new duplex mode interface->fullDuplex = (status & NCR_FDX) ? TRUE : FALSE; //Display link state TRACE_INFO("Link is up (%s)...\r\n", interface->name); //Display actual speed and duplex mode TRACE_INFO("%s %s\r\n", interface->speed100 ? "100BASE-TX" : "10BASE-T", interface->fullDuplex ? "Full-Duplex" : "Half-Duplex"); } else { //Link is down interface->linkState = FALSE; //Display link state TRACE_INFO("Link is down (%s)...\r\n", interface->name); } //Process link state change event nicNotifyLinkChange(interface); } //Check whether a packet has been received? if(status & ISR_PR) { //Clear interrupt flag dm9000WriteReg(DM9000_REG_ISR, ISR_PR); //Process all pending packets do { //Read incoming packet error = dm9000ReceivePacket(interface, interface->ethFrame, ETH_MAX_FRAME_SIZE, &length); //Check whether a valid packet has been received if(!error) { //Pass the packet to the upper layer nicProcessPacket(interface, interface->ethFrame, length); } //No more data in the receive buffer? } while(error != ERROR_BUFFER_EMPTY); } //Re-enable LNKCHGI and PRI interrupts dm9000WriteReg(DM9000_REG_IMR, IMR_PAR | IMR_LNKCHGI | IMR_PTI | IMR_PRI); }
int main(void) { uint32_t i; uint32_t deviceId; uint8_t ucKey; uint8_t TestPassed = 0; /* Disable watchdog */ WDT_Disable(WDT); /* Output example information */ printf("-- QSPI Serialflash Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME); SCB_EnableICache(); SCB_EnableDCache(); TimeTick_Configure(); PIO_Configure(Qspi_pins, PIO_LISTSIZE(Qspi_pins)); ENABLE_PERIPHERAL(ID_QSPI); QSPI_UserMenu(); while (1) { ucKey = DBG_GetChar(); switch (ucKey) { case '1' : S25FL1D_InitFlashInterface(1); TRACE_INFO("QSPI drivers initialized "); /* enable quad mode */ S25FL1D_QuadMode(ENABLE); PeripheralInit = 1; break; case '2' : S25FL1D_InitFlashInterface(0); TRACE_INFO("QSPI Initialized in SPI mode"); S25FL1D_QuadMode(DISABLE); PeripheralInit = 2; break; case '3' : QSPI_UserMenu(); PeripheralInit = 0; break; default: break; } if (PeripheralInit) { while (1) { deviceId = S25FL1D_ReadJedecId(); printf("ID read: Manufacture ID = 0x%x, Device Type = 0x%x, \ Capacity = 0x%x\n\r", (uint8_t)(deviceId), (uint8_t)(deviceId >> 8), (uint8_t)(deviceId >> 16)); break; } /* erase entire chip */ S25FL1D_EraseChip(); /* fill up the buffer*/ _fillupbuffer(TestBuffer, BUFFER_SIZE); printf("Writing buffer to Flash memory...... \n\r"); /* write the buffer to flash memory */ for (i = 0; i < 0x200000; ) { S25FL1D_Write(TestBuffer, BUFFER_SIZE, i, 0); i += BUFFER_SIZE; } TestPassed = _VerifyData(0, 0x200000, TestBuffer, 0); printf("Erasing a block(64 KB) @ Add 0x10000 \n\r"); S25FL1D_Erase64KBlock(0x10000); memset(TestBuffer, 0xFFFFFF, BUFFER_SIZE); SCB_CleanDCache_by_Addr((uint32_t *)TestBuffer, sizeof(TestBuffer)); TestPassed = _VerifyData(0x10000, (0x10000 + 64 * 1024), TestBuffer, 0); if (TestPassed) printf(" \n\r**** Test Failed ***** \n\r"); else printf(" \n\r### Test Passed ###\n\r"); } PeripheralInit = 0; QSPI_UserMenu(); } }
error_t sslClientTest(void) { error_t error; size_t length; IpAddr ipAddr; static char_t buffer[256]; //Underlying socket Socket *socket = NULL; //SSL/TLS context TlsContext *tlsContext = NULL; //Debug message TRACE_INFO("Resolving server name...\r\n"); //Resolve SSL server name error = getHostByName(NULL, APP_SERVER_NAME, &ipAddr, 0); //Any error to report? if(error) { //Debug message TRACE_INFO("Failed to resolve server name!\r\n"); //Exit immediately return error; } //Create a new socket to handle the request socket = socketOpen(SOCKET_TYPE_STREAM, SOCKET_IP_PROTO_TCP); //Any error to report? if(!socket) { //Debug message TRACE_INFO("Failed to open socket!\r\n"); //Exit immediately return ERROR_OPEN_FAILED; } //Start of exception handling block do { //Debug message TRACE_INFO("Connecting to SSL server %s\r\n", ipAddrToString(&ipAddr, NULL)); //Connect to the SSL server error = socketConnect(socket, &ipAddr, APP_SERVER_PORT); //Any error to report? if(error) break; //Initialize SSL/TLS context tlsContext = tlsInit(); //Initialization failed? if(!tlsContext) { //Report an error error = ERROR_OUT_OF_MEMORY; //Exit immediately break; } //Bind TLS to the relevant socket error = tlsSetSocket(tlsContext, socket); //Any error to report? if(error) break; //Select client operation mode error = tlsSetConnectionEnd(tlsContext, TLS_CONNECTION_END_CLIENT); //Any error to report? if(error) break; //Set the PRNG algorithm to be used error = tlsSetPrng(tlsContext, YARROW_PRNG_ALGO, &yarrowContext); //Any error to report? if(error) break; #if (APP_SET_CIPHER_SUITES == ENABLED) //Preferred cipher suite list error = tlsSetCipherSuites(tlsContext, cipherSuites, arraysize(cipherSuites)); //Any error to report? if(error) break; #endif #if (APP_SET_SERVER_NAME == ENABLED) //Set the fully qualified domain name of the server error = tlsSetServerName(tlsContext, APP_SERVER_NAME); //Any error to report? if(error) break; #endif #if (APP_SET_TRUSTED_CA_LIST == ENABLED) //Import the list of trusted CA certificates error = tlsSetTrustedCaList(tlsContext, trustedCaList, trustedCaListLength); //Any error to report? if(error) break; #endif #if (APP_SET_CLIENT_CERT == ENABLED) //Import the client's certificate error = tlsAddCertificate(tlsContext, clientCert, clientCertLength, clientPrivateKey, clientPrivateKeyLength); //Any error to report? if(error) break; #endif //Establish a secure session error = tlsConnect(tlsContext); //TLS handshake failure? if(error) break; //Format HTTP request sprintf(buffer, "GET %s HTTP/1.0\r\nHost: %s:%u\r\n\r\n", APP_REQUEST_URI, APP_SERVER_NAME, APP_SERVER_PORT); //Debug message TRACE_INFO("\r\n"); TRACE_INFO("HTTP request:\r\n%s", buffer); //Send the request error = tlsWrite(tlsContext, buffer, strlen(buffer), 0); //Any error to report? if(error) break; //Debug message TRACE_INFO("HTTP response:\r\n"); //Read the whole response while(1) { //Read data error = tlsRead(tlsContext, buffer, sizeof(buffer) - 1, &length, 0); //End of stream? if(error) break; //Properly terminate the string with a NULL character buffer[length] = '\0'; //Debug message TRACE_INFO("%s", buffer); } //Successfull processing error = NO_ERROR; //End of exception handling block } while(0); //Any error to report? if(error) { //Debug message TRACE_INFO("Failed to communicate with SSL server!\r\n"); } //Terminate TLS session tlsFree(tlsContext); //Close socket socketClose(socket); //Debug message TRACE_INFO("Connection closed...\r\n"); //Return status code return error; }
/** * \brief Loads the logical mapping contained in the given physical block. * block contains the mapping, its index is stored in the provided variable (if * pointer is not 0). * * \param mapped Pointer to a MappedNandFlash instance. * \param physicalBlock Physical block number. * \return 0 if successful; otherwise, returns a NandCommon_ERROR code. */ static unsigned char LoadLogicalMapping( struct MappedNandFlash *mapped, unsigned short physicalBlock) { unsigned char error; unsigned char data[NandCommon_MAXPAGEDATASIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); unsigned short numBlocks = ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)); unsigned int remainingSize; unsigned char *currentBuffer; unsigned short currentPage; unsigned int readSize; unsigned int i; unsigned char status; signed short logicalBlock; /*signed short firstBlock, lastBlock;*/ TRACE_INFO("LoadLogicalMapping(B#%d)\n\r", physicalBlock); /* Load mapping from pages #1 - #XXX of block*/ currentBuffer = (unsigned char *) mapped->logicalMapping; remainingSize = sizeof(mapped->logicalMapping); currentPage = 1; while (remainingSize > 0) { /* Read page*/ readSize = min(remainingSize, pageDataSize); error = ManagedNandFlash_ReadPage(MANAGED(mapped), physicalBlock, currentPage, data, 0); if (error) { TRACE_ERROR( "LoadLogicalMapping: Failed to load mapping\n\r"); return error; } /* Copy page info*/ memcpy(currentBuffer, data, readSize); currentBuffer += readSize; remainingSize -= readSize; currentPage++; } /* Store mapping block index*/ mapped->logicalMappingBlock = physicalBlock; /* Power-loss recovery*/ for (i=0; i < numBlocks; i++) { /* Check that this is not the logical mapping block*/ if (i != physicalBlock) { status = mapped->managed.blockStatuses[i].status; logicalBlock = MappedNandFlash_PhysicalToLogical(mapped, i); /* Block is LIVE*/ if (status == NandBlockStatus_LIVE) { /* Block is not mapped -> release it*/ if (logicalBlock == -1) { TRACE_WARNING_WP("-I- Release unmapped LIVE #%d\n\r", i); ManagedNandFlash_ReleaseBlock(MANAGED(mapped), i); } } /* Block is DIRTY*/ else if (status == NandBlockStatus_DIRTY) { /* Block is mapped -> fake it as live*/ if (logicalBlock != -1) { TRACE_WARNING_WP("-I- Mark mapped DIRTY #%d -> LIVE\n\r", i); mapped->managed.blockStatuses[i].status = NandBlockStatus_LIVE; } } /* Block is FREE or BAD*/ else { /* Block is mapped -> remove it from mapping*/ if (logicalBlock != -1) { TRACE_WARNING_WP("-I- Unmap FREE or BAD #%d\n\r", i); mapped->logicalMapping[logicalBlock] = -1; } } } } TRACE_WARNING_WP("-I- Mapping loaded from block #%d\n\r", physicalBlock); return 0; }
error_t dhcpv6RelayStart(Dhcpv6RelayCtx *context, const Dhcpv6RelaySettings *settings) { error_t error; uint_t i; OsTask *task; //Debug message TRACE_INFO("Starting DHCPv6 relay agent...\r\n"); //Ensure the parameters are valid if(!context || !settings) return ERROR_INVALID_PARAMETER; //The pointer to the network-facing interface shall be valid if(!settings->serverInterface) return ERROR_INVALID_INTERFACE; //Check the number of client-facing interfaces if(!settings->clientInterfaceCount) return ERROR_INVALID_PARAMETER; if(settings->clientInterfaceCount >= DHCPV6_RELAY_MAX_CLIENT_IF) return ERROR_INVALID_PARAMETER; //Loop through the client-facing interfaces for(i = 0; i < settings->clientInterfaceCount; i++) { //A valid pointer is required for each interface if(!settings->clientInterface[i]) return ERROR_INVALID_INTERFACE; } //Check the address to be used when forwarding messages to the server if(ipv6CompAddr(&settings->serverAddress, &IPV6_UNSPECIFIED_ADDR)) return ERROR_INVALID_ADDRESS; //Clear the DHCPv6 relay agent context memset(context, 0, sizeof(Dhcpv6RelayCtx)); //Save the network-facing interface context->serverInterface = settings->serverInterface; //Save the number of client-facing interfaces context->clientInterfaceCount = settings->clientInterfaceCount; //Save all the client-facing interfaces for(i = 0; i < context->clientInterfaceCount; i++) context->clientInterface[i] = settings->clientInterface[i]; //Save the address to be used when relaying client messages to the server context->serverAddress = settings->serverAddress; //Join the All_DHCP_Relay_Agents_and_Servers multicast group //for each client-facing interface error = dhcpv6RelayJoinMulticastGroup(context); //Any error to report? if(error) return error; //Start of exception handling block do { //Open a UDP socket to handle the network-facing interface context->serverSocket = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_PROTOCOL_UDP); //Failed to open socket? if(!context->serverSocket) { //Report an error error = ERROR_OPEN_FAILED; //Stop processing break; } //Explicitly associate the socket with the relevant interface error = socketBindToInterface(context->serverSocket, context->serverInterface); //Unable to bind the socket to the desired interface? if(error) break; //Relay agents listen for DHCPv6 messages on UDP port 547 error = socketBind(context->serverSocket, &IP_ADDR_ANY, DHCPV6_SERVER_PORT); //Unable to bind the socket to the desired port? if(error) break; //Only accept datagrams with source port number 547 error = socketConnect(context->serverSocket, &IP_ADDR_ANY, DHCPV6_SERVER_PORT); //Any error to report? if(error) break; //If the relay agent relays messages to the All_DHCP_Servers address //or other multicast addresses, it sets the Hop Limit field to 32 //Loop through the client-facing interfaces for(i = 0; i < context->clientInterfaceCount; i++) { //Open a UDP socket to handle the current interface context->clientSocket[i] = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_PROTOCOL_UDP); //Failed to open socket? if(!context->clientSocket[i]) { //Report an error error = ERROR_OPEN_FAILED; //Stop processing break; } //Explicitly associate the socket with the relevant interface error = socketBindToInterface(context->clientSocket[i], context->clientInterface[i]); //Unable to bind the socket to the desired interface? if(error) break; //Relay agents listen for DHCPv6 messages on UDP port 547 error = socketBind(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_SERVER_PORT); //Unable to bind the socket to the desired port? if(error) break; //Only accept datagrams with source port number 546 error = socketConnect(context->clientSocket[i], &IP_ADDR_ANY, DHCPV6_CLIENT_PORT); //Any error to report? if(error) break; } //Propagate exception if necessary... if(error) break; //Create event objects context->event = osEventCreate(FALSE, FALSE); context->ackEvent = osEventCreate(FALSE, FALSE); //Out of resources? if(context->event == OS_INVALID_HANDLE || context->ackEvent == OS_INVALID_HANDLE) { //Report an error error = ERROR_OUT_OF_RESOURCES; //Stop processing break; } //The DHCPv6 relay agent is now running context->running = TRUE; //Start the DHCPv6 relay agent service task = osTaskCreate("DHCPv6 Relay", dhcpv6RelayTask, context, DHCPV6_RELAY_STACK_SIZE, DHCPV6_RELAY_PRIORITY); //Unable to create the task? if(task == OS_INVALID_HANDLE) error = ERROR_OUT_OF_RESOURCES; //End of exception handling block } while(0); //Did we encounter an error? if(error) { //Close the socket associated with the network-facing interface socketClose(context->serverSocket); //Close the socket associated with each client-facing interface for(i = 0; i < context->clientInterfaceCount; i++) socketClose(context->clientSocket[i]); //Leave the All_DHCP_Relay_Agents_and_Servers multicast group //for each client-facing interface dhcpv6RelayLeaveMulticastGroup(context); //Close event objects osEventClose(context->event); osEventClose(context->ackEvent); } //Return status code return error; }
error_t dhcpv6ForwardRelayReplyMessage(Dhcpv6RelayCtx *context) { error_t error; uint_t i; uint32_t interfaceId; size_t inputMessageLen; size_t outputMessageLen; Dhcpv6RelayMessage *inputMessage; Dhcpv6Message *outputMessage; Dhcpv6Option *option; IpAddr ipAddr; uint16_t port; //Point to the buffer where to store the incoming DHCPv6 message inputMessage = (Dhcpv6RelayMessage *) context->buffer; //Read incoming message error = socketReceiveFrom(context->serverSocket, &ipAddr, &port, inputMessage, DHCPV6_MAX_MSG_SIZE, &inputMessageLen, 0); //Any error to report? if(error) return error; //Debug message TRACE_INFO("\r\nDHCPv6 message received on network-facing interface %s (%u bytes)...\r\n", context->serverInterface->name, inputMessageLen); //Dump the contents of the message for debugging purpose dhcpv6DumpMessage(inputMessage, inputMessageLen); //Check the length of the DHCPv6 message if(inputMessageLen < sizeof(Dhcpv6RelayMessage)) return ERROR_INVALID_MESSAGE; //Inspect the message type and only forward Relay-Reply messages. //Other DHCPv6 message types must be silently discarded if(inputMessage->msgType != DHCPV6_MSG_TYPE_RELAY_REPL) return ERROR_INVALID_MESSAGE; //Get the length of the Options field inputMessageLen -= sizeof(Dhcpv6Message); //Check whether an Interface ID option is included in the Relay-Reply option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPTION_INTERFACE_ID); //Failed to retrieve specified option? if(!option || ntohs(option->length) != sizeof(interfaceId)) return ERROR_INVALID_MESSAGE; //Read the Interface ID option contents memcpy(&interfaceId, option->value, sizeof(interfaceId)); //Convert the 32-bit integer from network byte order interfaceId = ntohl(interfaceId); //The Relay-Reply message must include a Relay Message option option = dhcpv6GetOption(inputMessage->options, inputMessageLen, DHCPV6_OPTION_RELAY_MSG); //Failed to retrieve specified option? if(!option || ntohs(option->length) < sizeof(Dhcpv6Message)) return ERROR_INVALID_MESSAGE; //Extract the message from the Relay Message option outputMessage = (Dhcpv6Message *) option->value; //Save the length of the message outputMessageLen = ntohs(option->length); //Loop through client-facing interfaces for(i = 0; i < context->clientInterfaceCount; i++) { //Check whether the current interface matches the Interface ID option if(context->clientInterface[i]->identifier == interfaceId) { //Debug message TRACE_INFO("Forwarding DHCPv6 message on client-facing interface %s (%u bytes)...\r\n", context->clientInterface[i]->name, outputMessageLen); //Dump the contents of the message for debugging purpose dhcpv6DumpMessage(outputMessage, outputMessageLen); //Copy the peer-address into the destination IP address ipAddr.length = sizeof(Ipv6Addr); ipAddr.ipv6Addr = inputMessage->peerAddress; //Select the relevant port number to use if(outputMessage->msgType == DHCPV6_MSG_TYPE_RELAY_REPL) port = DHCPV6_SERVER_PORT; else port = DHCPV6_CLIENT_PORT; //Relay the DHCPv6 message to the client on the link //identified by the Interface ID option return socketSendTo(context->clientSocket[i], &ipAddr, port, outputMessage, outputMessageLen, NULL, 0); } } //Unknown interface identifier... return ERROR_INVALID_OPTION; }
int_t main(void) { error_t error; NetInterface *interface; OsTask *task; MacAddr macAddr; #if (APP_USE_DHCP == DISABLED) Ipv4Addr ipv4Addr; #endif #if (APP_USE_SLAAC == DISABLED) Ipv6Addr ipv6Addr; #endif //Update system core clock SystemCoreClockUpdate(); //Initialize kernel osInitKernel(); //Configure debug UART debugInit(115200); //Start-up message TRACE_INFO("\r\n"); TRACE_INFO("**********************************\r\n"); TRACE_INFO("*** CycloneTCP FTP Client Demo ***\r\n"); TRACE_INFO("**********************************\r\n"); TRACE_INFO("Copyright: 2010-2014 Oryx Embedded\r\n"); TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__); TRACE_INFO("Target: LPC4330\r\n"); TRACE_INFO("\r\n"); //Configure I/Os ioInit(); //TCP/IP stack initialization error = tcpIpStackInit(); //Any error to report? if(error) { //Debug message TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n"); } //Configure the first Ethernet interface interface = &netInterface[0]; //Set interface name tcpIpStackSetInterfaceName(interface, "eth0"); //Set host name tcpIpStackSetHostname(interface, "FTPClientDemo"); //Select the relevant network adapter tcpIpStackSetDriver(interface, &lpc43xxEthDriver); tcpIpStackSetPhyDriver(interface, &lan8720PhyDriver); //Set host MAC address macStringToAddr(APP_MAC_ADDR, &macAddr); tcpIpStackSetMacAddr(interface, &macAddr); //Initialize network interface error = tcpIpStackConfigInterface(interface); //Any error to report? if(error) { //Debug message TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name); } #if (IPV4_SUPPORT == ENABLED) #if (APP_USE_DHCP == ENABLED) //Get default settings dhcpClientGetDefaultSettings(&dhcpClientSettings); //Set the network interface to be configured by DHCP dhcpClientSettings.interface = interface; //Disable rapid commit option dhcpClientSettings.rapidCommit = FALSE; //DHCP client initialization error = dhcpClientInit(&dhcpClientContext, &dhcpClientSettings); //Failed to initialize DHCP client? if(error) { //Debug message TRACE_ERROR("Failed to initialize DHCP client!\r\n"); } //Start DHCP client error = dhcpClientStart(&dhcpClientContext); //Failed to start DHCP client? if(error) { //Debug message TRACE_ERROR("Failed to start DHCP client!\r\n"); } #else //Set IPv4 host address ipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr); ipv4SetHostAddr(interface, ipv4Addr); //Set subnet mask ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr); ipv4SetSubnetMask(interface, ipv4Addr); //Set default gateway ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr); ipv4SetDefaultGateway(interface, ipv4Addr); //Set primary and secondary DNS servers ipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr); ipv4SetDnsServer(interface, 0, ipv4Addr); ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr); ipv4SetDnsServer(interface, 1, ipv4Addr); #endif #endif #if (IPV6_SUPPORT == ENABLED) #if (APP_USE_SLAAC == ENABLED) //Get default settings slaacGetDefaultSettings(&slaacSettings); //Set the network interface to be configured slaacSettings.interface = interface; //SLAAC initialization error = slaacInit(&slaacContext, &slaacSettings); //Failed to initialize SLAAC? if(error) { //Debug message TRACE_ERROR("Failed to initialize SLAAC!\r\n"); } //Start IPv6 address autoconfiguration process error = slaacStart(&slaacContext); //Failed to start SLAAC process? if(error) { //Debug message TRACE_ERROR("Failed to start SLAAC!\r\n"); } #else //Set link-local address ipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr); ipv6SetLinkLocalAddr(interface, &ipv6Addr, IPV6_ADDR_STATE_VALID); //Set IPv6 prefix ipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr); ipv6SetPrefix(interface, &ipv6Addr, APP_IPV6_PREFIX_LENGTH); //Set global address ipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr); ipv6SetGlobalAddr(interface, &ipv6Addr, IPV6_ADDR_STATE_VALID); //Set router ipv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr); ipv6SetRouter(interface, &ipv6Addr); //Set primary and secondary DNS servers ipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr); ipv6SetDnsServer(interface, 0, &ipv6Addr); ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr); ipv6SetDnsServer(interface, 1, &ipv6Addr); #endif #endif //Create user task task = osCreateTask("User Task", userTask, NULL, 500, 1); //Failed to create the task? if(task == OS_INVALID_HANDLE) { //Debug message TRACE_ERROR("Failed to create task!\r\n"); } //Create a task to blink the LED task = osCreateTask("Blink", blinkTask, NULL, 500, 1); //Failed to create the task? if(task == OS_INVALID_HANDLE) { //Debug message TRACE_ERROR("Failed to create task!\r\n"); } //Start the execution of tasks osStartKernel(); //This function should never return return 0; }
error_t dm9000Init(NetInterface *interface) { uint_t i; uint16_t vendorId; uint16_t productId; uint8_t chipRevision; Dm9000Context *context; //Debug message TRACE_INFO("Initializing DM9000 Ethernet controller...\r\n"); //Initialize external interrupt line interface->extIntDriver->init(); //Point to the driver context context = (Dm9000Context *) interface->nicContext; //Initialize driver specific variables context->queuedPackets = 0; //Retrieve vendorID, product ID and chip revision vendorId = (dm9000ReadReg(DM9000_REG_VIDH) << 8) | dm9000ReadReg(DM9000_REG_VIDL); productId = (dm9000ReadReg(DM9000_REG_PIDH) << 8) | dm9000ReadReg(DM9000_REG_PIDL); chipRevision = dm9000ReadReg(DM9000_REG_CHIPR); //Check vendor ID and product ID if(vendorId != DM9000_VID || productId != DM9000_PID) return ERROR_WRONG_IDENTIFIER; //Check chip revision if(chipRevision != DM9000A_CHIP_REV && chipRevision != DM9000B_CHIP_REV) return ERROR_WRONG_IDENTIFIER; //Power up the internal PHY by clearing PHYPD dm9000WriteReg(DM9000_REG_GPR, 0x00); //Wait for the PHY to be ready sleep(10); //Software reset dm9000WriteReg(DM9000_REG_NCR, NCR_RST); //Wait for the reset to complete while(dm9000ReadReg(DM9000_REG_NCR) & NCR_RST); //PHY software reset dm9000WritePhyReg(DM9000_PHY_REG_BMCR, BMCR_RST); //Wait for the PHY reset to complete while(dm9000ReadPhyReg(DM9000_PHY_REG_BMCR) & BMCR_RST); //Debug message TRACE_INFO(" VID = 0x%04" PRIX16 "\r\n", vendorId); TRACE_INFO(" PID = 0x%04" PRIX16 "\r\n", productId); TRACE_INFO(" CHIPR = 0x%02" PRIX8 "\r\n", chipRevision); TRACE_INFO(" PHYIDR1 = 0x%04" PRIX16 "\r\n", dm9000ReadPhyReg(DM9000_PHY_REG_PHYIDR1)); TRACE_INFO(" PHYIDR2 = 0x%04" PRIX16 "\r\n", dm9000ReadPhyReg(DM9000_PHY_REG_PHYIDR2)); //Enable loopback mode? #if (DM9000_LOOPBACK_MODE == ENABLED) dm9000WriteReg(DM9000_REG_NCR, DM9000_LBK_PHY); dm9000WritePhyReg(DM9000_PHY_REG_BMCR, BMCR_LOOPBACK | BMCR_SPEED_SEL | BMCR_AN_EN | BMCR_DUPLEX_MODE); #endif //Set host MAC address for(i = 0; i < 6; i++) dm9000WriteReg(DM9000_REG_PAR0 + i, interface->macAddr.b[i]); //Initialize hash table for(i = 0; i < 8; i++) dm9000WriteReg(DM9000_REG_MAR0 + i, 0x00); //Always accept broadcast packets dm9000WriteReg(DM9000_REG_MAR7, 0x80); //Enable the Pointer Auto Return function dm9000WriteReg(DM9000_REG_IMR, IMR_PAR); //Clear NSR status bits dm9000WriteReg(DM9000_REG_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); //Clear interrupt flags dm9000WriteReg(DM9000_REG_ISR, ISR_LNKCHG | ISR_UDRUN | ISR_ROO | ISR_ROS | ISR_PT | ISR_PR); //Enable interrupts dm9000WriteReg(DM9000_REG_IMR, IMR_PAR | IMR_LNKCHGI | IMR_PTI | IMR_PRI); //Enable the receiver by setting RXEN dm9000WriteReg(DM9000_REG_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); //DM9000 transmitter is now ready to send osSetEvent(&interface->nicTxEvent); //Successful initialization return NO_ERROR; }
/** * \brief Applet main entry. This function decodes received command and executes it. * * \param argc always 1 * \param argv Address of the argument area.. */ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; uint32_t bufferSize, bufferAddr, memoryOffset, bytesToWrite; uint16_t pagesToWrite, pagesToRead; uint32_t bytesWritten = 0; uint32_t bytesRead = 0; uint32_t nbBadBlocks = 0; uint32_t nbBlocks = 0; /* Temporary buffer used for non block aligned read / write */ uint32_t tempBufferAddr; uint16_t block, page, offset, i; uint8_t unAlignedPage; /* Index in source buffer during buffer copy */ uint32_t offsetInSourceBuff; /* Index in destination buffer during buffer copy */ uint32_t offsetInTargetBuff; /* Errors returned by SkipNandFlash functions */ uint8_t error = 0; /* Global DMA driver instance for all DMA transfers in application. */ sDmad dmad; /*---------------------------------------------------------- * INIT: *----------------------------------------------------------*/ if (pMailbox->command == APPLET_CMD_INIT) { /* Save info of communication link */ comType = pMailbox->argument.inputInit.comType; /* Re-configurate UART (MCK maybe change in LowLevelInit()) */ UART_Configure(115200, BOARD_MCK); #if (DYN_TRACES == 1) dwTraceLevel = pMailbox->argument.inputInit.traceLevel; #endif TRACE_INFO("-- NandFlash SAM-BA applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); TRACE_INFO("INIT command\n\r"); /* Initialize DMA driver instance with polling mode */ DMAD_Initialize( &dmad, 1 ); if ( NandFlashConfigureDmaChannels( &dmad )) { TRACE_INFO ("-E- Initialize DMA failed !"); } TRACE_INFO ("-I- Initialize DMA done.\n\r"); /* Configure SMC for Nandflash accesses */ BOARD_ConfigureNandFlash(SMC); PIO_PinConfigure(pPinsNf, PIO_LISTSIZE(pPinsNf)); if (pPinsNf->pio == 0) { pMailbox->status = APPLET_NO_DEV; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; pMailbox->argument.outputInit.bufferAddress = (uint32_t) &end; TRACE_INFO("INIT command: No Nandflash defined for this board\n\r"); } else { memset(&skipBlockNf, 0, sizeof(skipBlockNf)); if (SkipBlockNandFlash_Initialize(&skipBlockNf, 0, cmdBytesAddr, addrBytesAddr, dataBytesAddr, nfCePin, nfRbPin)) { pMailbox->status = APPLET_DEV_UNKNOWN; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; TRACE_INFO("\tDevice Unknown\n\r"); } else { TRACE_INFO("\tNandflash driver initialized\n\r"); /* Get device parameters */ memSize = NandFlashModel_GetDeviceSizeInBytes(&skipBlockNf.ecc.raw.model); blockSize = NandFlashModel_GetBlockSizeInBytes(&skipBlockNf.ecc.raw.model); numBlocks = NandFlashModel_GetDeviceSizeInBlocks(&skipBlockNf.ecc.raw.model); pageSize = NandFlashModel_GetPageDataSize(&skipBlockNf.ecc.raw.model); numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(&skipBlockNf.ecc.raw.model); latestErasedBlock = 0xFFFF; pMailbox->status = APPLET_SUCCESS; pMailbox->argument.outputInit.bufferAddress = (uint32_t)EBI_SDRAMC_ADDR; pMailbox->argument.outputInit.bufferSize = blockSize; pMailbox->argument.outputInit.memorySize = memSize; TRACE_INFO("\t pageSize : 0x%x blockSize : 0x%x blockNb : 0x%x \n\r", (unsigned int)pageSize, (unsigned int)blockSize, (unsigned int)numBlocks); } } } /*---------------------------------------------------------- * WRITE: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; tempBufferAddr = bufferAddr + blockSize; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; unAlignedPage = 0; TRACE_INFO("WRITE arguments : offset 0x%x, buffer at 0x%x, of 0x%x Bytes\n\r", (unsigned int)memoryOffset, (unsigned int)bufferAddr, (unsigned int)bytesToWrite); pMailbox->argument.outputWrite.bytesWritten = 0; /* Check word alignment */ if (memoryOffset % 4) { pMailbox->status = APPLET_ALIGN_ERROR; goto exit; } /* Retrieve page and block addresses */ if (NandFlashModel_TranslateAccess(&(skipBlockNf.ecc.raw.model), memoryOffset, bytesToWrite, &block, &page, &offset)) { pMailbox->status = APPLET_FAIL; goto exit; } if (block != latestErasedBlock ){ /* Erase target block */ error = SkipBlockNandFlash_EraseBlock(&skipBlockNf, block, NORMAL_ERASE); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } latestErasedBlock = block; latestErasedPage = 0xff; } if (page <= ((uint8_t)(latestErasedPage + 1))){ error = SkipBlockNandFlash_EraseBlock(&skipBlockNf, block, NORMAL_ERASE); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } latestErasedBlock = block; latestErasedPage = page; } offsetInSourceBuff = 0; TRACE_INFO("WRITE at block 0x%x, page 0x%x, offset 0x%x in page \n\r", (unsigned int)block, (unsigned int)page, (unsigned int)offset); if (offset ) { /* We are not page aligned. */ offsetInTargetBuff = offset; memset((uint32_t *)tempBufferAddr, 0xFF, pageSize); while (offsetInTargetBuff < pageSize) { *(uint32_t *)(tempBufferAddr + offsetInTargetBuff) = *(uint32_t *)(bufferAddr + offsetInSourceBuff); offsetInSourceBuff += 4; offsetInTargetBuff += 4; bytesWritten += 4; } error = SkipBlockNandFlash_WritePage(&skipBlockNf, block, page, ( void *)tempBufferAddr ,0); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } unAlignedPage++; } pagesToWrite = (bytesToWrite - bytesWritten) / pageSize; if (bytesToWrite - ((pagesToWrite + unAlignedPage) * pageSize)) { pagesToWrite++; } if ((pagesToWrite + page ) > numPagesPerBlock) { pagesToWrite = numPagesPerBlock - page; } /* Write target block */ error = SkipBlockNandFlash_WriteBlockUnaligned(&skipBlockNf, block, (page + unAlignedPage), pagesToWrite, ( void *)(bufferAddr + offsetInSourceBuff)); bytesWritten += pagesToWrite * pageSize; if (bytesWritten > bytesToWrite) { bytesWritten = bytesToWrite; } if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } pMailbox->argument.outputWrite.bytesWritten = bytesWritten; pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * READ: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; tempBufferAddr = bufferAddr + blockSize; bufferSize = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", (unsigned int)memoryOffset, (unsigned int)bufferAddr, (unsigned int)bufferSize); pMailbox->argument.outputRead.bytesRead = 0; unAlignedPage = 0; /* Check word alignment */ if (memoryOffset % 4) { pMailbox->status = APPLET_ALIGN_ERROR; goto exit; } /* Retrieve page and block addresses */ if (NandFlashModel_TranslateAccess(&(skipBlockNf.ecc.raw.model), memoryOffset, bufferSize, &block, &page, &offset)) { pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("READ at block 0x%x, page 0x%x, offset in page 0x%x\n\r", (unsigned int)block, (unsigned int)page, (unsigned int)offset); offsetInTargetBuff = 0; if (offset) { memset((uint32_t *)tempBufferAddr, 0xFF, pageSize); error = SkipBlockNandFlash_ReadPage(&skipBlockNf, block, page, ( void *)tempBufferAddr ,0); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } /* Fill dest buffer with read data */ offsetInSourceBuff = offset; while (offsetInSourceBuff < pageSize) { *(uint32_t *)(bufferAddr + offsetInTargetBuff) = *(uint32_t *)(tempBufferAddr + offsetInSourceBuff); offsetInSourceBuff += 4; offsetInTargetBuff += 4; bytesRead += 4; } unAlignedPage++; } pagesToRead = (bufferSize - bytesRead) / pageSize; if (bufferSize - ((pagesToRead + unAlignedPage)* pageSize)) { pagesToRead++; } if ((pagesToRead + page ) > numPagesPerBlock) { pagesToRead = numPagesPerBlock - page; } /* Read target block */ error = SkipBlockNandFlash_ReadBlockUnaligned(&skipBlockNf, block, (page + unAlignedPage), pagesToRead, ( void *)(bufferAddr + offsetInTargetBuff)); bytesRead += pagesToRead * pageSize; if (bytesRead > bufferSize) { bytesRead = bufferSize; } if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } pMailbox->argument.outputRead.bytesRead = bytesRead; pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * FULL ERASE: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command\n\r"); TRACE_INFO("\tForce erase flag: 0x%x\n\r", (unsigned int)pMailbox->argument.inputFullErase.eraseType); for (i = 0; i < numBlocks; i++) { /* Erase the page */ if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, i, pMailbox->argument.inputFullErase.eraseType)) { TRACE_INFO("Found block #%d BAD, skip it\n\r", (unsigned int)i); } } TRACE_INFO("Full Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * BATCH FULL ERASE: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_BATCH_ERASE) { TRACE_INFO("BATCH ERASE command\n\r"); block = pMailbox->argument.inputBatchErase.batch * (numBlocks / ERASE_BATCH); TRACE_INFO("Erase block from #%d to #%d\n\r", (unsigned int)block, (unsigned int)(block + (numBlocks / ERASE_BATCH))); for (i = block ; i < block + (numBlocks / ERASE_BATCH) ; i++) { /* Erase the block */ if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, i, pMailbox->argument.inputBatchErase.eraseType)) { TRACE_INFO("Found block #%d BAD, skip it\n\r", (unsigned int)i); } } if ((pMailbox->argument.inputBatchErase.batch + 1) == ERASE_BATCH) { TRACE_INFO("Full Erase achieved, erase type is %d\n\r", (unsigned int)pMailbox->argument.inputBatchErase.eraseType); pMailbox->argument.outputBatchErase.nextBatch = 0; } else { pMailbox->argument.outputBatchErase.nextBatch = pMailbox->argument.inputBatchErase.batch + 1; TRACE_INFO("Batch Erase achieved\n\r"); } pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * ERASE_BLOCKS: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_ERASE_BLOCKS) { TRACE_INFO("BLOCKS ERASE command\n\r"); memoryOffset = pMailbox->argument.inputBlocksErase.memoryOffsetStart; if ((pMailbox->argument.inputBlocksErase.memoryOffsetEnd > memSize) || (pMailbox->argument.inputBlocksErase.memoryOffsetEnd < memoryOffset) ) { TRACE_INFO("Out of memory space\n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } nbBlocks = ((pMailbox->argument.inputBlocksErase.memoryOffsetEnd- memoryOffset)/ blockSize) + 1; TRACE_INFO("Erase blocks from %d to %d \n\r", (unsigned int)(memoryOffset / blockSize),(unsigned int)((memoryOffset / blockSize)+ nbBlocks) ); /* Erase blocks */ for (i = memoryOffset / blockSize; i < memoryOffset / blockSize + nbBlocks ; i++) { if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, i , NORMAL_ERASE)) { TRACE_INFO("Found block #%d BAD, skip it\n\r", (unsigned int)i); } } TRACE_INFO("Blocks Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * LIST BAD BLOCKS: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_LIST_BAD_BLOCKS) { TRACE_INFO("LIST BAD BLOCKS command\n\r"); nbBadBlocks = 0; bufferAddr = (uint32_t) &end; pMailbox->argument.outputListBadBlocks.bufferAddress = bufferAddr; for (i = 0; i < numBlocks; i++) { /* Erase the page */ if (SkipBlockNandFlash_CheckBlock(&skipBlockNf, i) == BADBLOCK) { nbBadBlocks++; *((uint32_t *)bufferAddr) = i; bufferAddr += 4; TRACE_INFO("Found block #%d BAD\n\r", i); } } TRACE_INFO("LIST BAD BLOCKS achieved\n\r"); pMailbox->argument.outputListBadBlocks.nbBadBlocks = nbBadBlocks; pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * TAG BLOCK: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_TAG_BLOCK) { TRACE_INFO("TAG BLOCK command\n\r"); bufferAddr = (uint32_t) &end; block = pMailbox->argument.inputTagBlock.blockId; /* To tag the block as good, just erase it without bad block check */ if ((uint8_t)pMailbox->argument.inputTagBlock.tag == 0xFF) { if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, block, SCRUB_ERASE)) { TRACE_INFO("Cannot erase block %d\n\r", (unsigned int)block); pMailbox->status = APPLET_FAIL; goto exit; } } else { for (i = 0; i < 2; i++) { /* Start by reading the spare */ memset((uint8_t *)bufferAddr, 0xFF, NandCommon_MAXSPAREECCBYTES); TRACE_INFO("Tag to write : 0x%x\n\r", (unsigned int)pMailbox->argument.inputTagBlock.tag); NandSpareScheme_WriteBadBlockMarker((struct NandSpareScheme *)(NandFlashModel_GetScheme((struct NandFlashModel *)(&skipBlockNf))), (uint8_t *)bufferAddr, ((uint8_t)pMailbox->argument.inputTagBlock.tag)); if (RawNandFlash_WritePage((struct RawNandFlash *)(&skipBlockNf), block, i, 0, (uint8_t *)bufferAddr)) { TRACE_ERROR("Failed to write spare data of page %d of block %d\n\r", i, block); pMailbox->status = APPLET_FAIL; goto exit; } } } TRACE_INFO("TAG BLOCK achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit : /* Acknowledge the end of command */ TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", (unsigned int)pMailbox->command, (unsigned int)pMailbox->status); /* Notify the host application of the end of the command processing */ pMailbox->command = ~(pMailbox->command); if (comType == DBGU_COM_TYPE) { UART_PutChar(0x6); } return 0; }
bool_t ksz8721EventHandler(NetInterface *interface) { uint16_t value; //Read status register to acknowledge the interrupt value = ksz8721ReadPhyReg(interface, KSZ8721_PHY_REG_ICSR); //Link status change? if(value & (ICSR_LINK_DOWN_IF | ICSR_LINK_UP_IF)) { //Read basic status register value = ksz8721ReadPhyReg(interface, KSZ8721_PHY_REG_BMSR); //Link is up? if(value & BMSR_LINK_STATUS) { //Read PHY control register value = ksz8721ReadPhyReg(interface, KSZ8721_PHY_REG_PHYCON); //Check current operation mode switch(value & PHYCON_OP_MODE_MASK) { //10BASE-T case PHYCON_OP_MODE_10BT: interface->speed100 = FALSE; interface->fullDuplex = FALSE; break; //10BASE-T full-duplex case PHYCON_OP_MODE_10BT_FD: interface->speed100 = FALSE; interface->fullDuplex = TRUE; break; //100BASE-TX case PHYCON_OP_MODE_100BTX: interface->speed100 = TRUE; interface->fullDuplex = FALSE; break; //100BASE-TX full-duplex case PHYCON_OP_MODE_100BTX_FD: interface->speed100 = TRUE; interface->fullDuplex = TRUE; break; //Unknown operation mode default: //Debug message TRACE_WARNING("Invalid Duplex mode\r\n"); break; } //Update link state interface->linkState = TRUE; //Display link state TRACE_INFO("Link is up (%s)...\r\n", interface->name); //Display actual speed and duplex mode TRACE_INFO("%s %s\r\n", interface->speed100 ? "100BASE-TX" : "10BASE-T", interface->fullDuplex ? "Full-Duplex" : "Half-Duplex"); } else { //Update link state interface->linkState = FALSE; //Display link state TRACE_INFO("Link is down (%s)...\r\n", interface->name); } //Notify the user that the link state has changed return TRUE; } else { //No link state change... return FALSE; } }
void tcpTick(void) { error_t error; uint_t i; uint_t n; uint_t u; //Enter critical section osMutexAcquire(socketMutex); //Loop through opened sockets for(i = 0; i < SOCKET_MAX_COUNT; i++) { //Shortcut to the current socket Socket *socket = socketTable + i; //Check socket type if(socket->type != SOCKET_TYPE_STREAM) continue; //Check the current state of the TCP state machine if(socket->state == TCP_STATE_CLOSED) continue; //Is there any packet in the retransmission queue? if(socket->retransmitQueue != NULL) { //Retransmission timeout? if(osTimerElapsed(&socket->retransmitTimer)) { //When a TCP sender detects segment loss using the retransmission //timer and the given segment has not yet been resent by way of //the retransmission timer, the value of ssthresh must be updated if(!socket->retransmitCount) { //Amount of data that has been sent but not yet acknowledged uint_t flightSize = socket->sndNxt - socket->sndUna; //Adjust ssthresh value socket->ssthresh = max(flightSize / 2, 2 * socket->mss); } //Furthermore, upon a timeout cwnd must be set to no more than //the loss window, LW, which equals 1 full-sized segment socket->cwnd = min(TCP_LOSS_WINDOW * socket->mss, socket->txBufferSize); //Make sure the maximum number of retransmissions has not been reached if(socket->retransmitCount < TCP_MAX_RETRIES) { //Debug message TRACE_INFO("%s: TCP segment retransmission #%u (%u data bytes)...\r\n", timeFormat(osGetTickCount()), socket->retransmitCount + 1, socket->retransmitQueue->length); //Retransmit the earliest segment that has not been //acknowledged by the TCP receiver tcpRetransmitSegment(socket); //Use exponential back-off algorithm to calculate the new RTO socket->rto = min(socket->rto * 2, TCP_MAX_RTO); //Restart retransmission timer osTimerStart(&socket->retransmitTimer, socket->rto); //Increment retransmission counter socket->retransmitCount++; } else { //The maximum number of retransmissions has been exceeded tcpChangeState(socket, TCP_STATE_CLOSED); //Turn off the retransmission timer osTimerStop(&socket->retransmitTimer); } //TCP must use Karn's algorithm for taking RTT samples. That is, RTT //samples must not be made using segments that were retransmitted socket->rttBusy = FALSE; } } //Check the current state of the TCP state machine if(socket->state == TCP_STATE_CLOSED) continue; //The persist timer is used when the remote host advertises //a window size of zero if(!socket->sndWnd && socket->wndProbeInterval) { //Time to send a new probe? if(osTimerElapsed(&socket->persistTimer)) { //Make sure the maximum number of retransmissions has not been reached if(socket->wndProbeCount < TCP_MAX_RETRIES) { //Debug message TRACE_INFO("%s: TCP zero window probe #%u...\r\n", timeFormat(osGetTickCount()), socket->wndProbeCount + 1); //Zero window probes usually have the sequence number one less than expected tcpSendSegment(socket, TCP_FLAG_ACK, socket->sndNxt - 1, socket->rcvNxt, 0, FALSE); //The interval between successive probes should be increased exponentially socket->wndProbeInterval = min(socket->wndProbeInterval * 2, TCP_MAX_PROBE_INTERVAL); //Restart the persist timer osTimerStart(&socket->persistTimer, socket->wndProbeInterval); //Increment window probe counter socket->wndProbeCount++; } else { //Enter CLOSED state tcpChangeState(socket, TCP_STATE_CLOSED); } } } //To avoid a deadlock, it is necessary to have a timeout to force //transmission of data, overriding the SWS avoidance algorithm. In //practice, this timeout should seldom occur (see RFC 1122 4.2.3.4) if(socket->state == TCP_STATE_ESTABLISHED || socket->state == TCP_STATE_CLOSE_WAIT) { //The override timeout occurred? if(socket->sndUser && osTimerElapsed(&socket->overrideTimer)) { //The amount of data that can be sent at any given time is //limited by the receiver window and the congestion window n = min(socket->sndWnd, socket->cwnd); n = min(n, socket->txBufferSize); //Retrieve the size of the usable window u = n - (socket->sndNxt - socket->sndUna); //Send as much data as possible while(socket->sndUser > 0) { //The usable window size may become zero or negative, //preventing packet transmission if((int_t) u <= 0) break; //Calculate the number of bytes to send at a time n = min(u, socket->sndUser); n = min(n, socket->mss); //Send TCP segment error = tcpSendSegment(socket, TCP_FLAG_PSH | TCP_FLAG_ACK, socket->sndNxt, socket->rcvNxt, n, TRUE); //Failed to send TCP segment? if(error) break; //Advance SND.NXT pointer socket->sndNxt += n; //Adjust the number of bytes buffered but not yet sent socket->sndUser -= n; } //Check whether the transmitter can accept more data tcpUpdateEvents(socket); //Restart override timer if necessary if(socket->sndUser > 0) osTimerStart(&socket->overrideTimer, TCP_OVERRIDE_TIMEOUT); } } //The FIN-WAIT-2 timer prevents the connection //from staying in the FIN-WAIT-2 state forever if(socket->state == TCP_STATE_FIN_WAIT_2) { //Maximum FIN-WAIT-2 time has elapsed? if(osTimerElapsed(&socket->finWait2Timer)) { //Debug message TRACE_WARNING("TCP FIN-WAIT-2 timer elapsed...\r\n"); //Enter CLOSED state tcpChangeState(socket, TCP_STATE_CLOSED); } } //TIME-WAIT timer if(socket->state == TCP_STATE_TIME_WAIT) { //2MSL time has elapsed? if(osTimerElapsed(&socket->timeWaitTimer)) { //Debug message TRACE_WARNING("TCP 2MSL timer elapsed (socket %u)...\r\n", i); //Enter CLOSED state tcpChangeState(socket, TCP_STATE_CLOSED); //Dispose the socket if the user does not have the ownership anymore if(!socket->ownedFlag) { //Delete the TCB tcpDeleteControlBlock(socket); //Mark the socket as closed socket->type = SOCKET_TYPE_UNUSED; } } } } //Leave critical section osMutexRelease(socketMutex); }
bool_t upd60611EventHandler(NetInterface *interface) { uint16_t value; bool_t linkState; //Read basic status register value = upd60611ReadPhyReg(interface, UPD60611_PHY_REG_BMSR); //Retrieve current link state linkState = (value & BMSR_LINK_STATUS) ? TRUE : FALSE; //Link is up? if(linkState && !interface->linkState) { //Read PHY special control/status register value = upd60611ReadPhyReg(interface, UPD60611_PHY_REG_PSCSR); //Check current operation mode switch(value & PSCSR_HCDSPEED_MASK) { //10BASE-T case PSCSR_HCDSPEED_10BT: interface->speed100 = FALSE; interface->fullDuplex = FALSE; break; //10BASE-T full-duplex case PSCSR_HCDSPEED_10BT_FD: interface->speed100 = FALSE; interface->fullDuplex = TRUE; break; //100BASE-TX case PSCSR_HCDSPEED_100BTX: interface->speed100 = TRUE; interface->fullDuplex = FALSE; break; //100BASE-TX full-duplex case PSCSR_HCDSPEED_100BTX_FD: interface->speed100 = TRUE; interface->fullDuplex = TRUE; break; //Unknown operation mode default: //Debug message TRACE_WARNING("Invalid Duplex mode\r\n"); break; } //Update link state interface->linkState = TRUE; //Display link state TRACE_INFO("Link is up (%s)...\r\n", interface->name); //Display actual speed and duplex mode TRACE_INFO("%s %s\r\n", interface->speed100 ? "100BASE-TX" : "10BASE-T", interface->fullDuplex ? "Full-Duplex" : "Half-Duplex"); //Notify the user that the link state has changed return TRUE; } //Link is down? else if(!linkState && interface->linkState) { //Update link state interface->linkState = FALSE; //Display link state TRACE_INFO("Link is down (%s)...\r\n", interface->name); //Notify the user that the link state has changed return TRUE; } else { //No link state change... return FALSE; } }
error_t xmc4700EthInit(NetInterface *interface) { error_t error; //Debug message TRACE_INFO("Initializing XMC4700 Ethernet MAC...\r\n"); //Save underlying network interface nicDriverInterface = interface; //Disable parity error trap SCU_PARITY->PETE = 0; //Disable unaligned access trap PPB->CCR &= ~PPB_CCR_UNALIGN_TRP_Msk; //Enable ETH0 peripheral clock SCU_CLK->CLKSET = SCU_CLK_CLKSET_ETH0CEN_Msk; //GPIO configuration xmc4700EthInitGpio(interface); //Reset ETH0 peripheral SCU_RESET->PRSET2 = SCU_RESET_PRSET2_ETH0RS_Msk; SCU_RESET->PRCLR2 = SCU_RESET_PRCLR2_ETH0RS_Msk; //Reset DMA controller ETH0->BUS_MODE |= ETH_BUS_MODE_SWR_Msk; //Wait for the reset to complete while(ETH0->BUS_MODE & ETH_BUS_MODE_SWR_Msk); //Adjust MDC clock range depending on ETH clock frequency ETH0->GMII_ADDRESS = ETH_GMII_ADDRESS_CR_DIV62; //PHY transceiver initialization error = interface->phyDriver->init(interface); //Failed to initialize PHY transceiver? if(error) return error; //Use default MAC configuration ETH0->MAC_CONFIGURATION = ETH_MAC_CONFIGURATION_RESERVED15_Msk | ETH_MAC_CONFIGURATION_DO_Msk; //Set the MAC address ETH0->MAC_ADDRESS0_LOW = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16); ETH0->MAC_ADDRESS0_HIGH = interface->macAddr.w[2]; //Initialize hash table ETH0->HASH_TABLE_LOW = 0; ETH0->HASH_TABLE_HIGH = 0; //Configure the receive filter ETH0->MAC_FRAME_FILTER = ETH_MAC_FRAME_FILTER_HPF_Msk | ETH_MAC_FRAME_FILTER_HMC_Msk; //Disable flow control ETH0->FLOW_CONTROL = 0; //Enable store and forward mode ETH0->OPERATION_MODE = ETH_OPERATION_MODE_RSF_Msk | ETH_OPERATION_MODE_TSF_Msk; //Configure DMA bus mode ETH0->BUS_MODE = ETH_BUS_MODE_AAL_Msk | ETH_BUS_MODE_USP_Msk | ETH_BUS_MODE_RPBL_1 | ETH_BUS_MODE_PR_1_1 | ETH_BUS_MODE_PBL_1; //Initialize DMA descriptor lists xmc4700EthInitDmaDesc(interface); //Prevent interrupts from being generated when statistic counters reach //half their maximum value ETH0->MMC_TRANSMIT_INTERRUPT_MASK = 0xFFFFFFFF; ETH0->MMC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF; ETH0->MMC_IPC_RECEIVE_INTERRUPT_MASK = 0xFFFFFFFF; //Disable MAC interrupts ETH0->INTERRUPT_MASK = ETH_INTERRUPT_MASK_TSIM_Msk | ETH_INTERRUPT_MASK_PMTIM_Msk; //Enable the desired DMA interrupts ETH0->INTERRUPT_ENABLE = ETH_INTERRUPT_ENABLE_NIE_Msk | ETH_INTERRUPT_ENABLE_RIE_Msk | ETH_INTERRUPT_ENABLE_TIE_Msk; //Set priority grouping (6 bits for pre-emption priority, no bits for subpriority) NVIC_SetPriorityGrouping(XMC4700_ETH_IRQ_PRIORITY_GROUPING); //Configure Ethernet interrupt priority NVIC_SetPriority(ETH0_0_IRQn, NVIC_EncodePriority(XMC4700_ETH_IRQ_PRIORITY_GROUPING, XMC4700_ETH_IRQ_GROUP_PRIORITY, XMC4700_ETH_IRQ_SUB_PRIORITY)); //Enable MAC transmission and reception ETH0->MAC_CONFIGURATION |= ETH_MAC_CONFIGURATION_TE_Msk | ETH_MAC_CONFIGURATION_RE_Msk; //Enable DMA transmission and reception ETH0->OPERATION_MODE |= ETH_OPERATION_MODE_ST_Msk | ETH_OPERATION_MODE_SR_Msk; //Accept any packets from the upper layer osSetEvent(&interface->nicTxEvent); //Successful initialization return NO_ERROR; }
void tcpDiscardListenerTask(void *param) { error_t error; uint16_t clientPort; IpAddr clientIpAddr; Socket *serverSocket; Socket *clientSocket; DiscardServiceContext *context; OsTask *task; //Point to the listening socket serverSocket = (Socket *) param; //Main loop while(1) { //Accept an incoming connection clientSocket = socketAccept(serverSocket, &clientIpAddr, &clientPort); //Check whether a valid connection request has been received if(!clientSocket) continue; //Debug message TRACE_INFO("Discard service: connection established with client %s port %" PRIu16 "\r\n", ipAddrToString(&clientIpAddr, NULL), clientPort); //Adjust timeout error = socketSetTimeout(clientSocket, DISCARD_TIMEOUT); //Any error to report? if(error) { //Close socket socketClose(clientSocket); //Wait for an incoming connection attempt continue; } //Allocate resources for the new connection context = osAllocMem(sizeof(DiscardServiceContext)); //Failed to allocate memory? if(!context) { //Close socket socketClose(clientSocket); //Wait for an incoming connection attempt continue; } //Record the handle of the newly created socket context->socket = clientSocket; //Create a task to service the current connection task = osCreateTask("TCP Discard Connection", tcpDiscardConnectionTask, context, DISCARD_SERVICE_STACK_SIZE, DISCARD_SERVICE_PRIORITY); //Did we encounter an error? if(task == OS_INVALID_HANDLE) { //Close socket socketClose(clientSocket); //Release resources osFreeMem(context); } } }
error_t dnsSendQuery(DnsCacheEntry *entry) { error_t error; size_t length; size_t offset; ChunkedBuffer *buffer; DnsHeader *message; DnsQuestion *dnsQuestion; IpAddr destIpAddr; #if (IPV4_SUPPORT == ENABLED) //An IPv4 address is expected? if(entry->type == HOST_TYPE_IPV4) { //Select the relevant DNS server destIpAddr.length = sizeof(Ipv4Addr); ipv4GetDnsServer(entry->interface, entry->dnsServerNum, &destIpAddr.ipv4Addr); //Make sure the IP address is valid if(destIpAddr.ipv4Addr == IPV4_UNSPECIFIED_ADDR) return ERROR_NO_DNS_SERVER; } else #endif #if (IPV6_SUPPORT == ENABLED) //An IPv6 address is expected? if(entry->type == HOST_TYPE_IPV6) { //Select the relevant DNS server destIpAddr.length = sizeof(Ipv6Addr); ipv6GetDnsServer(entry->interface, entry->dnsServerNum, &destIpAddr.ipv6Addr); //Make sure the IP address is valid if(ipv6CompAddr(&destIpAddr.ipv6Addr, &IPV6_UNSPECIFIED_ADDR)) return ERROR_NO_DNS_SERVER; } else #endif //Invalid host type? { //Report an error return ERROR_INVALID_PARAMETER; } //Allocate a memory buffer to hold the DNS query message buffer = udpAllocBuffer(DNS_MESSAGE_MAX_SIZE, &offset); //Failed to allocate buffer? if(!buffer) return ERROR_OUT_OF_MEMORY; //Point to the DNS header message = chunkedBufferAt(buffer, offset); //Format DNS query message message->id = htons(entry->id); message->qr = 0; message->opcode = DNS_OPCODE_QUERY; message->aa = 0; message->tc = 0; message->rd = 1; message->ra = 0; message->z = 0; message->rcode = DNS_RCODE_NO_ERROR; //The DNS query contains one question message->qdcount = HTONS(1); message->ancount = 0; message->nscount = 0; message->arcount = 0; //Length of the DNS query message length = sizeof(DnsHeader); //Encode the host name using the DNS name notation length += dnsEncodeName(entry->name, message->questions); //Point to the corresponding question structure dnsQuestion = DNS_GET_QUESTION(message, length); #if (IPV4_SUPPORT == ENABLED) //An IPv4 address is expected? if(entry->type == HOST_TYPE_IPV4) { //Fill in question structure dnsQuestion->qtype = HTONS(DNS_RR_TYPE_A); dnsQuestion->qclass = HTONS(DNS_RR_CLASS_IN); } #endif #if (IPV6_SUPPORT == ENABLED) //An IPv6 address is expected? if(entry->type == HOST_TYPE_IPV6) { //Fill in question structure dnsQuestion->qtype = HTONS(DNS_RR_TYPE_AAAA); dnsQuestion->qclass = HTONS(DNS_RR_CLASS_IN); } #endif //Update the length of the DNS query message length += sizeof(DnsQuestion); //Adjust the length of the multi-part buffer chunkedBufferSetLength(buffer, offset + length); //Debug message TRACE_INFO("Sending DNS message (%" PRIuSIZE " bytes)...\r\n", length); //Dump message dnsDumpMessage(message, length); //Send DNS query message error = udpSendDatagramEx(entry->interface, entry->port, &destIpAddr, DNS_PORT, buffer, offset, 0); //Free previously allocated memory chunkedBufferFree(buffer); //Return status code return error; }
NTSTATUS WINAPI Hook_NtCreateProcessEx (PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ParentProcess, BOOLEAN InheritObjectTable, HANDLE SectionHandle, HANDLE DebugPort, HANDLE ExceptionPort, HANDLE Unknown) { PROC pfnStub = Hooks_GetStubAddress (HOOKS_NTCREATEPROCESSEX) ; NTSTATUS nStatus ; UINT nReaction, nOptions ; WCHAR wszFilePath[MAX_PATH] ; LARGE_INTEGER liFileTime ; WOTSECTION *pWotSectionData ; ULONG nWotDataSize ; PVOID pObjectSection = NULL ; //DbgPrint ("/ Enter \\ irql = %d\n", KeGetCurrentIrql()) ; TRACE ; nStatus = ObReferenceObjectByHandle (SectionHandle, GENERIC_ALL, NULL, KernelMode, &pObjectSection, NULL) ; if( nStatus!=STATUS_SUCCESS || pObjectSection==NULL ) { TRACE_ERROR (TEXT("ObReferenceObjectByHandle failed (status=0x%08X)\n"), nStatus) ; return nStatus ; } nStatus = WatchObjs_Lock () ; if( nStatus != STATUS_SUCCESS ) { ObDereferenceObject (pObjectSection) ; return nStatus ; } nStatus = WatchObjs_GetFromPointer (pObjectSection, WOT_SECTION, (void**)&pWotSectionData, &nWotDataSize) ; if( nStatus!=STATUS_SUCCESS ) { TRACE_WARNING (TEXT("SectionObject is not in watched object list\n")) ; wcscpy (wszFilePath, g_usUnknownFile.Buffer) ; liFileTime.QuadPart = 0 ; } else { wcscpy (wszFilePath, pWotSectionData->wszFilePath) ; liFileTime = pWotSectionData->liFileTime ; } WatchObjs_Unlock () ; ObDereferenceObject (pObjectSection) ; TRACE_INFO (TEXT("File = %ls\n"), wszFilePath) ; HookCommon_CatchCall (&nReaction, &nOptions, FILTREASON_SYS_EXECUTE, TEXT("s"), wszFilePath) ; if( (nOptions&RULE_SCAN)!=0 && nReaction==RULE_ACCEPT && HookCommon_ShouldScanFile(wszFilePath) ) { HookCommon_ScanFile (&nReaction, wszFilePath, &liFileTime) ; } if( nReaction == RULE_REJECT ) { *ProcessHandle = INVALID_HANDLE_VALUE ; return STATUS_FILE_INVALID ; } if( nReaction == RULE_FEIGN ) { *ProcessHandle = INVALID_HANDLE_VALUE ; return STATUS_SUCCESS ; } //DbgPrint ("Calling CreateProcessEx... %ls\n", wszFilePath) ; nStatus = pfnStub (ProcessHandle, DesiredAccess, ObjectAttributes,ParentProcess, InheritObjectTable,SectionHandle, DebugPort, ExceptionPort, Unknown) ; //DbgPrint ("Calling CreateProcessEx... result = 0x%08X\n", nStatus); if( SUCCEEDED (nStatus) ) HookSys_ProcessCreated (*ProcessHandle, wszFilePath) ; //DbgPrint ("\\ Leave /\n") ; return nStatus ; }
error_t dnsResolve(NetInterface *interface, const char_t *name, HostType type, IpAddr *ipAddr) { error_t error; systime_t delay; DnsCacheEntry *entry; //Debug message TRACE_INFO("Resolving host name %s (DNS resolver)...\r\n", name); //Acquire exclusive access to the DNS cache osAcquireMutex(&dnsCacheMutex); //Search the DNS cache for the specified host name entry = dnsFindEntry(interface, name, type, HOST_NAME_RESOLVER_DNS); //Check whether a matching entry has been found if(entry) { //Host name already resolved? if(entry->state == DNS_STATE_RESOLVED || entry->state == DNS_STATE_PERMANENT) { //Return the corresponding IP address *ipAddr = entry->ipAddr; //Successful host name resolution error = NO_ERROR; } else { //Host name resolution is in progress... error = ERROR_IN_PROGRESS; } } else { //If no entry exists, then create a new one entry = dnsCreateEntry(); //Record the host name whose IP address is unknown strcpy(entry->name, name); //Initialize DNS cache entry entry->type = type; entry->protocol = HOST_NAME_RESOLVER_DNS; entry->interface = interface; //Select primary DNS server entry->dnsServerNum = 0; //Get an ephemeral port number entry->port = socketGetEphemeralPort(); //An identifier is used by the DNS client to match replies //with corresponding requests entry->id = tcpIpStackGetRand(); //Callback function to be called when a DNS response is received error = udpAttachRxCallback(interface, entry->port, dnsProcessResponse, NULL); //Check status code if(!error) { //Initialize retransmission counter entry->retransmitCount = DNS_CLIENT_MAX_RETRIES; //Send DNS query error = dnsSendQuery(entry); //DNS message successfully sent? if(!error) { //Save the time at which the query message was sent entry->timestamp = osGetSystemTime(); //Set timeout value entry->timeout = DNS_CLIENT_INIT_TIMEOUT; entry->maxTimeout = DNS_CLIENT_MAX_TIMEOUT; //Decrement retransmission counter entry->retransmitCount--; //Switch state entry->state = DNS_STATE_IN_PROGRESS; //Host name resolution is in progress error = ERROR_IN_PROGRESS; } else { //Unregister callback function udpDetachRxCallback(interface, entry->port); } } } //Release exclusive access to the DNS cache osReleaseMutex(&dnsCacheMutex); //Set default polling interval delay = DNS_CACHE_INIT_POLLING_INTERVAL; //Wait the host name resolution to complete while(error == ERROR_IN_PROGRESS) { //Wait until the next polling period osDelayTask(delay); //Acquire exclusive access to the DNS cache osAcquireMutex(&dnsCacheMutex); //Search the DNS cache for the specified host name entry = dnsFindEntry(interface, name, type, HOST_NAME_RESOLVER_DNS); //Check whether a matching entry has been found if(entry) { //Host name successfully resolved? if(entry->state == DNS_STATE_RESOLVED) { //Return the corresponding IP address *ipAddr = entry->ipAddr; //Successful host name resolution error = NO_ERROR; } } else { //Host name resolution failed error = ERROR_FAILURE; } //Release exclusive access to the DNS cache osReleaseMutex(&dnsCacheMutex); //Backoff support for less aggressive polling delay = MIN(delay * 2, DNS_CACHE_MAX_POLLING_INTERVAL); } //Check status code if(error) { //Failed to resolve host name TRACE_INFO("Host name resolution failed!\r\n"); } else { //Successful host name resolution TRACE_INFO("Host name resolved to %s...\r\n", ipAddrToString(ipAddr, NULL)); } //Return status code return error; }
NTSTATUS DDKAPI Hook_NtTerminateProcess (IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus) { PROC pfnStub = Hooks_GetStubAddress (HOOKS_NTTERMINATEPROCESS) ; NTSTATUS nStatus ; TRACE_INFO (TEXT("ProcessHandle=0x%08X (currentprocess=0x%08X)\n"), ProcessHandle, ProcInfo_GetCurrentProcessAddress()) ; if( ProcessHandle!=INVALID_HANDLE_VALUE && ProcessHandle!=NULL ) { PROCSTRUCT *pProc ; PROCADDR nProcessAddress ; UINT nReaction = RULE_ACCEPT ; WCHAR wszFilePath[MAX_PATH] ; ProcInfo_GetAddress (ProcessHandle, &nProcessAddress) ; TRACE_ALWAYS (TEXT("Process 0x%08X is killing process 0x%08X\n"), ProcInfo_GetCurrentProcessAddress(), nProcessAddress) ; wcscpy (wszFilePath, g_usUnknownFile.Buffer) ; nStatus = ProcList_Lock () ; if( nStatus == STATUS_SUCCESS ) { pProc = ProcList_Get (nProcessAddress) ; if( pProc != NULL ) wcscpy (wszFilePath, pProc->wszPath) ; ProcList_Unlock () ; } HookCommon_CatchCall (&nReaction, NULL, FILTREASON_SYS_KILLPROCESS, TEXT("s"), wszFilePath) ; if( nReaction == RULE_REJECT ) return STATUS_ACCESS_DENIED ; if( nReaction == RULE_FEIGN ) return STATUS_SUCCESS ; } // if NtTerminateProcess is called with ProcessHandle==0xFFFFFFFF, it will not return // in this case, we call it later if( ProcessHandle!=INVALID_HANDLE_VALUE ) nStatus = (NTSTATUS) pfnStub (ProcessHandle, ExitStatus) ; else nStatus = STATUS_SUCCESS ; // we ignore the call if it ProcessHandle==NULL because NtTerminateProcess will be called // a second time with a valie ProcessHandle or with 0xFFFFFFFF // (this has been observed on Windows XP SP2 and Windows 2000 SP4) if( SUCCEEDED(nStatus) && ProcessHandle!=NULL ) { PROCSTRUCT *pProc ; PROCADDR nProcessAddress ; if( nStatus!=STATUS_SUCCESS ) TRACE_WARNING(TEXT("NtTerminateProcess returned 0x%08X\n"), nStatus) ; if( ProcessHandle!=NULL && ProcessHandle!=INVALID_HANDLE_VALUE ) ProcInfo_GetAddress (ProcessHandle, &nProcessAddress) ; else nProcessAddress = ProcInfo_GetCurrentProcessAddress() ; nStatus = ProcList_Lock () ; if( nStatus != STATUS_SUCCESS ) return nStatus ; pProc = ProcList_Remove (nProcessAddress) ; ProcList_Unlock () ; if( pProc==NULL ) TRACE_WARNING (TEXT("Unknown process (handle=0x%08X, address=0x%08)\n"), ProcessHandle, nProcessAddress) ; if( pProc!=NULL && (pProc->nFlags&PROCESS_NO_NOTIFICATION)==0 ) HookCommon_SendProcessTerminatedNotification (nProcessAddress) ; ProcList_Delete (pProc) ; } // read comment above if( ProcessHandle==INVALID_HANDLE_VALUE ) nStatus = (NTSTATUS) pfnStub (ProcessHandle, ExitStatus) ; return nStatus ; }
//------------------------------------------------------------------------------ /// Saves the logical mapping on a FREE, unmapped physical block. Allocates the /// new block, releases the previous one (if any) and save the mapping. /// Returns 0 if successful; otherwise, returns NandCommon_ERROR_WRONGSTATUS /// if the block is not LIVE, or a NandCommon_ERROR code. /// \param mapped Pointer to a MappedNandFlash instance. /// \param physicalBlock Physical block number. //------------------------------------------------------------------------------ unsigned char MappedNandFlash_SaveLogicalMapping( struct MappedNandFlash *mapped, unsigned short physicalBlock) { unsigned char error; //unsigned char data[NandCommon_MAXPAGEDATASIZE]; unsigned short pageDataSize = NandFlashModel_GetPageDataSize(MODEL(mapped)); unsigned char *pDataBuffer; //unsigned short numBlocks = // ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)); unsigned int i; unsigned int remainingSize; unsigned char *currentBuffer; unsigned short currentPage; unsigned int writeSize; signed short previousPhysicalBlock; TRACE_INFO("MappedNandFlash_SaveLogicalMapping(B#%d)\r\n", physicalBlock); // If mapping has not been modified, do nothing if (!mapped->mappingModified) { return 0; } pDataBuffer = RawNandFlash_GetDataBuffer(RAW(mapped)); // Allocate new block error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock); if (error) { goto error; } // Save mapping previousPhysicalBlock = mapped->logicalMappingBlock; mapped->logicalMappingBlock = physicalBlock; // Save actual mapping in pages #1-#XXX currentBuffer = (unsigned char *) mapped->logicalMapping; remainingSize = sizeof(mapped->logicalMapping); currentPage = 1; while (remainingSize > 0) { writeSize = min(remainingSize, pageDataSize); memset(pDataBuffer, 0xFF, pageDataSize); memcpy(pDataBuffer, currentBuffer, writeSize); error = ManagedNandFlash_WritePage(MANAGED(mapped), physicalBlock, currentPage, pDataBuffer, 0); if (error) { TRACE_ERROR( "MappedNandFlash_SaveLogicalMapping: Failed to write mapping\r\n"); goto error; } currentBuffer += writeSize; remainingSize -= writeSize; currentPage++; } // Mark page #0 of block with a distinguishible pattern, so the mapping can // be retrieved at startup for (i=0; i < pageDataSize; i++) { pDataBuffer[i] = PATTERN(i); } error = ManagedNandFlash_WritePage(MANAGED(mapped), physicalBlock, 0, pDataBuffer, 0); if (error) { TRACE_ERROR( "MappedNandFlash_SaveLogicalMapping: Failed to write pattern\r\n"); goto error; } // Mapping is not modified anymore mapped->mappingModified = 0; // Release previous block (if any) if (previousPhysicalBlock != -1) { TRACE_DEBUG("Previous physical block was #%d\r\n", previousPhysicalBlock); error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped), previousPhysicalBlock); if (error) { goto error; } } TRACE_INFO("Mapping saved on block #%d\r\n", physicalBlock); error: RawNandFlash_ReleaseDataBuffer(RAW(mapped)); return 0; }
NTSTATUS DDKAPI Hook_NtCreateSection (PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle) { PROC pfnStub = Hooks_GetStubAddress (HOOKS_NTCREATESECTION) ; NTSTATUS nStatus ; TRACE ; //if( FileHandle==NULL ) // TRACE_WARNING (TEXT("FileHandle==NULL\n")) ; nStatus = pfnStub (SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle) ; if( nStatus==STATUS_SUCCESS && FileHandle ) { WOTFILE *pWotFileData ; WOTSECTION *pWotSectionData ; ULONG nWotDataSize ; PVOID pObjectFile = NULL ; PVOID pObjectSection = NULL ; nStatus = ObReferenceObjectByHandle (FileHandle, GENERIC_ALL, NULL, KernelMode, &pObjectFile, NULL) ; if( nStatus!=STATUS_SUCCESS || pObjectFile==NULL ) { TRACE_ERROR (TEXT("ObReferenceObjectByHandle failed (status=0x%08X)\n"), nStatus) ; ZwClose (*SectionHandle) ; return nStatus ; } nStatus = WatchObjs_Lock () ; if( nStatus != STATUS_SUCCESS ) { ObDereferenceObject (pObjectFile) ; ZwClose (*SectionHandle) ; return nStatus ; } nStatus = WatchObjs_GetFromPointer (pObjectFile, WOT_FILE, (void**)&pWotFileData, &nWotDataSize) ; if( nStatus==STATUS_SUCCESS ) { pWotSectionData = MALLOC (nWotDataSize) ; if( pWotSectionData == NULL ) { TRACE_ERROR (TEXT("Failed to allocate structure WOTSECTION (%u bytes)\n"), nWotDataSize) ; WatchObjs_Unlock () ; ObDereferenceObject (pObjectFile) ; ZwClose (*SectionHandle) ; return STATUS_INSUFFICIENT_RESOURCES ; } memcpy (pWotSectionData, pWotFileData, nWotDataSize) ; WatchObjs_Unlock () ; ObDereferenceObject (pObjectFile) ; } else { UNICODE_STRING usFileName ; WatchObjs_Unlock () ; ObDereferenceObject (pObjectFile) ; nWotDataSize = sizeof(WOTSECTION) + MAX_PATH*sizeof(WCHAR) ; pWotSectionData = MALLOC (nWotDataSize) ; if( pWotSectionData == NULL ) { TRACE_ERROR (TEXT("Failed to allocate structure WOTSECTION (%u bytes)\n"), nWotDataSize) ; ZwClose (*SectionHandle) ; return STATUS_INSUFFICIENT_RESOURCES ; } usFileName.Length = 0 ; usFileName.MaximumLength = MAX_PATH *sizeof(WCHAR) ; usFileName.Buffer = MALLOC(usFileName.MaximumLength) ; if( usFileName.Buffer == NULL ) { TRACE_ERROR (TEXT("Failed to allocate buffer for filename (%u bytes)\n"), usFileName.MaximumLength) ; FREE(pWotSectionData) ; ZwClose (*SectionHandle) ; return STATUS_INSUFFICIENT_RESOURCES ; } nStatus = FileInfo_GetPath (FileHandle, &usFileName) ; if( nStatus!=STATUS_SUCCESS ) { TRACE_ERROR (TEXT("FileInfo_GetDosPath failed (status=0x%08X)\n"), nStatus) ; RtlCopyUnicodeString (&usFileName, &g_usUnknownFile) ; } } TRACE_INFO (TEXT("File = %ls\n"), pWotSectionData->wszFilePath) ; ASSERT (*SectionHandle!=NULL) ; nStatus = ObReferenceObjectByHandle (*SectionHandle, GENERIC_ALL, NULL, KernelMode, &pObjectSection, NULL) ; if( nStatus!=STATUS_SUCCESS || pObjectSection==NULL ) { TRACE_ERROR (TEXT("ObReferenceObjectByHandle failed (status=0x%08X)\n"), nStatus) ; ZwClose (*SectionHandle) ; return nStatus ; } nStatus = WatchObjs_Lock () ; if( nStatus != STATUS_SUCCESS ) { ZwClose (*SectionHandle) ; ObDereferenceObject (pObjectSection) ; return nStatus ; } nStatus = WatchObjs_AddFromPointer (pObjectSection, WOT_SECTION, pWotSectionData, nWotDataSize) ; WatchObjs_Unlock () ; ObDereferenceObject (pObjectSection) ; // restore original status nStatus = STATUS_SUCCESS ; } return nStatus ; }
error_t ftpClientTest(void) { error_t error; size_t length; IpAddr ipAddr; FtpClientContext ftpContext; static char_t buffer[256]; //Debug message TRACE_INFO("\r\n\r\nResolving server name...\r\n"); //Resolve FTP server name error = getHostByName(NULL, "ftp.gnu.org", &ipAddr, 0); //Any error to report? if(error) { //Debug message TRACE_INFO("Failed to resolve server name!\r\n"); //Exit immediately return error; } //Debug message TRACE_INFO("Connecting to FTP server %s\r\n", ipAddrToString(&ipAddr, NULL)); //Connect to the FTP server error = ftpConnect(&ftpContext, NULL, &ipAddr, 21, FTP_NO_SECURITY | FTP_PASSIVE_MODE); //Any error to report? if(error) { //Debug message TRACE_INFO("Failed to connect to FTP server!\r\n"); //Exit immediately return error; } //Debug message TRACE_INFO("Successful connection\r\n"); //Start of exception handling block do { //Login to the FTP server using the provided username and password error = ftpLogin(&ftpContext, "anonymous", "password", ""); //Any error to report? if(error) break; //Open the specified file for reading error = ftpOpenFile(&ftpContext, "welcome.msg", FTP_FOR_READING | FTP_BINARY_TYPE); //Any error to report? if(error) break; //Dump the contents of the file while(1) { //Read data error = ftpReadFile(&ftpContext, buffer, sizeof(buffer) - 1, &length, 0); //End of file? if(error) break; //Properly terminate the string with a NULL character buffer[length] = '\0'; //Dump current data TRACE_INFO("%s", buffer); } //End the string with a line feed TRACE_INFO("\r\n"); //Close the file error = ftpCloseFile(&ftpContext); //End of exception handling block } while(0); //Close the connection ftpClose(&ftpContext); //Debug message TRACE_INFO("Connection closed...\r\n"); //Return status code return error; }
/** * State machine for the MSD %device driver * \param pMsdDriver Pointer to a MSDDriver instance */ void MSDD_StateMachine(MSDDriver * pMsdDriver) { MSDCommandState *commandState = &(pMsdDriver->commandState); MSCbw *cbw = &(commandState->cbw); MSCsw *csw = &(commandState->csw); MSDTransfer *transfer = &(commandState->transfer); unsigned char status; /* Identify current driver state */ switch (pMsdDriver->state) { /*---------------------- */ case MSDD_STATE_READ_CBW: /*---------------------- */ /* Start the CBW read operation */ transfer->semaphore = 0; #if 1 status = USBD_Read(commandState->pipeOUT, cbw, MSD_CBW_SIZE, (TransferCallback) MSDDriver_Callback, (void *) transfer); #else status = MSDD_Read(cbw, MSD_CBW_SIZE, (TransferCallback) MSDDriver_Callback, (void *) transfer); #endif /* Check operation result code */ if (status == USBD_STATUS_SUCCESS) { /* If the command was successful, wait for transfer */ pMsdDriver->state = MSDD_STATE_WAIT_CBW; } break; /*---------------------- */ case MSDD_STATE_WAIT_CBW: /*---------------------- */ /* Check transfer semaphore */ if (transfer->semaphore > 0) { /* Take semaphore and terminate transfer */ transfer->semaphore--; /* Check if transfer was successful */ if (transfer->status == USBD_STATUS_SUCCESS) { TRACE_INFO_WP("\n\r------------------------------\n\r"); /* Process received command */ pMsdDriver->state = MSDD_STATE_PROCESS_CBW; } else if (transfer->status == USBD_STATUS_RESET) { TRACE_INFO("MSDD_StateMachine: EP resetted\n\r"); pMsdDriver->state = MSDD_STATE_READ_CBW; } else { TRACE_WARNING( "MSDD_StateMachine: Failed to read CBW\n\r"); pMsdDriver->state = MSDD_STATE_READ_CBW; } } break; /*------------------------- */ case MSDD_STATE_PROCESS_CBW: /*------------------------- */ /* Check if this is a new command */ if (commandState->state == 0) { /* Copy the CBW tag */ csw->dCSWTag = cbw->dCBWTag; /* Check that the CBW is 31 bytes long */ if ((transfer->transferred != MSD_CBW_SIZE) || (transfer->remaining != 0)) { TRACE_WARNING( "MSDD_StateMachine: Invalid CBW (len %d)\n\r", (int)transfer->transferred); /* Wait for a reset recovery */ pMsdDriver->waitResetRecovery = 1; /* Halt the Bulk-IN and Bulk-OUT pipes */ //MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN); USBD_Halt(commandState->pipeIN); USBD_Halt(commandState->pipeOUT); csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; pMsdDriver->state = MSDD_STATE_READ_CBW; } /* Check the CBW Signature */ else if (cbw->dCBWSignature != MSD_CBW_SIGNATURE) { TRACE_WARNING( "MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r"); /* Wait for a reset recovery */ pMsdDriver->waitResetRecovery = 1; /* Halt the Bulk-IN and Bulk-OUT pipes */ //MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN); USBD_Halt(commandState->pipeIN); USBD_Halt(commandState->pipeOUT); csw->bCSWStatus = MSD_CSW_COMMAND_FAILED; pMsdDriver->state = MSDD_STATE_READ_CBW; } else { /* Pre-process command */ MSDD_PreProcessCommand(pMsdDriver); } } /* Process command */ if (csw->bCSWStatus == MSDD_STATUS_SUCCESS) { if (MSDD_ProcessCommand(pMsdDriver)) { /* Post-process command if it is finished */ if (MSDD_PostProcessCommand(pMsdDriver)) { TRACE_INFO_WP("WaitHALT "); pMsdDriver->state = MSDD_STATE_WAIT_HALT; } else { pMsdDriver->state = MSDD_STATE_SEND_CSW; } } TRACE_INFO_WP("\n\r"); } break; /*---------------------- */ case MSDD_STATE_SEND_CSW: /*---------------------- */ /* Set signature */ csw->dCSWSignature = MSD_CSW_SIGNATURE; /* Start the CSW write operation */ #if 1 status = USBD_Write(commandState->pipeIN, csw, MSD_CSW_SIZE, (TransferCallback) MSDDriver_Callback, (void *) transfer); #else status = MSDD_Write(csw, MSD_CSW_SIZE, (TransferCallback) MSDDriver_Callback, (void *) transfer); #endif /* Check operation result code */ if (status == USBD_STATUS_SUCCESS) { TRACE_INFO_WP("SendCSW "); /* Wait for end of transfer */ pMsdDriver->state = MSDD_STATE_WAIT_CSW; } break; /*---------------------- */ case MSDD_STATE_WAIT_CSW: /*---------------------- */ /* Check transfer semaphore */ if (transfer->semaphore > 0) { /* Take semaphore and terminate transfer */ transfer->semaphore--; /* Check if transfer was successful */ if (transfer->status == USBD_STATUS_RESET) { TRACE_INFO("MSDD_StateMachine: EP resetted\n\r"); } else if (transfer->status == USBD_STATUS_ABORTED) { TRACE_WARNING( "MSDD_StateMachine: Failed to send CSW\n\r"); } else { TRACE_INFO_WP("ok"); } /* Read new CBW */ pMsdDriver->state = MSDD_STATE_READ_CBW; } break; /*---------------------- */ case MSDD_STATE_WAIT_HALT: /*---------------------- */ //if (MSDD_IsHalted() == 0) { if (!USBD_IsHalted(commandState->pipeIN)) { pMsdDriver->state = MSDD_STATE_SEND_CSW; } break; } }