0.前言
1.MAC48地址变为IPv6地址
在IPV6中有一种称为无状态自动配置的机制使用EUI-64地址来自动配置IPV6地址,EUI-64格式即扩展唯一标识符,相当于MAC-48地址。所谓无状态自动配置是指在网络中没有DHCP服务器的情况下,允许节点自行配置IPV6地址的机制。
【工作原理】
自动将48bit的以太网MAC地址扩展成64bit,再挂在一个64bit的前缀后面,组成一个IPV6地址,步骤共有三步。
【第一步】将48位的MAC地址从中间分开,插入一个固定数值FFFE(16进制)。
【第二步】将第7个比特位反转,如果原来是0就变为1,如果原来是1就变为0 。
【第三步】加上64位的网络前缀这就是一个完整的IPV6地址
【反转原因】
在MAC地址中,第7比特为1表示本地管理,为0表示全球管理。
在EUI-64格式中,第7位为1表示全球唯一,为0表示本地唯一。
【具体例子】——【】
图1 IPv6和EUI-64地址变化
【1】原MAC48地址为39-A7-94-07-CB-D0,从中间断开插入FF-FE,变为39-A7-94--FF-FE-07-CB-D0。
【2】第7个比特反转(从左往右数),变为3B-A7-94-FF-FE-07-CB-D0
【3】加入网络前缀,若前缀为链路本地地址则网络前缀为FE-80-00-00-00-00.
IPV6地址最终为FE-80-00-00-00-00-00-00-3B-A7-94-FF-FE-07-CB-D0
可简写为FE80::3BA7:94FF:FE07:CBD0
2. IEEE 802.15.4地址变为IPv6地址
CC2530符合IEEE802.15.4标准,在出厂时便有一个IEEE地址,IEEE802.15.4地址共有8字节(IEEE802.15.4分为长地址8字节和短地址2字节)。由于CC2530的IEEE地址共有8字节,扩展IPv6地址时便可省略上文提到的步骤1,只执行步骤2和步骤3即可。
【如何获得CC2530 IEEE地址】
使用SmartRF Flash Programmer便可获得CC2530地址,通过CC2530仿真器连接CC2530目标板即可。此时CC2530的IEEE地址为00-12-4B-00-02-6E-7D-AA。那么链路本地地址为FE-80-00-00-00-00-00-00-02-12-4B-00-02-6E-7D-AA,请注意IEEE地址的首字节00被翻转为02。
可简写为FE80::212:4B00:26E:7DAA。
图2 CC2530 IEEE地址
3.contiki中如何使用
很多人发邮件给我询问关于CC2530 UDP例子,问题多数反应Client和Server之间无法收发数据(除了这之外还有重启问题,下篇博文再说),
【问题原因】
Client程序中未指定Server的Ipv6地址,由于未指定server的Ip地址,server便直接过滤client发送的无线报文。
【解决方法】
修改client.c中的关于server IPv6地址设定。(链路单播地址,全局单播地址以后的博文再讨论)
// 设置链路单播地址
uip_ip6addr(&ipaddr,0xfe80,0,0,0,0x0212,0x4b00,0x26e,0x7daa);
// 设置全局单播地址
uip_ip6addr(&ipaddr,0xaaaa,0,0,0,0x0212,0x4b00,0x26e,0x7daa);
-
PROCESS_THREAD(udp_client_process, ev, data)
-
{
-
static struct etimer et;
-
uip_ipaddr_t ipaddr;
-
PROCESS_BEGIN();
-
-
uip_ip6addr(&ipaddr,0xfe80,0,0,0,0x0212,0x4b00,0x26e,0x7daa);
-
-
l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL);
-
if(!l_conn) {
-
PRINTF("udp_new l_conn error.\n");
-
}
-
udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT));
-
PRINTF("Link-Local connection with ");
-
PRINT6ADDR(&l_conn->ripaddr);
-
PRINTF(" local/remote port %u/%u\n",
-
UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport));
-
-
uip_ip6addr(&ipaddr,0xaaaa,0,0,0,0x0212,0x4b00,0x26e,0x7daa);
-
g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL);
-
if(!g_conn) {
-
PRINTF("udp_new g_conn error.\n");
-
}
-
udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT));
4.参考资料
【】
【】
转载:http://blog.csdn.net/xukai871105/article/details/23615211
阅读(905) | 评论(0) | 转发(0) |