END_TEST /** Call tcp_new() and tcp_abort() and test memp stats */ START_TEST(test_tcp_listen_passive_open) { struct tcp_pcb *pcb, *pcbl; struct tcp_pcb_listen *lpcb; struct netif netif; struct test_tcp_txcounters txcounters; struct test_tcp_counters counters; struct pbuf *p; ip_addr_t src_addr; err_t err; LWIP_UNUSED_ARG(_i); fail_unless(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0); test_tcp_init_netif(&netif, &txcounters, &test_local_ip, &test_netmask); /* initialize counter struct */ memset(&counters, 0, sizeof(counters)); pcb = tcp_new(); EXPECT_RET(pcb != NULL); err = tcp_bind(pcb, &netif.ip_addr, 1234); EXPECT(err == ERR_OK); pcbl = tcp_listen(pcb); EXPECT_RET(pcbl != NULL); EXPECT_RET(pcbl != pcb); lpcb = (struct tcp_pcb_listen *)pcbl; ip_addr_set_ip4_u32_val(src_addr, lwip_htonl(lwip_ntohl(ip_addr_get_ip4_u32(&lpcb->local_ip)) + 1)); /* check correct syn packet */ p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345, lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN); EXPECT(p != NULL); if (p != NULL) { /* pass the segment to tcp_input */ test_tcp_input(p, &netif); /* check if counters are as expected */ EXPECT(txcounters.num_tx_calls == 1); } /* check syn packet with short length */ p = tcp_create_segment(&src_addr, &lpcb->local_ip, 12345, lpcb->local_port, NULL, 0, 12345, 54321, TCP_SYN); EXPECT(p != NULL); EXPECT(p->next == NULL); if ((p != NULL) && (p->next == NULL)) { p->len -= 2; p->tot_len -= 2; /* pass the segment to tcp_input */ test_tcp_input(p, &netif); /* check if counters are as expected */ EXPECT(txcounters.num_tx_calls == 1); } tcp_close(pcbl); }
/** * Initialize request struct to be sent to server. */ static void sntp_initialize_request(struct sntp_msg *req) { memset(req, 0, SNTP_MSG_LEN); req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT; #if SNTP_CHECK_RESPONSE >= 2 { u32_t sntp_time_sec, sntp_time_us; /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */ SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us); sntp_last_timestamp_sent[0] = lwip_htonl(sntp_time_sec + DIFF_SEC_1900_1970); req->transmit_timestamp[0] = sntp_last_timestamp_sent[0]; /* we send/save us instead of fraction to be faster... */ sntp_last_timestamp_sent[1] = lwip_htonl(sntp_time_us); req->transmit_timestamp[1] = sntp_last_timestamp_sent[1]; } #endif /* SNTP_CHECK_RESPONSE >= 2 */ }
/** * @ingroup netif_ip6 * Create a link-local IPv6 address on a netif (stored in slot 0) * * @param netif the netif to create the address on * @param from_mac_48bit if != 0, assume hwadr is a 48-bit MAC address (std conversion) * if == 0, use hwaddr directly as interface ID */ void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit) { u8_t i, addr_index; /* Link-local prefix. */ ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul); ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0; /* Generate interface ID. */ if (from_mac_48bit) { /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */ ip_2_ip6(&netif->ip6_addr[0])->addr[2] = lwip_htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) | ((u32_t)(netif->hwaddr[1]) << 16) | ((u32_t)(netif->hwaddr[2]) << 8) | (0xff)); ip_2_ip6(&netif->ip6_addr[0])->addr[3] = lwip_htonl((0xfeul << 24) | ((u32_t)(netif->hwaddr[3]) << 16) | ((u32_t)(netif->hwaddr[4]) << 8) | (netif->hwaddr[5])); } else { /* Use hwaddr directly as interface ID. */ ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0; ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0; addr_index = 3; for (i = 0; (i < 8) && (i < netif->hwaddr_len); i++) { if (i == 4) { addr_index--; } ip_2_ip6(&netif->ip6_addr[0])->addr[addr_index] |= ((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03)); } } /* Set address state. */ #if LWIP_IPV6_DUP_DETECT_ATTEMPTS /* Will perform duplicate address detection (DAD). */ netif->ip6_addr_state[0] = IP6_ADDR_TENTATIVE; #else /* Consider address valid. */ netif->ip6_addr_state[0] = IP6_ADDR_PREFERRED; #endif /* LWIP_IPV6_AUTOCONFIG */ }
static void frame_client_create_net_data(struct msfd_report_collection_data_sn_st *data) { int i; for (i=0; i<sizeof(data->coll_data.pt_ct_app_p)/sizeof(data->coll_data.pt_ct_app_p[0]); i++) { data->coll_data.pt_ct_app_p[i] = lwip_htonl(data->coll_data.pt_ct_app_p[i]); } for (i=0; i<sizeof(data->coll_data.pt_ct_ap_p)/sizeof(data->coll_data.pt_ct_ap_p[0]); i++) { data->coll_data.pt_ct_ap_p[i] = lwip_htonl(data->coll_data.pt_ct_ap_p[i]); } for (i=0; i<sizeof(data->coll_data.pt_ct_v)/sizeof(data->coll_data.pt_ct_v[0]); i++) { data->coll_data.pt_ct_v[i] = lwip_htonl(data->coll_data.pt_ct_v[i]); } for (i=0; i<sizeof(data->coll_data.pt_ct_i)/sizeof(data->coll_data.pt_ct_i[0]); i++) { data->coll_data.pt_ct_i[i] = lwip_htonl(data->coll_data.pt_ct_i[i]); } data->last_update_time = lwip_htonl(data->last_update_time); }
/* Send 6LoWPAN TX packets as UDP broadcast */ static err_t zepif_linkoutput(struct netif *netif, struct pbuf *p) { err_t err; struct pbuf *q; struct zep_hdr *zep; struct zepif_state *state; LWIP_ASSERT("invalid netif", netif != NULL); LWIP_ASSERT("invalid pbuf", p != NULL); if (p->tot_len > ZEP_MAX_DATA_LEN) { return ERR_VAL; } LWIP_ASSERT("TODO: support chained pbufs", p->next == NULL); state = (struct zepif_state *)netif->state; LWIP_ASSERT("state->pcb != NULL", state->pcb != NULL); q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct zep_hdr) + p->tot_len, PBUF_RAM); if (q == NULL) { return ERR_MEM; } zep = (struct zep_hdr *)q->payload; memset(zep, 0, sizeof(struct zep_hdr)); zep->prot_id[0] = 'E'; zep->prot_id[1] = 'X'; zep->prot_version = 2; zep->type = 1; /* Data */ zep->channel_id = 0; /* whatever */ zep->device_id = lwip_htons(1); /* whatever */ zep->crc_mode = 1; zep->unknown_1 = 0xff; zep->seq_num = lwip_htonl(state->seqno); state->seqno++; zep->len = (u8_t)p->tot_len; err = pbuf_take_at(q, p->payload, p->tot_len, sizeof(struct zep_hdr)); if (err == ERR_OK) { #if ZEPIF_LOOPBACK zepif_udp_recv(netif, state->pcb, pbuf_clone(PBUF_RAW, PBUF_RAM, q), NULL, 0); #endif err = udp_sendto(state->pcb, q, state->init.zep_dst_ip_addr, state->init.zep_dst_udp_port); } pbuf_free(q); return err; }
/** Start TCP connection back to the client (either parallel or after the * receive test has finished. */ static err_t lwiperf_tx_start(lwiperf_state_tcp_t* conn) { err_t err; lwiperf_state_tcp_t* client_conn; struct tcp_pcb* newpcb; ip_addr_t remote_addr; u16_t remote_port; client_conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); if (client_conn == NULL) { return ERR_MEM; } newpcb = tcp_new(); if (newpcb == NULL) { LWIPERF_FREE(lwiperf_state_tcp_t, client_conn); return ERR_MEM; } MEMCPY(client_conn, conn, sizeof(lwiperf_state_tcp_t)); client_conn->base.server = 0; client_conn->server_pcb = NULL; client_conn->conn_pcb = newpcb; client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */ client_conn->poll_count = 0; client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */ client_conn->bytes_transferred = 0; client_conn->settings.flags = 0; /* prevent the remote side starting back as client again */ tcp_arg(newpcb, client_conn); tcp_sent(newpcb, lwiperf_tcp_client_sent); tcp_poll(newpcb, lwiperf_tcp_poll, 2U); tcp_err(newpcb, lwiperf_tcp_err); ip_addr_copy(remote_addr, conn->conn_pcb->remote_ip); remote_port = (u16_t)lwip_htonl(client_conn->settings.remote_port); err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected); if (err != ERR_OK) { lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL); return err; } lwiperf_list_add(&client_conn->base); return ERR_OK; }
/** Checks if a netmask is valid (starting with ones, then only zeros) * * @param netmask the IPv4 netmask to check (in network byte order!) * @return 1 if the netmask is valid, 0 if it is not */ uint8_t ip4_addr_netmask_valid(uint32_t netmask) { uint32_t mask; uint32_t nm_hostorder = lwip_htonl(netmask); /* first, check for the first zero */ for (mask = 1UL << 31; mask != 0; mask >>= 1) { if ((nm_hostorder & mask) == 0) { break; } } /* then check that there is no one */ for (; mask != 0; mask >>= 1) { if ((nm_hostorder & mask) != 0) { /* there is a one after the first zero -> invalid */ return 0; } } /* no one after the first zero -> valid */ return 1; }
/** * RTP send packets */ static void rtp_send_packets( int sock, struct sockaddr_in* to) { struct rtp_hdr* rtphdr; u8_t* rtp_payload; int rtp_payload_size; size_t rtp_data_index; /* prepare RTP packet */ rtphdr = (struct rtp_hdr*)rtp_send_packet; rtphdr->version = RTP_VERSION; rtphdr->payloadtype = 0; rtphdr->ssrc = PP_HTONL(RTP_SSRC); rtphdr->timestamp = lwip_htonl(lwip_ntohl(rtphdr->timestamp) + RTP_TIMESTAMP_INCREMENT); /* send RTP stream packets */ rtp_data_index = 0; do { rtp_payload = rtp_send_packet+sizeof(struct rtp_hdr); rtp_payload_size = LWIP_MIN(RTP_PAYLOAD_SIZE, (sizeof(rtp_data) - rtp_data_index)); MEMCPY(rtp_payload, rtp_data + rtp_data_index, rtp_payload_size); /* set MARKER bit in RTP header on the last packet of an image */ rtphdr->payloadtype = RTP_PAYLOADTYPE | (((rtp_data_index + rtp_payload_size) >= sizeof(rtp_data)) ? RTP_MARKER_MASK : 0); /* send RTP stream packet */ if (sendto(sock, rtp_send_packet, sizeof(struct rtp_hdr) + rtp_payload_size, 0, (struct sockaddr *)to, sizeof(struct sockaddr)) >= 0) { rtphdr->seqNum = lwip_htons(lwip_ntohs(rtphdr->seqNum) + 1); rtp_data_index += rtp_payload_size; } else { LWIP_DEBUGF(RTP_DEBUG, ("rtp_sender: not sendto==%i\n", errno)); } }while (rtp_data_index < sizeof(rtp_data)); }
/** * Check whether "cp" is a valid ascii representation * of an IPv6 address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * * @param cp IPv6 address in ascii representation (e.g. "FF01::1") * @param addr pointer to which to save the ip address in network order * @return 1 if cp could be converted to addr, 0 on failure */ int ip6addr_aton(const char *cp, ip6_addr_t *addr) { u32_t addr_index, zero_blocks, current_block_index, current_block_value; const char *s; #if LWIP_IPV4 int check_ipv4_mapped = 0; #endif /* LWIP_IPV4 */ /* Count the number of colons, to count the number of blocks in a "::" sequence zero_blocks may be 1 even if there are no :: sequences */ zero_blocks = 8; for (s = cp; *s != 0; s++) { if (*s == ':') { zero_blocks--; #if LWIP_IPV4 } else if (*s == '.') { if ((zero_blocks == 5) ||(zero_blocks == 2)) { check_ipv4_mapped = 1; /* last block could be the start of an IPv4 address */ zero_blocks--; } else { /* invalid format */ return 0; } break; #endif /* LWIP_IPV4 */ } else if (!lwip_isxdigit(*s)) { break; } } /* parse each block */ addr_index = 0; current_block_index = 0; current_block_value = 0; for (s = cp; *s != 0; s++) { if (*s == ':') { if (addr) { if (current_block_index & 0x1) { addr->addr[addr_index++] |= current_block_value; } else { addr->addr[addr_index] = current_block_value << 16; } } current_block_index++; #if LWIP_IPV4 if (check_ipv4_mapped) { if (current_block_index == 6) { ip4_addr_t ip4; int ret = ip4addr_aton(s + 1, &ip4); if (ret) { if (addr) { addr->addr[3] = lwip_htonl(ip4.addr); current_block_index++; goto fix_byte_order_and_return; } return 1; } } } #endif /* LWIP_IPV4 */ current_block_value = 0; if (current_block_index > 7) { /* address too long! */ return 0; } if (s[1] == ':') { if (s[2] == ':') { /* invalid format: three successive colons */ return 0; } s++; /* "::" found, set zeros */ while (zero_blocks > 0) { zero_blocks--; if (current_block_index & 0x1) { addr_index++; } else { if (addr) { addr->addr[addr_index] = 0; } } current_block_index++; if (current_block_index > 7) { /* address too long! */ return 0; } } } } else if (lwip_isxdigit(*s)) { /* add current digit */ current_block_value = (current_block_value << 4) + (lwip_isdigit(*s) ? (u32_t)(*s - '0') : (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A'))); } else { /* unexpected digit, space? CRLF? */ break; } } if (addr) { if (current_block_index & 0x1) { addr->addr[addr_index++] |= current_block_value; } else { addr->addr[addr_index] = current_block_value << 16; } #if LWIP_IPV4 fix_byte_order_and_return: #endif /* convert to network byte order. */ for (addr_index = 0; addr_index < 4; addr_index++) { addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]); } ip6_addr_clear_zone(addr); } if (current_block_index != 7) { return 0; } return 1; }
/** * Fragment an IPv6 datagram if too large for the netif or path MTU. * * Chop the datagram in MTU sized chunks and send them in order * by pointing PBUF_REFs into p * * @param p ipv6 packet to send * @param netif the netif on which to send * @param dest destination ipv6 address to which to send * * @return ERR_OK if sent successfully, err_t otherwise */ err_t ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) { struct ip6_hdr *original_ip6hdr; struct ip6_hdr *ip6hdr; struct ip6_frag_hdr *frag_hdr; struct pbuf *rambuf; #if !LWIP_NETIF_TX_SINGLE_PBUF struct pbuf *newpbuf; u16_t newpbuflen = 0; u16_t left_to_copy; #endif static u32_t identification; u16_t nfb; u16_t left, cop; u16_t mtu; u16_t fragment_offset = 0; u16_t last; u16_t poff = IP6_HLEN; identification++; original_ip6hdr = (struct ip6_hdr *)p->payload; mtu = nd6_get_destination_mtu(dest, netif); /* @todo we assume there are no options in the unfragmentable part (IPv6 header). */ left = p->tot_len - IP6_HLEN; nfb = (mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK; while (left) { last = (left <= nfb); /* Fill this fragment */ cop = last ? left : nfb; #if LWIP_NETIF_TX_SINGLE_PBUF rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM); if (rambuf == NULL) { IP6_FRAG_STATS_INC(ip6_frag.memerr); return ERR_MEM; } LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff); /* make room for the IP header */ if (pbuf_header(rambuf, IP6_HLEN)) { pbuf_free(rambuf); IP6_FRAG_STATS_INC(ip6_frag.memerr); return ERR_MEM; } /* fill in the IP header */ SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); ip6hdr = (struct ip6_hdr *)rambuf->payload; frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); #else /* When not using a static buffer, create a chain of pbufs. * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, * but limited to the size of an mtu. */ rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM); if (rambuf == NULL) { IP6_FRAG_STATS_INC(ip6_frag.memerr); return ERR_MEM; } LWIP_ASSERT("this needs a pbuf in one piece!", (p->len >= (IP6_HLEN))); SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); ip6hdr = (struct ip6_hdr *)rambuf->payload; frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); /* Can just adjust p directly for needed offset. */ p->payload = (u8_t *)p->payload + poff; p->len -= poff; p->tot_len -= poff; left_to_copy = cop; while (left_to_copy) { struct pbuf_custom_ref *pcr; newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; /* Is this pbuf already empty? */ if (!newpbuflen) { p = p->next; continue; } pcr = ip6_frag_alloc_pbuf_custom_ref(); if (pcr == NULL) { pbuf_free(rambuf); IP6_FRAG_STATS_INC(ip6_frag.memerr); return ERR_MEM; } /* Mirror this pbuf, although we might not need all of it. */ newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); if (newpbuf == NULL) { ip6_frag_free_pbuf_custom_ref(pcr); pbuf_free(rambuf); IP6_FRAG_STATS_INC(ip6_frag.memerr); return ERR_MEM; } pbuf_ref(p); pcr->original = p; pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom; /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain * so that it is removed when pbuf_dechain is later called on rambuf. */ pbuf_cat(rambuf, newpbuf); left_to_copy -= newpbuflen; if (left_to_copy) { p = p->next; } } poff = newpbuflen; #endif /* LWIP_NETIF_TX_SINGLE_PBUF */ /* Set headers */ frag_hdr->_nexth = original_ip6hdr->_nexth; frag_hdr->reserved = 0; frag_hdr->_fragment_offset = lwip_htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)); frag_hdr->_identification = lwip_htonl(identification); IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT); IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN); /* No need for separate header pbuf - we allowed room for it in rambuf * when allocated. */ IP6_FRAG_STATS_INC(ip6_frag.xmit); netif->output_ip6(netif, rambuf, dest); /* Unfortunately we can't reuse rambuf - the hardware may still be * using the buffer. Instead we free it (and the ensuing chain) and * recreate it next time round the loop. If we're lucky the hardware * will have already sent the packet, the free will really free, and * there will be zero memory penalty. */ pbuf_free(rambuf); left -= cop; fragment_offset += cop; } return ERR_OK; }
/** Try to send more data on an iperf tcp session */ static err_t lwiperf_tcp_client_send_more(lwiperf_state_tcp_t* conn) { int send_more; err_t err; u16_t txlen; u16_t txlen_max; void* txptr; u8_t apiflags; LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0)); do { send_more = 0; if (conn->settings.amount & PP_HTONL(0x80000000)) { /* this session is time-limited */ u32_t now = sys_now(); u32_t diff_ms = now - conn->time_started; u32_t time = (u32_t)-(s32_t)lwip_htonl(conn->settings.amount); u32_t time_ms = time * 10; if (diff_ms >= time_ms) { /* time specified by the client is over -> close the connection */ lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT); return ERR_OK; } } else { /* this session is byte-limited */ u32_t amount_bytes = lwip_htonl(conn->settings.amount); /* @todo: this can send up to 1*MSS more than requested... */ if (amount_bytes >= conn->bytes_transferred) { /* all requested bytes transferred -> close the connection */ lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT); return ERR_OK; } } if (conn->bytes_transferred < 24) { /* transmit the settings a first time */ txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred]; txlen_max = (u16_t)(24 - conn->bytes_transferred); apiflags = TCP_WRITE_FLAG_COPY; } else if (conn->bytes_transferred < 48) { /* transmit the settings a second time */ txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred - 24]; txlen_max = (u16_t)(48 - conn->bytes_transferred); apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE; send_more = 1; } else { /* transmit data */ /* @todo: every x bytes, transmit the settings again */ txptr = (void*)(size_t)&lwiperf_txbuf_const[conn->bytes_transferred % 10]; txlen_max = TCP_MSS; if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */ txlen_max = TCP_MSS - 24; } apiflags = 0; /* no copying needed */ send_more = 1; } txlen = txlen_max; do { err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags); if (err == ERR_MEM) { txlen /= 2; } } while ((err == ERR_MEM) && (txlen >= (TCP_MSS/2))); if (err == ERR_OK) { conn->bytes_transferred += txlen; } else { send_more = 0; } } while(send_more); tcp_output(conn->conn_pcb); return ERR_OK; }
/** * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. * * @param cp IP address in ascii representation (e.g. "127.0.0.1") * @param addr pointer to which to save the ip address in network order * @return 1 if cp could be converted to addr, 0 on failure */ int ip4addr_aton(const char *cp, ip4_addr_t *addr) { u32_t val; u8_t base; char c; u32_t parts[4]; u32_t *pp = parts; c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, 1-9=decimal. */ if (!isdigit(c)) { return 0; } val = 0; base = 10; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') { base = 16; c = *++cp; } else { base = 8; } } for (;;) { if (isdigit(c)) { val = (val * base) + (u32_t)(c - '0'); c = *++cp; } else if (base == 16 && isxdigit(c)) { val = (val << 4) | (u32_t)(c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; } else { break; } } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3) { return 0; } *pp++ = val; c = *++cp; } else { break; } } /* * Check for trailing characters. */ if (c != '\0' && !isspace(c)) { return 0; } /* * Concoct the address according to * the number of parts specified. */ switch (pp - parts + 1) { case 0: return 0; /* initial nondigit */ case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if (val > 0xffffffUL) { return 0; } if (parts[0] > 0xff) { return 0; } val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if (val > 0xffff) { return 0; } if ((parts[0] > 0xff) || (parts[1] > 0xff)) { return 0; } val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if (val > 0xff) { return 0; } if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) { return 0; } val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; default: LWIP_ASSERT("unhandled", 0); break; } if (addr) { ip4_addr_set_u32(addr, lwip_htonl(val)); } return 1; }
void cliSetVar(const clivalue_t *var, const char *str) { uint32_t val = 0; uint8_t val2 = 0; switch (var->type) { case VAR_UINT32: *(uint32_t*)var->ptr = atoi_decimal(str); break; case VAR_UINT16: *(uint16_t*)var->ptr = atoi_decimal(str); break; #if CLI_TYPE_IP4 case VAR_IP4: while (*str) { if (*str == '.') { val = (val << 8) | val2; val2 = 0; } else if (*str >= '0' && *str <= '9') { val2 = val2 * 10 + (*str - '0'); } str++; } val = (val << 8) | val2; *(uint32_t*)var->ptr = lwip_htonl(val); break; #endif #if CLI_TYPE_IP6 case VAR_IP6: { uint32_t *packed = (uint32_t*)var->ptr; uint8_t i; uint16_t words[8]; for (i = 0; i < 8; i++) { words[i] = 0; } i = 0; while (*str) { if (*str == ':') { if (++i == 8) { break; } } else { words[i] = (words[i] << 4) | parse_hex(*str); } str++; } packed[0] = htonl(words[1] | ((uint32_t)words[0] << 16)); packed[1] = htonl(words[3] | ((uint32_t)words[2] << 16)); packed[2] = htonl(words[5] | ((uint32_t)words[4] << 16)); packed[3] = htonl(words[7] | ((uint32_t)words[6] << 16)); break; } #endif #if CLI_TYPE_HEX case VAR_HEX: { uint8_t *ptr = (uint8_t*)var->ptr; int i; for (i = 0; i < var->len; i++) { val2 = *str++; if (val2 == 0) { break; } else { val = parse_hex(val2) << 4; } val2 = *str++; if (val2 == 0) { break; } else { val |= parse_hex(val2); } *ptr++ = val; } /* Pad the remainder with zeroes */ for (; i < var->len; i++) { *ptr++ = 0; } break; } #endif #if CLI_TYPE_FLAG case VAR_FLAG: if (*str == 't' || *str == 'y' || (*str == 'o' && *(str+1) == 'n')) { *(uint32_t*)var->ptr |= var->len; } else if (*str == 'f' || *str == 'n' || (*str == 'o' && *(str+1) == 'f')) { *(uint32_t*)var->ptr &= ~(var->len); } break; #endif case VAR_INVALID: break; } }
/** * Check whether "cp" is a valid ascii representation * of an IPv6 address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * * @param cp IPv6 address in ascii representation (e.g. "FF01::1") * @param addr pointer to which to save the ip address in network order * @return 1 if cp could be converted to addr, 0 on failure */ int ip6addr_aton(const char *cp, ip6_addr_t *addr) { u32_t addr_index, zero_blocks, current_block_index, current_block_value; const char *s; /* Count the number of colons, to count the number of blocks in a "::" sequence zero_blocks may be 1 even if there are no :: sequences */ zero_blocks = 8; for (s = cp; *s != 0; s++) { if (*s == ':') { zero_blocks--; } else if (!isxdigit(*s)) { break; } } /* parse each block */ addr_index = 0; current_block_index = 0; current_block_value = 0; for (s = cp; *s != 0; s++) { if (*s == ':') { if (addr) { if (current_block_index & 0x1) { addr->addr[addr_index++] |= current_block_value; } else { addr->addr[addr_index] = current_block_value << 16; } } current_block_index++; current_block_value = 0; if (current_block_index > 7) { /* address too long! */ return 0; } if (s[1] == ':') { if (s[2] == ':') { /* invalid format: three successive colons */ return 0; } s++; /* "::" found, set zeros */ while (zero_blocks > 0) { zero_blocks--; if (current_block_index & 0x1) { addr_index++; } else { if (addr) { addr->addr[addr_index] = 0; } } current_block_index++; if (current_block_index > 7) { /* address too long! */ return 0; } } } } else if (isxdigit(*s)) { /* add current digit */ current_block_value = (current_block_value << 4) + (isdigit(*s) ? (u32_t)(*s - '0') : (u32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A'))); } else { /* unexpected digit, space? CRLF? */ break; } } if (addr) { if (current_block_index & 0x1) { addr->addr[addr_index++] |= current_block_value; } else { addr->addr[addr_index] = current_block_value << 16; } } /* convert to network byte order. */ if (addr) { for (addr_index = 0; addr_index < 4; addr_index++) { addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]); } } if (current_block_index != 7) { return 0; } return 1; }
/* * 获取除了"区分三相的数据"以及"波形采用数据"以外的其他数据 * * 当返回值为SIE_OK时,非空指针指向的变量存储了返回值 */ enum sinkinfo_error_e get_sinkinfo_other_param(int em_no, enum sinkinfo_cmd_e cmd, u32_t *pinfo) { enum sinkinfo_error_e ret = SIE_OK; int temp; if (NULL==pinfo) return SIE_NULL_PTR; ret = rt_sem_take(&sinkinfo_sem, RT_WAITING_FOREVER); if (RT_EOK != ret) { printf_syn("take sinkinfo_sem fail(%d)\n", ret); return SIE_FAIL; } switch (cmd) { case SIC_GET_EM_ACT_ELECTRIC_ENERGY: if(sinkinfo_all_em[em_no].em_dev_info.em_act_total_energy == INVLIDE_DATAL){ *pinfo = lwip_htonl(sinkinfo_all_em[em_no].em_dev_info.em_act_total_energy); }else{ *pinfo = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_act_total_energy)); } break; case SIC_GET_DEV_ACT_ELECTRIC_ENERGY: *pinfo = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_act_total_energy)); //sinkinfo.emc_dev_info.dev_act_electric_energy; break; case SIC_GET_EM_REACT_ELECTRIC_ENERGY: if(sinkinfo_all_em[em_no].em_dev_info.em_react_total_energy == INVLIDE_DATAL){ *pinfo = lwip_htonl(sinkinfo_all_em[em_no].em_dev_info.em_react_total_energy); }else{ *pinfo = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_react_total_energy)); } break; case SIC_GET_DEV_REACT_ELECTRIC_ENERGY: *pinfo = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_react_total_energy)); //sinkinfo.emc_dev_info.dev_react_electric_energy; break; case SIC_GET_ACT_INACCURACY: if(sinkinfo_all_em[em_no].em_dev_info.em_act_ee_inaccuracy == INVLIDE_DATAL){ temp = sinkinfo_all_em[em_no].em_dev_info.em_act_ee_inaccuracy; }else{ temp = conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_act_ee_inaccuracy); } *pinfo = lwip_htonl(temp); break; case SIC_GET_REACT_INACCURACY: if(sinkinfo_all_em[em_no].em_dev_info.em_react_ee_inaccuracy == INVLIDE_DATAL){ temp = sinkinfo_all_em[em_no].em_dev_info.em_react_ee_inaccuracy; }else{ temp = conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_react_ee_inaccuracy); } *pinfo = lwip_htonl(temp); break; case SIC_GET_EM_METER_TEMPERATURE: if(sinkinfo_all_em[em_no].em_dev_info.em_temper == INVLIDE_DATAS){ temp = sinkinfo_all_em[em_no].em_dev_info.em_temper; }else{ temp = conv_4byte_bcd_to_long((unsigned long)sinkinfo_all_em[em_no].em_dev_info.em_temper); } *pinfo = lwip_htonl(temp); break; case SIC_GET_EM_CLOCK_BATTERY_VOL: if(sinkinfo_all_em[em_no].em_dev_info.em_v_clock == INVLIDE_DATAL){ temp = sinkinfo_all_em[em_no].em_dev_info.em_v_clock; }else{ temp = conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_v_clock); } *pinfo = lwip_htonl(temp); break; case SIC_GET_EM_METER_COLLECT_BATTERY_VOL: if(sinkinfo_all_em[em_no].em_dev_info.em_v_read_em == INVLIDE_DATAL){ temp = sinkinfo_all_em[em_no].em_dev_info.em_v_read_em; }else{ temp = conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].em_dev_info.em_v_read_em); } *pinfo = lwip_htonl(temp); break; case SIC_GET_PT_TEMP: temp = sinkinfo_all_em[em_no].pttmp; *pinfo = lwip_htonl(temp); break; case SIC_GET_CT_TEMP: temp = sinkinfo_all_em[em_no].cttmp; *pinfo = lwip_htonl(temp); break; #if 0 case SIC_GET_EM_MONTH_ELECTRIC_ENERGY: break; case SIC_GET_DEV_MONTH_ELECTRIC_ENERGY: break; case SIC_GET_MONTH_INACCURACY: break; #endif default: ret = SIE_INVALID_CMD; break; } rt_sem_release(&sinkinfo_sem); return ret; }
/* * 获取"区分三相的数据",但不包括"波形采用数据"(波形数据有专用接口函数) * * 当返回值为SIE_OK时,非空指针指向的变量存储了返回值,不需要获取的使用NULL * 例如,获取A相电压的调用形式为:get_sinkinfo_abc_param(SIC_GET_VOLTAGE, &a, NULL, NULL) */ enum sinkinfo_error_e get_sinkinfo_abc_param(int em_no, int ptct_no,enum sinkinfo_cmd_e cmd, u32_t *pa, u32_t *pb, u32_t *pc) { enum sinkinfo_error_e ret = SIE_OK; if (NULL==pa && NULL==pb && NULL==pc) return SIE_NULL_PTR; ret = rt_sem_take(&sinkinfo_sem, RT_WAITING_FOREVER); if (RT_EOK != ret) { printf_syn("take sinkinfo_sem fail(%d)\n", ret); return SIE_FAIL; } switch (cmd) { case SIC_GET_VOLTAGE: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.vx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].si_emc_ind_pb.vx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.vx; break; case SIC_GET_CURRENT: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.ix; if (NULL != pb) *pb = sinkinfo_all_em[em_no].si_emc_ind_pb.ix; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.ix; break; case SIC_GET_FREQUENCY: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.hzx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].si_emc_ind_pb.hzx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.hzx; break; case SIC_GET_PHASE: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.phx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].si_emc_ind_pb.phx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.phx; break; case SIC_GET_ACTIVE_POWER: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.apx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].si_emc_ind_pb.apx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.apx; break; case SIC_GET_REACTIVE_POWER: if (NULL != pa) // *pa = sinkinfo.si_emc_ind_pa.rapx; *pa = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pa.rapx)); if (NULL != pb) // *pb = sinkinfo.si_emc_ind_pb.rapx; *pb = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pb.rapx)); if (NULL != pc) // *pc = sinkinfo.si_emc_ind_pc.rapx; *pc = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pc.rapx)); break; case SIC_GET_APPARENT_POWER: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.appx; if (NULL != pb) *pb =sinkinfo_all_em[em_no].si_emc_ind_pb.appx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.appx; break; case SIC_GET_POWER_FACTOR: if (NULL != pa) *pa = sinkinfo_all_em[em_no].si_emc_ind_pa.pfx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].si_emc_ind_pb.pfx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].si_emc_ind_pc.pfx; break; case SIC_GET_VOLTAGE_DISTORTION: if (NULL != pa) *pa = INVLIDE_DATAL; //sinkinfo.si_emc_ind_pa.vdx; /* 该版本不实现, 所有二进制bit置1 */ if (NULL != pb) *pb = INVLIDE_DATAL; //sinkinfo.si_emc_ind_pb.vdx; if (NULL != pc) *pc = INVLIDE_DATAL; //sinkinfo.si_emc_ind_pc.vdx; break; case SIC_GET_CURRENT_DISTORTION: if (NULL != pa) *pa = INVLIDE_DATAL; //sinkinfo.si_emc_ind_pa.cdx; /* 该版本不实现, 所有二进制bit置1 */ if (NULL != pb) *pb = INVLIDE_DATAL; //sinkinfo.si_emc_ind_pb.cdx; if (NULL != pc) *pc = INVLIDE_DATAL; //sinkinfo.si_emc_ind_pc.cdx; break; case SIC_GET_EM_VOLTAGE: /* 电表中读取的电压 */ if (NULL != pa) *pa = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pa.vx)); if (NULL != pb) *pb = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pb.vx)); if (NULL != pc) *pc = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pc.vx)); break; case SIC_GET_EM_CURRENT: /* 电表中读取的电流 */ if (NULL != pa) *pa = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pa.ix)); if (NULL != pb) *pb = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pb.ix)); if (NULL != pc) *pc = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pc.ix)); break; case SIC_GET_EM_ACTIVE_POWER: /* 电表中读取的有功功率 */ if (NULL != pa) *pa = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pa.apx)); if (NULL != pb) *pb = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pb.apx)); if (NULL != pc) *pc = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pc.apx)); break; case SIC_GET_EM_REACTIVE_POWER: /* 电表中读取的无功功率 */ if (NULL != pa) *pa = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pa.rapx)); if (NULL != pb) *pb = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pb.rapx)); if (NULL != pc) *pc = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pc.rapx)); break; case SIC_GET_EM_POWER_FACTOR: /* 电表中读取的功率因数 */ if (NULL != pa) *pa = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pa.pfx)); if (NULL != pb) *pb = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pb.pfx)); if (NULL != pc) *pc = lwip_htonl(conv_4byte_bcd_to_long(sinkinfo_all_em[em_no].si_em_ind_pc.pfx)); break; case SIC_GET_PT_LOAD: /* pt负荷 */ if (NULL != pa) *pa = sinkinfo_all_em[em_no].pt_info.pt_pa.appx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].pt_info.pt_pb.appx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].pt_info.pt_pc.appx; break; case SIC_GET_CT_LOAD: /* ct负荷 */ if (ptct_no == 1){ if (NULL != pa) *pa = sinkinfo_all_em[em_no].ct_info.ct_pa.appx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].ct_info.ct_pb.appx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].ct_info.ct_pc.appx; }else if (ptct_no == 2){ if (NULL != pa) *pa = sinkinfo_all_em[em_no].ct1_info.ct_pa.appx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].ct1_info.ct_pb.appx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].ct1_info.ct_pc.appx; } break; case SIC_GET_PT_VOLTAGE_DROP: /* 二次侧电压 */ if (NULL != pa) *pa = sinkinfo_all_em[em_no].pt_info.pt_pa.vx; if (NULL != pb) *pb = sinkinfo_all_em[em_no].pt_info.pt_pb.vx; if (NULL != pc) *pc = sinkinfo_all_em[em_no].pt_info.pt_pc.vx; break; default: ret = SIE_INVALID_CMD; break; } rt_sem_release(&sinkinfo_sem); return ret; }