POC1.5 prototype 2 x color sensor 2 x LM75B 3 x AnalogIn 1 x accel

Dependencies:   mbed vt100

Revision:
0:f0de320e23ac
Child:
1:66c21c62c449
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/af_utils/af_attriburtes.cpp	Fri Dec 01 06:16:31 2017 +0000
@@ -0,0 +1,498 @@
+#include "mbed.h"
+#include <ctype.h>
+#include "af_attributes.h"
+#include "edge_attributes.h"
+#include "edge_time.h"
+#include "edge_sensor.h"
+#include "edge_accel.h"
+#include "edge_color.h"
+#include "edge_temp.h"
+#include "edge_pressure.h"
+#include "edge_mgr.h"
+#include "pending.h"
+
+extern pending_class *pending ;
+
+static const af_attribute_type af_attr[] = {
+/*     ID,   Description,                Type,                 Size */
+    {    1,  "Sensor Value",             ATTRIBUTE_TYPE_UTF8S, 255 },
+    {  100,  "Accel Present",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  101,  "Accel Enable",             ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  102,  "Accel Interval",           ATTRIBUTE_TYPE_SINT16,  2 },
+    {  103,  "Accel Value",              ATTRIBUTE_TYPE_FIXED_15_16, 4},
+    
+    {  200,  "Color0 Present",           ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  201,  "Color0 Enable",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  202,  "Color0 Interval",          ATTRIBUTE_TYPE_SINT16,  2 },
+    {  203,  "Color0 Trigger Mode",      ATTRIBUTE_TYPE_SINT8,   1 },
+    {  204,  "Color0 Integration Time",  ATTRIBUTE_TYPE_SINT8,   1 },    
+    {  205,  "Color0 Calibrate",         ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  206,  "Color0 PWM R",             ATTRIBUTE_TYPE_SINT32,  4 },
+    {  207,  "Color0 PWM G",             ATTRIBUTE_TYPE_SINT32,  4 },
+    {  208,  "Color0 PWM B",             ATTRIBUTE_TYPE_SINT32,  4 },
+    {  209,  "Color0 PWM Period",        ATTRIBUTE_TYPE_SINT16,  2 },
+    {  210,  "Color0 PWM Target",        ATTRIBUTE_TYPE_SINT16,  2 },
+    {  211,  "Color0 R",                 ATTRIBUTE_TYPE_SINT16,  2 },
+    {  212,  "Color0 G",                 ATTRIBUTE_TYPE_SINT16,  2 },
+    {  213,  "Color0 B",                 ATTRIBUTE_TYPE_SINT16,  2 },
+ 
+    {  220,  "Color1 Present",           ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  221,  "Color1 Enable",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  222,  "Color1 Interval",          ATTRIBUTE_TYPE_SINT16,  2 },
+    {  223,  "Color1 Trigger Mode",      ATTRIBUTE_TYPE_SINT8,   1 },
+    {  224,  "Color1 Integration Time",  ATTRIBUTE_TYPE_SINT8,   1 },
+    {  225,  "Color1 Calibrate",         ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  226,  "Color1 PWM R",             ATTRIBUTE_TYPE_SINT32,  4 },
+    {  227,  "Color1 PWM G",             ATTRIBUTE_TYPE_SINT32,  4 },
+    {  228,  "Color1 PWM B",             ATTRIBUTE_TYPE_SINT32,  4 },
+    {  229,  "Color1 PWM Period",        ATTRIBUTE_TYPE_SINT16,  2 },
+    {  230,  "Color1 PWM Target",        ATTRIBUTE_TYPE_SINT16,  2 },
+    {  231,  "Color1 R",                 ATTRIBUTE_TYPE_SINT16,  2 },
+    {  232,  "Color1 G",                 ATTRIBUTE_TYPE_SINT16,  2 },
+    {  233,  "Color1 B",                 ATTRIBUTE_TYPE_SINT16,  2 },
+    
+    {  300,  "Temp0 Present",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  301,  "Temp0 Enable",             ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  302,  "Temp0 Interval",           ATTRIBUTE_TYPE_SINT16,  2 },
+    {  303,  "Temp0 Value",              ATTRIBUTE_TYPE_FIXED_15_16, 4},
+    
+    {  310,  "Temp1 Present",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  311,  "Temp1 Enable",             ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  312,  "Temp1 Interval",           ATTRIBUTE_TYPE_SINT16,  2 },
+    {  313,  "Temp1 Value",              ATTRIBUTE_TYPE_FIXED_15_16, 4},
+    
+    {  320,  "Temp2 Present",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  321,  "Temp2 Enable",             ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  322,  "Temp2 Interval",           ATTRIBUTE_TYPE_SINT16,  2 },
+    {  323,  "Temp2 Value",              ATTRIBUTE_TYPE_FIXED_15_16, 4},
+
+    {  330,  "Temp3 Present",            ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  331,  "Temp3 Enable",             ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  332,  "Temp3 Interval",           ATTRIBUTE_TYPE_SINT16,  2 },
+    {  333,  "Temp3 Value",              ATTRIBUTE_TYPE_FIXED_15_16, 4}, 
+    
+    {  400,  "Gas Pressure Present",    ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  401,  "Gas Pressure Enable",     ATTRIBUTE_TYPE_BOOLEAN, 1 },
+    {  402,  "Gas Pressure Interval",   ATTRIBUTE_TYPE_SINT16,  2 },
+    {  403,  "Gas Pressure Value",      ATTRIBUTE_TYPE_FIXED_15_16, 4}, 
+                   
+    { 1024,  "LED",                      ATTRIBUTE_TYPE_SINT16,  2 },
+    { 1025,  "I/O 0",                    ATTRIBUTE_TYPE_SINT64,  8 },
+    { 1026,  "I/O 1",                    ATTRIBUTE_TYPE_SINT64,  8 },
+    { 1028,  "I/O 2",                    ATTRIBUTE_TYPE_SINT64,  8 },
+    { 1030,  "BUTTON",                   ATTRIBUTE_TYPE_BOOLEAN, 2 },
+    { 1031,  "I/O 3",                    ATTRIBUTE_TYPE_SINT64,  8 },
+    { 2001,  "Bootloader Version",       ATTRIBUTE_TYPE_SINT64,  8 },
+    { 2002,  "BLE Stack Version",        ATTRIBUTE_TYPE_SINT64,  8 },
+    { 2003,  "FW Application Version",   ATTRIBUTE_TYPE_SINT64,  8 },
+    { 2004,  "Device Description",       ATTRIBUTE_TYPE_SINT64,  8 },
+    { 2006,  "Wi-Fi chip",               ATTRIBUTE_TYPE_SINT64,  8 },
+    { 59001, "Offline Schedules enable", ATTRIBUTE_TYPE_SINT16,  2 }, 
+    { 60000, "Security Enabled",         ATTRIBUTE_TYPE_SINT8,   1 }, /* ? */
+    { 65001, "UTC offset data",          ATTRIBUTE_TYPE_BYTES,   8 },
+    { 65004, "Configured SSID",          ATTRIBUTE_TYPE_UTF8S,  10 }, /* ? */
+    { 65005, "Wi-Fi Bars",               ATTRIBUTE_TYPE_SINT8,   1 },
+    { 65006, "Wi-Fi Steady State",       ATTRIBUTE_TYPE_SINT8,   1 },
+    { 65012, "Command",                  ATTRIBUTE_TYPE_BYTES,   8 }, /* ? */   
+    { 65013, "ASR State",                ATTRIBUTE_TYPE_SINT8,   1 },
+    { 65014, "Low Battery Warning",      ATTRIBUTE_TYPE_SINT8,   1 },
+    { 65015, "Linked Timestamp",         ATTRIBUTE_TYPE_SINT32,  4 },
+    { 65018, "Attribute ACK",            ATTRIBUTE_TYPE_SINT16,  8 },
+    { 65019, "Reboot Reason",            ATTRIBUTE_TYPE_UTF8S, 100 },
+    { 65020, "BLE Comms",                ATTRIBUTE_TYPE_BYTES,  12 },
+    { 65021, "MCU Interface",            ATTRIBUTE_TYPE_SINT8,   1 },
+    {     0, 0,                          0,                      0 }
+} ;
+
+int get_af_attr(uint16_t id) 
+{
+    int i ;
+    for (i = 0 ; af_attr[i].id != 0 ; i++ ) {
+        if (id == af_attr[i].id) {
+            break ;
+        }
+    }
+    return (i) ;
+}
+
+void print_af_error(int resultCode) 
+{
+    switch(resultCode) {
+    case afSUCCESS:
+        printf("Operation completed successfully\n") ;
+        break ;
+    case afERROR_NO_SUCH_ATTRIBUTE:
+        printf("Request was made for unknown attribute id\n") ;
+        break ;
+    case afERROR_BUSY:
+        printf("Request already in progress, try again\n") ;
+        break ;
+    case afERROR_INVALID_COMMAND:
+        printf("Command could not be parsed\n") ;
+        break ;
+    case afERROR_QUEUE_OVERFLOW:
+        printf("Queue is full\n") ;
+        break ;
+    case afERROR_QUEUE_UNDERFLOW:
+        printf("Queue is empty\n") ;
+        break ;
+    case afERROR_INVALID_PARAM:
+        printf("Bad input parameter\n") ;
+        break ;
+    default:
+        printf("Unknown error code %d\n", resultCode) ;
+        break ;
+    }
+}
+
+void af_print_values(
+    const uint8_t   requestId, 
+    const uint16_t  attributeId,
+    const uint16_t  valueLen,
+    const uint8_t   *value
+) 
+{
+    int i, id ;
+
+    id = get_af_attr(attributeId) ;
+
+    if (af_attr[id].id  != 0) {
+        printf(af_attr[id].description) ;
+        printf(" : ") ;
+        switch(af_attr[id].attribute_type) {
+        case ATTRIBUTE_TYPE_BOOLEAN:
+        case ATTRIBUTE_TYPE_SINT8: 
+            if (valueLen >= 1) {
+                printf("%02X\n", value[0]) ;
+            }
+            break ;
+        case ATTRIBUTE_TYPE_SINT16:
+            if (valueLen >= 2) {
+                printf("%02X%02X\n", value[1], value[0]) ;
+            }
+            break ; 
+        case ATTRIBUTE_TYPE_SINT32:
+            if (valueLen >= 4) {
+                printf("%02X%02X%02X%02X\n",
+                    value[3],value[2],value[1],value[0]) ;
+            }
+            break ;
+        case ATTRIBUTE_TYPE_SINT64:
+            if (valueLen >= 8) {
+                printf("%02X%02X %02X%02X %02X%02X %02X%02X\n",
+                    value[7], value[6], value[5], value[4],
+                    value[3], value[2], value[1], value[0]) ;
+            }
+            break ;
+        case ATTRIBUTE_TYPE_UTF8S: 
+            if (valueLen > 0) {
+                for (i = 0 ; i < valueLen ; i++) {
+                    if (isprint(value[i])) {
+                        printf("%c", value[i]) ;
+                    } else if (value[i] == 0) { /* string terminator NULL */
+                        break ;
+                    } else {
+                        printf("\'%02X\'",value[i]) ;
+                    }
+                }
+                printf("\n") ;
+            }
+            break ;
+        case ATTRIBUTE_TYPE_BYTES:
+        default:
+            if (valueLen > 0) {
+                for (i = 0 ; i < valueLen ; i++ ) {
+                    printf("%02X ", value[i]) ;
+                }
+                printf("\n") ;
+            }
+            break ;
+        }
+    } else {
+        if (valueLen > 0) {
+            for (i = 0 ; i < valueLen ; i++ ) {
+                printf("%02X ", value[i]) ;
+            }
+            printf("\n") ;
+        }
+    }
+//    printf("\n") ;
+}
+
+/*
+ * Callback that allows ASR to request an MCU attribute be changed. 
+ * You should define this function in your MCU firmware to perform application-specific actions 
+ * your code must take (e.g., updating the state of the hardware), 
+ * in light of the attribute value change.
+*/
+void attributeChangeRequest(
+    const uint8_t   requestId, 
+    const uint16_t  attributeId,
+    const uint16_t  valueLen,
+    const uint8_t   *value
+) 
+{ 
+//    int result ;   
+    uint32_t timestamp = edge_time ;
+    if ((pending != 0)&&(pending->request->requestId == requestId)) {
+        pending->replied_time = timestamp ;
+
+    }
+    ts2time(timestamp, &current_time) ;
+    print_time(&current_time) ;
+    printf(" %5d ASR requested [%d] : ", attributeId, requestId) ;
+    af_print_values(requestId, attributeId, valueLen, value) ;
+    switch(attributeId) {
+    case AF_SYSTEM_LINKED_TIMESTAMP: /* timestamp */
+        set_time(valueLen, value) ;
+        printf("timestampe = %d\n", timestamp) ;
+//        print_date(&current_time) ;
+        print_time(&current_time) ;
+        break ;
+    case ATTR_ACCEL_ENABLE: /* accel enable */
+        if (sensor[0]) {
+            if (value[0]) {
+                printf("Accel Enabled\n") ;
+                sensor[0]->reset() ;
+                sensor[0]->enable() ;
+                afero->setAttributeBool(ATTR_ACCEL_ENABLE, true) ;
+            } else if (sensor[0]){
+                printf("Accel Disabled\n") ;
+                sensor[0]->disable() ;
+                afero->setAttributeBool(ATTR_ACCEL_ENABLE, false) ;
+            }
+        }
+        break ;
+    case ATTR_ACCEL_INTERVAL:
+        if (sensor[0]) {
+            sensor[0]->setInterval((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_ACCEL_INTERVAL, 2, value) ;
+        }
+        break ;
+    case ATTR_COLOR0_ENABLE: /* color0 enable */
+        if (sensor[1]) {
+            if (value[0]) {
+                sensor[1]->reset() ;
+                sensor[1]->enable() ;
+                afero->setAttributeBool(ATTR_COLOR0_ENABLE, true) ;
+            } else {
+                sensor[1]->disable() ;
+                afero->setAttributeBool(ATTR_COLOR0_ENABLE, false) ;
+            }
+        }
+        break ;
+    case ATTR_COLOR0_INTERVAL:
+        if (sensor[1]) {
+            sensor[1]->setInterval((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_COLOR0_INTERVAL, 2, value) ;
+        }
+        break ;    
+    case ATTR_COLOR0_TRIGMODE: /* color0 config */
+        if (sensor[1]) {
+            uint8_t config = ((edge_color*)sensor[1])->getConfig() & 0x70 ;
+            if (value[0]) {
+                config = config | 0x06 ;
+            } 
+            ((edge_color*)sensor[1])->setConfig(config) ;
+            afero->setAttribute(ATTR_COLOR0_TRIGMODE, 1, value) ;
+        }
+        break ;
+    case ATTR_COLOR0_ITIME: /* color0 config */
+        if (sensor[1]) {
+            uint8_t config = ((edge_color*)sensor[1])->getConfig() & 0x07 ;
+            config = (value[0] << 4) | config ;
+            ((edge_color*)sensor[1])->setConfig(config) ;
+            afero->setAttribute(ATTR_COLOR0_ITIME, 1, value) ;
+        }
+        break ;    
+    case ATTR_COLOR0_PWM_PERIOD: /* color0 pwm period */
+        if (sensor[1]) {
+            ((edge_color*)sensor[1])->set_pwm_period((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_COLOR0_PWM_PERIOD, 2, value) ;
+        }            
+        break ;
+    case ATTR_COLOR0_PWM_TARGET: /* color0 pwm calibration target */
+        if (sensor[1]) {
+            color0_target[0] = (value[1] << 8) | value[0] ;
+            color0_target[1] = color0_target[0] ;
+            color0_target[2] = color0_target[1] ;
+            afero->setAttribute(ATTR_COLOR0_PWM_TARGET, 2, value) ;
+        }            
+        break ;        
+    case ATTR_COLOR0_CALIBRATE: /* calibrate color0 */
+        if (sensor[1] && value[0]) { /* do calibration! */
+            ((edge_color*)sensor[1])->calibrate(color0_target, color0_pwm, 10) ;
+            afero->setAttribute32(ATTR_COLOR0_PWM_R, color0_pwm[0]) ;
+            afero->setAttribute32(ATTR_COLOR0_PWM_G, color0_pwm[1]) ;
+            afero->setAttribute32(ATTR_COLOR0_PWM_B, color0_pwm[2]) ;
+        }
+        afero->setAttributeBool(ATTR_COLOR0_CALIBRATE, false) ;
+        break ;
+    case ATTR_COLOR1_ENABLE: /* color1 enable */
+        if (sensor[2]) {
+            if (value[0]) {
+                sensor[2]->reset() ;
+                sensor[2]->enable() ;
+                afero->setAttributeBool(ATTR_COLOR1_ENABLE, true) ;
+            } else {
+                sensor[2]->disable() ;
+                afero->setAttributeBool(ATTR_COLOR1_ENABLE, false) ;
+            }
+        }
+        break ;
+    case ATTR_COLOR1_INTERVAL:
+        if (sensor[2]) {
+            sensor[2]->setInterval((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_COLOR1_INTERVAL, 2, value) ;
+        }
+        break ;    
+    case ATTR_COLOR1_TRIGMODE: /* color0 config */
+        if (sensor[2]) {
+            uint8_t config = ((edge_color*)sensor[2])->getConfig() & 0x70 ;
+            if (value[0]) {
+                config = config | 0x06 ;
+            } 
+            ((edge_color*)sensor[2])->setConfig(config) ;
+            afero->setAttribute(ATTR_COLOR1_TRIGMODE, 1, value) ;
+        }
+        break ;
+    case ATTR_COLOR1_ITIME: /* color0 config */
+        if (sensor[2]) {
+            uint8_t config = ((edge_color*)sensor[2])->getConfig() & 0x07 ;
+            config = (value[0] << 4) | config ;
+            ((edge_color*)sensor[2])->setConfig(config) ;
+            afero->setAttribute(ATTR_COLOR1_ITIME, 1, value) ;
+        }
+        break ;  
+    case ATTR_COLOR1_PWM_PERIOD: /* color0 pwm period */
+        if (sensor[2]) {
+            ((edge_color*)sensor[2])->set_pwm_period((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_COLOR1_PWM_PERIOD, 2, value) ;
+        }            
+        break ;
+    case ATTR_COLOR1_PWM_TARGET: /* color0 pwm calibration target */
+        if (sensor[2]) {
+            color1_target[0] = (value[1] << 8) | value[0] ;
+            color1_target[1] = color0_target[0] ;
+            color1_target[2] = color0_target[1] ;
+            afero->setAttribute(ATTR_COLOR1_PWM_TARGET, 2, value) ;
+        }            
+        break ;   
+    case ATTR_COLOR1_CALIBRATE: /* calibrate color1 */
+        if (sensor[2] && value[0]) { /* do calibration! */
+            ((edge_color*)sensor[2])->calibrate(color1_target, color1_pwm, 10) ;
+            afero->setAttribute32(ATTR_COLOR1_PWM_R, color1_pwm[0]) ;
+            afero->setAttribute32(ATTR_COLOR1_PWM_G, color1_pwm[1]) ;
+            afero->setAttribute32(ATTR_COLOR1_PWM_B, color1_pwm[2]) ;
+        }
+        afero->setAttributeBool(ATTR_COLOR1_CALIBRATE, false) ;
+        break ;
+    case ATTR_TEMP0_ENABLE: /* temp0 is used to control temp-sensors */
+        if (sensor[3]) {
+            if (value[0]) {
+                sensor[3]->reset() ;
+                sensor[3]->enable() ;
+                afero->setAttributeBool(ATTR_TEMP0_ENABLE, true) ;
+            } else {
+                sensor[3]->disable() ;
+                afero->setAttributeBool(ATTR_TEMP0_ENABLE, false) ;
+            }
+        } 
+        break ;
+    case ATTR_TEMP0_INTERVAL:
+        if (sensor[3]) {
+            sensor[3]->setInterval((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_TEMP0_INTERVAL, 2, value) ;
+        }
+        break ; 
+    case ATTR_TEMP3_ENABLE: /* temp3 enable */
+        break ;
+    case ATTR_GAS_ENABLE: /* pressure enable */
+        if (sensor[4]) {
+            if (value[0]) {
+                sensor[4]->reset() ;
+                sensor[4]->enable() ;
+                afero->setAttributeBool(ATTR_GAS_ENABLE, true) ;
+            } else {
+                sensor[4]->disable() ;
+                afero->setAttributeBool(ATTR_GAS_ENABLE, false) ;
+            }
+        }   
+        break ;
+    case ATTR_GAS_INTERVAL:
+        if (sensor[4]) {
+            sensor[4]->setInterval((value[1] << 8) | value[0]) ;
+            afero->setAttribute(ATTR_GAS_INTERVAL, 2, value) ;
+        }
+        break ; 
+    default:
+        break ;   
+    }
+//    af_print_values(requestId, attributeId, valueLen, value) ;
+    if ((pending != 0)&&(pending->request->requestId == requestId)) {
+        printf("Request [%d] replied in %d sec!\n", requestId, pending->replied_time - pending->submit_time) ;
+        delete pending ;
+        pending = 0 ;
+    }
+}
+
+/*
+ * Application callback that allows afLib to notify that an attribute has changed. 
+ * This method will be called in response to a getAttribute call from the application 
+ * and whenever a ASR module attribute changes.
+ */
+void attributeUpdatedReport(
+    const uint8_t   requestId,
+    const uint16_t  attributeId,
+    const uint16_t  valueLen,
+    const uint8_t   *value
+) 
+{
+    uint32_t timestamp = edge_time ;
+    if ((pending != 0)&&(pending->request->requestId == requestId)) {
+        pending->replied_time = timestamp ;
+    }
+    ts2time(timestamp, &current_time) ;
+    print_time(&current_time) ;
+    printf(" %5d ASR reported [%d]: ", attributeId, requestId) ;
+    if (attributeId == 65015) { /* timestamp! */
+        set_time(valueLen, value) ;
+        printf("timestampe = %d\n", timestamp) ;
+        print_date(&current_time) ;
+//        print_time(&current_time) ;
+        printf("\n") ;
+    }
+    af_print_values(requestId, attributeId, valueLen, value) ;
+    switch(attributeId) {
+    case AF_SYSTEM_ASR_STATE:
+        printf("ASR state: ") ;
+        switch(value[0]) {
+        case MODULE_STATE_REBOOTED:
+            printf("Rebooted\n") ;
+            break ;
+        case MODULE_STATE_LINKED:
+            printf("Linked\n") ;
+            break ;
+        case MODULE_STATE_UPDATING:
+            printf("Updating\n") ;
+            break ;
+        case MOUDLE_STATE_UPDATE_READY:
+            printf("Update ready - rebooting\n") ;
+            while(afero->setAttribute32(AF_SYSTEM_COMMAND, MODULE_COMMAND_REBOOT) != afSUCCESS) {
+                afero->loop() ;
+                wait(0.1) ;
+            }
+            break ;
+        default:
+            break ;
+        }
+        break ;
+    default:
+        break ;
+    }      
+    if ((pending != 0)&&(pending->request->requestId == requestId)) {
+        printf("Request [%d] replied in %d sec!\n", requestId, pending->replied_time - pending->submit_time) ;
+        delete pending ;
+        pending = 0 ;
+    }      
+}
\ No newline at end of file