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 7 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
 static union pd_msg *policy_engine_message = NULL;
49
 static union pd_msg *policy_engine_message = NULL;
50
 /* Whether or not the source capabilities match our required power */
50
 /* Whether or not the source capabilities match our required power */
51
 static bool capability_match = false;
51
 static bool capability_match = false;
52
+/* Whether or not we have an explicit contract */
53
+static bool explicit_contract = false;
52
 /* Policy Engine thread mailbox */
54
 /* Policy Engine thread mailbox */
53
 static msg_t pdb_pe_mailbox_queue[PDB_MSG_POOL_SIZE];
55
 static msg_t pdb_pe_mailbox_queue[PDB_MSG_POOL_SIZE];
54
 mailbox_t pdb_pe_mailbox;
56
 mailbox_t pdb_pe_mailbox;
55
 
57
 
56
 static enum policy_engine_state pe_sink_startup(void)
58
 static enum policy_engine_state pe_sink_startup(void)
57
 {
59
 {
60
+    explicit_contract = false;
61
+
58
     /* No need to reset the protocol layer here.  There are two ways into this
62
     /* No need to reset the protocol layer here.  There are two ways into this
59
      * state: startup and exiting hard reset.  On startup, the protocol layer
63
      * state: startup and exiting hard reset.  On startup, the protocol layer
60
      * is reset by the startup procedure.  When exiting hard reset, the
64
      * is reset by the startup procedure.  When exiting hard reset, the
154
             chPoolFree(&pdb_msg_pool, policy_engine_message);
158
             chPoolFree(&pdb_msg_pool, policy_engine_message);
155
             policy_engine_message = NULL;
159
             policy_engine_message = NULL;
156
             return PESinkSoftReset;
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
         } else {
179
         } else {
180
+            chPoolFree(&pdb_msg_pool, policy_engine_message);
181
+            policy_engine_message = NULL;
159
             return PESinkSendSoftReset;
182
             return PESinkSendSoftReset;
160
         }
183
         }
161
     }
184
     }
176
         /* If we got a PS_RDY, handle it */
199
         /* If we got a PS_RDY, handle it */
177
         if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_PS_RDY
200
         if (PD_MSGTYPE_GET(policy_engine_message) == PD_MSGTYPE_PS_RDY
178
                 && PD_NUMOBJ_GET(policy_engine_message) == 0) {
201
                 && PD_NUMOBJ_GET(policy_engine_message) == 0) {
202
+            /* We just finished negotiating an explicit contract */
203
+            explicit_contract = true;
204
+
179
             /* Set the output appropriately */
205
             /* Set the output appropriately */
180
             if (capability_match) {
206
             if (capability_match) {
181
                 pdb_dpm_output_on();
207
                 pdb_dpm_output_on();
344
 
370
 
345
 static enum policy_engine_state pe_sink_transition_default(void)
371
 static enum policy_engine_state pe_sink_transition_default(void)
346
 {
372
 {
373
+    explicit_contract = false;
374
+
347
     /* Tell the DPM to turn off the output */
375
     /* Tell the DPM to turn off the output */
348
     pdb_dpm_output_off();
376
     pdb_dpm_output_off();
349
 
377
 

Loading…
Cancel
Save