Beispiel #1
0
/**
 * Initialises an HID device.
 *
 * @param device the USB device.
 * @param handle configuration information.
 */
static void hid_initUsb(usb_device * device, hid_usbConfiguration * handle)
{
	// Initialise/configure the USB device.
	usb_initDevice(device, handle->configuration);

#ifdef DEBUG
	usb_printDeviceInfo( device );
#endif

	// Initialise bulk / interrupt input endpoint.
	usb_initEndPoint(&(device->bulk_in), handle->inputEndPointAddress);
	device->bulk_in.attributes = USB_ENDPOINT_XFER_INT;
	device->bulk_in.maxPacketSize = HID_USB_PACKETSIZE;

	// Initialise bulk / interrupt output endpoint.
	usb_initEndPoint(&(device->bulk_out), handle->outputEndPointAddress);
	device->bulk_out.attributes = USB_ENDPOINT_XFER_INT;
	device->bulk_out.maxPacketSize = HID_USB_PACKETSIZE;

#ifdef DEBUG
    xSerialPrintf_P(PSTR("handle->inputEndPointAddress: 0x%02x\r\n"), handle->inputEndPointAddress);
    xSerialPrintf_P(PSTR("handle->outputEndPointAddress: 0x%02x\r\n"), handle->outputEndPointAddress);
    xSerialPrintf_P(PSTR("bulk_in.address: 0x%02x\r\n"), device->bulk_in.address);
    xSerialPrintf_P(PSTR("bulk_out.address: 0x%02x\r\n"), device->bulk_out.address);
#endif
}
Beispiel #2
0
/**
 @brief 	Send ping reply packet to the specified peer

 If Error is occurred in sending ping reply packet, then ignored\n
 Because it is not need to send ping reply packet to the specified peer every time.

 */
static void SendPingReply(
	PING_MSG *pingrequest,	/**< received ping reply packet from the specified peer */
	uint32_t destaddr		/**< 32bit peer ip address (network ordering) */
	)
{
	SOCKET PingReplySocket;

	PingReplySocket = getSocket(SOCK_CLOSED,0);	// Find free socket number
	if(PingReplySocket != MAX_SOCK_NUM )        // Is there a free socket?
	{
		setSn_PROTO( PingReplySocket, IP_PROTO_ICMP); 	    		// Set upper protocol of IP_RAW mode
		if( socket( PingReplySocket, Sn_MR_IPRAW, 3001, 0) != 0)	// Open ICMP socket
		{
			(*pingrequest).type = 0;				// Ping-Reply
			(*pingrequest).code = 0;                // Always 0
  			(*pingrequest).checksum = 0;
			(*pingrequest).checksum = htons( checksum((uint8_t*)pingrequest, sizeof(PING_MSG)));	// Calculate checksum

			if(sendto( PingReplySocket, (uint8_t *)pingrequest, sizeof(PING_MSG), (uint8_t*)&destaddr, 3001) == 0)  // sent ping-reply packet to the specified peer
				xSerialPrintf_P(PSTR("Fail to send ping-reply packet to %s. Send failure"),inet_ntoa(ntohl(destaddr)));

			close(PingReplySocket);				// Close ICMP socket
		}

		setSn_PROTO(PingReplySocket,0);		// Clear IP protocol register.
	}
	else	xSerialPrintf_P(PSTR("Fail to send ping-reply packet to %s. NO FREE SOCKET"),inet_ntoa(ntohl(destaddr)));
}
Beispiel #3
0
/**
 * @brief		Initialise the socket & buffer for HTTP server
 */
uint8_t init_httpd_ch(SOCKET s)
{
	uint8_t ret;
	ret = 0;

	if( getSn_SR(s) != SOCK_CLOSED )	// Check the preferred socket is available,
	{
		s = getSocket(SOCK_CLOSED, 0);	// otherwise find free socket,
		if(s == MAX_SOCK_NUM )        	// If there is no free socket?
			ret = 0;
	}
	else
	{
		ret = 1;
	}

	if(!socket(s, Sn_MR_TCP, IP_PORT_HTTP, 0x00)) // initialise the socket for DHCP service
	{
		xSerialPrintf_P(PSTR("HTTPD socket: %d, initialise fail..!\r\n"),s);
		ret = 0;
	}
#ifdef HTTP_DEBUG
	else
		xSerialPrintf_P(PSTR("HTTPD socket: %d, initialise success..!\r\n"),s);
#endif

	if(pHTTPRequest == NULL) // if there is no buffer allocated (pointer is NULL), then allocate request buffer for all HTTP functions.
	{
		if( !(pHTTPRequest = (HTTP_REQUEST *) pvPortMalloc( sizeof(HTTP_REQUEST) )))
		{
			xSerialPrint_P(PSTR("HTTP Request Buffer: malloc fail..!\r\n"));
			ret = 0;
		}
#ifdef HTTP_DEBUG
		else
			xSerialPrint_P(PSTR("HTTP Request Buffer: malloc success..!\r\n"));
#endif
	}

	if(pHTTPResponse == NULL) // if there is no buffer allocated (pointer is NULL), then allocate response buffer for all HTTP functions.
	{
		if( !(pHTTPResponse = (uint8_t *) pvPortMalloc( sizeof(uint8_t) * (FILE_BUFFER_SIZE + 1) )))
		{
			xSerialPrint_P(PSTR("HTTP Response Buffer: malloc fail..!\r\n"));
			vPortFree(pHTTPRequest);
			ret = 0;
		}
#ifdef HTTP_DEBUG
		else
			xSerialPrint_P(PSTR("HTTP Response Buffer: malloc success..!\r\n"));
#endif
	}

	HTTPD_SOCK = s;

	return ret;
}
Beispiel #4
0
/**
 * Writes an HID message with payload to the HID device using the interrupt endpoint
 *
 * @param device USB device handle.
 * @param data command payload.
 * @return error code or 0 for success.
 */
static int16_t hid_writeMessage( usb_device * device, uint8_t data )
{
	hid_bootKeyboardOutputReport message;
	int16_t rcode;

	// Fill out the message record.
	message.generic = data;

	if (*theConnection == HID_OPEN)
	{
		*theConnection = HID_WRITING;
#ifdef DEBUG
		xSerialPrintf_P(PSTR("\r\nOUT << 0x%02x"), message.generic);
#endif

		rcode = usb_bulkWrite(device, sizeof(hid_bootKeyboardOutputReport), (uint8_t*)&message);
		if (rcode < 0)
			return rcode;

		rcode = usb_bulkWrite(device, 1, (uint8_t *)&data);
		if (rcode < 0)
			return rcode;
	}
	*theConnection = HID_OPEN;
	return 0;
}
Beispiel #5
0
/**
 * Helper function for usb_isHIDDevice to check whether an interface is a valid HID interface.
 * @param interface interface descriptor struct.
 */
static uint8_t usb_isHIDInterface(usb_interfaceDescriptor * interface)
{

	// Check if the interface has exactly one endpoint (excluding the control endpoint 0).
	if (interface->bNumEndpoints!=1) return false;

#ifdef DEBUG
    xSerialPrintf_P(PSTR("Interface class: %d\r\n"), interface->bInterfaceClass);
    xSerialPrintf_P(PSTR("Interface subclass: %d\r\n"), interface->bInterfaceSubClass);
    xSerialPrintf_P(PSTR("Interface protocol: %d\r\n"), interface->bInterfaceProtocol);
#endif

	// Check if the endpoint supports interrupt transfer.
	if (interface->bInterfaceClass != HID_INTF) return false;
	if (interface->bInterfaceSubClass != BOOT_INTF_SUBCLASS) return false;
	if ( !(interface->bInterfaceProtocol && (HID_PROTOCOL_KEYBOARD | HID_PROTOCOL_MOUSE)) ) return false;


	return true;
}
Beispiel #6
0
/**
 * Print USB device information.
 */
int usb_printDeviceInfo(usb_device * device)
{
	int rcode;
    // char buf[128];

    // Read the device descriptor
	usb_deviceDescriptor deviceDescriptor;
    rcode = usb_getDeviceDescriptor(device, &deviceDescriptor);
    if (rcode) return rcode;

    xSerialPrintf_P(PSTR("\r\nVendor ID: %x\r\n"), deviceDescriptor.idVendor);
    xSerialPrintf_P(PSTR("Product ID: %x\r\n"), deviceDescriptor.idProduct);
    xSerialPrintf_P(PSTR("Configuration count: %d\r\n"), deviceDescriptor.bNumConfigurations);
    xSerialPrintf_P(PSTR("Device class: %d\r\n"), deviceDescriptor.bDeviceClass);
    xSerialPrintf_P(PSTR("Device subclass: %d\r\n"), deviceDescriptor.bDeviceSubClass);
    xSerialPrintf_P(PSTR("Device protocol: %d\r\n"), deviceDescriptor.bDeviceProtocol);

    /*
    usb_getString(device, deviceDescriptor.iManufacturer, device->firstStringLanguage, 128, buf);
    avr_serialPrintf("Manufacturer: %d %s\n", deviceDescriptor.iManufacturer, buf);

    usb_getString(device, deviceDescriptor.iProduct, device->firstStringLanguage, 128, buf);
    avr_serialPrintf("Product: %s\n", buf);

    usb_getString(device, deviceDescriptor.iSerialNumber, device->firstStringLanguage, 128, buf);
    avr_serialPrintf("Serial number: %s\n", buf);
    */

    return 0;
}
Beispiel #7
0
uint8_t* get_http_uri_name(uint8_t* uri)
{
	uint8_t tempURI[MAX_URI_SIZE];
	uint8_t* uri_name;
	if(!uri) return 0;
	strncpy((char *)tempURI, (const char *)uri, MAX_URI_SIZE);
	uri_name = (uint8_t*)strtok((char *)tempURI, " ?");
	if(strcmp( (const char *)uri_name, "/" )) uri_name++;
#ifdef HTTP_DEBUG
	xSerialPrintf_P(PSTR("\nuri_name=%s "),uri_name);
#endif
	return (uint8_t*)uri_name;
}
Beispiel #8
0
void hid_put_dump(const uint8_t *buffer, uint16_t cnt)
{
	uint8_t i;

	for(i = 0; i < cnt; ++i)
		xSerialPrintf_P(PSTR(" %02X"), buffer[i]);

	xSerialPutChar( &xSerialPort, ' ' );
	for(i = 0; i < cnt; ++i)
	{
		xSerialPutChar( &xSerialPort, (buffer[i] >= ' ' && buffer[i] <= '~') ? buffer[i] : '.' );
	}
	xSerialPrint((uint8_t *)"\r\n");
	vTaskDelay( 8 / portTICK_PERIOD_MS ); // Whoa... too fast.
}
unsigned short fill_buf(void* blk)
{
	uint16_t webpage_len;
	char int_string[4];

	webpage_len = (strlen_P(webpage)>uip_mss())?uip_mss():strlen_P(webpage);

	xSerialPrintf_P(PSTR("fill_buf : %s\r\n"), webpage);

	memcpy_P(uip_appdata, webpage, webpage_len);

	sprintf(int_string, "%X", mfg_id[0]);
	memcpy(&uip_appdata[104], int_string, 2);
	sprintf(int_string, "%X", mfg_id[1]);
	memcpy(&uip_appdata[108], int_string, 2);
	return webpage_len;
}
Beispiel #10
0
/**
 @brief 	Display result of ping
 */
void DisplayPingStatistics(
	PING_LOG log		/**< result of ping */
	)
{
	xSerialPrintf_P(PSTR("\r\n\tPackets: Sent = %d, Received = %d, Lost = %d\r\n"),
    		log.PingRequest,log.PingReply+log.CheckSumErr+log.UnknownMSG+log.UnreachableMSG+log.TimeExceedMSG,log.Loss+log.ARPErr);
	if(log.CheckSumErr > 0)
		xSerialPrintf_P(PSTR("\tChecksum Error packets = %d\r\n"),log.CheckSumErr);
	if(log.UnreachableMSG > 0)
		xSerialPrintf_P(PSTR("\tUnreachable Message packets = %d\r\n"),log.UnreachableMSG);
	if(log.TimeExceedMSG > 0)
		xSerialPrintf_P(PSTR("\tTime Exceeded Message packets = %d\r\n"),log.TimeExceedMSG);
	if(log.UnknownMSG > 0)
		xSerialPrintf_P(PSTR("\tUnknown Message packets = %d\r\n"),log.UnknownMSG);
	if(log.ARPErr > 0)
		xSerialPrintf_P(PSTR("\tFail To Send ARP packets = %d\r\n"),log.ARPErr);
	if(log.Loss > 0)
		xSerialPrintf_P(PSTR("\tRequest timed out = %d\r\n"),log.Loss);
	if(log.PingReply > 0)
		xSerialPrintf_P(PSTR("\tPing Reply packets = %d\r\n"),log.PingReply);
}
Beispiel #11
0
/**
 @brief	get next parameter value in the request
 */
uint8_t* get_http_param_value(
	uint8_t* uri,
	uint8_t* param_name
	)
{
	uint8_t tempURI[MAX_URI_SIZE];
	uint8_t* name=0;
	if(!uri || !param_name) return 0;

	strncpy((char *)tempURI, (const char *)uri, MAX_URI_SIZE);
	if((name=(uint8_t*)strstr((const char *)tempURI, (const char *)param_name)))
	{
		name += strlen((const char *)param_name) + 1; // strlen(para_name) + strlen("=")
		if((name = (uint8_t*)strtok((char *)name,"& \r\n\t\0")))
		{
			unescape_http_url((uint8_t*)name);
			replacetochar((uint8_t*)name,'+',' ');
		}
	}
#ifdef HTTP_DEBUG
	xSerialPrintf_P(PSTR("\n%s=%s "),param_name,name);
#endif
	return (uint8_t*)name;
}
Beispiel #12
0
/**
 @brief 	Send ping-request to the specified peer and receive ping-reply from the specified peer.
 @return	1 - success, 0 - fail because free socket is not found or can't be opened.
 */
uint8_t ping(
	uint8_t count, 		/**< Ping request count. */
	uint16_t time, 		/**< wait ping reply time (unit : ms) */
	uint8_t* addr, 		/**< Peer IP Address string in dotted decimal format */
	PING_LOG* log		/**< result of ping */
	)
{

	PING_MSG* pPingRequest;		// pointer for Ping Request
	PING_MSG* pPingReply;		// pointer for Ping Reply
	uint32_t peerip;            // 32 bit Peer IP Address
	uint32_t tempip;			// IP address received from a destination
	uint16_t port;              // port number received from a destination

	SOCKET   s;					// socket variable for pinging

	uint16_t RandomSeqNum;		// Ping-Request ID

	uint16_t len;
	uint8_t  IsReceived;    	// Received packet = 1, not received packet = 0

    portTickType xInitialTick;

	/* Initialise PingRequest */


	if( !(pPingRequest = (PING_MSG *) pvPortMalloc( sizeof(PING_MSG) )))
		return 0;

	if( !(pPingReply   = (PING_MSG *) pvPortMalloc( sizeof(PING_MSG) )))
	{
		vPortFree(pPingRequest);
		return 0;
	}

	RandomSeqNum = htons( (uint16_t)rand());		// set ping-request's sequence number to random integer value

	pPingRequest->type = 0x08;           			// Ping-Request - ICMP
	pPingRequest->code = 0x00;						// always 0
	pPingRequest->checksum = 0;						// value of checksum before calculating checksum of ping-request packet
	pPingRequest->id = htons(PING_ID);				// set ping-request ID

	for(uint16_t i = 0 ; i < PING_OPT_LEN; i++)
		pPingRequest->OPT[i] = 'a' + i % 23;		// fill 'a'~'w' characters into ping-request's data

	/* Initialise result of ping */
	memset((void*)log,0,sizeof(PING_LOG));

    /* Verify arguments */
	if(!count) count = 4;					// set count to default value (4 pings)
	if(!time) time = 1000;					// set response time to default value (1000ms)

	/* Create a ping socket */
	s = getSocket(SOCK_CLOSED,0);
	if(s == MAX_SOCK_NUM)					// if it isn't exist free socket, Error
	{
		vPortFree(pPingRequest);
		vPortFree(pPingReply);
		return 0;
	}

	setSn_PROTO(s,IP_PROTO_ICMP);           	// Set upper-protocol of IP protocol
	if( socket( s, Sn_MR_IPRAW, 3000, 0) == 0)	// Open IP_RAW Mode , if fail then Error
	{
		vPortFree(pPingRequest);
		vPortFree(pPingReply);
		return 0;
	}
	peerip = htonl( inet_addr(addr));				// convert address string into 32bit address

	xSerialPrintf_P(PSTR("\r\nPinging %s with %d bytes of data:\r\n"), addr, (sizeof(PING_MSG) - 8));


	/* Ping Service */
	while( count-- != 0)
	{
		IsReceived = 0;
		pPingRequest->seqNum = htons( RandomSeqNum++);	// Increase Sequence number for next ping-request packet
		pPingRequest->checksum = 0;
		pPingRequest->checksum = htons( checksum( (uint8_t*)pPingRequest, sizeof(PING_MSG)));	// update checksum field

		(*log).PingRequest++;							// Increase PingRequest's value

		xInitialTick = xTaskGetTickCount();

		if( sendto( s, (const uint8_t *)pPingRequest, sizeof(PING_MSG), (uint8_t*)&peerip, 3000)== 0)	// Send Ping-Request to the specified peer. If fail, then it is occurred ARP Error.
		{
			(*log).ARPErr++;							// Increase ARPErr
			close(s);									// close the pinging socket

			/* Reopen pinging socket */
			setSn_PROTO(s,IP_PROTO_ICMP);
			if(socket( s, Sn_MR_IPRAW, 3000, 0)==0)
				{
				vPortFree(pPingRequest);
				vPortFree(pPingReply);
				return 0;
				}
			continue;
		}

		while( xTaskGetTickCount() < (xInitialTick + ( time / portTICK_RATE_MS )) )	// as long as time is remaining
		{

			if((len = getSn_RX_RSR(s)) > 0)		// Has pinging socket received a packet?
			{
				len = recvfrom( s, (uint8_t*)pPingReply, len, (uint8_t*)&tempip, &port);	// receive a packet from unknown peer

				xSerialPrintf_P(PSTR("\r\nReply from %s"), inet_ntoa( ntohl(tempip))); // convert 32 bit unknown peer IP address into string of IP Address.

				if( checksum((uint8_t*)pPingReply,len) != 0)		// if the packet's checksum value is correct
				{                                                   // not correct
					(*log).CheckSumErr++;                           // checksum error
					if(tempip == peerip) IsReceived = 1;
					xSerialPrint_P(PSTR(": Checksum Error"));
				}
				else if(pPingReply->type == 0)					// if the received packet is ping-reply
				{

					if((pPingReply->id!=pPingRequest->id) || (pPingReply->seqNum!=pPingRequest->seqNum) || (tempip!=peerip)) // verify id,sequence nubmer, and ip address
					{
						xSerialPrint_P(PSTR(": Unmatched ID / SeqNum from peer"));			// fail to verify
						(*log).UnknownMSG++;
					}
					else                                                    // success
					{
						IsReceived = 1;
						xSerialPrintf_P(PSTR(": bytes=%d, time<=%dms"),len-8,(xTaskGetTickCount()-xInitialTick)*portTICK_RATE_MS );
						(*log).PingReply++;
					}
				}
				else if( pPingReply->type == 3)  					// If the packet is unreachable message
				{
					IsReceived = 1;
					xSerialPrint_P(PSTR(": Destination unreachable"));
					(*log).UnreachableMSG++;
				}
				else if( pPingReply->type == 11)                 	// If the packet is time exceeded message
				{
				        IsReceived = 1;
				        xSerialPrint_P(PSTR(": TTL expired in transit"));
					(*log).TimeExceedMSG++;
				}
				else if( pPingReply->type == 8)					// Send ping reply to a peer
				{
					xSerialPrint_P(PSTR(": Ping Request message"));
					SendPingReply(pPingReply,tempip);
				}
				else                                                            // if the packet is unknown message
				{
					xSerialPrintf_P(PSTR(": Unknown message (type = 0x%02X)"), pPingReply->type);
					(*log).UnknownMSG++;
				}
			}
			else if(getSn_SR(s)==SOCK_CLOSED) 				// if it is occurred to fail to send arp packet
			{
				(*log).ARPErr++;
				close(s);									// close the pinging socket

				setSn_PROTO( s, IP_PROTO_ICMP);             // reopen the pinging socket
				if(socket( s, Sn_MR_IPRAW, 3000, 0) == 0 )
					{
					vPortFree(pPingRequest);
					vPortFree(pPingReply);
					return 0;
					}
				break;
			}
			if((xTaskGetTickCount() >= (xInitialTick + ( time / portTICK_RATE_MS ))) && (IsReceived == 0))					// If it is not received packet from the specified peer during waiting ping-reply packet.
			{
				(*log).Loss++;
				xSerialPrint_P(PSTR("Request timed out\r\n"));
			}

		}
	}

	/* Release pinging socket */
	setSn_PROTO(s,0);
	close(s);
	vPortFree(pPingRequest);
	vPortFree(pPingReply);
	return 1;
}
Beispiel #13
0
/**
 * Checks whether the a connected USB device is an HID device and populates a configuration record if it is.
 *
 * @param device USB device.
 * @param protocol desired protocol for endpoint (keyboard or mouse).
 * @param handle pointer to a configuration record. The endpoint device address, protocol (keyboard or mouse), and endpoint information will be stored here.
 * @return true if the device is an HID device. Assume Configuration 0 exactly 1 configuration is allowed.
 */
static uint8_t hid_isHIDDevice(usb_device * device, uint8_t protocol, hid_usbConfiguration * handle)
{
	uint8_t ret = false;
	uint8_t buf[MAX_BUF_SIZE];
	int16_t bytesRead;

	// Read the length of the configuration descriptor.
	bytesRead = usb_getConfigurationDescriptor(device, 0, MAX_BUF_SIZE, buf);
	if (bytesRead<0) return false;

	uint16_t pos = 0;
	uint8_t descriptorLength;
	uint8_t descriptorType;

	usb_configurationDescriptor * config = NULL;
	usb_interfaceDescriptor * interface = NULL;
	usb_endpointDescriptor * endpoint = NULL;

	while (pos < bytesRead)
	{
		descriptorLength = buf[pos];
		descriptorType = buf[pos + 1];

		switch (descriptorType)
		{
		case (USB_DESCRIPTOR_CONFIGURATION):
			config = (usb_configurationDescriptor *)(buf + pos);
			break;

		case (USB_DESCRIPTOR_INTERFACE):
			interface = (usb_interfaceDescriptor *)(buf + pos);

			if ( usb_isHIDInterface(interface) && (interface->bInterfaceProtocol == protocol))
			{

				handle->configuration = config->bConfigurationValue;
				handle->interface = interface->bInterfaceNumber;

				// Detected requested HID interface!
				ret = true;

#ifdef DEBUG
				xSerialPrintf_P(PSTR("HID Interface Descriptor parsed. 0x%02X\r\n"), interface->bInterfaceProtocol);
#endif

			}
			break;

		case (USB_DESCRIPTOR_ENDPOINT):
			endpoint = (usb_endpointDescriptor *)(buf + pos);

			// If this endpoint descriptor is found right after the HID interface descriptor, it belongs to that interface.
			if (interface->bInterfaceNumber == handle->interface)
			{
				if (endpoint->bEndpointAddress & 0x80)
				{
					handle->inputEndPointAddress = endpoint->bEndpointAddress & ~0x80;
#ifdef DEBUG
					xSerialPrintf_P(PSTR("HID INPUT Endpoint Descriptor parsed. 0x%02X\r\n"), handle->inputEndPointAddress);
#endif
				}else{
					handle->outputEndPointAddress = endpoint->bEndpointAddress;
#ifdef DEBUG
					xSerialPrintf_P(PSTR("HID OUTPUT Endpoint Descriptor parsed. 0x%02X\r\n"), handle->outputEndPointAddress);
#endif
				}
			}


			break;

		default:
			break;
		}

		pos += descriptorLength;
	}

	return ret;

}
Beispiel #14
0
/**
 * Sends a control request to a USB device.
 *
 * @param device USB device to send the control request to.
 * @param requestType request type (in/out).
 * @param request request.
 * @param valueLow low byte of the value parameter.
 * @param valueHigh high byte of the value parameter.
 * @param index index.
 * @param length number of bytes to transfer.
 * @param data data to send in case of output transfer, or reception buffer in case of input. If no data is to be exchanged this should be set to NULL.
 * @return 0 on success, error code otherwise
 */
int usb_controlRequest(
		usb_device * device,
		uint8_t requestType,
		uint8_t request,
		uint8_t valueLow,
		uint8_t valueHigh,
		uint16_t index,
		uint16_t length,
		uint8_t * data)
{
	boolean direction = false; //request direction, IN or OUT
	uint8_t rcode;
	usb_setupPacket setup_pkt;

	// Set device address.
	max3421e_write(MAX_REG_PERADDR, device->address);

	if (requestType & 0x80)
		direction = true; //determine request direction

	// Build setup packet.
	setup_pkt.bmRequestType = requestType;
	setup_pkt.bRequest = request;
	setup_pkt.wValue = valueLow | (valueHigh << 8);
	setup_pkt.wIndex = index;
	setup_pkt.wLength = length;

	// Write setup packet to the FIFO and dispatch
	max3421e_writeMultiple(MAX_REG_SUDFIFO, 8, (uint8_t *) &setup_pkt);
	rcode = usb_dispatchPacket(tokSETUP, &(device->control), USB_NAK_LIMIT);

	// Print error in case of failure.
	if (rcode)
	{
		xSerialPrintf_P(PSTR("Setup packet error: 0x%02x @ Tick: %u\r\n"), rcode, xTaskGetTickCount());
		return -1;
	}

	// Data stage, if present
	if (data != NULL)
	{
		rcode = usb_ctrlData(device, direction, length, data);

		// If unsuccessful, return error.
		if (rcode<0)
		{
			xSerialPrintf_P(PSTR("\r\nData packet error: 0x%02x @ Tick: %u\r\n"), rcode, xTaskGetTickCount());
			return -2;
		}
	}

	// Status stage.
	if (direction)
		rcode = usb_dispatchPacket(tokOUTHS, &(device->control), USB_NAK_LIMIT);
	else
		rcode = usb_dispatchPacket(tokINHS, &(device->control), USB_NAK_LIMIT);

	if (rcode)
		return -3;
	else
		return 0;
}
Beispiel #15
0
/**
 * Performs an in transfer from a USB device from an arbitrary endpoint.
 *
 * @param device USB bulk device.
 * @param device length number of bytes to read.
 * @param data target buffer.
 * @return number of bytes read, or error code in case of failure.
 */
int usb_read(usb_device * device, usb_endpoint * endpoint, uint16_t length, uint8_t * data, unsigned int nakLimit)
{
	uint16_t rcode, bytesRead;
	uint16_t maxPacketSize = endpoint->maxPacketSize;

	unsigned int totalTransferred = 0;

	// Set device address.
	max3421e_write(MAX_REG_PERADDR, device->address);

	// Set toggle value.
	max3421e_write(MAX_REG_HCTL, endpoint->receiveToggle);

	while (1)
	{

		// Start IN transfer
		rcode = usb_dispatchPacket(tokIN, endpoint, nakLimit);

		if (rcode)
		{
			if (rcode != hrNAK)
				xSerialPrintf_P(PSTR("usb_read: dispatch error %d @ Tick: %u\r\n"), rcode, xTaskGetTickCount());

			return -1;
		}

		// Assert that the RCVDAVIRQ bit in register MAX_REG_HIRQ is set.
		if ((max3421e_read(MAX_REG_HIRQ) & bmRCVDAVIRQ) == 0)
		{
			xSerialPrintf_P(PSTR("usb_read: toggle error? %d @ Tick: %u\r\n"), rcode, xTaskGetTickCount());

			// TODO: the absence of RCVDAVIRQ indicates a toggle error. Need to add handling for that.
			return -2;
		}

		// Obtain the number of bytes in FIFO.
		bytesRead = max3421e_read(MAX_REG_RCVBC);

		// Read the data from the FIFO.
		data = max3421e_readMultiple(MAX_REG_RCVFIFO, bytesRead, data);

		// Clear the interrupt to free the buffer.
		max3421e_write(MAX_REG_HIRQ, bmRCVDAVIRQ);

		totalTransferred += bytesRead;

		// Check if we're done reading. Either we've received a 'short' packet (<maxPacketSize), or the
		// desired number of bytes has been transferred.
		if ((bytesRead < maxPacketSize) || (totalTransferred >= length))
		{
			// Remember the toggle value for the next transfer.
			if (max3421e_read(MAX_REG_HRSL) & bmRCVTOGRD)
				endpoint->receiveToggle = bmRCVTOG1;
			else
				endpoint->receiveToggle = bmRCVTOG0;

			// Break out of the loop.
			break;
		}
	}

	// Report success.
	return totalTransferred;
}
Beispiel #16
0
static void TaskMonitor(void *pvParameters) // Monitor for Serial Interface
{
    (void) pvParameters;

	uint8_t *ptr;
	int32_t p1;

	// create the buffer on the heap (so they can be moved later).
	if(LineBuffer == NULL) // if there is no Line buffer allocated (pointer is NULL), then allocate buffer.
		if( !(LineBuffer = (uint8_t *) pvPortMalloc( sizeof(uint8_t) * LINE_SIZE )))
			xSerialPrint_P(PSTR("pvPortMalloc for *LineBuffer fail..!\r\n"));


    while(1)
    {
    	xSerialPutChar(&xSerialPort, '>');

		ptr = LineBuffer;
		get_line(ptr, (uint8_t)(sizeof(uint8_t)* LINE_SIZE)); //sizeof (Line);

		switch (*ptr++) {

		case 'h' : // help
			xSerialPrint_P( PSTR("rt - reset maximum & minimum temperatures\r\n") );
			xSerialPrint_P( PSTR("t  - show the time\r\n") );
			xSerialPrint_P( PSTR("t  - set the time\r\nt [<year yy> <month mm> <date dd> <day: Sun=0> <hour hh> <minute mm> <second ss>]\r\n") );
			break;

#ifdef portRTC_DEFINED
		case 't' :	/* t [<year yy> <month mm> <date dd> <day: Sun=0> <hour hh> <minute mm> <second ss>] */

			if (xatoi(&ptr, &p1)) {
				SetTimeDate.tm_year = (uint8_t)p1 + 100; 			// convert to (Gregorian - 1900)
				xatoi(&ptr, &p1); SetTimeDate.tm_mon = (uint8_t)p1;
				xatoi(&ptr, &p1); SetTimeDate.tm_mday = (uint8_t)p1;
				xatoi(&ptr, &p1); SetTimeDate.tm_wday = (uint8_t)p1;
				xatoi(&ptr, &p1); SetTimeDate.tm_hour = (uint8_t)p1;
				xatoi(&ptr, &p1); SetTimeDate.tm_min = (uint8_t)p1;
				if (!xatoi(&ptr, &p1))
					break;
				SetTimeDate.tm_sec = (uint8_t)p1;

				xSerialPrintf_P(PSTR("Set: %u/%u/%u %2u:%02u:%02u\r\n"), SetTimeDate.tm_year, SetTimeDate.tm_mon, SetTimeDate.tm_mday, SetTimeDate.tm_hour, SetTimeDate.tm_min, SetTimeDate.tm_sec);
				if (setDateTimeDS1307( &SetTimeDate ) == pdTRUE)
					xSerialPrint_P( PSTR("Setting successful\r\n") );

			} else {

				if (getDateTimeDS1307( &xCurrentTempTime.DateTime) == pdTRUE)
					xSerialPrintf_P(PSTR("Current: %u/%u/%u %2u:%02u:%02u\r\n"), xCurrentTempTime.DateTime.tm_year + 1900, xCurrentTempTime.DateTime.tm_mon, xCurrentTempTime.DateTime.tm_mday, xCurrentTempTime.DateTime.tm_hour, xCurrentTempTime.DateTime.tm_min, xCurrentTempTime.DateTime.tm_sec);
			}
			break;
#endif

		case 'r' : // reset
			switch (*ptr++) {
			case 't' : // temperature

				xMaximumTempTime = xCurrentTempTime;
				xMinimumTempTime = xCurrentTempTime;
				// Now we commit the time and temperature to the EEPROM, forever...
				eeprom_update_block(&xMaximumTempTime, &xMaximumEverTempTime, sizeof(xRTCTempArray));
				eeprom_update_block(&xMinimumTempTime, &xMinimumEverTempTime, sizeof(xRTCTempArray));
				break;

			default :
				break;
			}
			break;

		default :
			break;
		}
// 		xSerialPrintf_P(PSTR("\r\nSerial Monitor: Stack HighWater @ %u"), uxTaskGetStackHighWaterMark(NULL));
//		xSerialPrintf_P(PSTR("\r\nFree Heap Size: %u\r\n"), xPortGetMinimumEverFreeHeapSize() ); // needs heap_1, heap_2 or heap_4 for this function to succeed.

    }

}
//void main(int argc, char ** argv) {
void TaskKermit(void *pvParameters) // Operate the Kermit Server
{
	(void) pvParameters;

    int status, rx_len, i, x;
    char c;
    UCHAR *inbuf;
    short r_slot;

    parity = P_PARITY;                  /* Set this to desired parity */
    status = X_OK;                      /* Initial kermit status */

    xargc = argc;
    xargv = argv;
    xname = argv[0];

    while (--xargc > 0) {		/* Loop through command-line words */
	xargv++;
	if (**xargv == '-') {		/* Have dash */
	    c = *(*xargv+1);		/* Get the option letter */
	    x = doarg(c);		/* Go handle the option */
	    if (x < 0) doexit(FAILURE);
    	} else {			/* No dash where expected */
	    fatal("Malformed command-line option: '",*xargv,"'");
	}
    }
    if (!action)			/* Nothing to do, give usage message */
      usage();

#ifdef DEBUG
    debug(DB_LOG,"SIMULATED ERROR RATE:",0,errorrate);
    if (errorrate) srand(seed);		/* Init random error generator */
#endif /* DEBUG */

/* THE REAL STUFF IS FROM HERE DOWN */

	xSerialPrintf_P(PSTR("\r\nFree Heap Size: %u"),xPortGetMinimumEverFreeHeapSize() ); // needs heap_1.c, heap_2.c or heap_4.c
	xSerialPrintf_P(PSTR("\r\nKermit HighWater: %u\r\n"), uxTaskGetStackHighWaterMark(NULL));

	spiBegin(SDCard);						// initialise the SPI bus for Kermit Server SD Card use.
	spiSelect (SDCard);

    if (!devopen("dummy"))		/* Open the communication device */
      doexit(FAILURE);
    if (!devsettings("dummy"))		/* Perform any needed settings */
      doexit(FAILURE);
    if (db)				/* Open debug log if requested */
      debug(DB_OPN,"debug.log",0,0);

    debug(DB_MSG,"Initializing...",0,0);

/*  Fill in parameters for this run */

    k.xfermode = xmode;			/* Text/binary automatic/manual  */
    k.remote = remote;			/* Remote vs local */
    k.binary = ftype;			/* 0 = text, 1 = binary */
    k.parity = parity;          /* Communications parity */
    k.bct = (check == 5) ? 3 : check;	/* Block check type */
    k.ikeep = keep;			    /* Keep incompletely received files */
    k.filelist = cmlist;		/* List of files to send (if any) */
    k.cancel = 0;			    /* Not cancelled yet */

/*  Fill in the i/o pointers  */

    k.zinbuf = i_buf;			/* File input buffer */
    k.zinlen = IBUFLEN;			/* File input buffer length */
    k.zincnt = 0;			    /* File input buffer position */
    k.obuf = o_buf;			    /* File output buffer */
    k.obuflen = OBUFLEN;		/* File output buffer length */
    k.obufpos = 0;			    /* File output buffer position */

/* Fill in function pointers */

    k.rxd    = readpkt;			/* for reading packets */
    k.txd    = tx_data;			/* for sending packets */
    k.ixd    = inchk;			/* for checking connection */
    k.openf  = openfile;        /* for opening files */
    k.finfo  = fileinfo;        /* for getting file info */
    k.readf  = readfile;		/* for reading files */
    k.writef = writefile;       /* for writing to output file */
    k.closef = closefile;       /* for closing files */
#ifdef DEBUG
    k.dbf    = db ? dodebug : 0;	/* for debugging */
#else
    k.dbf    = 0;
#endif /* DEBUG */
    /* Force Type 3 Block Check (16-bit CRC) on all packets, or not */
    k.bctf   = (check == 5) ? 1 : 0;

/* Initialize Kermit protocol */

    status = kermit(K_INIT, &k, 0, 0, "", &r);
#ifdef DEBUG
    debug(DB_LOG,"init status:",0,status);
    debug(DB_LOG,"version:",k.version,0);
#endif /* DEBUG */
    if (status == X_ERROR)
      doexit(FAILURE);
    if (action == A_SEND)
      status = kermit(K_SEND, &k, 0, 0, "", &r);
/*
  Now we read a packet ourselves and call Kermit with it.  Normally, Kermit
  would read its own packets, but in the embedded context, the device must be
  free to do other things while waiting for a packet to arrive.  So the real
  control program might dispatch to other types of tasks, of which Kermit is
  only one.  But in order to read a packet into Kermit's internal buffer, we
  have to ask for a buffer address and slot number.

  To interrupt a transfer in progress, set k.cancel to I_FILE to interrupt
  only the current file, or to I_GROUP to cancel the current file and all
  remaining files.  To cancel the whole operation in such a way that the
  both Kermits return an error status, call Kermit with K_ERROR.
*/
    while (status != X_DONE) {
/*
  Here we block waiting for a packet to come in (unless readpkt times out).
  Another possibility would be to call inchk() to see if any bytes are waiting
  to be read, and if not, go do something else for a while, then come back
  here and check again.
*/
        inbuf = getrslot(&k,&r_slot);	/* Allocate a window slot */
        rx_len = k.rxd(&k,inbuf,P_PKTLEN); /* Try to read a packet */
        debug(DB_PKT,"main packet",&(k.ipktbuf[0][r_slot]),rx_len);
/*
  For simplicity, kermit() ACKs the packet immediately after verifying it was
  received correctly.  If, afterwards, the control program fails to handle the
  data correctly (e.g. can't open file, can't write data, can't close file),
  then it tells Kermit to send an Error packet next time through the loop.
*/
        if (rx_len < 1) {               /* No data was read */
            freerslot(&k,r_slot);	/* So free the window slot */
            if (rx_len < 0)             /* If there was a fatal error */
              doexit(FAILURE);          /* give up */

	    /* This would be another place to dispatch to another task */
	    /* while waiting for a Kermit packet to show up. */

        }
        /* Handle the input */

        switch (status = kermit(K_RUN, &k, r_slot, rx_len, "", &r)) {
	  case X_OK:
#ifdef DEBUG
/*
  This shows how, after each packet, you get the protocol state, file name,
  date, size, and bytes transferred so far.  These can be used in a
  file-transfer progress display, log, etc.
*/
	    debug(DB_LOG,"NAME",r.filename ? (char *)r.filename : "(NULL)",0);
	    debug(DB_LOG,"DATE",r.filedate ? (char *)r.filedate : "(NULL)",0);
	    debug(DB_LOG,"SIZE",0,r.filesize);
	    debug(DB_LOG,"STATE",0,r.status);
	    debug(DB_LOG,"SOFAR",0,r.sofar);
#endif /* DEBUG */
	    /* Maybe do other brief tasks here... */
	    continue;			/* Keep looping */
	  case X_DONE:
	    break;			/* Finished */
	  case X_ERROR:
	    doexit(FAILURE);		/* Failed */
	    break;
	}
    }
    doexit(SUCCESS);
}
Beispiel #18
0
/**
 @brief	parse http request from a peer
 */
void parse_http_request(
	HTTP_REQUEST *request, 	/**< request to be returned */
	uint8_t *buffer			/**< pointer to be parsed */
	)
{
	uint8_t *nexttok;
	nexttok = (uint8_t *)strtok((char *)buffer," ");
	if(!nexttok)
	{
		request->METHOD = METHOD_ERR;
		return;
	}
	if 	(!strcmp_P((const char *)nexttok, PSTR("GET")) || !strcmp_P((const char *)nexttok, PSTR("get")))
	{
		request->METHOD = METHOD_GET;
		nexttok = (uint8_t *)strtok(NULL," ");
#ifdef HTTP_DEBUG
		xSerialPrint_P(PSTR("METHOD_GET "));
#endif
	}
	else if (!strcmp_P((const char *)nexttok, PSTR("HEAD")) || !strcmp_P((const char *)nexttok, PSTR("head")))
	{
		request->METHOD = METHOD_HEAD;
		nexttok = (uint8_t *)strtok(NULL," ");
#ifdef HTTP_DEBUG
		xSerialPrint_P(PSTR("METHOD_HEAD "));
#endif

	}
	else if (!strcmp_P((const char *)nexttok, PSTR("POST")) || !strcmp_P((const char *)nexttok, PSTR("post")))
	{
		nexttok = (uint8_t *)strtok((char *)NULL,"\0");
		request->METHOD = METHOD_POST;
#ifdef HTTP_DEBUG
		xSerialPrint_P(PSTR("METHOD_POST "));
#endif
	}
	else
	{
		request->METHOD = METHOD_ERR;
#ifdef HTTP_DEBUG
		xSerialPrint_P(PSTR("METHOD_ERR "));
#endif
	}

	if(!nexttok)
	{
		request->METHOD = METHOD_ERR;
#ifdef HTTP_DEBUG
		xSerialPrint_P(PSTR("METHOD_ERR "));
#endif
		return;
	}

	strcpy((char *)request->URI,(const char *)nexttok);

#ifdef HTTP_DEBUG
	{
		uint16_t i;
		xSerialPrint_P(PSTR("\nhttp_request->URI: "));
		for(i=0; i < strlen((const char *)request->URI);i++)
			xSerialPrintf_P(PSTR("%c"),request->URI[i]);
		xSerialPrint_P(PSTR(""));
	}
#endif

}
/**
 @brief	Analyse HTTP request and then services WEB.
*/
void process_HTTP(
	SOCKET s, 			/**< http server socket */
	uint8_t * buffer, 	/**< buffer pointer included http request */
	uint16_t length		/**< length of http request */
	)
{
	uint8_t * name;
	uint16_t bytes_read;
	TickType_t wait_send;
	FIL source_file;	/* File object for the source file */

	parse_HTTP_request(pHTTPRequest, buffer);			// After analysing request, convert into pHTTPRequest

	/* method Analyse */
	switch (pHTTPRequest->METHOD)
	{
		case METHOD_HEAD:
		case METHOD_GET :
		case METHOD_POST :

			name = get_HTTP_URI_name(pHTTPRequest->URI);

			if (!strcmp((const char *)name, "/")) strcpy((char *)name,"index.htm");	// If URI is "/", respond by index.htm

#ifdef WEB_DEBUG
			if(strlen( (const char *)name) < MAX_INT_STR ) xSerialPrintf_P(PSTR("\r\nPAGE : %s "), name);
			else xSerialPrint_P(PSTR("\r\nFILENAME TOO LONG"));
#endif

			find_HTTP_URI_type(&pHTTPRequest->TYPE, name);	//Check file type (HTML, TEXT, ICO, GIF, JPEG, ZIP are included)

			// OK now we start to respond to the info we've decoded.

			/* Open the specified file stored in the SD card FAT32 */
			if (f_open(&source_file, (const TCHAR *)name, FA_OPEN_EXISTING | FA_READ))
			{	// if file open failure

				memcpy_P( (char *)pHTTPResponse, ERROR_HTML_PAGE, strnlen_P(ERROR_HTML_PAGE, FILE_BUFFER_SIZE) );

#ifdef WEB_DEBUG
				xSerialPrint_P(PSTR("HTTP Unknown file or page.\r\n"));
				xSerialPrintf_P(PSTR("HTTP Response...\r\n%s\r\nResponse Size: %u \r\n"), pHTTPResponse, strlen_P(ERROR_HTML_PAGE));
#endif

				send( s, (const uint8_t*)pHTTPResponse, strlen_P(ERROR_HTML_PAGE));

			}
			else
			{	// if file open success

				make_HTTP_response_header( pHTTPResponse, pHTTPRequest->TYPE, source_file.fsize);

#ifdef WEB_DEBUG
				xSerialPrintf_P(PSTR("HTTP Opened file: %s  Source Size: %u \r\n"), name, source_file.fsize);
				xSerialPrintf_P(PSTR("HTTP Response Header...\r\n%s\r\nResponse Header Size: %u \r\n"), pHTTPResponse, strlen((char*)pHTTPResponse ));
#endif

				send(s, (const uint8_t*)pHTTPResponse, strlen((char*)pHTTPResponse ));

				wait_send = xTaskGetTickCount();

				while(getSn_TX_FSR(s)!= WIZCHIP_getTxMAX(s))

				{
					if( (xTaskGetTickCount() - wait_send) > (WEBSERVER_SOCKET_TIMEOUT / portTICK_PERIOD_MS) ) // wait up to 1.5 Sec
					{
#ifdef WEB_DEBUG
						xSerialPrint_P(PSTR("HTTP Response head send fail\r\n"));
#endif
						break;
					}
					vTaskDelay( 0 ); // yield until next tick.
				}

				for (;;)
				{
					if ( f_read(&source_file, pHTTPResponse, (sizeof(uint8_t)*(FILE_BUFFER_SIZE) ), &bytes_read) || bytes_read == 0 )
						break;   // read error or reached end of file

					if(pHTTPRequest->TYPE == PTYPE_HTML) // if we've got a html document, there might be some system variables to set
					{
						*(pHTTPResponse + bytes_read + 1) = 0; // make the buffer a string, null terminated
						bytes_read = replace_sys_env_value(pHTTPResponse, bytes_read); // Replace html system environment value to real value
					}

					if (send(s, (const uint8_t*)pHTTPResponse, bytes_read) != bytes_read)
						break;  // TCP/IP send error

					wait_send = xTaskGetTickCount();

					while(getSn_TX_FSR(s)!= WIZCHIP_getTxMAX(s))

					{
						if( (xTaskGetTickCount() - wait_send) > (WEBSERVER_SOCKET_TIMEOUT / portTICK_PERIOD_MS) ) // wait up to 1.5 Sec
						{
#ifdef WEB_DEBUG
							xSerialPrint_P(PSTR("HTTP Response body send fail\r\n"));
#endif
							break;
						}
						vTaskDelay( 0 ); // yield until next tick.
					}
				}
				f_close(&source_file);

				eeprom_busy_wait();
				eeprom_update_dword( &pagesServed, eeprom_read_dword(&pagesServed) +1 );
			}
			break;

		case METHOD_ERR :

			memcpy_P( (char *)pHTTPResponse, ERROR_REQUEST_PAGE, strnlen_P(ERROR_REQUEST_PAGE, FILE_BUFFER_SIZE) );

#ifdef WEB_DEBUG
			xSerialPrint_P(PSTR("HTTP Method Error.\r\n"));
			xSerialPrintf_P(PSTR("HTTP Response...\r\n%s\r\nResponse Size: %u \r\n"), pHTTPResponse, strlen_P(ERROR_REQUEST_PAGE));
#endif

			send( s, (const uint8_t*)pHTTPResponse, strlen_P(ERROR_REQUEST_PAGE));

			break;

		default :
			break;
	}
}