diff options
author | 2018-08-13 19:23:34 +0530 | |
---|---|---|
committer | 2018-08-13 19:25:27 +0530 | |
commit | 7dc65518819f2b453fd2837e92c115592d8832ec (patch) | |
tree | f9119bb3624ff11af480981c9904b84c172a607c /stacks/lwip_stack/lwip_src/core | |
parent | bd6e75c243db1b384ba0882ecaf9063ec4cd70bd (diff) |
Feat : LWIP integration part1
Change-Id: Ia26c092d16579c6f845a021ba66bde106363883a
Signed-off-by: Swarup Nayak <swarupnpvt@gmail.com>
Diffstat (limited to 'stacks/lwip_stack/lwip_src/core')
-rw-r--r-- | stacks/lwip_stack/lwip_src/core/global_tick.c | 48 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/core/spl_pbuf.c | 597 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/core/spl_timers.c | 608 | ||||
-rw-r--r-- | stacks/lwip_stack/lwip_src/core/unmatch_version.c | 59 |
4 files changed, 1312 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/core/global_tick.c b/stacks/lwip_stack/lwip_src/core/global_tick.c new file mode 100644 index 0000000..ee180c9 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/global_tick.c @@ -0,0 +1,48 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nsfw_mem_api.h" +#include "nstack_share_res.h" +#include "nstack_securec.h" + +extern nstack_tick_info_t g_nstack_timer_tick; + +int +init_stackx_global_tick (void) +{ + nsfw_mem_zone mzone; + + if (STRCPY_S + (mzone.stname.aname, NSFW_MEM_NAME_LENGTH, NSTACK_GLOBAL_TICK_SHM) != 0) + { + NSPOL_LOGERR ("STRCPY_S fail"); + return -1; + } + + mzone.stname.entype = NSFW_SHMEM; + mzone.isocket_id = -1; + mzone.length = sizeof (uint64_t); + mzone.ireserv = 0; + + g_nstack_timer_tick.tick_ptr = (uint64_t *) nsfw_mem_zone_create (&mzone); + if (NULL == g_nstack_timer_tick.tick_ptr) + { + NSPOL_LOGERR ("Failed to create global timer tick memory"); + return -1; + } + + return 0; +} diff --git a/stacks/lwip_stack/lwip_src/core/spl_pbuf.c b/stacks/lwip_stack/lwip_src/core/spl_pbuf.c new file mode 100644 index 0000000..03e30ed --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/spl_pbuf.c @@ -0,0 +1,597 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "spl_opt.h" + +#include "spl_def.h" +#include "spl_pbuf.h" +#include "stackx_pbuf.h" + +#include "stackx_spl_share.h" +#include "spl_api.h" + +#include "nsfw_maintain_api.h" +#include "netif/sc_dpdk.h" +#include <common_mem_mbuf.h> + +#include <string.h> +#include "nstack_log.h" +#include "nstack_securec.h" +#include "spl_instance.h" + +#include "sys.h" +#include "mem.h" +#include "memp.h" +//#include "sockets.h" +//#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#ifdef HAL_LIB +#else +#include "rte_memcpy.h" +#endif +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct spl_pbuf)) +u16_t g_offSetArry[SPL_PBUF_MAX_LAYER]; + +u16_t g_offSetArry[SPL_PBUF_MAX_LAYER] = + { PBUF_TRANSPORT_HLEN + PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN, + SPL_PBUF_UDP_HLEN + PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN, + PBUF_IP_HLEN + SPL_PBUF_LINK_HLEN, + SPL_PBUF_LINK_HLEN, + 0 +}; + +inline struct spl_pbuf * +spl_pbuf_alloc_hugepage (spl_pbuf_layer layer, u16_t length, + spl_pbuf_type Type, u16_t proc_id, void *net_conn) +{ + struct spl_pbuf *p; + u16_t offset; + u16_t count = 0; + spl_netconn_t *conn = (spl_netconn_t *) net_conn; + + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "spl_pbuf_alloc_hugepage]length=%" U16_F, length); + + /* determine header offset */ + if (likely (layer < SPL_PBUF_MAX_LAYER)) + { + offset = g_offSetArry[layer]; + } + else + { + NSPOL_LOGERR ("spl_pbuf_alloc_hugepage: bad pbuf layer"); + return NULL; + } + + if (unlikely (length < offset || Type != SPL_PBUF_HUGE)) + { + NSPOL_LOGERR ("input is invalid!]length=%u, Type = %d", length, Type); + return NULL; + } + + p = spl_mbuf_malloc (length, SPL_PBUF_HUGE, &count); + + if (p == NULL) + { + /* last_log_prt_time and unprint_log_count indeed have multi-thread issue, + * but their values don't have precision requirement. No risk. */ + NS_LOG_CTRL (LOG_CTRL_HUGEPAGE_ALLOC_FAIL, STACKX, "NSPOL", NSLOG_ERR, + "pbuf_alloc_huge: Could not allocate PBUF for SPL_PBUF_HUGE"); + + return NULL; + } + + if (conn) + { + p->conn_a = ADDR_LTOSH (conn); + } + else + { + p->conn_a = 0; + } + + p->tot_len -= offset; + p->len -= offset; + p->next_a = 0; + + p->payload_a = p->payload_a + offset; + + p->proto_type = SPL_PBUF_PROTO_NONE; + + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "pbuf_alloc]length=%" U16_F ",p=%p", length, (void *) p); + return p; +} + +inline int +spl_pbuf_internal_copy (struct spl_pbuf *dst, struct spl_pbuf *src) +{ + u32_t dst_len = dst->len; + u32_t src_len = src->len; + u32_t dst_pos = 0; + u32_t src_pos = 0; + while (dst != NULL && src != NULL) + { + if (dst_len > src_len) + { + if (NULL == + common_memcpy (PTR_SHTOL (char *, dst->payload_a) + dst_pos, + PTR_SHTOL (char *, src->payload_a) + src_pos, + src_len)) + { + NSPOL_LOGERR ("rte_memcpy error"); + return -1; + } + + dst_len -= src_len; + dst_pos += src_len; + src = ADDR_SHTOL (src->next_a); + src_len = src != NULL ? src->len : 0; + src_pos = 0; + } + else if (dst_len < src_len) + { + if (NULL == + common_memcpy (PTR_SHTOL (char *, dst->payload_a) + dst_pos, + PTR_SHTOL (char *, src->payload_a) + src_pos, + dst_len)) + { + NSPOL_LOGERR ("rte_memcpy error"); + return -1; + } + + src_len -= dst_len; + src_pos += dst_len; + dst = ADDR_SHTOL (dst->next_a); + dst_len = dst != NULL ? dst->len : 0; + dst_pos = 0; + } + else + { + if (NULL == + common_memcpy (PTR_SHTOL (char *, dst->payload_a) + dst_pos, + PTR_SHTOL (char *, src->payload_a) + src_pos, + dst_len)) + { + NSPOL_LOGERR ("rte_memcpy error"); + return -1; + } + + src = ADDR_SHTOL (src->next_a); + src_len = src != NULL ? src->len : 0; + src_pos = 0; + dst = ADDR_SHTOL (dst->next_a); + dst_len = dst != NULL ? dst->len : 0; + dst_pos = 0; + } + } + return 0; +} + +void +spl_pbuf_realloc (struct spl_pbuf *p, u32_t new_len) +{ + if (NULL != p && p->type == SPL_PBUF_HUGE) + { + p->tot_len = new_len; + p->len = new_len; + return; + } +} + +void +spl_pbuf_free (struct spl_pbuf *p) +{ + struct spl_pbuf *q; + u8_t count = 0; + + NSPOL_LOGINF (PBUF_DEBUG, "Freeing PBF %p", p); + + if (unlikely (p == NULL || p->type != SPL_PBUF_HUGE)) + { + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_LEVEL_SERIOUS, + "input param illegal]p=%p, type=%d", p, p ? p->type : -1); + return; + } + + (void) count; + + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + do + { + /* remember next pbuf in chain for next iteration */ + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "spl_pbuf_free: deallocating]buf=%p", (void *) p); + q = (struct spl_pbuf *) ADDR_SHTOL (p->next_a); + if (res_free (&p->res_chk)) + { + //NSPOL_LOGERR("res_free failed]p=%p", p); + } + + count++; + { + pbuf_set_recycle_flg (p, MBUF_UNUSED); /* release buf hold by app on abnormal exit */ + spl_mbuf_free ((char *) p - sizeof (struct common_mem_mbuf)); + p->res_chk.u8Reserve |= PBUF_FREE_FLAG; + } + + /* proceed to next pbuf */ + p = q; + } + while (p != NULL); + + /* return number of de-allocated pbufs */ + return; +} + +void +spl_pbuf_cat (struct spl_pbuf *h, struct spl_pbuf *t) +{ + struct spl_pbuf *p; + + if (h == NULL || t == NULL) + { + NSPOL_LOGERR ("pbuf_cat: h=NULL||t=NULL!!"); + return; + } + + for (p = h; p->next_a != 0; p = PTR_SHTOL (struct spl_pbuf *, p->next_a)) + { + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + } + + if (0 != p->next_a) + { + NSPOL_LOGERR + ("pbuf_cat: p is not the last pbuf of the first chain, p->next_a != 0"); + return; + } + + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + + /* chain last pbuf of head (p) with first of tail (t) */ + p->next_a = (uint64_t) ADDR_LTOSH_EXT (t); + + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + +err_t +spl_pbuf_copy (struct spl_pbuf * p_to, struct spl_pbuf * p_from) +{ + u32_t offset_to = 0; + u32_t offset_from = 0; + u32_t len = 0; + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, "pbuf_copy]p_to=%p,p_from=%p", + (void *) p_to, (void *) p_from); + + if (! + ((p_to != NULL) && (p_from != NULL) + && (p_to->tot_len >= p_from->tot_len))) + { + NSPOL_LOGERR ("pbuf_copy: target not big enough to hold source"); + return ERR_ARG; + } + + do + { + if (p_to == NULL) + { + NSPOL_LOGERR ("pbuf_copy: target pbuf not exist: p_to == NULL!!"); + return ERR_ARG; + } + + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) + { + + len = p_from->len - offset_from; + } + else + { + + len = p_to->len - offset_to; + } + + if (EOK != + MEMMOVE_S ((u8_t *) ADDR_SHTOL (p_to->payload_a) + offset_to, len, + (u8_t *) ADDR_SHTOL (p_from->payload_a) + offset_from, + len)) + { + NSPOL_LOGERR ("MEMMOVE_S failed"); + return ERR_MEM; + } + + offset_to += len; + offset_from += len; + if (offset_to > p_to->len) + { + NSPOL_LOGERR + ("pbuf_copy: target offset not match: offset_to > p_to->len."); + return ERR_VAL; + } + if (offset_to == p_to->len) + { + offset_to = 0; + p_to = (struct spl_pbuf *) ADDR_SHTOL (p_to->next_a); + } + + if (offset_from >= p_from->len) + { + /* on to next p_from (if any) */ + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "pbuf_copy: source offset not match: offset_from >= p_from->len"); + offset_from = 0; + p_from = (struct spl_pbuf *) ADDR_SHTOL (p_from->next_a); + } + + if ((p_from != NULL) && (p_from->len == p_from->tot_len)) + { + if ((p_from->next_a != 0)) + { + NSPOL_LOGERR ("pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + + if ((p_to != NULL) && (p_to->len == p_to->tot_len)) + { + /* don't copy more than one packet! */ + if ((p_to->next_a != 0)) + { + NSPOL_LOGERR ("pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + } + while (p_from); + + NSPOL_LOGDBG (PBUF_DEBUG | STACKX_DBG_TRACE, + "pbuf_copy: end of chain reached."); + return ERR_OK; +} + +err_t +splpbuf_to_pbuf_copy (struct pbuf * p_to, struct spl_pbuf * p_from) +{ + u32_t offset_to = 0; + u32_t offset_from = 0; + u32_t len = 0; + + NSPOL_LOGINF (NETIF_DEBUG, "splpbuf_to_pbuf_copy"); + + if (! + ((p_to != NULL) && (p_from != NULL) + && (p_to->tot_len >= p_from->tot_len))) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy: target not big enough to hold source"); + return ERR_ARG; + } + NSPOL_LOGINF (PBUF_DEBUG, + "splpbuf_to_pbuf_copy]p_to=%p [type %d tot_len %d], p_from=%p [type %d tot_len %d]", + (void *) p_to, p_to->type, p_to->tot_len, (void *) p_from, + p_from->type, p_from->tot_len); + do + { + NSPOL_LOGINF (NETIF_DEBUG, "copying...."); + if (p_to == NULL) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy: target not big enough to hold source p_to len [%d] p_from len [%d]", + p_to->tot_len, p_from->tot_len); + return ERR_ARG; + } + + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) + { + + len = p_from->len - offset_from; + } + else + { + + len = p_to->len - offset_to; + } + + if (EOK != MEMMOVE_S ((u8_t *) p_to->payload + offset_to, + len, + (u8_t *) ADDR_SHTOL (p_from->payload_a) + + offset_from, len)) + { + NSPOL_LOGERR ("MEMMOVE_S failed"); + return ERR_MEM; + } + + offset_to += len; + offset_from += len; + if (offset_to > p_to->len) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy: target offset not match: offset_to > p_to->len."); + return ERR_VAL; + } + if (offset_to == p_to->len) + { + offset_to = 0; + p_to = p_to->next; + + NSPOL_LOGINF (NETIF_DEBUG, + "splpbuf_to_pbuf_copy: p_to next %p", p_to); + } + + if (offset_from >= p_from->len) + { + /* on to next p_from (if any) */ + NSPOL_LOGINF (NETIF_DEBUG, + "splpbuf_to_pbuf_copy: source offset not match: offset_from >= p_from->len"); + offset_from = 0; + p_from = (struct spl_pbuf *) ADDR_SHTOL (p_from->next_a); + NSPOL_LOGINF (NETIF_DEBUG, + "splpbuf_to_pbuf_copy: pfrom next %p", p_from); + } + + if ((p_from != NULL) && (p_from->len == p_from->tot_len)) + { + if ((p_from->next_a != 0)) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + + if ((p_to != NULL) && (p_to->len == p_to->tot_len)) + { + /* don't copy more than one packet! */ + if ((p_to->next != NULL)) + { + NSPOL_LOGERR + ("splpbuf_to_pbuf_copy() does not allow packet queues!"); + return ERR_VAL; + } + } + } + while (p_from); + + NSPOL_LOGDBG (NETIF_DEBUG, "splpbuf_to_pbuf_copy: end of chain reached."); + return ERR_OK; +} + +err_t +pbuf_to_splpbuf_copy (struct spl_pbuf * p_to, struct pbuf * p_from) +{ + int offset = 0; + void *data = NULL; + + do + { + data = (u8_t *) (p_to->payload_a) + offset; + memcpy (data, (u8_t *) p_from->payload, p_from->len); + offset = offset + p_from->len; + if (offset >= 2048) + { + NSPOL_LOGERR ("More thank 2K size"); + return ERR_MEM; + } + p_from = p_from->next; + } + while (p_from != NULL); + + return ERR_OK; +} + +struct pbuf * +spl_convert_spl_pbuf_to_pbuf (struct spl_pbuf *p_from) +{ + struct pbuf *p_to = NULL; + + p_to = pbuf_alloc (PBUF_RAW, p_from->tot_len, PBUF_POOL); + if (p_to) + { + splpbuf_to_pbuf_copy (p_to, p_from); + } + return p_to; +} + +spl_pbuf_layer +get_pbuf_layer_from_pbuf_payload (struct pbuf * buf) +{ + + struct eth_hdr *ethhdr; + spl_pbuf_layer layer = SPL_PBUF_TRANSPORT; + u16_t type; + + if (buf->len <= SIZEOF_ETH_HDR) + { + NSPOL_LOGINF (PBUF_DEBUG, + "get_pbuf_layer_from_payload failed. length is wrong"); + return layer; + } + ethhdr = (struct eth_hdr *) buf->payload; + type = spl_htons (ethhdr->type); + + NSPOL_LOGINF (PBUF_DEBUG, "packet type %x", type); + + switch (type) + { + case ETHTYPE_IP: + layer = SPL_PBUF_IP; + break; + case ETHTYPE_ARP: + layer = SPL_PBUF_LINK; + break; + default: + layer = SPL_PBUF_TRANSPORT; + break; + } + + return layer; +} + +void +print_pbuf_payload_info (struct pbuf *buf, bool send) +{ + + struct eth_hdr *ethhdr; + u16_t type; + + if (buf->len <= SIZEOF_ETH_HDR) + { + NSPOL_LOGINF (PBUF_DEBUG, + "get_pbuf_layer_from_payload failed. length is wrong"); + return; + } + ethhdr = (struct eth_hdr *) buf->payload; + type = spl_htons (ethhdr->type); + + if (send) + { + NSPOL_LOGINF (PBUF_DEBUG, "send packet start type %x len %d *****", + type, buf->len); + } + else + { + NSPOL_LOGINF (PBUF_DEBUG, + "receive packet start type %x len %d ########", type, + buf->len); + } + + switch (type) + { + case ETHTYPE_IP: + NSPOL_LOGINF (TCPIP_DEBUG, "ip packet len %d tot len %d type %x", + buf->len, buf->tot_len, type); + struct ip_hdr *ip = + (struct ip_hdr *) ((char *) buf->payload + SIZEOF_ETH_HDR); + NSPOL_LOGINF (PBUF_DEBUG, "ip packet src %x dest %x proto %d", ip->src, + ip->dest, ip->_proto); + break; + case ETHTYPE_ARP: + NSPOL_LOGINF (TCPIP_DEBUG, "arp packet len %d tot len %d type %x", + buf->len, buf->tot_len, type); + break; + default: + NSPOL_LOGINF (TCPIP_DEBUG, "other packet len %d tot len %d type %x", + buf->len, buf->tot_len, type); + break; + } + return; +} diff --git a/stacks/lwip_stack/lwip_src/core/spl_timers.c b/stacks/lwip_stack/lwip_src/core/spl_timers.c new file mode 100644 index 0000000..50582fc --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/spl_timers.c @@ -0,0 +1,608 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "opt.h" +#include "nsfw_mem_api.h" +#include "def.h" +#include "sc_dpdk.h" +#include "nstack_log.h" +#include "nstack_securec.h" +#include "nstack_share_res.h" + +#include <time.h> +#include <signal.h> +#include <pthread.h> +#include <syscall.h> +#include "nsfw_ps_api.h" +#include "spl_timers.h" +#include "common_mem_api.h" + +extern sys_thread_t g_timerThread_id; + +/*Since the range of the dpdk read TSC value is u64_t, it changes*/ + +#ifndef typecheck +#define typecheck(type, x) \ +({ type __dummy; \ + typeof(x)__dummy2; \ + (void)(&__dummy == &__dummy2); \ + 1; \ + }) +#endif + +#ifndef time_after_eq +#define time_after_eq(a, b) \ +(typecheck(unsigned long, a) \ + && typecheck(unsigned long, b) \ + && ((long)(a) - (long)(b) >= 0)) +#endif + +#define MIN_TIME_PICE 50 +#define MICRO_PER_SECOND 1000 +#define NANO_PER_MICROSECOND 1000000 +#define NANO_PER_SECOND 1000000000 + +#define PTIMER_MSG_BUFFER_SIZE 4096 + +#define PTIMER_STATE_INACTIVE 0x00 +#define PTIMER_STATE_ENQUEUED 0x01 +#define gettid() syscall(__NR_gettid) + +#define TIMER_CONTEXT_NAME "TIMER_CONTEXT_NAME" + +static timer_t lazy_tim; +static timer_t lazy_tim_retry; +static struct ptimer_base ptimer; +static sys_sem_t ptimer_lock; + +extern void recycle_tmr (struct ptimer_node *tmo); + +extern nstack_tick_info_t g_nstack_timer_tick; + +/* + *************************** + * rb_tree wrapper function* + *************************** + */ +NSTACK_STATIC void +remove_ptimer (struct ptimer_node *tmo, struct ptimer_base *base) +{ + if (tmo == NULL) + { + NSPOL_LOGERR ("input parameter tmo is null"); + return; + } + if (!(tmo->state & PTIMER_STATE_ENQUEUED)) + { + NSPOL_LOGWAR (TIMERS_DEBUG | LWIP_DBG_LEVEL_WARNING, + "the timer state is: PTIMER_STATE_INACTIVE, no need to remove!"); + return; + } + + if (base->first == &tmo->node) + { + base->first = rb_next (&tmo->node); + } + + rb_erase (&tmo->node, &base->active); + + tmo->state = PTIMER_STATE_INACTIVE; +} + +NSTACK_STATIC struct ptimer_node * +search_ptimer (struct ptimer_msg *msg) +{ + if (msg == NULL) + { + NSPOL_LOGERR ("input parameter msg is null"); + return NULL; + } + if (msg->node) + { + return msg->node; + } + + return NULL; + +} + +err_t +del_ptimer (struct ptimer_msg * msg) +{ + struct ptimer_node *tmo; + + tmo = search_ptimer (msg); + if (tmo) + { + remove_ptimer (tmo, &ptimer); + NSPOL_LOGDBG (TIMERS_DEBUG, "del]thread=%u,ptimer_node=%p", tmo->index, + tmo); + return ERR_OK; + } + + NSPOL_LOGERR ("ptime_node not found!!"); + return ERR_VAL; +} + +/* + * Ptimer inserted into rb_tree + * @param node: the ptimer node pointer + * @param base: the ptimer root_base pointer + */ +NSTACK_STATIC void +enqueue_ptimer (struct ptimer_node *tmo, struct ptimer_base *base) +{ + struct rb_node **linknode; + struct rb_node *parent = NULL; + struct ptimer_node *entry; + int leftmost = 1; + if (tmo == NULL || base == NULL) + { + NSPOL_LOGERR ("input parameter is null"); + return; + } + + if ((tmo->state & PTIMER_STATE_ENQUEUED)) + { + NSPOL_LOGWAR (TIMERS_DEBUG | LWIP_DBG_LEVEL_WARNING, + "the timer state is: PTIMER_STATE_ENQUEUED"); + return; + } + + linknode = &base->active.rb_node; + while (*linknode) + { + parent = *linknode; + entry = rb_entry (parent, struct ptimer_node, node); + //XXX: do by the equal case is all of price of the large case + if (time_after_eq (entry->abs_nsec, tmo->abs_nsec)) + { + linknode = &(*linknode)->rb_left; + } + else + { + linknode = &(*linknode)->rb_right; + leftmost = 0; + } + } + + /* + * Insert the timer to the rb_tree and check whether it + * replaces the first pending timer + */ + if (leftmost) + { + base->first = &tmo->node; + } + + rb_link_node (&tmo->node, parent, linknode); + rb_insert_color (&tmo->node, &base->active); + NSPOL_LOGDBG (TIMERS_DEBUG, "enqueue]thread=%u,ptimer_node=%p", tmo->index, + tmo); + tmo->state |= PTIMER_STATE_ENQUEUED; +} + +void +launch_tmr (timer_t * tim, u64_t nsec) +{ + struct itimerspec vtim; + + vtim.it_value.tv_sec = (nsec) / NANO_PER_SECOND; + vtim.it_value.tv_nsec = (nsec) % NANO_PER_SECOND; + vtim.it_interval.tv_sec = 0; + vtim.it_interval.tv_nsec = 0; + + if (timer_settime (*tim, 0, &vtim, NULL) < 0) + { + NSPOL_LOGERR ("add_ptimer:timer_settime failed"); + } + +} + +/* + * add ptimer to rb_tree + * @param tmo: the ptimer node pointer + */ +void +add_ptimer (struct ptimer_node *tmo) +{ + if (tmo == NULL) + { + NSPOL_LOGERR ("input parameter is null"); + return; + } + enqueue_ptimer (tmo, &ptimer); + + if (ptimer.first == &tmo->node) + { + launch_tmr (&lazy_tim, tmo->info.msec * NANO_PER_MICROSECOND); + } +} + +#if 1 +/* + * cond signal ,send a ptimer message + * @param type: the message type + * @param handler: timeout handler + * @param node: the ptimer node pointer + */ +void +regedit_ptimer (enum msg_type Type, sys_timeout_handler handler, + struct ptimer_node *node) +{ + (void) handler; + (void) pthread_mutex_lock (&ptimer.lock); + if (ptimer.tail == NULL) + { + (void) pthread_mutex_unlock (&ptimer.lock); + NSPOL_LOGERR ("ptimer.tail is null"); + free (node); + node = NULL; + return; + } + ptimer.tail->msg_type = Type; + ptimer.tail->node = node; + ptimer.tail = ptimer.tail->next; + if (ptimer.head == ptimer.tail) + { + (void) pthread_mutex_unlock (&ptimer.lock); + NSPOL_LOGERR ("ptimer.head equal to ptimer.tail"); + return; + } + + (void) pthread_kill (g_timerThread_id, SIGRTMIN + 2); + + (void) pthread_mutex_unlock (&ptimer.lock); + return; +} +#endif +/* + * deal with the timeout signal + * + */ +void +deal_timeout_sig (void) +{ + struct ptimer_node *tmo; + struct timespec now; + unsigned long abs_nsec; + err_t err; + int retval; + if (ptimer.first == NULL) + { + NSPOL_LOGERR ("ptimer.first=NULL!!"); + return; + } + tmo = rb_entry (ptimer.first, struct ptimer_node, node); + retval = clock_gettime (CLOCK_MONOTONIC, &now); + if (0 != retval) + { + NSPOL_LOGERR ("clock_gettime failed]retval=%d,errno=%d", retval, errno); + } + abs_nsec = now.tv_sec * NANO_PER_SECOND + now.tv_nsec; + + // deal with all timeout point + while (time_after_eq (abs_nsec, tmo->abs_nsec)) + { + remove_ptimer (tmo, &ptimer); + + if (tmo->info.flags & PTIMER_ONESHOT) + { + } + else + { + //re-entry periodic ptimer + tmo->abs_nsec = now.tv_sec * NANO_PER_SECOND + now.tv_nsec + + tmo->info.msec * NANO_PER_MICROSECOND; + add_ptimer (tmo); + } + + //send timeout message + NSPOL_LOGDBG (INTERRUPT_DEBUG, + "ptimer happened to thread_index]index=%u", tmo->index); + if ((err = ltt_apimsg (tmo->info._phandle, (void *) tmo))) + { + NSPOL_LOGWAR (TIMERS_DEBUG | LWIP_DBG_LEVEL_WARNING, + "send timeout message failed!]errno=%d", err); + } + + if (ptimer.first == NULL) + { + NSPOL_LOGERR ("deal_timeout_sig: ptimer.first == NULL!!"); + return; + } + tmo = rb_entry (ptimer.first, struct ptimer_node, node); + } + + if (tmo->abs_nsec <= abs_nsec) + { + NSPOL_LOGERR ("tmo->abs_nsec is smaller than abs_nsec"); + return; + } + + NSPOL_LOGDBG (TIMERS_DEBUG, "TIMERSIGNAL : Launch timer for]time=%ul", + tmo->abs_nsec - abs_nsec); + launch_tmr (&lazy_tim, tmo->abs_nsec - abs_nsec); //timer interupted eveny 50ms instand by tmo->abs_nsec +} + +/* + * timeout signal handle function + * @param v: unused argument + */ +/*ptimer is already protected and used*/ + +NSTACK_STATIC void +timeout_sigaction (int sig) +{ + (void) sig; + if (!sys_arch_sem_trywait (&ptimer_lock)) + { + launch_tmr (&lazy_tim_retry, + (MIN_TIME_PICE / 5) * NANO_PER_MICROSECOND); + return; + } + + deal_timeout_sig (); + + sys_sem_signal (&ptimer_lock); + + return; +} + +/* + * initialize the ptimer buffer and timing mechanism + */ +err_t +init_ptimer (void) +{ + int i, retval; + struct sigevent timer_event; + struct sigevent timer_event1; + struct ptimer_msg *ptr; + + if (pthread_mutex_init (&ptimer.lock, NULL)) + { + NSPOL_LOGERR ("pthread_mutex_init failed"); + return ERR_MEM; + } + /*codex fix */ + if (ERR_MEM == sys_sem_new (&ptimer_lock, 1)) + { + NSPOL_LOGERR ("init_ptimer: sys_sem_new failure"); + return ERR_MEM; + } + + ptimer.active.rb_node = NULL; + ptimer.first = NULL; + + ptr = + (struct ptimer_msg *) malloc (PTIMER_MSG_BUFFER_SIZE * + sizeof (struct ptimer_msg)); + if (!ptr) + { + NSPOL_LOGERR ("init_ptimer: malloc ptimer buffer failed!"); + return ERR_MEM; + } + + int ret = + MEMSET_S (ptr, (PTIMER_MSG_BUFFER_SIZE * sizeof (struct ptimer_msg)), + 0, (PTIMER_MSG_BUFFER_SIZE * sizeof (struct ptimer_msg))); + if (EOK != ret) + { + free (ptr); + NSPOL_LOGERR ("init_ptimer: MEMSET_S ptimer buffer failed]ret=%d", ret); + return ERR_MEM; + } + + for (i = 0; i < PTIMER_MSG_BUFFER_SIZE - 1; i++) + { + ptr[i].next = &ptr[(i + 1)]; + ptr[(i + 1)].prev = &ptr[i]; + } + + ptr[i].next = &ptr[0]; + ptr[0].prev = &ptr[i]; + ptimer.head = ptimer.tail = &ptr[0]; + retval = + MEMSET_S (&timer_event, sizeof (struct sigevent), 0, + sizeof (struct sigevent)); + if (EOK != retval) + { + free (ptr); + ptr = NULL; + NSPOL_LOGERR ("MEMSET_S failed]ret=%d", retval); + return ERR_VAL; + } + timer_event.sigev_notify = SIGEV_SIGNAL; + timer_event.sigev_signo = SIGRTMIN; + timer_event.sigev_value.sival_ptr = (void *) &lazy_tim; + timer_event1 = timer_event; + timer_event1.sigev_value.sival_ptr = (void *) &lazy_tim_retry; + + if (timer_create (CLOCK_MONOTONIC, &timer_event, &lazy_tim) < 0) + { + free (ptr); + ptr = NULL; + NSPOL_LOGERR ("ptimer_init: timer_create failed!"); + return ERR_VAL; + } + + if (timer_create (CLOCK_MONOTONIC, &timer_event1, &lazy_tim_retry) < 0) + { + free (ptr); + ptr = NULL; + NSPOL_LOGERR ("ptimer_init: timer_create failed!"); + return ERR_VAL; + } + + return ERR_OK; +} + +NSTACK_STATIC err_t +process_timeout_msg (struct ptimer_msg * msg) +{ + struct ptimer_node *tmo = msg->node; + struct timespec now; + + switch (msg->msg_type) + { + case SYS_PTIMEROUT_MSG: + if (tmo) + { + int retval = clock_gettime (CLOCK_MONOTONIC, &now); + if (0 != retval) + { + NSPOL_LOGERR ("clock_gettime failed]retval=%d,errno=%d", retval, + errno); + } + tmo->abs_nsec = now.tv_sec * NANO_PER_SECOND + now.tv_nsec + + tmo->info.msec * NANO_PER_MICROSECOND; + add_ptimer (tmo); + } + else + { + NSPOL_LOGERR ("process_timeout_msg: rb_node is NULL!"); + return ERR_MEM; + } + + break; + case SYS_UNPTIMEROUT_MSG: + if (del_ptimer (msg) != ERR_OK) + { + NSPOL_LOGERR + ("process_timeout_msg: can not find the timeout event(oops)!"); + } + + break; + default: + NSPOL_LOGERR + ("process_timeout_msg: oops! lwip timeout_thread receive unacquainted message!"); + break; + } + + return ERR_OK; +} + +void +ptimer_thread (void *arg) +{ + LWIP_UNUSED_ARG (arg); + int sig, ret = -1; + sigset_t waitset; + sigset_t oset; + struct ptimer_msg *msg; + + if (0 != sigemptyset (&waitset)) + { + NSTCP_LOGERR ("sigemptyset function call error"); + return; + } + + if (0 != sigaddset (&waitset, SIGRTMIN)) + { + NSTCP_LOGERR ("sigaddset function call error"); + return; + } + + if (0 != sigaddset (&waitset, SIGRTMIN + 2)) + { + NSTCP_LOGERR ("sigaddset function call error"); + return; + } + + (void) pthread_sigmask (SIG_BLOCK, &waitset, &oset); + + (void) pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + (void) pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + NSPOL_LOGDBG (TIMERS_DEBUG, "ptimer: init done !"); + + if (!g_nstack_timer_tick.tick_ptr) + { + NSTCP_LOGERR ("g_nstack_timer_tick not inited"); + return; + } + (void) gettimeofday (&g_nstack_timer_tick.ref_time, NULL); + g_nstack_timer_tick.interval = 100; + *g_nstack_timer_tick.tick_ptr = 0; + g_nstack_timer_tick.ref_tick = 0; + while (1) + { + ret = sigwait (&waitset, &sig); + (void) nsfw_thread_chk (); // will only return TRUE, no need to check return value + if (ret != -1) + { + /* for timer expirt handle */ + if (SIGRTMIN == sig) + { + timeout_sigaction (sig); + continue; + } + } + else + { + continue; + } + + while (1) + { + (void) pthread_mutex_lock (&ptimer.lock); + if (ptimer.head == ptimer.tail) + { + (void) pthread_mutex_unlock (&ptimer.lock); + break; + } + + msg = ptimer.head; + ptimer.head = ptimer.head->next; + (void) pthread_mutex_unlock (&ptimer.lock); + + sys_arch_sem_wait (&ptimer_lock, 0); + + if (process_timeout_msg (msg) != ERR_OK) + { + NSPOL_LOGERR ("oops: ptimer_thread panic!"); + } + + sys_sem_signal (&ptimer_lock); + } + } +} + +void +timeout_phandler (void *act, void *arg) +{ + struct ptimer_node *tmo = arg; + if (act == NULL) + { + NSPOL_LOGERR ("input parameter arg is null"); + return; + } + + NSPOL_LOGINF (TIMERS_DEBUG, "Timer expire @timeout_phandler Handle %p", + tmo->info._phandle); + if (tmo->info.flags & PTIMER_ONESHOT) + { + sys_timeout_handler handle = act; + handle (tmo->info.ctx); + return; + } + else + { + NSPOL_LOGINF (TIMERS_DEBUG, + "Timer expire error @timeout_phandler Handle %p", + tmo->info._phandle); + } +} diff --git a/stacks/lwip_stack/lwip_src/core/unmatch_version.c b/stacks/lwip_stack/lwip_src/core/unmatch_version.c new file mode 100644 index 0000000..6c8cad3 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/core/unmatch_version.c @@ -0,0 +1,59 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nsfw_mem_api.h" +#include "nstack_share_res.h" +#include "nstack_securec.h" + +char *g_nstack_ver_info = NULL; + +int +init_unmatch_version (void) +{ + int ret; + nsfw_mem_zone mzone; + + ret = + STRCPY_S (mzone.stname.aname, NSFW_MEM_NAME_LENGTH, NSTACK_VERSION_SHM); + if (EOK != ret) + { + NSPOL_LOGERR ("STRCPY_S fail]ret=%d", ret); + return -1; + } + mzone.stname.entype = NSFW_SHMEM; + mzone.isocket_id = -1; + mzone.length = + NSTACK_VERSION_LEN + MAX_UNMATCH_VER_CNT * sizeof (unmatch_ver_info_t); + mzone.ireserv = 0; + + char *version = (char *) nsfw_mem_zone_create (&mzone); + if (NULL == version) + { + NSPOL_LOGERR ("Failed to create unmatch_version memory"); + return -1; + } + + ret = STRCPY_S (version, NSTACK_VERSION_LEN, NSTACK_VERSION); + if (EOK != ret) + { + NSPOL_LOGERR ("STRCPY_S NSTACK_VERSION fail]ret=%d", ret); + return -1; + } + + g_nstack_ver_info = version; + + return 0; +} |