アリIot SDKの登録コールバック分析
コールバック関数の登録は3つのマクロで実現し、巧みに##で関数をつなぎ合わせた.
コールバック関数を登録すると、次のマクロが呼び出されます.
マクロが展開されるとiotx_が直接呼び出されます.register_for_ITE_STATE_EVERYTHING、入力パラメータeverything_state_handle
実は関数呼び出しです
つまり、次の関数を呼び出します.次の関数は、すべての機能(impl_event_map_t g_impl_event_map[]というデータ型に定義されています)をこのコールバックに登録します.つまり、次のいずれかの機能イベントがトリガーされ、転送されたcallbackが呼び出されます.
関数の定義は次のとおりです.
だからこのIOT_RegisterCallback(ITE_STATE_EVERYTHING, everything_state_handle);デバッグ用のはずですが、各機能がトリガーされるとeverythingが呼び出されます.state_handle
同様に、次の関数はiotx_を呼び出すはずです.register_for_ITE_IDENTITY_RESPONSE(identity_response_handle);
しかし、この関数は見つかりませんでした.プリコンパイルで生成されました.マクロで定義
さらに下を見るとマクロ定義があります
そうです.このマクロ定義で関数iotx_を宣言します.register_for_ITE_IDENTITY_RESPONSE()
宣言int iotx_register_for_ITE_IDENTITY_RESPONSE( int (*cb)(const char *));
宣言int iotx_register_for_ITE_STATE_EVERYTHING(state_handler_t cb);
上記の関数を定義するマクロもあります.
これらの関数定義はinfra_compat.cで定義し、mqtt_を抽出するexample.cで使った解析
マクロを置き換えると、次のようになります.
この関数は指定されたコールバック関数の登録を担当し、ITE_が発生します.IDENTITY_RESPONSEイベントの場合、転送されたcallbackが呼び出されます.
この関数は指定したコールバック関数を返し、呼び出し者に呼び出されます.
呼び出し形式
#define IOT_RegisterCallback(evt, cb) iotx_register_for_##evt(cb)
#define DECLARE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb);
#define DEFINE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb) { \
if (evt < 0 || evt >= sizeof(g_impl_event_map)/sizeof(impl_event_map_t)) {return -1;} \
g_impl_event_map[evt].callback = (void *)callback;return 0;}
int everything_state_handle(const int state_code, const char * state_message)
{
EXAMPLE_TRACE("code: -0x%04x, message: %s", -state_code, state_message);
return 0;
}
IOT_RegisterCallback(ITE_STATE_EVERYTHING, everything_state_handle);
コールバック関数を登録すると、次のマクロが呼び出されます.
#define IOT_RegisterCallback(evt, cb) iotx_register_for_##evt(cb)
マクロが展開されるとiotx_が直接呼び出されます.register_for_ITE_STATE_EVERYTHING、入力パラメータeverything_state_handle
実は関数呼び出しです
iotx_register_for_ITE_STATE_EVERYTHING(everything_state_handle);
つまり、次の関数を呼び出します.次の関数は、すべての機能(impl_event_map_t g_impl_event_map[]というデータ型に定義されています)をこのコールバックに登録します.つまり、次のいずれかの機能イベントがトリガーされ、転送されたcallbackが呼び出されます.
関数の定義は次のとおりです.
int iotx_register_for_ITE_STATE_EVERYTHING(state_handler_t callback)
{
int idx = 0;
for (idx = ITE_STATE_EVERYTHING; idx <= ITE_STATE_DEV_MODEL; idx++) {
g_impl_event_map[idx].callback = (void *)callback;
}
return 0;
}
typedef struct {
int eventid;
void *callback;
} impl_event_map_t;
static impl_event_map_t g_impl_event_map[] = {
{ITE_AWSS_STATUS, NULL},
{ITE_CONNECT_SUCC, NULL},
{ITE_CONNECT_FAIL, NULL},
{ITE_DISCONNECTED, NULL},
{ITE_RAWDATA_ARRIVED, NULL},
{ITE_SERVICE_REQUEST, NULL},
{ITE_SERVICE_REQUEST_EXT, NULL},
{ITE_PROPERTY_SET, NULL},
{ITE_PROPERTY_GET, NULL},
#ifdef DEVICE_MODEL_SHADOW
{ITE_PROPERTY_DESIRED_GET_REPLY, NULL},
#endif
{ITE_REPORT_REPLY, NULL},
{ITE_TRIGGER_EVENT_REPLY, NULL},
{ITE_TIMESTAMP_REPLY, NULL},
{ITE_TOPOLIST_REPLY, NULL},
{ITE_PERMIT_JOIN, NULL},
{ITE_INITIALIZE_COMPLETED, NULL},
{ITE_FOTA, NULL},
{ITE_COTA, NULL},
{ITE_MQTT_CONNECT_SUCC, NULL},
{ITE_CLOUD_ERROR, NULL},
{ITE_DYNREG_DEVICE_SECRET, NULL},
{ITE_IDENTITY_RESPONSE, NULL},
{ITE_STATE_EVERYTHING, NULL},
{ITE_STATE_USER_INPUT, NULL},
{ITE_STATE_SYS_DEPEND, NULL},
{ITE_STATE_MQTT_COMM, NULL},
{ITE_STATE_WIFI_PROV, NULL},
{ITE_STATE_COAP_LOCAL, NULL},
{ITE_STATE_HTTP_COMM, NULL},
{ITE_STATE_OTA, NULL},
{ITE_STATE_DEV_BIND, NULL},
{ITE_STATE_DEV_MODEL, NULL}
};
だからこのIOT_RegisterCallback(ITE_STATE_EVERYTHING, everything_state_handle);デバッグ用のはずですが、各機能がトリガーされるとeverythingが呼び出されます.state_handle
同様に、次の関数はiotx_を呼び出すはずです.register_for_ITE_IDENTITY_RESPONSE(identity_response_handle);
しかし、この関数は見つかりませんでした.プリコンパイルで生成されました.マクロで定義
int identity_response_handle(const char *payload)
{
EXAMPLE_TRACE("identify: %s", payload);
return 0;
}
IOT_RegisterCallback(ITE_IDENTITY_RESPONSE, identity_response_handle);
さらに下を見るとマクロ定義があります
#define DECLARE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb);
そうです.このマクロ定義で関数iotx_を宣言します.register_for_ITE_IDENTITY_RESPONSE()
宣言int iotx_register_for_ITE_IDENTITY_RESPONSE( int (*cb)(const char *));
DECLARE_EVENT_CALLBACK(ITE_IDENTITY_RESPONSE, int (*cb)(const char *))
宣言int iotx_register_for_ITE_STATE_EVERYTHING(state_handler_t cb);
typedef int (*state_handler_t)(const int state_code, const char *state_message);
DECLARE_EVENT_CALLBACK(ITE_STATE_EVERYTHING, state_handler_t cb);
上記の関数を定義するマクロもあります.
#define DEFINE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb) { \
if (evt < 0 || evt >= sizeof(g_impl_event_map)/sizeof(impl_event_map_t)) {return -1;} \
g_impl_event_map[evt].callback = (void *)callback;return 0;}
これらの関数定義はinfra_compat.cで定義し、mqtt_を抽出するexample.cで使った解析
DEFINE_EVENT_CALLBACK(ITE_IDENTITY_RESPONSE, int (*callback)(const char *))
マクロを置き換えると、次のようになります.
int iotx_register_for_ITE_IDENTITY_RESPONSE( int (*callback)(const char *) )
{
if (ITE_IDENTITY_RESPONSE< 0 || ITE_IDENTITY_RESPONSE>= sizeof(g_impl_event_map)/sizeof(impl_event_map_t))
{
return -1;
}
g_impl_event_map[evt].callback = (void *)callback;
return 0;
}
この関数は指定されたコールバック関数の登録を担当し、ITE_が発生します.IDENTITY_RESPONSEイベントの場合、転送されたcallbackが呼び出されます.
この関数は指定したコールバック関数を返し、呼び出し者に呼び出されます.
void *iotx_event_callback(int evt)
{
if (evt < 0 || evt >= sizeof(g_impl_event_map) / sizeof(impl_event_map_t)) {
return NULL;
}
return g_impl_event_map[evt].callback;
}
呼び出し形式
void *callback = NULL;
callback = iotx_event_callback(ITE_IDENTITY_RESPONSE);
if (callback)
{
((int (*)(const char*))callback)(payload);
}