Ejemplo n.º 1
0
std::wstring StringUtilities::ToWString(const std::string& input) {
  // Assumption: The wstring character count will be the same as the length of
  // the string character count. Allocate the buffer with that many wchar_t items
  // so that the first MultiByteToWideChar call will succeed most of the time as
  // an optimization.
  std::wstring output = L"";
  int input_string_byte_count = static_cast<int>(input.size()) + 1;
  int wide_string_length = input_string_byte_count;
  std::vector<wchar_t> output_buffer(wide_string_length);
  bool convert_failed = (0 == ::MultiByteToWideChar(CP_UTF8,
                                                    0,
                                                    input.c_str(),
                                                    input_string_byte_count,
                                                    &output_buffer[0],
                                                    wide_string_length));
  if (convert_failed) {
    if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
      // Buffer wasn't big enough. Call MultiByteToWideChar again with
      // NULL values to determine how big the buffer should be.
      wide_string_length = ::MultiByteToWideChar(CP_UTF8,
                                                 0,
                                                 input.c_str(),
                                                 input_string_byte_count,
                                                 NULL,
                                                 0);
      output_buffer.resize(wide_string_length);
      convert_failed = (0 == ::MultiByteToWideChar(CP_UTF8,
                                                   0,
                                                   input.c_str(),
                                                   input_string_byte_count,
                                                   &output_buffer[0],
                                                   wide_string_length));
      if (!convert_failed) {
        output = &output_buffer[0];
      }
    }
  } else {
    output = &output_buffer[0];
  }
  return output;
}
Ejemplo n.º 2
0
int send_data(dtls_connection_t *connP,
                    uint8_t * buffer,
                    size_t length)
{
    int nbSent;
    size_t offset;

#ifdef WITH_LOGS
    char s[INET6_ADDRSTRLEN];
    in_port_t port;

    s[0] = 0;

    if (AF_INET == connP->addr.sin6_family)
    {
        struct sockaddr_in *saddr = (struct sockaddr_in *)&connP->addr;
        inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
        port = saddr->sin_port;
    }
    else if (AF_INET6 == connP->addr.sin6_family)
    {
        struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&connP->addr;
        inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
        port = saddr->sin6_port;
    }

    fprintf(stderr, "Sending %d bytes to [%s]:%hu\r\n", length, s, ntohs(port));

    output_buffer(stderr, buffer, length, 0);
#endif

    offset = 0;
    while (offset != length)
    {
        nbSent = sendto(connP->sock, buffer + offset, length - offset, 0, (struct sockaddr *)&(connP->addr), connP->addrLen);
        if (nbSent == -1) return -1;
        offset += nbSent;
    }
    connP->lastSend = lwm2m_gettime();
    return 0;
}
Ejemplo n.º 3
0
void SaveLz4(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, int compression_level)
{
#ifdef HAVE_LZ4

  const int64_t src_size = image.SizeBytes();
  const int64_t max_dst_size = LZ4_compressBound(src_size);
  std::unique_ptr<char[]> output_buffer(new char[max_dst_size]);

  // Same as LZ4_compress_default(), but allows to select an "acceleration" factor. 
  // The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
  // It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
  // An acceleration value of "1" is the same as regular LZ4_compress_default()
  // Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. 
  const int64_t compressed_data_size = LZ4_compress_fast((char*)image.ptr, output_buffer.get(), src_size, max_dst_size, compression_level);

  if (compressed_data_size < 0)
    throw std::runtime_error("A negative result from LZ4_compress_default indicates a failure trying to compress the data.");
  if (compressed_data_size == 0)
    throw std::runtime_error("A result of 0 for LZ4 means compression worked, but was stopped because the destination buffer couldn't hold all the information.");

    lz4_image_header header;
    strncpy(header.magic,"LZ4",3);
    strncpy(header.fmt, fmt.format.c_str(), sizeof(header.fmt));
    header.w = image.w;
    header.h = image.h;
    header.compressed_size = compressed_data_size;
    out.write((char*)&header, sizeof(header));

  out.write(output_buffer.get(), compressed_data_size);

#else
    PANGOLIN_UNUSED(image);
    PANGOLIN_UNUSED(fmt);
    PANGOLIN_UNUSED(out);
    PANGOLIN_UNUSED(compression_level);
    throw std::runtime_error("Rebuild Pangolin for LZ4 support.");
#endif // HAVE_LZ4
}
Ejemplo n.º 4
0
void dump_tlv(FILE * stream,
              int size,
              lwm2m_data_t * dataP,
              int indent)
{
    int i;

    for(i= 0 ; i < size ; i++)
    {
        print_indent(stream, indent);
        fprintf(stream, "{\r\n");
        print_indent(stream, indent+1);
        fprintf(stream, "id: %d\r\n", dataP[i].id);

        print_indent(stream, indent+1);
        fprintf(stream, "type: ");
        switch (dataP[i].type)
        {
        case LWM2M_TYPE_OBJECT:
            fprintf(stream, "LWM2M_TYPE_OBJECT\r\n");
            dump_tlv(stream, dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, indent + 1);
            break;
        case LWM2M_TYPE_OBJECT_INSTANCE:
            fprintf(stream, "LWM2M_TYPE_OBJECT_INSTANCE\r\n");
            dump_tlv(stream, dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, indent + 1);
            break;
        case LWM2M_TYPE_MULTIPLE_RESOURCE:
            fprintf(stream, "LWM2M_TYPE_MULTIPLE_RESOURCE\r\n");
            dump_tlv(stream, dataP[i].value.asChildren.count, dataP[i].value.asChildren.array, indent + 1);
            break;
        case LWM2M_TYPE_UNDEFINED:
            fprintf(stream, "LWM2M_TYPE_UNDEFINED\r\n");
            break;
        case LWM2M_TYPE_STRING:
            fprintf(stream, "LWM2M_TYPE_STRING\r\n");
            print_indent(stream, indent + 1);
            fprintf(stream, "\"%.*s\"\r\n", dataP[i].value.asBuffer.length, dataP[i].value.asBuffer.buffer);
            break;
        case LWM2M_TYPE_OPAQUE:
            fprintf(stream, "LWM2M_TYPE_OPAQUE\r\n");
            output_buffer(stream, dataP[i].value.asBuffer.buffer, dataP[i].value.asBuffer.length, indent + 1);
            break;
        case LWM2M_TYPE_INTEGER:
            fprintf(stream, "LWM2M_TYPE_INTEGER: ");
            print_indent(stream, indent + 1);
            fprintf(stream, "%" PRId64, dataP[i].value.asInteger);
            fprintf(stream, "\r\n");
            break;
        case LWM2M_TYPE_FLOAT:
            fprintf(stream, "LWM2M_TYPE_FLOAT: ");
            print_indent(stream, indent + 1);
            fprintf(stream, "%f", dataP[i].value.asInteger);
            fprintf(stream, "\r\n");
            break;
        case LWM2M_TYPE_BOOLEAN:
            fprintf(stream, "LWM2M_TYPE_BOOLEAN: ");
            fprintf(stream, "%s", dataP[i].value.asBoolean ? "true" : "false");
            fprintf(stream, "\r\n");
            break;
        case LWM2M_TYPE_OBJECT_LINK:
            fprintf(stream, "LWM2M_TYPE_OBJECT_LINK\r\n");
            break;
        default:
            fprintf(stream, "unknown (%d)\r\n", (int)dataP[i].type);
            break;
        }
        print_indent(stream, indent);
        fprintf(stream, "}\r\n");
    }
}
Ejemplo n.º 5
0
void output_tlv(FILE * stream,
                uint8_t * buffer,
                size_t buffer_len,
                int indent)
{
    lwm2m_data_type_t type;
    uint16_t id;
    size_t dataIndex;
    size_t dataLen;
    int length = 0;
    int result;

    while (0 != (result = lwm2m_decode_TLV((uint8_t*)buffer + length, buffer_len - length, &type, &id, &dataIndex, &dataLen)))
    {
        print_indent(stream, indent);
        fprintf(stream, "{\r\n");
        print_indent(stream, indent+1);
        fprintf(stream, "ID: %d", id);

        fprintf(stream, " type: ");
        switch (type)
        {
        case LWM2M_TYPE_OBJECT_INSTANCE:
            fprintf(stream, "Object Instance");
            break;
        case LWM2M_TYPE_MULTIPLE_RESOURCE:
            fprintf(stream, "Multiple Instances");
            break;
        case LWM2M_TYPE_OPAQUE:
            fprintf(stream, "Resource Value");
            break;
        default:
            printf("unknown (%d)", (int)type);
            break;
        }
        fprintf(stream, "\n");

        print_indent(stream, indent+1);
        fprintf(stream, "{\n");
        if (type == LWM2M_TYPE_OBJECT_INSTANCE || type == LWM2M_TYPE_MULTIPLE_RESOURCE)
        {
            output_tlv(stream, buffer + length + dataIndex, dataLen, indent+1);
        }
        else
        {
            int64_t intValue;
            double floatValue;
            uint8_t tmp;

            print_indent(stream, indent+2);
            fprintf(stream, "data (%ld bytes):\r\n", dataLen);
            output_buffer(stream, (uint8_t*)buffer + length + dataIndex, dataLen, indent+2);

            tmp = buffer[length + dataIndex + dataLen];
            buffer[length + dataIndex + dataLen] = 0;
            if (0 < sscanf(buffer + length + dataIndex, "%"PRId64, &intValue))
            {
                print_indent(stream, indent+2);
                fprintf(stream, "data as Integer: %" PRId64 "\r\n", intValue);
            }
            if (0 < sscanf(buffer + length + dataIndex, "%g", &floatValue))
            {
                print_indent(stream, indent+2);
                fprintf(stream, "data as Float: %.16g\r\n", floatValue);
            }
            buffer[length + dataIndex + dataLen] = tmp;
        }
        print_indent(stream, indent+1);
        fprintf(stream, "}\r\n");
        length += result;
        print_indent(stream, indent);
        fprintf(stream, "}\r\n");
    }
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
    int sock;
    fd_set readfds;
    struct timeval tv;
    int result;
    lwm2m_context_t * lwm2mH = NULL;
    int i;
    connection_t * connList = NULL;
    int addressFamily = AF_INET6;
    int opt;

    command_desc_t commands[] =
    {
            {"list", "List registered clients.", NULL, prv_output_clients, NULL},
            {"read", "Read from a client.", " read CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to read such as /3, /3/0/2, /1024/11, /1024/0/1\r\n"
                                            "Result will be displayed asynchronously.", prv_read_client, NULL},
            {"disc", "Discover resources of a client.", " disc CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to discover such as /3, /3/0/2, /1024/11, /1024/0/1\r\n"
                                            "Result will be displayed asynchronously.", prv_discover_client, NULL},
            {"write", "Write to a client.", " write CLIENT# URI DATA\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to write to such as /3, /3/0/2, /1024/11, /1024/0/1\r\n"
                                            "   DATA: data to write\r\n"
                                            "Result will be displayed asynchronously.", prv_write_client, NULL},
            {"time", "Write time-related attributes to a client.", " time CLIENT# URI PMIN PMAX\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to write attributes to such as /3, /3/0/2, /1024/11, /1024/0/1\r\n"
                                            "   PMIN: Minimum period\r\n"
                                            "   PMAX: Maximum period\r\n"
                                            "Result will be displayed asynchronously.", prv_time_client, NULL},
            {"attr", "Write value-related attributes to a client.", " attr CLIENT# URI LT GT [STEP]\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to write attributes to such as /3, /3/0/2, /1024/11, /1024/0/1\r\n"
                                            "   LT: \"Less than\" value\r\n"
                                            "   GT: \"Greater than\" value\r\n"
                                            "   STEP: \"Step\" value\r\n"
                                            "Result will be displayed asynchronously.", prv_attr_client, NULL},
            {"clear", "Clear attributes of a client.", " clear CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to clear attributes of such as /3, /3/0/2, /1024/11, /1024/0/1\r\n"
                                            "Result will be displayed asynchronously.", prv_clear_client, NULL},
            {"exec", "Execute a client resource.", " exec CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri of the resource to execute such as /3/0/2\r\n"
                                            "Result will be displayed asynchronously.", prv_exec_client, NULL},
            {"del", "Delete a client Object instance.", " del CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri of the instance to delete such as /1024/11\r\n"
                                            "Result will be displayed asynchronously.", prv_delete_client, NULL},
            {"create", "create an Object instance.", " create CLIENT# URI DATA\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to which create the Object Instance such as /1024, /1024/45 \r\n"
                                            "   DATA: data to initialize the new Object Instance (0-255 for object 1024) \r\n"
                                            "Result will be displayed asynchronously.", prv_create_client, NULL},
            {"observe", "Observe from a client.", " observe CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri to observe such as /3, /3/0/2, /1024/11\r\n"
                                            "Result will be displayed asynchronously.", prv_observe_client, NULL},
            {"cancel", "Cancel an observe.", " cancel CLIENT# URI\r\n"
                                            "   CLIENT#: client number as returned by command 'list'\r\n"
                                            "   URI: uri on which to cancel an observe such as /3, /3/0/2, /1024/11\r\n"
                                            "Result will be displayed asynchronously.", prv_cancel_client, NULL},

            {"q", "Quit the server.", NULL, prv_quit, NULL},

            COMMAND_END_LIST
    };

    while ((opt = getopt(argc, argv, "4")) != -1)
    {
        switch (opt)
        {
        case '4':
            addressFamily = AF_INET;
            break;
        default:
            print_usage();
            return 0;
        }
    }


    sock = create_socket(LWM2M_STANDARD_PORT_STR, addressFamily);
    if (sock < 0)
    {
        fprintf(stderr, "Error opening socket: %d\r\n", errno);
        return -1;
    }

    lwm2mH = lwm2m_init(NULL);
    if (NULL == lwm2mH)
    {
        fprintf(stderr, "lwm2m_init() failed\r\n");
        return -1;
    }

    signal(SIGINT, handle_sigint);

    for (i = 0 ; commands[i].name != NULL ; i++)
    {
        commands[i].userData = (void *)lwm2mH;
    }
    fprintf(stdout, "> "); fflush(stdout);

    lwm2m_set_monitoring_callback(lwm2mH, prv_monitor_callback, lwm2mH);

    while (0 == g_quit)
    {
        FD_ZERO(&readfds);
        FD_SET(sock, &readfds);
        FD_SET(STDIN_FILENO, &readfds);

        tv.tv_sec = 60;
        tv.tv_usec = 0;

        result = lwm2m_step(lwm2mH, &(tv.tv_sec));
        if (result != 0)
        {
            fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
            return -1;
        }

        result = select(FD_SETSIZE, &readfds, 0, 0, &tv);

        if ( result < 0 )
        {
            if (errno != EINTR)
            {
              fprintf(stderr, "Error in select(): %d\r\n", errno);
            }
        }
        else if (result > 0)
        {
            uint8_t buffer[MAX_PACKET_SIZE];
            int numBytes;

            if (FD_ISSET(sock, &readfds))
            {
                struct sockaddr_storage addr;
                socklen_t addrLen;

                addrLen = sizeof(addr);
                numBytes = recvfrom(sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen);

                if (numBytes == -1)
                {
                    fprintf(stderr, "Error in recvfrom(): %d\r\n", errno);
                }
                else
                {
                    char s[INET6_ADDRSTRLEN];
                    in_port_t port;
                    connection_t * connP;

					s[0] = 0;
                    if (AF_INET == addr.ss_family)
                    {
                        struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
                        inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin_port;
                    }
                    else if (AF_INET6 == addr.ss_family)
                    {
                        struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
                        inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin6_port;
                    }

                    fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port));
                    output_buffer(stderr, buffer, numBytes, 0);

                    connP = connection_find(connList, &addr, addrLen);
                    if (connP == NULL)
                    {
                        connP = connection_new_incoming(connList, sock, (struct sockaddr *)&addr, addrLen);
                        if (connP != NULL)
                        {
                            connList = connP;
                        }
                    }
                    if (connP != NULL)
                    {
                        lwm2m_handle_packet(lwm2mH, buffer, numBytes, connP);
                    }
                }
            }
            else if (FD_ISSET(STDIN_FILENO, &readfds))
            {
                numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1);

                if (numBytes > 1)
                {
                    buffer[numBytes] = 0;
                    handle_command(commands, (char*)buffer);
                    fprintf(stdout, "\r\n");
                }
                if (g_quit == 0)
                {
                    fprintf(stdout, "> ");
                    fflush(stdout);
                }
                else
                {
                    fprintf(stdout, "\r\n");
                }
            }
        }
    }

    lwm2m_close(lwm2mH);
    close(sock);
    connection_free(connList);

#ifdef MEMORY_TRACE
    if (g_quit == 1)
    {
        trace_print(0, 1);
    }
#endif

    return 0;
}
Ejemplo n.º 7
0
static void flush_input_buffer(WORDWRAP *wrapper, bool force_flush)
{
  z_ucs *index = NULL, *ptr, *hyphenated_word, *last_hyphen, *word_start;
  z_ucs *word_end_without_split_chars, *word_end_with_split_chars;
  z_ucs buf=0, buf2; // buf initialized to avoid compiler warning
  z_ucs buf3 = '-'; // buf3 initialized to avoid compiler warning
  long len, chars_sent = 0;
  z_ucs *input = wrapper->input_buffer;
  bool minus_found;
  int metadata_offset = 0;
  int i, chars_left_on_line;
  //int hyphen_offset;
  struct wordwrap_metadata *metadata_entry;

  input[wrapper->input_index] = 0;
  TRACE_LOG("input-index: %ld\n", wrapper->input_index);

  TRACE_LOG("metadata stored: %d.\n", wrapper->metadata_index);

  for (;;)
  {
    TRACE_LOG("Processing flush.\n");

    if (*input != 0)
    {
      TRACE_LOG("flush wordwrap-buffer: \"");
      TRACE_LOG_Z_UCS(input);
      TRACE_LOG("\".\n");
    }

    if ((index = z_ucs_chr(input, Z_UCS_NEWLINE)) != NULL)
      len = index - input;
    else
    {
      len = z_ucs_len(input);
      TRACE_LOG("len:%ld, force:%d.\n", len, force_flush);

      if (len == 0)
      {
        if (force_flush == true)
        {
          // Force flush metadata behind end of output.
          while (metadata_offset < wrapper->metadata_index)
          {
            TRACE_LOG("flush post-output metadata at: %ld.\n",
                wrapper->metadata[metadata_offset].output_index);

            metadata_entry = &wrapper->metadata[metadata_offset];

            TRACE_LOG("Output metadata prm %d.\n",
                metadata_entry->int_parameter);

            metadata_entry->metadata_output_function(
                metadata_entry->ptr_parameter,
                metadata_entry->int_parameter);

            metadata_offset++;
          }
        }
        break;
      }

      if ( (len <= wrapper->line_length) && (force_flush == false) )
        // We're quitting on len == wrapper->line_length since we can only
        // determine wether we can break cleanly is if a space follows
        // immediately after the last char.
        break;

      // FIXME: Add break in case hyph is enabled and a word longer than
      // the line is not terminated with a space.
    }

    TRACE_LOG("wordwrap-flush-len: %ld.\n", len);

    if (len <= wrapper->line_length)
    {
      // Line fits on screen.
      TRACE_LOG("Line fits on screen.\n");
      if (index != NULL)
      {
        index++;
        len++;
        buf = *index;
        *index = 0;
      }
      chars_sent += len;

      output_buffer(wrapper, input, &metadata_offset);
      if (wrapper->left_side_padding != 0)
        wrapper->wrapped_text_output_destination(
            wrapper->padding_buffer,
            wrapper->destination_parameter);

      if (index != NULL)
        *index = buf;
      else
      {
        //wrapper->input_index = 0;
        break;
      }
    }
    else if (wrapper->enable_hyphenation == true)
    {
      TRACE_LOG("to wrap/hyphenate (force:%d): \"", force_flush);
      TRACE_LOG_Z_UCS(input);
      TRACE_LOG("\".\n");

      if ((word_end_without_split_chars = z_ucs_chrs(
              input + wrapper->line_length, word_split_chars)) == NULL)
      {
        if (force_flush == true)
          word_end_without_split_chars = input + len;
        else
        {
          TRACE_LOG("No word end found.\n");
          break;
        }
      }

      // We'll remeber the current position of the word-split-char we've
      // just found in "word_end_without_split_chars" and advance this pointer
      // until we won't find any more word-split-chars. Thus, if we've just
      // found the start dot of an ellipsis "..." we'll end up with the
      // position of the last dot.
      word_end_with_split_chars = word_end_without_split_chars;
      while ((ptr = z_ucs_chr(
              word_split_chars, *word_end_with_split_chars)) != NULL)
        word_end_with_split_chars++;
      // Now we've stored the end of the word in "word_end_without_split_chars".

      // We've now found a word boundary. This char may however not be part
      // of the actual last word (we might have hit a minus representing
      // a n- or m-dash--like this--or an elipsis like "..."). So we'll
      // rewind further if necessary.
      TRACE_LOG("examining split end:\"%c\".\n", *word_end_without_split_chars);
      //while (word_end_without_split_chars - 1 > input + wrapper->line_length)
      while (word_end_without_split_chars > input)
      {
        TRACE_LOG("Checking for split-char: %c/%d.\n",
            *word_end_without_split_chars, *word_end_without_split_chars);
        if (z_ucs_chr(
              word_split_chars, *(word_end_without_split_chars - 1)) == NULL)
          break;
        word_end_without_split_chars--;
      }

      if (
          (word_end_without_split_chars != word_end_with_split_chars)
          &&
          (*word_end_without_split_chars == Z_UCS_SPACE)
          &&
          (word_end_without_split_chars < input + wrapper->line_length)
         )
      {
        // In this case we have skipped a number of stand-alone word-split-
        // chars (like the elipsis in "Powers -- these") and are now so far
        // back that we can split right at the space before these chars.
        index = word_end_without_split_chars;
        last_hyphen = NULL;
      }
      else
      {
        word_start = NULL;

        // In case we've now found a word end, check for dashes before it.
        // Example: "first-class car", where the word end we've now found is
        // between "first-class" and "car".
        word_start = word_end_without_split_chars - 1;
        while (word_start > input)
        {
          TRACE_LOG("examining word end: \"%c\".\n", *word_start);
          if (*word_start == Z_UCS_MINUS)
          {
            if (input + wrapper->line_length > word_start)
            {
              // Found a dash to break on
              word_start++;
              break;
            }
          }
          else if ((ptr = z_ucs_chr(word_split_chars, *word_start)) != NULL)
          {
            // In case we've found a non-dash separator, we've found the
            // start of the word.
            word_start++;
            break;
          }
          word_start--;
        }

        // FIXME: Do we need a space left from here?

        TRACE_LOG("word-start: %c\n", *word_start);

        TRACE_LOG("%p / %p\n", word_end_without_split_chars,
            word_end_with_split_chars);

        TRACE_LOG("%c / %c\n", *word_end_without_split_chars,
            *word_end_with_split_chars);

        TRACE_LOG("%p / %p\n",
            word_end_without_split_chars, input + wrapper->line_length);

        last_hyphen = NULL;

        if (word_end_with_split_chars > input + wrapper->line_length)
        {
          // We only have to hyphenate in case the line is still too long.

          buf = *word_end_without_split_chars;
          *word_end_without_split_chars = 0;

          TRACE_LOG("buffer terminated at word end: \"");
          TRACE_LOG_Z_UCS(input);
          TRACE_LOG("\".\n");

          index = word_start;

          if ((hyphenated_word = hyphenate(index)) == NULL)
          {
            TRACE_LOG("Error hyphenating.\n");
            i18n_translate_and_exit(
                libfizmo_module_name,
                i18n_libfizmo_UNKNOWN_ERROR_CASE,
                -1);
          }
          *word_end_without_split_chars = buf;

          chars_left_on_line = wrapper->line_length - (index - input);
          TRACE_LOG("chars left on line: %d\n", chars_left_on_line);

          //hyphen_offset = index - input;

          ptr = hyphenated_word;
          while (chars_left_on_line > 0)
          {
            TRACE_LOG("Testing %c for hyphen.\n", *ptr);
            if (*ptr == Z_UCS_SOFT_HYPEN)
              last_hyphen = input + (wrapper->line_length - chars_left_on_line);
            else
              chars_left_on_line--;
            ptr++;
          }
          free(hyphenated_word);

          if (last_hyphen != NULL)
          {
            TRACE_LOG("Last hyphen at %ld.\n", last_hyphen - input);
            buf3 = *last_hyphen;
            *last_hyphen = '-';

            index = last_hyphen + 1;
          }
          else if ( (word_start != input) && (*(word_start-1) != Z_UCS_MINUS) )
          {
            TRACE_LOG("No hyphen found.\n");
            index--;
          }
        }
        else
        {
          index = word_end_with_split_chars;
        }
      }

      // Output everything before *index and a newline after.

      buf2 = *index;
      *index = Z_UCS_NEWLINE;
      buf = *(index + 1);
      *(index + 1) = 0;

      output_buffer(wrapper, input, &metadata_offset);
      if (wrapper->left_side_padding != 0)
        wrapper->wrapped_text_output_destination(
            wrapper->padding_buffer,
            wrapper->destination_parameter);

      *(index + 1) = buf;
      *index = buf2;

      if (last_hyphen != NULL)
      {
        *last_hyphen = buf3;
        index--;
      }

      if (*index == Z_UCS_SPACE)
        index++;

      len = index - input;
      chars_sent += len;

      TRACE_LOG("Processed %ld chars in hyphenated wordwrap.\n", len);
    }
    else
    {
      // Line won't fit completely. Find the end of the last word.
      TRACE_LOG("linelength: %d.\n", wrapper->line_length);

      //word_end_with_split_chars = NULL;
      ptr = input + wrapper->line_length;
      if (*ptr == Z_UCS_SPACE)
        ptr++;
      TRACE_LOG("%p/%p/%c\n", input, ptr, *ptr);
      buf = *ptr;
      *ptr = 0;
      TRACE_LOG("examine buffer: \"");
      TRACE_LOG_Z_UCS(input);
      TRACE_LOG("\".\n");

      index = z_ucs_rchrs(input, word_split_chars);
      if (*index == Z_UCS_MINUS)
      {
        minus_found = true;
        index++;
      }
      else
        minus_found = false;
      TRACE_LOG("Found word-split at %p from %p.\n", index, input);
      *ptr = buf;

      if (index == NULL)
        index = input + wrapper->line_length;

      buf = *index;
      *index = Z_UCS_NEWLINE;
      buf2 = *(index+1);
      *(index+1) = 0;

      TRACE_LOG("Output from %p.\n", input);

      output_buffer(wrapper, input, &metadata_offset);
      if (wrapper->left_side_padding != 0)
        wrapper->wrapped_text_output_destination(
            wrapper->padding_buffer,
            wrapper->destination_parameter);

      *(index+1) = buf2;
      *index = buf;

      if (minus_found == false)
        index++;

      len = index - input;
      chars_sent += len;
    }

    TRACE_LOG("len-after: %ld.\n", len);

    if (index != NULL)
    {
      TRACE_LOG("index: \"");
      TRACE_LOG_Z_UCS(index);
      TRACE_LOG("\".\n");
    }

    input += len;
  }

  TRACE_LOG("chars sent: %ld, moving: %ld.\n",
      chars_sent, wrapper->input_index - chars_sent + 1);

  memmove(
      wrapper->input_buffer,
      input,
      sizeof(z_ucs) * (wrapper->input_index - chars_sent + 1));

  wrapper->input_index -= chars_sent;

  if (metadata_offset > 0)
  {
    memmove(
        wrapper->metadata,
        wrapper->metadata + metadata_offset,
        sizeof(struct wordwrap_metadata)
        * (wrapper->metadata_index - metadata_offset));
    wrapper->metadata_index -= metadata_offset;

    TRACE_LOG("metadata stored: %d.\n", wrapper->metadata_index);
  }

  for (i=0; i<wrapper->metadata_index; i++)
    wrapper->metadata[i].output_index -= chars_sent;
}
Ejemplo n.º 8
0
/* a tristate buffer is used to handle fan-ins
 * The area of an unbalanced htree (rows != columns)
 * depends on how data is traversed.
 * In the following function, if ( no. of rows < no. of columns),
 * then data first traverse in excess hor. links until vertical
 * and horizontal nodes are same.
 * If no. of rows is bigger, then data traverse in
 * a hor. link followed by a ver. link in a repeated
 * fashion (similar to a balanced tree) until there are no
 * hor. links left. After this it goes through the remaining vertical
 * links.
 */
void Htree2::out_htree()
{
  //temp var
  double s1 = 0, s2 = 0, s3 = 0;
  double l_eff = 0;
  Wire *wtemp1 = 0, *wtemp2 = 0, *wtemp3 = 0;
  double len = 0, ht = 0;
  int option = 0;

  int h = (int) _log2(ndwl);
  int v = (int) _log2(ndbl);
  double hdist;
  double vdist;
  if (ndwl == ndbl) {
    hdist = ndwl/2 - 1;
    vdist = hdist;
  }
  else if (ndwl > ndbl) {
    hdist = ndbl/2-1 + (_log2(ndwl/2) - _log2(ndbl/2));
    vdist = pow(2, (_log2(ndwl/2) - _log2(ndbl/2))) * (ndbl/2-1);
  }
  else {
    hdist = ndwl/2-1;
    vdist = ndwl/2-1 + ((ndwl/2)/2)*(_log2(ndbl/2)-_log2(ndwl/2));
  }
  double len_temp;
  double ht_temp;
  if (uca_tree) {
    ht_temp = (mat_height*ndbl /* mat height => bank height */ +
      (add_bits + data_in_bits + data_out_bits+ (search_data_in_bits + search_data_out_bits)) * hdist * g_tp.wire_outside_mat.pitch)/2;
  len_temp = (mat_width*ndwl /* mat width => bank width */ +
      (add_bits + data_in_bits + data_out_bits+ (search_data_in_bits + search_data_out_bits)) * g_tp.wire_outside_mat.pitch * vdist)/2;
  }
  else {
    if (ndwl == ndbl) {
      ht_temp = ((mat_height*ndbl/2) +
          ((add_bits + (search_data_in_bits + search_data_out_bits)) * hdist * g_tp.wire_outside_mat.pitch) +
          ((data_in_bits + data_out_bits) * g_tp.wire_outside_mat.pitch * hdist)
          )/2;
    }
    else if (ndwl > ndbl) {
      double excess_part = (_log2(ndwl/2) - _log2(ndbl/2));
      ht_temp = ((mat_height*ndbl/2) +
          ((add_bits + (search_data_in_bits + search_data_out_bits)) * hdist * g_tp.wire_outside_mat.pitch) +
          (((data_in_bits + data_out_bits) * g_tp.wire_outside_mat.pitch * (ndbl/2-1)) +
          (2 *(data_in_bits + data_out_bits) * g_tp.wire_outside_mat.pitch * (1 - pow(0.5, excess_part+1))))
          )/2;
    }
    else {
      ht_temp = ((mat_height*ndbl/2) +
          ((add_bits + (search_data_in_bits + search_data_out_bits)) * hdist * g_tp.wire_outside_mat.pitch) +
          ((data_in_bits + data_out_bits) * g_tp.wire_outside_mat.pitch * hdist)
          )/2;
    }
    len_temp = (mat_width*ndwl/2 +
        (add_bits + data_in_bits + data_out_bits + (search_data_in_bits + search_data_out_bits)) * g_tp.wire_outside_mat.pitch * vdist)/2;
  }
  area.h = ht_temp * 2;
  area.w = len_temp * 2;
  delay = 0;
  power.readOp.dynamic = 0;
  power.readOp.leakage = 0;
  power.readOp.gate_leakage = 0;
  //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
  len = len_temp;
  ht = ht_temp/2;

  while (v > 0 || h > 0)
  { //finds delay/power of each link in the tree
    if (wtemp1) delete wtemp1;
    if (wtemp2) delete wtemp2;
    if (wtemp3) delete wtemp3;

    if(h > v) {
      //the iteration considers only one horizontal link
      wtemp1 = new Wire(wt, len); // hor
      wtemp2 = new Wire(wt, len/2);  // ver
      len_temp = len;
      len /= 2;
      wtemp3 = 0;
      h--;
      option = 0;
    }
    else if (v>0 && h>0) {
      //considers one horizontal link and one vertical link
      wtemp1 = new Wire(wt, len); // hor
      wtemp2 = new Wire(wt, ht);  // ver
      wtemp3 = new Wire(wt, len/2);  // next hor
      len_temp = len;
      ht_temp = ht;
      len /= 2;
      ht /= 2;
      v--;
      h--;
      option = 1;
    }
    else {
      // considers only one vertical link
      assert(h == 0);
      wtemp1 = new Wire(wt, ht); // hor
      wtemp2 = new Wire(wt, ht/2);  // ver
      ht_temp = ht;
      ht /= 2;
      wtemp3 = 0;
      v--;
      option = 2;
    }
    delay += wtemp1->delay;
    power.readOp.dynamic += wtemp1->power.readOp.dynamic;
    power.searchOp.dynamic += wtemp1->power.readOp.dynamic*init_wire_bw;
    power.readOp.leakage += wtemp1->power.readOp.leakage*wire_bw;
    power.readOp.gate_leakage += wtemp1->power.readOp.gate_leakage*wire_bw;
    //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
    if ((uca_tree == false && option == 2) || search_tree==true)
    {
      wire_bw*=2;
    }

    if (uca_tree == false)
    {
      if (len_temp > wtemp1->repeater_spacing)
      {
        s1 = wtemp1->repeater_size;
        l_eff = wtemp1->repeater_spacing;
      }
      else
      {
        s1 = (len_temp/wtemp1->repeater_spacing) * wtemp1->repeater_size;
        l_eff = len_temp;
      }
      if (ht_temp > wtemp2->repeater_spacing)
      {
        s2 = wtemp2->repeater_size;
      }
      else
      {
        s2 = (len_temp/wtemp2->repeater_spacing) * wtemp2->repeater_size;
      }
      // first level
      output_buffer(s1, s2, l_eff);
    }


    if (option != 1)
    {
      continue;
    }

    // second level
    delay += wtemp2->delay;
    power.readOp.dynamic += wtemp2->power.readOp.dynamic;
    power.searchOp.dynamic += wtemp2->power.readOp.dynamic*init_wire_bw;
    power.readOp.leakage += wtemp2->power.readOp.leakage*wire_bw;
    power.readOp.gate_leakage += wtemp2->power.readOp.gate_leakage*wire_bw;
    //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
    if (uca_tree)
    {
      power.readOp.leakage += (wtemp2->power.readOp.leakage*wire_bw);
      power.readOp.gate_leakage += wtemp2->power.readOp.gate_leakage*wire_bw;
    }
    else
    {
      power.readOp.leakage += (wtemp2->power.readOp.leakage*wire_bw);
      power.readOp.gate_leakage += wtemp2->power.readOp.gate_leakage*wire_bw;
      wire_bw*=2;

      if (ht_temp > wtemp3->repeater_spacing)
      {
        s3 = wtemp3->repeater_size;
        l_eff = wtemp3->repeater_spacing;
      }
      else
      {
        s3 = (len_temp/wtemp3->repeater_spacing) * wtemp3->repeater_size;
        l_eff = ht_temp;
      }

      output_buffer(s2, s3, l_eff);
    }
    //cout<<"power.readOp.leakage"<<power.readOp.leakage<<endl;
    //cout<<"power.readOp.gate_leakage"<<power.readOp.gate_leakage<<endl;
    //cout<<"wtemp2->power.readOp.gate_leakage"<<wtemp2->power.readOp.gate_leakage<<endl;
  }

  if (wtemp1) delete wtemp1;
  if (wtemp2) delete wtemp2;
  if (wtemp3) delete wtemp3;
}
Ejemplo n.º 9
0
static void flush_input_buffer(WORDWRAP *wrapper, bool force_flush)
{
  z_ucs *index = NULL, *ptr, *hyphenated_word, *last_hyphen, *word_start;
  z_ucs *word_end, *input = wrapper->input_buffer, *first_space_or_newline;
  z_ucs buf=0, buf2; // buf initialized to avoid compiler warning
  z_ucs buf3 = '-'; // buf3 initialized to avoid compiler warning
  long len, chars_sent = 0;
  int metadata_offset = 0, i, chars_left_on_line;
  struct wordwrap_metadata *metadata_entry;
  int current_line_length
    = wrapper->line_length - wrapper->chars_already_on_line;

  input[wrapper->input_index] = 0;
  TRACE_LOG("input-index: %ld\n", wrapper->input_index);

  TRACE_LOG("metadata stored: %d.\n", wrapper->metadata_index);

  for (;;)
  {
    TRACE_LOG("Processing flush for line-length %d, already in line: %d.\n",
        current_line_length, wrapper->chars_already_on_line);

    if (*input != 0)
    {
      TRACE_LOG("flush wordwrap-buffer at %p: \"", input);
      TRACE_LOG_Z_UCS(input);
      TRACE_LOG("\".\n");
    }

    if ((index = z_ucs_chr(input, Z_UCS_NEWLINE)) != NULL) {
      len = index - input;
    }
    else
    {
      len = z_ucs_len(input);
      TRACE_LOG("len:%ld, force:%d.\n", len, force_flush);

      if (len == 0)
      {
        if (force_flush == true)
        {
          // Force flush metadata behind end of output.
          while (metadata_offset < wrapper->metadata_index)
          {
            TRACE_LOG("flush post-output metadata at: %ld.\n",
                wrapper->metadata[metadata_offset].output_index);

            metadata_entry = &wrapper->metadata[metadata_offset];

            TRACE_LOG("Output metadata prm %d.\n",
                metadata_entry->int_parameter);

            metadata_entry->metadata_output_function(
                metadata_entry->ptr_parameter,
                metadata_entry->int_parameter);

            metadata_offset++;
          }
        }
        wrapper->chars_already_on_line = 0;
        break;
      }

      if (len <= current_line_length) {
        if (force_flush == false) {
          // We're quitting on len == current_line_length since we can only
          // determine wether we can break cleanly is if a space follows
          // immediately after the last char.
          wrapper->chars_already_on_line = 0;
          break;
        }
        wrapper->chars_already_on_line = len;
      }

      // FIXME: Add break in case hyph is enabled and a word longer than
      // the line is not terminated with a space.
    }

    TRACE_LOG("wordwrap-flush-len: %ld.\n", len);

    if (len <= current_line_length)
    {
      // Line fits on screen.
      TRACE_LOG("Line fits on screen.\n");
      if (index != NULL)
      {
        index++;
        len++;
        buf = *index;
        *index = 0;
      }
      chars_sent += len;

      output_buffer(wrapper, input, &metadata_offset);
      if (wrapper->left_side_padding != 0)
        wrapper->wrapped_text_output_destination(
            wrapper->padding_buffer,
            wrapper->destination_parameter);

      if (index != NULL)
        *index = buf;
      else
      {
        //wrapper->input_index = 0;
        break;
      }
    }
    else if (wrapper->enable_hyphenation == true)
    {
      // Line does not fit on screen and hyphenation is enabled, so we'll
      // try to hyphenate.

      // In this section we'll set "index" to the point where the line
      // should be split and "last_hyphen" to the word position where
      // hyphenation should take place -- if possible, otherwise NULL.
      
      // In case hyphenation is active we're looking at the word overruning
      // the line end. It has to be completed in order to make hyphenation
      // work.
      
      TRACE_LOG("to wrap/hyphenate (force:%d) to length %d : \"",
          force_flush, current_line_length);
      TRACE_LOG_Z_UCS(input);
      TRACE_LOG("\".\n");

      // Get the char at the current line end.
      if (input[current_line_length] == Z_UCS_SPACE) {
        // Fine, we can wrap right here at this space.
        index = input + current_line_length;
        last_hyphen = NULL;
      }
      else {
        if ( ((first_space_or_newline = z_ucs_chrs(
                  input + current_line_length, word_split_chars)) == NULL) 
            && (force_flush == false) ) {
          // In case we can't find any space the word may not have been
          // completely written to the buffer. Wait until we've got more
          // input.
          TRACE_LOG("No word end found.\n");
          break;
        }
        else {
          if (first_space_or_newline == NULL) {
            word_end = input + current_line_length;
            while (*(word_end + 1) != 0) {
              word_end++;
            }
          }
          else {
            // We've found a space behind the overrunning word so we're
            // able to correctly split the current line.
            word_end = first_space_or_newline - 1;
          }

          // Before hyphentation, check for dashes inside the last word.
          // Example: "first-class car", where the word end we've now
          // found is between "first-class" and "car".
          word_start = word_end - 1;
          while (word_start > input) {
            TRACE_LOG("examining word end: \"%c\".\n", *word_start);
            if (*word_start == Z_UCS_MINUS) {
              if (input + current_line_length > word_start) {
                // Found a dash to break on
                word_start++;
                break;
              }
            }
            else if (*word_start == Z_UCS_SPACE) {
              // We just passed the word-start.
              word_start++;
              break;
            }
            word_start--;
          }

          // FIXME: Do we need a space left from here?

          TRACE_LOG("word-start: %c\n", *word_start);
          TRACE_LOG("word-end: %c\n", *word_end);

          last_hyphen = NULL;
          if (word_end >= input + current_line_length) {
            // We only have to hyphenate in case the line is still too long.

            buf = *(word_end+ 1);
            *(word_end+ 1) = 0;

            TRACE_LOG("buffer terminated at word end: \"");
            TRACE_LOG_Z_UCS(input);
            TRACE_LOG("\".\n");

            index = word_start;

            if ((hyphenated_word = hyphenate(index)) == NULL) {
              TRACE_LOG("Error hyphenating.\n");
              i18n_translate_and_exit(
                  libfizmo_module_name,
                  i18n_libfizmo_UNKNOWN_ERROR_CASE,
                  -1);
            }
            TRACE_LOG("hyphenated word: \"");
            TRACE_LOG_Z_UCS(hyphenated_word);
            TRACE_LOG("\".\n");
            *(word_end + 1) = buf;

            chars_left_on_line = current_line_length - (index - input);
            TRACE_LOG("chars left on line: %d\n", chars_left_on_line);

            ptr = hyphenated_word;
            while ((chars_left_on_line > 0) && (*ptr != 0)) {
              TRACE_LOG("Testing %c for soft-hyphen.\n", *ptr);
              if (*ptr == Z_UCS_SOFT_HYPEN) {
                last_hyphen
                  = input + (current_line_length - chars_left_on_line);
              }
              else {
                chars_left_on_line--;
              }
              ptr++;
            }
            free(hyphenated_word);

            if (last_hyphen != NULL) {
              TRACE_LOG("Last hyphen at %ld.\n", last_hyphen - input);
              buf3 = *last_hyphen;
              *last_hyphen = '-';

              index = last_hyphen + 1;
            }
            else {
              // We couldn't find a possibility to hyphenate the last
              // word in the line.
              TRACE_LOG("No hyphen found.\n");

              if (index > input) {
                if  (*(index-1) != Z_UCS_MINUS) {
                  // In case the char before the last word is not a dash,
                  // we'll skip the space before this word by moving back
                  // the index by one.
                  index--;
                }
              }
              else {
                // In case the current word is so long that it doesn't fit
                // on the line -- this may be the case if we're supposed
                // to display ASCII art and the linesize is to short -- we
                // have to advance the index to the line end.
                TRACE_LOG("This is the first word in the line, hard break.\n");
                index = input + current_line_length;
              }
            }
          }
          else {
            index = word_end;
            last_hyphen = NULL;
          }
        }
      }

      // Output everything before *index and a newline after.

      TRACE_LOG("Input (%p, %p): \"", input, index);
      TRACE_LOG_Z_UCS(input);
      TRACE_LOG("\".\n");

      buf2 = *index;
      *index = Z_UCS_NEWLINE;
      buf = *(index + 1);
      *(index + 1) = 0;

      output_buffer(wrapper, input, &metadata_offset);
      if (wrapper->left_side_padding != 0)
        wrapper->wrapped_text_output_destination(
            wrapper->padding_buffer,
            wrapper->destination_parameter);

      *(index + 1) = buf;
      *index = buf2;

      if (last_hyphen != NULL) {
        *last_hyphen = buf3;
        index--;
      }

      // if (*index == Z_UCS_SPACE) {
      while (*index == Z_UCS_SPACE) {
        index++;
      }

      len = index - input;
      chars_sent += len;

      TRACE_LOG("Processed %ld chars in hyphenated wordwrap.\n", len);
    }
    else
    {
      // Line won't fit completely and hyphenation is disabled.
      // Find the end of the last word or dash in it before the end of line
      // (opposed to looking at the word overring the line end in case of
      // hyphentation).
      TRACE_LOG("linelength: %d.\n", current_line_length);
      ptr = input + current_line_length - 1;
      while (ptr > input) {
        if (*ptr == Z_UCS_SPACE) {
          index = ptr;
          break;
        }
        else if (*ptr == Z_UCS_MINUS) {
          index = ptr + 1;
          break;
        }
        ptr--;
      }

      if (ptr == input) {
        // We couldn't find any space or dash in the whole line, so we're
        // forced to flush everything.
        index = input + current_line_length;
      }

      buf = *index;
      *index = Z_UCS_NEWLINE;
      buf2 = *(index+1);
      *(index+1) = 0;

      TRACE_LOG("Output from %p.\n", input);

      output_buffer(wrapper, input, &metadata_offset);
      if (wrapper->left_side_padding != 0)
        wrapper->wrapped_text_output_destination(
            wrapper->padding_buffer,
            wrapper->destination_parameter);

      *(index+1) = buf2;
      *index = buf;

      //if (*index == Z_UCS_SPACE) {
      while (*index == Z_UCS_SPACE) {
        index++;
      }

      len = index - input;
      chars_sent += len;
    }

    TRACE_LOG("len-after: %ld.\n", len);

    if (index != NULL) {
      TRACE_LOG("index: \"");
      TRACE_LOG_Z_UCS(index);
      TRACE_LOG("\".\n");
    }

    input += len;
    current_line_length = wrapper->line_length;
  }

  TRACE_LOG("chars sent: %ld, moving: %ld.\n",
      chars_sent, wrapper->input_index - chars_sent + 1);

  TRACE_LOG("chars_already_on_line: %d\n", wrapper->chars_already_on_line);

  index = z_ucs_rchr(wrapper->input_buffer, Z_UCS_NEWLINE);

  memmove(
      wrapper->input_buffer,
      input,
      sizeof(z_ucs) * (wrapper->input_index - chars_sent + 1));

  wrapper->input_index -= chars_sent;

  if (metadata_offset > 0)
  {
    memmove(
        wrapper->metadata,
        wrapper->metadata + metadata_offset,
        sizeof(struct wordwrap_metadata)
        * (wrapper->metadata_index - metadata_offset));
    wrapper->metadata_index -= metadata_offset;

    TRACE_LOG("metadata stored: %d.\n", wrapper->metadata_index);
  }

  for (i=0; i<wrapper->metadata_index; i++)
    wrapper->metadata[i].output_index -= chars_sent;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
{
    client_data_t data;
    int result;
    lwm2m_context_t * lwm2mH = NULL;
    int i;
    const char * localPort = "56830";
    const char * server = NULL;
    const char * serverPort = LWM2M_STANDARD_PORT_STR;
    char * name = "testlwm2mclient";
    int lifetime = 300;
    int batterylevelchanging = 0;
    time_t reboot_time = 0;
    int opt;
    bool bootstrapRequested = false;
    bool serverPortChanged = false;

#ifdef LWM2M_BOOTSTRAP
    lwm2m_client_state_t previousState = STATE_INITIAL;
#endif

    char * pskId = NULL;
    char * psk = NULL;
    uint16_t pskLen = -1;
    char * pskBuffer = NULL;

    /*
     * The function start by setting up the command line interface (which may or not be useful depending on your project)
     *
     * This is an array of commands describes as { name, description, long description, callback, userdata }.
     * The firsts tree are easy to understand, the callback is the function that will be called when this command is typed
     * and in the last one will be stored the lwm2m context (allowing access to the server settings and the objects).
     */
    command_desc_t commands[] =
    {
            {"list", "List known servers.", NULL, prv_output_servers, NULL},
            {"change", "Change the value of resource.", " change URI [DATA]\r\n"
                                                        "   URI: uri of the resource such as /3/0, /3/0/2\r\n"
                                                        "   DATA: (optional) new value\r\n", prv_change, NULL},
            {"update", "Trigger a registration update", " update SERVER\r\n"
                                                        "   SERVER: short server id such as 123\r\n", prv_update, NULL},
#ifdef LWM2M_BOOTSTRAP
            {"bootstrap", "Initiate a DI bootstrap process", NULL, prv_initiate_bootstrap, NULL},
            {"dispb", "Display current backup of objects/instances/resources\r\n"
                    "\t(only security and server objects are backupped)", NULL, prv_display_backup, NULL},
#endif
            {"ls", "List Objects and Instances", NULL, prv_object_list, NULL},
            {"disp", "Display current objects/instances/resources", NULL, prv_display_objects, NULL},
            {"dump", "Dump an Object", "dump URI"
                                       "URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL},
            {"add", "Add support of object 1024", NULL, prv_add, NULL},
            {"rm", "Remove support of object 1024", NULL, prv_remove, NULL},
            {"quit", "Quit the client gracefully.", NULL, prv_quit, NULL},
            {"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL},

            COMMAND_END_LIST
    };

    memset(&data, 0, sizeof(client_data_t));
    data.addressFamily = AF_INET6;

    opt = 1;
    while (opt < argc)
    {
        if (argv[opt] == NULL
            || argv[opt][0] != '-'
            || argv[opt][2] != 0)
        {
            print_usage();
            return 0;
        }
        switch (argv[opt][1])
        {
        case 'b':
            bootstrapRequested = true;
            if (!serverPortChanged) serverPort = LWM2M_BSSERVER_PORT_STR;
            break;
        case 'c':
            batterylevelchanging = 1;
            break;
        case 't':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            if (1 != sscanf(argv[opt], "%d", &lifetime))
            {
                print_usage();
                return 0;
            }
            break;
#ifdef WITH_TINYDTLS
        case 'i':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            pskId = argv[opt];
            break;
        case 's':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            psk = argv[opt];
            break;
#endif						
        case 'n':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            name = argv[opt];
            break;
        case 'l':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            localPort = argv[opt];
            break;
        case 'h':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            server = argv[opt];
            break;
        case 'p':
            opt++;
            if (opt >= argc)
            {
                print_usage();
                return 0;
            }
            serverPort = argv[opt];
            serverPortChanged = true;
            break;
        case '4':
            data.addressFamily = AF_INET;
            break;
        default:
            print_usage();
            return 0;
        }
        opt += 1;
    }

    if (!server)
    {
        server = (AF_INET == data.addressFamily ? DEFAULT_SERVER_IPV4 : DEFAULT_SERVER_IPV6);
    }

    /*
     *This call an internal function that create an IPV6 socket on the port 5683.
     */
    fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort);
    data.sock = create_socket(localPort, data.addressFamily);
    if (data.sock < 0)
    {
        fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno));
        return -1;
    }

    /*
     * Now the main function fill an array with each object, this list will be later passed to liblwm2m.
     * Those functions are located in their respective object file.
     */
#ifdef WITH_TINYDTLS
    if (psk != NULL)
    {
        pskLen = strlen(psk) / 2;
        pskBuffer = malloc(pskLen);

        if (NULL == pskBuffer)
        {
            fprintf(stderr, "Failed to create PSK binary buffer\r\n");
            return -1;
        }
        // Hex string to binary
        char *h = psk;
        char *b = pskBuffer;
        char xlate[] = "0123456789ABCDEF";

        for ( ; *h; h += 2, ++b)
        {
            char *l = strchr(xlate, toupper(*h));
            char *r = strchr(xlate, toupper(*(h+1)));

            if (!r || !l)
            {
                fprintf(stderr, "Failed to parse Pre-Shared-Key HEXSTRING\r\n");
                return -1;
            }

            *b = ((l - xlate) << 4) + (r - xlate);
        }
    }
#endif

    char serverUri[50];
    int serverId = 123;
    sprintf (serverUri, "coap://%s:%s", server, serverPort);
#ifdef LWM2M_BOOTSTRAP
    objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, bootstrapRequested);
#else
    objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, false);
#endif
    if (NULL == objArray[0])
    {
        fprintf(stderr, "Failed to create security object\r\n");
        return -1;
    }
    data.securityObjP = objArray[0];

    objArray[1] = get_server_object(serverId, "U", lifetime, false);
    if (NULL == objArray[1])
    {
        fprintf(stderr, "Failed to create server object\r\n");
        return -1;
    }

    objArray[2] = get_object_device();
    if (NULL == objArray[2])
    {
        fprintf(stderr, "Failed to create Device object\r\n");
        return -1;
    }

    objArray[3] = get_object_firmware();
    if (NULL == objArray[3])
    {
        fprintf(stderr, "Failed to create Firmware object\r\n");
        return -1;
    }

    objArray[4] = get_object_location();
    if (NULL == objArray[4])
    {
        fprintf(stderr, "Failed to create location object\r\n");
        return -1;
    }

    objArray[5] = get_test_object();
    if (NULL == objArray[5])
    {
        fprintf(stderr, "Failed to create test object\r\n");
        return -1;
    }

    objArray[6] = get_object_conn_m();
    if (NULL == objArray[6])
    {
        fprintf(stderr, "Failed to create connectivity monitoring object\r\n");
        return -1;
    }

    objArray[7] = get_object_conn_s();
    if (NULL == objArray[7])
    {
        fprintf(stderr, "Failed to create connectivity statistics object\r\n");
        return -1;
    }

    int instId = 0;
    objArray[8] = acc_ctrl_create_object();
    if (NULL == objArray[8])
    {
        fprintf(stderr, "Failed to create Access Control object\r\n");
        return -1;
    }
    else if (acc_ctrl_obj_add_inst(objArray[8], instId, 3, 0, serverId)==false)
    {
        fprintf(stderr, "Failed to create Access Control object instance\r\n");
        return -1;
    }
    else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 0, 0b000000000001111)==false)
    {
        fprintf(stderr, "Failed to create Access Control ACL default resource\r\n");
        return -1;
    }
    else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 999, 0b000000000000001)==false)
    {
        fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n");
        return -1;
    }
    /*
     * The liblwm2m library is now initialized with the functions that will be in
     * charge of communication
     */
    lwm2mH = lwm2m_init(&data);
    if (NULL == lwm2mH)
    {
        fprintf(stderr, "lwm2m_init() failed\r\n");
        return -1;
    }
	
#ifdef WITH_TINYDTLS
    data.lwm2mH = lwm2mH;
#endif

    /*
     * We configure the liblwm2m library with the name of the client - which shall be unique for each client -
     * the number of objects we will be passing through and the objects array
     */
    result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray);
    if (result != 0)
    {
        fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result);
        return -1;
    }

    signal(SIGINT, handle_sigint);

    /**
     * Initialize value changed callback.
     */
    init_value_change(lwm2mH);

    /*
     * As you now have your lwm2m context complete you can pass it as an argument to all the command line functions
     * precedently viewed (first point)
     */
    for (i = 0 ; commands[i].name != NULL ; i++)
    {
        commands[i].userData = (void *)lwm2mH;
    }
    fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort);
    fprintf(stdout, "> "); fflush(stdout);
    /*
     * We now enter in a while loop that will handle the communications from the server
     */
    while (0 == g_quit)
    {
        struct timeval tv;
        fd_set readfds;

        if (g_reboot)
        {
            time_t tv_sec;

            tv_sec = lwm2m_gettime();

            if (0 == reboot_time)
            {
                reboot_time = tv_sec + 5;
            }
            if (reboot_time < tv_sec)
            {
                /*
                 * Message should normally be lost with reboot ...
                 */
                fprintf(stderr, "reboot time expired, rebooting ...");
                system_reboot();
            }
            else
            {
                tv.tv_sec = reboot_time - tv_sec;
            }
        }
        else if (batterylevelchanging) 
        {
            update_battery_level(lwm2mH);
            tv.tv_sec = 5;
        }
        else 
        {
            tv.tv_sec = 60;
        }
        tv.tv_usec = 0;

        FD_ZERO(&readfds);
        FD_SET(data.sock, &readfds);
        FD_SET(STDIN_FILENO, &readfds);

        /*
         * This function does two things:
         *  - first it does the work needed by liblwm2m (eg. (re)sending some packets).
         *  - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction
         *    (eg. retransmission) and the time between the next operation
         */
        result = lwm2m_step(lwm2mH, &(tv.tv_sec));
        if (result != 0)
        {
            fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
            if(previousState == STATE_BOOTSTRAPPING)
            {
#ifdef WITH_LOGS
                fprintf(stdout, "[BOOTSTRAP] restore security and server objects\r\n");
#endif
                prv_connections_free(lwm2mH);
                prv_restore_objects(lwm2mH);
                lwm2mH->state = STATE_INITIAL;
            }
            else return -1;
        }
#ifdef LWM2M_BOOTSTRAP
        update_bootstrap_info(&previousState, lwm2mH);
#endif
        /*
         * This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set
         * with the precedent function)
         */
        result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv);

        if (result < 0)
        {
            if (errno != EINTR)
            {
              fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno));
            }
        }
        else if (result > 0)
        {
            uint8_t buffer[MAX_PACKET_SIZE];
            int numBytes;

            /*
             * If an event happens on the socket
             */
            if (FD_ISSET(data.sock, &readfds))
            {
                struct sockaddr_storage addr;
                socklen_t addrLen;

                addrLen = sizeof(addr);

                /*
                 * We retrieve the data received
                 */
                numBytes = recvfrom(data.sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen);

                if (0 > numBytes)
                {
                    fprintf(stderr, "Error in recvfrom(): %d %s\r\n", errno, strerror(errno));
                }
                else if (0 < numBytes)
                {
                    char s[INET6_ADDRSTRLEN];
                    in_port_t port;

#ifdef WITH_TINYDTLS
                    dtls_connection_t * connP;
#else
                    connection_t * connP;
#endif
                    if (AF_INET == addr.ss_family)
                    {
                        struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
                        inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin_port;
                    }
                    else if (AF_INET6 == addr.ss_family)
                    {
                        struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
                        inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin6_port;
                    }
                    fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port));

                    /*
                     * Display it in the STDERR
                     */
                    output_buffer(stderr, buffer, numBytes, 0);

                    connP = connection_find(data.connList, &addr, addrLen);
                    if (connP != NULL)
                    {
                        /*
                         * Let liblwm2m respond to the query depending on the context
                         */
#ifdef WITH_TINYDTLS
                        int result = connection_handle_packet(connP, buffer, numBytes);
						if (0 != result)
                        {
                             printf("error handling message %d\n",result);
                        }
#else
                        lwm2m_handle_packet(lwm2mH, buffer, numBytes, connP);
#endif
                        conn_s_updateRxStatistic(objArray[7], numBytes, false);
                    }
                    else
                    {
                        fprintf(stderr, "received bytes ignored!\r\n");
                    }
                }
            }

            /*
             * If the event happened on the SDTIN
             */
            else if (FD_ISSET(STDIN_FILENO, &readfds))
            {
                numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1);

                if (numBytes > 1)
                {
                    buffer[numBytes] = 0;
                    /*
                     * We call the corresponding callback of the typed command passing it the buffer for further arguments
                     */
                    handle_command(commands, (char*)buffer);
                }
                if (g_quit == 0)
                {
                    fprintf(stdout, "\r\n> ");
                    fflush(stdout);
                }
                else
                {
                    fprintf(stdout, "\r\n");
                }
            }
        }
    }

    /*
     * Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it
     */
    if (g_quit == 1)
    {
#ifdef LWM2M_BOOTSTRAP
        close_backup_object();
#endif
        lwm2m_close(lwm2mH);
    }
    close(data.sock);
    connection_free(data.connList);

    clean_security_object(objArray[0]);
    lwm2m_free(objArray[0]);
    clean_server_object(objArray[1]);
    lwm2m_free(objArray[1]);
    free_object_device(objArray[2]);
    free_object_firmware(objArray[3]);
    free_object_location(objArray[4]);
    free_test_object(objArray[5]);
    free_object_conn_m(objArray[6]);
    free_object_conn_s(objArray[7]);
    acl_ctrl_free_object(objArray[8]);

#ifdef MEMORY_TRACE
    if (g_quit == 1)
    {
        trace_print(0, 1);
    }
#endif

    return 0;
}
Ejemplo n.º 11
0
int lwm2m_client_cb(void *args)
{
	int argc;
	char **argv;

	int i;
	int result;
	int opt;
	char *name = "testlwm2mclient";

#ifdef WITH_MBEDTLS
	unsigned char psk[MBEDTLS_PSK_MAX_LEN];

	/* set default tls option */

	/*
	 * if you want to change auth_mode, please change 3rd parameter of tls_opt structure
	 * - auth_mode can be configured (2: mandatory 1: optional, 0: not verify)
	 */
	tls_opt option = {MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, 0, 1, NULL, };
	/* set cipher suite to all*/
	option.force_ciphersuites[0] = mbedtls_ssl_get_ciphersuite_id(LWM2M_CIPHERSUIT);
	option.force_ciphersuites[1] = 0;
#endif

	struct timeval tv = {60, 0};
	argc = ((struct pthread_arg *)args)->argc;
	argv = ((struct pthread_arg *)args)->argv;

	lwm2mH = NULL;
	g_quit = 0;
	server = DEFAULT_SERVER_IPV4;
	serverPort = LWM2M_STANDARD_PORT_STR;
	/* Setting up the command line interface. */
	command_desc_t commands[] = {
		{"list", "List known servers.", NULL, prv_output_servers, NULL},
		{
			"change", "Change the value of resource.", " change URI [DATA]\r\n"
			"   URI: uri of the resource such as /3/0, /3/0/2\r\n"
			"   DATA: (optional) new value\r\n", prv_change, NULL
		},
		{
			"update", "Trigger a registration update", " update SERVER\r\n"
			"   SERVER: short server id such as 123\r\n", prv_update, NULL
		},
		{"ls", "List Objects and Instances", NULL, prv_object_list, NULL},
		{
			"dump", "Dump an Object", "dump URI"
			"URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL
		},
		{"add", "Add support of object 1024", NULL, prv_add, NULL},
		{"rm", "Remove support of object 1024", NULL, prv_remove, NULL},
		{"quit", "Quit the client gracefully.", NULL, prv_quit, NULL},
		{"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL},
		COMMAND_END_LIST
	};

	memset(&data, 0, sizeof(client_data_t));
	data.addressFamily = AF_INET;

	opt = 1;
	while (opt < argc) {
		if (argv[opt] == NULL
			|| argv[opt][0] != '-'
			|| argv[opt][2] != 0) {
			print_usage();
			return 0;
		}
		switch (argv[opt][1]) {
		case 't':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			if (1 != sscanf(argv[opt], "%d", &g_lifetime)) {
				print_usage();
				return 0;
			}
			break;
#ifdef WITH_MBEDTLS
		case 'i':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			g_pskId = argv[opt];
			break;
		case 's':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			g_pskBuffer = argv[opt];
			break;
#endif
		case 'h':
			opt++;
			if (opt >= argc) {
				print_usage();
				return 0;
			}
			server = argv[opt];
			break;
		default:
			print_usage();
			return 0;
		}
		opt += 1;
	}

	/* Parse server URI to distinguish protocol and server address */
	g_proto = coap_get_protocol_from_uri(server);
	if (g_proto >= COAP_PROTOCOL_MAX) {
		printf("Not supported protocol : %d\n", g_proto);
		return -1;
	}

	/* Move pointer to address field */
	server += strlen(coap_uri_prefix[g_proto]);
	serverPort = coap_get_port_from_proto(g_proto);

	if (lwm2m_init_object() < 0) {
	}

	/* This call an internal function that create an socket. */
	printf("Trying to bind LWM2M Client to port %s\n", serverPort);
	data.sock = create_socket(g_proto, serverPort, data.addressFamily);
	if (data.sock < 0) {
		fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno));
		return -1;
	}

#ifdef WITH_MBEDTLS
	if (g_proto == COAP_TCP_TLS || g_proto == COAP_UDP_DTLS) {

		/* Set Transport layer (TCP or UDP) */
		switch (g_proto) {
		case COAP_TCP_TLS:
			option.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
			break;
		case COAP_UDP_DTLS:
			option.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
			break;
		default:
			break;
		}
		data.tls_opt = &option;

		/* Set credential information */
		tls_cred cred;
		memset(&cred, 0, sizeof(tls_cred));

		if (g_pskBuffer) {
			if (lwm2m_unhexify(psk, g_pskBuffer, &cred.psk_len) == 0) {
				if (g_pskId) {
					cred.psk_identity = g_pskId;
					cred.psk = psk;
				}
			}
			if (cred.psk_identity == NULL && cred.psk == NULL) {
				printf("failed to set psk info\n");
				goto exit;
			}
		} else {
			printf("Please set psk and psk_id\n");
			goto exit;
		}

		data.tls_context = TLSCtx(&cred);
		if (data.tls_context == NULL) {
			printf("TLS context initialize failed\n");
			goto exit;
		}
	}
#endif
	if ((lwm2mH = lwm2m_init(&data)) == NULL) {
		printf("lwm2m_init2() failed\n");
		goto exit;
	}
	lwm2mH->protocol = g_proto;

	if ((result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray)) != 0) {
		printf("lwm2m_configure() failed: 0x%X\n", result);
		goto exit;
	}

	/* Register the command line command */
	for (i = 0 ; commands[i].name != NULL ; i++) {
		commands[i].userData = (void *)lwm2mH;
	}
	printf("LWM2M Client \"%s\" started on port %s\n>  ", name, serverPort);

	/* We now enter in a while loop that will handle the communications from the server */
	while (0 == g_quit) {
		tv.tv_sec = 60;
		tv.tv_usec = 0;

		if ((result = lwm2m_step(lwm2mH, &(tv.tv_sec))) != 0) {
			printf("lwm2m_step() failed: 0x%X\n", result);
			goto exit;
		} else {
			printf(" -> State: %s\n", g_step[lwm2mH->state]);
		}

		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(data.sock, &readfds);
		FD_SET(STDIN_FILENO, &readfds);

		result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv);
		if (result < 0) {
			if (errno != EINTR) {
				fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno));
			}
		} else if (result > 0) {
			uint8_t buffer[MAX_PACKET_SIZE];
			int numBytes;

			if (FD_ISSET(data.sock, &readfds)) {
				client_data_t *user_data = lwm2mH->userData;

				numBytes = connection_read(g_proto, user_data->connP, data.sock, buffer, MAX_PACKET_SIZE, NULL, 0);

				if (numBytes > 0) {
					output_buffer(stderr, buffer, numBytes, 0);
					lwm2m_handle_packet(lwm2mH, buffer, numBytes, user_data->connP);
					conn_s_updateRxStatistic(objArray[7], numBytes, false);
				} else {
					printf("received bytes ignored!\n");
				}
				/* If the event happened on the SDTIN */
			} else if (FD_ISSET(STDIN_FILENO, &readfds)) {
				numBytes = read_input_command_line((char *)buffer);
				if (numBytes > 1) {
					buffer[numBytes] = 0;
					handle_command(commands, (char *)buffer);
				}
				if (g_quit == 0) {
					fprintf(stdout, "\r\n> ");
					fflush(stdout);
				}
			}
		}
	}

exit:
	if (g_quit && lwm2mH) {
		lwm2m_close(lwm2mH);
		sleep(1);
	}

#ifdef WITH_MBEDTLS
	if (data.tls_context) {
		TLSCtx_free(data.tls_context);
	}
#endif

	if (data.sock >= 0) {
		printf("Closing %d\n", data.sock);
		shutdown(data.sock, 3);
		if ((i = close(data.sock)) != 0) {
			printf("Fail to close %d\n", errno);
		}
	}

	if (data.connP) {
		connection_free(data.connP);
	}

	clean_security_object(objArray[0]);
	clean_server_object(objArray[1]);
	free_object_device(objArray[2]);
	free_object_firmware(objArray[3]);
	free_object_location(objArray[4]);
	free_test_object(objArray[5]);
	free_object_conn_m(objArray[6]);
	free_object_conn_s(objArray[7]);
	acl_ctrl_free_object(objArray[8]);
	lwm2m_free(objArray[0]);
	lwm2m_free(objArray[1]);

	return 0;
}
Ejemplo n.º 12
0
int main(int argc, char *argv[])
{
    fd_set readfds;
    struct timeval tv;
    int result;
    char * port = "5685";
    internal_data_t data;
    char * filename = "bootstrap_server.ini";
    int opt;
    FILE * fd;
    command_desc_t commands[] =
    {
        {"boot", "Bootstrap a client (Server Initiated).", " boot URI [NAME]\r\n"
                                    "   URI: uri of the client to bootstrap\r\n"
                                    "   NAME: endpoint name of the client as in the .ini file (optionnal)\r\n"
                                    "Example: boot coap://[::1]:56830 testlwm2mclient", prv_bootstrap_client, &data},
        {"q", "Quit the server.", NULL, prv_quit, NULL},

        COMMAND_END_LIST
    };

    while ((opt = getopt(argc, argv, "f:p:")) != -1)
    {
        switch (opt)
        {
        case 'f':
            filename = optarg;
            break;
        case 'p':
            port = optarg;
            break;
        default:
            print_usage(filename, port);
            return 0;
        }
    }

    memset(&data, 0, sizeof(internal_data_t));

    data.sock = create_socket(port);
    if (data.sock < 0)
    {
        fprintf(stderr, "Error opening socket: %d\r\n", errno);
        return -1;
    }

    data.lwm2mH = lwm2m_init(NULL, prv_buffer_send, NULL);
    if (NULL == data.lwm2mH)
    {
        fprintf(stderr, "lwm2m_init() failed\r\n");
        return -1;
    }

    signal(SIGINT, handle_sigint);

    fd = fopen(filename, "r");
    if (fd == NULL)
    {
        fprintf(stderr, "Opening file %s failed.\r\n", filename);
        return -1;
    }

    data.bsInfo = bs_get_info(fd);
    fclose(fd);
    if (data.bsInfo == NULL)
    {
        fprintf(stderr, "Reading Bootsrap Info from file %s failed.\r\n", filename);
        return -1;
    }

    lwm2m_set_bootstrap_callback(data.lwm2mH, prv_bootstrap_callback, (void *)&data);

    fprintf(stdout, "LWM2M Bootstrap Server now listening on port %s.\r\n\n", port);
    fprintf(stdout, "> "); fflush(stdout);

    while (0 == g_quit)
    {
        endpoint_t * endP;

        FD_ZERO(&readfds);
        FD_SET(data.sock, &readfds);
        FD_SET(STDIN_FILENO, &readfds);

        tv.tv_sec = 60;
        tv.tv_usec = 0;

        result = lwm2m_step(data.lwm2mH, &(tv.tv_sec));
        if (result != 0)
        {
            fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
            return -1;
        }

        result = select(FD_SETSIZE, &readfds, 0, 0, &tv);

        if ( result < 0 )
        {
            if (errno != EINTR)
            {
              fprintf(stderr, "Error in select(): %d\r\n", errno);
            }
        }
        else if (result >= 0)
        {
            uint8_t buffer[MAX_PACKET_SIZE];
            int numBytes;

            // Packet received
            if (FD_ISSET(data.sock, &readfds))
            {
                struct sockaddr_storage addr;
                socklen_t addrLen;

                addrLen = sizeof(addr);
                numBytes = recvfrom(data.sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen);

                if (numBytes == -1)
                {
                    fprintf(stderr, "Error in recvfrom(): %d\r\n", errno);
                }
                else
                {
                    char s[INET6_ADDRSTRLEN];
                    in_port_t port;
                    connection_t * connP;

					s[0] = 0;
                    if (AF_INET == addr.ss_family)
                    {
                        struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
                        inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin_port;
                    }
                    else if (AF_INET6 == addr.ss_family)
                    {
                        struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
                        inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin6_port;
                    }

                    fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port));

                    output_buffer(stderr, buffer, numBytes, 0);

                    connP = connection_find(data.connList, &addr, addrLen);
                    if (connP == NULL)
                    {
                        connP = connection_new_incoming(data.connList, data.sock, (struct sockaddr *)&addr, addrLen);
                        if (connP != NULL)
                        {
                            data.connList = connP;
                        }
                    }
                    if (connP != NULL)
                    {
                        lwm2m_handle_packet(data.lwm2mH, buffer, numBytes, connP);
                    }
                }
            }
            // command line input
            else if (FD_ISSET(STDIN_FILENO, &readfds))
            {
                numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1);

                if (numBytes > 1)
                {
                    buffer[numBytes] = 0;
                    handle_command(commands, (char*)buffer);
                }
                if (g_quit == 0)
                {
                    fprintf(stdout, "\r\n> ");
                    fflush(stdout);
                }
                else
                {
                    fprintf(stdout, "\r\n");
                }
            }
            // Do operations on endpoints
            prv_endpoint_clean(&data);

            endP = data.endpointList;
            while (endP != NULL)
            {
                switch(endP->status)
                {
                case CMD_STATUS_OK:
                    endP->cmdList = endP->cmdList->next;
                    endP->status = CMD_STATUS_NEW;
                    // fall through
                case CMD_STATUS_NEW:
                    prv_send_command(&data, endP);
                    break;
                default:
                    break;
                }

                endP = endP->next;
            }
        }
    }

    lwm2m_close(data.lwm2mH);
    bs_free_info(data.bsInfo);
    while (data.endpointList != NULL)
    {
        endpoint_t * endP;

        endP = data.endpointList;
        data.endpointList = data.endpointList->next;

        prv_endpoint_free(endP);
    }
    close(data.sock);
    connection_free(data.connList);

    return 0;
}
Ejemplo n.º 13
0
int main(int argc, char* argv[]) {
    std::string output_filename;

    static struct option long_options[] = {
        {"help",         no_argument, 0, 'h'},
        {"output", required_argument, 0, 'o'},
        {0, 0, 0, 0}
    };

    while (1) {
        int c = getopt_long(argc, argv, "ho:", long_options, 0);
        if (c == -1)
            break;

        switch (c) {
            case 'h':
                print_help();
                exit(return_code_ok);
            case 'o':
                output_filename = optarg;
                break;
            default:
                exit(return_code_fatal);
        }
    }

    if (output_filename.empty()) {
        std::cerr << "Missing -o/--output=OSMFILE option\n";
        exit(return_code_cmdline);
    }

    if (optind != argc - 1) {
        std::cerr << "Usage: osmcoastline_filter [OPTIONS] OSMFILE\n";
        exit(return_code_cmdline);
    }

    osmium::io::Header header;
    header.set("generator", "osmcoastline_filter");
    header.add_box(osmium::Box(-180.0, -90.0, 180.0, 90.0));

    osmium::io::File infile(argv[optind]);

    try {
        osmium::io::Writer writer(output_filename, header);

        std::set<osmium::object_id_type> ids;
        osmium::memory::Buffer output_buffer(10240);

        {
            osmium::io::Reader reader(infile, osmium::osm_entity_bits::way);
            while (auto input_buffer = reader.read()) {
                for (auto it = input_buffer.begin<const osmium::Way>(); it != input_buffer.end<const osmium::Way>(); ++it) {
                    const char* natural = it->get_value_by_key("natural");
                    if (natural && !strcmp(natural, "coastline")) {
                        output_buffer.add_item(*it);
                        output_buffer.commit();
                        if (output_buffer.committed() >= 10240) {
                            osmium::memory::Buffer new_buffer(10240);
                            std::swap(output_buffer, new_buffer);
                            writer(std::move(new_buffer));
                        }
                        for (const auto& nr : it->nodes()) {
                            ids.insert(nr.ref());
                        }
                    }
                }
            }
            reader.close();
        }

        {
            osmium::io::Reader reader(infile, osmium::osm_entity_bits::node);
            while (auto input_buffer = reader.read()) {
                for (auto it = input_buffer.begin<const osmium::Node>(); it != input_buffer.end<const osmium::Node>(); ++it) {
                    const char* natural = it->get_value_by_key("natural");
                    if ((ids.find(it->id()) != ids.end()) || (natural && !strcmp(natural, "coastline"))) {
                        output_buffer.add_item(*it);
                        output_buffer.commit();
                        if (output_buffer.committed() >= 10240) {
                            osmium::memory::Buffer new_buffer(10240);
                            std::swap(output_buffer, new_buffer);
                            writer(std::move(new_buffer));
                        }
                    }
                }
            }
            reader.close();
        }

        if (output_buffer.committed() > 0) {
            writer(std::move(output_buffer));
        }

        writer.close();
    } catch (osmium::io_error& e) {
        std::cerr << "io error: " << e.what() << "'\n";
        exit(return_code_fatal);
    }

    google::protobuf::ShutdownProtobufLibrary();
}
Ejemplo n.º 14
0
int lwm2mclient_main()
{
    client_data_t data;
    int result;
    lwm2m_context_t * lwm2mH = NULL;
    int i;
    const char * localPort = "56830";
    //const char * server = "beta-devices.zatar.com";
	const char * server = "leshan.eclipse.org";
	//const char * server = "5.39.83.206";
    const char * serverPort = LWM2M_STANDARD_PORT_STR;
    char * name = "ZebraBlr";
    int lifetime = 300;
    int batterylevelchanging = 0;
    time_t reboot_time = 0;
    int opt;
    bool bootstrapRequested = false;
#ifdef LWM2M_BOOTSTRAP
    lwm2m_bootstrap_state_t previousBootstrapState = NOT_BOOTSTRAPPED;
#endif

    /*
     * The function start by setting up the command line interface (which may or not be useful depending on your project)
     *
     * This is an array of commands describes as { name, description, long description, callback, userdata }.
     * The firsts tree are easy to understand, the callback is the function that will be called when this command is typed
     * and in the last one will be stored the lwm2m context (allowing access to the server settings and the objects).
     */
    command_desc_t commands[] =
    {
            {"list", "List known servers.", NULL, prv_output_servers, NULL},
            {"change", "Change the value of resource.", " change URI [DATA]\r\n"
                                                        "   URI: uri of the resource such as /3/0, /3/0/2\r\n"
                                                        "   DATA: (optional) new value\r\n", prv_change, NULL},
            {"update", "Trigger a registration update", " update SERVER\r\n"
                                                        "   SERVER: short server id such as 123\r\n", prv_update, NULL},
#ifdef LWM2M_BOOTSTRAP
            {"bootstrap", "Initiate a DI bootstrap process", NULL, prv_initiate_bootstrap, NULL},
            {"disp", "Display current objects/instances/resources", NULL, prv_display_objects, NULL},
            {"dispb", "Display current backup of objects/instances/resources\r\n"
                    "\t(only security and server objects are backupped)", NULL, prv_display_backup, NULL},
#endif
            {"ls", "List Objects and Instances", NULL, prv_object_list, NULL},
            {"dump", "Dump an Object", "dump URI"
                                       "URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL},
            {"quit", "Quit the client gracefully.", NULL, prv_quit, NULL},
            {"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL},

            COMMAND_END_LIST
    };

    memset(&data, 0, sizeof(client_data_t));
/* Zebra change: Reddy
    while ((opt = getopt(argc, argv, "bcl:n:p:t:h:")) != -1)
    {
        switch (opt)
        {
        case 'b':
            bootstrapRequested = true;
            break;
        case 'c':
            batterylevelchanging = 1;
            break;
        case 't':
            sscanf(optarg, "%d", &lifetime);
            break;
        case 'n':
            name = optarg;
            break;
        case 'l':
            localPort = optarg;
            break;
        case 'h':
            server = optarg;
            break;
        case 'p':
            serverPort = optarg;
            break;
        default:
            print_usage();
            return 0;
        }
    }
*/
    /*
     *This call an internal function that create an IPV6 socket on the port 5683.
     */
    fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort);
    data.sock = create_socket(localPort);
    if (data.sock < 0)
    {
        fprintf(stderr, "Failed to open socket: %d\r\n", errno);
        return -1;
    }

    /*
     * Now the main function fill an array with each object, this list will be later passed to liblwm2m.
     * Those functions are located in their respective object file.
     */
    char serverUri[50];
    int serverId = 123;
    sprintf (serverUri, "coap://%s:%s", server, serverPort);
	fprintf(stderr, " LWM2M serverUri %s\r\n", serverUri);
#ifdef LWM2M_BOOTSTRAP
    objArray[0] = get_security_object(serverId, serverUri, bootstrapRequested);
#else
    objArray[0] = get_security_object(serverId, serverUri, false);
#endif
    if (NULL == objArray[0])
    {
        fprintf(stderr, "Failed to create security object\r\n");
        return -1;
    }
    data.securityObjP = objArray[0];

    objArray[1] = get_server_object(serverId, "U", lifetime, false);
    if (NULL == objArray[1])
    {
        fprintf(stderr, "Failed to create server object\r\n");
        return -1;
    }

    objArray[2] = get_object_device();
    if (NULL == objArray[2])
    {
        fprintf(stderr, "Failed to create Device object\r\n");
        return -1;
    }

    objArray[3] = get_object_firmware();
    if (NULL == objArray[3])
    {
        fprintf(stderr, "Failed to create Firmware object\r\n");
        return -1;
    }

    objArray[4] = get_object_location();
    if (NULL == objArray[4])
    {
        fprintf(stderr, "Failed to create location object\r\n");
        return -1;
    }

    objArray[5] = get_test_object();
    if (NULL == objArray[5])
    {
        fprintf(stderr, "Failed to create test object\r\n");
        return -1;
    }

    objArray[6] = get_object_conn_m();
    if (NULL == objArray[6])
    {
        fprintf(stderr, "Failed to create connectivity monitoring object\r\n");
        return -1;
    }

    objArray[7] = get_object_conn_s();
    if (NULL == objArray[7])
    {
        fprintf(stderr, "Failed to create connectivity statistics object\r\n");
        return -1;
    }

    int instId = 0;
    objArray[8] = acc_ctrl_create_object();
    if (NULL == objArray[8])
    {
        fprintf(stderr, "Failed to create Access Control object\r\n");
        return -1;
    }
    else if (acc_ctrl_obj_add_inst(objArray[8], instId, 3, 0, serverId)==false)
    {
        fprintf(stderr, "Failed to create Access Control object instance\r\n");
        return -1;
    }
    else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 0, 0b000000000001111)==false)
    {
        fprintf(stderr, "Failed to create Access Control ACL default resource\r\n");
        return -1;
    }
    else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 999, 0b000000000000001)==false)
    {
        fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n");
        return -1;
    }
    /*
     * The liblwm2m library is now initialized with the functions that will be in
     * charge of communication
     */
    lwm2mH = lwm2m_init(prv_connect_server, prv_buffer_send, &data);
    if (NULL == lwm2mH)
    {
        fprintf(stderr, "lwm2m_init() failed\r\n");
        return -1;
    }

#ifdef LWM2M_BOOTSTRAP
    /*
     * Bootstrap state initialization
     */
    if (bootstrapRequested)
    {
        lwm2mH->bsState = BOOTSTRAP_REQUESTED;
    }
    else
    {
        lwm2mH->bsState = NOT_BOOTSTRAPPED;
    }
#endif

    /*
     * We configure the liblwm2m library with the name of the client - which shall be unique for each client -
     * the number of objects we will be passing through and the objects array
     */
    result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray);
    if (result != 0)
    {
        fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result);
        return -1;
    }

    signal(SIGINT, handle_sigint);

    /*
     * This function start your client to the LWM2M servers
     */
    result = lwm2m_start(lwm2mH);
    if (result != 0)
    {
        fprintf(stderr, "lwm2m_start() failed: 0x%X\r\n", result);
        return -1;
    }

    /**
     * Initialize value changed callback.
     */
    init_value_change(lwm2mH);

    /*
     * As you now have your lwm2m context complete you can pass it as an argument to all the command line functions
     * precedently viewed (first point)
     */
    for (i = 0 ; commands[i].name != NULL ; i++)
    {
        commands[i].userData = (void *)lwm2mH;
    }
    fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort);
    fprintf(stdout, "> "); fflush(stdout);
    /*
     * We now enter in a while loop that will handle the communications from the server
     */
    while (0 == g_quit)
    {
        struct timeval tv;
        fd_set readfds;

        if (g_reboot)
        {
            time_t tv_sec;

            tv_sec = lwm2m_gettime();

            if (0 == reboot_time)
            {
                reboot_time = tv_sec + 5;
            }
            if (reboot_time < tv_sec)
            {
                /*
                 * Message should normally be lost with reboot ...
                 */
                fprintf(stderr, "reboot time expired, rebooting ...");
                system_reboot();
            }
            else
            {
                tv.tv_sec = reboot_time - tv_sec;
            }
        }
        else if (batterylevelchanging) 
        {
            update_battery_level(lwm2mH);
            tv.tv_sec = 5;
        }
        else 
        {
            tv.tv_sec = 60;
        }
        tv.tv_usec = 0;

        FD_ZERO(&readfds);
        FD_SET(data.sock, &readfds);
        FD_SET(STDIN_FILENO, &readfds);

        /*
         * This function does two things:
         *  - first it does the work needed by liblwm2m (eg. (re)sending some packets).
         *  - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction
         *    (eg. retransmission) and the time between the next operation
         */
        result = lwm2m_step(lwm2mH, &(tv.tv_sec));
        if (result != 0)
        {
            fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
            return -1;
        }
#ifdef LWM2M_BOOTSTRAP
        update_bootstrap_info(&previousBootstrapState, lwm2mH);
#endif
        /*
         * This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set
         * with the precedent function)
         */
        //result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv);

        if (result < 0)
        {
            if (errno != EINTR)
            {
              fprintf(stderr, "Error in select(): %d\r\n", errno);
            }
        }
        else if (result > 0)
        {
            uint8_t buffer[MAX_PACKET_SIZE];
            int numBytes;

            /*
             * If an event happens on the socket
             */
            if (FD_ISSET(data.sock, &readfds))
            {
                //struct sockaddr_storage addr;
				struct sockaddr addr;
                uint32 addrLen;

                addrLen = sizeof(addr);

                /*
                 * We retrieve the data received
                 */
                //numBytes = recvfrom(data.sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen);
				numBytes = recvfrom(data.sock, buffer, MAX_PACKET_SIZE,0);

                if (0 > numBytes)
                {
                    fprintf(stderr, "Error in recvfrom(): %d\r\n", errno);
                }
                else if (0 < numBytes)
                {
                    char s[INET6_ADDRSTRLEN];
                    uint16 port;
                    connection_t * connP;

                    if (AF_INET == addr.sa_family)
                    {
                        struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
                        //inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
                        port = saddr->sin_port;
                    }
                    //else if (AF_INET6 == addr.ss_family)
                    //{
                    //    struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
                    //    inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
                    //    port = saddr->sin6_port;
                   // }
                    //fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port));

                    /*
                     * Display it in the STDERR
                     */
                    output_buffer(stderr, buffer, numBytes, 0);

                    connP = connection_find(data.connList, &addr, addrLen);
                    if (connP != NULL)
                    {
                        /*
                         * Let liblwm2m respond to the query depending on the context
                         */
                        lwm2m_handle_packet(lwm2mH, buffer, numBytes, connP);
                        conn_s_updateRxStatistic(objArray[7], numBytes, false);
                    }
                    else
                    {
                        fprintf(stderr, "received bytes ignored!\r\n");
                    }
                }
            }

            /*
             * If the event happened on the SDTIN
             */
            else if (FD_ISSET(STDIN_FILENO, &readfds))
            {
                numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1);

                if (numBytes > 1)
                {
                    buffer[numBytes] = 0;
                    fprintf(stderr, "STDIN %d bytes '%s'\r\n> ", numBytes, buffer);

                    /*
                     * We call the corresponding callback of the typed command passing it the buffer for further arguments
                     */
                    handle_command(commands, (char*)buffer);
                }
                if (g_quit == 0)
                {
                    fprintf(stdout, "\r\n> ");
                    fflush(stdout);
                }
                else
                {
                    fprintf(stdout, "\r\n");
                }
            }
        }
    }

    /*
     * Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it
     */
    if (g_quit == 1) {
#ifdef LWM2M_BOOTSTRAP
        close_backup_object();
#endif
        lwm2m_close(lwm2mH);
    }
    close(data.sock);
    connection_free(data.connList);

    return 0;
}
Ejemplo n.º 15
0
void dump_tlv(FILE * stream,
              int size,
              lwm2m_tlv_t * tlvP,
              int indent)
{
    int i;

    for(i= 0 ; i < size ; i++)
    {
        print_indent(stream, indent);
        fprintf(stream, "{\r\n");
        print_indent(stream, indent+1);
        fprintf(stream, "id: %d\r\n", tlvP[i].id);

        print_indent(stream, indent+1);
        fprintf(stream, "type: ");
        switch (tlvP[i].type)
        {
        case LWM2M_TYPE_OBJECT_INSTANCE:
            fprintf(stream, "LWM2M_TYPE_OBJECT_INSTANCE\r\n");
            break;
        case LWM2M_TYPE_RESOURCE_INSTANCE:
            fprintf(stream, "LWM2M_TYPE_RESOURCE_INSTANCE\r\n");
            break;
        case LWM2M_TYPE_MULTIPLE_RESOURCE:
            fprintf(stream, "LWM2M_TYPE_MULTIPLE_RESOURCE\r\n");
            break;
        case LWM2M_TYPE_RESOURCE:
            fprintf(stream, "LWM2M_TYPE_RESOURCE\r\n");
            break;
        default:
            fprintf(stream, "unknown (%d)\r\n", (int)tlvP[i].type);
            break;
        }

        print_indent(stream, indent+1);
        fprintf(stream, "flags: ");
        if (tlvP[i].flags & LWM2M_TLV_FLAG_STATIC_DATA)
        {
            fprintf(stream, "STATIC_DATA");
            if (tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT)
            {
                fprintf(stream, " | TEXT_FORMAT");
            }
        }
        else if (tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT)
        {
            fprintf(stream, "TEXT_FORMAT");
        }
        fprintf(stream, "\r\n");

        print_indent(stream, indent+1);
        fprintf(stream, "data length: %d\r\n", (int) tlvP[i].length);

        if (tlvP[i].type == LWM2M_TYPE_OBJECT_INSTANCE
         || tlvP[i].type == LWM2M_TYPE_MULTIPLE_RESOURCE)
        {
            dump_tlv(stream, tlvP[i].length, (lwm2m_tlv_t *)(tlvP[i].value), indent+1);
        }
        else
        {
            print_indent(stream, indent+1);
            fprintf(stream, "data type: ");
            switch (tlvP[i].dataType)
            {
            case LWM2M_TYPE_INTEGER:
                fprintf(stream, "Integer");
                if ((tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT) == 0)
                {
                    int64_t value;
                    if (1 == lwm2m_tlv_decode_int(tlvP + i, &value))
                    {
                        fprintf(stream, " (%" PRId64 ")", value);
                    }
                }
                break;
            case LWM2M_TYPE_STRING:
                fprintf(stream, "String");
                break;
            case LWM2M_TYPE_FLOAT:
                fprintf(stream, "Float");
                break;
            case LWM2M_TYPE_BOOLEAN:
                fprintf(stream, "Boolean");
                if ((tlvP[i].flags & LWM2M_TLV_FLAG_TEXT_FORMAT) == 0)
                {
                    bool value;
                    if (1 == lwm2m_tlv_decode_bool(tlvP + i, &value))
                    {
                        fprintf(stream, " (%s)", value?"true":"false");
                    }
                }
                break;
            case LWM2M_TYPE_TIME:
                fprintf(stream, "Time");
                break;
            case LWM2M_TYPE_OBJECT_LINK:
                fprintf(stream, "Object Link");
                break;
            case LWM2M_TYPE_OPAQUE:
                fprintf(stream, "Opaque");
                break;
            case LWM2M_TYPE_UNDEFINED:
                fprintf(stream, "Undefined");
                break;
            }
            fprintf(stream, "\r\n");
            output_buffer(stream, tlvP[i].value, tlvP[i].length, indent+1);
        }
        print_indent(stream, indent);
        fprintf(stream, "}\r\n");
    }
}
Ejemplo n.º 16
0
static void output_tlv(uint8_t * buffer,
                       size_t buffer_len,
                       int indent)
{
    lwm2m_tlv_type_t type;
    uint16_t id;
    size_t dataIndex;
    size_t dataLen;
    int length = 0;
    int result;

    while (0 != (result = lwm2m_decodeTLV((uint8_t*)buffer + length, buffer_len - length, &type, &id, &dataIndex, &dataLen)))
    {
        print_indent(indent);
        fprintf(stdout, "ID: %d", id);
        fprintf(stdout, "  type: ");
        switch (type)
        {
        case LWM2M_TYPE_OBJECT_INSTANCE:
            fprintf(stdout, "Object Instance");
            break;
        case LWM2M_TYPE_RESOURCE_INSTANCE:
            fprintf(stdout, "Resource Instance");
            break;
        case LWM2M_TYPE_MULTIPLE_RESOURCE:
            fprintf(stdout, "Multiple Instances");
            break;
        case LWM2M_TYPE_RESOURCE:
            fprintf(stdout, "Resource");
            break;
        default:
            printf("unknown (%d)", (int)type);
            break;
        }
        fprintf(stdout, "\n");
        print_indent(indent);
        fprintf(stdout, "{\n");
        if (type == LWM2M_TYPE_OBJECT_INSTANCE || type == LWM2M_TYPE_MULTIPLE_RESOURCE)
        {
            output_tlv(buffer + length + dataIndex, dataLen, indent+2);
        }
        else
        {
            int64_t intValue;
            double floatValue;

            print_indent(indent+2);
            fprintf(stdout, "data (%ld bytes):  ", dataLen);
            if (dataLen >= 16) fprintf(stdout, "\n");
            output_buffer(stdout, (uint8_t*)buffer + length + dataIndex, dataLen);
            if (0 < lwm2m_opaqueToInt(buffer + length + dataIndex, dataLen, &intValue))
            {
                print_indent(indent+2);
                fprintf(stdout, "data as Integer: %" PRId64 "\r\n", intValue);
            }
            if (0 < lwm2m_opaqueToFloat(buffer + length + dataIndex, dataLen, &floatValue))
            {
                print_indent(indent+2);
                fprintf(stdout, "data as Float: %.16g\r\n", floatValue);
            }
        }
        print_indent(indent);
        fprintf(stdout, "}\n");
        length += result;
    }
}
Ejemplo n.º 17
0
int main(int argc, char *argv[])
{
    dmclt_session session;
    dmclt_buffer_t buffer;
    dmclt_buffer_t reply;
	int i;
    bool isWbxml = false;
    int err;
    long status = 200;
    char * server = NULL;
    omadm_mo_interface_t * iMoP;
    char * proxyStr;

    server = NULL;

	for (i = 1; i < argc; i++ )
	{
	  if (!strcmp(argv[i], "-s"))
		server = argv[++i];
	  else if (!strcmp(argv[i], "-w"))
		isWbxml = true;
	  else
	  {
		  print_usage();
		  break;
	  }
	}

	session = omadmclient_session_init(isWbxml);
    if (session == NULL)
    {
        fprintf(stderr, "Initialization failed\r\n");
        return 1;
    }
    err = omadmclient_set_UI_callback(session, uiCallback, NULL);
    if (err != DMCLT_ERR_NONE)
    {
        fprintf(stderr, "Initialization failed: %d\r\n", err);
        return err;
    }

    iMoP = test_get_mo_interface();
    if (iMoP)
    {
        err = omadmclient_session_add_mo(session, iMoP);
        if (err != DMCLT_ERR_NONE)
        {
            fprintf(stderr, "Adding test MO failed: %d\r\n", err);
            if (iMoP->base_uri) free(iMoP->base_uri);
            free(iMoP);
        }
    }
    else
    {
        fprintf(stderr, "Loading test MO failed\r\n");
    }
    
	iMoP = omadm_get_mo_devdetail();
    if (iMoP)
    {
        err = omadmclient_session_add_mo(session, iMoP);
        if (err != DMCLT_ERR_NONE)
        {
            fprintf(stderr, "Adding DevDetail MO failed: %d\r\n", err);
            if (iMoP->base_uri) free(iMoP->base_uri);
            free(iMoP);
        }
    }
    else
    {
        fprintf(stderr, "Loading DevInfo MO failed\r\n");
    }

	iMoP = omadm_get_mo_dmacc();
    if (iMoP)
    {
        err = omadmclient_session_add_mo(session, iMoP);
        if (err != DMCLT_ERR_NONE)
        {
            fprintf(stderr, "Adding DmAcc MO failed: %d\r\n", err);
            if (iMoP->base_uri) free(iMoP->base_uri);
            free(iMoP);
        }
    }
    else
    {
        fprintf(stderr, "Loading DmAcc MO failed\r\n");
    }

	iMoP = omadm_get_mo_devinfo();
    if (iMoP)
    {
        err = omadmclient_session_add_mo(session, iMoP);
        if (err != DMCLT_ERR_NONE)
        {
            fprintf(stderr, "Adding DevInfo MO failed: %d\r\n", err);
            if (iMoP->base_uri) free(iMoP->base_uri);
            free(iMoP);
        }
    }
    else
    {
        fprintf(stderr, "Loading DevInfo MO failed\r\n");
    }

    err = omadmclient_session_start(session,
                                    server?server:"funambol",
                                    1);
    if (err != DMCLT_ERR_NONE)
    {
        fprintf(stderr, "Session opening to \"%s\" failed: %d\r\n", server?server:"funambol", err);
        return err;
    }
    
    do
    {
        err = omadmclient_get_next_packet(session, &buffer);
        if (DMCLT_ERR_NONE == err)
        {
            output_buffer(stderr, isWbxml, buffer);
            status = sendPacket(isWbxml?"Content-Type: application/vnd.syncml+wbxml":"Content-Type: application/vnd.syncml+xml", &buffer, &reply);
            fprintf(stderr, "Reply from \"%s\": %d\r\n\n", buffer.uri, status);

            omadmclient_clean_buffer(&buffer);

            if (200 == status)
            {
                if (isWbxml)
                {
                    output_buffer(stderr, isWbxml, reply);
                }
                else
                {
                    int i;
                    for (i = 0 ; i < reply.length ; i++)
                        fprintf(stderr, "%c", reply.data[i]);
                    fprintf(stderr, "\r\n\n");
                    fflush(stderr);
                }
                err = omadmclient_process_reply(session, &reply);
                omadmclient_clean_buffer(&reply);
            }
        }
    } while (DMCLT_ERR_NONE == err && 200 == status);

	omadmclient_session_close(session);

    // check that we return 0 in case of success
    if (DMCLT_ERR_END == err) err = 0;
    else if (status != 200) err = status;

    return err;
}
Ejemplo n.º 18
0
void test_resampler_duplex(uint32_t input_channels, uint32_t output_channels,
                           uint32_t input_rate, uint32_t output_rate,
                           uint32_t target_rate, float chunk_duration)
{
  cubeb_stream_params input_params;
  cubeb_stream_params output_params;
  osc_state state;

  input_params.format = output_params.format = cubeb_format<T>();
  state.input_channels = input_params.channels = input_channels;
  state.output_channels = output_params.channels = output_channels;
  input_params.rate = input_rate;
  state.output_rate = output_params.rate = output_rate;
  state.target_rate = target_rate;
  long got;

  cubeb_resampler * resampler =
    cubeb_resampler_create((cubeb_stream*)nullptr, &input_params, &output_params, target_rate,
                           data_cb_resampler, (void*)&state, CUBEB_RESAMPLER_QUALITY_VOIP);

  long latency = cubeb_resampler_latency(resampler);

  const uint32_t duration_s = 2;
  int32_t duration_frames = duration_s * target_rate;
  uint32_t input_array_frame_count = ceil(chunk_duration * input_rate / 1000) + ceilf(static_cast<float>(input_rate) / target_rate) * 2;
  uint32_t output_array_frame_count = chunk_duration * output_rate / 1000;
  auto_array<float> input_buffer(input_channels * input_array_frame_count);
  auto_array<float> output_buffer(output_channels * output_array_frame_count);
  auto_array<float> expected_resampled_input(input_channels * duration_frames);
  auto_array<float> expected_resampled_output(output_channels * output_rate * duration_s);

  state.max_output_phase_index = duration_s * target_rate;

  expected_resampled_input.push_silence(input_channels * duration_frames);
  expected_resampled_output.push_silence(output_channels * output_rate * duration_s);

  /* expected output is a 440Hz sine wave at 16kHz */
  fill_with_sine(expected_resampled_input.data() + latency,
                 target_rate, input_channels, duration_frames - latency, 0);
  /* expected output is a 440Hz sine wave at 32kHz */
  fill_with_sine(expected_resampled_output.data() + latency,
                 output_rate, output_channels, output_rate * duration_s - latency, 0);

  while (state.output_phase_index != state.max_output_phase_index) {
    uint32_t leftover_samples = input_buffer.length() * input_channels;
    input_buffer.reserve(input_array_frame_count);
    state.input_phase_index = fill_with_sine(input_buffer.data() + leftover_samples,
                                             input_rate,
                                             input_channels,
                                             input_array_frame_count - leftover_samples,
                                             state.input_phase_index);
    long input_consumed = input_array_frame_count;
    input_buffer.set_length(input_array_frame_count);

    got = cubeb_resampler_fill(resampler,
                               input_buffer.data(), &input_consumed,
                               output_buffer.data(), output_array_frame_count);

    /* handle leftover input */
    if (input_array_frame_count != static_cast<uint32_t>(input_consumed)) {
      input_buffer.pop(nullptr, input_consumed * input_channels);
    } else {
      input_buffer.clear();
    }

    state.output.push(output_buffer.data(), got * state.output_channels);
  }

  dump("input_expected.raw", expected_resampled_input.data(), expected_resampled_input.length());
  dump("output_expected.raw", expected_resampled_output.data(), expected_resampled_output.length());
  dump("input.raw", state.input.data(), state.input.length());
  dump("output.raw", state.output.data(), state.output.length());

  ASSERT_TRUE(array_fuzzy_equal(state.input, expected_resampled_input, epsilon<T>(input_rate/target_rate)));
  ASSERT_TRUE(array_fuzzy_equal(state.output, expected_resampled_output, epsilon<T>(output_rate/target_rate)));

  cubeb_resampler_destroy(resampler);
}
static void test_data_and_compare(const char * uriStr,
                        lwm2m_media_type_t format,
                        lwm2m_data_t * tlvP,
                        int size,
                        const char * id,
                        const uint8_t* original_buffer,
                        size_t original_length)
{
    lwm2m_uri_t uri;
    uint8_t * buffer;
    size_t length;
    
    if (uriStr != NULL)
    {
        lwm2m_stringToUri(uriStr, strlen(uriStr), &uri);
    }

    length = lwm2m_data_serialize((uriStr != NULL) ? &uri : NULL, size, tlvP, &format, &buffer);
    if (length <= 0)
    {
        printf("Serialize lwm2m_data_t %s to TLV failed.\n", id);
        //dump_data_t(stdout, size, tlvP, 0);
        CU_TEST_FATAL(CU_FALSE);
        return;
    }

    char* original_compact;
    if (format == LWM2M_CONTENT_JSON) {
        // Remove white spaces from original_buffer if not in a "" context
        // so that the original input string can be compared to the serialized data output,
        // which does not contain additional white spaces.
        original_compact= malloc(original_length);
        char* s = (char*)original_buffer; char* d = original_compact;
        uint8_t in_string_context = 0;
        do
        {
            *d = *s;
            // Toggle "in_string_context" flag if " has been detected and if " is not escaped
            if (*d == '"' && *(d-1) != '\\')
                in_string_context = !in_string_context;
            if(in_string_context || !isspace(*d))
                d++;

        } while(*s++ != 0);
        original_length = strlen(original_compact);
    } else {
        // No JSON format? Just use the original buffer
        original_compact = (char*)original_buffer;
    }

    CU_ASSERT_EQUAL(original_length, length);

    if ((original_length != length) ||
            (memcmp(original_compact, buffer, length) != 0))
    {
        printf("Comparing buffer after parse/serialize failed for %s:\n", id);
        output_buffer(stdout, buffer, length, 0);
        printf("\ninstead of:\n");
        output_buffer(stdout, (uint8_t*)original_compact, original_length, 0);
        CU_TEST_FATAL(CU_FALSE);
    }

    // Free the compact representation of the original buffer
    if (original_compact != (char*)original_buffer)
        free(original_compact);

    lwm2m_free(buffer);
}