일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- RS-485
- 배당
- 코스피
- 애플
- Espressif
- Home Assistant
- MQTT
- raspberry pi
- 홈네트워크
- 파이썬
- 국내주식
- 공모주
- 매터
- SK텔레콤
- Apple
- matter
- cluster
- 월패드
- 해외주식
- 힐스테이트 광교산
- 현대통신
- 나스닥
- Bestin
- 티스토리챌린지
- 미국주식
- homebridge
- esp32
- 오블완
- Python
- ConnectedHomeIP
- Today
- Total
YOGYUI
Matter - WiFi IP 주소 할당 이벤트 캐치 본문
Matter - Catch Wi-Fi IP address assignment event
BLE-WiFi 커미셔닝을 통해 매터 디바이스를 커미셔닝한 경우, 라우터(공유기)의 DHCP를 통해 IP주소(v4, v6)를 할당받게 된다 (dynamic or static address)
IP 주소를 할당받은 후 웹서버 등 비매터(non-matter) 동작을 활성화하고 싶은 경우 IP주소 할당 이벤트를 캐치해야하는데, CHIP(Connected Home IP)의 PlatformManager의 이벤트 핸들러에 콜백을 추가하는 방식을 통해 구현하는 방법을 알아보자
함수원형
헤더파일 위치: connectedhomeip/src/include/platform/PlatformManager.h
inline CHIP_ERROR PlatformManager::AddEventHandler(EventHandlerFunct handler, intptr_t arg)
{
return static_cast<ImplClass *>(this)->_AddEventHandler(handler, arg);
}
CHIP 초기화 (DeviceLayer::PlatformMgr()::ScheduleWork 호출) 전에 AddEventHandler 함수를 통해 콜백을 등록하면 된다
콜백함수 원형은 다음과 같다
typedef void (*EventHandlerFunct)(const ChipDeviceEvent * event, intptr_t arg);
ChipDeviceEvent는 connectedhomeip/src/include/platform/CHIPDeviceEvent.h 파일에 선언되어 있는 구조체(struct)이며, 다음과 같이 굉장히 많은 이벤트 관련 변수를 담고 있다
struct ChipDeviceEvent final
{
uint16_t Type;
union
{
ChipDevicePlatformEvent Platform;
LambdaBridge LambdaEvent;
struct
{
AsyncWorkFunct WorkFunct;
intptr_t Arg;
} CallWorkFunct;
struct
{
ConnectivityChange Result;
} WiFiConnectivityChange;
struct
{
ConnectivityChange Result;
} ThreadConnectivityChange;
struct
{
ConnectivityChange IPv4;
ConnectivityChange IPv6;
chip::Inet::IPAddress ipAddress;
} InternetConnectivityChange;
struct
{
struct
{
ConnectivityChange Result;
} Overall;
struct
{
ConnectivityChange Result;
} ViaThread;
} ServiceConnectivityChange;
struct
{
ConnectivityChange Result;
} ServiceSubscriptionStateChange;
struct
{
bool IsMemberOfFabric;
} FabricMembershipChange;
struct
{
bool IsServiceProvisioned;
bool ServiceConfigUpdated;
} ServiceProvisioningChange;
struct
{
bool IsPairedToAccount;
} AccountPairingChange;
struct
{
bool IsTimeSynchronized;
} TimeSyncChange;
struct
{
uint64_t PeerNodeId;
uint16_t SessionKeyId;
uint8_t SessionType;
bool IsCommissioner;
} SessionEstablished;
struct
{
BLE_CONNECTION_OBJECT ConId;
} CHIPoBLESubscribe;
struct
{
BLE_CONNECTION_OBJECT ConId;
} CHIPoBLEUnsubscribe;
struct
{
BLE_CONNECTION_OBJECT ConId;
chip::System::PacketBuffer * Data;
} CHIPoBLEWriteReceived;
struct
{
BLE_CONNECTION_OBJECT ConId;
} CHIPoBLEIndicateConfirm;
struct
{
BLE_CONNECTION_OBJECT ConId;
CHIP_ERROR Reason;
} CHIPoBLEConnectionError;
struct
{
BLE_CONNECTION_OBJECT ConId;
} CHIPoBLENotifyConfirm;
struct
{
bool RoleChanged : 1;
bool AddressChanged : 1;
bool NetDataChanged : 1;
bool ChildNodesChanged : 1;
struct
{
uint32_t Flags;
} OpenThread;
} ThreadStateChange;
struct
{
ActivityChange Result;
} CHIPoBLEAdvertisingChange;
struct
{
InterfaceIpChangeType Type;
} InterfaceIpAddressChanged;
struct
{
uint64_t nodeId;
FabricIndex fabricIndex;
} CommissioningComplete;
struct
{
FabricIndex fabricIndex;
bool addNocCommandHasBeenInvoked;
bool updateNocCommandHasBeenInvoked;
} FailSafeTimerExpired;
struct
{
// TODO(cecille): This should just specify wifi or thread since we assume at most 1.
int network;
} OperationalNetwork;
struct
{
OtaState newState;
} OtaStateChanged;
};
void Clear() { memset(this, 0, sizeof(*this)); }
bool IsPublic() const { return DeviceEventType::IsPublic(Type); }
bool IsInternal() const { return DeviceEventType::IsInternal(Type); }
bool IsPlatformSpecific() const { return DeviceEventType::IsPlatformSpecific(Type); }
bool IsPlatformGeneric() const { return DeviceEventType::IsPlatformGeneric(Type); }
};
ChipDeviceEvent 구조체 내에서 눈여겨봐야할 변수는 InterfaceIpAddressChanged 구조체 변수다
※ Type 변수의 값을 통해 전달되고 있는 이벤트가 어떤 종류인지 확인 가능
struct
{
InterfaceIpChangeType Type;
} InterfaceIpAddressChanged;
IP 주소 변경에 대한 이벤트 정보를 담고 있는데, InterfaceIpChangeType 열거형(enum)의 원형을 살펴보면
enum class InterfaceIpChangeType
{
kIpV4_Assigned,
kIpV4_Lost,
kIpV6_Assigned,
kIpV6_Lost,
};
IPv4, IPv6 각각에 대해 '주소가 할당되었음(Assigned)', '연결이 해제되었음(Lost)' 값이 이벤트 발생 시 할당되는 것을 알 수 있다
구현
콜백함수를 등록하고 활용하는 예시의 psuedo-code는 다음과 같다
(namespace를 쓰면 코드가 깔끔해지지만, 여기서는 사용하지 않는다)
static void matter_callback(const ChipDeviceEvent * event, intptr_t arg)
{
switch (event->Type) {
case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged:
if (event->InterfaceIpAddressChanged.Type == chip::DeviceLayer::InterfaceIpChangeType::kIpV6_Assigned) {
std::cout << "IP Address(v6) assigned\n";
} else if (event->InterfaceIpAddressChanged.Type == chip::DeviceLayer::InterfaceIpChangeType::kIpV4_Assigned) {
std::cout << "IP Address(v4) assigned\n";
// TODO: IP 주소 할당 후 동작 추가
}
break;
default:
break;
}
}
void start_matter()
{
// initialize code
// ...
// 이벤트 핸들러 콜백함수 등록
chip::DeviceLayer::PlatformMgr().AddEventHandler(matter_callback, static_cast<intptr_t>(NULL));
// Matter 시작
chip::DeviceLayer::PlatformMgr().ScheduleWork(task, task_handle);
}
이벤트 타입이 DeviceEventType::kInterfaceIpAddressChanged일 때, InterfaceIpAddressChanged 구조체 변수 내 Type의 값에 따라 IPv4, IPv6 각각 주소가 할당되었는지 여부를 확인할 수 있다
ESP32에서 위와 같이 구현해서 로그를 찍어보면
I (2658) wifi:connected with SEUNGHEE_2G, aid = 5, channel 8, 40D, bssid = 70:5d:cc:24:ec:2d
I (2658) wifi:security: WPA2-PSK, phy: bgn, rssi: -48
I (2668) wifi:pm start, type: 1
I (2668) chip[DL]: WIFI_EVENT_STA_CONNECTED
I (2668) chip[DL]: WiFi station state change: Connecting -> Connecting_Succeeded
I (2688) chip[DL]: WiFi station state change: Connecting_Succeeded -> Connected
I (2688) chip[DL]: WiFi station interface connected
I (2698) wifi:AP's beacon interval = 102400 us, DTIM period = 3
I (2698) chip[ZCL]: WiFiDiagnosticsDelegate: OnConnectionStatusChanged
I (2718) chip[DL]: Done driving station state, nothing else to do...
I (2718) chip[DL]: Updating advertising data
I (3908) chip[DL]: IP_EVENT_GOT_IP6
I (3908) esp_netif_handlers: sta ip: 192.168.10.250, mask: 255.255.0.0, gw: 192.168.0.1
I (3908) chip[DL]: IPv6 addr available. Ready on WIFI_STA_DEF interface: fe80:0000:0000:0000:c6de:e2ff:fec1:b304
I (3928) chip[DL]: IPv4 Internet connectivity ESTABLISHED
I (3928) chip[DL]: IP_EVENT_STA_GOT_IP
I (3938) chip[DL]: IPv4 address changed on WiFi station interface: 192.168.10.250/255.255.0.0 gateway 192.168.0.1
IP Address(v6) assigned
I (3958) chip[DIS]: Updating services using commissioning mode 1
I (3968) chip[DIS]: CHIP minimal mDNS started advertising.
I (3988) chip[DIS]: Advertise commission parameter vendorID=65522 productID=32769 discriminator=3840/15 cm=1
I (3998) chip[DIS]: CHIP minimal mDNS configured as 'Commissionable node device'; instance name: DD16D87950553F61.
I (4018) chip[DIS]: mDNS service published: _matterc._udp
IP Address(v4) assigned
I (4148) chip[DIS]: Updating services using commissioning mode 1
I (4148) chip[DIS]: CHIP minimal mDNS started advertising.
I (4188) chip[DIS]: Advertise commission parameter vendorID=65522 productID=32769 discriminator=3840/15 cm=1
I (4198) chip[DIS]: CHIP minimal mDNS configured as 'Commissionable node device'; instance name: DD16D87950553F61.
I (4218) chip[DIS]: mDNS service published: _matterc._udp
I (4218) ROUTE_HOOK: Hook already installed on netif, skip...
E (4218) chip[DL]: Long dispatch time: 198 ms, for event type 32780
W (4278) wifi:<ba-add>idx:0 (ifx:0, 70:5d:cc:24:ec:2d), tid:0, ssn:3, winSize:64
CHIP 자체적으로 기록하는 로그와 임의로 추가한 로그(빨간색)가 함께 찍히는 것을 확인할 수 있다
※ esp-idf의 network interface(netif) 모듈 로그도 같이 찍힌다
- 커미셔닝에 사용된 Wi-Fi SSID에 접속 (station connect)
- DHCP로 IPv4, IPv6 주소 할당
- mDNS 설정
매터 디바이스에 IP 주소가 할당되는 이벤트를 캐치하는 방법에 대해 알아봤다
CHIP 소스코드가 매우 구조화가 잘 되어있기 때문에 코드 트레이싱이 굉장히 쉽다!
이제 열심히 소켓, HTTP, HTTPS 기능을 추가해보자..
'홈네트워크(IoT) > Matter' 카테고리의 다른 글
Matter Specification - Level Control Cluster (0) | 2023.03.25 |
---|---|
Matter Specification - On/Off Cluster (0) | 2023.03.24 |
Matter - Wi-Fi AP Mode 기본으로 활성화하기 (ESP32) (0) | 2023.02.13 |
Matter - Google Home 개발 프로젝트 생성하기 (0) | 2023.02.02 |
Matter Specification 1.0 발표 (09/28) (0) | 2022.10.07 |