• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License. \n
14  *
15  * Description: Provides AT async notify \n
16  */
17 
18 #ifdef CONFIG_AT_SUPPORT_NOTIFY_REPORT
19 #include "at_product.h"
20 #include "at_base.h"
21 #include "at_msg.h"
22 #include "at_process.h"
23 #include "at_notify.h"
24 
25 #define STRING_END_FLAG_LEN 1
26 
27 typedef struct at_async_notify_t {
28     char *rsp_string;
29     uint16_t string_len;
30     at_channel_id_t channel_id;
31     struct at_async_notify_t *next;
32 } at_async_notify_t;
33 
34 static at_async_notify_t *g_notify_list = NULL;
35 static void *g_notify_mutex_handle = NULL;
36 
at_notify_append_node(at_async_notify_t * node)37 static void at_notify_append_node(at_async_notify_t *node)
38 {
39     if (g_notify_list == NULL) {
40         g_notify_list = node;
41     } else {
42         at_async_notify_t *next_node = g_notify_list;
43         while (next_node->next != NULL) {
44             next_node = next_node->next;
45         }
46         next_node->next = node;
47     }
48 }
49 
50 /* Ensured that the input is not null */
at_notify_free_node(at_async_notify_t * node)51 static void at_notify_free_node(at_async_notify_t *node)
52 {
53     if (node->rsp_string != NULL) {
54         at_free(node->rsp_string);
55         node->rsp_string = NULL;
56     }
57 
58     at_free(node);
59 }
60 
at_notify_find_next_node(void)61 static at_async_notify_t* at_notify_find_next_node(void)
62 {
63     if (g_notify_list == NULL) {
64         return NULL;
65     }
66 
67     at_async_notify_t *node = g_notify_list;
68     g_notify_list = g_notify_list->next;
69     return node;
70 }
71 
at_notify_send_msg(void)72 static errcode_t at_notify_send_msg(void)
73 {
74     at_msg_block_t msg;
75     msg.type = AT_CMD_URC_REPORT_MSG;
76 
77     return at_msg_send(&msg);
78 }
79 
uapi_at_urc_to_channel(at_channel_id_t channel_id,const char * msg,uint32_t msg_len)80 errcode_t uapi_at_urc_to_channel(at_channel_id_t channel_id, const char *msg, uint32_t msg_len)
81 {
82     if (msg == NULL || msg_len == 0) {
83         return ERRCODE_INVALID_PARAM;
84     }
85 
86     at_async_notify_t *node = at_malloc(sizeof(at_async_notify_t));
87     if (node == NULL) {
88         return ERRCODE_MALLOC;
89     }
90 
91     node->rsp_string = at_malloc(msg_len + STRING_END_FLAG_LEN);
92     if (node->rsp_string == NULL) {
93         return ERRCODE_MALLOC;
94     }
95     node->string_len = msg_len;
96     node->channel_id = channel_id;
97     memset_s(node->rsp_string, msg_len + STRING_END_FLAG_LEN, 0, msg_len + STRING_END_FLAG_LEN);
98     if (memcpy_s(node->rsp_string, msg_len, msg, msg_len) != EOK) {
99         at_free(node->rsp_string);
100         at_free(node);
101         return ERRCODE_MEMCPY;
102     }
103     node->next = NULL;
104 
105     at_mutex_acquire(g_notify_mutex_handle);
106     at_notify_append_node(node);
107     at_mutex_release(g_notify_mutex_handle);
108     return at_notify_send_msg();
109 }
110 
at_notify_process_list(void)111 void at_notify_process_list(void)
112 {
113     at_mutex_acquire(g_notify_mutex_handle);
114     at_async_notify_t *node = at_notify_find_next_node();
115     while (node != NULL) {
116         uapi_at_report_to_single_channel(node->channel_id, node->rsp_string);
117         at_notify_free_node(node);
118         node = at_notify_find_next_node();
119     }
120     at_mutex_release(g_notify_mutex_handle);
121 }
122 
at_notify_init(void)123 void at_notify_init(void)
124 {
125     g_notify_mutex_handle = at_mutex_create();
126 }
127 #endif
128