Пример #1
0
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;
}
Пример #4
0
//-----------------------------------------------------------------------------
/// 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;
}
Пример #5
0
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");
    }
}
Пример #7
0
 /* FreeRTOS Callbacks */
 void vApplicationTickHook(void) {
   static int i = 0;
   if (i < 1000) i++;
   else { TRACE_INFO("tick\n"); i = 0; }
 }
Пример #8
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;
}
Пример #9
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);
}
Пример #10
0
Файл: main.c Проект: gstroe/Arm
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();
	}
}
Пример #11
0
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;
}
Пример #12
0
/**
 * \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;
}
Пример #13
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;
}
Пример #14
0
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;
}
Пример #15
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

   //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;
}
Пример #16
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;
}
Пример #17
0
/**
 * \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;
}
Пример #18
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;
   }
}
Пример #19
0
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);
}
Пример #20
0
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;
   }
}
Пример #21
0
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;
}
Пример #22
0
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);
      }
   }
}
Пример #23
0
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;
}
Пример #24
0
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 ;
}
Пример #25
0
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;
}
Пример #26
0
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;
}
Пример #28
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 ;
}
Пример #29
0
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;
}
Пример #30
0
/**
 * 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;
    }
}