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