— 2013/11/20/星期三
学习进度:
(1) 已经阅读完RFC6282,6LowPan适配层IPHC,NHC协议设计,及其代码实现。
(2) 已经阅读完RFC4861 邻居发现协议及其代码实现。
(3) 本文档说明contiki 系统中UDP报文的发送流程,分析函数调用关系。
待完成任务:
(1) Contiki中数据包的接收流程,分析函数调用关系。
(2) 再详细阅读RFC4944和RFC6282,分析其实现方式的区别和特点。
(3) 阅读Rime协议栈,了解Mesh-under 路由原理和代码实现。
(4) 学习TCP/IP详解卷,补充相关知识。
一、网络层UDP传输
下面讨论发送数据包的流程。发数据包的过程相对复杂。用到了回调机制。下面分别说明。
以doc/example-program.c 为例,该函数执行的事情是:周期性的广播发送hello。
PROCESS_THREAD(example_program_process,ev, data)
{
static structuip_udp_conn *c;
PROCESS_BEGIN();
c = udp_broadcast_new(UIP_HTONS(4321), NULL);
while(1)
{
etimer_set(&timer,CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
tcpip_poll_udp(c);
PROCESS_WAIT_EVENT_UNTIL(ev ==tcpip_event);
uip_send("Hello", 5);
}
PROCESS_END();
}
首先解释:c =udp_broadcast_new(UIP_HTONS(4321), NULL);先创建UDP端口号是port=4321。
接下来从tcpip_poll_udp(c) 开始
void
tcpip_poll_udp(structuip_udp_conn *conn)
{
process_post(&tcpip_process, UDP_POLL, conn); // 给tcpip_process 传递消息 UDP_POLL
}
当tcpip_process 收到消息后,进行的处理如下:
static voideventhandler(process_event_t ev, process_data_t data) //core/net/tcpip.c
{
switch(ev) {
case PROCESS_EVENT_EXITED:
case PROCESS_EVENT_TIMER:
case TCP_POLL:
case UDP_POLL:
if(data != NULL) {
uip_udp_periodic_conn(data); // 产生数据
tcpip_ipv6_output(); // IPv6 发送也许有报头压缩
}
break;
};
}
其中uip_udp_periodic_conn 用于产生数据包,tcpip_ipv6_output()用于发送。
先看uip_udp_periodic_conn:
#define uip_udp_periodic_conn(conn) do { uip_udp_conn =conn; \
uip_process(UIP_UDP_TIMER); } while(0)
转到uip_process()。 这是uip