LoRaWAN demo.

Dependencies:   modem_ref_helper DebouncedInterrupt

modem_callbacks.cpp

Committer:
Jeej
Date:
2018-11-26
Revision:
15:86f6fa566d89
Parent:
7:026f8c8bcdab
Child:
16:59d93cb1efee

File content as of revision 15:86f6fa566d89:

#include "modem_ref_helper.h"


// ============================================================}}}

// Callbacks to MODEM's ALP requests
// ============================================================{{{
void my_read(u8 fid, u32 offset, u32 length, int id)
{
    u8 data[256];
    
    if (!ram_fs_read(fid, offset, length, data))
    {
        modem_respond_read(fid, data, offset, length, id);
    }
    else
    {
        modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
    }
}

void my_write(u8 fid, void *data, u32 offset, u32 length, int id)
{
    if (!ram_fs_write(fid, offset, length, (uint8_t*)data))
    {
        extern Queue<void, 8> g_file_modified;

        modem_respond(ALP_ERR_NONE, id);
        g_file_modified.put((void*)fid);
    }
    else
    {
        modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
    }
}

void my_read_fprop(u8 fid, int id)
{
    u8* hdr = (u8*)ram_fs_get_header(fid);
    
    if (hdr != NULL)
    {
        modem_respond_fprop(fid, hdr, id);
    }
    else
    {
        modem_respond(ALP_ERR_FILE_NOT_FOUND, id);
    }
}

void my_flush(u8 fid, int id)
{
    // No flush in this file system
    modem_respond(ALP_ERR_NONE, id);
}

void my_delete(u8 fid, int id)
{
    modem_respond((ram_fs_delete(fid))? ALP_ERR_FILE_NOT_FOUND : ALP_ERR_NONE, id);
}

void my_udata(void *data, u32 length)
{    
    uint8_t* p = (uint8_t*)data;
    int32_t rem = length;
    alp_parsed_chunk_t r;
    d7a_sp_res_t* istat;
    
    do {
        uint32_t parsed = alp_parse_chunk(&p, &r);
        if (!parsed)
        {
            // Discard the payload in case of parsing error.
            PRINT("Parsing error!\r\n");
            break;
        }
        rem -= parsed;
        
        switch (r.type)
        {
            // Interface status
            case ALP_OPCODE_RSP_ISTATUS:
                // D7A Interface
                if (ALP_ITF_TYPE_D7A == r.meta.itf.type)
                {
                    union {
                        u8      b[8];
                        u32     w[2];
                    } uid;
                    
                    // ISTATUS can come either alone or together with ALP_OPCODE_RSP_F_DATA
                    // but there should be only one per payload, moreover it will come first
                    istat = (d7a_sp_res_t*)r.data;
                    memcpy(uid.b,istat->addressee.id,8);
                        
                    PRINT("Got accessed by UID:%08X%08X SNR: %3ddB RXLEV: -%-3ddBm LB: %3ddB\n",
                    HAL_U32_BYTE_SWAP(uid.w[0]), HAL_U32_BYTE_SWAP(uid.w[1]),
                    istat->snr, istat->rxlev, istat->lb);
                }
                else
                {
                    PRINT("Got accessed by unknown Interface 0x%02X\n", r.meta.itf.type);
                }
                break;
            // Data return
            case ALP_OPCODE_RSP_F_DATA:
                // RSP_F_DATA can come either alone or together with ISTATUS
                PRINT("Got UNS File[%3d]@%d %d Bytes\n", r.meta.f_data.fid, r.meta.f_data.offset, r.meta.f_data.length);
                break;
            default:
                PRINT("Untreated OPCODE %d\n", r.type);
                break;
        }
    } while (rem > 0);
}

void my_lqual(u8 ifid, int per)
{
    PRINT("Interface File [%3d] LQUAL : %d%% PER\r\n", ifid, per);
}

void my_ldown(u8 ifid)
{
    PRINT("Interface File [%3d] LDOWN\r\n", ifid);
}

void my_reset(void)
{
    PRINT("Restarting application...\r\n");
    FLUSH();
    NVIC_SystemReset();
}

void my_boot(u8 cause, u16 number)
{
    PRINT("Modem BOOT[%c] #%d\r\n", cause, number);
    
    // Modem re-booted, restart APP
    my_reset();
}

void my_busy(u8 busy)
{
    if (busy)
    {
        PRINT("Modem Busy\r\n");
        
        /* Stop report, do not use modem */
        /* Wait for modem reboot or modem not busy */
    }
    else
    {
        PRINT("Modem not Busy\r\n");
        
        /* Resume reports */
    }
}

void my_itf_busy(u8 ifid, u32 seconds)
{
    //PRINT("ITF[%d] Busy for %d seconds.\r\n", ifid, seconds);
    
    extern Semaphore modem_urc;
    extern uint32_t itf_busy;
    
    itf_busy = seconds;
    modem_urc.release();
}