[Platinum UPnP] 101 :: (1) 간단한 Device 만들기




파일: tutorial01.cpp


UPnP는 크게 Device와 Control-Point라는 개념으로 나뉘어 집니다. 우선 간단한 Device를 만들어 보겠습니다. Device를 먼저하는 이유는 Device Spy 프로그램으로 동작을 간단히 확인해 볼 수 있기 때문입니다. Control-Point의 기본적인 동작은 Device를 찾아내어 그 정보들을 확인하고 그에 맞게 Device를 조작하는 등의 복잡한 작업을 하기 때문에 Device를 먼저 알아보도록 하겠습니다.


    우선 main() 함수를 구성합니다. Platinum은 Network 통신을 위한 PLT_UPnP 객체를 제공합니다. 이 객체에 AddDevice() 함수를 통해 Device를 등록하면, UPnP 통신에 대한 것은 PLT_UPnP 객체가 담당해주고, Device는 자신의 임무만 열심히 하면 됩니다.


int main()
{
	PLT_UPnP upnp;
	upnp.Start();

	bool stop = false;
	do {
		const char c = fgetc(stdin);
		stop = (c == 'q' || c == 'Q');
	} while(!stop);

	upnp.Stop();
	return 0;
}


    위 코드를 통해 프로그램은 시작하면서 Network 통신을 준비하고, q 또는 Q 문자가 입력될 때까지 대기합니다. Platinum은 기본적으로 멀티 쓰레드로 동작하기 때문에, main() 함수에서 아무 동작을 하지 않아도 내부에서는 UPnP 통신을 위한 많은 동작을 하고 있습니다.


    이제 UPnP 통신은 준비를 했지만, 사용할 Device가 없습니다. 그래서 Device를 만들어 봅니다. Device는 PLT_DeviceHost 클래스를 상속을 받아서 구현을 합니다. 이 때, 주의할 점은 PLT_DeviceHost 클래스는 SetupServices() 라는 순수 가상함수를 포함하고 있습니다. 따라서 상속만 받아서는 객체가 생성되지 않습니다. SetupServices() 함수도 함께 구현을 해주어야 합니다. 코드는 아래와 같습니다.


class TutorialDevice :public PLT_DeviceHost
{
protected:
	virtual NPT_Result SetupServices(void)
	{
		return NPT_SUCCESS;
	}
};


    현재 위의 코드에서는 아무 일도 하지 않습니다. 왜냐하면 우리는 Service가 존재하지 않는 가장 단순한 Device를 만들기로 했기 때문 입니다. Service가 무엇인지는 다음 단계에서 알아보고 구현하겠습니다.

    Device가 만들어 졌으면 Device가 Network 상에서 동작할 수 있도록 PLT_UPnP 객체에 등록을 합니다. 등록 코드는 아래와 같습니다.


	...

	PLT_UPnP upnp;
	PLT_DeviceHostReference device(new TutorialDevice());
	upnp.AddDevice(device);
	upnp.Start();

	...


    이제 실행을 시켜 봅니다. 실행을 시키면 Device Spy 에 새로운 디바이스가 추가되는 것을 볼 수 있습니다. 하지만, 이름이 없는 Device 입니다. 너무 궁색해 보이니 TutorialDevice 클래스의 생성자에서 이름을 추가합니다.


	...

	TutorialDevice()
		: PLT_DeviceHost()
	{
		m_FriendlyName = "Tutorial Device";
	}

	...


    프로그램을 다시 실행 시킨 뒤에 Device Spy 프로그램의 Device 목록을 보면 "Tutorial Device"라는 이름의 새로운 Device를 볼 수 있습니다.