1 /* Copyright (c) 2003-2006 MySQL AB
2    Use is subject to license terms
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #ifndef TransporterInternalDefinitions_H
18 #define TransporterInternalDefinitions_H
19 
20 #if defined DEBUG_TRANSPORTER || defined VM_TRACE
21 #include <NdbOut.hpp>
22 #endif
23 
24 #define NDB_TCP_TRANSPORTER
25 
26 #ifdef HAVE_NDB_SHM
27 #define NDB_SHM_TRANSPORTER
28 #endif
29 
30 #ifdef HAVE_NDB_SCI
31 #define NDB_SCI_TRANSPORTER
32 #endif
33 
34 #ifdef DEBUG_TRANSPORTER
35 #define DEBUG(x) ndbout << x << endl
36 #else
37 #define DEBUG(x)
38 #endif
39 
40 #if defined VM_TRACE || defined DEBUG_TRANSPORTER
41 #define WARNING(X) ndbout << X << endl;
42 #else
43 #define WARNING(X)
44 #endif
45 
46 // Calculate a checksum
47 inline
48 Uint32
computeChecksum(const Uint32 * const startOfData,int nWords)49 computeChecksum(const Uint32 * const startOfData, int nWords) {
50   Uint32 chksum = startOfData[0];
51   for (int i=1; i < nWords; i++)
52     chksum ^= startOfData[i];
53   return chksum;
54 }
55 
56 struct Protocol6 {
57   Uint32 word1;
58   Uint32 word2;
59   Uint32 word3;
60 
61 /**
62  *
63  * b = Byte order           -  4 Bits (Note 1 significant bit)
64  * g = GSN                  - 16 Bits
65  * p = Prio                 -  2 Bits
66  * c = Checksum included    -  1 Bit
67  * z = Compression          -  1 Bit
68  * v = Version id           -  4 Bits
69  * i = Signal id included   -  1 Bit
70  * m = Message length       - 16 Bits (0-65536) (In word -> 0-256k bytes)
71  * d = Signal data length   -  5 Bits (0-31)
72  * t = trace                -  6 Bits (0-63)
73  * r = Recievers block no   - 16 Bits
74  * s = Senders block no     - 16 Bits
75  * u = Unused               -  7 Bits
76  * f = FragmentInfo1        -  1 Bit
77  * h = FragmentInfo2        -  1 bit
78  * n = No of segments       -  2 Bits
79 
80  * Word 1
81  *
82  *
83  *           1111111111222222222233
84  * 01234567890123456789012345678901
85  * bfizcppbmmmmmmmmmmmmmmmmbhdddddb
86 
87  **
88  * Word 2
89  *
90  *           1111111111222222222233
91  * 01234567890123456789012345678901
92  * ggggggggggggggggvvvvttttttnn
93 
94  **
95  * Word 3
96  *
97  *           1111111111222222222233
98  * 01234567890123456789012345678901
99  * rrrrrrrrrrrrrrrrssssssssssssssss
100 
101  **
102  * Word 4 (Optional Signal Id)
103  */
104 
105   /**
106    * 0 = Big endian (Sparc), 1 = Little endian (Intel)
107    */
108   static Uint32 getByteOrder       (const Uint32 & word1);
109   static Uint32 getCompressed      (const Uint32 & word1);
110   static Uint32 getSignalIdIncluded(const Uint32 & word1);
111   static Uint32 getCheckSumIncluded(const Uint32 & word1);
112   static Uint32 getPrio            (const Uint32 & word1);
113   static Uint32 getMessageLength   (const Uint32 & word1);
114 
115   static void setByteOrder       (Uint32 & word1, Uint32 byteOrder);
116   static void setCompressed      (Uint32 & word1, Uint32 compressed);
117   static void setSignalIdIncluded(Uint32 & word1, Uint32 signalId);
118   static void setCheckSumIncluded(Uint32 & word1, Uint32 checkSum);
119   static void setPrio            (Uint32 & word1, Uint32 prio);
120   static void setMessageLength   (Uint32 & word1, Uint32 messageLen);
121 
122   static void createSignalHeader(SignalHeader * const dst,
123 				 const Uint32 & word1,
124 				 const Uint32 & word2,
125 				 const Uint32 & word3);
126 
127   static void createProtocol6Header(Uint32 & word1,
128 				    Uint32 & word2,
129 				    Uint32 & word3,
130 				    const SignalHeader * const src);
131 };
132 
133 #define WORD1_BYTEORDER_MASK   (0x81000081)
134 #define WORD1_SIGNALID_MASK    (0x00000004)
135 #define WORD1_COMPRESSED_MASK  (0x00000008)
136 #define WORD1_CHECKSUM_MASK    (0x00000010)
137 #define WORD1_PRIO_MASK        (0x00000060)
138 #define WORD1_MESSAGELEN_MASK  (0x00FFFF00)
139 #define WORD1_SIGNAL_LEN_MASK  (0x7C000000)
140 #define WORD1_FRAG_INF_MASK    (0x00000002)
141 #define WORD1_FRAG_INF2_MASK   (0x02000000)
142 
143 #define WORD1_FRAG_INF_SHIFT   (1)
144 #define WORD1_SIGNALID_SHIFT   (2)
145 #define WORD1_COMPRESSED_SHIFT (3)
146 #define WORD1_CHECKSUM_SHIFT   (4)
147 #define WORD1_PRIO_SHIFT       (5)
148 #define WORD1_MESSAGELEN_SHIFT (8)
149 #define WORD1_FRAG_INF2_SHIFT  (25)
150 #define WORD1_SIGNAL_LEN_SHIFT (26)
151 
152 #define WORD2_VERID_GSN_MASK   (0x000FFFFF)
153 #define WORD2_TRACE_MASK       (0x03f00000)
154 #define WORD2_SEC_COUNT_MASK   (0x0c000000)
155 
156 #define WORD2_TRACE_SHIFT      (20)
157 #define WORD2_SEC_COUNT_SHIFT  (26)
158 
159 #define WORD3_SENDER_MASK      (0x0000FFFF)
160 #define WORD3_RECEIVER_MASK    (0xFFFF0000)
161 
162 #define WORD3_RECEIVER_SHIFT   (16)
163 
164 inline
165 Uint32
getByteOrder(const Uint32 & word1)166 Protocol6::getByteOrder(const Uint32 & word1){
167   return word1 & 1;
168 }
169 
170 inline
171 Uint32
getCompressed(const Uint32 & word1)172 Protocol6::getCompressed(const Uint32 & word1){
173   return (word1 & WORD1_COMPRESSED_MASK) >> WORD1_COMPRESSED_SHIFT;
174 }
175 
176 inline
177 Uint32
getSignalIdIncluded(const Uint32 & word1)178 Protocol6::getSignalIdIncluded(const Uint32 & word1){
179   return (word1 & WORD1_SIGNALID_MASK) >> WORD1_SIGNALID_SHIFT;
180 }
181 
182 inline
183 Uint32
getCheckSumIncluded(const Uint32 & word1)184 Protocol6::getCheckSumIncluded(const Uint32 & word1){
185   return (word1 & WORD1_CHECKSUM_MASK) >> WORD1_CHECKSUM_SHIFT;
186 }
187 
188 inline
189 Uint32
getMessageLength(const Uint32 & word1)190 Protocol6::getMessageLength(const Uint32 & word1){
191   return (word1 & WORD1_MESSAGELEN_MASK) >> WORD1_MESSAGELEN_SHIFT;
192 }
193 
194 inline
195 Uint32
getPrio(const Uint32 & word1)196 Protocol6::getPrio(const Uint32 & word1){
197   return (word1 & WORD1_PRIO_MASK) >> WORD1_PRIO_SHIFT;
198 }
199 
200 inline
201 void
setByteOrder(Uint32 & word1,Uint32 byteOrder)202 Protocol6::setByteOrder(Uint32 & word1, Uint32 byteOrder){
203   Uint32 tmp = byteOrder;
204   tmp |= (tmp << 7);
205   tmp |= (tmp << 24);
206   word1 |= (tmp & WORD1_BYTEORDER_MASK);
207 }
208 
209 inline
210 void
setCompressed(Uint32 & word1,Uint32 compressed)211 Protocol6::setCompressed(Uint32 & word1, Uint32 compressed){
212   word1 |= ((compressed << WORD1_COMPRESSED_SHIFT) & WORD1_COMPRESSED_MASK);
213 }
214 
215 inline
216 void
setSignalIdIncluded(Uint32 & word1,Uint32 signalId)217 Protocol6::setSignalIdIncluded(Uint32 & word1, Uint32 signalId){
218   word1 |= ((signalId << WORD1_SIGNALID_SHIFT) & WORD1_SIGNALID_MASK);
219 }
220 
221 inline
222 void
setCheckSumIncluded(Uint32 & word1,Uint32 checkSum)223 Protocol6::setCheckSumIncluded(Uint32 & word1, Uint32 checkSum){
224   word1 |= ((checkSum << WORD1_CHECKSUM_SHIFT) & WORD1_CHECKSUM_MASK);
225 }
226 
227 inline
228 void
setMessageLength(Uint32 & word1,Uint32 messageLen)229 Protocol6::setMessageLength(Uint32 & word1, Uint32 messageLen){
230   word1 |= ((messageLen << WORD1_MESSAGELEN_SHIFT) & WORD1_MESSAGELEN_MASK);
231 }
232 
233 inline
234 void
setPrio(Uint32 & word1,Uint32 prio)235 Protocol6::setPrio(Uint32 & word1, Uint32 prio){
236   word1 |= ((prio << WORD1_PRIO_SHIFT) & WORD1_PRIO_MASK);
237 }
238 
239 inline
240 void
createSignalHeader(SignalHeader * const dst,const Uint32 & word1,const Uint32 & word2,const Uint32 & word3)241 Protocol6::createSignalHeader(SignalHeader * const dst,
242 			      const Uint32 & word1,
243 			      const Uint32 & word2,
244 			      const Uint32 & word3){
245 
246   Uint32 signal_len = (word1 & WORD1_SIGNAL_LEN_MASK)>> WORD1_SIGNAL_LEN_SHIFT;
247   Uint32 fragInfo1  = (word1 & WORD1_FRAG_INF_MASK) >> (WORD1_FRAG_INF_SHIFT-1);
248   Uint32 fragInfo2  = (word1 & WORD1_FRAG_INF2_MASK) >> (WORD1_FRAG_INF2_SHIFT);
249   Uint32 trace      = (word2 & WORD2_TRACE_MASK) >> WORD2_TRACE_SHIFT;
250   Uint32 verid_gsn  = (word2 & WORD2_VERID_GSN_MASK);
251   Uint32 secCount   = (word2 & WORD2_SEC_COUNT_MASK) >> WORD2_SEC_COUNT_SHIFT;
252 
253   dst->theTrace              = trace;
254   dst->m_noOfSections        = secCount;
255   dst->m_fragmentInfo        = fragInfo1 | fragInfo2;
256 
257   dst->theLength             = signal_len;
258   dst->theVerId_signalNumber = verid_gsn;
259 
260   Uint32 sBlockNum  = (word3 & WORD3_SENDER_MASK);
261   Uint32 rBlockNum  = (word3 & WORD3_RECEIVER_MASK) >> WORD3_RECEIVER_SHIFT;
262 
263   dst->theSendersBlockRef      = sBlockNum;
264   dst->theReceiversBlockNumber = rBlockNum;
265 }
266 
267 inline
268 void
createProtocol6Header(Uint32 & word1,Uint32 & word2,Uint32 & word3,const SignalHeader * const src)269 Protocol6::createProtocol6Header(Uint32 & word1,
270 				 Uint32 & word2,
271 				 Uint32 & word3,
272 				 const SignalHeader * const src){
273   const Uint32 signal_len = src->theLength;
274   const Uint32 fragInfo   = src->m_fragmentInfo;
275   const Uint32 fragInfo1 = (fragInfo & 2);
276   const Uint32 fragInfo2 = (fragInfo & 1);
277 
278   const Uint32 trace      = src->theTrace;
279   const Uint32 verid_gsn  = src->theVerId_signalNumber;
280   const Uint32 secCount   = src->m_noOfSections;
281 
282   word1 |= ((signal_len << WORD1_SIGNAL_LEN_SHIFT) & WORD1_SIGNAL_LEN_MASK);
283   word1 |= ((fragInfo1 << (WORD1_FRAG_INF_SHIFT-1)) & WORD1_FRAG_INF_MASK);
284   word1 |= ((fragInfo2 << WORD1_FRAG_INF2_SHIFT) & WORD1_FRAG_INF2_MASK);
285 
286   word2 |= ((trace << WORD2_TRACE_SHIFT) & WORD2_TRACE_MASK);
287   word2 |= (verid_gsn & WORD2_VERID_GSN_MASK);
288   word2 |= ((secCount << WORD2_SEC_COUNT_SHIFT) & WORD2_SEC_COUNT_MASK);
289 
290   Uint32 sBlockNum  = src->theSendersBlockRef ;
291   Uint32 rBlockNum  = src->theReceiversBlockNumber ;
292 
293   word3 |= (sBlockNum & WORD3_SENDER_MASK);
294   word3 |= ((rBlockNum << WORD3_RECEIVER_SHIFT) & WORD3_RECEIVER_MASK);
295 }
296 
297 // Define of TransporterInternalDefinitions_H
298 #endif
299