1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2010-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /******************************* DisplayPort *******************************\
25 * *
26 * Module: dp_messagecodings.cpp *
27 * Encoding routines for various messages *
28 * *
29 \***************************************************************************/
30 #include "dp_internal.h"
31 #include "dp_messagecodings.h"
32 #include "dp_auxdefs.h"
33
34 using namespace DisplayPort;
35
36 //
37 // LINK_ADDRESS 0x1
38 //
set(const Address & target)39 void LinkAddressMessage::set(const Address & target)
40 {
41 clear();
42 BitStreamWriter writer(&encodedMessage.buffer, 0);
43
44 //
45 // Write request identifier
46 //
47 writer.write(0 /*zero*/, 1);
48 writer.write(requestIdentifier, 7);
49
50 encodedMessage.isPathMessage = false;
51 encodedMessage.isBroadcast = false;
52 encodedMessage.address = target;
53 }
54
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)55 ParseResponseStatus LinkAddressMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
56 {
57 DisplayPort::extractGUID(reader, &reply.guid);
58 reader->readOrDefault(4 /*zeroes*/, 0);
59 reply.numberOfPorts = reader->readOrDefault(4 /*Number_Of_Ports*/, 0xF);
60
61 for (unsigned i = 0; i < reply.numberOfPorts; i++)
62 {
63 reply.res[i].isInputPort = !!reader->readOrDefault(1 /*Input_Port*/, 1);
64 reply.res[i].peerDeviceType = (PeerDevice) reader->readOrDefault(3 /*Peer_Device_Type*/, 0x0);
65 reply.res[i].portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
66 reply.res[i].hasMessaging = !!reader->readOrDefault(1 /*Messaging_Capability_Status*/, 0x1);
67 reply.res[i].dpPlugged = !!reader->readOrDefault(1 /*DisplayPort_Device_Plug_Status*/, 0x1);
68
69 if (reply.res[i].isInputPort == false)
70 {
71 reply.res[i].legacyPlugged = !!reader->readOrDefault(1 /*Legacy_Device_Plug_Status*/, 0x1);
72
73 reader->readOrDefault(5 /*zeroes*/, 0x0);
74
75 unsigned ver = reader->readOrDefault(8/*DPCD_Revision*/, 0);
76 reply.res[i].dpcdRevisionMajor = ver >> 4;
77 reply.res[i].dpcdRevisionMinor = ver & 0xF;
78 DisplayPort::extractGUID(reader, &reply.res[i].peerGUID);
79 reply.res[i].SDPStreams = reader->readOrDefault(4 /*Number_SDP_Streams*/, 0xF);
80 reply.res[i].SDPStreamSinks = reader->readOrDefault(4 /*Number_SDP_Stream_Sinks*/, 0xF);
81 }
82 else
83 {
84 reader->readOrDefault(6 /*zeroes*/, 0x0);
85 }
86 }
87
88 return ParseResponseSuccess;
89 }
90
91 //
92 // CONNECTION_STATUS_NOTIFY 0x2
93 //
ConnStatusNotifyMessage(MessageReceiverEventSink * sink)94 ConnStatusNotifyMessage::ConnStatusNotifyMessage(MessageReceiverEventSink * sink)
95 : MessageReceiver(sink, NV_DP_SBMSG_REQUEST_ID_CONNECTION_STATUS_NOTIFY /*request id*/)
96 {
97 }
98
processByType(EncodedMessage * message,BitStreamReader * reader)99 bool ConnStatusNotifyMessage::processByType(EncodedMessage * message, BitStreamReader * reader)
100 {
101 // read the request body
102 request.port = reader->readOrDefault(4/*Port_Number*/, 0xF);
103 reader->readOrDefault(4/*zeroes*/, 0);
104 bool status = DisplayPort::extractGUID(reader/*GUID of the originating branch device*/, &request.guid);
105 reader->readOrDefault(1/*zero*/, 0);
106 request.legacyPlugged = !!reader->readOrDefault(1/*Legacy_Device_Plug_Status*/, 0);
107 request.devicePlugged = !!reader->readOrDefault(1/*DisplayPort_Device_Plug_Status*/, 0);
108 request.messagingCapability = !!reader->readOrDefault(1/*Messaging_Capability_Status*/, 0);
109 request.isInputPort = !!reader->readOrDefault(1/*Input_Port*/, 0);
110 request.peerDeviceType = (PeerDevice) reader->readOrDefault(3/*Peer_Device_Type*/, 0);
111
112 // action will be implemented by evensink
113 this->sink->messageProcessed(this);
114 return status;
115 }
116
117 //
118 // GENERIC_UP_REPLY 0xnn
119 //
set(const Address & target,bool bReplyIsNack,bool bBroadcast,bool bPath)120 void GenericUpReplyMessage::set(const Address & target,
121 bool bReplyIsNack,
122 bool bBroadcast,
123 bool bPath)
124 {
125 clear();
126 BitStreamWriter writer(&encodedMessage.buffer, 0);
127
128 writer.write(bReplyIsNack?1:0, 1);
129 writer.write(requestIdentifier, 7);
130
131 encodedMessage.isPathMessage = bPath;
132 encodedMessage.isBroadcast = bBroadcast;
133 encodedMessage.address = target;
134 }
135
GenericUpReplyMessage(unsigned requestId,bool bReplyIsNack,bool bBroadcast,bool bPath)136 GenericUpReplyMessage::GenericUpReplyMessage(unsigned requestId, bool bReplyIsNack, bool bBroadcast, bool bPath)
137 : Message(requestId, NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
138 {
139 BitStreamWriter writer(&encodedMessage.buffer, 0);
140
141 //
142 // Write request identifier
143 //
144 writer.write(bReplyIsNack?1:0, 1);
145 writer.write(requestId, 7);
146
147 encodedMessage.isPathMessage = bPath;
148 encodedMessage.isBroadcast = bBroadcast;
149 }
150
GenericUpReplyMessage(const Address & target,unsigned requestId,bool bReplyIsNack,bool bBroadcast,bool bPath)151 GenericUpReplyMessage::GenericUpReplyMessage(const Address & target, unsigned requestId, bool bReplyIsNack, bool bBroadcast, bool bPath)
152 : Message(requestId, NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
153 {
154 BitStreamWriter writer(&encodedMessage.buffer, 0);
155
156 //
157 // Write request identifier
158 //
159 writer.write(bReplyIsNack?1:0, 1);
160 writer.write(requestId, 7);
161
162 encodedMessage.isPathMessage = bPath;
163 encodedMessage.isBroadcast = bBroadcast;
164 encodedMessage.address = target;
165 }
166
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)167 ParseResponseStatus GenericUpReplyMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
168 {
169 //
170 // we are not expecting any replies here
171 // Since the corresponding post for this kind of message is of reply type;
172 // message manager won't queue an awaiting down reply for the same.
173 //
174 DP_ASSERT(0 && "We shouldn't be here!!");
175 return ParseResponseSuccess;
176 }
177
178 //
179 // CLEAR_PAYLOAD_ID_TABLE 0x14
180 //
ClearPayloadIdTableMessage()181 ClearPayloadIdTableMessage::ClearPayloadIdTableMessage()
182 : Message(NV_DP_SBMSG_REQUEST_ID_CLEAR_PAYLOAD_ID_TABLE /* request id */, NV_DP_SBMSG_PRIORITY_LEVEL_1)
183 {
184 BitStreamWriter writer(&encodedMessage.buffer, 0);
185
186 // Write request identifier
187 writer.write(0/*zero*/, 1);
188 writer.write(requestIdentifier, 7);
189
190 encodedMessage.isPathMessage = true;
191 encodedMessage.isBroadcast = true;
192 encodedMessage.address = Address();
193 }
194
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)195 ParseResponseStatus ClearPayloadIdTableMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
196 {
197 return ParseResponseSuccess;
198 }
199
parseResponse(EncodedMessage * message)200 ParseResponseStatus ClearPayloadIdTableMessage::parseResponse(EncodedMessage * message)
201 {
202 sink->messageCompleted(this);
203 return ParseResponseSuccess;
204 }
205
206 //
207 // ENUM_PATH_RESOURCES 0x10
208 //
EnumPathResMessage(const Address & target,unsigned port,bool point)209 EnumPathResMessage::EnumPathResMessage(const Address & target, unsigned port, bool point)
210 : Message(NV_DP_SBMSG_REQUEST_ID_ENUM_PATH_RESOURCES /* request identifier */,
211 NV_DP_SBMSG_PRIORITY_LEVEL_4)
212 {
213 BitStreamWriter writer(&encodedMessage.buffer, 0);
214
215 // Write request identifier
216 writer.write(0/*zereo*/, 1);
217 writer.write(requestIdentifier, 7);
218 writer.write(port, 4);
219 writer.write(0/*zeroes*/, 4);
220
221 encodedMessage.isPathMessage = !point;
222 encodedMessage.isBroadcast = false;
223 encodedMessage.address = target;
224 sinkPort = port;
225 dpMemZero(&reply, sizeof(reply));
226 }
227
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)228 ParseResponseStatus EnumPathResMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
229 {
230 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
231 reply.availableStreams = reader->readOrDefault(3 /*Available_Streams*/, 0);
232 reply.bFECCapability = (reader->readOrDefault(1 /*FEC*/, 0x0) == 1) ? true : false;
233 reply.TotalPBN = reader->readOrDefault(16 /*PBN*/, 0xFFFF);
234 reply.FreePBN = reader->readOrDefault(16 /*PBN*/, 0xFFFF);
235
236 if (this->getSinkPort() != reply.portNumber)
237 return ParseResponseWrong;
238
239 return ParseResponseSuccess;
240 }
241
242 //
243 // ALLOCATE_PAYLOAD 0x11
244 //
set(const Address & target,unsigned port,unsigned nSDPStreams,unsigned vcPayloadId,unsigned PBN,unsigned * SDPStreamSink,bool entirePath)245 void AllocatePayloadMessage::set
246 (
247 const Address & target,
248 unsigned port,
249 unsigned nSDPStreams,
250 unsigned vcPayloadId,
251 unsigned PBN,
252 unsigned* SDPStreamSink,
253 bool entirePath
254 )
255 {
256 clear();
257 BitStreamWriter writer(&encodedMessage.buffer, 0);
258
259 // Write request identifier
260 writer.write(0/*zero*/, 1);
261 writer.write(requestIdentifier, 7);
262
263 DP_ASSERT(SDPStreamSink || (!nSDPStreams));
264
265 // Write message request body
266 writer.write(port, 4);
267 writer.write(nSDPStreams, 4);
268 writer.write(0/*zero*/, 1);
269 writer.write(vcPayloadId, 7);
270 writer.write(PBN, 16);
271 for (unsigned i=0; i<nSDPStreams; i++)
272 {
273 writer.write(SDPStreamSink[i], 4);
274 }
275
276 // emit 0s until byte aligned.
277 writer.align(8);
278
279 encodedMessage.isPathMessage = entirePath;
280 encodedMessage.isBroadcast = false;
281 encodedMessage.address = target;
282 sinkPort = port;
283 }
284
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)285 ParseResponseStatus AllocatePayloadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
286 {
287 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
288 reader->readOrDefault(5 /*zeroes*/, 0);
289 reply.virtualChannelPayloadId = reader->readOrDefault(7 /*Virtual_Channel_Payload_Identifier*/, 0x0);
290 reply.PBN = reader->readOrDefault(16 /*PBN*/, 0xFFFF);
291
292 if (this->getSinkPort() != reply.portNumber)
293 return ParseResponseWrong;
294
295 return ParseResponseSuccess;
296 }
297 //
298 // QUERY_PAYLOAD 0x12
299 //
QueryPayloadMessage(const Address & target,unsigned port,unsigned vcPayloadId)300 QueryPayloadMessage::QueryPayloadMessage
301 (
302 const Address & target,
303 unsigned port,
304 unsigned vcPayloadId
305 )
306 : Message(NV_DP_SBMSG_REQUEST_ID_QUERY_PAYLOAD /* request identifier*/,
307 NV_DP_SBMSG_PRIORITY_LEVEL_DEFAULT)
308 {
309 BitStreamWriter writer(&encodedMessage.buffer, 0);
310
311
312 // Write request identifier
313 writer.write(0 /*zero*/, 1);
314 writer.write(requestIdentifier, 7);
315
316 // Write message request
317 writer.write(port, 4);
318 writer.write(0 /*zeroes*/, 5);
319 writer.write(vcPayloadId, 7);
320
321 encodedMessage.isPathMessage = false;
322 encodedMessage.isBroadcast = false;
323 encodedMessage.address = target;
324 sinkPort = port;
325 dpMemZero(&reply, sizeof(reply));
326 }
327
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)328 ParseResponseStatus QueryPayloadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
329 {
330 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
331 reader->readOrDefault(4 /*zeroes*/, 0);
332 reply.allocatedPBN = reader->readOrDefault(16 /*Allocated_PBN*/, 0xFFFF);
333
334 if (this->getSinkPort() != reply.portNumber)
335 return ParseResponseWrong;
336
337 return ParseResponseSuccess;
338 }
339
340
341 //
342 // RESOURCE_STATUS_NOTIFY 0x13
343 //
344
ResStatusNotifyMessage(MessageReceiverEventSink * sink)345 ResStatusNotifyMessage::ResStatusNotifyMessage(MessageReceiverEventSink * sink)
346 : MessageReceiver(sink, NV_DP_SBMSG_REQUEST_ID_RESOURCE_STATUS_NOTIFY /*request id*/)
347 {
348 dpMemZero(&request, sizeof(request));
349 }
350
processByType(EncodedMessage * message,BitStreamReader * reader)351 bool ResStatusNotifyMessage::processByType(EncodedMessage * message, BitStreamReader * reader)
352 {
353 bool status;
354
355 // read the request body
356 request.port = reader->readOrDefault(4 /*Port_Number*/, 0xF);
357 request.availableStreams = reader->readOrDefault(3 /*Available_Streams*/, 0);
358 request.bFECCapability = reader->readOrDefault(1 /*FEC Capability*/, 0);
359 status = DisplayPort::extractGUID(reader, &request.guid);
360 request.PBN = reader->readOrDefault(16/*Available_PBN*/, 0);
361
362 // action will be implemented by evensink
363 this->sink->messageProcessed(this);
364 return status;
365 }
366
367 //
368 // REMOTE_DPCD_READ 0x20
369 //
set(const Address & target,unsigned port,unsigned dpcdAddress,unsigned nBytesToRead)370 void RemoteDpcdReadMessage::set
371 (
372 const Address & target,
373 unsigned port,
374 unsigned dpcdAddress,
375 unsigned nBytesToRead
376 )
377 {
378 clear();
379
380 BitStreamWriter writer(&encodedMessage.buffer, 0);
381
382 // Write request identifier
383 writer.write(0/*zero*/, 1);
384 writer.write(requestIdentifier, 7);
385
386 // write request data
387 writer.write(port, 4);
388 writer.write(dpcdAddress, 20);
389 writer.write(nBytesToRead, 8);
390
391 encodedMessage.isPathMessage = false;
392 encodedMessage.isBroadcast = false;
393 encodedMessage.address = target;
394 sinkPort = port;
395 }
396
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)397 ParseResponseStatus RemoteDpcdReadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
398 {
399 reader->readOrDefault(4 /*zeroes*/, 0);
400 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
401 reply.numBytesReadDPCD = reader->readOrDefault(8 /*Num_Of_Bytes_Read*/, 0x0);
402 for (unsigned i=0; i<reply.numBytesReadDPCD; i++)
403 {
404 reply.readData[i] = (NvU8)reader->readOrDefault(8 /*data*/, 0x0);
405 }
406
407 if (this->getSinkPort() != reply.portNumber)
408 return ParseResponseWrong;
409
410 return ParseResponseSuccess;
411 }
412
413 //
414 // REMOTE_DPCD_WRITE 0x21
415 //
set(const Address & target,unsigned port,unsigned dpcdAddress,unsigned nBytesToWrite,const NvU8 * writeData)416 void RemoteDpcdWriteMessage::set
417 (
418 const Address & target,
419 unsigned port,
420 unsigned dpcdAddress,
421 unsigned nBytesToWrite,
422 const NvU8 * writeData
423 )
424 {
425 clear();
426 BitStreamWriter writer(&encodedMessage.buffer, 0);
427
428 DP_ASSERT(writeData || (!nBytesToWrite));
429
430 // Write request identifier
431 writer.write(0/*zero*/, 1);
432 writer.write(requestIdentifier, 7);
433
434 // write request data
435 writer.write(port, 4);
436 writer.write(dpcdAddress, 20);
437 writer.write(nBytesToWrite, 8);
438
439 for (unsigned i=0; i<nBytesToWrite; i++)
440 {
441 writer.write(writeData[i], 8);
442 }
443
444 encodedMessage.isPathMessage = false;
445 encodedMessage.isBroadcast = false;
446 encodedMessage.address = target;
447 sinkPort = port;
448 }
449
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)450 ParseResponseStatus RemoteDpcdWriteMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
451 {
452 reader->readOrDefault(4 /*zeroes*/, 0);
453 unsigned portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
454
455 DP_ASSERT(portNumber == this->sinkPort);
456 DP_USED(portNumber);
457
458 if (this->getSinkPort() != portNumber)
459 return ParseResponseWrong;
460
461 return ParseResponseSuccess;
462 }
463
464 //
465 // REMOTE_I2C_READ 0x22
466 //
set(const Address & target,unsigned nWriteTransactions,unsigned port,I2cWriteTransaction * transactions,unsigned readI2cDeviceId,unsigned nBytesToRead)467 void RemoteI2cReadMessage::set
468 (
469 const Address & target,
470 unsigned nWriteTransactions,
471 unsigned port,
472 I2cWriteTransaction* transactions,
473 unsigned readI2cDeviceId,
474 unsigned nBytesToRead
475 )
476 {
477 clear();
478
479 BitStreamWriter writer(&encodedMessage.buffer, 0);
480
481 DP_ASSERT(transactions || (!nWriteTransactions));
482
483 // Write request identifier
484 writer.write(0 /*zero*/, 1);
485 writer.write(requestIdentifier, 7);
486
487 // write request specific data
488 writer.write(port, 4);
489 writer.write(0/*zeroes*/, 2);
490 writer.write(nWriteTransactions, 2);
491
492 for (unsigned i=0; i<nWriteTransactions; i++)
493 {
494 writer.write(0/*zero*/, 1);
495 writer.write(transactions[i].WriteI2cDeviceId, 7);
496 writer.write(transactions[i].NumBytes, 8);
497 for(unsigned j=0; j<transactions[i].NumBytes; j++)
498 {
499 writer.write(transactions[i].I2cData[j], 8);
500 }
501 writer.write(0/*zeroes*/, 3);
502 writer.write(transactions[i].NoStopBit ? 1 : 0, 1);
503 writer.write(transactions[i].I2cTransactionDelay, 4);
504 }
505 writer.write(0/*zero*/, 1);
506 writer.write(readI2cDeviceId, 7);
507 writer.write(nBytesToRead, 8);
508
509 encodedMessage.isPathMessage = false;
510 encodedMessage.isBroadcast = false;
511 encodedMessage.address = target;
512 sinkPort = port;
513 }
514
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)515 ParseResponseStatus RemoteI2cReadMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
516 {
517 reader->readOrDefault(4 /*zeroes*/, 0);
518 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
519 reply.numBytesReadI2C = reader->readOrDefault(8 /*Num_Of_Bytes_Read*/, 0x0);
520 for (unsigned i=0; i<reply.numBytesReadI2C; i++)
521 {
522 reply.readData[i] = (NvU8)reader->readOrDefault(8 /*data*/, 0x0);
523 }
524
525 if (this->getSinkPort() != reply.portNumber)
526 return ParseResponseWrong;
527
528 return ParseResponseSuccess;
529 }
530
531 //
532 // REMOTE_I2C_WRITE 0x23
533 //
set(const Address & target,unsigned port,unsigned writeI2cDeviceId,unsigned nBytesToWrite,unsigned char * writeData)534 void RemoteI2cWriteMessage::set
535 (
536 const Address & target,
537 unsigned port,
538 unsigned writeI2cDeviceId,
539 unsigned nBytesToWrite,
540 unsigned char* writeData
541 )
542 {
543 clear();
544
545 BitStreamWriter writer(&encodedMessage.buffer, 0);
546
547 DP_ASSERT(writeData || (!nBytesToWrite));
548
549 // Write request identifier
550 writer.write(0 /*zero*/, 1);
551 writer.write(requestIdentifier, 7);
552
553 // write request data
554 writer.write(port, 4);
555 writer.write(0/*zero*/, 5);
556 writer.write(writeI2cDeviceId, 7);
557 writer.write(nBytesToWrite, 8);
558
559 for (unsigned i=0; i<nBytesToWrite; i++)
560 {
561 writer.write(writeData[i], 8);
562 }
563
564 encodedMessage.isPathMessage = false;
565 encodedMessage.isBroadcast = false;
566 encodedMessage.address = target;
567 sinkPort = port;
568 }
569
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)570 ParseResponseStatus RemoteI2cWriteMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
571 {
572 reader->readOrDefault(4 /*zeroes*/, 0);
573 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
574
575 if (this->getSinkPort() != reply.portNumber)
576 return ParseResponseWrong;
577
578 return ParseResponseSuccess;
579 }
580 //
581 // POWER_UP_PHY 0x24
582 //
set(const Address & target,unsigned port,bool entirePath)583 void PowerUpPhyMessage::set
584 (
585 const Address & target,
586 unsigned port,
587 bool entirePath
588 )
589 {
590 clear();
591
592 BitStreamWriter writer(&encodedMessage.buffer, 0);
593
594 // Write request identifier
595 writer.write(0 /*zero*/, 1);
596 writer.write(requestIdentifier, 7);
597
598 // write request specific data
599 writer.write(port, 4);
600 writer.write(0 /*zero*/, 4);
601
602 encodedMessage.isPathMessage = entirePath;
603 encodedMessage.isBroadcast = false;
604 encodedMessage.address = target;
605 sinkPort = port;
606 }
607
608 //
609 // POWER_DOWN_PHY 0x25
610 //
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)611 ParseResponseStatus PowerUpPhyMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
612 {
613 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
614 reader->readOrDefault(4 /*zeroes*/, 0);
615
616 if (this->getSinkPort() != reply.portNumber)
617 return ParseResponseWrong;
618
619 return ParseResponseSuccess;
620 }
621
set(const Address & target,unsigned port,bool entirePath)622 void PowerDownPhyMessage::set
623 (
624 const Address & target,
625 unsigned port,
626 bool entirePath
627 )
628 {
629 BitStreamWriter writer(&encodedMessage.buffer, 0);
630
631 // Write request identifier
632 writer.write(0 /*zero*/, 1);
633 writer.write(requestIdentifier, 7);
634
635 // write request specific data
636 writer.write(port, 4);
637 writer.write(0/*zeros*/, 4);
638
639 encodedMessage.isPathMessage = entirePath;
640 encodedMessage.isBroadcast = false;
641 encodedMessage.address = target;
642 sinkPort = port;
643 }
644
parseResponseAck(EncodedMessage * message,BitStreamReader * reader)645 ParseResponseStatus PowerDownPhyMessage::parseResponseAck(EncodedMessage * message, BitStreamReader * reader)
646 {
647 reply.portNumber = reader->readOrDefault(4 /*Port_Number*/, 0xF);
648 reader->readOrDefault(4 /*zeroes*/, 0);
649
650 if (this->getSinkPort() != reply.portNumber)
651 return ParseResponseWrong;
652
653 return ParseResponseSuccess;
654 }
655
656 //
657 // SINK_EVENT_NOTIFY 0x30
658 //
659
SinkEventNotifyMessage(MessageReceiverEventSink * sink,unsigned requestId)660 SinkEventNotifyMessage::SinkEventNotifyMessage(MessageReceiverEventSink * sink, unsigned requestId)
661 : MessageReceiver(sink, 0x30 /*request id*/)
662 {
663 }
664
processByType(EncodedMessage * message,BitStreamReader * reader)665 bool SinkEventNotifyMessage::processByType(EncodedMessage * message, BitStreamReader * reader)
666 {
667 return true;
668 }
669
670
I2cWriteTransaction(unsigned WriteI2cDeviceId,unsigned NumBytes,unsigned char * buffer,bool NoStopBit,unsigned I2cTransactionDelay)671 I2cWriteTransaction::I2cWriteTransaction
672 (
673 unsigned WriteI2cDeviceId,
674 unsigned NumBytes,
675 unsigned char * buffer,
676 bool NoStopBit,
677 unsigned I2cTransactionDelay
678 )
679 {
680 this->WriteI2cDeviceId = WriteI2cDeviceId;
681 this->NumBytes = NumBytes;
682 this->NoStopBit = NoStopBit;
683 this->I2cTransactionDelay = I2cTransactionDelay;
684 this->I2cData = buffer;
685 }
686
I2cWriteTransaction()687 I2cWriteTransaction::I2cWriteTransaction():
688 WriteI2cDeviceId(0), NumBytes(0), I2cData(0), NoStopBit(0), I2cTransactionDelay(0)
689 {
690 }
691
692