注册回调函数用了三个宏来实现,巧妙的用了##来拼接函数
#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);
}