• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
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.
14  */
15 
16 #include "KRecvBuf.h"
17 
18 #include "osal.h"
19 #include "securec.h"
20 #include "user_copy.h"
21 
22 #define HDF_LOG_TAG     KRecvBuf
23 
24 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
25 
KRecvBufUsedSize(KRecvBuf * krbCB)26 UINT32 KRecvBufUsedSize(KRecvBuf *krbCB)
27 {
28     UINT32 size;
29     UINT32 intSave;
30 
31     LOS_SpinLockSave(&krbCB->lock, &intSave);
32     size = krbCB->size - krbCB->remain;
33     LOS_SpinUnlockRestore(&krbCB->lock, intSave);
34 
35     return size;
36 }
37 
KRecvBufWriteLinear(KRecvBuf * krbCB,const CHAR * buf,UINT32 size)38 STATIC UINT32 KRecvBufWriteLinear(KRecvBuf *krbCB, const CHAR *buf, UINT32 size)
39 {
40     UINT32 cpSize;
41     errno_t err;
42 
43     // get copy size
44     cpSize = MIN(krbCB->remain, size);
45 
46     if (cpSize == 0) {
47         return 0;
48     }
49 
50     // copy to buffer
51     err = memcpy_s(krbCB->fifo + krbCB->wIdx, MIN((krbCB->size - krbCB->wIdx), krbCB->remain), buf, cpSize);
52     if (err != EOK) {
53         HDF_LOGE("%s: something is wrong in memcpy_s.\r\n", __func__);
54         return 0;
55     }
56 
57     krbCB->remain -= cpSize;
58     krbCB->wIdx += cpSize;
59 
60     // write point roll to start
61     if (krbCB->wIdx >= krbCB->size) {
62         krbCB->wIdx = 0;
63     }
64 
65     return cpSize;
66 }
67 
KRecvBufWriteLoop(KRecvBuf * krbCB,const CHAR * buf,UINT32 size)68 STATIC UINT32 KRecvBufWriteLoop(KRecvBuf *krbCB, const CHAR *buf, UINT32 size)
69 {
70     UINT32 right, cpSize;
71 
72     // get upper part space
73     right = krbCB->size - krbCB->wIdx;
74 
75     // get upper part copy size
76     cpSize = MIN(right, size);
77 
78     // copy upper part
79     cpSize = KRecvBufWriteLinear(krbCB, buf, cpSize);
80     if (cpSize == 0) {
81         HDF_LOGE("%s: something is wrong in KRecvBufWriteLinear.\r\n", __func__);
82         return 0;
83     }
84 
85     // copy lower part (if needed)
86     if (cpSize != size) {
87         cpSize += KRecvBufWriteLinear(krbCB, buf + cpSize, size - cpSize);
88     }
89 
90     return cpSize;
91 }
92 
KRecvBufWrite(KRecvBuf * krbCB,const CHAR * buf,UINT32 size)93 UINT32 KRecvBufWrite(KRecvBuf *krbCB, const CHAR *buf, UINT32 size)
94 {
95     UINT32 cpSize;
96 
97     if ((krbCB == NULL) || (buf == NULL) || (size == 0)) {
98         return 0;
99     }
100 
101     if ((krbCB->fifo == NULL) || (krbCB->remain == 0)) {
102         return 0;
103     }
104 
105     if (krbCB->rIdx <= krbCB->wIdx) {
106         cpSize = KRecvBufWriteLoop(krbCB, buf, size);
107     } else {
108         cpSize = KRecvBufWriteLinear(krbCB, buf, size);
109     }
110 
111     return cpSize;
112 }
113 
KRecvBufReadLinear(KRecvBuf * krbCB,const CHAR * buf,UINT32 size)114 STATIC UINT32 KRecvBufReadLinear(KRecvBuf *krbCB, const CHAR *buf, UINT32 size)
115 {
116     UINT32 cpSize;
117     errno_t err;
118 
119     // this time max size
120     cpSize = MIN((krbCB->size - krbCB->remain), (krbCB->size - krbCB->rIdx));
121 
122     // copy size
123     cpSize = MIN(cpSize, size);
124 
125     if (cpSize == 0) {
126         return 0;
127     }
128 
129     // copy data to user space
130     err = LOS_CopyFromKernel((void *)buf, size, (void *)(krbCB->fifo + krbCB->rIdx), cpSize);
131     if (err != EOK) {
132         return 0;
133     }
134 
135     krbCB->remain += cpSize;
136     krbCB->rIdx += cpSize;
137 
138     if (krbCB->rIdx >= krbCB->size) {
139         krbCB->rIdx = 0;
140     }
141 
142     return cpSize;
143 }
144 
KRecvBufReadLoop(KRecvBuf * krbCB,const CHAR * buf,UINT32 size)145 STATIC UINT32 KRecvBufReadLoop(KRecvBuf *krbCB, const CHAR *buf, UINT32 size)
146 {
147     UINT32 right, cpSize;
148 
149     // get upper part size
150     right = krbCB->size - krbCB->rIdx;
151 
152     // get upper part copy size
153     cpSize = MIN(right, size);
154 
155     // copy upper part
156     cpSize = KRecvBufReadLinear(krbCB, buf, cpSize);
157     if (cpSize == 0) {
158         HDF_LOGE("%s: something is wrong in KRecvBufReadLinear.\r\n", __func__);
159         return 0;
160     }
161 
162     // copy lower part (if needed)
163     if (cpSize < size) {
164         cpSize += KRecvBufReadLinear(krbCB, buf + cpSize, size - cpSize);
165     }
166 
167     return cpSize;
168 }
169 
KRecvBufRead(KRecvBuf * krbCB,CHAR * buf,UINT32 size)170 UINT32 KRecvBufRead(KRecvBuf *krbCB, CHAR *buf, UINT32 size)
171 {
172     UINT32 cpSize;
173 
174     if ((krbCB == NULL) || (buf == NULL) || (size == 0)) {
175         return 0;
176     }
177 
178     if ((krbCB->fifo == NULL) || (krbCB->remain == krbCB->size)) {
179         return 0;
180     }
181 
182     if (krbCB->rIdx >= krbCB->wIdx) {
183         cpSize = KRecvBufReadLoop(krbCB, buf, size);
184     } else {
185         cpSize = KRecvBufReadLinear(krbCB, buf, size);
186     }
187 
188     return cpSize;
189 }
190 
KRecvBufInit(KRecvBuf * krbCB,CHAR * fifo,UINT32 size)191 UINT32 KRecvBufInit(KRecvBuf *krbCB, CHAR *fifo, UINT32 size)
192 {
193     if ((krbCB == NULL) || (fifo == NULL)) {
194         return LOS_NOK;
195     }
196 
197     (VOID)memset_s(krbCB, sizeof(KRecvBuf), 0, sizeof(KRecvBuf));
198     LOS_SpinInit(&krbCB->lock);
199     krbCB->size = size;
200     krbCB->remain = size;
201     krbCB->status = BUF_USED;
202     krbCB->fifo = fifo;
203 
204     return LOS_OK;
205 }
206 
KRecvBufDeinit(KRecvBuf * krbCB)207 VOID KRecvBufDeinit(KRecvBuf *krbCB)
208 {
209     (VOID)memset_s(krbCB, sizeof(KRecvBuf), 0, sizeof(KRecvBuf));
210 }
211 
KRecvBufDump(KRecvBuf * krbCB)212 VOID KRecvBufDump(KRecvBuf *krbCB)
213 {
214     dprintf("\r\nKRecvBufDump : \r\n");
215     dprintf("\r\n rIdx : %d\r\n", krbCB->rIdx);
216     dprintf("\r\n wIdx : %d\r\n", krbCB->wIdx);
217     dprintf("\r\n size : %d\r\n", krbCB->size);
218     dprintf("\r\n status : %d\r\n", krbCB->status);
219     dprintf("\r\n remain : %d\r\n", krbCB->remain);
220     dprintf("\r\n status : %d\r\n", krbCB->status);
221 }
222