Connections - HomeACcessoryKid/ESP8266-HomeKit GitHub Wiki

Connection tracking is important for a HomeKit Accessory

We use the pespconn->reserve pointer to store our private information called pcryp (it mainly contains crypto stuff) This pcryp is the main structure to send between routines and contains a pointer to the espconn. In some cases we know the pcryp directly and we deduce the espconn. Sometimes we know the espconn and can deduce the pcryp

//hk.h
typedef struct _crypto_parm {
    xSemaphoreHandle semaphore;
    struct espconn  *pespconn;
    int             state;
    int             stale;
    uint32_t        connectionid;
    int             encrypted;
    long            countwr;
    long            countrd;
    word32          sessionkey_len;
    byte            sessionkey[32];
    byte            verKey[CHACHA20_POLY1305_AEAD_KEYSIZE];
    byte            readKey[CHACHA20_POLY1305_AEAD_KEYSIZE];
    byte            writeKey[CHACHA20_POLY1305_AEAD_KEYSIZE];
    char            object[0x1cb];
    int             objects_len[TLVNUM];
} crypto_parm;

For example, in the send_events function arg is the pcryp and we also look at all other connections via plist (explained below)

void    send_events(void *arg, int aid, int iid)
{
    crypto_parm *pcryp = arg;
    espconn_msg *plist = NULL;
    plist = plink_active;
    struct espconn *pespconn = NULL;

    if (pcryp) pespconn=pcryp->pespconn;
    
    while(plist != NULL){
        if ( (plist->pespconn!=pespconn) && //do not send to self!
                    (pcryp=plist->pespconn->reserve) &&  //does it have a valid pointer
                    (pcryp->connectionid&acc_items[iid].events) ) { //compare bitmaps
            if (xSemaphoreTake(pcryp->semaphore,5)) { //if busy, wait up till 50ms
                //prepare json
                event_send(pcryp,json);
                xSemaphoreGive(pcryp->semaphore);
            }
        }
        plist = plist->pnext;
    }
}

Originally Espressif had all their source open. But since some time they have it closed. However, the actual structure has changed very little. We can redefine ourselves. We use the following definitions based on memory inspection and some trial and error.
(If this would fail in the future, we can set up a linked list of pcryp pointers.)

//global
extern  espconn_msg *plink_active;
//in a function
espconn_msg *plist = NULL;
plist = plink_active;
    while(plist != NULL){ 
        //do something with plist->pespconn
        plist = plist ->pnext;
    }
//hk.h
typedef struct _espconn_msg{
    struct espconn *pespconn;
    void *pcommon; //at least that is what I suspect
    int rport;
    uint8 rip[4];
    void *p05;
    void *p06;
    void *p07;
    void *p08;
    void *p09;
    void *p10;
    void *p11;
    void *p12;
    int i13;
    void *p14;
    void *p15;
    void *p16;
    void *p17;
    void *p18;
    int i19;
    void *p20;
    void *p21;
    void *p22;
    void *preverse;
    void *pssl;
    struct _espconn_msg *pnext;
    void *p26;
    void *p27;
    int i28;
}espconn_msg;