Browse Source

Handle Wait and Reject messages better

In the PE_SNK_Select_Capability state, we Shall do some transitions if
we receive a Wait or Reject message.  Now we do.  This creates another
TODO (running SinkRequestTimer in the PE_SNK_Ready state), but this
one's only for a Should, not a Shall.
Clara Hobbs 5 years ago
parent
commit
6d8b6232a7
1 changed files with 29 additions and 1 deletions
  1. 29
    1
      src/policy_engine.c

+ 29
- 1
src/policy_engine.c View File

@@ -49,12 +49,16 @@ enum policy_engine_state {
49 49
 static union pd_msg *policy_engine_message = NULL;
50 50
 /* Whether or not the source capabilities match our required power */
51 51
 static bool capability_match = false;
52
+/* Whether or not we have an explicit contract */
53
+static bool explicit_contract = false;
52 54
 /* Policy Engine thread mailbox */
53 55
 static msg_t pdb_pe_mailbox_queue[PDB_MSG_POOL_SIZE];
54 56
 mailbox_t pdb_pe_mailbox;
55 57
 
56 58
 static enum policy_engine_state pe_sink_startup(void)
57 59
 {
60
+    explicit_contract = false;
61
+
58 62
     /* No need to reset the protocol layer here.  There are two ways into this
59 63
      * state: startup and exiting hard reset.  On startup, the protocol layer
60 64
      * is reset by the startup procedure.  When exiting hard reset, the
@@ -154,8 +158,27 @@ static enum policy_engine_state pe_sink_select_cap(void)
154 158
             chPoolFree(&pdb_msg_pool, policy_engine_message);
155 159
             policy_engine_message = NULL;
156 160
             return PESinkSoftReset;
157
-        /* TODO: Wait and Reject messages should be recognized here */
161
+        /* If the message was Wait or Reject */
162
+        } else if ((PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_REJECT
163
+                    || PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_WAIT)
164
+                && PD_NUMOBJ_GET(policy_engine_message) == 0) {
165
+            /* If we don't have an explicit contract, wait for capabilities */
166
+            if (!explicit_contract) {
167
+                chPoolFree(&pdb_msg_pool, policy_engine_message);
168
+                policy_engine_message = NULL;
169
+                return PESinkWaitCap;
170
+            /* If we do have an explicit contract, go to the ready state */
171
+            } else {
172
+                /* TODO: we should take note if we got here from a Wait
173
+                 * message, because we Should run the SinkRequestTimer in the
174
+                 * Ready state if that's the case. */
175
+                chPoolFree(&pdb_msg_pool, policy_engine_message);
176
+                policy_engine_message = NULL;
177
+                return PESinkReady;
178
+            }
158 179
         } else {
180
+            chPoolFree(&pdb_msg_pool, policy_engine_message);
181
+            policy_engine_message = NULL;
159 182
             return PESinkSendSoftReset;
160 183
         }
161 184
     }
@@ -176,6 +199,9 @@ static enum policy_engine_state pe_sink_transition_sink(void)
176 199
         /* If we got a PS_RDY, handle it */
177 200
         if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_PS_RDY
178 201
                 && PD_NUMOBJ_GET(policy_engine_message) == 0) {
202
+            /* We just finished negotiating an explicit contract */
203
+            explicit_contract = true;
204
+
179 205
             /* Set the output appropriately */
180 206
             if (capability_match) {
181 207
                 pdb_dpm_output_on();
@@ -344,6 +370,8 @@ static enum policy_engine_state pe_sink_hard_reset(void)
344 370
 
345 371
 static enum policy_engine_state pe_sink_transition_default(void)
346 372
 {
373
+    explicit_contract = false;
374
+
347 375
     /* Tell the DPM to turn off the output */
348 376
     pdb_dpm_output_off();
349 377
 

Loading…
Cancel
Save