This program collects raw time series data from the ADC using the NXP board that will later be post processed by PFP Cyber-security cloud base machine learning engine to determine the state of the device.

Dependencies:   FXAS21002 FXOS8700Q

main.cpp

Committer:
vithyat
Date:
2019-11-20
Revision:
1:0c589850480e
Parent:
0:977e87915078
Child:
2:990c985a69ae

File content as of revision 1:0c589850480e:

// ----------------------------------------------------------------------------
// Copyright 2019 PFP Cybersecurity.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------
#ifndef MBED_TEST_MODE

#include "mbed.h"

// Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi.
NetworkInterface *net = NetworkInterface::get_default_instance();

AnalogIn ain(A1);

///////////////////////////////////////////////////////////////////////////////////////
///
///                        PFP Main code start 
///
//////////////////////////////////////////////////////////////////////////////////////
uint8_t PFP_REGISTER_DIGITIZER = 87;
uint8_t PFP_CLK_FREQ = 11;
uint8_t PFP_ADC_GET_RAW = 3;
uint8_t PFP_ADC_INIT = 0;
uint8_t PFP_TRIG_CONFIG = 26;
uint8_t PFP_TRIG_RECEIVED = 88;

struct DeviceData {
    int channel;

    int numberOfTraces;
    int traceLength;

    int sampleRate;
    int digitizer;

    int trigMode;
    int trigSource;

    float trigLevel;
    float trigHyst;

    int trigPercentage;
    int gain;
};

struct DeviceData deviceData;

int bytesToInt(int8_t b0, int8_t b1, int8_t b2, int8_t b3)
{
    int value = (b3 << 24) & 0xff000000
                | (b2 << 16) & 0x00ff0000
                | (b1 << 8) & 0x0000ff00
                | (b0 << 0) & 0x000000ff;
    return value;
}

float bytesToFloat(int8_t b0, int8_t b1, int8_t b2, int8_t b3)
{

    float val = 0;
    unsigned long result = 0;
    result |= ((unsigned long) (b0) << 0x18);
    result |= ((unsigned long) (b1) << 0x10);
    result |= ((unsigned long) (b2) << 0x08);
    result |= ((unsigned long) (b3));
    memcpy(&val, &result, 4);

    return val;
}

int8_t * intToBytes(int value)
{
    int8_t *b = (int8_t*) calloc(4, sizeof(int8_t));

    b[0] = ((int8_t) (value >> 0));
    b[1] = ((int8_t) (value >> 8));
    b[2] = ((int8_t) (value >> 16));
    b[3] = ((int8_t) (value >> 24));
    return b;
}

int8_t * longToBytes(long value)
{
    static int8_t b[8];
    b[0] = (int8_t) ((value >> 0) & 0xFF);
    b[1] = (int8_t) ((value >> 8) & 0xFF);
    b[2] = (int8_t) ((value >> 16) & 0xFF);
    b[3] = (int8_t) ((value >> 24) & 0xFF);
    b[4] = (int8_t) ((value >> 32) & 0xFF);
    b[5] = (int8_t) ((value >> 40) & 0xFF);
    b[6] = (int8_t) ((value >> 48) & 0xFF);
    b[7] = (int8_t) ((value >> 56) & 0xFF);
    return b;
}

int8_t * pfp_emon_create_ack_for_client(int commandType, int numberOfBytes)
{
    static int8_t b[64];

    int8_t *totalBytes = intToBytes(numberOfBytes);
    int8_t *successBytes = intToBytes(3);
    int8_t *returnBytes = intToBytes(commandType);
    int8_t *totaTrace = intToBytes(numberOfBytes / 2);

    // EMON HEADER
    b[0] = 69;
    b[1] = 77;
    b[2] = 79;
    b[3] = 78;

    // NUMBER OF BYTES
    b[4] = totalBytes[0];
    b[5] = totalBytes[1];
    b[6] = totalBytes[2];
    b[7] = totalBytes[3];

    // ERROR
    b[8] = 0;
    b[9] = 0;
    b[10] = 0;
    b[11] = 0;

    // SKIP BYTES
    b[12] = 0;
    b[13] = 0;
    b[14] = 0;
    b[15] = 0;

    // SUCCESS COMMAND
    b[16] = successBytes[0];
    b[17] = successBytes[1];
    b[18] = successBytes[2];
    b[19] = successBytes[3];

    // RETURN COMMAND
    b[20] = returnBytes[0];
    b[21] = returnBytes[1];
    b[22] = returnBytes[2];
    b[23] = returnBytes[3];

    // SKIP BYTES
    b[24] = 0;
    b[25] = 0;
    b[26] = 0;
    b[27] = 0;

    // TOTAL TRACE
    b[28] = totaTrace[0];
    b[29] = totaTrace[1];
    b[30] = totaTrace[2];
    b[31] = totaTrace[3];


    free(totalBytes);
    free(successBytes);
    free(returnBytes);
    free(totaTrace);


    return b;
}


void startEmonThread(void const *args)
{

    printf("The target IP address is '%s'\r\n", net->get_ip_address());

    TCPServer srv;
    TCPSocket clt_sock;
    SocketAddress clt_addr;

    /* Open the server on ethernet stack */
    srv.open(net);

    /* Bind the HTTP port (TCP 80) to the server */
    srv.bind(net->get_ip_address(), 7001);

    long traceTrack = 0;


    //srv.set_blocking(false);
    while (true) {
        /* Can handle 5 simultaneous connections */
        int err= srv.listen(1);
        printf("server listening error : %d\r\n",err);

        while(1) {

            printf("waiting for client connection\r\n");
            err = srv.accept(&clt_sock, &clt_addr);
            if(err == 0) {
                printf("client connected :%s:%d\r\n", clt_addr.get_ip_address(), clt_addr.get_port());
                int MAX_LEN = 80;
                int8_t bytes[MAX_LEN];
                int32_t rawDataLen = 2048;
                int16_t *rawData = (int16_t*)calloc(rawDataLen, sizeof(int16_t));
                int16_t MAX_TRANSMIT_DATA = 500;
                int16_t data[MAX_TRANSMIT_DATA];
                traceTrack = 0;
                while(1) {

                    ////////////////
                    //  int len = read(sockfd, bytes, sizeof(bytes));
                    int len = clt_sock.recv(bytes, MAX_LEN);

                    if (len < 1) {
                        printf("Connection is closed....\n");
                        break;
                    }

                    int commandType = 0;
                    int commandLength = 0;

                    int8_t *sendBytes = NULL;

                    if (len < 0) {
                        return;
                    }
                    if (len == 8) {
                        commandType = bytesToInt(bytes[0], bytes[1], bytes[2], bytes[3]);
                    } else if (len == 12) {
                        commandType = bytesToInt(bytes[0], bytes[1], bytes[2], bytes[3]);
                        commandLength = bytesToInt(bytes[4], bytes[5], bytes[6], bytes[7]);
                        if (commandType == PFP_REGISTER_DIGITIZER) {

                            deviceData.digitizer = bytesToInt(bytes[8], bytes[9], bytes[10],
                                                              bytes[11]);

                        } else if (commandType == PFP_CLK_FREQ) {
                            deviceData.sampleRate = bytesToInt(bytes[8], bytes[9],
                                                               bytes[10], bytes[11]);
                        } else if (commandType == PFP_ADC_GET_RAW) {
                            deviceData.channel = bytesToInt(bytes[8], bytes[9], bytes[10],
                                                            bytes[11]);
                        }

                    } else {
                        commandType = bytesToInt(bytes[0], bytes[1], bytes[2], bytes[3]);
                        commandLength = bytesToInt(bytes[4], bytes[5], bytes[6], bytes[7]);
                    }

                    // Got command form client. Send back header
                    if (commandType == PFP_ADC_INIT) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType, 0);

                        if (sendBytes != NULL) {
                            clt_sock.send(sendBytes,64);
                            wait(0.05);
                        }
                    } else if (commandType == PFP_REGISTER_DIGITIZER) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType, 0);

                        if (sendBytes != NULL) {
                            clt_sock.send(sendBytes,64);
                            wait(0.05);
                        }
                    } else if (commandType == PFP_TRIG_CONFIG) {

                        if ((commandLength > 12) && (commandLength < 1000)) {
                            deviceData.channel = bytesToInt(bytes[8], bytes[9], bytes[10],
                                                            bytes[11]);
                            deviceData.traceLength = bytesToInt(bytes[12], bytes[13],
                                                                bytes[14], bytes[15]);

                            deviceData.trigMode = bytesToInt(bytes[16], bytes[17],
                                                             bytes[18], bytes[19]);
                            deviceData.trigSource = bytesToInt(bytes[20], bytes[21],
                                                               bytes[22], bytes[23]);

                            deviceData.trigLevel = bytesToFloat(bytes[24], bytes[25],
                                                                bytes[26], bytes[27]);
                            deviceData.trigHyst = bytesToFloat(bytes[28], bytes[29],
                                                               bytes[30], bytes[31]);

                            deviceData.trigPercentage = bytesToInt(bytes[32], bytes[33],
                                                                   bytes[34], bytes[35]);
                            deviceData.gain = bytesToInt(bytes[36], bytes[37], bytes[38],
                                                         bytes[39]);

                            printf("trigSource is %i\n", deviceData.trigSource);
                            printf("channel is %i\n", deviceData.channel);
                            printf("trigLevel is %f\n", deviceData.trigLevel);
                            printf("traceLength is %i\n", deviceData.traceLength);
                            printf("sample rate is %i\n", deviceData.sampleRate);
                            printf("trigHyst is %i\n", deviceData.trigHyst);

                            printf("trigPercentage is %i\n", deviceData.trigPercentage);
                            printf("gain is %i\n", deviceData.gain);

                            sendBytes = pfp_emon_create_ack_for_client(commandType,
                                        deviceData.traceLength * 2);

                            if (sendBytes != NULL) {
                                clt_sock.send(sendBytes,64);
                                wait(0.05);
                            }
                        }


                    } else if (commandType == PFP_CLK_FREQ) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType, 0);
                        if (sendBytes != NULL) {
                            clt_sock.send(sendBytes,64);
                            wait(0.05);
                        }
                    } else if (commandType == PFP_ADC_GET_RAW) {

                        sendBytes = pfp_emon_create_ack_for_client(PFP_TRIG_RECEIVED,
                                    deviceData.traceLength * 2);

                        if (sendBytes != NULL) {
                            clt_sock.send(sendBytes,64);
                            wait(0.05);
                        }

                        wait(0.05);

                        sendBytes = pfp_emon_create_ack_for_client(commandType,
                                    deviceData.traceLength * 2);
                        if (sendBytes != NULL) {
                            clt_sock.send(sendBytes,64);
                            wait(0.05);
                        }

                        wait(0.05);

                        if (deviceData.traceLength != rawDataLen) {
                            printf("Data size change to %i===============>\n",rawDataLen);
                            free(rawData);
                            rawDataLen = deviceData.traceLength;
                            rawData = (int16_t*)calloc(rawDataLen, sizeof(int16_t));
                        }

                        // Store raw data
                        printf("Populate sensor data to %i===============>\n",rawDataLen);
//                        for (int i = 0; i < rawDataLen; i++) {
//                            rawData[i] = ain.read_u16();
//                        }        
                                        
                        float max = -32768;
                        uint16_t val=0;
                        
                        // find max
                        for (int i = 0; i < rawDataLen; i++) {
                            val = (ain.read_u16()-32768);
                            rawData[i] =val;
                            if(val>max){
                                max = val;
                            }
                        }
                        
                        float scaling = 32762/abs(max);
                        printf("scaling value %f===============>\n",scaling);
                        for (int i = 0; i < rawDataLen; i++) {
                            rawData[i] =(int16_t)(rawData[i]*scaling);                        
                        }
                        
                        
                        ///////////////////////////////////////////////////////////
                        
                        

                        int num = rawDataLen/MAX_TRANSMIT_DATA;
                        int startIndex = 0;
                        for(int k =0; k<num; k++) {
                            startIndex = k*MAX_TRANSMIT_DATA;
                            for(int i=0; i<MAX_TRANSMIT_DATA; i++) {
                                data[i] = rawData[i + startIndex];
                            }
                            clt_sock.send(data,MAX_TRANSMIT_DATA*sizeof(int16_t));
                            //printf("Sending batch %i of %i\n",k,num);
                            wait(0.04);
                        }

                        int leftOver = rawDataLen - num*MAX_TRANSMIT_DATA;
                        //printf("LeftOver is %i\n",leftOver);

                        if(leftOver>0) {
                            startIndex = num*MAX_TRANSMIT_DATA;

                            for(int j=startIndex; j<rawDataLen; j++) {
                                int i = j-startIndex;
                                data[i] = rawData[j];
                            }
                            clt_sock.send(data,leftOver * sizeof(int16_t));
                            //printf("Sending left over bytes %i\n",leftOver);
                            wait(0.04);
                        }
                        traceTrack++;
                        if(traceTrack>100000000) {
                            traceTrack = 0;
                        }
                        printf("<================== Trace Count is %ld ===============>\n",traceTrack);
                    }
                }

                free(rawData);
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////////////////
///
///                        PFP Main code end 
///
//////////////////////////////////////////////////////////////////////////////////////

int main(void)
{
    printf("Connecting to the network using the default network interface...\n");
    net = NetworkInterface::get_default_instance();

    nsapi_error_t net_status = NSAPI_ERROR_NO_CONNECTION;
    while ((net_status = net->connect()) != NSAPI_ERROR_OK) {
        printf("Unable to connect to network (%d). Retrying...\n", net_status);
    }

    Thread thread(startEmonThread);

    while (true) {
        wait(0.5);
    }
}

#endif /* MBED_TEST_MODE */