static network_uint64_t _init_iid(uint8_t *l2addr, size_t l2addr_len) { network_uint64_t res = { 0 }; if (l2addr_len <= 4) { res = byteorder_htonll(0x000000fffe000000); if (l2addr_len == 1) { res.u8[7] = l2addr[0]; } else if (l2addr_len == 2) { res.u8[6] = l2addr[0]; res.u8[7] = l2addr[1]; } else if (l2addr_len == 4) { res.u8[0] = l2addr[0]; res.u8[1] = l2addr[1]; res.u8[6] = l2addr[2]; res.u8[7] = l2addr[3]; } } else if (l2addr_len == 8) { network_uint64_t *l2addr_u64 = (network_uint64_t *)l2addr; res = *l2addr_u64; res.u8[0] ^= 0x02; /* swap local/universal bit */ } return res; }
static void send(int argc, char **argv) { if (argc < 2) { puts("Send n bytes to fe80::1\n"); puts("Usage: send <n>"); return; } ipv6_hdr_t ipv6_hdr; netdev_hlist_t ulh = { NULL, NULL, &ipv6_hdr, sizeof(ipv6_hdr_t) }; long long n = atoll(argv[1]); uint8_t bytes[n]; uint16_t dest = 1; if (n < 0 || n >= (1 << 16)) { puts("n must be a 16-bit unsigned integer"); return; } for (int i = 0; i < n; i++) { bytes[i] = data_value; } data_value++; ulh.next = &ulh; ulh.prev = &ulh; ipv6_hdr_set_version(&ipv6_hdr); ipv6_hdr_set_trafficclass(&ipv6_hdr, 0); ipv6_hdr_set_flowlabel(&ipv6_hdr, 0); ipv6_hdr.length = byteorder_htons((uint16_t)n); ipv6_hdr.nextheader = IPV6_PROTO_NUM_NONE; ipv6_hdr.hoplimit = 64; ipv6_hdr.srcaddr.u64[0] = byteorder_htonll(0xfe80000000000000); ipv6_hdr.srcaddr.u32[2] = byteorder_htonl(0x000000ff); ipv6_hdr.srcaddr.u16[6] = byteorder_htons(0xfe00); ipv6_hdr.srcaddr.u16[7] = byteorder_htons(src); ipv6_hdr.destaddr.u64[0] = byteorder_htonll(0xfe80000000000000); ipv6_hdr.destaddr.u32[2] = byteorder_htonl(0x000000ff); ipv6_hdr.destaddr.u16[6] = byteorder_htons(0xfe00); ipv6_hdr.destaddr.u16[7] = byteorder_htons(dest); netapi_send_data2(sixlowpan, &ulh, &dest, sizeof(uint16_t), bytes, n); }
int watr_li_network_init (void) { DEBUG("%s()\n", __func__); kernel_pid_t ifs[GNRC_NETIF_NUMOF]; uint16_t channel = WATR_LI_CHANNEL; uint16_t pan_id = WATR_LI_PAN; if (0 >= gnrc_netif_get(ifs)) { puts ("[watr_li_network_init] ERROR: failed to get ifaces!"); return -1; } if (0 > gnrc_netapi_set(ifs[0], NETOPT_CHANNEL, 0, (uint16_t *)&channel, sizeof(uint16_t))) { puts ("[watr_li_network_init] ERROR: failed to set channel!"); return -1; } if (0 > gnrc_netapi_set(ifs[0], NETOPT_NID, 0, (uint16_t *)&pan_id, sizeof(uint16_t))) { puts ("[watr_li_network_init] ERROR: failed to set pan_id!"); return -1; } uint8_t iid[8]; if (0 > gnrc_netapi_get(ifs[0], NETOPT_IPV6_IID, 0, &iid, sizeof(iid))) { puts ("[watr_li_network_init] ERROR: failed to get IPv6 IID!"); return -1; } #ifdef WATR_LI_GLOBAL_IPV6 ipv6_addr_t myaddr; ipv6_addr_set_aiid(&myaddr, iid); myaddr.u64[0] = byteorder_htonll(0x2015110700000000); if (0 > gnrc_ipv6_netif_add_addr(ifs[0], &myaddr, 64, 0)) { puts ("[watr_li_network_init] ERROR: failed to set IPv6 addr!"); return -1; } #endif send_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (send_sock < 0) { puts("[watr_li_network_init] ERROR: initializing send socket!"); return -1; } /* FIXME stringify my_id. we'll be needing this in a sec. */ memset(my_id, 0, sizeof(my_id)); sprintf(my_id, "%02X%02X%02X%02X%02X%02X%02X%02X", iid[0],iid[1],iid[2],iid[3],iid[4],iid[5],iid[6],iid[7]); /* Add my_id to humidity_path */ register_path = (coap_endpoint_path_t) {1, {"nodes"}}; //FIXME: should be nodes/my_id ? humidity_path = (coap_endpoint_path_t) {3, {"nodes", my_id, "humidity"}}; if (0 > watr_li_set_root_addr(watr_li_root_addr_str)) { puts("[watr_li_network_init] ERROR: failed to set root_addr!"); return -1; } if (0 > watr_li_register_at_root(my_id)) { puts("[watr_li_network_init] ERROR: failed to register at root!"); return -1; } return 0; }