1 /*
2 * Copyright (c) 2021 Huawei Device 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 "softbus_sequence_verification.h"
17 #include "softbus_log.h"
18
19 #define MAX_SEQ_BIAS 60
20
IsDifferentSign(int32_t seqA,int32_t seqB)21 static bool IsDifferentSign(int32_t seqA, int32_t seqB)
22 {
23 if ((seqA >= 0 && seqB >= 0) || (seqA < 0 && seqB < 0)) {
24 return false;
25 }
26 return true;
27 }
28
IsPassDuplicateCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)29 static bool IsPassDuplicateCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
30 {
31 uint32_t offset = (uint32_t)(seqVerifyInfo->maxSeq - recvSeq);
32 int32_t isRepeat = seqVerifyInfo->recvBitmap & (0x1UL << offset);
33 if (isRepeat) {
34 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_INFO, "duplicated package seq[%d].", recvSeq);
35 return false;
36 }
37 seqVerifyInfo->recvBitmap |= (0x1UL << offset);
38 return true;
39 }
40
IsPassOverMaxCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)41 static bool IsPassOverMaxCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
42 {
43 /* consider flip */
44 if (recvSeq - seqVerifyInfo->maxSeq < 0) {
45 return false;
46 }
47
48 if (recvSeq - seqVerifyInfo->minSeq >= MAX_SEQ_BIAS) {
49 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "seq bias reach max[%d].", MAX_SEQ_BIAS);
50 return false;
51 }
52 uint32_t seqOffset = (uint32_t)(recvSeq - seqVerifyInfo->maxSeq + 1);
53 seqVerifyInfo->maxSeq = ++recvSeq;
54 seqVerifyInfo->recvBitmap = seqVerifyInfo->recvBitmap << seqOffset;
55 /* 1: represent the penultimate bit of recvBitmap is 1. */
56 seqVerifyInfo->recvBitmap |= (0x1UL << 1);
57 return true;
58 }
59
IsPassAllRangeCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)60 static bool IsPassAllRangeCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
61 {
62 if (recvSeq == seqVerifyInfo->minSeq) {
63 seqVerifyInfo->minSeq = ++recvSeq;
64 return true;
65 }
66
67 if (recvSeq > seqVerifyInfo->minSeq) {
68 if (recvSeq < seqVerifyInfo->maxSeq) {
69 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
70 }
71 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
72 }
73 return false;
74 }
75
IsPassNormalCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)76 static bool IsPassNormalCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
77 {
78 /* normal case */
79 if (recvSeq == seqVerifyInfo->minSeq) {
80 seqVerifyInfo->minSeq = recvSeq + 1;
81 seqVerifyInfo->maxSeq = recvSeq + 1;
82 return true;
83 }
84 /* first disorder package, recvSeq and minSeq/maxSeq are same signs. */
85 if (!IsDifferentSign(recvSeq, seqVerifyInfo->minSeq)) {
86 if (recvSeq > seqVerifyInfo->maxSeq) {
87 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
88 }
89 return false;
90 }
91 /* first disorder package, recvSeq and minSeq/maxSeq are different signs. */
92 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
93 }
94
IsPassNoflipDisorderCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)95 static bool IsPassNoflipDisorderCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
96 {
97 if (seqVerifyInfo->minSeq >= 0) {
98 if (recvSeq >= 0) {
99 return IsPassAllRangeCheck(seqVerifyInfo, recvSeq);
100 }
101 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
102 }
103 if (seqVerifyInfo->maxSeq < 0) {
104 if (recvSeq < 0) {
105 return IsPassAllRangeCheck(seqVerifyInfo, recvSeq);
106 }
107 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
108 }
109 /* can not reach here. */
110 return false;
111 }
112
IsPassFlipPositiveCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)113 static bool IsPassFlipPositiveCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
114 {
115 if (recvSeq >= 0) {
116 if (recvSeq < seqVerifyInfo->maxSeq) {
117 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
118 }
119 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
120 }
121 if (recvSeq < 0) {
122 if (recvSeq == seqVerifyInfo->minSeq) {
123 seqVerifyInfo->minSeq = ++recvSeq;
124 return true;
125 }
126 if (recvSeq > seqVerifyInfo->minSeq) {
127 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
128 }
129 return false;
130 }
131 /* can not reach here. */
132 return false;
133 }
134
IsPassFlipNegativeCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)135 static bool IsPassFlipNegativeCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
136 {
137 if (recvSeq >= 0) {
138 if (recvSeq == seqVerifyInfo->minSeq) {
139 seqVerifyInfo->minSeq = ++recvSeq;
140 return true;
141 }
142 if (recvSeq > seqVerifyInfo->minSeq) {
143 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
144 }
145 return false;
146 }
147 if (recvSeq < 0) {
148 if (recvSeq < seqVerifyInfo->maxSeq) {
149 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
150 }
151 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
152 }
153 /* can not reach here. */
154 return false;
155 }
156
IsPassSeqCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)157 bool IsPassSeqCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
158 {
159 if (seqVerifyInfo == NULL) {
160 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "%s:invalid param.", __func__);
161 return false;
162 }
163 bool isDifferentSign = IsDifferentSign(seqVerifyInfo->minSeq, seqVerifyInfo->maxSeq);
164 if (seqVerifyInfo->minSeq == seqVerifyInfo->maxSeq) {
165 return IsPassNormalCheck(seqVerifyInfo, recvSeq);
166 }
167 if ((seqVerifyInfo->minSeq < seqVerifyInfo->maxSeq) && !isDifferentSign) {
168 return IsPassNoflipDisorderCheck(seqVerifyInfo, recvSeq);
169 }
170 if ((seqVerifyInfo->minSeq > seqVerifyInfo->maxSeq) && isDifferentSign) {
171 return IsPassFlipNegativeCheck(seqVerifyInfo, recvSeq);
172 }
173 if ((seqVerifyInfo->minSeq < seqVerifyInfo->maxSeq) && isDifferentSign) {
174 return IsPassFlipPositiveCheck(seqVerifyInfo, recvSeq);
175 }
176 /* can not reach here. */
177 return false;
178 }
179