// Copyright 2011 Juri Glass, Mathias Runge, Nadim El Sayed // DAI-Labor, TU-Berlin // // This file is part of libSML. // // libSML is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // libSML is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with libSML. If not, see . #include #include #include #include #include #include #include #include #include #include int serial_port_open(const char* device) { int bits; struct termios config; memset(&config, 0, sizeof(config)); int fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { printf("error: open(%s): %s\n", device, strerror(errno)); return -1; } // set RTS ioctl(fd, TIOCMGET, &bits); bits |= TIOCM_RTS; ioctl(fd, TIOCMSET, &bits); tcgetattr( fd, &config ) ; // set 8-N-1 config.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); config.c_oflag &= ~OPOST; config.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); config.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); config.c_cflag |= CS8; // set speed to 9600 baud cfsetispeed( &config, B9600); cfsetospeed( &config, B9600); tcsetattr(fd, TCSANOW, &config); return fd; } //void transport_receiver(unsigned char *buffer, size_t buffer_len) { // // the buffer contains the whole message, with transport escape sequences. // // these escape sequences are stripped here. // sml_file *file = sml_file_parse(buffer + 8, buffer_len - 16); // // the sml file is parsed now // // read here some values .. // // this prints some information about the file // sml_file_print(file); // // free the malloc'd memory // sml_file_free(file); //} void transport_receiver(unsigned char *buffer, size_t buffer_len) { // Danke an Axel (tuxedo) für seinen Beispielcode int i; double value; sml_file *file = sml_file_parse(buffer + 8, buffer_len - 16); // the sml file is parsed now for (i = 0; i < file->messages_len; i++) { sml_message *message = file->messages[i]; if (*message->message_body->tag == SML_MESSAGE_GET_LIST_RESPONSE) { sml_list *entry; sml_get_list_response *body; body = (sml_get_list_response *) message->message_body->data; for (entry = body->val_list; entry != NULL; entry = entry->next) { switch (entry->value->type) { case 0x51: value= *entry->value->data.int8; break; case 0x52: value= *entry->value->data.int16; break; case 0x54: value= *entry->value->data.int32; break; case 0x58: value= *entry->value->data.int64; break; case 0x61: value= *entry->value->data.uint8; break; case 0x62: value= *entry->value->data.uint16; break; case 0x64: value= *entry->value->data.uint32; break; case 0x68: value= *entry->value->data.uint64; break; default: value = 0; } int scaler = (entry->scaler) ? *entry->scaler : 1; if (scaler==-1) value *= 0.0001; if (value) { printf("%d-%d:%d.%d.%d*%d#%.3f#\n", entry->obj_name->str[0], entry->obj_name->str[1], entry->obj_name->str[2], entry->obj_name->str[3], entry->obj_name->str[4], entry->obj_name->str[5], value); } } sml_file_free(file); exit(0); // processed first message - exit } } } int main(int argc, char **argv) { // this example assumes that a EDL21 meter sending SML messages via a // serial device. Adjust as needed. // char *device = "/dev/cu.usbserial"; char *device=argv[1]; int fd = serial_port_open(device); if (fd > 0) { // listen on the serial device, this call is blocking. sml_transport_listen(fd, &transport_receiver); close(fd); } return 0; }