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 "comm_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 uint64_t isRepeat = seqVerifyInfo->recvBitmap & (0x1UL << offset);
33 if (isRepeat) {
34 COMM_LOGI(COMM_VERIFY, "duplicated package seq. recvSeq=%{public}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 COMM_LOGE(COMM_VERIFY, "seq bias reach max. MAX_SEQ_BIAS=%{public}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 } else {
121 if (recvSeq == seqVerifyInfo->minSeq) {
122 seqVerifyInfo->minSeq = ++recvSeq;
123 return true;
124 }
125 if (recvSeq > seqVerifyInfo->minSeq) {
126 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
127 }
128 return false;
129 }
130 /* can not reach here. */
131 return false;
132 }
133
IsPassFlipNegativeCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)134 static bool IsPassFlipNegativeCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
135 {
136 if (recvSeq >= 0) {
137 if (recvSeq == seqVerifyInfo->minSeq) {
138 seqVerifyInfo->minSeq = ++recvSeq;
139 return true;
140 }
141 if (recvSeq > seqVerifyInfo->minSeq) {
142 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
143 }
144 return false;
145 } else {
146 if (recvSeq < seqVerifyInfo->maxSeq) {
147 return IsPassDuplicateCheck(seqVerifyInfo, recvSeq);
148 }
149 return IsPassOverMaxCheck(seqVerifyInfo, recvSeq);
150 }
151 /* can not reach here. */
152 return false;
153 }
154
IsPassSeqCheck(SeqVerifyInfo * seqVerifyInfo,int32_t recvSeq)155 bool IsPassSeqCheck(SeqVerifyInfo *seqVerifyInfo, int32_t recvSeq)
156 {
157 if (seqVerifyInfo == NULL) {
158 COMM_LOGE(COMM_VERIFY, "invalid param.");
159 return false;
160 }
161 bool isDifferentSign = IsDifferentSign(seqVerifyInfo->minSeq, seqVerifyInfo->maxSeq);
162 if (seqVerifyInfo->minSeq == seqVerifyInfo->maxSeq) {
163 return IsPassNormalCheck(seqVerifyInfo, recvSeq);
164 }
165 if ((seqVerifyInfo->minSeq < seqVerifyInfo->maxSeq) && !isDifferentSign) {
166 return IsPassNoflipDisorderCheck(seqVerifyInfo, recvSeq);
167 }
168 if ((seqVerifyInfo->minSeq > seqVerifyInfo->maxSeq) && isDifferentSign) {
169 return IsPassFlipNegativeCheck(seqVerifyInfo, recvSeq);
170 }
171 if ((seqVerifyInfo->minSeq < seqVerifyInfo->maxSeq) && isDifferentSign) {
172 return IsPassFlipPositiveCheck(seqVerifyInfo, recvSeq);
173 }
174 /* can not reach here. */
175 return false;
176 }
177