• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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