This is `Funnel.h`:
```
#pragma once

#include 
#include 
#include 
#include "cJSON.h"
#include "Bond\_Req.h"

/\* defined in Funnel\_Tree.h \*/
typedef struct funnel\_tree\_s funnel\_tree\_t;

typedef enum {
 FUNNEL\_AUTH\_LEVEL\_NONE = 0,
 FUNNEL\_AUTH\_LEVEL\_DISCOVER,
 FUNNEL\_AUTH\_LEVEL\_CONTROL,
 FUNNEL\_AUTH\_LEVEL\_ADMIN
} funnel\_auth\_level\_t;

#define FUNNEL\_CONNECTION\_BROADCAST -1
#define FUNNEL\_TRANSPORT\_GRATUITOUS -42
#define FUNNEL\_TRANSPORT\_HASH\_ONLY -43

/\*\*
 \* request handler function pointer
 \* @param ft pointer to corresponding funnel tree node
 \* which contains data, key, and hash useful to this handler
 \* @param req [in] pointer to request to handle
 \* [out] reply to be sent by funnel, if FUNNEL\_REPLY\_IMMEDIATE
 \*
 \* @return FUNNEL\_REPLY\_DEFERRED:
 \* who sends reply: timer associated with handler
 \* who frees req: handler
 \* children enumerated?: no
 \*
 \* FUNNEL\_REPLY\_IMMEDIATE
 \* who sends reply: Funnel
 \* who frees req: Funnel
 \* children enumerated?: only if !Bond\_Status\_Is\_Error(req.status)
 \*
 \* @note While it is \_possible\_, for the handler to call Funnel\_Process\_Up(),
 \* we strongly discourage it! The reason for the reply via req
 \* parameter is that it avoids keeping the handler functions' stack
 \* context, and furthermore, that this way other children can be
 \* enumerated.
 \*/
typedef void (\*request\_handler\_t) (funnel\_tree\_t \* ft,
 bond\_req\_t \* req);

/\*\*
 \* callback for sending bond requests on a transport
 \* @param req request to send
 \* @return true if message queued for sending
 \* / false if message not sent
 \*/
typedef bool (\*funnel\_transport\_cb\_t)(bond\_req\_t \* req);

/\*\*
 \* initialize the Funnel singleton
 \* @return true
 \*/
bool Funnel\_Init();

/\*\*
 \* free all funnel resources
 \* @warning any funnel (or funnel\_tree) calls may fail after this point!
 \* @return true
 \*/
bool Funnel\_Deinit();

/\*\*
 \* register a transport
 \* @param f function to transmit an up bond request
 \* @param transport\_id [out] id required by Funnel\_Process\_Down
 \* @return true if added to transport table
 \*/
bool Funnel\_Register\_Transport(funnel\_transport\_cb\_t f,
 const char \*name, int \*transport\_id);

/\*\*
 \* add hash to the reply whenever it's an object
 \* @param req reply to augment
 \* @param ft corresponding funnel tree node
 \* @return true if hash added
 \*/
bool Funnel\_Req\_Add\_Hash(bond\_req\_t \* req, funnel\_tree\_t \* ft);

/\*\*
 \* add children enumeration to reply without hash
 \* @param req reply to augment
 \* @return true if children enumerated
 \* @note Only adds to 200 replies.
 \* We exclude 201 because those replies just contain the new id.
 \*/
bool Funnel\_Req\_Add\_Children\_No\_Hash(bond\_req\_t \* req, funnel\_tree\_t \* ft);

/\*\*
 \* add children enumeration to reply
 \* @param req reply to augment
 \* @return true if children enumerated
 \* @note Only adds to 200 replies.
 \* We exclude 201 because those replies just contain the new id.
 \*/
bool Funnel\_Req\_Add\_Children(bond\_req\_t \* req, funnel\_tree\_t \* ft);

/\*\*
 \* process a down request (from app/cloud to BOND)
 \* @param req request to process
 \* This function takes ownership of the req object,
 \* and will free it, even under error conditions.
 \* req becomes invalid after this function returns.
 \* @return true
 \*/
bool Funnel\_Process\_Down(bond\_req\_t \* req);

/\*\*
 \* process an up request (from BOND to app/cloud)
 \* @param req request to send
 \* @return true
 \*/
bool Funnel\_Process\_Up(bond\_req\_t \* req);

/\*\*
 \* split the topic into the first and rest
 \* @param topic topic string, delimited by forward-slashes
 \* @param rest [out] will point to remainder of topic
 \* @return newly-allocated string containing the first token of topic
 \* Must be Osal\_Free'd by caller!
 \*/
char \*Funnel\_Topic\_Split(const char \*topic, const char \* \* rest);

/\*\*
 \* add the result of a GET request to the body of a non-idempotent reply
 \* @param req reply
 \* @return true on success
 \*/
bool Funnel\_Check\_Add\_Nonidempotent\_Body(bond\_req\_t \* req);

/\*\*
 \* generate a gratuitous request but don't send it
 \* @param topic the topic to make the request on, the caller retains ownership
 \* @param method the method to use for the request
 \* @param body the body of the request, this function takes ownership
 \* @param flags flags to add to the request, beyond the default
 \* BOND\_REQ\_FLAG\_QUIET and BOND\_REQ\_FLAG\_BCAST
 \* @param class the requestor class to use for this gratuitous request
 \* @return the gratuitous request
 \*/
bond\_req\_t \* Funnel\_Gratuitous\_Req(const char \* topic,
 bond\_req\_method\_t method,
 cJSON \* body,
 uint8\_t flags,
 bond\_req\_uuid\_class\_t class);

/\*\*
 \* generate a gratuitous request and send it
 \* @param topic the topic to make the request on, the caller retains ownership
 \* @param method the method to use for the request
 \* @param body the body of the request, this function takes ownership
 \* @param class the class to use for the request
 \* @return true iff request sent
 \*/
bool Funnel\_Gratuitous\_Req\_Reply\_With\_Class(const char \*topic,
 bond\_req\_method\_t method,
 cJSON \* body,
 bond\_req\_uuid\_class\_t class);

/\*\*
 \* generate a gratuitous request and send it using BOND class
 \* @param topic the topic to make the request on, the caller retains ownership
 \* @param method the method to use for the request
 \* @param body the body of the request, this function takes ownership
 \* @return true iff request sent
 \*/
bool Funnel\_Gratuitous\_Req\_Reply(const char \* topic,
 bond\_req\_method\_t method,
 cJSON \* body);

/\*\*
 \* generate a gratuitous get and send it
 \* @param topic
 \* @return true if request sent
 \*/
bool Funnel\_Gratuitous\_Get\_Reply(const char \*topic);
/\*\*
 \* get name of transport (possibilities: "mqtt", "http", "cli", "bond")
 \* @param transport\_id id (index) of transport
 \* @return name as const string
 \*/
const char \*Funnel\_Get\_Transport\_Name(int transport\_id);

/\*\*
 \* convert 64-bit key to 8- or 16-nibble string
 \* 8-nibble string used if upper 32-bits of key are zero
 \* @param key
 \* @param buf [out]
 \* @param buf\_size must be >= 17
 \* @return buf or NULL on failure
 \*/
const char \* Funnel\_Key2String(uint64\_t key, char \* buf, uint32\_t buf\_size);
```
이것은 `Funnel.h`입니다:```#프라그마 한 번#include #포함 #포함 #include "cJSON.h"#포함 "Bond\_Req.h"/\* Funnel\_Tree.h에 정의됨 \*/typedef 구조체 퍼널\_tree\_s 퍼널\_tree\_t;typedef enum { funnel\_auth\_level\_none = 0, FUNNEL\_AUTH\_LEVEL\_DISCOVER, funnel\_auth\_level\_control, funnel\_auth\_level\_admin} FUNNEL\_AUTH\_LEVEL\_T;#define FUNNEL\_CONNECTION\_BROADCAST -1#define FUNNEL\_TRANSPORT\_GRATUITOUS -42#define FUNNEL\_TRANSPORT\_HASH\_ONLY -43/\*\* \* 요청 핸들러 함수 포인터 \* 해당 퍼널 트리 노드에 대한 @param ft 포인터 \* 이 핸들러에 유용한 데이터, 키, 해시를 포함합니다. 처리할 요청에 대한 포인터 \* [인] 요청 포인터 \* [아웃] 퍼널이 전송할 응답, FUNNEL\_REPLY\_IMMEDIATE인 경우 \* \* @return FUNNEL\_REPLY\_DEFERRED: \* 응답을 보내는 사람: 핸들러와 연결된 타이머 \* 누가 요청을 해제하는가: 핸들러 \* 자녀가 열거되어 있습니까?: 아니요 \* \* 퍼널\_응답\_즉시 \* 응답을 보내는 사람: Funnel \* 요청을 해제하는 사람: 퍼널 \* 자녀 열거됨?: !Bond\_Status\_Is\_Error(req.status) 인 경우에만 \* \* @주 핸들러가 Funnel\_Process\_Up()을 호출하는 것은 \_가능\_하지만, \* 강력히 권장하지 않습니다! 리퀘스트를 통한 응답의 이유는 \* 매개변수를 통한 응답은 핸들러 함수의 스택을 유지하지 않기 때문입니다. \* 컨텍스트를 유지하는 것을 피하고, 더 나아가 다른 자식 함수가 \* 열거될 수 있기 때문입니다. \*/typedef void (\*request\_handler\_t) (funnel\_tree\_t \* ft, bond\_req\_t \* req);/\*\* 전송에서 본드 요청을 보내기 위한 \* 콜백 \* @param req 요청 전송할 요청 메시지 전송을 위해 대기 중인 경우 \* @return true \* / 메시지가 전송되지 않으면 거짓 \*/typedef bool (\*funnel\_transport\_cb\_t)(bond\_req\_t \* req);/\*\* \* 퍼널 싱글톤 초기화 \* @return true \*/bool Funnel\_Init();/\*\* \* 모든 퍼널 리소스 해제 \* @warning 이 시점 이후 모든 퍼널(또는 퍼널\_tree) 호출이 실패할 수 있습니다! \* @return true \*/bool Funnel\_Deinit();/\*\* \* 전송 등록 \* @param f 업 본드 요청을 전송할 함수 \* @param transport\_id [out] Funnel\_Process\_Down에 필요한 아이디 전송 테이블에 추가되면 \* @return true \*/bool Funnel\_Register\_Transport(funnel\_transport\_cb\_t f., const char \*name, int \*transport\_id);/\*\* \* 응답이 객체일 때마다 해시를 추가합니다. \* @param 요청 응답을 보강합니다. \* @param ft 해당 퍼널 트리 노드 해시가 추가되면 \* @return true \*/bool Funnel\_Req\_Add\_Hash(bond\_req\_t \* req, funnel\_tree\_t \* ft);/\*\* \* 해시 없이 응답하기 위해 자식 열거 추가 \* @param req 응답을 보강합니다. 자녀가 열거된 경우 \* @return true \* @note 답장 200개까지만 추가합니다. \* 201개는 새 아이디만 포함하므로 제외합니다. \*/bool Funnel\_Req\_Add\_Children\_No\_Hash(bond\_req\_t \* req, funnel\_tree\_t \* ft);/\*\* \* 응답에 자녀 열거 추가 \* @param req 응답을 보강합니다. 자녀가 열거된 경우 \* @return true \* @note 200개의 답글만 추가합니다. \* 201개는 새 ID만 포함하므로 제외합니다. \*/bool Funnel\_Req\_Add\_Children(bond\_req\_t \* req, funnel\_tree\_t \* ft);/\*\* \* 다운 요청 처리(앱/클라우드에서 BOND로) \* @param req 요청 처리할 요청 \* 이 함수는 요청 객체의 소유권을 가져옵니다, \* 소유권을 가져와서 오류 조건에서도 해제합니다. 이 함수가 반환된 후 \* req는 유효하지 않게 됩니다. \* @return true \*/bool Funnel\_Process\_Down(bond\_req\_t \* req);/\*\* \* 업 요청을 처리합니다(BOND에서 앱/클라우드로). \* @param 요청을 보낼 요청 \* @return true \*/bool Funnel\_Process\_Up(bond\_req\_t \* req);/\*\* \* 토픽을 첫 번째와 나머지 토픽으로 분할합니다. \* @param topic 주제 문자열, 슬래시로 구분됨 \* @param rest [out]은 토픽의 나머지 부분을 가리킴 \* 주제 첫 번째 토큰을 포함하는 새로 할당된 문자열을 반환합니다. \* 호출자가 오살\_프리드해야 합니다! \*/char \*Funnel\_Topic\_Split(const char \*topic, const char \* \* rest);/\*\* \* 비무효 응답 본문에 GET 요청 결과를 추가합니다. \* @param req reply \* @성공 시 참 반환 \*/bool Funnel\_Check\_Add\_Nonidempotent\_Body(bond\_req\_t \* req);/\*\* \* 무상 요청을 생성하지만 전송하지 않음 \* @param topic 요청을 할 주제, 호출자가 소유권을 보유합니다. \* @param method 요청에 사용할 메서드 \* @param body 요청 본문, 이 함수가 소유권을 가짐 기본값 외에 요청에 추가할 플래그 \* @param flags 요청에 추가할 플래그 \* BOND\_REQ\_FLAG\_QUIET 및 BOND\_REQ\_FLAG\_BCAST \* @param 클래스 이 무상 요청에 사용할 요청자 클래스 \* 무료 요청을 반환합니다. \*/bond\_req\_t \* Funnel\_Gratuitous\_Req(const char \* topic, bond\_req\_method\_t method, cJSON \* body, uint8\_t 플래그, bond\_req\_uuid\_class\_t class);/\*\* \* 무상 요청을 생성하여 전송합니다. \* @param topic 요청할 주제, 호출자가 소유권을 보유합니다. \* @param method 요청에 사용할 메서드 \* @param body t