simple-udp.c中的simple_udp_register()函数的解析,重点为回掉函数,结合broadcast-udp.c这个例子对其进行分析。
broadcast-udp.c是基于simple-udp的一个广播数据报的例子。
int simple_udp_register(structsimple_udp_connection *c,
uint16_t local_port,
uip_ipaddr_t *remote_addr,
uint16_t remote_port,
simple_udp_callback receive_callback)
该函数的声明在simple-udp.h头文件进行声明,注册一个UDP连接
receive_callback 一个指针,指向一个函数,该函数在接收到数据包时将被调用
返回值:0,无法分配UDP连接;1,连接成功分配
该函数注册一个UDP连接,同时附加一个回调函数给它。该毁掉函数在有数据包到来时将被调用。本地UDP端口可以设置为0来表示一个临时的UDP端口应当被分配。远程IP地址可以为空,表示来自任何IP地址的数据包应当被接受。
同时,在该头文件中,也声明了simple_udp_callback回掉函数,需要注意的是,这里只是声明,真正的实现是在调用方broadcast-udp.c这个例子程序中。
回调函数:typedef void (*simple_udp_callback)(struct simple_udp_connection *c,
constuip_ipaddr_t *source_addr,
uint16_tsource_port,
constuip_ipaddr_t *dest_addr,
uint16_tdest_port,
constuint8_t *data, uint16_t datalen);
声明一个回调函数指针,并将其转换成simple_udp_callback类型。(声明在simple-udp.h中)
但该回调函数的实现是在例子程序broadcast-udp.c中通过名为recerver的函数实现的。
这是回调函数的典型应用实例。
simple_udp_register函数中对回掉函数进行了赋值,通过下面这行代码:
c->receive_callback = receive_callback
这句话看起来像是赋值,其实receive_callback都是指针,这样,两个指针是指向了同一个内存空间,即回调函数,在本例中,也就是broadcast-udp.c中的receiver函数,这样对c->receive_callback的操作就等同于receiver的操作,这样就明白了receiver其实是通过c->receive_callback进行赋值的(这种用法在contiki中很常见),赋值过程发生在simple-udp.c的进程处理函数中,如下:
if(c->receive_callback != NULL) {
PROCESS_CONTEXT_BEGIN(c->client_process);
c->receive_callback(c,
&(UIP_IP_BUF->srcipaddr),
UIP_HTONS(UIP_IP_BUF->srcport),
&(UIP_IP_BUF->destipaddr),
UIP_HTONS(UIP_IP_BUF->destport),
databuffer,uip_datalen());
PROCESS_CONTEXT_END();
其中,
#define UIP_IP_BUF ((struct uip_udpip_hdr*)&uip_buf[UIP_LLH_LEN])
而,
/* The UDP and IP headers. */struct uip_udpip_hdr {
#if UIP_CONF_IPV6
/* IPv6 header. */
uint8_t vtc,
tcf;
uint16_t flow;
uint8_t len[2];
uint8_t proto, ttl;
uip_ip6addr_t srcipaddr, destipaddr;
#else /* UIP_CONF_IPV6 */
/* IP header. */
uint8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
uint16_t ipchksum;
uip_ipaddr_t srcipaddr, destipaddr;
#endif /* UIP_CONF_IPV6 */
/* UDP header. */
uint16_t srcport,
destport;
uint16_t udplen;
uint16_t udpchksum;
};
这样就明白&(UIP_IP_BUF->srcipaddr)的含义就是指向源地址;UIP_IP_BUF->srcport指向端口号。