const SimpleString CommonServiceValues::GetOmiscidServiceDnsSdType()
{
	static SimpleString OmiscidServiceDnsSdType;

	if ( OmiscidServiceDnsSdType.IsEmpty() )
	{
		SimpleString DefaultDomain = "_bip._tcp";

		char * Option = getenv( "OMISCID_WORKING_DOMAIN" );
		if ( Option == NULL || DefaultDomain == Option )
		{
			OmiscidServiceDnsSdType = DefaultDomain;
			OmiscidTrace( "OMiSCID working domain not override. Use '%s'.\n", DefaultDomain.GetStr() );
			return OmiscidServiceDnsSdType;
		}

		// Copy the environment variable
		size_t size = strlen( Option );
		TemporaryMemoryBuffer tmpdomain(128);

		if ( size >= RegtypeLength )
		{
			SimpleString Msg = "OMiSCID working domain '";
			Msg += Option;
			Msg += "' too long (";
			Msg += (RegtypeLength-1);
			Msg += ")";

			// Set default domain in cas of exception catch 
			OmiscidServiceDnsSdType = DefaultDomain;
			
			OmiscidError( Msg.GetStr() );
			throw SimpleException( Msg );
		}

		if ( sscanf( Option, "_bip_%[^.]._tcp", (char*)tmpdomain) == 1 )
		{
			// Set default domain in cas of exception catch 
			OmiscidServiceDnsSdType = DefaultDomain;
			
			OmiscidError( "Old style OMiSCID working domain, please conform to new 'XXX._bip._tcp' pattern" );
			throw SimpleException( "Old style OMiSCID working domain, please conform to new 'XXX._bip._tcp' pattern" );
		}

		if ( sscanf( Option, "%[^.]._bip._tcp", (char*)tmpdomain) == 1 )
		{
			OmiscidServiceDnsSdType = Option;
			OmiscidTrace( "OMISCID_WORKING_DOMAIN defined in environment variable. Use '%s'.\n", OmiscidServiceDnsSdType.GetStr() );
			return OmiscidServiceDnsSdType;
		}

		// OMiSCID Domain simplest way to define it
		OmiscidServiceDnsSdType = Option;
		OmiscidTrace( "OMISCID_WORKING_DOMAIN defined in environment variable. Use '%s'.\n", OmiscidServiceDnsSdType.GetStr() );
	}

	return OmiscidServiceDnsSdType;
}
SimpleException::SimpleException(const SimpleString m, int i)
{
	OmiscidTrace( "%s : %d\n", m.GetStr(), i );

	msg = m;
	err = i;
}
void ControlServer::Connect(const SimpleString host, int port, bool tcp, InOutputAttribute* ioa)
{
#ifdef DEBUG
	fprintf(stderr, "in ControlServer::Connect (%s:%d", host.GetStr(), port);
	if (tcp) fprintf(stderr, " [TCP] "); else fprintf(stderr, " [UDP] ");
	fprintf(stderr, "%s\n", ioa->GetName().GetStr());
#endif
}
RegisterOmiscidService::RegisterOmiscidService( const SimpleString FullName, uint16_t ePort, bool AutoRegister /* = false */ )
	: RegisterService( FullName, ePort, /* AutoRegister = */ false, /* AutoRename */ false )
{
	if ( strstr( FullName.GetStr(), GetOmiscidServiceDnsSdType().GetStr() ) == NULL )
	{
		throw ServiceException( "It do not seem to be a valid BIP service" );
	}

	Init(AutoRegister);
}
Beispiel #5
0
void Attribute::GenerateHeaderDescription(const SimpleString& type,
										  const SimpleString& name,
										  SimpleString& str,
										  bool end)
{
	// "<"+ type + " name=\"" + name + "\"/>" at max
	TemporaryMemoryBuffer MemBuff( 1 + type.GetLength() + 7 + name.GetLength() + 4 );
	if ( end == true )
	{
		snprintf( (char*)MemBuff, MemBuff.GetLength(), "<%s name=\"%s\"/>", type.GetStr(), name.GetStr() );
	}
	else
	{
		snprintf( (char*)MemBuff, MemBuff.GetLength(), "<%s name=\"%s\">", type.GetStr(), name.GetStr() );
	}

	str += (char*)MemBuff;

	//str = str + "<"+ type + " name=\"" + name;
	//if(end) str = str + "\"/>";
	//else  str = str + "\">";
}
Beispiel #6
0
bool ServiceProxy::GetConnectionInfos( const SimpleString Connector, ConnectionInfos& Connection )
{
	InOutputAttribute * pAtt = FindConnector( Connector );
	if ( pAtt == (InOutputAttribute *)NULL )
	{
		OmiscidError( "Could not find connector nammed '%s'\n", Connector.GetStr() );
		return false;
	}

	Connection.TcpPort = pAtt->GetTcpPort();
	Connection.UdpPort = pAtt->GetUdpPort();
	Connection.Type	   = pAtt->GetType();

	return true;
}
void ControlServer::VariableChange( VariableAttribute* va, SimpleString NewValue, ControlServerStatus status )
{
	OmiscidTrace( "ControlServer::VariableChange '%s' New Value='%s'\n", va->GetName().GetStr(), NewValue.GetStr());
	// Do what we must do...

	// va will call back me to know if I agree to change it's value
	// va will also notify me that the value has changed (if change have been validated)
	va->SetValue( NewValue );
}
void ControlServer::ProcessAMessage(XMLMessage* msg)
{
	// OmiscidTrace( "in ControlServer::ProcessAMessage\n");
	// OmiscidTrace( "from pid = %u \n",msg->pid);

	if ( msg == NULL )
	{
		// Nothing to do
		return;
	}

	xmlNodePtr node = msg->GetRootNode();

	SmartLocker SL_AutoProtect(AutoProtect);

	// if( strcmp((const char*)node->name, "controlQuery") == 0 )
	if ( ControlQueryValidator.ValidateDoc(msg->doc) )
	{
		SL_AutoProtect.Unlock();

		SimpleString id;
		xmlAttrPtr attr = XMLMessage::FindAttribute("id", node);
		if ( attr != (xmlAttrPtr)NULL )
		{
			id = SimpleString((const char*)attr->children->content);
		}

		bool ReplyAnAnswer = true;	// default
		SimpleString str;

		if ( node->children == NULL )
		{
			//global description
			GenerateGlobalShortDescription(str);
		}
		else
		{
			// more precise request
			xmlNodePtr cur_node = node->children;
			for(; cur_node; cur_node = cur_node->next)
			{
				SimpleString name = (const char*)(cur_node->name);
				//std::cerr << "tag name="<<(*it)->name <<"\n";
				if( name == InOutputAttribute::input_str.GetStr() ||
					name == InOutputAttribute::output_str.GetStr() ||
					name == InOutputAttribute::inoutput_str.GetStr() )
				{
					// OmiscidTrace( " process io : %s \n", (*it)->name.GetStr());
					ProcessInOutputQuery(cur_node, str);
				}
				else if( name == VariableAttribute::VariableStr )
				{
					ProcessVariableQuery(cur_node, msg->pid,  str);
				}
				else if( name == "connect" )
				{
					ProcessConnectQuery(cur_node, str);
				}
				else if( name == "subscribe" )
				{
					ProcessSubscribeQuery(cur_node, msg->pid, true, str);
				}
				else if( name == "unsubscribe" )
				{
					ReplyAnAnswer = false;
					ProcessSubscribeQuery(cur_node, msg->pid, false, str);
				}
				else if( name == "lock" )
				{
					ProcessLockQuery(cur_node, msg->pid, true, str);
				}
				else if( name == "unlock" )
				{
					ProcessLockQuery(cur_node, msg->pid, false, str);
				}
				else if( name == "fullDescription" )
				{
					ProcessFullDescriptionQuery(cur_node, str);
				}
				else
				{
					// Should not appear
					OmiscidError( "unknown tag : %s\n", name.GetStr() );
				}
			}
			// OmiscidError( "Send : %s \n", str.GetStr());
		}

		if ( ReplyAnAnswer == true )
		{
			str = "<controlAnswer id=\""+id+"\">"
				+ str
				+ "</controlAnswer>";

#ifdef DEBUG
			SL_AutoProtect.Lock();
			if ( ControlAnswerValidator.ValidateDoc( str ) == false )
			{
				OmiscidError( "ControlServer::ProcessAMessage: bad ControlAnswer sent.\n" );
			}
			SL_AutoProtect.Unlock();
#endif

			SmartLocker SL_TcpServer_listConnections(TcpServer::listConnections);

			MsgSocket* ms = FindClientFromId( msg->pid );
			if( ms != (MsgSocket*)NULL )
			{
				try
				{
					ms->Send((int)str.GetLength(), str.GetStr());
				}
				catch( SocketException& e )
				{
					OmiscidError( "Error when responding to a client request : %s (%d)\n", e.msg.GetStr(), e.err );
				}
			}
		}
	}
	else
	{
		OmiscidError( "waited : controlQuery, received='%s'\n", node->name);
		msg->Display(stderr);
	}
}
void ControlServer::DisplayServiceGlobalShortDescription()
{
	SimpleString str;
	GenerateGlobalShortDescription(str);
	printf("%s\n", str.GetStr());
}
Beispiel #10
0
void MsgSocket::Receive()
{
	SmartLocker SL_CallbackObjects(CallbackObjects, false);
	try
	{
		if(socket->Select())
		{
			int nb_read = socket->Recv(bufferSize-occupiedSize, (buffer+occupiedSize));
			// OmiscidTrace( "%d %d \n ",nb_read, occupiedSize);
			if(nb_read == 0)
			{
				if ( connected )
				{
					// Send disconnected message
					SL_CallbackObjects.Lock();
					// Send info to all listener
					for( CallbackObjects.First(); CallbackObjects.NotAtEnd(); CallbackObjects.Next() )
					{
						try
						{
							CallbackObjects.GetCurrent()->Disconnected(*this,GetPeerPid());
						}
						catch(SocketException&) {} // Discard it
					}
					SL_CallbackObjects.Unlock();
					connected = false;
				}
				return ;
			}
			occupiedSize += nb_read;

			// DevOmiscidTrace( "occupiedSize %d\n", occupiedSize );

			// For printing stuff...
			buffer[occupiedSize] = '\0';

			bool stop = false;
			unsigned int length_msg, pid, mid;
			int length_header;

			int offset = 0;
			int size = occupiedSize;
			while ( connected == true && stop == false )
			{
				length_msg = pid = mid = 0;
				if((length_header = GoodBeginning(buffer+offset, size, length_msg, pid, mid)) != 0)
				{
					//cerr << "good beginning ";
					//cerr.write(aBuffer+offset, keyword_min);
					//cerr << endl;
					if ( (unsigned int)size < length_header + length_msg + tag_end_size )
					{
						// OmiscidTrace( "wait more byte\n");
						int total = (int)(length_header + length_msg + tag_end_size);
						if ( total >= bufferSize )
						{
							OmiscidTrace( "buffer too small : new buffer allocation\n");
							//allocation new buffer
							bufferSize = (total+1023)&~1023; // bufferSize = rouded to the KB over
							unsigned char* tmp_buffer = new OMISCID_TLM unsigned char[bufferSize+1];
							if ( tmp_buffer )
							{
								memcpy(tmp_buffer, buffer+offset, size*sizeof(unsigned char));
								offset = 0;
								occupiedSize = size;
								delete [] buffer;
								buffer = tmp_buffer;
							}
						}
						stop = true;
					}
					else if ( mid == 0 )
					{
#ifdef DEBUG
						if ( Debug & DBG_LINKSYNC )
						{
							// buffer[offset+offset+length_msg+tag_size] = '\0';
							fprintf( stderr, "MsgSocket::Receive: %s\n", buffer+offset );
						}
#endif
						peer_pid = pid;

						SmartLocker SL_mutex(mutex);
						if ( callbackSyncLinkFct )
						{
							*(buffer+offset+tag_size+length_msg)='\0';
							callbackSyncLinkData.Msg.len = length_msg;
							if ( length_msg != 0 )
							{
								callbackSyncLinkData.Msg.buffer =  (char*)buffer+offset+tag_size;
							}
							else
							{
								callbackSyncLinkData.Msg.buffer =  NULL;
							}
							callbackSyncLinkData.Msg.origine = FromTCP;
							callbackSyncLinkData.Msg.pid = pid;
							callbackSyncLinkData.Msg.mid = mid;
							try
							{
								(*callbackSyncLinkFct)( &callbackSyncLinkData, this );
							}
							catch( SocketException& e )
							{
								throw e;
							}
						}
						SL_mutex.Unlock();

						//std::cout << "Link connexion Msg from "<<pid<<"\n";
						receivedSyncLinkMsg = true;
						if( SyncLinkMsgSent() == false )
						{
							SendSyncLinkMsg();
						}

						if ( length_msg != 0 )
						{
							SetPeerSyncLinkData( (char*)(buffer+offset+length_header), length_msg );
						}

						// Let's say we have a new connected peer
						SL_CallbackObjects.Lock();
						// Send info to all listener
						for( CallbackObjects.First(); CallbackObjects.NotAtEnd(); CallbackObjects.Next() )
						{
							try
							{
								CallbackObjects.GetCurrent()->Connected(*this,pid);
							}
							catch(SocketException& e)
							{
								// Unlock the list
								SL_CallbackObjects.Unlock();

								// Thow the exception
								throw e;
							}
						}
						SL_CallbackObjects.Unlock();

						offset += length_header + length_msg + tag_end_size;
						size =  occupiedSize - offset;

						// Ok, we have someone connected
					}
					//					else if(length_msg == 0)
					//					{
					//						//std::cout << "Empty Msg from "<<pid<<"\n";
					//						offset += length_header;
					//						size =  occupiedSize - offset;
					//					}
					else
					{
						offset += length_header;

						unsigned char* msgptr =  (buffer+offset);

						//verif end tag
						if( memcmp(tag_end, (msgptr + length_msg), tag_end_size))
						{
							OmiscidTrace( "warning end tag\n");
							size =  occupiedSize - offset;
						}
						else
						{
							offset += length_msg + tag_end_size;
							size =  occupiedSize - offset;
#ifdef DEBUG
							if ( Debug & DBG_RECV )
							{
								if ( length_msg != 0 )
								{
									SimpleString SFormat = "MsgSocket::Recv: %";
									SFormat += length_msg;
									SFormat += ".";
									SFormat += length_msg;
									SFormat += "s\n";
									fprintf( stderr, SFormat.GetStr(), msgptr );
								}
								else
								{
									fprintf( stderr, "MsgSocket::Recv: <empty>\n" );
								}
							}
#endif
							// Send info to all receiver
							SL_CallbackObjects.Lock();
							if ( CallbackObjects.GetNumberOfElements() )
							{
								// Prepare data
								*(msgptr+length_msg)='\0';
								callbackData.Msg.len = length_msg;
								if ( length_msg != 0 )
								{
									callbackData.Msg.buffer =  (char*)msgptr;
								}
								else
								{
									callbackData.Msg.buffer =  (char*)NULL;
								}
								callbackData.Msg.origine = FromTCP;
								callbackData.Msg.pid = pid;
								callbackData.Msg.mid = mid;

								// Send info to all listener
								for( CallbackObjects.First(); CallbackObjects.NotAtEnd(); CallbackObjects.Next() )
								{
									try
									{
										CallbackObjects.GetCurrent()->Receive(*this, callbackData);
									}
									catch(SocketException& e)
									{
										// Unlock the list
										SL_CallbackObjects.Unlock();

										// Throw the exception
										throw e;
									}
								}
							}
							SL_CallbackObjects.Unlock();
						}
					}
				}
				else
				{
					//cerr << "Decalage\n";
					int dec;
					if(!MoveToMessage(buffer+offset, size, dec))
					{
						stop = true;
						size -= dec;
						offset += dec;
					}
					else
					{
						offset += dec;
						size -= dec;
					}
				}
			}
			occupiedSize = size;
			if ( occupiedSize != 0 && offset != 0 )
			{
				memmove(buffer, buffer+offset, occupiedSize);
				// offset is local. It will be set to 0 again.
			}
		}
	}
	catch(SocketException& e)
	{
		OmiscidTrace( "SocketException: %s %d\n", e.msg.GetStr(), e.err);
		if ( connected )
		{
			// Send disconnected message
			SL_CallbackObjects.Lock();
			// Send info to all listener
			for( CallbackObjects.First(); CallbackObjects.NotAtEnd(); CallbackObjects.Next() )
			{
				try
				{
					CallbackObjects.GetCurrent()->Disconnected(*this,GetPeerPid());
				}
				catch(SocketException&) {} // Discard
			}
			SL_CallbackObjects.Unlock();
			connected = false;
		}
	}
}
	/**
	 * Called when the connexion between the local service and the remote
	 * service is broken.
	 * @param TheService A reference to the service which losts a connection
	 * @param LocalConnectorName the name of the connector handling the broken link
	 * @param PeerId the disconnected remote service PeerId
	 */
void ConnectorListener::Disconnected(Service& TheService, const SimpleString LocalConnectorName, unsigned int PeerId)
{
	OmiscidTrace( "The peer %8.8x disconnects from %s:%s.\n", PeerId, TheService.GetName().GetStr(), LocalConnectorName.GetStr() );
}
Beispiel #12
0
ServiceProxy::ServiceProxy( unsigned int PeerId, SimpleString eHostName, int eControlPort, ServiceProperties& ServiceProps )
	: ControlClient(PeerId)
{
	SimpleString TmpString;
	VariableAttribute * VarAtt;
	InOutputAttribute * IOAtt;
	int Pos;
	unsigned int Port;

	HostName	= eHostName;
	ControlPort	= eControlPort;
	FullDescription = false;

	// Is the description
	TmpString = ServiceProps["desc"].GetValue();
	//if ( ServiceProps.IsDefined( "name" ) )
	//{
	//	OmiscidError( "Warning, forced fallback for '%s' (%s).\n",
	//		ServiceProps[NameString].GetValue().GetStr(), ServiceProps["id"].GetValue().GetStr() );
	//}
	//else
	//{
	//	OmiscidError( "Warning, forced fallback for %8.8x.\n", PeerId );
	//}
	//if ( TmpString == "forced fallback" )
	// OmiscidTrace( "Working on'%s' (%s).\n",
	//	 ServiceProps[ControlServer::NameString].GetValue().GetStr(), ServiceProps["id"].GetValue().GetStr() );

	if ( TmpString == "full" )
	{
		FullDescription = true;
	}

	for( Pos = 0; Pos <  ServiceProps.GetNumberOfProperties(); Pos++ )
	{
		ServiceProperty& LocalProp = ServiceProps.GetProperty(Pos);

		if ( LocalProp.GetName() == "desc" )
		{
			continue;
		}

		// SimpleString TmpName = LocalProp.GetName();

		// Parse property
		TmpString = LocalProp.GetValue();
		char * TmpChar = (char*)TmpString.GetStr();
		switch( TmpString[0] )
		{
			// Work on Variables
			case 'c':
				if ( TmpString.GetLength() <= 2 || TmpString[1] != '/' )
				{
					FullDescription = false;
					continue;
				}

				// Ok, something like c/...
				VarAtt = new OMISCID_TLM VariableAttribute( LocalProp.GetName() );
				if ( VarAtt == NULL )
				{
					FullDescription = false;
					continue;
				}
				VarAtt->SetValue( TmpChar+2 );
				VarAtt->SetAccessConstant();
				listVariableName.Add( LocalProp.GetName() );
				listVariableAttr.Add( VarAtt );
				break;

			case 'r':
				if ( TmpString.GetLength() != 1 )
				{
					FullDescription = false;
					continue;
				}

				// Ok, something like r/...
				VarAtt = new OMISCID_TLM VariableAttribute( LocalProp.GetName() );
				if ( VarAtt == NULL )
				{
					FullDescription = false;
					continue;
				}
				VarAtt->SetAccessRead();
				listVariableName.Add( LocalProp.GetName() );
				listVariableAttr.Add( VarAtt );
				break;

			case 'w':
				if ( TmpString.GetLength() != 1 )
				{
					FullDescription = false;
					continue;
				}

				// Ok, something like w/...
				VarAtt = new OMISCID_TLM VariableAttribute( LocalProp.GetName() );
				if ( VarAtt == NULL )
				{
					FullDescription = false;
					continue;
				}
				VarAtt->SetAccessReadWrite();
				listVariableName.Add( LocalProp.GetName() );
				listVariableAttr.Add( VarAtt );
				break;

			// Work on Connectors
			case 'i':
				if ( TmpString[1] != '/' || TmpString[2] < '0' || TmpString[2] > '9' )
				{
					FullDescription = false;
					continue;
				}

				// Check if we've got a correct port
				Port = 0;
				Port = atoi(TmpChar+2);
				if ( Port == 0 || Port >= 0x0000ffff )
				{
					FullDescription = false;
					continue;
				}

				IOAtt = new OMISCID_TLM InOutputAttribute( LocalProp.GetName(), NULL, AnInput );
				if ( IOAtt == NULL )
				{
					FullDescription = false;
					continue;
				}
				IOAtt->SetTcpPort( (unsigned short)Port );
				listInputName.Add( LocalProp.GetName() );
				listInputAttr.Add( IOAtt );
				break;

			case 'o':
				if ( TmpString[1] != '/' || TmpString[2] < '0' || TmpString[2] > '9' )
				{
					FullDescription = false;
					continue;
				}

				// Check if we've got a correct port
				Port = 0;
				Port = atoi(TmpChar+2);
				if ( Port == 0 || Port >= 0x0000ffff )
				{
					FullDescription = false;
					continue;
				}

				IOAtt = new OMISCID_TLM InOutputAttribute( LocalProp.GetName(), NULL, AnOutput );
				if ( IOAtt == NULL )
				{
					FullDescription = false;
					continue;
				}
				IOAtt->SetTcpPort( (unsigned short)Port );
				listOutputName.Add( LocalProp.GetName() );
				listOutputAttr.Add( IOAtt );
				break;

			case 'd':
				if ( TmpString[1] != '/' || TmpString[2] < '0' || TmpString[2] > '9' )
				{
					FullDescription = false;
					continue;
				}

				// Check if we've got a correct port
				Port = 0;
				Port = atoi(TmpChar+2);
				if ( Port == 0 || Port >= 0x0000ffff )
				{
					FullDescription = false;
					continue;
				}

				IOAtt = new OMISCID_TLM InOutputAttribute( LocalProp.GetName(), NULL, AnInOutput );
				if ( IOAtt == NULL )
				{
					FullDescription = false;
					continue;
				}
				IOAtt->SetTcpPort( (unsigned short)Port );
				listInOutputName.Add( LocalProp.GetName() );
				listInOutputAttr.Add( IOAtt );
				break;

			default:
				FullDescription = false;
				continue;
		}
	}

	//if ( FullDescription == false )
	//{
	//	UpdateDescription();
	//}
}
Beispiel #13
0
int main(int argc, char* argv[])
{
	int Argument;
	char Message[512];
	SimpleString ServiceName;
	int ConnectionString = -1;
	int ConnectionObjects = -1;

	if ( argc < 2 )
	{
		Usage( "Two few parameters" );
	}

	if ( argv[1][0] == '-' )
	{
		Usage( "The first parameter *must* be the service name" );
	}
	ServiceName = argv[1];

	// Check argument before launching any registering process
	for( Argument = 2; Argument < argc; Argument++ )
	{
		if ( strcmp( "-o", argv[Argument]) == 0 )
		{
			if ( Argument+1 >= argc || argv[Argument+1][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing output name at parameter %d\n", Argument+1 );
				Usage( (const char *)Message );
			}
			if ( Argument+2 >= argc || argv[Argument+2][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing description for output '%s' at parameter %d\n", argv[Argument+1], Argument+2 );
				Usage( (const char *)Message );
			}

			Argument += 2;
			continue;
		}

		if ( strcmp( "-i", argv[Argument]) == 0 )
		{
			if ( Argument+1 >= argc || argv[Argument+1][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing input name at parameter %d\n", Argument+1 );
				Usage( (const char *)Message );
			}
			if ( Argument+2 >= argc || argv[Argument+2][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing description for input '%s' at parameter %d\n", argv[Argument+1], Argument+2 );
				Usage( (const char *)Message );
			}
			Argument += 2;
			continue;
		}

		if ( strcmp( "-io", argv[Argument]) == 0 )
		{
			if ( Argument+1 >= argc || argv[Argument+1][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing inoutput name at parameter %d\n", Argument+1 );
				Usage( (const char *)Message );
			}
			if ( Argument+2 >= argc || argv[Argument+2][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing description for inoutput '%s' at parameter %d\n", argv[Argument+1], Argument+2 );
				Usage( (const char *)Message );
			}
			Argument += 2;
			continue;
		}

		if ( strcmp( "-v", argv[Argument]) == 0 )
		{
			if ( Argument+1 >= argc || argv[Argument+1][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing variable name at parameter %d\n", Argument+1 );
				Usage( (const char *)Message );
			}
			if ( Argument+2 >= argc || argv[Argument+2][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing description for variable '%s' at parameter %d\n", argv[Argument+1], Argument+2 );
				Usage( (const char *)Message );
			}
			if ( Argument+3 >= argc || argv[Argument+3][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing value for variable '%s' at parameter %d\n", argv[Argument+1], Argument+3 );
				Usage( (const char *)Message );
			}
			Argument += 3;
			continue;
		}

		if ( strcmp( "-ct", argv[Argument]) == 0 )
		{
			if ( Argument+1 >= argc || argv[Argument+1][0] == '-')
			{
				// We consider it as the name
				sprintf( Message, "Missing connection strint after parameter %d\n", Argument+1 );
				Usage( (const char *)Message );
			}

			ConnectionString = Argument+1;

			ConnectionObjects = ParseConnectionString( argv[ConnectionString], false );
			if ( ConnectionObjects <= 0 )
			{
				sprintf( Message, "Bad connection string in parameter %d\n", Argument+1 );
				Usage( (const char *)Message );
			}

			Argument += 1;
			continue;
		}

		if ( strcmp( "-d", argv[Argument]) == 0 )
		{
			if ( Debug )
			{
				fprintf( stderr, "Warning: debug mode already set\n" );
			}
			Debug = true;
			continue;
		}

		sprintf( Message, "invalid option in parameter %d ('%s')", Argument+1, argv[Argument] );
		Usage( (const char *)Message );
	}

#ifdef _DEBUG
		// MsgSocket::Debug = MsgSocket::DBG_LINKSYNC;
#endif

	// Ok, it seems that parameters looks ok...
	// start registering service
	if ( Debug ) { printf("Launching service '%s' ", ServiceName.GetStr() ); }

	Service * pServ = ServiceFactory.Create( ServiceName );
	if ( Debug ) { printf("with ServiceId %s\n", pServ->GetPeerIdAsString().GetStr() ); }

	// Check argument before launching any registering process
	for( Argument = 2; Argument < argc; Argument++ )
	{
		if ( strcmp( "-o", argv[Argument]) == 0 )
		{
			pServ->AddConnector( argv[Argument+1], argv[Argument+2], AnOutput );

			Argument += 2;
			continue;
		}

		if ( strcmp( "-i", argv[Argument]) == 0 )
		{
			pServ->AddConnector( argv[Argument+1], argv[Argument+2], AnInput );

			Argument += 2;
			continue;
		}

		if ( strcmp( "-io", argv[Argument]) == 0 )
		{
			pServ->AddConnector( argv[Argument+1], argv[Argument+2], AnInOutput );

			Argument += 2;
			continue;
		}

		if ( strcmp( "-v", argv[Argument]) == 0 )
		{
			if ( Debug ) { printf( "Adding variable '%s' ('%s') with value '%s'...", argv[Argument+1], argv[Argument+2], argv[Argument+3] ); }

			if ( pServ->AddVariable( argv[Argument+1], SimpleString::EmptyString, argv[Argument+2], ReadWriteAccess ) == true )
			{
				pServ->SetVariableValue( argv[Argument+1], argv[Argument+3] );
				if ( Debug ) { printf( "done.\n" ); }
			}
			else
			{
				if ( Debug ) { printf( "failed.\n" ); }
			}

			Argument += 3;
			continue;
		}

		if ( strcmp( "-ct", argv[Argument]) == 0 )
		{
			// Already processed
			Argument += 1;
			 continue;
		}

		if ( strcmp( "-d", argv[Argument]) == 0 )
		{
			// Debug option already processed int the validity checking mode
			 continue;
		}

		sprintf( Message, "invalid option in parameter %d ('%s')", Argument+1, argv[Argument] );
		Usage( (const char *)Message );
	}

	pServ->Start();

	printf( "Waiting...\n" );
	// Lock Mylself
	Event ForEver;
	ForEver.Wait();

	return 0;
}