Browse Source

Time out on chunked extended messages

Now when a part of a chunked extended message is received, the
ChunkingNotSupportedTimer is run.  When it times out, we transition to
PE_SNK_Send_Not_Supported.  Just like the spec says.
Clara Hobbs 6 years ago
parent
commit
f62ca97cc6
3 changed files with 75 additions and 3 deletions
  1. 30
    0
      lib/include/pd.h
  2. 8
    2
      lib/include/pdb_msg.h
  3. 37
    1
      lib/src/policy_engine.c

+ 30
- 0
lib/include/pd.h View File

114
 #define PD_NUMOBJ_GET(msg) (((msg)->hdr & PD_HDR_NUMOBJ) >> PD_HDR_NUMOBJ_SHIFT)
114
 #define PD_NUMOBJ_GET(msg) (((msg)->hdr & PD_HDR_NUMOBJ) >> PD_HDR_NUMOBJ_SHIFT)
115
 
115
 
116
 
116
 
117
+/*
118
+ * PD Extended Message Header
119
+ */
120
+#define PD_EXTHDR_DATA_SIZE_SHIFT 0
121
+#define PD_EXTHDR_DATA_SIZE (0x1FF << PD_EXTHDR_DATA_SIZE_SHIFT)
122
+#define PD_EXTHDR_REQUEST_CHUNK_SHIFT 10
123
+#define PD_EXTHDR_REQUEST_CHUNK (1 << PD_EXTHDR_REQUEST_CHUNK_SHIFT)
124
+#define PD_EXTHDR_CHUNK_NUMBER_SHIFT 11
125
+#define PD_EXTHDR_CHUNK_NUMBER (0xF << PD_EXTHDR_CHUNK_NUMBER_SHIFT)
126
+#define PD_EXTHDR_CHUNKED_SHIFT 15
127
+#define PD_EXTHDR_CHUNKED (1 << PD_EXTHDR_CHUNKED_SHIFT)
128
+
129
+/* Data size */
130
+#define PD_DATA_SIZE(n) (((n) << PD_EXTHDR_DATA_SIZE_SHIFT) & PD_EXTHDR_DATA_SIZE)
131
+#define PD_DATA_SIZE_GET(msg) (((msg)->exthdr & PD_EXTHDR_DATA_SIZE) >> PD_EXTHDR_DATA_SIZE_SHIFT)
132
+
133
+/* Chunk number */
134
+#define PD_CHUNK_NUMBER(n) (((n) << PD_EXTHDR_CHUNK_NUMBER_SHIFT) & PD_EXTHDR_CHUNK_NUMBER)
135
+#define PD_CHUNK_NUMBER_GET(msg) (((msg)->exthdr & PD_EXTHDR_CHUNK_NUMBER) >> PD_EXTHDR_CHUNK_NUMBER_SHIFT)
136
+
137
+
117
 /*
138
 /*
118
  * PD Power Data Object
139
  * PD Power Data Object
119
  */
140
  */
216
  * Where a range is specified, the middle of the range (rounded down to the
237
  * Where a range is specified, the middle of the range (rounded down to the
217
  * nearest millisecond) is used.
238
  * nearest millisecond) is used.
218
  */
239
  */
240
+#define PD_T_CHUNKING_NOT_SUPPORTED MS2ST(45)
219
 #define PD_T_HARD_RESET_COMPLETE MS2ST(4)
241
 #define PD_T_HARD_RESET_COMPLETE MS2ST(4)
220
 #define PD_T_PS_TRANSITION MS2ST(500)
242
 #define PD_T_PS_TRANSITION MS2ST(500)
221
 #define PD_T_SENDER_RESPONSE MS2ST(27)
243
 #define PD_T_SENDER_RESPONSE MS2ST(27)
231
 #define PD_N_HARD_RESET_COUNT 2
253
 #define PD_N_HARD_RESET_COUNT 2
232
 
254
 
233
 
255
 
256
+/*
257
+ * Value parameters
258
+ */
259
+#define PD_MAX_EXT_MSG_LEN 260
260
+#define PD_MAX_EXT_MSG_CHUNK_LEN 26
261
+#define PD_MAX_EXT_MSG_LEGACY_LEN 26
262
+
263
+
234
 /*
264
 /*
235
  * Unit conversions
265
  * Unit conversions
236
  *
266
  *

+ 8
- 2
lib/include/pdb_msg.h View File

27
 /*
27
 /*
28
  * PD message union
28
  * PD message union
29
  *
29
  *
30
- * This can be safely read from or written to in either form without any
30
+ * This can be safely read from or written to in any form without any
31
  * transformations because everything in the system is little-endian.
31
  * transformations because everything in the system is little-endian.
32
  *
32
  *
33
  * Two bytes of padding are required at the start to prevent problems due to
33
  * Two bytes of padding are required at the start to prevent problems due to
42
     struct {
42
     struct {
43
         uint8_t _pad2[2];
43
         uint8_t _pad2[2];
44
         uint16_t hdr;
44
         uint16_t hdr;
45
-        uint32_t obj[7];
45
+        union {
46
+            uint32_t obj[7];
47
+            struct {
48
+                uint16_t exthdr;
49
+                uint8_t data[26];
50
+            };
51
+        };
46
     } __attribute__((packed));
52
     } __attribute__((packed));
47
 };
53
 };
48
 
54
 

+ 37
- 1
lib/src/policy_engine.c View File

42
     PESinkSoftReset,
42
     PESinkSoftReset,
43
     PESinkSendSoftReset,
43
     PESinkSendSoftReset,
44
     PESinkSendNotSupported,
44
     PESinkSendNotSupported,
45
+    PESinkChunkReceived,
45
     PESinkSourceUnresponsive
46
     PESinkSourceUnresponsive
46
 };
47
 };
47
 
48
 
404
                 chPoolFree(&pdb_msg_pool, cfg->pe._message);
405
                 chPoolFree(&pdb_msg_pool, cfg->pe._message);
405
                 cfg->pe._message = NULL;
406
                 cfg->pe._message = NULL;
406
                 return PESinkSoftReset;
407
                 return PESinkSoftReset;
407
-            /* If we got an unknown message, send a soft reset */
408
+            /* PD 3.0 messges */
409
+            } else if ((cfg->pe.hdr_template & PD_HDR_SPECREV) == PD_SPECREV_3_0) {
410
+                /* If the message is a multi-chunk extended message, let it
411
+                 * time out. */
412
+                if ((cfg->pe._message->hdr & PD_HDR_EXT)
413
+                        && (PD_DATA_SIZE_GET(cfg->pe._message) > PD_MAX_EXT_MSG_LEGACY_LEN)) {
414
+                    chPoolFree(&pdb_msg_pool, cfg->pe._message);
415
+                    cfg->pe._message = NULL;
416
+                    return PESinkChunkReceived;
417
+                /* If we got an unknown message, send a soft reset */
418
+                } else {
419
+                    chPoolFree(&pdb_msg_pool, cfg->pe._message);
420
+                    cfg->pe._message = NULL;
421
+                    return PESinkSendSoftReset;
422
+                }
423
+            /* If we got an unknown message, send a soft reset
424
+             *
425
+             * XXX I don't like that this is duplicated. */
408
             } else {
426
             } else {
409
                 chPoolFree(&pdb_msg_pool, cfg->pe._message);
427
                 chPoolFree(&pdb_msg_pool, cfg->pe._message);
410
                 cfg->pe._message = NULL;
428
                 cfg->pe._message = NULL;
633
     return PESinkReady;
651
     return PESinkReady;
634
 }
652
 }
635
 
653
 
654
+static enum policy_engine_state pe_sink_chunk_received(struct pdb_config *cfg)
655
+{
656
+    (void) cfg;
657
+
658
+    /* Wait for tChunkingNotSupported */
659
+    eventmask_t evt = chEvtWaitAnyTimeout(PDB_EVT_PE_RESET,
660
+            PD_T_CHUNKING_NOT_SUPPORTED);
661
+    /* If we got reset signaling, transition to default */
662
+    if (evt & PDB_EVT_PE_RESET) {
663
+        return PESinkTransitionDefault;
664
+    }
665
+
666
+    return PESinkSendNotSupported;
667
+}
668
+
636
 /*
669
 /*
637
  * When Power Delivery is unresponsive, fall back to Type-C Current
670
  * When Power Delivery is unresponsive, fall back to Type-C Current
638
  */
671
  */
717
             case PESinkSendNotSupported:
750
             case PESinkSendNotSupported:
718
                 state = pe_sink_send_not_supported(cfg);
751
                 state = pe_sink_send_not_supported(cfg);
719
                 break;
752
                 break;
753
+            case PESinkChunkReceived:
754
+                state = pe_sink_chunk_received(cfg);
755
+                break;
720
             case PESinkSourceUnresponsive:
756
             case PESinkSourceUnresponsive:
721
                 state = pe_sink_source_unresponsive(cfg);
757
                 state = pe_sink_source_unresponsive(cfg);
722
                 break;
758
                 break;

Loading…
Cancel
Save