1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #include "iotx_dm_internal.h"
6 
7 dm_ipc_t g_dm_ipc;
8 
_dm_ipc_get_ctx(void)9 static dm_ipc_t *_dm_ipc_get_ctx(void)
10 {
11     return &g_dm_ipc;
12 }
13 
_dm_ipc_lock(void)14 static void _dm_ipc_lock(void)
15 {
16     dm_ipc_t *ctx = _dm_ipc_get_ctx();
17     if (ctx->mutex) {
18         HAL_MutexLock(ctx->mutex);
19     }
20 }
21 
_dm_ipc_unlock(void)22 static void _dm_ipc_unlock(void)
23 {
24     dm_ipc_t *ctx = _dm_ipc_get_ctx();
25     if (ctx->mutex) {
26         HAL_MutexUnlock(ctx->mutex);
27     }
28 }
29 
dm_ipc_init(int max_size)30 int dm_ipc_init(int max_size)
31 {
32     dm_ipc_t *ctx = _dm_ipc_get_ctx();
33 
34     memset(ctx, 0, sizeof(dm_ipc_t));
35 
36     /* Create Mutex */
37     ctx->mutex = HAL_MutexCreate();
38     if (ctx->mutex == NULL) {
39         return DM_INVALID_PARAMETER;
40     }
41 
42     /* Init List */
43     ctx->msg_list.max_size = max_size;
44     INIT_LIST_HEAD(&ctx->msg_list.message_list);
45 
46     return SUCCESS_RETURN;
47 }
48 
dm_ipc_deinit(void)49 void dm_ipc_deinit(void)
50 {
51     dm_ipc_t *ctx = _dm_ipc_get_ctx();
52     dm_ipc_msg_node_t *del_node = NULL;
53     dm_ipc_msg_node_t *next_node = NULL;
54     dm_ipc_msg_t *del_msg = NULL;
55 
56     if (ctx->mutex) {
57         HAL_MutexDestroy(ctx->mutex);
58     }
59 
60     list_for_each_entry_safe(del_node, next_node, &ctx->msg_list.message_list,
61                              linked_list, dm_ipc_msg_node_t)
62     {
63         /* Free Message */
64         del_msg = (dm_ipc_msg_t *)del_node->data;
65         if (del_msg->data) {
66             DM_free(del_msg->data);
67         }
68         DM_free(del_msg);
69         del_msg = NULL;
70 
71         /* Free Node */
72         list_del(&del_node->linked_list);
73         DM_free(del_node);
74     }
75 }
76 
dm_ipc_msg_insert(void * data)77 int dm_ipc_msg_insert(void *data)
78 {
79     dm_ipc_t *ctx = _dm_ipc_get_ctx();
80     dm_ipc_msg_node_t *node = NULL;
81 
82     if (data == NULL) {
83         return DM_INVALID_PARAMETER;
84     }
85 
86     _dm_ipc_lock();
87     dm_log_debug("dm msg list size: %d, max size: %d", ctx->msg_list.size,
88                  ctx->msg_list.max_size);
89     if (ctx->msg_list.size >= ctx->msg_list.max_size) {
90         dm_log_warning("dm ipc list full");
91         _dm_ipc_unlock();
92         return FAIL_RETURN;
93     }
94 
95     node = DM_malloc(sizeof(dm_ipc_msg_node_t));
96     if (node == NULL) {
97         _dm_ipc_unlock();
98         return DM_MEMORY_NOT_ENOUGH;
99     }
100     memset(node, 0, sizeof(dm_ipc_msg_node_t));
101 
102     node->data = data;
103     INIT_LIST_HEAD(&node->linked_list);
104     ctx->msg_list.size++;
105     list_add_tail(&node->linked_list, &ctx->msg_list.message_list);
106 
107     _dm_ipc_unlock();
108     return SUCCESS_RETURN;
109 }
110 
dm_ipc_msg_next(void ** data)111 int dm_ipc_msg_next(void **data)
112 {
113     dm_ipc_t *ctx = _dm_ipc_get_ctx();
114     dm_ipc_msg_node_t *node = NULL;
115 
116     if (data == NULL || *data != NULL) {
117         return DM_INVALID_PARAMETER;
118     }
119 
120     _dm_ipc_lock();
121 
122     if (list_empty(&ctx->msg_list.message_list)) {
123         _dm_ipc_unlock();
124         return FAIL_RETURN;
125     }
126 
127     node = list_first_entry(&ctx->msg_list.message_list, dm_ipc_msg_node_t,
128                             linked_list);
129     list_del(&node->linked_list);
130     ctx->msg_list.size--;
131 
132     *data = node->data;
133     DM_free(node);
134 
135     _dm_ipc_unlock();
136     return SUCCESS_RETURN;
137 }
138