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-08-28
Revision:
0:977e87915078
Child:
1:0c589850480e

File content as of revision 0:977e87915078:

// ----------------------------------------------------------------------------
// 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);

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;


///////////////////////////////////////////////////////////////////////////////////////
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)
{
    static int8_t b[4];
    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, long numberOfBytes)
{
    static int8_t b[24];

    int8_t *totalBytes = longToBytes(numberOfBytes);
    int8_t *successBytes = intToBytes(3);
    int8_t *returnBytes = intToBytes(commandType);

    // 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];
    b[8] = totalBytes[4];
    b[9] = totalBytes[5];
    b[10] = totalBytes[6];
    b[11] = totalBytes[7];

    // 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];

    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 if (len == 40) {
                        // Trig Configuration
                        commandType = bytesToInt(bytes[0], bytes[1], bytes[2], bytes[3]);
                        commandLength = bytesToInt(bytes[4], bytes[5], bytes[6], bytes[7]);

                        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]);
                    }

                    // Got command form client. Send back header
                    if (commandType == PFP_ADC_INIT) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType, 0);
                    } else if (commandType == PFP_REGISTER_DIGITIZER) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType, 0);
                    } else if (commandType == PFP_TRIG_CONFIG) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType,
                                    deviceData.traceLength * 2);
                    } else if (commandType == PFP_CLK_FREQ) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType, 0);
                    } else if (commandType == PFP_ADC_GET_RAW) {
                        sendBytes = pfp_emon_create_ack_for_client(commandType,
                                    deviceData.traceLength * 2);
                    }

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

                    if (commandType == PFP_ADC_GET_RAW) {
                        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();
                        }

                        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);
            }
        }
    }
}
///////////////////////////////////////////////////////////////////

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 */