IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(u32 command_address)
{
  SIOCtlVBuffer command_buffer(command_address);

  INFO_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str());
  INFO_LOG(OSHLE, "  Parameter: 0x%x", command_buffer.Parameter);
  INFO_LOG(OSHLE, "  NumberIn: 0x%08x", command_buffer.NumberInBuffer);
  INFO_LOG(OSHLE, "  NumberOut: 0x%08x", command_buffer.NumberPayloadBuffer);
  INFO_LOG(OSHLE, "  BufferVector: 0x%08x", command_buffer.BufferVector);
  DumpAsync(command_buffer.BufferVector, command_buffer.NumberInBuffer,
            command_buffer.NumberPayloadBuffer);

  Memory::Write_U32(0, command_address + 4);
  return GetNoReply();
}
Esempio n. 2
0
void XMLSERVERInterface(U8 *memory_map)
{
	data_len = W5x00.getRXReceivedSize(SRV_SOCK1);

	// If there are incoming data on the listened port
	if(data_len) 
	{	
		// Include debug functionalities, if required
		#if(XMLSERVER_DEBUG)
			XMLSERVER_LOG("(UDP/XML)Indata from controller<0x");
			XMLSERVER_LOG(data_len,HEX);
			XMLSERVER_LOG(">\r\n");		
		#endif
			
		// Retrieve data from the UDP socket
		data_len = recvfrom(SRV_SOCK1, buff, XML_REQBYTES, incoming_ip, &incoming_port);
		if(!data_len)
		{
			// Discard
			data_len = 0;
		
			// Reset the socket
			close(SRV_SOCK1);
			while(W5x00.readSnSR(SRV_SOCK1) != SnSR::CLOSED);
		
			// Init the socket
			socket(SRV_SOCK1, SnMR::UDP, ETH_PORT, 0);		// Open the socket		
		}
		
		// Include debug functionalities, if required
		#if(XMLSERVER_DEBUG)
			XMLSERVER_LOG("(UDP/XML)Indata <0x");
			XMLSERVER_LOG(data_len,HEX);
			XMLSERVER_LOG(">\r\n");		
		#endif
			
		#if(XMLSERVER_DEBUG)
			XMLSERVER_LOG("(UDP/XML)Instring buffer<");
			for(i=0;i<data_len;i++)
				XMLSERVER_LOG(buf[i]);

			XMLSERVER_LOG(">\r\n");					
		#endif
			
		// Move data into a string for parsing
		incomingURL = "";
		
		// 
		if(data_len < XML_REQBYTES)
		{
			for(i=0;i<data_len && buf[i] !=0;i++)						
				incomingURL = incomingURL + buf[i];	
				
			#if(XMLSERVER_DEBUG)
				XMLSERVER_LOG("(UDP/XML)incomingURL<");
				XMLSERVER_LOG(incomingURL);
				XMLSERVER_LOG(">\r\n");					
			#endif
			
			// Flag the incoming data and quit
			indata=1;	
		}	
		else
		{
			indata=0;
			
			#if(XMLSERVER_DEBUG)
			XMLSERVER_LOG("(UDP/XML)Bad request");
			#endif
		}
	}
	else
	{
		// If needed, restart the socket
		if(W5x00.readSnSR(SRV_SOCK1) != SnSR::UDP)
		{
			socket(SRV_SOCK1, SnMR::UDP, udpXML_inPORT, 0);	
		}		
	
		// Reset
		indata=0;
		
		// Send buffered commands
		command_send();			
	}
	
	// Look for data available from the LASTIN buffer
	if(MaCaco_isLastIn(memory_map))
	{
		#if(XMLSERVER_DEBUG)
			XMLSERVER_LOG("(UDP/XML)<LASTIN");
			XMLSERVER_LOG(">\r\n");								
		#endif		
	
		incomingURL = "GET /status";
		indata=1;
	}
	
	// Parse the incoming data
	if(indata)
    {	
		// Handler1, if /statusrequested from client	
		// an example command is "GET /status "
		if(incomingURL.startsWith("GET /status") || ((incomingURL.indexOf("GET /status",0) > 0)))
		{			
			// Init the buffer
			bufferlen=0;
		
		#if(XMLSERVER_DEBUG)
			XMLSERVER_LOG("(UDP/XML)<GET /status");
			XMLSERVER_LOG(">\r\n");								
		#endif			
	
			// Indentify if there are available data from LASTIN
			if(MaCaco_isLastIn(memory_map))
			{
				id_for = MaCaco_GetLastIn(memory_map);
				idx = MaCaco_GetLastIndex(memory_map, MaCaco_GetLastIn(memory_map));
			}
			else	// No data from LASTIN, load local data
			{
				// Store the node index
				*(memory_map+MaCaco_L_IDX_s) = 0;											// Local node has index 0
								
				// Store the data
				memmove((memory_map+MaCaco_L_OUT_s), (memory_map+MaCaco_OUT_s), MaCaco_SLOT);
			
				id_for = MaCaco_GetLastIn(memory_map);
				idx = MaCaco_GetLastIndex(memory_map, MaCaco_GetLastIn(memory_map));
			}
			
			// Print "<id"
			memmove(&buf[bufferlen],xml[3],strlen(xml[3]));
			bufferlen += strlen(xml[3]);

			// Print id number
			*(unsigned long*)(buf+bufferlen) = (unsigned long)id_for;
			ASCII_num2str((uint8_t*)(buf+bufferlen), DEC, (uint8_t*)(&bufferlen));						
			
			// Print ">"
			memmove(&buf[bufferlen],xml[1],strlen(xml[1]));
			bufferlen += strlen(xml[1]);
			
			for(U8 slot=0;slot<MaCaco_SLOT;slot++)
			{	
					// Print "<s"
					memmove(&buf[bufferlen],xml[0],strlen(xml[0]));
					bufferlen += strlen(xml[0]);
					
					// Print slot number
					*(unsigned long*)(buf+bufferlen) = (unsigned long)slot;
					ASCII_num2str((uint8_t*)(buf+bufferlen), DEC, (uint8_t*)(&bufferlen));						
					
					// Print ">"
					memmove(&buf[bufferlen],xml[1],strlen(xml[1]));
					bufferlen += strlen(xml[1]);

					/* 
						Typicals in group Souliss_T5n need conversion from half-precision float to string
					
							Using LASTIN all typicals in the 5n group shall be consecutive, only the first
							and the last 5n in the node is stored. Mixing different typical between 5n ones
							will result in floating point conversion of not floating point data.
					*/
					if((slot >= *(memory_map+MaCaco_L_TYP5n_s+2*id_for)) && (slot <= *(memory_map+MaCaco_L_TYP5n_s+2*id_for+1)))	
					{
						float f_val;
						
						f_val = Souliss_SinglePrecisionFloating(memory_map+(MaCaco_G_OUT_s+(idx*MaCaco_OUTLENGHT)+slot));
						ASCII_float2str((float)f_val, 2, &buf[bufferlen], HTTP_BUFBYTES);
						bufferlen = strlen(buf); 
					} 
					else // All others values are stored as unsigned byte
					{
						// Print "val" value
						*(unsigned long*)(buf+bufferlen) = (unsigned long)memory_map[MaCaco_G_OUT_s+(idx*MaCaco_OUTLENGHT)+slot];
						ASCII_num2str((uint8_t*)(buf+bufferlen), DEC, (uint8_t*)(&bufferlen));						
					}
							
					// Print "</slot"
					memmove(&buf[bufferlen],xml[2],strlen(xml[2]));
					bufferlen += strlen(xml[2]);
					
					// Print slot number
					*(unsigned long*)(buf+bufferlen) = (unsigned long)slot;
					ASCII_num2str((uint8_t*)(buf+bufferlen), DEC, (uint8_t*)(&bufferlen));						
					
					// Print ">"
					memmove(&buf[bufferlen],xml[1],strlen(xml[1]));
					bufferlen += strlen(xml[1]);
			}

			// Print "</id"
			memmove(&buf[bufferlen],xml[4],strlen(xml[4]));
			bufferlen += strlen(xml[4]);

			// Print id number
			*(unsigned long*)(buf+bufferlen) = (unsigned long)id_for;
			ASCII_num2str((uint8_t*)(buf+bufferlen), DEC, (uint8_t*)(&bufferlen));						
			
			// Print ">"
			memmove(&buf[bufferlen],xml[1],strlen(xml[1]));
			bufferlen += strlen(xml[1]);
									
			// Send the UDP/XML frame
			sendto(SRV_SOCK1, buff, bufferlen, incoming_ip, udpXML_outPORT);
			
			// At this point we reset all the subscription channels, in this way next time
			// there will be fresh data
			MaCaco_subscribe_reset();
		}
	
		// Handler2, if /force is requested from client	
		// an example command is "GET /force?id=4&slot=2&val=1 "
		if(incomingURL.startsWith("GET /force") || ((incomingURL.indexOf("GET /force",0) > 0)))
		{			
			// Include debug functionalities, if required
			#if(XMLSERVER_DEBUG)
				XMLSERVER_LOG("(UDP/XML)<GET /force");
				XMLSERVER_LOG(data_len,HEX);
				XMLSERVER_LOG(">\r\n");		
			#endif		
		
			// Find start and end index for callback request
			U8 force  = incomingURL.indexOf("force",0);
			if(incomingURL.indexOf("?id=",force) > 0)
			{						
				U8 id   = incomingURL.indexOf("?id=",force);		
				U8 slot = incomingURL.indexOf("&slot=", id);		
				U8 val_s  = incomingURL.indexOf("&val=", slot);		
				id = incomingURL.substring(id+4, slot).toInt();				// Sum length of "?id="
				slot = incomingURL.substring(slot+6, val_s).toInt();		// Sum length of "&slot="
								
				// This buffer is used to load values
				U8 valf[MAXVALUES];
				U8 vals[MAXVALUES];
				for(i=0;i<MAXVALUES;i++)	vals[i]=0;
				
				// Identify how many values (up to 5) are provided
				valf[0]  = incomingURL.indexOf(",", val_s);
				if(valf[0] != 0xFF)
				{
					// Buffer used to store offset of values
					for(i=0;i<MAXVALUES;i++)	valf[i]=0;
					
					// Get the offset of all values
					for(i=1;i<MAXVALUES;i++)
						valf[i]  = incomingURL.indexOf(",", valf[i-1]+1);
					
					vals[0] = incomingURL.substring(val_s+5, valf[0]).toInt();			// Sum length of "&val="						
					for(i=1;i<MAXVALUES;i++)
						vals[i] = incomingURL.substring(valf[i-1]+1, valf[i]).toInt();	// Sun the length of ","
				}
				else
				{		
					// Just one values
					U8 val_f  = incomingURL.indexOf(" ", val_s);					// Command should end with a space	
					
					// Convert to number
					vals[0] = incomingURL.substring(val_s+5, val_f).toInt();	// Sum length of "&val="						
				}
			
			
			#if(XMLSERVER_DEBUG)
				XMLSERVER_LOG("(UDP/XML)<GET /force");
				XMLSERVER_LOG(">\r\n");		
				
				XMLSERVER_LOG("(UDP/XML)<id=");
				XMLSERVER_LOG(id,DEC);
				XMLSERVER_LOG(">\r\n");		
				
				XMLSERVER_LOG("(UDP/XML)<slot=");
				XMLSERVER_LOG(slot,DEC);
				XMLSERVER_LOG(">\r\n");		
				
				XMLSERVER_LOG("(UDP/XML)<val=");
				XMLSERVER_LOG(val_s,DEC);
				XMLSERVER_LOG(">\r\n");		
			
				for(i=0;i<MAXVALUES;i++)
				{				
					XMLSERVER_LOG("<");		
					XMLSERVER_LOG(vals[i]);
					XMLSERVER_LOG(">\r\n");		
				}
				XMLSERVER_LOG("id=<");
				XMLSERVER_LOG(id);
				XMLSERVER_LOG(">\r\n");		
				XMLSERVER_LOG("slot=<");
				XMLSERVER_LOG(slot);
				XMLSERVER_LOG(">\r\n");		
			#endif				
			
				// Send a command to the node	
				if((id < MaCaco_NODES) && (id != MaCaco_LOCNODE) && (C8TO16(memory_map + MaCaco_ADDRESSES_s + 2*id) != 0x0000))	// If is a remote node, the command act as remote input				
					command_buffer(C8TO16(memory_map + MaCaco_ADDRESSES_s + 2*id), slot, vals);
				else if (id == MaCaco_LOCNODE)								// If is a local node (me), the command is written back
				{
					i = 0;
					while((vals[i] != 0) && (i < MAXVALUES))
					{
						#if(XMLSERVER_DEBUG)
							XMLSERVER_LOG("slot-vals=<");
							XMLSERVER_LOG(slot);
							XMLSERVER_LOG(" ");
							XMLSERVER_LOG(vals[i]);
							XMLSERVER_LOG(">\r\n");
						#endif		
						memory_map[MaCaco_IN_s+slot] = vals[i];
						slot++;
						i++;
					}
				}					
			}
			else if(incomingURL.indexOf("?typ=",force) > 0)
			{
				U8 typ_mask;
				U8 typ   = incomingURL.indexOf("?typ=",force);
				U8 val_s  = incomingURL.indexOf("&val=", typ);		
				U8 val_f  = incomingURL.indexOf(" ", val_s);				// Command should end with a space	
				typ = incomingURL.substring(typ+5, val_s).toInt();			// Sum length of "?typ="
				val_s = incomingURL.substring(val_s+5, val_f).toInt();		// Sum length of "&val="								

			#if(XMLSERVER_DEBUG)
				XMLSERVER_LOG("(UDP/XML)<GET /typ");
				XMLSERVER_LOG(">\r\n");		
			
				XMLSERVER_LOG("(UDP/XML)<val=");
				XMLSERVER_LOG(val_s,DEC);
				XMLSERVER_LOG(">\r\n");		
			#endif		
				
				U8* val_sp = &val_s;
				
				// Send a multicast command to all typicals, first identify if the command is issued
				// for a typical or a typical class
				if((typ & 0x0F) == 0x00)
					typ_mask = 0xF0;	// We look only to the typical class value
				else
					typ_mask = 0xFF;	// We look to whole typical value
				
				// Look for all slot assigned to this typical and put value in
				for(U8 id=0;id<MaCaco_NODES;id++)
				{						
					// Send a command to the node	
					if((id != MaCaco_LOCNODE) && (C8TO16(memory_map + MaCaco_ADDRESSES_s + 2*id)) != 0x0000))	// If is a remote node, the command act as remote input								
						MaCaco_send(C8TO16(memory_map + MaCaco_ADDRESSES_s + 2*id), MaCaco_TYP, 0, typ, 1, val_sp);		
					else if (id == MaCaco_LOCNODE)																	// If is a local node (me), the command is written back
					{
						U8 typ_mask;
						
						// Identify if the command is issued for a typical or a typical class
						if((typ & 0x0F) == 0x00)
							typ_mask = 0xF0;	// we look only to the typical class value
						else
							typ_mask = 0xFF;	// we look to whole typical value
					
						for(i=0; i<MaCaco_SLOT; i++)		
							if((*(memory_map + MaCaco_TYP_s + i) & typ_mask) == typ)	// Start offset used as typical logic indication
								*(memory_map+MaCaco_IN_s + i) = val_s;
					}
				}
			}