summaryrefslogtreecommitdiffstats
path: root/src/framework/ipc/ps
diff options
context:
space:
mode:
Diffstat (limited to 'src/framework/ipc/ps')
-rw-r--r--src/framework/ipc/ps/nsfw_fd_timer.c378
-rw-r--r--src/framework/ipc/ps/nsfw_ps_mem_module.c924
-rw-r--r--src/framework/ipc/ps/nsfw_ps_mem_module.h87
-rw-r--r--src/framework/ipc/ps/nsfw_ps_module.c1725
-rw-r--r--src/framework/ipc/ps/nsfw_ps_module.h99
-rw-r--r--src/framework/ipc/ps/nsfw_recycle_module.c666
-rw-r--r--src/framework/ipc/ps/nsfw_recycle_module.h84
-rw-r--r--src/framework/ipc/ps/nsfw_soft_param.c296
8 files changed, 4259 insertions, 0 deletions
diff --git a/src/framework/ipc/ps/nsfw_fd_timer.c b/src/framework/ipc/ps/nsfw_fd_timer.c
new file mode 100644
index 0000000..57535a3
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_fd_timer.c
@@ -0,0 +1,378 @@
+/*
+*
+* 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 <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/timerfd.h>
+
+#include "types.h"
+#include "list.h"
+
+#include "nstack_securec.h"
+#include "nsfw_init.h"
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_mem_api.h"
+#include "nstack_log.h"
+#include "nsfw_base_linux_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "nsfw_maintain_api.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#define NSFW_TIMER_CYCLE 1
+#define NSFW_TIMER_INFO_MAX_COUNT_DEF 8191
+#define NSFW_TIMER_INFO_MAX_COUNT (g_timer_cfg.timer_info_size)
+/* *INDENT-OFF* */
+nsfw_timer_init_cfg g_timer_cfg;
+
+u8 g_hbt_switch = FALSE;
+/* *INDENT-ON* */
+
+/*****************************************************************************
+* Prototype : nsfw_timer_reg_timer
+* Description : reg timer with callback function when timeout
+* Input : u32 timer_type
+* void* data
+* nsfw_timer_proc_fun fun
+* struct timespec time_left
+* Output : None
+* Return Value : nsfw_timer_info*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+nsfw_timer_info *
+nsfw_timer_reg_timer (u32 timer_type, void *data,
+ nsfw_timer_proc_fun fun, struct timespec time_left)
+{
+ nsfw_timer_info *tm_info = NULL;
+ if (0 ==
+ nsfw_mem_ring_dequeue (g_timer_cfg.timer_info_pool, (void *) &tm_info))
+ {
+ NSFW_LOGERR ("dequeue error]data=%p,fun=%p", data, fun);
+ return NULL;
+ }
+
+ if (EOK != MEMSET_S (tm_info, sizeof (*tm_info), 0, sizeof (*tm_info)))
+ {
+ if (0 == nsfw_mem_ring_enqueue (g_timer_cfg.timer_info_pool, tm_info))
+ {
+ NSFW_LOGERR ("enqueue error]data=%p,fun=%p", data, fun);
+ }
+ NSFW_LOGERR ("mem set error]data=%p,fun=%p", data, fun);
+ return NULL;
+ }
+
+ tm_info->fun = fun;
+ tm_info->argv = data;
+ tm_info->time_left = time_left;
+ //tm_info->time_left.tv_sec += NSFW_TIMER_CYCLE;
+ tm_info->timer_type = timer_type;
+ list_add_tail (&tm_info->node, &g_timer_cfg.timer_head);
+ tm_info->alloc_flag = TRUE;
+ return tm_info;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_timer_rmv_timer
+* Description : stop timer
+* Input : nsfw_timer_info* tm_info
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+void
+nsfw_timer_rmv_timer (nsfw_timer_info * tm_info)
+{
+ if (NULL == tm_info)
+ {
+ NSFW_LOGWAR ("tm_info nul");
+ return;
+ }
+
+ if (FALSE == tm_info->alloc_flag)
+ {
+ NSFW_LOGERR ("tm_info refree]tm_info=%p,argv=%p,fun=%p", tm_info,
+ tm_info->argv, tm_info->fun);
+ return;
+ }
+
+ tm_info->alloc_flag = FALSE;
+ list_del (&tm_info->node);
+ if (0 == nsfw_mem_ring_enqueue (g_timer_cfg.timer_info_pool, tm_info))
+ {
+ NSFW_LOGERR ("tm_info free failed]tm_info=%p,argv=%p,fun=%p", tm_info,
+ tm_info->argv, tm_info->fun);
+ }
+ return;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_timer_exp
+* Description : timer expire
+* Input : u64 count
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+void
+nsfw_timer_exp (u64 count)
+{
+ nsfw_timer_info *tm_info = NULL;
+ struct list_head *tNode;
+ struct list_head *tPretNode;
+
+ LINT_LIST ()list_for_each_entry (tm_info, tNode, (&g_timer_cfg.timer_head),
+ node)
+ {
+ tPretNode = tm_info->node.prev;
+ if (tm_info->time_left.tv_sec > (long) count * NSFW_TIMER_CYCLE)
+ {
+ tm_info->time_left.tv_sec -= count * NSFW_TIMER_CYCLE;
+ continue;
+ }
+
+ list_del (&tm_info->node);
+ list_add_tail (&tm_info->node, &g_timer_cfg.exp_timer_head);
+ tNode = tPretNode;
+ }
+
+ u32 i = 0;
+ while (!list_empty (&g_timer_cfg.exp_timer_head)
+ && i++ < NSFW_TIMER_INFO_MAX_COUNT)
+ {
+ tm_info =
+ (nsfw_timer_info *) list_get_first (&g_timer_cfg.exp_timer_head);
+ if (NULL != tm_info->fun)
+ {
+ (void) tm_info->fun (tm_info->timer_type, tm_info->argv);
+ }
+ nsfw_timer_rmv_timer (tm_info);
+ }
+
+}
+
+/*****************************************************************************
+* Prototype : nsfw_get_timer_socket
+* Description : get timer socket from kernel
+* Input : None
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*****************************************************************************/
+i32
+nsfw_get_timer_socket ()
+{
+ i32 tfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if (tfd == -1)
+ {
+ NSFW_LOGERR ("timerfd_create failed!]errno=%d\n", errno);
+ return -1;
+ }
+
+ /* close on exe */
+ if (-1 == nsfw_set_close_on_exec (tfd))
+ {
+ (void) nsfw_base_close (tfd);
+ NSFW_LOGERR ("set exec err]fd=%d, errno=%d", tfd, errno);
+ return -1;
+ }
+
+ struct itimerspec ts;
+ ts.it_interval.tv_sec = NSFW_TIMER_CYCLE;
+ ts.it_interval.tv_nsec = 0;
+ ts.it_value.tv_sec = 0;
+ ts.it_value.tv_nsec = NSFW_TIMER_CYCLE;
+
+ if (timerfd_settime (tfd, 0, &ts, NULL) < 0)
+ {
+ NSFW_LOGERR ("timerfd_settime failed] errno=%d", errno);
+ close (tfd);
+ return -1;
+ }
+
+ return tfd;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_timer_notify_fun
+* Description : receive timer event from kernel
+* Input : i32 epfd
+* i32 fd
+* u32 events
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_timer_notify_fun (i32 epfd, i32 fd, u32 events)
+{
+ i32 rc;
+
+ if ((events & EPOLLERR) || (events & EPOLLHUP) || (!(events & EPOLLIN)))
+ {
+ (void) nsfw_base_close (fd);
+ NSFW_LOGWAR ("timer disconnect!]epfd=%d,timer=%d,event=0x%x", epfd,
+ fd, events);
+
+ (void) nsfw_mgr_unreg_sock_fun (fd);
+ i32 timer_fd = nsfw_get_timer_socket ();
+ if (timer_fd < 0)
+ {
+ NSFW_LOGERR ("get timer_fd faied!]epfd=%d,timer_fd=%d,event=0x%x",
+ epfd, fd, events);
+ return FALSE;
+ }
+
+ (void) nsfw_mgr_reg_sock_fun (timer_fd, nsfw_timer_notify_fun);
+ return TRUE;
+ }
+
+ u64 data;
+ while (1)
+ {
+ rc = nsfw_base_read (fd, &data, sizeof (data));
+ if (rc == 0)
+ {
+ NSFW_LOGERR ("timer_fd recv 0]timer_fd=%d,errno=%d", fd, errno);
+ break;
+ }
+ else if (rc == -1)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ break;
+ }
+ NSMON_LOGERR ("timer_fd recv]timer_fd=%d,errno=%d", fd, errno);
+ break;
+ }
+
+ nsfw_timer_exp (data);
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_timer_start
+* Description : reg the timer module to epoll thread
+* Input : None
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+u8
+nsfw_timer_start ()
+{
+ i32 timer_fd = nsfw_get_timer_socket ();
+ if (timer_fd < 0)
+ {
+ NSFW_LOGERR ("get timer_fd failed!");
+ return FALSE;
+ }
+
+ NSFW_LOGINF ("start timer_fd module!]timer_fd=%d", timer_fd);
+ (void) nsfw_mgr_reg_sock_fun (timer_fd, nsfw_timer_notify_fun);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_timer_module_init
+* Description : module init
+* Input : void* param
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int
+nsfw_timer_module_init (void *param)
+{
+ u32 proc_type = (u32) ((long long) param);
+ nsfw_timer_init_cfg *timer_cfg = &g_timer_cfg;
+ NSFW_LOGINF ("ps module init]type=%u", proc_type);
+ switch (proc_type)
+ {
+ case NSFW_PROC_MASTER:
+ case NSFW_PROC_MAIN:
+ (void) NSFW_REG_SOFT_INT (NSFW_DBG_MODE_PARAM, g_hbt_switch, 0, 1);
+ break;
+ case NSFW_PROC_TOOLS:
+ case NSFW_PROC_CTRL:
+ break;
+ default:
+ return 0;
+ }
+
+ timer_cfg->timer_info_size = NSFW_TIMER_INFO_MAX_COUNT_DEF;
+
+ nsfw_mem_sppool pmpinfo;
+ pmpinfo.enmptype = NSFW_MRING_MPMC;
+ pmpinfo.usnum = timer_cfg->timer_info_size;
+ pmpinfo.useltsize = sizeof (nsfw_timer_info);
+ pmpinfo.isocket_id = NSFW_SOCKET_ANY;
+ pmpinfo.stname.entype = NSFW_NSHMEM;
+ if (-1 ==
+ SPRINTF_S (pmpinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ "MS_TM_INFOPOOL"))
+ {
+ NSFW_LOGERR ("SPRINTF_S failed");
+ return -1;
+ }
+ timer_cfg->timer_info_pool = nsfw_mem_sp_create (&pmpinfo);
+
+ if (!timer_cfg->timer_info_pool)
+ {
+ NSFW_LOGERR ("alloc timer info pool_err");
+ return -1;
+ }
+
+ MEM_STAT (NSFW_TIMER_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM,
+ nsfw_mem_get_len (timer_cfg->timer_info_pool, NSFW_MEM_SPOOL));
+
+ INIT_LIST_HEAD (&(timer_cfg->timer_head));
+ INIT_LIST_HEAD (&(timer_cfg->exp_timer_head));
+
+ (void) nsfw_timer_start ();
+ return 0;
+}
+
+/* *INDENT-OFF* */
+NSFW_MODULE_NAME (NSFW_TIMER_MODULE)
+NSFW_MODULE_PRIORITY (10)
+NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE)
+NSFW_MODULE_INIT (nsfw_timer_module_init)
+/* *INDENT-ON* */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/src/framework/ipc/ps/nsfw_ps_mem_module.c b/src/framework/ipc/ps/nsfw_ps_mem_module.c
new file mode 100644
index 0000000..9cda6b3
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_ps_mem_module.c
@@ -0,0 +1,924 @@
+/*
+*
+* 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 <stdlib.h>
+#include "types.h"
+#include "nstack_securec.h"
+#include "nsfw_init.h"
+
+#include "nsfw_ps_module.h"
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_ps_mem_api.h"
+#include "nsfw_ps_mem_module.h"
+#include "nsfw_ps_api.h"
+#include "nsfw_maintain_api.h"
+#include "nsfw_fd_timer_api.h"
+
+#include "nstack_log.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+ns_mem_mng_init_cfg g_mem_cfg;
+
+int mem_ps_exiting (void *pps_info, void *argv);
+
+int
+nsfw_mem_ps_exit_resend_timeout (u32 timer_type, void *data)
+{
+ nsfw_ps_info *ps_info = data;
+ if (NULL == ps_info)
+ {
+ NSFW_LOGERR ("ps_info nul!");
+ return FALSE;
+ }
+
+ if (NSFW_PROC_APP != ps_info->proc_type)
+ {
+ return FALSE;
+ }
+
+ if (NSFW_PS_EXITING != ps_info->state)
+ {
+ return FALSE;
+ }
+
+ ps_info->resend_timer_ptr = NULL;
+ (void) mem_ps_exiting (ps_info, NULL);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_ps_exiting
+* Description : send exiting message when ps_info exiting
+* Input : void *pps_info
+* void* argv
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+mem_ps_exiting (void *pps_info, void *argv)
+{
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("ps_info nul!");
+ return FALSE;
+ }
+
+ if (TRUE == NSFW_SRV_STATE_SUSPEND)
+ {
+ NSFW_LOGERR ("main suspend]ps_info=%d,pid=%u", pps_info,
+ ((nsfw_ps_info *) pps_info)->host_pid);
+ return FALSE;
+ }
+
+ nsfw_mgr_msg *msg =
+ nsfw_mgr_msg_alloc (MGR_MSG_APP_EXIT_REQ, NSFW_PROC_MAIN);
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("ps_exit alloc msg failed]ps_info=%p,pid=%u", pps_info,
+ ((nsfw_ps_info *) pps_info)->host_pid);
+ return FALSE;
+ }
+
+ nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, msg);
+ ps_msg->host_pid = ((nsfw_ps_info *) pps_info)->host_pid;
+
+ (void) nsfw_mgr_send_msg (msg);
+ NSFW_LOGINF ("ps_exiting send msg]ps_info=%p,pid=%u", pps_info,
+ ps_msg->host_pid);
+ nsfw_mgr_msg_free (msg);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_alloc_ps_info
+* Description : alloc ps_info
+* Input : u32 pid
+* u8 proc_type
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+mem_alloc_ps_info (u32 pid, u8 proc_type)
+{
+ nsfw_ps_info *pps_info = NULL;
+ pps_info = nsfw_ps_info_get (pid);
+ if (NULL != pps_info)
+ {
+ return TRUE;
+ }
+
+ pps_info = nsfw_ps_info_alloc (pid, proc_type);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("alloc ps_info falied!]pid=%u,proc_type=%u", pid,
+ proc_type);
+ return FALSE;
+ }
+
+ NSFW_LOGINF ("alloc new ps_info]pps_info=%p,pid=%u", pps_info, pid);
+ return TRUE;
+}
+
+/*mem alloc by msg begin*/
+void *
+mem_item_zone_create (void *mem_info)
+{
+ return (void *) nsfw_mem_zone_create ((nsfw_mem_zone *) mem_info);
+}
+
+void *
+mem_item_mbfmp_create (void *mem_info)
+{
+ return (void *) nsfw_mem_mbfmp_create ((nsfw_mem_mbfpool *) mem_info);
+}
+
+void *
+mem_item_sp_create (void *mem_info)
+{
+ return (void *) nsfw_mem_sp_create ((nsfw_mem_sppool *) mem_info);
+}
+
+void *
+mem_item_ring_create (void *mem_info)
+{
+ return (void *) nsfw_mem_ring_create ((nsfw_mem_mring *) mem_info);
+}
+
+nsfw_ps_mem_item_cfg g_ps_mem_map[] = {
+ {
+ NSFW_RESERV_REQ_MSG,
+ sizeof (nsfw_shmem_reserv_req),
+ NSFW_MEM_MZONE,
+ mem_item_zone_create,
+ mem_item_get_callargv}
+ ,
+
+ {
+ NSFW_MBUF_REQ_MSG,
+ sizeof (nsfw_shmem_mbuf_req),
+ NSFW_MEM_MBUF,
+ mem_item_mbfmp_create,
+ mem_item_get_callargv}
+ ,
+ {
+ NSFW_SPPOOL_REQ_MSG,
+ sizeof (nsfw_shmem_sppool_req),
+ NSFW_MEM_SPOOL,
+ mem_item_sp_create,
+ mem_item_get_callargv}
+ ,
+ {
+ NSFW_RING_REQ_MSG,
+ sizeof (nsfw_shmem_ring_req),
+ NSFW_MEM_RING,
+ mem_item_ring_create,
+ mem_item_get_callargv}
+ ,
+ {
+ NSFW_RELEASE_REQ_MSG,
+ sizeof (nsfw_shmem_free_req),
+ 0xFFFF,
+ mem_item_free,
+ mem_item_get_callargv,
+ }
+ ,
+ {
+ NSFW_MEM_LOOKUP_REQ_MSG,
+ sizeof (nsfw_shmem_lookup_req),
+ 0xFFFF,
+ mem_item_lookup,
+ mem_item_get_callargv,
+ }
+};
+
+/*****************************************************************************
+* Prototype : mem_item_get_cfg_from_msg
+* Description : get memory config
+* Input : u16 msg_type
+* Output : None
+* Return Value : nsfw_ps_mem_item_cfg *
+* Calls :
+* Called By :
+*****************************************************************************/
+nsfw_ps_mem_item_cfg *
+mem_item_get_cfg_from_msg (u16 msg_type)
+{
+ int idx;
+ int map_count = sizeof (g_ps_mem_map) / sizeof (nsfw_ps_mem_item_cfg);
+ for (idx = 0; idx < map_count; idx++)
+ {
+ if (g_ps_mem_map[idx].usmsg_type == msg_type)
+ {
+ return &g_ps_mem_map[idx];
+ }
+ }
+
+ return NULL;
+}
+
+/*****************************************************************************
+* Prototype : mem_item_get_callargv
+* Description : change the message value to structur value
+* Input : u16 msg_type
+* char* msg_body
+* char *memstr_buf
+* i32 buf_len
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+mem_item_get_callargv (u16 msg_type, char *msg_body, char *memstr_buf,
+ i32 buf_len)
+{
+ switch (msg_type)
+ {
+ case NSFW_RESERV_REQ_MSG:
+ MEM_GET_CALLARGV (lenth, lenth, nsfw_mem_zone, nsfw_shmem_reserv_req,
+ memstr_buf, msg_body);
+ MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_zone,
+ nsfw_shmem_reserv_req, memstr_buf, msg_body);
+ break;
+ case NSFW_MBUF_REQ_MSG:
+ MEM_GET_CALLARGV (usnum, usnum, nsfw_mem_mbfpool, nsfw_shmem_mbuf_req,
+ memstr_buf, msg_body);
+ MEM_GET_CALLARGV (uscash_size, uscash_size, nsfw_mem_mbfpool,
+ nsfw_shmem_mbuf_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (uspriv_size, uspriv_size, nsfw_mem_mbfpool,
+ nsfw_shmem_mbuf_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (usdata_room, usdata_room, nsfw_mem_mbfpool,
+ nsfw_shmem_mbuf_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (enmptype, enmptype, nsfw_mem_mbfpool,
+ nsfw_shmem_mbuf_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_mbfpool,
+ nsfw_shmem_mbuf_req, memstr_buf, msg_body);
+ break;
+ case NSFW_SPPOOL_REQ_MSG:
+ MEM_GET_CALLARGV (usnum, usnum, nsfw_mem_sppool,
+ nsfw_shmem_sppool_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (useltsize, useltsize, nsfw_mem_sppool,
+ nsfw_shmem_sppool_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (enmptype, enmptype, nsfw_mem_sppool,
+ nsfw_shmem_sppool_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_sppool,
+ nsfw_shmem_sppool_req, memstr_buf, msg_body);
+ break;
+ case NSFW_RING_REQ_MSG:
+ MEM_GET_CALLARGV (usnum, usnum, nsfw_mem_mring, nsfw_shmem_ring_req,
+ memstr_buf, msg_body);
+ MEM_GET_CALLARGV (enmptype, enmptype, nsfw_mem_mring,
+ nsfw_shmem_ring_req, memstr_buf, msg_body);
+ MEM_GET_CALLARGV (isocket_id, isocket_id, nsfw_mem_mring,
+ nsfw_shmem_ring_req, memstr_buf, msg_body);
+ break;
+ case NSFW_RELEASE_REQ_MSG:
+ MEM_GET_CALLARGV (ustype, ustype, nsfw_mem_type_info,
+ nsfw_shmem_free_req, memstr_buf, msg_body);
+ break;
+ case NSFW_MEM_LOOKUP_REQ_MSG:
+ MEM_GET_CALLARGV (ustype, ustype, nsfw_mem_type_info,
+ nsfw_shmem_lookup_req, memstr_buf, msg_body);
+ break;
+ default:
+ NSFW_LOGERR ("error msg]type=%u", msg_type);
+ return FALSE;
+ }
+ if (EOK !=
+ STRCPY_S (((nsfw_mem_zone *) memstr_buf)->stname.aname,
+ NSFW_MEM_NAME_LENTH,
+ ((nsfw_shmem_reserv_req *) msg_body)->aname))
+ {
+ NSFW_LOGERR ("STRCPY_S failed]msg_type=%u", msg_type);
+ return FALSE;
+ }
+
+ ((nsfw_mem_zone *) memstr_buf)->stname.entype = NSFW_SHMEM;
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_item_free
+* Description : free memory item
+* Input : void *pdata
+* Output : None
+* Return Value : void*
+* Calls :
+* Called By :
+*****************************************************************************/
+void *
+mem_item_free (void *pdata)
+{
+ nsfw_mem_type_info *mem_free = (nsfw_mem_type_info *) pdata;
+ i32 ret;
+ NSFW_LOGINF ("free mem]type=%u,name=%s", mem_free->ustype,
+ mem_free->stname.aname);
+ switch (mem_free->ustype)
+ {
+ case NSFW_MEM_MZONE:
+ ret = nsfw_mem_zone_release (&mem_free->stname);
+ break;
+ case NSFW_MEM_MBUF:
+ ret = nsfw_mem_mbfmp_release (&mem_free->stname);
+ break;
+ case NSFW_MEM_SPOOL:
+ ret = nsfw_mem_sp_release (&mem_free->stname);
+ break;
+ case NSFW_MEM_RING:
+ ret = nsfw_mem_ring_release (&mem_free->stname);
+ break;
+ default:
+ NSFW_LOGERR ("free mem err type]type=%u", mem_free->ustype);
+ return NULL;
+ }
+
+ if (NSFW_MEM_OK != ret)
+ {
+ NSFW_LOGERR ("mem free failed!]ret=%d", ret);
+ return NULL;
+ }
+
+ return pdata;
+}
+
+/*****************************************************************************
+* Prototype : mem_item_lookup
+* Description : lookup memory item
+* Input : void *pdata
+* Output : None
+* Return Value : void*
+* Calls :
+* Called By :
+*****************************************************************************/
+void *
+mem_item_lookup (void *pdata)
+{
+ nsfw_mem_type_info *mem_lookup = (nsfw_mem_type_info *) pdata;
+ void *ret;
+ NSFW_LOGDBG ("lookup mem]type=%u,name=%s", mem_lookup->ustype,
+ mem_lookup->stname.aname);
+ switch (mem_lookup->ustype)
+ {
+ case NSFW_MEM_MZONE:
+ ret = nsfw_mem_zone_lookup (&mem_lookup->stname);
+ break;
+ case NSFW_MEM_MBUF:
+ ret = nsfw_mem_mbfmp_lookup (&mem_lookup->stname);
+ break;
+ case NSFW_MEM_SPOOL:
+ ret = nsfw_mem_sp_lookup (&mem_lookup->stname);
+ break;
+ case NSFW_MEM_RING:
+ ret = nsfw_mem_ring_lookup (&mem_lookup->stname);
+ break;
+ default:
+ NSFW_LOGERR ("lookup mem err type]type=%d", mem_lookup->ustype);
+ return NULL;
+ }
+
+ if (NULL == ret)
+ {
+ NSFW_LOGERR ("mem lookup failed!]ret=%p,name=%s", ret,
+ mem_lookup->stname.aname);
+ return NULL;
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : mem_item_proc_by_msg
+* Description : call memory item process function
+* Input : void *pdata
+* nsfw_ps_mem_item_cfg* item_cfg
+* Output : None
+* Return Value : void*
+* Calls :
+* Called By :
+*****************************************************************************/
+void *
+mem_item_proc_by_msg (void *pdata, nsfw_ps_mem_item_cfg * item_cfg)
+{
+ char argv_buf[NSFW_MEM_CALL_ARG_BUF] = { 0 };
+
+ if ((NULL == item_cfg->change_fun) || (NULL == item_cfg->create_fun))
+ {
+ NSFW_LOGERR ("item error]change_fun=%p,create_fun=%p",
+ item_cfg->change_fun, item_cfg->create_fun);
+ return NULL;
+ }
+
+ if (FALSE ==
+ item_cfg->change_fun (item_cfg->usmsg_type, pdata, argv_buf,
+ NSFW_MEM_CALL_ARG_BUF))
+ {
+ NSFW_LOGERR ("call change_fun failed!]type=%u", item_cfg->usmsg_type);
+ return NULL;
+ }
+
+ void *pdataret = NULL;
+ pdataret = (item_cfg->create_fun) ((void *) argv_buf);
+ return pdataret;
+}
+
+/*****************************************************************************
+* Prototype : mem_init_rsp_msg
+* Description : init the rsp message
+* Input : nsfw_shmem_msg_head* msg
+* nsfw_shmem_msg_head *rsp
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+u8
+mem_init_rsp_msg (nsfw_shmem_msg_head * msg, nsfw_shmem_msg_head * rsp)
+{
+ nsfw_ps_mem_item_cfg *item_cfg =
+ mem_item_get_cfg_from_msg (msg->usmsg_type);
+ if (NULL == item_cfg)
+ {
+ NSFW_LOGERR ("get item cfg failed!]msg_type=%u", msg->usmsg_type);
+ return FALSE;
+ }
+
+ int idx;
+ int mem_count = msg->uslenth / item_cfg->item_size;
+
+ rsp->usmsg_type = msg->usmsg_type + 1;
+ rsp->uslenth = mem_count * sizeof (nsfw_shmem_ack);
+ nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]);
+ char *pdata = NULL;
+ for (idx = 0; idx < mem_count; idx++)
+ {
+ pdata = (char *) msg->aidata + idx * item_cfg->item_size;
+ pack->pbase_addr = NULL;
+ pack->usseq = ((nsfw_shmem_reserv_req *) pdata)->usseq;
+ pack->cstate = NSFW_MEM_ALLOC_FAIL;
+ pack++;
+ }
+
+ NSFW_LOGDBG ("init all rsp ack]mem_count=%d,msg_type=%u", mem_count,
+ msg->usmsg_type);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_rel_mem_by_msg
+* Description : release memory by message
+* Input : nsfw_shmem_msg_head* req_msg
+* nsfw_shmem_msg_head *rsp
+* u32 pid
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+mem_rel_mem_by_msg (nsfw_shmem_msg_head * req_msg,
+ nsfw_shmem_msg_head * rsp, u32 pid)
+{
+ u32 i;
+ nsfw_ps_mem_item_cfg *item_cfg =
+ mem_item_get_cfg_from_msg (req_msg->usmsg_type);
+ if (NULL == item_cfg)
+ {
+ NSFW_LOGERR ("get item cfg failed!]msg_type=%u", req_msg->usmsg_type);
+ return FALSE;
+ }
+
+ unsigned int mem_count = req_msg->uslenth / item_cfg->item_size;
+ char *pdata = NULL;
+ nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]);
+ for (i = 0; i < mem_count; i++)
+ {
+ pdata = (char *) req_msg->aidata + i * item_cfg->item_size;
+ if (NULL != mem_item_proc_by_msg ((void *) pdata, item_cfg))
+ {
+ pack->cstate = NSFW_MEM_ALLOC_SUCC;
+ pack->pbase_addr = NULL;
+ }
+ pack++;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_lookup_mem_by_msg
+* Description : lookup memory by message
+* Input : nsfw_shmem_msg_head* mgr_msg
+* nsfw_shmem_msg_head *rsp
+* u32 pid
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+mem_lookup_mem_by_msg (nsfw_shmem_msg_head * mgr_msg,
+ nsfw_shmem_msg_head * rsp, u32 pid)
+{
+ i32 idx;
+ nsfw_ps_mem_item_cfg *item_cfg =
+ mem_item_get_cfg_from_msg (mgr_msg->usmsg_type);
+ if (NULL == item_cfg)
+ {
+ NSFW_LOGERR ("get item cfg failed!]msg_type=%u", mgr_msg->usmsg_type);
+ return FALSE;
+ }
+
+ int mem_count = mgr_msg->uslenth / item_cfg->item_size;
+ char *pdata = NULL;
+ void *paddr = NULL;
+ nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]);
+
+ for (idx = 0; idx < mem_count; idx++)
+ {
+ pdata = (char *) mgr_msg->aidata + idx * item_cfg->item_size;
+ paddr = mem_item_proc_by_msg ((void *) pdata, item_cfg);
+ if (NULL != paddr)
+ {
+ pack->cstate = NSFW_MEM_ALLOC_SUCC;
+ pack->pbase_addr = paddr;
+ }
+ pack++;
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_alloc_mem_by_msg
+* Description : alloc memory by message
+* Input : nsfw_shmem_msg_head* mem_msg
+* nsfw_shmem_msg_head *rsp
+* Output : None
+* Return Value : ns_mem_info*
+* Calls :
+* Called By :
+*****************************************************************************/
+void *
+mem_alloc_mem_by_msg (nsfw_shmem_msg_head * mem_msg,
+ nsfw_shmem_msg_head * rsp)
+{
+ nsfw_ps_mem_item_cfg *item_cfg =
+ mem_item_get_cfg_from_msg (mem_msg->usmsg_type);
+ if (NULL == item_cfg)
+ {
+ NSFW_LOGERR ("get item cfg failed!]msg_type=%u", mem_msg->usmsg_type);
+ return NULL;
+ }
+
+ int i;
+ int j;
+ nsfw_mem_type_info mem_free;
+ char *pdata = NULL;
+ void *p_addr = NULL;
+
+ int mem_count = mem_msg->uslenth / item_cfg->item_size;
+ nsfw_shmem_ack *pack = (nsfw_shmem_ack *) & (rsp->aidata[0]);
+ for (i = 0; i < mem_count; i++)
+ {
+ pdata = (char *) mem_msg->aidata + i * item_cfg->item_size;
+ p_addr = mem_item_proc_by_msg ((void *) pdata, item_cfg);
+ if (NULL == p_addr)
+ {
+ NSFW_LOGERR
+ ("alloc mem failed!]type=%u,mem_count=%d,item=%d,name=%s",
+ mem_msg->usmsg_type, mem_count, i,
+ ((nsfw_shmem_reserv_req *) pdata)->aname);
+ goto fail_free_mem;
+ }
+
+ pack->cstate = NSFW_MEM_ALLOC_SUCC;
+ pack->pbase_addr = p_addr;
+ NSFW_LOGINF
+ ("alloc mem suc!]addr=%p,type=%u,mem_count=%d,item=%d,name=%s",
+ p_addr, mem_msg->usmsg_type, mem_count, i,
+ ((nsfw_shmem_reserv_req *) pdata)->aname);
+ pack++;
+ }
+ return p_addr;
+
+fail_free_mem:
+ for (j = 0; j < i; j++)
+ {
+ pdata = (char *) mem_msg->aidata + j * item_cfg->item_size;
+ if (EOK !=
+ STRCPY_S (mem_free.stname.aname, NSFW_MEM_NAME_LENTH,
+ ((nsfw_shmem_reserv_req *) pdata)->aname))
+ {
+ NSFW_LOGERR ("STRCPY_S failed]j=%d", j);
+ continue;
+ }
+
+ mem_free.ustype = item_cfg->mem_type;
+ mem_free.stname.entype = NSFW_SHMEM;
+ (void) mem_item_free (&mem_free);
+ NSFW_LOGINF ("free mem]addr=%p,type=%u,mem_count=%d,item=%d,name=%s",
+ p_addr, mem_msg->usmsg_type, mem_count, j,
+ ((nsfw_shmem_reserv_req *) pdata)->aname);
+ pack++;
+ }
+
+ return NULL;
+
+}
+
+/*****************************************************************************
+* Prototype : mem_alloc_req_proc
+* Description : memory message
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+mem_alloc_req_proc (nsfw_mgr_msg * msg)
+{
+ void *mem_addr = NULL;
+
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("msg nul");
+ return FALSE;
+ }
+
+ nsfw_shmem_msg_head *mem_msg = GET_USER_MSG (nsfw_shmem_msg_head, msg);
+ nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg);
+ if (NULL == rsp_msg)
+ {
+ NSFW_LOGERR ("alloc rsp msg failed]msg_type=%u", mem_msg->usmsg_type);
+ return FALSE;
+ }
+
+ nsfw_shmem_msg_head *mem_rsp_msg =
+ GET_USER_MSG (nsfw_shmem_msg_head, rsp_msg);
+
+ if (!mem_init_rsp_msg (mem_msg, mem_rsp_msg))
+ {
+ NSFW_LOGERR ("init rsp msg failed]msg_type=%u", mem_msg->usmsg_type);
+ nsfw_mgr_msg_free (rsp_msg);
+ return FALSE;
+ }
+
+ switch (mem_msg->usmsg_type)
+ {
+ case NSFW_MEM_LOOKUP_REQ_MSG:
+ if (!mem_lookup_mem_by_msg (mem_msg, mem_rsp_msg, msg->src_pid))
+ {
+ NSFW_LOGERR ("lookup mem msg failed]msg_type=%u",
+ mem_msg->usmsg_type);
+ goto sendrspmsg;
+ }
+ (void) mem_alloc_ps_info (msg->src_pid, msg->src_proc_type);
+ break;
+ case NSFW_RESERV_REQ_MSG:
+ case NSFW_MBUF_REQ_MSG:
+ case NSFW_SPPOOL_REQ_MSG:
+ case NSFW_RING_REQ_MSG:
+ mem_addr = mem_alloc_mem_by_msg (mem_msg, mem_rsp_msg);
+ if (NULL == mem_addr)
+ {
+ NSFW_LOGERR ("alloc mem msg failed]msg_type=%u",
+ mem_msg->usmsg_type);
+ (void) mem_init_rsp_msg (mem_msg, mem_rsp_msg);
+ goto sendrspmsg;
+ }
+ (void) mem_alloc_ps_info (msg->src_pid, msg->src_proc_type);
+ break;
+ case NSFW_RELEASE_REQ_MSG:
+ if (!mem_rel_mem_by_msg (mem_msg, mem_rsp_msg, msg->src_pid))
+ {
+ NSFW_LOGERR ("rel mem msg failed]msg_type=%u", mem_msg->usmsg_type);
+ goto sendrspmsg;
+ }
+ break;
+ default:
+ break;
+ }
+
+sendrspmsg:
+ (void) nsfw_mgr_send_msg (rsp_msg);
+ nsfw_mgr_msg_free (rsp_msg);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_ps_exiting_resend
+* Description : send the exiting message again
+* Input : void *pps_info
+* void* argv
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+mem_ps_exiting_resend (void *pps_info, void *argv)
+{
+ u32 *count = argv;
+ nsfw_ps_info *ps_info = pps_info;
+ if (NULL == ps_info)
+ {
+ NSFW_LOGERR ("ps_info nul!");
+ return FALSE;
+ }
+
+ if (NSFW_PROC_APP != ps_info->proc_type)
+ {
+ return FALSE;
+ }
+
+ if (NSFW_PS_EXITING != ps_info->state)
+ {
+ return FALSE;
+ }
+
+ if (NULL != count)
+ {
+ NSFW_LOGINF ("send count]count=%u,pid=%u", *count, ps_info->host_pid);
+ if (NSFW_PS_SEND_PER_TIME < (*count)++)
+ {
+ struct timespec time_left =
+ { NSFW_PS_MEM_RESEND_TVLAUE +
+((*count) / NSFW_PS_SEND_PER_TIME), 0
+ };
+ ps_info->resend_timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_PS_MEM_RESEND_TIMER,
+ pps_info,
+ nsfw_mem_ps_exit_resend_timeout,
+ time_left);
+ return TRUE;
+ }
+ }
+
+ (void) mem_ps_exiting (ps_info, NULL);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_mem_srv_restore_timeout
+* Description : service waiting resume timeout
+* Input : u32 timer_type
+* void* data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_mem_srv_restore_timeout (u32 timer_type, void *data)
+{
+ u32 max_count = 0;
+
+ g_mem_cfg.p_restore_timer = NULL;
+ if (TRUE == NSFW_SRV_STATE_SUSPEND)
+ {
+ NSFW_SRV_STATE_SUSPEND = FALSE;
+ (void) nsfw_ps_iterator (mem_ps_exiting_resend, &max_count);
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_srv_ctrl_proc
+* Description : service control message process
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+mem_srv_ctrl_proc (nsfw_mgr_msg * msg)
+{
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("msg nul");
+ return FALSE;
+ }
+
+ nsfw_srv_ctrl_msg *ctrl_msg = GET_USER_MSG (nsfw_srv_ctrl_msg, msg);
+ nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg);
+ if (NULL == rsp_msg)
+ {
+ NSFW_LOGERR ("alloc rsp msg failed]msg=%p", msg);
+ return FALSE;
+ }
+ nsfw_srv_ctrl_msg *ctrl_rsp_msg = GET_USER_MSG (nsfw_srv_ctrl_msg, rsp_msg);
+ NSFW_LOGINF ("get srv ctrl state] state=%d", ctrl_msg->srv_state);
+
+ ctrl_rsp_msg->rsp_code = NSFW_MGR_SUCESS;
+
+ (void) nsfw_mgr_send_msg (rsp_msg);
+ nsfw_mgr_msg_free (rsp_msg);
+
+ if (NSFW_SRV_CTRL_RESUME == ctrl_msg->srv_state)
+ {
+ if (TRUE == NSFW_SRV_STATE_SUSPEND)
+ {
+ NSFW_SRV_STATE_SUSPEND = FALSE;
+ }
+ u32 max_count = 0;
+ (void) nsfw_ps_iterator (mem_ps_exiting_resend, &max_count);
+ if (NULL != g_mem_cfg.p_restore_timer)
+ {
+ nsfw_timer_rmv_timer ((nsfw_timer_info *)
+ g_mem_cfg.p_restore_timer);
+ g_mem_cfg.p_restore_timer = NULL;
+ }
+ }
+ else
+ {
+ NSFW_SRV_STATE_SUSPEND = TRUE;
+ struct timespec time_left = { NSFW_SRV_RESTORE_TVALUE, 0 };
+ g_mem_cfg.p_restore_timer =
+ (void *) nsfw_timer_reg_timer (0, NULL,
+ nsfw_mem_srv_restore_timeout,
+ time_left);
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_mem_module_init
+* Description : module init
+* Input : void* param
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_mem_module_init (void *param)
+{
+ u32 proc_type = (u32) ((long long) param);
+ NSFW_LOGINF ("ps_mem module init]type=%u", proc_type);
+ switch (proc_type)
+ {
+ case NSFW_PROC_MAIN:
+ (void) nsfw_ps_reg_global_fun (NSFW_PROC_APP, NSFW_PS_EXITING,
+ mem_ps_exiting, NULL);
+ (void) nsfw_mgr_reg_msg_fun (MGR_MSG_MEM_ALLOC_REQ, mem_alloc_req_proc);
+ (void) NSFW_REG_SOFT_INT (NSFW_SRV_RESTORE_TIMER,
+ NSFW_SRV_RESTORE_TVALUE, 1, 0xFFFF);
+ (void) NSFW_REG_SOFT_INT (NSFW_APP_RESEND_TIMER,
+ NSFW_PS_MEM_RESEND_TVLAUE, 1, 0xFFFF);
+ (void) NSFW_REG_SOFT_INT (NSFW_APP_SEND_PER_TIME,
+ NSFW_PS_SEND_PER_TIME, 1, 0xFFFF);
+ break;
+ default:
+ if (proc_type < NSFW_PROC_MAX)
+ {
+ return 0;
+ }
+ return -1;
+ }
+
+ g_mem_cfg.srv_restore_tvalue = NSFW_SRV_RESTORE_TVALUE_DEF;
+ g_mem_cfg.ps_exit_resend_tvalue = NSFW_PS_MEM_RESEND_TVLAUE_DEF;
+ g_mem_cfg.ps_send_per_time = NSFW_PS_SEND_PER_TIME_DEF;
+
+ return 0;
+}
+
+/* *INDENT-OFF* */
+NSFW_MODULE_NAME (NSFW_PS_MEM_MODULE)
+NSFW_MODULE_PRIORITY (10)
+NSFW_MODULE_DEPENDS (NSFW_PS_MODULE)
+NSFW_MODULE_INIT (nsfw_ps_mem_module_init)
+/* *INDENT-ON* */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/src/framework/ipc/ps/nsfw_ps_mem_module.h b/src/framework/ipc/ps/nsfw_ps_mem_module.h
new file mode 100644
index 0000000..6b2b3c9
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_ps_mem_module.h
@@ -0,0 +1,87 @@
+/*
+*
+* 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.
+*/
+
+#ifndef _NSFW_PS_MEM_MODULE_H
+#define _NSFW_PS_MEM_MODULE_H
+
+#include "list.h"
+#include "pidinfo.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#define MEMZONE_MAX_NAME 32
+#define NS_MAX_FORK_NUM 32
+#define NSFW_PS_MEM_MAX_FILTER 4
+
+#define NSFW_SRV_RESTORE_TVALUE_DEF 120
+#define NSFW_SRV_RESTORE_TVALUE g_mem_cfg.srv_restore_tvalue
+#define NSFW_SRV_STATE_SUSPEND g_mem_cfg.srv_suspend
+
+#define NSFW_PS_MEM_RESEND_TIMER 1
+#define NSFW_PS_MEM_RESEND_TVLAUE_DEF 2
+#define NSFW_PS_SEND_PER_TIME_DEF 150
+#define NSFW_PS_SEND_PER_TIME (g_mem_cfg.ps_send_per_time)
+#define NSFW_PS_MEM_RESEND_TVLAUE (g_mem_cfg.ps_exit_resend_tvalue)
+
+typedef struct _ns_mem_mng_init_cfg
+{
+ u16 srv_restore_tvalue;
+ u16 ps_exit_resend_tvalue;
+ u16 ps_send_per_time;
+ u16 srv_suspend;
+ void *p_restore_timer;
+} ns_mem_mng_init_cfg;
+
+/*mem alloc by msg begin*/
+typedef struct
+{
+ nsfw_mem_name stname;
+ u16 ustype;
+} nsfw_mem_type_info;
+
+#define NSFW_MEM_CALL_ARG_BUF 256
+#define MEM_GET_CALLARGV(_dst_member,_src_member, _dst_type,_srctype,_dst_buf, _src_buf) \
+ ((_dst_type*)(void*)_dst_buf)->_dst_member = ((_srctype*)(void*)_src_buf)->_src_member
+
+typedef void *(*nsfw_ps_mem_create_fun) (void *memstr);
+typedef u8 (*nsfw_ps_mem_msg_to_memstr) (u16 msg_type, char *msg_body,
+ char *memstr_buf, i32 buf_len);
+
+typedef struct __nsfw_ps_mem_item_cfg
+{
+ u16 usmsg_type;
+ u16 item_size;
+ u16 mem_type;
+ nsfw_ps_mem_create_fun create_fun;
+ nsfw_ps_mem_msg_to_memstr change_fun;
+} nsfw_ps_mem_item_cfg;
+
+void *mem_item_free (void *pdata);
+void *mem_item_lookup (void *pdata);
+u8 mem_item_get_callargv (u16 msg_type, char *msg_body, char *memstr_buf,
+ i32 buf_len);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#endif /* _NSFW_PS_MEM_MODULE_H */
diff --git a/src/framework/ipc/ps/nsfw_ps_module.c b/src/framework/ipc/ps/nsfw_ps_module.c
new file mode 100644
index 0000000..e532c31
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_ps_module.c
@@ -0,0 +1,1725 @@
+/*
+*
+* 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 <stdlib.h>
+#include "types.h"
+#include "nstack_securec.h"
+#include "nsfw_init.h"
+
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_ps_api.h"
+#include "nsfw_ps_module.h"
+#include "nsfw_mem_api.h"
+#include "nstack_log.h"
+#include "nsfw_base_linux_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "nsfw_maintain_api.h"
+
+#include <errno.h>
+#include <sys/un.h>
+#include <stddef.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+
+#include <linux/cn_proc.h>
+#include <linux/connector.h>
+#include <linux/netlink.h>
+#include <dirent.h>
+#include <fnmatch.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+nsfw_ps_init_cfg g_ps_cfg;
+
+nsfw_pid_item *g_ps_info = NULL;
+
+nsfw_pid_item *g_master_ps_info = NULL;
+
+struct list_head g_ps_runing_list;
+nsfw_ps_callback g_ps_init_callback[NSFW_PROC_MAX][NSFW_PS_MAX_CALLBACK];
+nsfw_ps_info g_main_ps_info;
+
+void *g_ps_chk_timer = NULL;
+
+/*****************************************************************************
+* Prototype : nsfw_ps_reg_fun
+* Description : reg the callback fun when process state change
+* Input : nsfw_ps_info *pps_info
+* u8 ps_state
+* nsfw_ps_proc_fun fun
+* void* argv
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_reg_fun (nsfw_ps_info * pps_info, u8 ps_state,
+ nsfw_ps_proc_fun fun, void *argv)
+{
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("reg pps_info nul]state=%d,fun=%p", ps_state, fun);
+ return FALSE;
+ }
+
+ u32 i;
+ for (i = 0; i < NSFW_PS_MAX_CALLBACK; i++)
+ {
+ if (NULL == pps_info->callback[i].fun)
+ {
+ pps_info->callback[i].fun = fun;
+ pps_info->callback[i].argv = argv;
+ pps_info->callback[i].state = ps_state;
+ NSFW_LOGDBG
+ ("reg fun suc]ps_info=%p,state=%d,fun=%p,argv=%p,i=%d",
+ pps_info, ps_state, fun, argv, i);
+ return TRUE;
+ }
+ }
+
+ NSFW_LOGERR ("reg fun failed]ps_info=%p,state=%d,fun=%p,argv=%p,i=%d",
+ pps_info, ps_state, fun, argv, i);
+ return FALSE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_reg_global_fun
+* Description : reg the callback function of the specify proc_type state
+ change
+* Input : u8 proc_type
+* u8 ps_state
+* nsfw_ps_proc_fun fun
+* void* argv
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_reg_global_fun (u8 proc_type, u8 ps_state, nsfw_ps_proc_fun fun,
+ void *argv)
+{
+ if (NSFW_PROC_MAX <= proc_type)
+ {
+ NSFW_LOGERR ("proc_type err]state=%u,fun=%p,type=%u", ps_state, fun,
+ proc_type);
+ return FALSE;
+ }
+
+ nsfw_ps_callback *cb_fun = g_ps_init_callback[proc_type];
+ u32 i;
+ for (i = 0; i < NSFW_PS_MAX_CALLBACK; i++)
+ {
+ if (NULL == cb_fun[i].fun)
+ {
+ cb_fun[i].fun = fun;
+ cb_fun[i].argv = argv;
+ cb_fun[i].state = ps_state;
+ NSFW_LOGINF ("reg fun suc]type=%u,state=%u,fun=%p,argv=%p,i=%u",
+ proc_type, ps_state, fun, argv, i);
+ return TRUE;
+ }
+ }
+
+ NSFW_LOGERR ("reg fun ful failed]type=%u,state=%u,fun=%p,argv=%p,i=%u",
+ proc_type, ps_state, fun, argv, i);
+ return FALSE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_exit
+* Description : when recvive the process exit finish message ,change
+ to exit state
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_exit (nsfw_mgr_msg * msg)
+{
+ nsfw_ps_info *pps_info;
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("msg nul!");
+ return FALSE;
+ }
+
+ nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, msg);
+ pps_info = nsfw_ps_info_get (ps_msg->host_pid);
+ NSFW_LOGINF ("recv ps exit]host_pid=%d,ps_info=%p", ps_msg->host_pid,
+ pps_info);
+
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("error msg pps_info nul]host_pid=%d", ps_msg->host_pid);
+ return true;
+ }
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXIT);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_info_fork_alloc
+* Description : alloc fork ps_info
+* Input : u32 parent_pid
+* u32 child_pid
+* Output : None
+* Return Value : nsfw_ps_info*
+* Calls :
+* Called By :
+*****************************************************************************/
+nsfw_ps_info *
+nsfw_ps_info_fork_alloc (u32 parent_pid, u32 child_pid)
+{
+ nsfw_ps_info *pps_info = NULL;
+ nsfw_ps_info *pps_info_parent = NULL;
+ pps_info_parent = nsfw_ps_info_get (parent_pid);
+ if (NULL == pps_info_parent)
+ {
+ NSFW_LOGERR ("pps_info_parent nul");
+ return NULL;
+ }
+
+ pps_info = nsfw_ps_info_get (child_pid);
+ if (NULL == pps_info)
+ {
+ pps_info = nsfw_ps_info_alloc (child_pid, pps_info_parent->proc_type);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR
+ ("alloc ps_info failed!]ps_info=%p,host_pid=%u,child_pid=%u",
+ pps_info_parent, pps_info_parent->host_pid, child_pid);
+ return NULL;
+ }
+ }
+ else
+ {
+ NSFW_LOGWAR
+ ("fork alloc mem before!]ps_info=%p,host_pid=%u,child_pid=%u",
+ pps_info_parent, pps_info_parent->host_pid, child_pid);
+ }
+
+ NSFW_LOGWAR ("ps_info fork]ps_info=%p,host_pid=%u,child_pid=%u",
+ pps_info_parent, pps_info_parent->host_pid, child_pid);
+ pps_info->parent_pid = parent_pid;
+ if (EOK !=
+ MEMCPY_S (pps_info->callback, sizeof (pps_info->callback),
+ pps_info_parent->callback,
+ sizeof (pps_info_parent->callback)))
+ {
+ nsfw_ps_info_free (pps_info);
+ NSFW_LOGERR ("ps_info set_failed");
+ return NULL;
+ }
+
+ if (EOK !=
+ MEMCPY_S (pps_info->value, sizeof (pps_info->value),
+ pps_info_parent->value, sizeof (pps_info_parent->value)))
+ {
+ nsfw_ps_info_free (pps_info);
+ NSFW_LOGERR ("ps_info cpy_failed");
+ return NULL;
+ }
+
+ return pps_info;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_info_alloc
+* Description : alloc ps_info
+* Input : u32 pid
+* u8 proc_type
+* Output : None
+* Return Value : nsfw_ps_info*
+* Calls :
+* Called By :
+*****************************************************************************/
+nsfw_ps_info *
+nsfw_ps_info_alloc (u32 pid, u8 proc_type)
+{
+ nsfw_ps_info *pps_info = NULL;
+ if (0 == nsfw_mem_ring_dequeue (g_ps_cfg.ps_info_pool, (void *) &pps_info))
+ {
+ NSFW_LOGERR ("alloc ps_info falied]pid=%u,type=%u", pid, proc_type);
+ return NULL;
+ }
+
+ if (NULL == pps_info)
+ {
+ if (NSFW_PROC_MAIN != proc_type || TRUE == g_main_ps_info.alloc_flag)
+ {
+ NSFW_LOGERR ("alloc ps_info nul]pid=%u,type=%u", pid, proc_type);
+ return NULL;
+ }
+ pps_info = &g_main_ps_info;
+ }
+
+ if (EOK !=
+ MEMSET_S (pps_info, sizeof (nsfw_ps_info), 0, sizeof (nsfw_ps_info)))
+ {
+ nsfw_ps_info_free (pps_info);
+ NSFW_LOGERR ("set failed");
+ return NULL;
+ }
+
+ pps_info->proc_type = proc_type;
+ pps_info->host_pid = pid;
+
+ if (proc_type < NSFW_PROC_MAX)
+ {
+ int retval;
+ retval =
+ MEMCPY_S (pps_info->callback, sizeof (pps_info->callback),
+ g_ps_init_callback[proc_type], sizeof (pps_info->callback));
+ if (EOK != retval)
+ {
+ NSFW_LOGERR ("Failed to MEMCPY_S]retval=%d", retval);
+ nsfw_ps_info_free (pps_info);
+ return NULL;
+ }
+ }
+ list_add_tail (&pps_info->node, &g_ps_runing_list);
+ pps_info->alloc_flag = TRUE;
+
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_RUNNING);
+ if (pid < NSFW_MAX_PID)
+ {
+ g_ps_info[pid].ps_info = pps_info;
+ g_ps_info[pid].proc_type = proc_type;
+ }
+
+ NSFW_LOGINF ("ps_info alloc]ps_info=%p,pid=%u,type=%u", pps_info, pid,
+ proc_type);
+ return pps_info;
+
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_info_get
+* Description : get ps_info by pid
+* Input : u32 pid
+* Output : None
+* Return Value : inline nsfw_ps_info*
+* Calls :
+* Called By :
+*****************************************************************************/
+inline nsfw_ps_info *
+nsfw_ps_info_get (u32 pid)
+{
+ if (pid < NSFW_MAX_PID)
+ {
+ return g_ps_info[pid].ps_info;
+ }
+
+ return NULL;
+}
+
+nsfw_ps_info *
+nsfw_share_ps_info_get (u32 pid)
+{
+ if (pid < NSFW_MAX_PID)
+ {
+ return g_master_ps_info[pid].ps_info;
+ }
+
+ return NULL;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_info_free
+* Description : free ps_info
+* Input : nsfw_ps_info *ps_info
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*****************************************************************************/
+void
+nsfw_ps_info_free (nsfw_ps_info * ps_info)
+{
+ if (NULL == ps_info)
+ {
+ NSFW_LOGERR ("ps_info nul");
+ return;
+ }
+
+ if (FALSE == ps_info->alloc_flag)
+ {
+ NSFW_LOGERR ("ps_info refree]ps_info=%p,pid=%u,state=%u", ps_info,
+ ps_info->host_pid, ps_info->state);
+ return;
+ }
+
+ if (NULL != ps_info->exit_timer_ptr)
+ {
+ nsfw_timer_rmv_timer ((nsfw_timer_info *) ps_info->exit_timer_ptr);
+ ps_info->exit_timer_ptr = NULL;
+ }
+
+ if (NULL != ps_info->resend_timer_ptr)
+ {
+ nsfw_timer_rmv_timer ((nsfw_timer_info *) ps_info->resend_timer_ptr);
+ ps_info->resend_timer_ptr = NULL;
+ }
+
+ if (NULL != ps_info->hbt_timer_ptr)
+ {
+ nsfw_timer_rmv_timer ((nsfw_timer_info *) ps_info->hbt_timer_ptr);
+ ps_info->hbt_timer_ptr = NULL;
+ }
+
+ list_del (&ps_info->node);
+
+ ps_info->alloc_flag = FALSE;
+
+ NSFW_LOGINF ("ps_info free]ps_info=%p,pid=%u,state=%u", ps_info,
+ ps_info->host_pid, ps_info->state);
+ if (ps_info != &g_main_ps_info)
+ {
+ if (0 == nsfw_mem_ring_enqueue (g_ps_cfg.ps_info_pool, ps_info))
+ {
+ NSFW_LOGERR ("ps_info free failed]ps_info=%p,pid=%u,state=%u",
+ ps_info, ps_info->host_pid, ps_info->state);
+ return;
+ }
+ }
+
+ if (ps_info->host_pid < NSFW_MAX_PID)
+ {
+ g_ps_info[ps_info->host_pid].proc_type = 0;
+ g_ps_info[ps_info->host_pid].ps_info = NULL;
+ }
+
+ return;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_exiting_timeout
+* Description : waiting for remove ps_info timeout
+* Input : u32 timer_type
+* void* data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_exiting_timeout (u32 timer_type, void *data)
+{
+ nsfw_ps_info *pps_info = (nsfw_ps_info *) data;
+ NSFW_LOGINF ("ps_info timerout]pps_info=%p,pid=%u", pps_info,
+ pps_info->host_pid);
+ if (NULL == pps_info)
+ {
+ return TRUE;
+ }
+
+ pps_info->exit_timer_ptr = NULL;
+
+ if (TRUE == g_hbt_switch)
+ {
+ NSFW_LOGINF ("hbt off");
+ struct timespec time_left = { NSFW_PS_WEXIT_TVLAUE, 0 };
+ pps_info->exit_timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_PS_WEXIT_TIMER, pps_info,
+ nsfw_ps_exiting_timeout, time_left);
+ return TRUE;
+ }
+
+ if (NSFW_PS_EXITING == pps_info->state)
+ {
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXIT);
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_exit_end_notify
+* Description : send exitting state process finished
+* Input : u32 pid
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_exit_end_notify (u32 pid)
+{
+ nsfw_mgr_msg *rsp_msg =
+ nsfw_mgr_msg_alloc (MGR_MSG_APP_EXIT_RSP, NSFW_PROC_MASTER);
+ if (NULL == rsp_msg)
+ {
+ NSFW_LOGERR ("alloc rsp msg failed]pid=%u", pid);
+ return FALSE;
+ }
+
+ nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, rsp_msg);
+ ps_msg->host_pid = pid;
+ (void) nsfw_mgr_send_msg (rsp_msg);
+ nsfw_mgr_msg_free (rsp_msg);
+ NSFW_LOGINF ("send exit rsp msg]pid=%u", pid);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_sw_ps_state
+* Description : switch ps_info state
+* Input : nsfw_ps_info* pps_info
+* u8 new_state
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_sw_ps_state (nsfw_ps_info * pps_info, u8 new_state)
+{
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("pps_info nul!");
+ return FALSE;
+ }
+
+ NSFW_LOGINF ("sw]ps_info=%p,pid=%u,type=%u,old_state=%u,newstate=%u",
+ pps_info, pps_info->host_pid, pps_info->proc_type,
+ pps_info->state, new_state);
+
+ i32 i, ret;
+ for (i = 0; i < NSFW_PS_MAX_CALLBACK; i++)
+ {
+ if (NULL == pps_info->callback[i].fun)
+ {
+ /* NULL should be the last fun */
+ break;
+ }
+
+ if (new_state == pps_info->callback[i].state)
+ {
+ ret =
+ pps_info->callback[i].fun (pps_info, pps_info->callback[i].argv);
+ NSFW_LOGINF ("callback fun]ps_info=%p,i=%d,fun=%p,argv=%p,ret=%d",
+ pps_info, i, pps_info->callback[i].fun,
+ pps_info->callback[i].argv, ret);
+ }
+ }
+
+ if (NSFW_PS_HBT_FAILED != new_state)
+ {
+ pps_info->state = new_state;
+ }
+
+ if (NSFW_PS_EXIT == new_state)
+ {
+ nsfw_ps_info_free (pps_info);
+ }
+
+ if (NSFW_PS_EXITING == new_state)
+ {
+ struct timespec time_left = { NSFW_PS_WEXIT_TVLAUE, 0 };
+ pps_info->exit_timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_PS_WEXIT_TIMER, pps_info,
+ nsfw_ps_exiting_timeout, time_left);
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_get_netlink_socket
+* Description : get netlink socket to kernel
+* Input : None
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*****************************************************************************/
+i32
+nsfw_ps_get_netlink_socket ()
+{
+ int rc;
+ int nl_sock;
+ int size, size_len;
+ struct sockaddr_nl sa_nl;
+
+ nl_sock = nsfw_base_socket (PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+ if (nl_sock == -1)
+ {
+ NSFW_LOGERR ("get netlink socket err]errno=%d", errno);
+ return -1;
+ }
+
+ rc = nsfw_set_close_on_exec (nl_sock);
+ if (rc == -1)
+ {
+ (void) nsfw_base_close (nl_sock);
+ NSFW_LOGERR ("set exec err]fd=%d, errno=%d", nl_sock, errno);
+ return -1;
+ }
+
+ sa_nl.nl_family = AF_NETLINK;
+ sa_nl.nl_groups = CN_IDX_PROC;
+ sa_nl.nl_pid = getpid ();
+
+ rc = nsfw_base_bind (nl_sock, (struct sockaddr *) &sa_nl, sizeof (sa_nl));
+ if (rc == -1)
+ {
+ (void) nsfw_base_close (nl_sock);
+ NSFW_LOGERR ("netlink bind err]netlink_fd=%d, errno=%d", nl_sock,
+ errno);
+ return -1;
+ }
+
+ struct __attribute__ ((aligned (NLMSG_ALIGNTO)))
+ {
+ struct nlmsghdr nl_hdr;
+ struct __attribute__ ((__packed__))
+ {
+ struct cn_msg cn_msg;
+ enum proc_cn_mcast_op cn_mcast;
+ };
+ } nlcn_msg;
+ if (EOK != MEMSET_S (&nlcn_msg, sizeof (nlcn_msg), 0, sizeof (nlcn_msg)))
+ {
+ (void) nsfw_base_close (nl_sock);
+ NSFW_LOGERR ("netlink set failed]netlink_fd=%d", nl_sock);
+ return -1;
+ }
+ nlcn_msg.nl_hdr.nlmsg_len = sizeof (nlcn_msg);
+ nlcn_msg.nl_hdr.nlmsg_pid = getpid ();
+ nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
+
+ nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
+ nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
+ nlcn_msg.cn_msg.len = sizeof (enum proc_cn_mcast_op);
+
+ nlcn_msg.cn_mcast = PROC_CN_MCAST_LISTEN;
+ rc = nsfw_base_send (nl_sock, &nlcn_msg, sizeof (nlcn_msg), 0);
+ if (rc == -1)
+ {
+ (void) nsfw_base_close (nl_sock);
+ NSFW_LOGERR ("netlink send err]netlink_fd=%d, errno=%d", nl_sock,
+ errno);
+ return -1;
+ }
+
+ NSFW_LOGINF ("netlink connect]netlink_fd=%d", nl_sock);
+ int val, len;
+ len = sizeof (val);
+ if (0 >
+ nsfw_base_getsockopt (nl_sock, SOL_SOCKET, SO_RCVBUF, &val,
+ (socklen_t *) & len))
+ {
+ NSFW_LOGERR ("get socket opt err!]error=%d", errno);
+ }
+ else
+ {
+ NSFW_LOGINF ("] SO_RCVBUF=0x%x", val);
+ }
+
+ size = MAX_NET_LINK_BUF;
+ size_len = sizeof (size);
+ if (0 >
+ nsfw_base_setsockopt (nl_sock, SOL_SOCKET, SO_RCVBUFFORCE,
+ (void *) &size, (socklen_t) size_len))
+ {
+ NSFW_LOGERR ("set socket opt err!]error=%d", errno);
+ }
+
+ size_len = sizeof (size);
+ if (0 >
+ nsfw_base_getsockopt (nl_sock, SOL_SOCKET, SO_RCVBUF, (void *) &size,
+ (socklen_t *) & size_len))
+ {
+ NSFW_LOGERR ("get socket opt err!]error=%d", errno);
+ }
+
+ NSFW_LOGINF ("] SO_RCVBUF=0x%x", size);
+ return nl_sock;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_change_fun
+* Description : proc change when receive event from kernel
+* Input : i32 epfd
+* i32 fd
+* u32 events
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_change_fun (i32 epfd, i32 fd, u32 events)
+{
+ i32 rc;
+ u32 host_pid;
+ nsfw_ps_info *pps_info = NULL;
+
+ struct __attribute__ ((aligned (NLMSG_ALIGNTO)))
+ {
+ struct nlmsghdr nl_hdr;
+ struct __attribute__ ((__packed__))
+ {
+ struct cn_msg cn_msg;
+ struct proc_event proc_ev;
+ };
+ } nlcn_msg;
+
+ if (!(events & EPOLLIN))
+ {
+ return TRUE;
+ }
+
+ while (1)
+ {
+ rc = nsfw_base_recv (fd, &nlcn_msg, sizeof (nlcn_msg), 0);
+ if (rc == 0)
+ {
+ NSFW_LOGWAR ("netlink recv 0]netlink_fd=%d,errno=%d", fd, errno);
+ break;
+ }
+ else if (rc == -1)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ break;
+ }
+ NSMON_LOGERR ("netlink recv]netlink_fd=%d,errno=%d", fd, errno);
+ if (errno == ENOBUFS)
+ {
+ struct timespec time_left = { NSFW_PS_FIRST_CHK_TVLAUE, 0 };
+ g_ps_chk_timer =
+ (void *) nsfw_timer_reg_timer (NSFW_PS_CHK_TIMER,
+ (void *) FALSE,
+ nsfw_ps_chk_timeout,
+ time_left);
+ }
+ break;
+ }
+
+ switch (nlcn_msg.proc_ev.what)
+ {
+ case PROC_EVENT_EXIT:
+ host_pid = nlcn_msg.proc_ev.event_data.exit.process_pid;
+ pps_info = nsfw_ps_info_get (host_pid);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGDBG ("pps info is null]host pid=%d", host_pid);
+ break;
+ }
+
+ if (NSFW_PS_EXITING == pps_info->state)
+ {
+ NSFW_LOGERR ("double pid info]ps_info=%p,pid=%d", pps_info,
+ host_pid);
+ break;
+ }
+
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXITING);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_start_netlink
+* Description : reg ps_module to epoll thread
+* Input : None
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+u8
+nsfw_ps_start_netlink ()
+{
+ i32 netlink_fd = nsfw_ps_get_netlink_socket ();
+ if (netlink_fd < 0)
+ {
+ NSFW_LOGERR ("get netlink failed!");
+ return FALSE;
+ }
+
+ NSFW_LOGINF ("start ps_info module!]netlink_fd=%d", netlink_fd);
+ (void) nsfw_mgr_reg_sock_fun (netlink_fd, nsfw_ps_change_fun);
+ (void) nsfw_mgr_reg_msg_fun (MGR_MSG_APP_EXIT_RSP, nsfw_ps_exit);
+ return TRUE;
+}
+
+/* for heartbeat check*/
+
+NSTACK_STATIC __thread i32 t_val_idx = 0;
+nsfw_thread_dogs g_thread_dogs[NSFW_MAX_THREAD_DOGS_COUNT];
+/*****************************************************************************
+* Prototype : nsfw_all_thread_chk
+* Description : get all thread check state
+* Input : None
+* Output : None
+* Return Value : i32
+* Calls :
+* Called By :
+*****************************************************************************/
+i32
+nsfw_all_thread_chk ()
+{
+ i32 count = -1;
+ u32 i;
+ for (i = 0; i < NSFW_MAX_THREAD_DOGS_COUNT; i++)
+ {
+ if (FALSE == g_thread_dogs[i].alloc_flag)
+ {
+ continue;
+ }
+
+ if (count < g_thread_dogs[i].count)
+ {
+ count = g_thread_dogs[i].count;
+ }
+
+ g_thread_dogs[i].count++;
+ }
+ return count;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_thread_chk_unreg
+* Description : cancel the thread check
+* Input : None
+* Output : None
+* Return Value : inline u8
+* Calls :
+* Called By :
+*****************************************************************************/
+inline u8
+nsfw_thread_chk_unreg ()
+{
+ if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT)
+ {
+ g_thread_dogs[t_val_idx].alloc_flag = FALSE;
+ g_thread_dogs[t_val_idx].count = 0;
+ g_thread_dogs[t_val_idx].thread_id = 0;
+ t_val_idx = 0;
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_thread_chk
+* Description : add the thread to check, and should be call in every
+ process cycle
+* Input : None
+* Output : None
+* Return Value : inline u8
+* Calls :
+* Called By :
+*****************************************************************************/
+inline u8
+nsfw_thread_chk ()
+{
+ u32 i;
+ if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT)
+ {
+ g_thread_dogs[t_val_idx].count = 0;
+ return TRUE;
+ }
+
+ for (i = 1; i < NSFW_MAX_THREAD_DOGS_COUNT; i++)
+ {
+ if ((FALSE == g_thread_dogs[i].alloc_flag)
+ && __sync_bool_compare_and_swap (&g_thread_dogs[i].alloc_flag,
+ FALSE, TRUE))
+ {
+ t_val_idx = i;
+ break;
+ }
+ }
+
+ if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT)
+ {
+ g_thread_dogs[t_val_idx].count = 0;
+ g_thread_dogs[t_val_idx].thread_id = syscall (SYS_gettid);
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************
+Parameters : None
+Return :
+Description :
+*****************************************************************/
+nsfw_thread_dogs *
+nsfw_thread_getDog ()
+{
+ u32 i;
+ nsfw_thread_dogs *retPtr = NULL;
+ if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT)
+ {
+ return &g_thread_dogs[t_val_idx];
+ }
+
+ for (i = 1; i < NSFW_MAX_THREAD_DOGS_COUNT; i++)
+ {
+ if ((FALSE == g_thread_dogs[i].alloc_flag)
+ && __sync_bool_compare_and_swap (&g_thread_dogs[i].alloc_flag,
+ FALSE, TRUE))
+ {
+ t_val_idx = i;
+ break;
+ }
+ }
+
+ if (t_val_idx > 0 && t_val_idx < NSFW_MAX_THREAD_DOGS_COUNT)
+ {
+ g_thread_dogs[t_val_idx].count = 0;
+ g_thread_dogs[t_val_idx].thread_id = syscall (SYS_gettid);
+ retPtr = &g_thread_dogs[t_val_idx];
+ }
+ return retPtr;
+}
+
+pthread_t g_all_thread[MAX_THREAD] = { 0 };
+
+u8
+nsfw_reg_trace_thread (pthread_t tid)
+{
+ int i;
+ for (i = 0; i < MAX_THREAD; i++)
+ {
+ if ((0 == g_all_thread[i])
+ && __sync_bool_compare_and_swap (&g_all_thread[i], 0, tid))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_check_dst_init
+* Description : send check msg check the dst process is listening
+* Input : u8 dst_proc_type
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_check_dst_init (u8 dst_proc_type)
+{
+ u8 ps_state = FALSE;
+ nsfw_mgr_msg *msg =
+ nsfw_mgr_msg_alloc (MGR_MSG_CHK_INIT_REQ, dst_proc_type);
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("alloc msg failed]dst_typ=%d", dst_proc_type);
+ return FALSE;
+ }
+
+ nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, msg);
+ ps_msg->ps_state = TRUE;
+
+ nsfw_mgr_msg *rsp_msg = nsfw_mgr_null_rspmsg_alloc ();
+ if (NULL == rsp_msg)
+ {
+ nsfw_mgr_msg_free (msg);
+ NSFW_LOGERR ("alloc rsp msg failed]dst_typ=%d", dst_proc_type);
+ return FALSE;
+ }
+
+ (void) nsfw_mgr_send_req_wait_rsp (msg, rsp_msg);
+
+ ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, rsp_msg);
+ ps_state = ps_msg->ps_state;
+
+ nsfw_mgr_msg_free (msg);
+ nsfw_mgr_msg_free (rsp_msg);
+ NSFW_LOGINF ("get peer state]dst_type=%d,state=%d", dst_proc_type,
+ ps_state);
+ return ps_state;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_send_hbt
+* Description : seng heart beat message to peer
+* Input : nsfw_ps_info* pps_info
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_send_hbt (nsfw_ps_info * pps_info)
+{
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("null ps_info!");
+ return FALSE;
+ }
+
+ nsfw_mgr_msg *req_msg =
+ nsfw_mgr_msg_alloc (MGR_MSG_CHK_HBT_REQ, pps_info->proc_type);
+ if (NULL == req_msg)
+ {
+ NSFW_LOGERR ("alloc req msg failed]pps_info=%p", pps_info);
+ return FALSE;
+ }
+
+ req_msg->dst_pid = pps_info->host_pid;
+ nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, req_msg);
+ ps_msg->ps_state = TRUE;
+ u8 ret = nsfw_mgr_send_msg (req_msg);
+ nsfw_mgr_msg_free (req_msg);
+ NSFW_LOGDBG ("send hbt msg]ret=%d,pps_info=%p,pid=%d,type=%d", ret,
+ pps_info, pps_info->host_pid, pps_info->proc_type);
+ return ret;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_recv_hbt
+* Description : recv heart beat message process
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_recv_hbt (nsfw_mgr_msg * msg)
+{
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("error msg nul!");
+ return FALSE;
+ }
+
+ nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg);
+ if (NULL == rsp_msg)
+ {
+ NSFW_LOGERR ("alloc rsp failed,drop msg!" MSGINFO, PRTMSG (msg));
+ return FALSE;
+ }
+
+ nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, rsp_msg);
+ ps_msg->ps_state = TRUE;
+ ps_msg->thread_chk_count = nsfw_all_thread_chk ();
+ (void) nsfw_mgr_send_msg (rsp_msg);
+ nsfw_mgr_msg_free (rsp_msg);
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_recv_hbt_rsp
+* Description : recv heart beat response message process
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_recv_hbt_rsp (nsfw_mgr_msg * msg)
+{
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("error msg nul!");
+ return FALSE;
+ }
+
+ nsfw_ps_chk_msg *ps_msg = GET_USER_MSG (nsfw_ps_chk_msg, msg);
+ if (TRUE != ps_msg->ps_state)
+ {
+ NSFW_LOGERR ("Heartbeat failed]pid=%u,type=%u", msg->src_pid,
+ msg->src_proc_type);
+ return FALSE;
+ }
+
+ nsfw_ps_info *pps_info = nsfw_ps_info_get (msg->src_pid);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("get ps_info failed]pid=%u,type=%u,count=%d",
+ msg->src_pid, msg->src_proc_type,
+ ps_msg->thread_chk_count);
+ return FALSE;
+ }
+
+ if (0 == ps_msg->thread_chk_count)
+ {
+ pps_info->hbt_failed_count = 0;
+ return TRUE;
+ }
+
+ if (pps_info->hbt_failed_count > (u32) ps_msg->thread_chk_count)
+ {
+ pps_info->hbt_failed_count = (u32) ps_msg->thread_chk_count;
+ }
+
+ NSFW_LOGERR ("Heartbeat failed]pid=%u,type=%u,count=%d,ps_count=%u",
+ msg->src_pid, msg->src_proc_type, ps_msg->thread_chk_count,
+ pps_info->hbt_failed_count);
+ return FALSE;
+}
+
+int
+nsfw_ps_reset_hbt (void *pps_info, void *argv)
+{
+ nsfw_ps_info *ps_info = pps_info;
+ if (NULL == ps_info)
+ {
+ NSFW_LOGERR ("ps_info nul!");
+ return FALSE;
+ }
+
+ if (NSFW_PROC_MAIN != ps_info->proc_type)
+ {
+ return FALSE;
+ }
+
+ ps_info->hbt_failed_count = *(u32 *) argv;
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_hbt_timeout
+* Description : heart beat time out
+* Input : u32 timer_type
+* void* data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_hbt_timeout (u32 timer_type, void *data)
+{
+ nsfw_ps_info *pps_info = (nsfw_ps_info *) data;
+
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("null ps_info!");
+ return FALSE;
+ }
+
+ if (NULL == pps_info->hbt_timer_ptr)
+ {
+ NSFW_LOGERR ("hbt has stop]pps_info=%p", pps_info);
+ pps_info->hbt_failed_count = 0;
+ return TRUE;
+ }
+
+ if (TRUE == g_hbt_switch)
+ {
+ struct timespec time_left = { NSFW_CHK_HBT_TVLAUE, 0 };
+ pps_info->hbt_timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_CHK_HBT_TIMER, data,
+ nsfw_ps_hbt_timeout, time_left);
+ return TRUE;
+ }
+
+ /* nic init may cost a few seconds, master will restart main if heartbeat timeout */
+ if (NSFW_SOFT_HBT_CHK_COUNT != NSFW_MAX_HBT_CHK_COUNT)
+ {
+ if (NSFW_SOFT_HBT_CHK_COUNT < NSFW_MAX_HBT_CHK_COUNT)
+ {
+ u32 new_hbt_count = 0;
+ (void) nsfw_ps_iterator (nsfw_ps_reset_hbt, &new_hbt_count);
+ }
+
+ NSFW_MAX_HBT_CHK_COUNT = NSFW_SOFT_HBT_CHK_COUNT;
+ }
+
+ if (NSFW_MAX_HBT_CHK_COUNT <= pps_info->hbt_failed_count)
+ {
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_HBT_FAILED);
+ /*reset counter */
+ pps_info->hbt_failed_count = 0;
+ }
+
+ if (TRUE != nsfw_ps_send_hbt (pps_info))
+ {
+ }
+
+ if (pps_info->hbt_failed_count > 0)
+ {
+ NSFW_LOGWAR ("Heartbeat failed]pid=%u,ps_count=%u, max_count=%d",
+ pps_info->host_pid, pps_info->hbt_failed_count,
+ NSFW_MAX_HBT_CHK_COUNT);
+ }
+
+ pps_info->hbt_failed_count++;
+ struct timespec time_left = { NSFW_CHK_HBT_TVLAUE, 0 };
+ pps_info->hbt_timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_CHK_HBT_TIMER, data,
+ nsfw_ps_hbt_timeout, time_left);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_hbt_start
+* Description : start ps_info heart beat
+* Input : nsfw_ps_info* pps_info
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_hbt_start (nsfw_ps_info * pps_info)
+{
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("null ps_info!");
+ return FALSE;
+ }
+
+ if (NULL != pps_info->hbt_timer_ptr)
+ {
+ NSFW_LOGERR ("hbt start before!]ps_info=%p,pid=%u,type=%u", pps_info,
+ pps_info->host_pid, pps_info->proc_type);
+ return FALSE;
+ }
+
+ struct timespec time_left = { NSFW_CHK_HBT_TVLAUE, 0 };
+ pps_info->hbt_timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_CHK_HBT_TIMER, (void *) pps_info,
+ nsfw_ps_hbt_timeout, time_left);
+ NSFW_LOGINF ("hbt start!]ps_info=%p,pid=%u,type=%u", pps_info,
+ pps_info->host_pid, pps_info->proc_type);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_hbt_stop
+* Description : stop ps_info heart beat
+* Input : nsfw_ps_info* pps_info
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_ps_hbt_stop (nsfw_ps_info * pps_info)
+{
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("null ps_info!");
+ return FALSE;
+ }
+
+ if (NULL != pps_info->hbt_timer_ptr)
+ {
+ nsfw_timer_rmv_timer ((nsfw_timer_info *) pps_info->hbt_timer_ptr);
+ pps_info->hbt_timer_ptr = NULL;
+ }
+
+ NSFW_LOGINF ("hbt stop!]ps_info=%p,pid=%d,type=%d", pps_info,
+ pps_info->host_pid, pps_info->proc_type);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_iterator
+* Description : get all ps_info process by fun
+* Input : nsfw_ps_proc_fun fun
+* void* argv
+* Output : None
+* Return Value : u32
+* Calls :
+* Called By :
+*****************************************************************************/
+u32
+nsfw_ps_iterator (nsfw_ps_proc_fun fun, void *argv)
+{
+ u32 count = 0;
+ nsfw_ps_info *pps_info = NULL;
+ struct list_head *tNode;
+
+ if (NULL == fun)
+ {
+ NSFW_LOGERR ("fun null!");
+ return count;
+ }
+
+ LINT_LIST ()list_for_each_entry (pps_info, tNode, (&g_ps_runing_list), node)
+ {
+ (void) fun (pps_info, argv);
+ count++;
+ }
+
+ NSFW_LOGINF ("proc pid]count=%u", count);
+ return count;
+}
+
+int
+filter (const struct dirent *dir)
+{
+ return !fnmatch ("[1-9]*", dir->d_name, 0);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_realloc_pid
+* Description : realloc pid
+* Input : u32 pid
+* Output : None
+* Return Value : inline nsfw_ps_info*
+* Calls :
+* Called By :
+*****************************************************************************/
+inline nsfw_ps_info *
+nsfw_ps_realloc_pid (u32 pid, u8 realloc_flg)
+{
+ nsfw_ps_info *pps_info = NULL;
+ if (pid >= NSFW_MAX_PID)
+ {
+ return NULL;
+ }
+
+ if (g_ps_info[pid].ps_info == NULL)
+ {
+ return NULL;
+ }
+
+ if (TRUE == realloc_flg)
+ {
+ pps_info = nsfw_ps_info_alloc (pid, g_ps_info[pid].proc_type);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("alloc ps_info failed!]pid=%u,type=%u", pid,
+ g_ps_info[pid].proc_type);
+ return NULL;
+ }
+ }
+ else
+ {
+ pps_info = g_ps_info[pid].ps_info;
+ }
+
+ pps_info->rechk_flg = TRUE;
+ return pps_info;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_reload_pid
+* Description : reload pid
+* Input : None
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*****************************************************************************/
+void
+nsfw_ps_reload_pid ()
+{
+ struct dirent **namelist;
+ i32 n;
+ u32 host_pid;
+ nsfw_ps_info *pps_info = NULL;
+
+ n = scandir ("/proc", &namelist, filter, 0);
+ if (n < 0)
+ {
+ NSFW_LOGERR ("buf null");
+ }
+ else
+ {
+ while (n--)
+ {
+ host_pid = strtol (namelist[n]->d_name, NULL, 10);
+ pps_info = nsfw_ps_info_get (host_pid);
+ if (NULL != pps_info)
+ {
+ pps_info->rechk_flg = FALSE;
+ }
+ free (namelist[n]);
+ }
+ free (namelist);
+ }
+ return;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_realloc_all_pid
+* Description : realloc all pid
+* Input : u32 *main_pid
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*****************************************************************************/
+void
+nsfw_ps_realloc_all_pid (u32 * main_pid, u8 realloc_flg)
+{
+ u32 i;
+ nsfw_ps_info *pps_info = NULL;
+ for (i = 0; i < NSFW_MAX_PID; i++)
+ {
+ pps_info = nsfw_ps_realloc_pid (i, realloc_flg);
+ if (NULL != main_pid)
+ {
+ if (NULL != pps_info && NSFW_PROC_MAIN == pps_info->proc_type)
+ {
+ (*main_pid) = i;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_chk_exit_timeout
+* Description : chk ps info
+* Input : u32 timer_type
+* void* data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_chk_exit_timeout (u32 timer_type, void *data)
+{
+ u32 i;
+ nsfw_ps_info *pps_info = NULL;
+ u32 pid = (u64) data;
+
+ /*main pid exit first */
+ if (NULL != data)
+ {
+ pps_info = nsfw_ps_info_get (pid);
+ if (NULL != pps_info && TRUE == pps_info->rechk_flg)
+ {
+ if (NSFW_PS_EXITING != pps_info->state)
+ {
+ NSFW_LOGWAR ("rechk pid exit]ps_info=%p,pid=%u", pps_info,
+ pps_info->host_pid);
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXITING);
+ pps_info->rechk_flg = FALSE;
+ }
+ }
+ }
+
+ for (i = 0; i < NSFW_MAX_PID; i++)
+ {
+ pps_info = nsfw_ps_info_get (i);
+ if (NULL != pps_info && TRUE == pps_info->rechk_flg)
+ {
+ if (NSFW_PS_EXITING == pps_info->state)
+ {
+ NSFW_LOGWAR ("double pid info]ps_info=%p,pid=%u", pps_info,
+ pps_info->host_pid);
+ continue;
+ }
+
+ NSFW_LOGWAR ("rechk pid exit]ps_info=%p,pid=%u", pps_info,
+ pps_info->host_pid);
+ (void) nsfw_sw_ps_state (pps_info, NSFW_PS_EXITING);
+ pps_info->rechk_flg = FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_chk_timeout
+* Description : load all running pid
+* Input : u32 timer_type
+* void* data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+****************************************************************************/
+int
+nsfw_ps_chk_timeout (u32 timer_type, void *data)
+{
+ u32 main_pid = 0;
+ u8 realloc_flg = (u8) (u64) data;
+
+ nsfw_ps_realloc_all_pid (&main_pid, realloc_flg);
+ nsfw_ps_reload_pid ();
+
+ struct timespec time_left = { NSFW_PS_CHK_EXIT_TVLAUE, 0 };
+ g_ps_chk_timer =
+ (void *) nsfw_timer_reg_timer (NSFW_PS_CHK_EXIT_TVLAUE,
+ (void *) (u64) main_pid,
+ nsfw_ps_chk_exit_timeout, time_left);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_rechk_pid_exit
+* Description : rechck pid exit
+* Input : nsfw_ps_proc_fun fun
+* void* argv
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_rechk_pid_exit (nsfw_ps_pid_fun fun, void *argv)
+{
+ u32 ulI = 0;
+ if (NULL == fun)
+ {
+ NSFW_LOGERR ("input err! fun null");
+ return -1;
+ }
+
+ u8 *ps_pid = malloc (NSFW_MAX_PID);
+ if (NULL == ps_pid)
+ {
+ NSFW_LOGERR ("malloc failed");
+ return -1;
+ }
+
+ int retval = MEMSET_S (ps_pid, NSFW_MAX_PID, 0, NSFW_MAX_PID);
+ if (EOK != retval)
+ {
+ NSFW_LOGERR ("MEMSET_S failed]retval=%d", retval);
+ free (ps_pid);
+ return -1;
+ }
+
+ struct dirent **namelist;
+ i32 n;
+ u32 host_pid;
+ n = scandir ("/proc", &namelist, filter, 0);
+ if (n < 0)
+ {
+ NSFW_LOGERR ("buf null");
+ free (ps_pid);
+ return -1;
+ }
+
+ while (n--)
+ {
+ host_pid = strtol (namelist[n]->d_name, NULL, 10);
+ if (host_pid < NSFW_MAX_PID)
+ {
+ ps_pid[ulI] = TRUE;
+ }
+ free (namelist[n]);
+ }
+ free (namelist);
+
+ int count = 0;
+ for (ulI = 0; ulI < NSFW_MAX_PID; ulI++)
+ {
+ if ((NULL != g_master_ps_info[ulI].ps_info) && (FALSE == ps_pid[ulI]))
+ {
+ (void) fun (ulI, g_master_ps_info[ulI].proc_type, argv);
+ NSFW_LOGWAR ("rechk pid exit]pid=%d,type=%d", ulI,
+ g_master_ps_info[ulI].proc_type);
+ count++;
+ continue;
+ }
+ }
+
+ free (ps_pid);
+ return count;
+}
+
+void
+nsfw_ps_cfg_set_chk_count (u16 count)
+{
+ g_ps_cfg.ps_chk_hbt_count = count;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_ps_module_init
+* Description : ps_module init
+* Input : void* param
+* Output : None
+* Return Value : static int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_ps_module_init (void *param)
+{
+ u32 proc_type = (u32) ((long long) param);
+ nsfw_ps_init_cfg *ps_cfg = &g_ps_cfg;
+ int retval;
+ nsfw_pid_item *pid_info = NULL;
+ NSFW_LOGINF ("ps module init]type=%u", proc_type);
+
+ ps_cfg->ps_chk_hbt_count = NSFW_MAX_HBT_CHK_COUNT_DEF;
+ ps_cfg->ps_chk_hbt_tvalue = NSFW_CHK_HBT_TVLAUE_DEF;
+ ps_cfg->ps_chk_hbt_soft_count = ps_cfg->ps_chk_hbt_count;
+
+ nsfw_mem_zone pzoneinfo;
+ pzoneinfo.isocket_id = NSFW_SOCKET_ANY;
+ pzoneinfo.stname.entype = NSFW_SHMEM;
+ pzoneinfo.lenth = sizeof (nsfw_pid_item) * NSFW_MAX_PID;
+ if (-1 ==
+ SPRINTF_S (pzoneinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ "MAS_PS_INFO"))
+ {
+ NSFW_LOGERR ("SPRINTF_S failed]");
+ return -1;
+ }
+
+ switch (proc_type)
+ {
+ case NSFW_PROC_MASTER:
+ {
+ (void) nsfw_mgr_reg_msg_fun (MGR_MSG_CHK_HBT_RSP,
+ nsfw_ps_recv_hbt_rsp);
+ (void) NSFW_REG_SOFT_INT (NSFW_HBT_TIMER, NSFW_CHK_HBT_TVLAUE, 1,
+ 0xFFFF);
+ (void) NSFW_REG_SOFT_INT (NSFW_HBT_COUNT_PARAM,
+ NSFW_SOFT_HBT_CHK_COUNT, 1, 0xFFFF);
+ (void) NSFW_REG_SOFT_INT (NSFW_APP_EXIT_TIMER, NSFW_PS_WEXIT_TVLAUE,
+ 1, 0xFFFF);
+
+ pid_info = nsfw_mem_zone_lookup (&pzoneinfo.stname);
+ if (NULL == pid_info)
+ {
+ pid_info = nsfw_mem_zone_create (&pzoneinfo);
+ if (NULL == pid_info)
+ {
+ NSFW_LOGERR ("alloc rec nul!");
+ return -1;
+ }
+
+ retval =
+ MEMSET_S (pid_info, (sizeof (nsfw_pid_item) * NSFW_MAX_PID),
+ 0, (sizeof (nsfw_pid_item) * NSFW_MAX_PID));
+ if (EOK != retval)
+ {
+ NSFW_LOGERR ("MEMSET_S failed]retval=%d.\n", retval);
+ return -1;
+ }
+ }
+
+ MEM_STAT (NSFW_PS_MODULE, pzoneinfo.stname.aname, NSFW_SHMEM,
+ pzoneinfo.lenth);
+ g_ps_info = pid_info;
+ break;
+ }
+ case NSFW_PROC_MAIN:
+ {
+ pid_info = malloc (sizeof (nsfw_pid_item) * NSFW_MAX_PID);
+ if (NULL == pid_info)
+ {
+ NSFW_LOGERR ("malloc mem failed!");
+ return -1;
+ }
+
+ retval =
+ MEMSET_S (pid_info, (sizeof (nsfw_pid_item) * NSFW_MAX_PID), 0,
+ (sizeof (nsfw_pid_item) * NSFW_MAX_PID));
+ if (EOK != retval)
+ {
+ NSFW_LOGERR ("MEMSET_S failed]retval=%d.\n", retval);
+ free (pid_info);
+ return -1;
+ }
+
+ g_ps_info = pid_info;
+
+ pzoneinfo.stname.enowner = NSFW_PROC_MAIN;
+ pid_info = nsfw_mem_zone_create (&pzoneinfo);
+ if (NULL == pid_info)
+ {
+ NSFW_LOGERR ("create pid_info failed!");
+ return -1;
+ }
+
+ g_master_ps_info = pid_info;
+ break;
+ }
+ default:
+ return 0;
+ }
+
+ ps_cfg->ps_info_size = NSFW_PS_INFO_MAX_COUNT;
+ ps_cfg->ps_waite_exit_tvalue = NSFW_PS_WEXIT_TVLAUE_DEF;
+ ps_cfg->net_link_buf = MAX_NET_LINK_BUF_DEF;
+
+ INIT_LIST_HEAD (&(g_ps_runing_list));
+
+ nsfw_mem_sppool pmpinfo;
+ pmpinfo.enmptype = NSFW_MRING_MPMC;
+ pmpinfo.usnum = ps_cfg->ps_info_size;
+ pmpinfo.useltsize = sizeof (nsfw_ps_info);
+ pmpinfo.isocket_id = NSFW_SOCKET_ANY;
+ pmpinfo.stname.entype = NSFW_NSHMEM;
+ if (-1 ==
+ SPRINTF_S (pmpinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ "MAS_PS_INFOPOOL"))
+ {
+ NSFW_LOGERR ("SPRINTF_S failed]");
+ return -1;
+ }
+
+ ps_cfg->ps_info_pool = nsfw_mem_sp_create (&pmpinfo);
+
+ if (!ps_cfg->ps_info_pool)
+ {
+ NSFW_LOGERR ("alloc ps info pool_err");
+ return -1;
+ }
+
+ MEM_STAT (NSFW_PS_MODULE, pmpinfo.stname.aname, NSFW_NSHMEM,
+ nsfw_mem_get_len (ps_cfg->ps_info_pool, NSFW_MEM_SPOOL));
+
+ if (NSFW_PROC_MASTER != proc_type)
+ {
+ return 0;
+ }
+
+ struct timespec time_left = { NSFW_PS_FIRST_CHK_TVLAUE, 0 };
+ g_ps_chk_timer =
+ (void *) nsfw_timer_reg_timer (NSFW_PS_CHK_TIMER, (void *) TRUE,
+ nsfw_ps_chk_timeout, time_left);
+
+ if (TRUE != nsfw_ps_start_netlink ())
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/* *INDENT-OFF* */
+NSFW_MODULE_NAME (NSFW_PS_MODULE)
+NSFW_MODULE_PRIORITY (10)
+NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_TIMER_MODULE)
+NSFW_MODULE_INIT (nsfw_ps_module_init)
+/* *INDENT-ON* */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/src/framework/ipc/ps/nsfw_ps_module.h b/src/framework/ipc/ps/nsfw_ps_module.h
new file mode 100644
index 0000000..b754cea
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_ps_module.h
@@ -0,0 +1,99 @@
+/*
+*
+* 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.
+*/
+
+#ifndef _NSFW_PS_MODULE_H
+#define _NSFW_PS_MODULE_H
+
+#include "nsfw_ps_api.h"
+#include "nsfw_mem_api.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+/*==============================================*
+ * constants or macros define *
+ *----------------------------------------------*/
+
+#define NSFW_MAX_PID 65535
+COMPAT_PROTECT (NSFW_MAX_PID, 65535);
+
+#define NSFW_PS_INFO_MAX_COUNT 4095
+#define MAX_NET_LINK_BUF_DEF 0x34000*32
+
+#define NSFW_PS_WEXIT_TIMER 1
+#define NSFW_PS_WEXIT_TVLAUE_DEF 180
+
+#define NSFW_PS_WEXIT_TVLAUE (g_ps_cfg.ps_waite_exit_tvalue)
+#define MAX_NET_LINK_BUF (g_ps_cfg.net_link_buf)
+
+typedef struct _nsfw_ps_init_cfg
+{
+ u32 ps_info_size;
+ u32 net_link_buf;
+
+ u16 ps_waite_exit_tvalue;
+ u16 ps_chk_hbt_count;
+ u16 ps_chk_hbt_soft_count;
+ u16 ps_chk_hbt_tvalue;
+
+ mring_handle ps_info_pool;
+} nsfw_ps_init_cfg;
+
+#define NSFW_PS_CHK_TIMER 1
+#define NSFW_PS_FIRST_CHK_TVLAUE 1
+#define NSFW_PS_CHK_EXIT_TVLAUE 1
+
+typedef struct _nsfw_pid_item
+{
+ u8 proc_type;
+ u8 u8_reserve;
+ u16 u16_reserve;
+ u32 u32_reserve;
+ nsfw_ps_info *ps_info;
+} nsfw_pid_item;
+
+int nsfw_ps_change_fun (i32 epfd, i32 socket, u32 events);
+u8 nsfw_sw_ps_state (nsfw_ps_info * pps_info, u8 new_state);
+
+/* for heartbeat checking*/
+#define NSFW_MAX_THREAD_DOGS_COUNT 8
+#define NSFW_CHK_HBT_TIMER 1
+#define NSFW_MAX_HBT_PROC_FUN 4
+
+#define NSFW_CHK_HBT_TVLAUE_DEF 1
+
+#define NSFW_MAX_HBT_CHK_COUNT (g_ps_cfg.ps_chk_hbt_count)
+#define NSFW_SOFT_HBT_CHK_COUNT (g_ps_cfg.ps_chk_hbt_soft_count)
+#define NSFW_CHK_HBT_TVLAUE (g_ps_cfg.ps_chk_hbt_tvalue)
+
+typedef struct _nsfw_ps_chk_msg
+{
+ u32 ps_state;
+ i32 thread_chk_count;
+} nsfw_ps_chk_msg;
+
+int nsfw_ps_chk_timeout (u32 timer_type, void *data);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#endif /* _NSFW_PS_MODULE_H */
diff --git a/src/framework/ipc/ps/nsfw_recycle_module.c b/src/framework/ipc/ps/nsfw_recycle_module.c
new file mode 100644
index 0000000..bb3844f
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_recycle_module.c
@@ -0,0 +1,666 @@
+/*
+*
+* 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 <stdlib.h>
+#include "types.h"
+#include "nstack_securec.h"
+#include "nsfw_init.h"
+
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_mem_api.h"
+#include "nsfw_ps_api.h"
+#include "nsfw_ps_mem_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "nsfw_recycle_module.h"
+#include "nsfw_maintain_api.h"
+#include "nstack_log.h"
+#include "common_mem_api.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+/* only work on nStackMain*/
+nsfw_recycle_cfg g_rec_cfg;
+
+nsfw_recycle_fun g_rec_fun[NSFW_REC_TYPE_MAX] = { 0 };
+
+nsfw_rec_fun_info g_rec_lock_fun[NSFW_REC_LOCK_REL_MAX_FUN];
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_reg_fun
+* Description : reg one recycle type recycle funciton
+* Input : u16 rec_type
+* nsfw_recycle_fun fun
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_recycle_reg_fun (u16 rec_type, nsfw_recycle_fun fun)
+{
+ if (NULL == fun || rec_type >= NSFW_REC_TYPE_MAX)
+ {
+ NSFW_LOGERR ("argv err]fun=%p,type=%u", fun, rec_type);
+ return FALSE;
+ }
+
+ g_rec_fun[rec_type] = fun;
+ NSFW_LOGINF ("reg]fun=%d,type=%u", fun, rec_type);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_lock_rel_fun
+* Description : reg lock release when app exit run
+* Input : nsfw_recycle_fun fun
+* void* data
+* u8 proc_type: NULL as all
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_recycle_lock_rel_fun (nsfw_recycle_fun fun, void *data, u8 proc_type)
+{
+ if (NULL == fun)
+ {
+ NSFW_LOGERR ("argv err]fun=%p,data=%p", fun, data);
+ return FALSE;
+ }
+
+ u32 i;
+
+ for (i = 0; i < NSFW_REC_LOCK_REL_MAX_FUN; i++)
+ {
+ if (NULL == g_rec_lock_fun[i].rec_fun)
+ {
+ g_rec_lock_fun[i].rec_fun = fun;
+ g_rec_lock_fun[i].data = data;
+ g_rec_lock_fun[i].proc_type = proc_type;
+ NSFW_LOGINF ("reg mgr_msg fun suc]fun=%p,data=%p", fun, data);
+ return TRUE;
+ }
+ }
+
+ NSFW_LOGINF ("reg]fun=%p,data=%p", fun, data);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_exit_pid_lock
+* Description : release all lock fun
+* Input : u32 pid
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_recycle_exit_pid_lock (u32 pid, u8 proc_type, void *argv)
+{
+ u32 i;
+ NSFW_LOGINF ("release lock]pid=%d,type=%d", pid, proc_type);
+ for (i = 0; i < NSFW_REC_LOCK_REL_MAX_FUN; i++)
+ {
+ if (NULL == g_rec_lock_fun[i].rec_fun)
+ {
+ break;
+ }
+
+ if ((NSFW_PROC_NULL == g_rec_lock_fun[i].proc_type)
+ || (proc_type == g_rec_lock_fun[i].proc_type))
+ {
+ (void) g_rec_lock_fun[i].rec_fun (pid, g_rec_lock_fun[i].data, 0);
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_obj_end
+* Description : one recycle object process finished notify
+* Input : u32 pid
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_recycle_obj_end (u32 pid)
+{
+ nsfw_mgr_msg *rsp_msg =
+ nsfw_mgr_msg_alloc (MGR_MSG_RCC_END_REQ, NSFW_PROC_MAIN);
+ if (NULL == rsp_msg)
+ {
+ NSFW_LOGERR ("alloc rsp msg failed]pid=%u", pid);
+ return FALSE;
+ }
+
+ nsfw_ps_info_msg *ps_msg = GET_USER_MSG (nsfw_ps_info_msg, rsp_msg);
+ ps_msg->host_pid = pid;
+ (void) nsfw_mgr_send_msg (rsp_msg);
+ nsfw_mgr_msg_free (rsp_msg);
+ NSFW_LOGINF ("send obj end msg]pid=%d", pid);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_callback_all_obj
+* Description : process all recycle object
+* Input : u32 pid
+* nsfw_recycle_pool *rec_pool
+* Output : None
+* Return Value : nsfw_rcc_stat
+* Calls :
+* Called By :
+*****************************************************************************/
+nsfw_rcc_stat
+nsfw_recycle_callback_all_obj (u32 pid, nsfw_recycle_pool * rec_pool)
+{
+ u32 match = 0;
+ nsfw_recycle_obj *obj = NULL;
+ if (NULL == rec_pool)
+ {
+ return NSFW_RCC_CONTINUE;
+ }
+
+ nsfw_recycle_obj *p_start = rec_pool->obj;
+ u32 i;
+ u32 size = rec_pool->pool_size;
+
+ nsfw_ps_info *pps_info;
+ pps_info = nsfw_ps_info_get (pid);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("get ps_info falied!]pid=%d", pid);
+ return NSFW_RCC_CONTINUE;
+ }
+
+ i32 cur_idx = (i32) (u64) nsfw_ps_get_uv (pps_info, NSFW_REC_IDX);
+
+ if (-1 == cur_idx)
+ {
+ cur_idx = 0;
+ nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx);
+ (void) nsfw_recycle_exit_pid_lock (pid, NSFW_PROC_APP, NULL);
+ }
+ else
+ {
+ cur_idx++;
+ nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx);
+ }
+
+ for (i = cur_idx; i < size; i++)
+ {
+ obj = &p_start[i];
+ cur_idx = i;
+ nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (u64) cur_idx);
+ if (FALSE == obj->alloc_flag)
+ {
+ continue;
+ }
+
+ if ((obj->rec_type < NSFW_REC_TYPE_MAX)
+ && (NULL != g_rec_fun[obj->rec_type]))
+ {
+ match++;
+ if (NSFW_RCC_SUSPEND ==
+ g_rec_fun[obj->rec_type] (pid, obj->data, obj->rec_type))
+ {
+ NSFW_LOGINF
+ ("call suspend]type=%d,obj_pid=%d,pid=%d,count=%d",
+ obj->rec_type, obj->host_pid, pid, match);
+ return NSFW_RCC_SUSPEND;
+ }
+ }
+ else
+ {
+ NSFW_LOGERR ("obj_error!drop]type=%d,obj_pid=%d,pid=%d",
+ obj->rec_type, obj->host_pid, pid);
+ }
+ }
+
+ NSFW_LOGWAR ("rec obj]pid=%d,count=%d,cur_idx=%d", pid, match, cur_idx);
+ return NSFW_RCC_CONTINUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_pid_obj
+* Description : recycle object with pid
+* Input : u32 pid
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_recycle_pid_obj (u32 pid)
+{
+ nsfw_ps_info *pps_info;
+ pps_info = nsfw_ps_info_get (pid);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("get ps_info falied!]pid=%d", pid);
+ return FALSE;
+ }
+
+ nsfw_recycle_pool *rec_pool = g_rec_cfg.mem_rec_obj_pool;
+ void *timer_ptr = nsfw_ps_get_uv (pps_info, NSFW_REC_TIMER);
+ if (NSFW_RCC_SUSPEND == nsfw_recycle_callback_all_obj (pid, rec_pool))
+ {
+ if (NULL != timer_ptr)
+ {
+ nsfw_timer_rmv_timer (timer_ptr);
+ timer_ptr = NULL;
+ }
+
+ struct timespec time_left = { NSFW_REC_WEND_TVLAUE, 0 };
+ timer_ptr =
+ (void *) nsfw_timer_reg_timer (NSFW_REC_WEND_TIMER,
+ (void *) (u64) pid,
+ nsfw_recycle_obj_timeout, time_left);
+ nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr);
+ return TRUE;
+ }
+
+ if (NULL != timer_ptr)
+ {
+ nsfw_timer_rmv_timer (timer_ptr);
+ nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, NULL);
+ }
+
+ (void) nsfw_ps_exit_end_notify (pid);
+ nsfw_ps_info_free (pps_info);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_all_obj
+* Description :
+* Input : u32 pid
+* nsfw_mem_addr_msg *addr_msg
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_recycle_all_obj (u32 pid)
+{
+ nsfw_ps_info *pps_info;
+ pps_info = nsfw_ps_info_get (pid);
+ if (NULL == pps_info)
+ {
+ pps_info = nsfw_ps_info_alloc (pid, NSFW_PROC_APP);
+ if (NULL == pps_info)
+ {
+ NSFW_LOGERR ("alloc ps_info falied!]pid=%u", pid);
+ return FALSE;
+ }
+ }
+
+ nsfw_ps_set_uv (pps_info, NSFW_REC_IDX, (void *) (-1));
+ nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, NULL);
+ return nsfw_recycle_pid_obj (pid);
+}
+
+/*****************************************************************************
+* Prototype : mem_app_exit_proc
+* Description : exiting message process
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+mem_app_exit_proc (nsfw_mgr_msg * msg)
+{
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("msg nul");
+ return FALSE;
+ }
+
+ nsfw_ps_info_msg *ps_info_msg = GET_USER_MSG (nsfw_ps_info_msg, msg);
+
+ /* look up the app rec memzone and release all resource */
+ /* no need to send rsp for it will be send after stack process over */
+ if (TRUE == nsfw_recycle_all_obj (ps_info_msg->host_pid))
+ {
+ NSFW_LOGINF ("obj found!]pid=%d", ps_info_msg->host_pid);
+ return TRUE;
+ }
+
+ (void) nsfw_ps_exit_end_notify (ps_info_msg->host_pid);
+ return FALSE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_obj_end_proc
+* Description : obj recycle finished notify process
+* Input : nsfw_mgr_msg* msg
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_recycle_obj_end_proc (nsfw_mgr_msg * msg)
+{
+ if (NULL == msg)
+ {
+ NSFW_LOGERR ("msg nul");
+ return FALSE;
+ }
+
+ nsfw_ps_info_msg *ps_info_msg = GET_USER_MSG (nsfw_ps_info_msg, msg);
+
+ return nsfw_recycle_pid_obj (ps_info_msg->host_pid);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_obj_timeout
+* Description : recycle object timeout process
+* Input : u32 timer_type
+* void* data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_recycle_obj_timeout (u32 timer_type, void *data)
+{
+ u32 pid = (u64) data;
+ void *timer_ptr = NULL;
+ NSFW_LOGINF ("ps_info timerout]pid=%u", pid);
+
+ nsfw_ps_info *pps_info;
+ pps_info = nsfw_ps_info_get (pid);
+ if (NULL != pps_info)
+ {
+ nsfw_recycle_pool *rec_pool = g_rec_cfg.mem_rec_obj_pool;
+ if (NULL != rec_pool)
+ {
+ if (TRUE == g_hbt_switch)
+ {
+ struct timespec time_left = { NSFW_REC_WEND_TVLAUE, 0 };
+ timer_ptr =
+ (void *) nsfw_timer_reg_timer (timer_type, data,
+ nsfw_recycle_obj_timeout,
+ time_left);
+ nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr);
+ return TRUE;
+ }
+ }
+ nsfw_ps_set_uv (pps_info, NSFW_REC_TIMER, timer_ptr);
+ }
+
+ (void) nsfw_recycle_pid_obj (pid);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : mem_rec_zone_init
+* Description : init recycle zone in app, only work on App
+* Input : None
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+mem_rec_zone_init ()
+{
+ nsfw_mem_mring pringinfo;
+ pringinfo.enmptype = NSFW_MRING_MPMC;
+ pringinfo.isocket_id = NSFW_SOCKET_ANY;
+ pringinfo.stname.entype = NSFW_NSHMEM;
+ pringinfo.usnum = MEM_RECYCLE_PER_PRO_QUE;
+ u32 i;
+ for (i = 0; i < NSFW_REC_PRO_MAX; i++)
+ {
+ if (-1 ==
+ SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s%d",
+ MEM_REC_QUEUE_NAME, i))
+ {
+ NSFW_LOGERR ("SPRINTF_S failed]");
+ return FALSE;
+ }
+ g_rec_cfg.mem_rec_pro[i] = nsfw_mem_ring_create (&pringinfo);
+ if (NULL == g_rec_cfg.mem_rec_pro[i])
+ {
+ NSFW_LOGERR ("alloc rec ring nul!");
+ return FALSE;
+ }
+ }
+
+ MEM_STAT (NSFW_RECYCLE_MODULE, MEM_REC_QUEUE_NAME, NSFW_NSHMEM,
+ NSFW_REC_PRO_MAX * nsfw_mem_get_len (g_rec_cfg.mem_rec_pro[0],
+ NSFW_MEM_RING));
+
+ nsfw_mem_zone pzoneinfo;
+ pzoneinfo.isocket_id = NSFW_SOCKET_ANY;
+ pzoneinfo.stname.entype = NSFW_NSHMEM;
+ pzoneinfo.lenth =
+ MEM_RECYCLE_OBJ_MAX_NUM * sizeof (nsfw_recycle_obj) +
+ sizeof (nsfw_recycle_pool);
+ if (-1 ==
+ SPRINTF_S (pzoneinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MEM_REC_POOL_NAME))
+ {
+ NSFW_LOGERR ("SPRINTF_S failed]");
+ return FALSE;
+ }
+
+ g_rec_cfg.mem_rec_obj_pool = nsfw_mem_zone_create (&pzoneinfo);
+ if (NULL == g_rec_cfg.mem_rec_obj_pool)
+ {
+ NSFW_LOGERR ("alloc rec pool nul!");
+ return FALSE;
+ }
+
+ MEM_STAT (NSFW_RECYCLE_MODULE, MEM_REC_POOL_NAME, NSFW_NSHMEM,
+ pzoneinfo.lenth);
+
+ int retval;
+ retval =
+ MEMSET_S (g_rec_cfg.mem_rec_obj_pool, pzoneinfo.lenth, 0,
+ pzoneinfo.lenth);
+ if (EOK != retval)
+ {
+ NSFW_LOGERR ("mem set init failed!");
+ return FALSE;
+ }
+
+ i32 j;
+ nsfw_recycle_pool *rec_pool =
+ (nsfw_recycle_pool *) g_rec_cfg.mem_rec_obj_pool;
+ rec_pool->pool_size = MEM_RECYCLE_OBJ_MAX_NUM;
+
+ nsfw_recycle_obj *p_start = rec_pool->obj;
+ for (i = 0; i < NSFW_REC_PRO_MAX; i++)
+ {
+ for (j = 0; j < MEM_RECYCLE_PER_PRO_QUE; j++)
+ {
+ if (FALSE == p_start[j].alloc_flag)
+ {
+ if (0 ==
+ nsfw_mem_ring_enqueue (g_rec_cfg.mem_rec_pro[i],
+ &p_start[j]))
+ {
+ NSFW_LOGERR ("enqueue failed");
+ break;
+ }
+ }
+ }
+ p_start = p_start + MEM_RECYCLE_PER_PRO_QUE;
+ }
+
+ NSFW_LOGINF ("init rec pool and ring suc!");
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_reg_obj
+* Description : reg one recycle object
+* Input : u8 priority
+* u16 rec_type
+* void* data
+* Output : None
+* Return Value : void *
+* Calls :
+* Called By :
+*****************************************************************************/
+void *
+nsfw_recycle_reg_obj (u8 priority, u16 rec_type, void *data)
+{
+ if (NSFW_REC_PRO_MAX <= priority)
+ {
+ NSFW_LOGERR ("pro error]priority=%d,rec_type=%d,data=%p", priority,
+ rec_type, data);
+ return NULL;
+ }
+
+ nsfw_recycle_obj *obj = NULL;
+ if (0 ==
+ nsfw_mem_ring_dequeue (g_rec_cfg.mem_rec_pro[priority], (void *) &obj))
+ {
+ NSFW_LOGERR ("dequeue error]priority=%d,rec_type=%d,data=%p",
+ priority, rec_type, data);
+ return NULL;
+ }
+
+ if (EOK != MEMSET_S (obj, sizeof (*obj), 0, sizeof (*obj)))
+ {
+ if (0 == nsfw_mem_ring_enqueue (g_rec_cfg.mem_rec_pro[priority], obj))
+ {
+ NSFW_LOGERR ("enqueue error]priority=%d,rec_type=%d,data=%p",
+ priority, rec_type, data);
+ }
+
+ NSFW_LOGERR ("mem set error]priority=%d,rec_type=%d,data=%p",
+ priority, rec_type, data);
+ return NULL;
+ }
+
+ obj->alloc_flag = TRUE;
+ obj->rec_type = rec_type;
+ obj->data = data;
+ obj->host_pid = get_sys_pid ();
+ obj->alloc_flag = TRUE;
+ NSFW_LOGINF ("en queue obj]priority=%d,rec_type=%d,data=%p", priority,
+ rec_type, data);
+ return obj;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_rechk_lock
+* Description : add for rechk lock
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*****************************************************************************/
+int
+nsfw_recycle_rechk_lock ()
+{
+ return nsfw_ps_rechk_pid_exit (nsfw_recycle_exit_pid_lock, NULL);
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_module_init
+* Description : module init
+* Input : void* param
+* Output : None
+* Return Value : static int
+* Calls :
+* Called By :
+*****************************************************************************/
+NSTACK_STATIC int nsfw_recycle_module_init (void *param);
+NSTACK_STATIC int
+nsfw_recycle_module_init (void *param)
+{
+ u32 proc_type = (u32) ((long long) param);
+ NSFW_LOGINF ("recycle module init]type=%d", proc_type);
+ g_rec_cfg.rec_waite_end_tvalue = NSFW_REC_WEND_TVLAUE_DEF;
+ switch (proc_type)
+ {
+ case NSFW_PROC_MASTER:
+ return 0;
+ case NSFW_PROC_MAIN:
+ (void) nsfw_mgr_reg_msg_fun (MGR_MSG_APP_EXIT_REQ, mem_app_exit_proc);
+ (void) nsfw_mgr_reg_msg_fun (MGR_MSG_RCC_END_REQ,
+ nsfw_recycle_obj_end_proc);
+ if (TRUE == mem_rec_zone_init ())
+ {
+ return 0;
+ }
+
+ return 0;
+ default:
+ if (proc_type < NSFW_PROC_MAX)
+ {
+ break;
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_recycle_fork_init
+* Description : fork init
+* Input : None
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_recycle_fork_init ()
+{
+ /* reconnect to master after fork in child proc */
+ nsfw_mgr_close_dst_proc (NSFW_PROC_MAIN, 0);
+ nsfw_mgr_close_dst_proc (NSFW_PROC_MASTER, 0);
+ if (0 == nsfw_recycle_module_init ((void *) ((long long) NSFW_PROC_APP)))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* *INDENT-OFF* */
+NSFW_MODULE_NAME (NSFW_RECYCLE_MODULE)
+NSFW_MODULE_PRIORITY (10)
+NSFW_MODULE_DEPENDS (NSFW_PS_MEM_MODULE)
+NSFW_MODULE_INIT (nsfw_recycle_module_init)
+/* *INDENT-ON* */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/src/framework/ipc/ps/nsfw_recycle_module.h b/src/framework/ipc/ps/nsfw_recycle_module.h
new file mode 100644
index 0000000..694c1d2
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_recycle_module.h
@@ -0,0 +1,84 @@
+/*
+*
+* 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.
+*/
+
+#ifndef _NSFW_RECYCLE_MODULE_H
+#define _NSFW_RECYCLE_MODULE_H
+
+#include "nsfw_recycle_api.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#define MEM_RECYCLE_PER_PRO_QUE 128
+#define MEM_RECYCLE_OBJ_MAX_NUM (MEM_RECYCLE_PER_PRO_QUE*NSFW_REC_PRO_MAX)
+
+#define MEM_REC_POOL_NAME "APP_REC_POOL"
+#define MEM_REC_QUEUE_NAME "APP_REC_RINGQ"
+
+#define REC_POOL_MAGIC_FLAG 0xDBFC01A600000000
+
+#define NSFW_REC_WEND_TIMER 1
+#define NSFW_REC_WEND_TVLAUE_DEF 60
+
+#define NSFW_REC_WEND_TVLAUE (g_rec_cfg.rec_waite_end_tvalue)
+
+typedef struct _nsfw_recycle_obj
+{
+ u8 alloc_flag;
+ u8 u8reserve;
+ u16 rec_type;
+ u32 host_pid;
+ void *data;
+ u64 u64reserve;
+} nsfw_recycle_obj;
+
+#define NSFW_REC_LOCK_REL_MAX_FUN 32
+
+typedef struct _nsfw_rec_fun_info
+{
+ nsfw_recycle_fun rec_fun;
+ void *data;
+ u8 proc_type;
+} nsfw_rec_fun_info;
+
+typedef struct _nsfw_recycle_pool
+{
+ u32 pool_size;
+ nsfw_recycle_obj obj[0];
+} nsfw_recycle_pool;
+
+typedef struct _nsfw_recycle_cfg
+{
+ u16 rec_waite_end_tvalue;
+ mring_handle mem_rec_obj_pool;
+ mzone_handle mem_rec_pro[NSFW_REC_PRO_MAX];
+} nsfw_recycle_cfg;
+
+extern nsfw_rcc_stat nsfw_recycle_callback_all_obj (u32 pid,
+ nsfw_recycle_pool *
+ rec_pool);
+extern int nsfw_recycle_obj_timeout (u32 timer_type, void *data);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#endif /* _NSFW_RECYCLE_MODULE_H */
diff --git a/src/framework/ipc/ps/nsfw_soft_param.c b/src/framework/ipc/ps/nsfw_soft_param.c
new file mode 100644
index 0000000..d458040
--- /dev/null
+++ b/src/framework/ipc/ps/nsfw_soft_param.c
@@ -0,0 +1,296 @@
+/*
+*
+* 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 header files *
+ *----------------------------------------------*/
+
+#include <stdlib.h>
+#include "types.h"
+#include "nstack_securec.h"
+#include "nsfw_init.h"
+
+#include "nstack_log.h"
+#include "nsfw_maintain_api.h"
+
+#include "nsfw_mem_api.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+typedef struct _nsfw_set_soft_item
+{
+ void *data;
+ u32 size;
+ u64 max;
+ u64 min;
+} nsfw_set_soft_item;
+
+/* *INDENT-OFF* */
+nsfw_set_soft_fun g_soft_fun[NSFW_MAX_SOFT_PARAM] = { 0 };
+nsfw_set_soft_item g_soft_int_cfg[NSFW_MAX_SOFT_PARAM];
+/* *INDENT-ON* */
+
+int
+nsfw_isdigitstr (const char *str)
+{
+ if (NULL == str || '\0' == str[0])
+ return 0;
+
+ while (*str)
+ {
+ if (*str < '0' || *str > '9')
+ return 0;
+ str++;
+ }
+ return 1;
+}
+
+u8
+nsfw_soft_param_reg_fun (u32 param_name, nsfw_set_soft_fun fun)
+{
+ if (NULL == fun || param_name >= NSFW_MAX_SOFT_PARAM)
+ {
+ NSFW_LOGERR ("argv err]fun=%p,type=%u", fun, param_name);
+ return FALSE;
+ }
+
+ g_soft_fun[param_name] = fun;
+ NSFW_LOGINF ("reg]fun=%d,type=%u", fun, param_name);
+ return TRUE;
+}
+
+int
+nsfw_soft_set_int (u32 param, char *buf, u32 buf_len)
+{
+ u64 buf_value = 0;
+ if (NULL == buf || param >= NSFW_MAX_SOFT_PARAM)
+ {
+ NSFW_LOGERR ("argv err]buf=%p,param=%u", buf, param);
+ return FALSE;
+ }
+
+ if (!nsfw_isdigitstr (buf))
+ {
+ NSFW_LOGERR ("argv err]buf=%s,param=%u", buf, param);
+ return FALSE;
+ }
+
+ char *parsing_end;
+ buf_value = (u64) strtol (buf, &parsing_end, 10);
+ nsfw_set_soft_item *int_item = &g_soft_int_cfg[param];
+ if (NULL == int_item->data)
+ {
+ NSFW_LOGERR ("data err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, int_item->min, int_item->max); //[DTS2017112402499][2017-11-24][z00316269] Issue #40, fix type dismatch
+ return FALSE;
+ }
+
+ if (buf_value < int_item->min || buf_value > int_item->max)
+ {
+ NSFW_LOGERR ("argv err]buf=%s,param=%u,min=%llu,max=%llu", buf, param, int_item->min, int_item->max); //[DTS2017112402499][2017-11-24][z00316269] Issue #40, fix type dismatch
+ return FALSE;
+ }
+
+ u32 size = int_item->size;
+ if (size >= sizeof (u64))
+ {
+ size = sizeof (u64);
+ }
+
+ if (EOK != MEMCPY_S (int_item->data, size, &buf_value, size))
+ {
+ NSFW_LOGERR ("MEMCPY_S failed");
+ return FALSE;
+ }
+
+ NSFW_LOGINF ("set soft param ok]param=%u,value=%llu,size=%u", param,
+ buf_value, size);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : nsfw_soft_param_reg_int
+* Description : reg int param set
+* Input : u32 param_name
+* u32 size
+* u32 min
+* u32 max
+* u64 *data
+* Output : None
+* Return Value : u8
+* Calls :
+* Called By :
+*****************************************************************************/
+u8
+nsfw_soft_param_reg_int (u32 param_name, u32 size, u32 min, u32 max,
+ u64 * data)
+{
+ if (NULL == data || param_name >= NSFW_MAX_SOFT_PARAM)
+ {
+ NSFW_LOGERR ("argv err]data=%p,type=%u", data, param_name);
+ return FALSE;
+ }
+
+ g_soft_int_cfg[param_name].data = data;
+ g_soft_int_cfg[param_name].size = size;
+ g_soft_int_cfg[param_name].max = max;
+ g_soft_int_cfg[param_name].min = min;
+ return nsfw_soft_param_reg_fun (param_name, nsfw_soft_set_int);
+}
+
+void
+nsfw_set_soft_para (fw_poc_type proc_type, u32 para_name, void *value,
+ u32 size)
+{
+ nsfw_mgr_msg *msg =
+ (nsfw_mgr_msg *) nsfw_mgr_msg_alloc (MGR_MSG_SOF_PAR_REQ, proc_type);
+ if (NULL == msg)
+ {
+ NSFW_LOGERR
+ ("nsfw_mgr_msg_alloc failed] msg type=%d, proc type=%d, para_name=%u",
+ MGR_MSG_SOF_PAR_REQ, proc_type, para_name);
+ return;
+ }
+
+ nsfw_soft_param_msg *soft_msg = GET_USER_MSG (nsfw_soft_param_msg, msg);
+
+ soft_msg->param_name = para_name;
+ soft_msg->rsp_code = 0;
+
+ if (EOK !=
+ MEMCPY_S (soft_msg->param_value, sizeof (soft_msg->param_value),
+ value, size))
+ {
+ NSFW_LOGERR
+ ("MEMCPY_S failed] msg type=%d, proc type=%d, para_name=%u",
+ MGR_MSG_SOF_PAR_REQ, proc_type, para_name);
+ nsfw_mgr_msg_free (msg);
+ return;
+ }
+
+ nsfw_mgr_msg *rsp = nsfw_mgr_null_rspmsg_alloc ();
+ if (NULL == rsp)
+ {
+ NSFW_LOGERR
+ ("nsfw_mgr_null_rspmsg_alloc failed] msg type=%d, proc type=%d, para_name=%u",
+ MGR_MSG_SOF_PAR_REQ, proc_type, para_name);
+ nsfw_mgr_msg_free (msg);
+ return;
+ }
+
+ if (!nsfw_mgr_send_req_wait_rsp (msg, rsp))
+ {
+ NSFW_LOGERR
+ ("can not get response] msg type=%d, proc type=%d, para_name=%u",
+ MGR_MSG_SOF_PAR_REQ, proc_type, para_name);
+ nsfw_mgr_msg_free (msg);
+ nsfw_mgr_msg_free (rsp);
+ return;
+ }
+
+ nsfw_soft_param_msg *soft_rsp_msg = GET_USER_MSG (nsfw_soft_param_msg, rsp);
+ if (soft_rsp_msg->rsp_code != NSFW_EXIT_SUCCESS)
+ {
+ NSFW_LOGERR
+ ("set soft param failed] msg type=%d, proc type=%d, para_name=%u, rsp code=%u",
+ MGR_MSG_SOF_PAR_REQ, proc_type, para_name, soft_rsp_msg->rsp_code);
+ nsfw_mgr_msg_free (msg);
+ nsfw_mgr_msg_free (rsp);
+ return;
+ }
+
+ NSFW_LOGINF
+ ("set soft param success] msg type=%d, proc type=%d, para_name=%u",
+ MGR_MSG_SOF_PAR_REQ, proc_type, para_name);
+
+ nsfw_mgr_msg_free (msg);
+ nsfw_mgr_msg_free (rsp);
+ return;
+}
+
+int
+nsfw_softparam_msg_proc (nsfw_mgr_msg * msg)
+{
+ nsfw_mgr_msg *rsp_msg = nsfw_mgr_rsp_msg_alloc (msg);
+ if (NULL == rsp_msg)
+ {
+ NSFW_LOGERR ("alloc rsp failed,drop msg!" MSGINFO, PRTMSG (msg));
+ return FALSE;
+ }
+
+ nsfw_soft_param_msg *soft_msg = GET_USER_MSG (nsfw_soft_param_msg, msg);
+ nsfw_soft_param_msg *soft_rsp_msg =
+ GET_USER_MSG (nsfw_soft_param_msg, rsp_msg);
+ if ((soft_msg->param_name < NSFW_MAX_SOFT_PARAM)
+ && (NULL != g_soft_fun[soft_msg->param_name]))
+ {
+ soft_msg->param_value[sizeof (soft_msg->param_value) - 1] = 0;
+ (void) g_soft_fun[soft_msg->param_name] (soft_msg->param_name,
+ (char *)
+ soft_msg->param_value,
+ sizeof
+ (soft_msg->param_value));
+ soft_rsp_msg->rsp_code = NSFW_EXIT_SUCCESS;
+ }
+ else
+ {
+ NSFW_LOGERR ("set soft failed!]soft=%u", soft_msg->param_name);
+ soft_rsp_msg->rsp_code = NSFW_EXIT_FAILED;
+ }
+
+ (void) nsfw_mgr_send_msg (rsp_msg);
+ nsfw_mgr_msg_free (rsp_msg);
+ return TRUE;
+}
+
+int nsfw_softparam_module_init (void *param);
+int
+nsfw_softparam_module_init (void *param)
+{
+ u8 proc_type = (u8) ((long long) param);
+ NSFW_LOGINF ("softparam module init]type=%u", proc_type);
+ switch (proc_type)
+ {
+ case NSFW_PROC_MAIN:
+ case NSFW_PROC_MASTER:
+ (void) nsfw_mgr_reg_msg_fun (MGR_MSG_SOF_PAR_REQ,
+ nsfw_softparam_msg_proc);
+ return 0;
+ default:
+ if (proc_type < NSFW_PROC_MAX)
+ {
+ break;
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
+/* *INDENT-OFF* */
+NSFW_MODULE_NAME (NSFW_SOFT_PARAM_MODULE)
+NSFW_MODULE_PRIORITY (99)
+NSFW_MODULE_INIT (nsfw_softparam_module_init)
+/* *INDENT-ON* */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */