• 10 dec 2017: forum version update. In case of issues use this topic.
  • 30 nov 2017: pilight moved servers. In case of issues use this topic.
Hello There, Guest! Login Register


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Parser standalone
#1
I wrote this parser as a Standalone.

You can convert:
NanoString<>PulseTrain<>Protocol

At the moment i use the Setup.sh and flash.c (put my whole code into it) to compile my code.
Because I don't know how to add my parser.c to the cmake setup / setup.sh.
Maybe someone can help me to add my parser.c to the setup.sh Smile

Code:
/*
  Copyright (C) 2013 - 2016 CurlyMo

  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include "libs/pilight/protocols/protocol.h"

/* Reset repeats after a certain amount of time */
static struct timeval tv;

struct protocols_t *protocols = NULL;
#define RECEIVER_BUFFER_SIZE 10
#define MIN_PULSELENGTH       80
#define MAX_PULSELENGTH       16000
#define MAX_PULSE_TYPES       16

unsigned int maxrawlen = MAXPULSESTREAMLENGTH;
enum PilightRepeatStatus_t { FIRST, INVALID, VALID, KNOWN };
static struct timeval tv;

int indexOf(char* token, char s, int from);
char* substr(const char* string, int pos, int len);
int parsePulseTrain(int *pulses, int length, char *protocols);
int createPulseTrain(int *pulses, const char* protocol_id, const char* content);
int pulseTrainTostring(int *code, int rawlen, int repeats, char* send);
int stringToPulseTrain(char *data, int *codes, int maxlength);

int indexOf(char* token, char s, int from){
    int pos = 0;
    if (!token || s == '\0')
        return -1;

    for (; *token; token++){
        if (from <= pos){
            if (*token == s)
                return pos;
        }
        pos++;
    }
    return -1;
}

char* substr(const char* string, int pos, int len){
    char* substring;
    int   i;
    int   length;

    if (string == NULL)
        return NULL;
    length = len - pos;

    if ((substring = malloc(sizeof(*substring)*(length + 1))) == NULL)
        return NULL;
    for (i = 0; pos != len; i++, pos++)
        substring[i] = string[pos];
    substring[i] = '\0';
    return substring;
}


int parsePulseTrain(int *pulses, int length, char *protocolBuffer) {
    int matches = 0;
    struct protocol_t *protocol = NULL;
    struct protocols_t *pnode = protocols;
  int strlength=0;

    while (pnode != NULL) {
        protocol = pnode->listener;

        if (protocol->parseCode != NULL && protocol->validate != NULL) {


            protocol->raw = pulses;
            protocol->rawlen = length;

            if (protocol->validate() == 0) {
                gettimeofday(&tv, NULL);
                if (protocol->first > 0) {
                    protocol->first = protocol->second;
                }

                protocol->second = 1000000 * (unsigned int)tv.tv_sec + (unsigned int)tv.tv_usec;

                if (protocol->first == 0) {
                    protocol->first = protocol->second;
                }

                if (((int)protocol->second - (int)protocol->first) > 500000) {
                    protocol->repeats = 0;
                }

                protocol->message = NULL;
                protocol->parseCode();
                if (protocol->message != NULL) {
                    matches++;
                    protocol->repeats++;

          if (protocol->message != NULL) {
              char *valid = json_stringify(protocol->message, NULL);
              json_delete(protocol->message);
              if (valid != NULL && json_validate(valid) == true) {
              int len=0;
                  struct JsonNode *jmessage = json_mkobject();
          
                  json_append_member(jmessage, "message", json_decode(valid));
                  json_append_member(jmessage, "origin", json_mkstring("receiver"));
                  json_append_member(jmessage, "protocol", json_mkstring(protocol->id));
                  if (strlen(pilight_uuid) > 0) {
                      json_append_member(jmessage, "uuid", json_mkstring(pilight_uuid));
                  }
                  if (protocol->repeats > -1) {
                      json_append_member(jmessage, "repeats", json_mknumber(protocol->repeats, 0));
                  }
                  char *output = json_stringify(jmessage, NULL);
                  struct JsonNode *json = json_decode(output);
              len = strlen(output);
              strncpy(&protocolBuffer[strlength], output, len);
              strlength += len;
                  json_free(output);
                  json_delete(json);
                  json = NULL;
                  json_delete(jmessage);
              }
              json_free(valid);
          }
          protocol->message = NULL;

                    json_delete(protocol->message);
                    protocol->message = NULL;
                }
            }
        }
        pnode = pnode->next;
    }
    return strlength;
}

int createPulseTrain(int *pulses, const char *protocol_id, const char *content) {
  struct protocol_t *protocol = NULL;
  struct protocols_t *pnode = protocols;
  int return_value = EXIT_FAILURE;
  JsonNode *message;

  if (json_validate(content) != true) {
    printf("invalid json: ");
    printf(content);
    return -2;
  }

  while (pnode != NULL) {
    protocol = pnode->listener;        
    if ((protocol->createCode != NULL) && (strcmp(protocol_id, protocol->id) == 0) && (protocol->maxrawlen <= MAXPULSESTREAMLENGTH)) {
      protocol->rawlen = 0;
      protocol->raw = pulses;
      message = json_decode(content);
      return_value = protocol->createCode(message);
      json_delete(message);

      if (return_value == EXIT_SUCCESS) {
        return protocol->rawlen;
      }
      else {
        return -1;
      }
    }
    pnode = pnode->next;
  }
  return 0;
}

int stringToPulseTrain(char *data, int *codes, int maxlength) {
    int start = 0, end = 0, pulse_index;
    int i = 0;
    int plstypes[MAX_PULSE_TYPES];


    for (i = 0; i<MAX_PULSE_TYPES; i++) {
        plstypes[i] = 0;
    }
    int scode = indexOf(data, 'c', 0) + 2;
    int spulse = indexOf(data, 'p', 0) + 2;


    if (scode > 0 && scode < strlen(data) && spulse > 0 && spulse < strlen(data)) {
        int nrpulses = 0, codelen = 0;
    char* sub[RECEIVER_BUFFER_SIZE];
        start = spulse;
        end = indexOf(data, ',', start);

        while (end > 0) {
            plstypes[nrpulses++] = atoi(substr(data, start, end));
            sub[0] = '\0';
            start = end + 1;
            end = indexOf(data, ',', start);
        }
        end = indexOf(data, ';', start);
        if (end < 0)
            end = indexOf(data, '@', start);
        if (end < 0)
            return -2;
        plstypes[nrpulses++] = atoi(substr(data, start, end));
        sub[0] = '\0';


        for (i = scode; i < strlen(data); i++) {
            if ((data[i] == ';') || (data[i] == '@'))
                break;
            if (i >= maxlength)
                break;
            pulse_index = data[i] - '0';
            if ((pulse_index < 0) || (pulse_index >= nrpulses))
                return -3;
            codes[codelen++] = plstypes[pulse_index];
        }
        return codelen;
    }
    return -1;
}

int pulseTrainTostring(int *code, int rawlen, int repeats, char* send) {
    unsigned int i = 0, x = 0, y = 0, len = 0, nrpulses = 0;
    int pulses[10], match = 0;
    char c[16];

    memset(send, 0, MAXPULSESTREAMLENGTH);
    strncpy(&send[0], "c:", 2);
    len += 2;

    for (i = 0; i < rawlen; i++) {
        match = -1;
        for (x = 0; x < nrpulses; x++) {
            if (pulses[x] == code[i]) {
                match = (int)x;
                break;
            }
        }
        if (match == -1) {
            pulses[nrpulses] = code[i];
            match = (int)nrpulses;
            nrpulses++;
        }
        if (match < 10) {
            send[len++] = (char)(((int)'0') + match);
        }
        else {
            printf("too many distinct pulses for pilight usb nano to send");
        }
    }

    strncpy(&send[len], ";p:", 3);
    len += 3;
    for (i = 0; i < nrpulses; i++) {
        y = (unsigned int)snprintf(c, sizeof(c), "%d", pulses[i]);
        strncpy(&send[len], c, y);
        len += y;
        if (i + 1 < nrpulses) {
            strncpy(&send[len++], ",", 1);
        }
    }
    strncpy(&send[len], ";r:", 3);
    len += 3;
    y = (unsigned int)snprintf(c, sizeof(c), "%d", repeats);
    strncpy(&send[len], c, y);
    len += y;
    strncpy(&send[len], "@", 1);
    len += 3;
    return strlen(send);
}

int main(int argc, char **argv) {
    int length=0, i=0,pulsecount=0;
    int pulses[MAXPULSESTREAMLENGTH];
  char buffer0[MAXPULSESTREAMLENGTH+1],buffer1[MAXPULSESTREAMLENGTH+1];
  if (protocols == NULL) protocol_init();

  pulsecount = stringToPulseTrain("c:010002000200020002000200020002000200020002000200020002000200020002000200020002000200020200000200020002020000020200000200020002020003;p:300,2700,1200,10200;r:3@", pulses, MAXPULSESTREAMLENGTH);
    for (i = 0; i < pulsecount; i++) {
        printf("%d", pulses[i]);
        printf(" ");
    }
    printf("\n\n");
  
  length = parsePulseTrain(pulses, pulsecount, buffer0);  
  for (i = 0; i < length; i++) {
        printf("%c", buffer0[i]);
    }
    printf("\n\n");
  
    length = pulseTrainTostring(pulses, pulsecount, 3, buffer1);
    for (i = 0; i < length; i++) {
        printf("%c", buffer1[i]);
    }
    printf("\n\n");

  length = createPulseTrain(pulses, "arctech_switch", "{\"id\":17,\"unit\":1,\"on\":1}");
    for (i = 0; i < length; i++) {
      printf("%d", pulses[i]);
      printf(" ");
    }
    printf("\n\n");

    return 0;
}
 
Reply
#2
Seems to be a nice example of thinkering with some shameless copy and pasting :p

I did add the license back into the header, because you missed to include it.

Nice work.
 
Reply
#3
Yes thank you to add it again.

It was not only C&P Tongue

Can you help me to add this to your setup script. Because the outputfile is about 2Mb and i dont know if this is good.
 
Reply
#4
If you have statically compiled the whole thing it can well be 2mb. The pilight shared lib is 10.3mb Smile
 
Reply
  


Possibly Related Threads...
Thread Author Replies Views Last Post
  Standalone but SSDP brenner23 6 3,334 04-16-2017, 11:34 PM
Last Post: brenner23

Forum Jump:


Browsing: 1 Guest(s)